Dragonfire shield charging, discharge and creation - #1186
Merged
Conversation
GregHib
reviewed
Aug 18, 2026
The shield gains a charge from every dragonfire and wyvern icy breath it absorbs, up to 50, each adding one to its melee, ranged and summoning defences. Activating the worn shield spends a charge to breathe dragonfire back at the current target for up to 290, on a two minute cooldown and at up to twelve squares, over obstacles. Inspect reports the charges and Empty releases them, reverting to the tradeable uncharged shield. Creating one is now possible either by smithing a draconic visage onto an anti-dragon shield at an anvil, needing 90 Smithing and a hammer for 2000 experience, or by paying Oziach 1,250,000 coins to forge it. Oziach had no dialogue at all before, only the shop his definition points at. Charges are lost with the shield on death, after items kept on death are worked out so a protected shield stays charged. Supporting fixes: - Item.amount treated the charges held in an item's value as a quantity unless the definition's starting charge count was above one, which it never is for an item that starts empty. A twenty charge shield counted as twenty items, so items kept on death protected three of them and the rest dropped as a stack. Capacity now decides, which also covers satchels, tea flasks and enchanted headgear. - Dragonfire damage reduction in Equipment read the attacker's shield and antifire rather than the victim's, and messaged the attacker. It was unreachable while only npcs breathed dragonfire, but firing the shield woke it up and cut the wielder's own damage by 80%. Dragonfire.maxHit already applies the victim's shield, potion and prayer, so the duplicate is gone and its shield message moved there where it reaches the victim. - The same wrong-entity bug left a fire resistant shield doing nothing against a wyvern's icy breath, and fireResistantShield compared against "dragonfire_shield" which is an alias rather than an equipped id. The cap also replaced the damage instead of limiting it, so a small hit was raised to it. SkeletalWyvern now shares the same shield check. - Dragonfire dealt by a player granted Constitution experience alone; it now grants Magic and Defence as well. - Dragonfire.maxHit returned -1 for a dragon immune to it, which would have thrown out of random.nextInt once a player could deal dragonfire.
HarleyGilpin
force-pushed
the
feat/DFS-Special
branch
from
August 18, 2026 20:47
3359e01 to
90786e9
Compare
A shielded player was told their shield absorbed most of the breath and that they were horribly burnt by it, which contradict each other. Both 2009scape and Darkan pick a single message by whichever protection did the most, so report the shield alone when one is worn.
Void reported the same two messages whatever the target was wearing or drinking, so an antifire potion or protect from magic went unmentioned and a fully immune player was still told they were horribly burnt. Darkan is revision 727 against 2009scape's 530, so its wording is the closer match for 634. Its ladder is adopted whole, reporting only the strongest protection: super antifire, shield and potion together, shield, potion, prayer, then the unprotected hit.
The fire left the shield before the animation had played enough of its wind up, so hold it back another sixty client ticks.
Ninety client ticks lands the fire just before the ninety five tick activate animation finishes, rather than after the player has already dropped back to idle.
HarleyGilpin
marked this pull request as ready for review
August 18, 2026 22:31
GregHib
approved these changes
Aug 19, 2026
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.
Implements the dragonfire shield, which had item definitions but no behaviour.
Referenced against the 2011 wiki revision
Shield
Creation
Both produce the uncharged shield.
Supporting fixes
Each of these was reached, or made reachable, by the shield.
Item.amountcounted charges as a quantity. The guard only recognised item-value charges when the definition's starting charge count was above one, which it never is for something that starts empty. A twenty charge shield therefore looked like twenty items: items kept on death protected three of them and the rest dropped as a stack. Capacity now decides, which also covers satchels, tea flasks and enchanted headgear.Equipmentread the wrong entity. It sat in awhen (source)and used the attacker's shield and antifire, messaging the attacker. Unreachable while only npcs breathed dragonfire, but firing the shield woke it up and cut the wielder's own damage by 80% while telling them their shield had absorbed it.Dragonfire.maxHitalready applies the victim's shield, potion and prayer, so the duplicate is gone and its shield message moved there, where it reaches the victim.fireResistantShieldcompared againstdragonfire_shield, an alias rather than an equipped id. The cap also replaced the damage rather than limiting it, so a small hit was raised to it.SkeletalWyvernnow shares the one shield check instead of keeping its own copy.Dragonfire.maxHitreturned-1for an immune dragon, which would have thrown out ofrandom.nextInt(0, 0)inDamage.rollas soon as a player could deal dragonfire.Data
Shield definitions moved out of
ancient_cavern.*intodata/entity/player/equipment/dragonfire_shield.*, since it is not ancient cavern content.Testing
20 tests across
DragonfireShieldTest,OziachTestandIcyBreathTestcovering charging and the cap, the defence bonus, activate with its cooldown, range and dragon immunity, inspect and empty, death conversion, both creation routes and their requirements, and the icy breath cap. Full suite green.One test changed:
EnchantedHeadgearTestasserted a helm's stored scroll count throughItem.amount, now read throughcharges().