Files
benilla-octo/crates/benilla/assets/ui/DeathFrame.xml
T
SamandClaude Fable 5 2ad0043523 benilla: initial public release
A from-scratch World of Warcraft 1.12.1 client in Rust + Bevy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-24 14:27:01 +07:00

266 lines
12 KiB
XML
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<Ui xmlns="http://www.blizzard.com/wow/ui/">
<!--
The death arc's UI (decision 0308 slices 1/3): the reference's death dialogs registered on
the shared StaticPopup engine (UiPanels.xml), and the UIParent death-event driver,
transcribed from the patch-chain FrameXML (mpqx extraction, decision 0246):
StaticPopup.lua l.375-505 (DEATH + RESURRECT×3), l.1134-1201 (XP_LOSS×2 + RECOVER_CORPSE*),
UIParent.lua l.237-262 + l.399-436 (the event arms). Strings verbatim from
GlobalStrings.lua. The engine-side events feeding this: PLAYER_DEAD/ALIVE/UNGHOST +
RESURRECT_REQUEST + CONFIRM_XP_LOSS fire from `death.rs`'s state machine;
CORPSE_IN_RANGE/OUT_OF_RANGE/IN_INSTANCE join with the slice-2 corpse-run range gate
(registered now — they simply don't fire yet). Deferred with 0308 §8: the SKINNED/
SKINNED_REPOP pair (battleground insignia) and UseSoulstone (HasSoulstone() is nil).
-->
<Script><![CDATA[
-- ── Strings (GlobalStrings.lua, verbatim; %% escapes as shipped) ─────────────────────────
local DEATH_RELEASE_TIMER = "%d %s until release"
local DEATH_RELEASE_NOTIMER = "You have died. Release to the nearest graveyard?"
local DEATH_RELEASE = "Release Spirit"
local USE_SOULSTONE = "Reincarnate" -- the shaman default; OnShow overrides with HasSoulstone()'s text
local RECOVER_CORPSE_TEXT = "Resurrect now?"
local RECOVER_CORPSE_TIMER = "%d %s until resurrection"
local RECOVER_CORPSE_INSTANCE_TEXT = "You must enter the instance to recover your corpse"
local RESURRECT_REQUEST_TEXT = "%s wants to resurrect you. You will be afflicted with resurrection sickness."
local RESURRECT_REQUEST_TIMER = "%s wants to resurrect you and will be able to in %d %s. You will be afflicted with resurrection sickness."
local RESURRECT_REQUEST_NO_SICKNESS = "%s wants to resurrect you"
local RESURRECT_REQUEST_NO_SICKNESS_TIMER = "%s wants to resurrect you and will be able to in %d %s"
local CONFIRM_XP_LOSS = "If you find your corpse, you can resurrect for no penalty. If I resurrect you all of your items will take 25%% durability damage (equipped and inventory) and you will be afflicted by %s of Resurrection Sickness."
local CONFIRM_XP_LOSS_AGAIN = "Remember, if you find your corpse there is no penalty. Are you sure you want to incur %s of Resurrection Sickness and have all your items take 25%% durability damage?"
local CONFIRM_XP_LOSS_NO_SICKNESS = "If you find your corpse, you can resurrect for no penalty. If I resurrect you all of your items will take 25%% durability damage (equipped and inventory)."
local CONFIRM_XP_LOSS_AGAIN_NO_SICKNESS = "Remember, if you find your corpse there is no penalty. Are you sure you want to have all your items take 25% durability damage?"
local ACCEPT = "Accept"
local DECLINE = "Decline"
local CANCEL = "Cancel"
-- ── The DEATH (release) dialog — StaticPopup.lua l.375-414, verbatim behavior ────────────
-- OnShow seeds timeleft from GetReleaseTimeRemaining(): >0 counts down through the engine's
-- per-tick DEATH text; −1 swaps in the no-timer text (no countdown). Timeout expiry is a
-- silent hide — the SERVER force-releases at 6:00 (0308 §1). No hideOnEscape: ESC never
-- dismisses it. Button2 is soulstone-only (HasSoulstone() is nil in v1 → hidden, and the
-- OnCancel clicked-branch falls through to RepopMe()).
StaticPopupDialogs["DEATH"] = {
text = DEATH_RELEASE_TIMER,
button1 = DEATH_RELEASE,
button2 = USE_SOULSTONE,
OnShow = function()
this.timeleft = GetReleaseTimeRemaining()
local text = HasSoulstone()
if text then
getglobal(this:GetName() .. "Button2"):SetText(text)
end
if this.timeleft == -1 then
getglobal(this:GetName() .. "Text"):SetText(DEATH_RELEASE_NOTIMER)
end
end,
OnAccept = function()
RepopMe()
end,
OnCancel = function(data, reason)
if reason == "override" then
return
end
if reason == "timeout" then
return
end
if reason == "clicked" then
if HasSoulstone() then
UseSoulstone()
else
RepopMe()
end
end
end,
DisplayButton2 = function()
return HasSoulstone()
end,
timeout = 0,
whileDead = 1,
interruptCinematic = 1,
notClosableByLogout = 1,
cancels = "RECOVER_CORPSE",
}
-- ── RECOVER_CORPSE — StaticPopup.lua l.1182-1202 (slice 2's range gate shows it) ─────────
StaticPopupDialogs["RECOVER_CORPSE"] = {
StartDelay = GetCorpseRecoveryDelay,
delayText = RECOVER_CORPSE_TIMER,
text = RECOVER_CORPSE_TEXT,
button1 = ACCEPT,
OnAccept = function()
RetrieveCorpse()
return 1
end,
timeout = 0,
whileDead = 1,
interruptCinematic = 1,
notClosableByLogout = 1,
}
StaticPopupDialogs["RECOVER_CORPSE_INSTANCE"] = {
text = RECOVER_CORPSE_INSTANCE_TEXT,
timeout = 0,
whileDead = 1,
interruptCinematic = 1,
notClosableByLogout = 1,
}
-- ── The RESURRECT trio — StaticPopup.lua l.416-505: sickness / no-sickness / no-timer.
-- Decline (or the 60 s timeout) answers the offer and re-shows DEATH if still unreleased.
local function resurrect_entry(text, delayText)
return {
StartDelay = delayText and GetCorpseRecoveryDelay or nil,
delayText = delayText,
text = text,
button1 = ACCEPT,
button2 = DECLINE,
OnShow = function()
this.timeleft = GetCorpseRecoveryDelay() + 60
end,
OnAccept = function()
AcceptResurrect()
end,
OnCancel = function()
DeclineResurrect()
if UnitIsDead("player") then
StaticPopup_Show("DEATH")
end
end,
timeout = 60,
whileDead = 1,
cancels = "DEATH",
interruptCinematic = 1,
notClosableByLogout = 1,
hideOnEscape = 1,
}
end
StaticPopupDialogs["RESURRECT"] = resurrect_entry(RESURRECT_REQUEST_TEXT, RESURRECT_REQUEST_TIMER)
StaticPopupDialogs["RESURRECT_NO_SICKNESS"] =
resurrect_entry(RESURRECT_REQUEST_NO_SICKNESS, RESURRECT_REQUEST_NO_SICKNESS_TIMER)
StaticPopupDialogs["RESURRECT_NO_TIMER"] = resurrect_entry(RESURRECT_REQUEST_NO_SICKNESS, nil)
-- ── The spirit healer's XP_LOSS two-step — StaticPopup.lua l.1134-1180: the first Accept
-- rewrites to the "Are you sure" text (data cleared, dialog stays via return 1), the second
-- sends AcceptXPLoss(); walking out of range auto-hides (the entry's own OnUpdate poll).
StaticPopupDialogs["XP_LOSS"] = {
text = CONFIRM_XP_LOSS,
button1 = ACCEPT,
button2 = CANCEL,
OnAccept = function(data)
if data then
getglobal(this:GetParent():GetName() .. "Text"):SetText(
format(CONFIRM_XP_LOSS_AGAIN, data))
this:GetParent().data = nil
return 1
else
AcceptXPLoss()
end
end,
OnUpdate = function(elapsed, dialog)
if not CheckSpiritHealerDist() then
dialog:Hide()
end
end,
timeout = 0,
exclusive = 1,
whileDead = 1,
showAlert = 1,
hideOnEscape = 1,
}
StaticPopupDialogs["XP_LOSS_NO_SICKNESS"] = {
text = CONFIRM_XP_LOSS_NO_SICKNESS,
button1 = ACCEPT,
button2 = CANCEL,
OnAccept = function(data)
if data then
getglobal(this:GetParent():GetName() .. "Text"):SetText(
CONFIRM_XP_LOSS_AGAIN_NO_SICKNESS)
this:GetParent().data = nil
return 1
else
AcceptXPLoss()
end
end,
OnUpdate = function(elapsed, dialog)
if not CheckSpiritHealerDist() then
dialog:Hide()
end
end,
timeout = 0,
exclusive = 1,
whileDead = 1,
showAlert = 1,
hideOnEscape = 1,
}
-- ── The death-event driver — UIParent.lua l.237-262 + l.399-436, transcribed ─────────────
function BenillaDeathDriver_OnEvent()
if event == "PLAYER_DEAD" then
if not StaticPopup_Visible("DEATH") then
CloseAllWindows(1)
if GetReleaseTimeRemaining() > 0 or GetReleaseTimeRemaining() == -1 then
StaticPopup_Show("DEATH")
end
end
elseif event == "PLAYER_ALIVE" then
StaticPopup_Hide("DEATH")
StaticPopup_Hide("RESURRECT_NO_SICKNESS")
elseif event == "PLAYER_UNGHOST" then
StaticPopup_Hide("RESURRECT")
StaticPopup_Hide("RESURRECT_NO_SICKNESS")
StaticPopup_Hide("RESURRECT_NO_TIMER")
elseif event == "RESURRECT_REQUEST" then
if ResurrectHasSickness() then
StaticPopup_Show("RESURRECT", arg1)
elseif ResurrectHasTimer() then
StaticPopup_Show("RESURRECT_NO_SICKNESS", arg1)
else
StaticPopup_Show("RESURRECT_NO_TIMER", arg1)
end
elseif event == "CONFIRM_XP_LOSS" then
local resSicknessTime = GetResSicknessDuration()
if resSicknessTime then
local dialog = StaticPopup_Show("XP_LOSS", resSicknessTime)
if dialog then
dialog.data = resSicknessTime
end
else
local dialog = StaticPopup_Show("XP_LOSS_NO_SICKNESS")
if dialog then
dialog.data = 1
end
end
-- The ref hides the gossip window under the confirm (UIParent.lua l.412).
local gossip = getglobal("BenillaGossipFrame")
if gossip and gossip:IsVisible() then
HideUIPanel(gossip)
end
elseif event == "CORPSE_IN_RANGE" then
StaticPopup_Show("RECOVER_CORPSE")
elseif event == "CORPSE_IN_INSTANCE" then
StaticPopup_Show("RECOVER_CORPSE_INSTANCE")
elseif event == "CORPSE_OUT_OF_RANGE" then
StaticPopup_Hide("RECOVER_CORPSE")
StaticPopup_Hide("RECOVER_CORPSE_INSTANCE")
StaticPopup_Hide("XP_LOSS")
end
end
]]></Script>
<Frame name="BenillaDeathDriver" hidden="true">
<Size><AbsDimension x="1" y="1"/></Size>
<Anchors><Anchor point="TOPLEFT"/></Anchors>
<Scripts>
<OnLoad>
self:RegisterEvent("PLAYER_DEAD")
self:RegisterEvent("PLAYER_ALIVE")
self:RegisterEvent("PLAYER_UNGHOST")
self:RegisterEvent("RESURRECT_REQUEST")
self:RegisterEvent("CONFIRM_XP_LOSS")
self:RegisterEvent("CORPSE_IN_RANGE")
self:RegisterEvent("CORPSE_IN_INSTANCE")
self:RegisterEvent("CORPSE_OUT_OF_RANGE")
</OnLoad>
<OnEvent>BenillaDeathDriver_OnEvent()</OnEvent>
</Scripts>
</Frame>
</Ui>