Content drop: music for the whole map, quests, skilling, combat and world plugins - #216
Closed
Blade9766 wants to merge 46 commits into
Closed
Content drop: music for the whole map, quests, skilling, combat and world plugins#216Blade9766 wants to merge 46 commits into
Blade9766 wants to merge 46 commits into
Conversation
Adds `::cheat`, an administrator menu covering item spawning, teleports, stat and experience editing, appearance editing, and the god mode / one-hit-kill / no-rune-cost / no-clip toggles. Shortcuts `::ohk`, `::norunes`, `::noclip` and `::heal` skip the menu. The menu uses the chatbox option dialogue (`ifChoice`) rather than `ProtectedAccess.menu`, which opens a main modal over the middle of the screen. That dialogue holds five options, so screens are grouped into four plus a navigation entry, the long lists (skills, 75 teleport destinations) are reached by typing a name, and appearance styles and colours are cycled with next/previous rather than entered as ids. Four cheats had no existing hook, so each is backed by an attribute in `org.rsmod.api.player.cheat` and read where it takes effect: - `MagicRuneManager.validateSpell` treats obj requirements as an unlimited source, so nothing is consumed. Level and spellbook requirements still apply. - `StandardNpcHitModifier` raises a hit to the npc's remaining hitpoints, applied after style immunity and flat armour so neither can undo it. Player-vs-player hits are deliberately untouched. - `PlayerMovementProcessor` walks a straight line through collision, but only once pathfinding reports it cannot reach the destination, so loc and npc interactions still resolve at their proper approach tile. `Appearance.setIdentKit` now accepts -1. The backing array already initialised to -1 and the appearance encoder passes the value straight to a protocol that reads it as "no model", so the setter's lower bound contradicted both. Body type B needs it: every id in the jaw slot is a real beard model, so clean-shaven is the absence of a model rather than a blank one. The ident-kit tables in `CheatAppearance` were read out of the revision 240 client cache (config index 2, IDENTKIT archive 3) and grouped by `bodyPartId`. They cannot be read back at runtime because the server cache does not decode ident-kit definitions, so a test cross-checks them against the engine's own default appearance to catch drift. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Adds the content/other/level-up plugin, which listens to the AdvanceStat engine queue and plays the skill's level-up jingle, the fireworks spotanim and the levelup_display chatbox box. Jingles are sent by archive 11 group id rather than RSCM id, since the client does not understand the gameval id the RSCM table resolves to. Each released skill maps to its jingle pair following the wiki rules (unlock levels, Hitpoints/Strength at 50, Hunter odd/even, Construction every tenth, Sailing at max, Smithing always unlock). Includes ::testlevelup and ::jingle admin commands for verifying by ear. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Fill in `param.defend_anim` at game startup for items the cache leaves it off: every shield, defender, book, tome and ward, plus the scimitars, blade of Saeldor, bone dagger, Verac's flail and other weapons with no block animation. The combat api's existing resolver then plays the right animation when a player is hit. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Npc-versus-player combat plays one `param.attack_anim` per npc, defaulting to the bare-handed punch, and only a few hundred npcs declare one. Add `tools/combat-anims`, which identifies each humanoid npc's weapon and shield by matching its models against item wear models, classes casters and rangers, and derives monster attack, block and death animations from their animation family. Its output ships in `content/other/npc-combat-anims`, which applies it to the cached npc types at game startup, with a hand-maintained overrides file on top. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Surfaces the varp.playtime counter that the mapclock plugin increments each cycle: a greeting on login showing total time played, and a ::playtime [name] command to look up any online player. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Puts experience gain on a configurable multiplier read from xp-rates.yml next to game.yml, defaulting to authentic 1.0x. The bundled development realm seeds new characters at 150x, so the rate is re-applied on login to correct existing characters. Adds ::xprate, ::setxprate, ::globalxprate, ::reloadxprates, and the confirmed ::resetxp / ::resetxpall commands, plus an opt-in one-time level reset for characters levelled at an old inflated rate. xp-rates.yml is generated on first boot and per-server, so it is gitignored alongside game.yml. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
account_characters has no appearance columns and its schema lives in an external module, so body type, pronoun, ident kit and colours are stored in character_attrs, the key/json store the save already writes. They are encoded from player.appearance on save and restored before the player is registered on login, with out-of-range values falling back to engine defaults instead of failing the login. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Walks a player into a solid wall with and without adminNoClip set and checks the destination is only reached when no clip is on. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Weapon attack, spell cast and npc attack sounds were sent as a per-player synth packet; they now play as area sounds around the attacker, as they do officially, so nearby players hear them too. Gives the wrench blunt attack animations and sounds; it had no attack params at all. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
The generator only recognised weapons whose model matches an item, so barbarians, Gunthor and skeleton heavies holding npc-only giant axes, great hammers and two-handed swords punched. Those models and the two-handed, ice-warrior and staff stances now map to weapon animations, casters are also recognised by gameval name, and the family matcher handles orks, Olaf's undead and Dharok. Spear and halberd npcs use the lunge, axe npcs the chop, each with that stance's sound. Overrides cover the Barrows brothers and the dark wizards' spell elements. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Dark wizards cast Water Strike and Confuse (levels 7-11) or Earth Strike and Weaken (level 20+) with the spells' own graphics, sounds and stat drains instead of the generic caster attack. The Ring of stone, coins and nature transmogrify the wearer into the rock, coin pile or bush until they move; the Ring of stone unequips itself when the disguise ends. Poison in combat: poisonous npcs (data-driven list) poison the players they hit, poisoned weapons and ammunition poison players and npcs, and npcs take poison ticks through a new npc var and timer. Adds an unkeyed npc hit impact event for mechanics that apply to every npc. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Dragon dagger, mace, scimitar, sword, 2h, halberd, spear, battleaxe and claws; Zamorakian spear and hasta; the godswords and ornament kits; Saradomin and blessed swords; whips, tentacle, abyssal dagger and bludgeon; dragon warhammer, elder maul, granite maul and hammer, barrelchest anchor, ancient mace; Darklight, Arclight, Excalibur, bone dagger, brine sabre, Voidwaker, Osmumten's fang; magic shortbow, magic longbow and comp bow, Seercull, Dorgeshuun, dragon and Armadyl crossbows, ballistas, dragon knife and thrownaxe. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Implements the Ancient Magicks, the standard curses, binds, Crumble Undead, Iban Blast, Magic Dart and god spells, the Arceuus grasps and demonbanes, and Lunar Vengeance and Vengeance Other. Npcs can now be held in place by binds, grasps and ice spells. Spells are no longer locked behind quests: the server no longer enforces teleport quest requirements, and a spellbook plugin pack overrides the client's per-spell quest check so nothing is greyed out for a quest. The cheat menu gains a spellbook switch and a ::spellbook command. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Death was a normal queue, which can never launch while the player is busy, and a player who has just been killed is always fighting back. Death is now a strong queue, and strong queues interrupt the current interaction and route so they can launch - without cancelling a script that is already mid-way, since the death sequence's own pause would otherwise be cut short by the hits still landing. Plays the death sound as an area sound and the death jingle by its archive group, which is the id the client actually plays. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds content/skills/agility: Draynor, Al Kharid, Varrock, Canifis, Falador, Seers' Village, Pollnivneach, Rellekka and Ardougne rooftop courses with wiki experience values, lap tracking, failure damage and marks of grace, plus 42 two-way agility shortcuts. Every start, landing and fall tile was verified against the cache map and collision; balance obstacles move the player tile by tile with teleport steps so the route finder can never knock them off course, and an interrupted walk always lands on the far side. Adds a rooftop course teleport group to the cheat menu. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds modern music areas for East Ardougne, West Ardougne, the Ardougne Sewers, south Ardougne (Clock Tower, Monastery), the Legends' Guild and the Mourner Tunnels, with their polygons and gameval ids, alongside the earlier city area tomls the packed music table already referenced. Adds content/interfaces/music-tab, the server side of the music player side panel: track play/unlock hint, Area/Shuffle/Single modes, Skip Track, and the three custom playlists. The handlers follow the cache's client scripts: varp.musicplay is 0 Area / 1 Shuffle / 2 Single (the old enum values were wrong), jukebox comsubs index the non-hidden rows by ascending row id, and playlist slots store varp-index*100+bit. MusicPlayer now highlights the playing row via varp.music_current_track, loops in Single mode and draws Shuffle picks from the selected playlist. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds content/travel/fairy-rings: the ring locs' Zanaris, Configure, Last-destination and Favourites ops, the dial interface with rotation and confirm, and the travel log with visited codes and up to ten favourites. Codes and destinations come from the cache's dbtable.fairyring, whose id column fixes the dial order as ADCB / ILKJ / PSRQ. The travel log only draws entries whose text the server sets, so visited codes and favourites are written into their components before the pair opens. Requires a wielded dramen or lunar staff; codes that go nowhere give the official "hardly moved at all" line. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A cast paid for entirely from a rune pouch or divine rune pouch passed the rune check but was rejected when consuming: the inventory delete transaction ran with nothing to delete and an empty transaction counts as a failure. Skip it when there are no inventory runes to remove so the pouch quantities are decremented instead. Every character now logs in as a member. The client only counts rune pouch and combination runes, and draws member spells as castable, when the login response flags the player as a member. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… music Adds content/other/emirs-arena: the Al Kharid arena as a safe PvP minigame. Inside area.emirs_arena the attack option reads Challenge; two players challenging each other (right-click or the clickable chat request, which the client sends as option 1) get the cache's legacy duel options screen, driven through varp.dueloptions exactly as clientscripts 6169/6174 read it, with all twelve rules, per-slot worn restrictions and the presets. Stakes reuse the trade screens (trademain + partydrop_side + tradeconfirm) since the cache has no Duel Arena stake window; each stake sits in a new persisted inv.emirs_arena_stake shown to the client under inv.tradeoffer, mirrored to the opponent, refunded on cancel or logout, handed to the winner, and returned at login after an interrupted duel. Duellists are placed in one of the four walled combat areas for a 3-2-1 countdown with the Commence The Fight! jingle; death keeps every item and respawns in the hospital, trapdoors forfeit, the winner gets You Are Victorious!. Recruitment boards run ranked matchmaking with rank and reward points (varbits pvpa_rank_points / pvpa_points_currency), which Mubariz's reward shop spends through a varbit shop currency. Scoreboards, hospital healing and the arena NPCs' dialogues are included, and The Emir's Arena / Shine music areas are added. Engine additions: PlayerRestrictionHook (walk/prayer/food/drink/equip), PvPAttackRestrictionHook (attack style and specials), PlayerRespawnHook, a Silent PvP attack validation result, ifSetPosition and mirrored inventory helpers, and player option 3 only follows when labelled Follow. Also fixes MiscOutput.setPlayerOp inserting instead of replacing the slot. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…nd jingle Adds content/other/grand-exchange: the cache's ge_offers, ge_collect and ge_history screens driven from the server, an order book that matches new buy offers against the cheapest sells (refunding the difference) and new sells against the highest buys, the 2% seller fee with the wiki's cap and exemptions, four-hour buy limits, per-slot collect boxes at any bank, trade history, Repeat Offer, pricing experts, and an ironman bonds-only rule. Guide prices and limits for every tradeable item ship in a TSV. The world book persists in .data/grand-exchange.json. The Trade Parade plays in a new area.grand_exchange music area carved out of the Varrock polygon, and the Grand Transaction jingle (index 11 group 86, matched by decoding the cache's jingles against the track) plays when an offer completes. Grand Exchange staff no longer wander from their desks. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds the Demon Slayer quest to the quest module: Aris starts it with a crystal-ball reading and an instanced vision of Wally banishing Delrith, Sir Prysin holds Silverlight behind three keys (Captain Rovin, the palace drain and sewer, and Wizard Traiborn in exchange for 25 bones), and the stone circle south of Varrock becomes a private instance where Denath and his dark wizards summon Delrith. Reducing Delrith to zero hitpoints leaves him weakened; the player must speak their randomised five-word incantation to banish him, with wrong words restoring him and idling letting him slip away. Quest sub-state lives in persisted quest attributes and is mirrored to the cache varbits, because the quest manager writes the whole quest varp (which those varbits share) on login and stage changes. Both cutscenes run inside the instance helper with guaranteed cleanup, exempt teleports and a dialogue fallback for the vision. Also adds the quest-wide completion jingle, the Wally the Hero and Delrith music tracks (the latter looping through the fight), quest sound effects, Silverlight-only attack validation for Delrith, and the ::resetquest, ::queststage and ::testloc admin commands used to test it. Registers the stone circle area and the weakened-Delrith timeout queue as gamevals. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds content/other/pets: kittens, cats, overgrown cats and lazy cats in all colours follow their owner when dropped. Kittens need fish or milk and stroking or a ball of wool or they run away; they grow into cats after three hours and into overgrown cats after another five and a half. Cats can chase rats, talk with a catspeak amulet, and meow, purr and hiss. The follower varp is set so the client shows the pet's options, and a cat that is out respawns on login and runs away on death. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds Gertrude's Cat to the quest module. Gertrude asks for help finding Fluffs; Shilop and Wilough sell the location of the lumber yard for 100 coins; Fluffs, up the shed ladder, hisses until she is given a bucket of milk and then a doogle sardine (raw sardine seasoned with doogle leaves); one of the mewing crates around the yard, fixed per player, holds her kitten, and returning it sends Fluffs and the kitten home. Gertrude then hands over a random-colour kitten, chocolate cake and stew with 1,525 Cooking XP, and sells further kittens for 100 coins to anyone without a cat. The kitten is the pets plugin's kitten obj so it drops, follows, feeds and grows as usual, and the cat sounds are the ids that plugin declares. The broken fence, yard ladders and doogle leaf spawns already worked generically. Gertrude's options are registered on the base multi-npc: the engine looks for a handler under the transformed form but dispatches the event with the base id, so hooks on the transformed names never fire. The mewing crate npcs get a server timer entry so their ambient "Mew!" runs, and are pinned to their crates so the Search option stays where the sound is. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ld, Yanille and Castle Wars Adds modern music areas and track lists for Mudskipper Point (Mudskipper Melody), the Fishing Guild (Mellow), the Tree Gnome Stronghold (Gnome King, Gnome Village, Gnome Village 2, with Gnomeball confined to the ball field), Yanille (Big Chords, Magic Dance), the Yanille Chain (Long Ago), the Yanille Agility Dungeon (Cavern) and Castle Wars (Castle Wars above ground, Ready for Battle in the waiting rooms and tunnels). Extends Port Sarim south to meet Mudskipper Point and includes the pending Wizards Tower (Vision) area. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds The Restless Ghost to the quest module. Father Aereck asks for the graveyard ghost to be dealt with; Father Urhney in the swamp hands over the Amulet of Ghostspeak (with the lost-amulet flow that checks pack, worn slot and bank before giving a spare); the ghost in the graveyard is only intelligible with the amulet on and explains that a warlock stole his skull; searching the altar in the Wizards' Tower basement yields the skull and raises the skeleton in the corner; putting the skull in the opened coffin releases the ghost and completes the quest for 1,125 Prayer XP. The coffin opens and closes as a shared loc swap, and the coffin, altar and skeleton use the cache multilocs on varp.restless_ghost_control. The skull has its Inspect text and a destroy-on-drop confirmation. Coffin, skeleton and ghost sound ids are declared in the quest module's gamevals.toml. Quest completion jingles now play for every quest: the client plays a jingle by its js5 archive group (the "Cache ID" on the wiki's jingle pages), not the jingle gameval id, so Quest.completedQuest sends group 154 (Quest Complete 3) by default with 152/153 available to quest scripts. Gives the Restless Ghost's skeleton a combat animation override with the updated skeleton set every other skeleton uses, since its definition carries human idle animations and the generator skipped it. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Adds Witch's Potion to the quest module. Hetty in Rimmington asks for an eye of newt, a rat's tail, an onion and a piece of burnt meat; her report of what the player is carrying reads back exactly as in the original; with all four she turns to her cauldron, casts her charm while it bubbles, and the potion is drunk straight from the cauldron for 325 Magic XP. Ordinary rats drop a rat's tail as a guaranteed drop, gated to the quest being in progress, through a new rat drop table. Betty's Magic Emporium had a shop config but no keeper, so Betty now talks and trades, which is where the eye of newt comes from. The drink and cauldron sound ids join the quest module's gamevals. Attaches "Faerie" and "Crystal Cave" to the existing Zanaris area in the modern music table. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ear shove Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ged defend waits for the projectile Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… end on death Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…d annihilate hit npcs across zones Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…points run out Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…sts and spiders Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…el glides Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ess ditch Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…lderness level rule Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ath hooks Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
# Conflicts: # .data/gamevals/varn.rscm # .data/raw-cache/server/npcs.toml
…sic map Adds 539 modern music areas traced from the wiki "Map:Music tracks" polygons: every surface region, dungeon and instance region the wiki lists, except the sailing ocean areas. Each area is a rectangle toml under .data/raw-cache/map/area with an area gameval, a music_modern dbrow and a track list in Music.kt. Reconciles the 40 existing music areas with the wiki footprints: 26 are regenerated so the sub-areas the wiki lists separately (Mage Arena, the Enclave, Dwarf Theme, Knightmare, Temple of Light, Clock Tower dungeon, Fairy Queen's hideout, Cave Background, ...) own their tiles, 14 are extended where the old rectangles stopped short, and the Wilderness, Catherby, Seers' Village, Al Kharid and Fishing Guild shuffles gain the tracks the wiki lists. The map area encoder stored the per-square zone count in a byte; a square split between region-aligned areas on all four levels has 256 zone entries, which wrapped to zero and crashed the map decoder at boot. The count is now a short. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…and Zanaris shed Adds the Lost City quest plugin: the swamp camp adventurers' dialogue, Shamus popping out of his tree when it is chopped, the Monks of Entrana ship with the weapon and armour search and its gangplanks, the cave monk and one-way ladder into the Entrana dungeon (prayer drained, magic door to the Wilderness), the Tree spirit fight at the Dramen tree with branch cutting afterwards, and the shed door that carries a staff wielder into Zanaris and completes the quest. Fairy ring teleports and the shed portal now play the vanish pose, the flower ring spotanim and the fairy ring chime (sound 1098). The Entrana dungeon zombies get their drop table so the bronze axe can be found on the island. Shamus' static map spawn is removed since the script spawns him. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
seelad
reviewed
Sep 8, 2026
| fun roll(player: Player, random: GameRandom, layout: CourseLayout): Boolean { | ||
| val course = layout.course | ||
| var denominator = course.markDenominator | ||
| if (player.baseAgilityLvl >= course.level + OVERLEVEL_THRESHOLD) { |
Contributor
There was a problem hiding this comment.
The Canifis course does not decrease the mark of grace chance at level 60, as it would here. Although the wiki states its because of a bug, I still think we should aim for accurate behavior when possible.
https://oldschool.runescape.wiki/w/Canifis_Rooftop_Course
Disclaimer: I'm not doing any full review nor have I really looked at much of what's in this PR, this part just jumped out to me as I skimmed through some things.
Collaborator
|
Closing as i need to sort through their is a lot of content on same pr, feel free to re pr with smaller drops |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Content drop from the
Content-Dropbranch: 45 commits on top ofmain. The headline change is music for the whole game map; the rest is quests, skilling, combat and player-facing plugins that landed on this branch over the last weeks.Music for the whole map (latest commit)
.data/raw-cache/map/areawith anareagameval, amusic_moderndbrow and a track list inor-cache/.../impl/Music.kt.MapAreaEncoder/MapAreaDecoderstored the per-map-square zone count in a byte. A square split between region-aligned areas on all four levels has 256 zone entries, which wrapped to zero and crashedGameMapDecoderat boot. The count is now a short, so the cache must be rebuilt (./gradlew :or-cache:buildCache).Also on this branch
Verification
./gradlew :or-cache:buildCachesucceeds with the new areas and the widened zone count../gradlew :server:app:runloads the map, all 585 music areas and 356 plugin scripts cleanly (startup was then stopped by an unrelated port clash with another local instance).🤖 Generated with Claude Code