Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 118 additions & 24 deletions .github/workflows/build-package-and-upload.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,38 @@
name: Check and build addon

on:
workflow_dispatch:
inputs:
forever_only:
description: Only build the WoW Forever package
required: true
default: true
type: boolean
push:
branches:
- master
tags:
- '*'
# paths-ignore:
#- '.github/**'
pull_request:
branches:
- master

jobs:
build:
runs-on: ubuntu-latest
permissions:
contents: write
env:
CF_API_KEY: ${{ secrets.CF_API_KEY }}
# Branch and pull-request builds validate packages but never publish
# alpha files. Version tags are the only publishing trigger.
CF_API_KEY: ${{ github.ref_type == 'tag' && secrets.CF_API_KEY || '' }}
#WAGO_API_TOKEN: ${{ secrets.WAGO_API_TOKEN }}
#WOWI_API_TOKEN: ${{ secrets.WOWI_API_TOKEN }}
GITHUB_OAUTH: ${{ secrets.GITHUB_TOKEN }}
GITHUB_OAUTH: ${{ github.ref_type == 'tag' && secrets.GITHUB_TOKEN || '' }}
RELEASE_COMMIT_MESSAGE: ${{ github.event.head_commit.message || '' }}
steps:
- name: Checkout code
uses: actions/checkout@v3
uses: actions/checkout@v7.0.1
with:
fetch-depth: 0

Expand All @@ -36,42 +49,123 @@ jobs:

- name: Package retail
if: >-
!contains(github.event.head_commit.message, '#skipretail') &&
!contains(github.event.head_commit.message, '#skipall')
uses: BigWigsMods/packager@master
!(github.event_name == 'workflow_dispatch' && inputs.forever_only) &&
!contains(github.ref_name, '-Forever-') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#skipretail') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#skipall')
uses: BigWigsMods/packager@v2.6.1

- name: Package classic
if: >-
!contains(github.event.head_commit.message, '#retailOnly') &&
!contains(github.event.head_commit.message, '#skipclassic') &&
!contains(github.event.head_commit.message, '#skipall')
uses: BigWigsMods/packager@master
!(github.event_name == 'workflow_dispatch' && inputs.forever_only) &&
!contains(github.ref_name, '-Forever-') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#retailOnly') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#skipclassic') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#skipall')
uses: BigWigsMods/packager@v2.6.1
with:
args: -g classic

- name: Package mists
if: >-
!contains(github.event.head_commit.message, '#retailOnly') &&
!contains(github.event.head_commit.message, '#skipmop') &&
!contains(github.event.head_commit.message, '#skipall')
uses: BigWigsMods/packager@master
!(github.event_name == 'workflow_dispatch' && inputs.forever_only) &&
!contains(github.ref_name, '-Forever-') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#retailOnly') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#skipmop') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#skipall')
uses: BigWigsMods/packager@v2.6.1
with:
args: -g mists

- name: Package bcc
if: >-
!contains(github.event.head_commit.message, '#retailOnly') &&
!contains(github.event.head_commit.message, '#skipbcc') &&
!contains(github.event.head_commit.message, '#skipall')
uses: BigWigsMods/packager@master
!(github.event_name == 'workflow_dispatch' && inputs.forever_only) &&
!contains(github.ref_name, '-Forever-') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#retailOnly') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#skipbcc') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#skipall')
uses: BigWigsMods/packager@v2.6.1
with:
args: -g bcc

- name: Package wrath
if: >-
!contains(github.event.head_commit.message, '#retailOnly') &&
!contains(github.event.head_commit.message, '#skiptitan') &&
!contains(github.event.head_commit.message, '#skipall')
uses: BigWigsMods/packager@master
!(github.event_name == 'workflow_dispatch' && inputs.forever_only) &&
!contains(github.ref_name, '-Forever-') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#retailOnly') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#skiptitan') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#skipall')
uses: BigWigsMods/packager@v2.6.1
with:
args: -g titan

- name: Package Forever
if: >-
!contains(env.RELEASE_COMMIT_MESSAGE, '#skipforever') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#skipall')
uses: BigWigsMods/packager@v2.6.1
with:
args: -g forever

- name: Mark release candidates as prereleases
if: github.ref_type == 'tag' && contains(github.ref_name, '-RC')
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: gh release edit "$GITHUB_REF_NAME" --prerelease

- name: Verify Forever package
if: >-
!contains(env.RELEASE_COMMIT_MESSAGE, '#skipforever') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#skipall')
shell: bash
run: |
set -euo pipefail

archives=()
while IFS= read -r candidate; do
candidate_toc="$(unzip -p "$candidate" 'Decursive/Decursive.toc' 2>/dev/null || true)"
if grep -q '^## Interface: 16001' <<<"$candidate_toc"; then
archives+=("$candidate")
fi
done < <(find .release -maxdepth 1 -type f -iname '*.zip' ! -iname '*nolib*')

if [[ ${#archives[@]} -ne 1 ]]; then
printf 'Expected one full Forever archive, found %d\n' "${#archives[@]}" >&2
printf '%s\n' "${archives[@]}" >&2
exit 1
fi

archive="${archives[0]}"
toc="$(unzip -p "$archive" 'Decursive/Decursive.toc')"
grep -q '^## Interface: 16001' <<<"$toc"
! grep -q '@project-' <<<"$toc"

ace_db="$(unzip -p "$archive" 'Decursive/Libs/AceDB-3.0/AceDB-3.0.lua')"
grep -q '"AceDB-3.0", 36' <<<"$ace_db"
grep -q 'version > 16000 and version < 20000' <<<"$ace_db"

en_us="$(unzip -p "$archive" 'Decursive/Localization/enUS.lua')"
locale_entry_count="$(grep -c '^L\[' <<<"$en_us")"
if [[ $locale_entry_count -lt 350 ]]; then
printf 'Expected at least 350 English locale entries, found %d\n' "$locale_entry_count" >&2
exit 1
fi
grep -Fq 'L["DEBUG_REPORT_HEADER"]' <<<"$en_us"
grep -Fq 'L["OPT_OPTIONS_DISABLED_WHILE_IN_COMBAT"]' <<<"$en_us"

debuffs_frame="$(unzip -p "$archive" 'Decursive/Dcr_DebuffsFrame.lua')"
grep -q 'AddDispelTypeTexture' <<<"$debuffs_frame"
! grep -q ':SetAuraBorder(' <<<"$debuffs_frame"

- name: Upload Forever test package
if: >-
(github.ref_type == 'branch' || github.event_name == 'pull_request') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#skipforever') &&
!contains(env.RELEASE_COMMIT_MESSAGE, '#skipall')
uses: actions/upload-artifact@v7.0.1
with:
name: Decursive-Forever-${{ github.sha }}
path: .release/*.zip
include-hidden-files: true
if-no-files-found: error
retention-days: 30
11 changes: 10 additions & 1 deletion DCR_init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,16 @@ local function SetRuntimeConstants_Once () -- {{{
-- }}}
else -- WOW CLASSIC
if not DC.CATACLYSM then
DC.IS_STEALTH_BUFF = D:tReverse({DS["Prowl"], DS["Stealth"], DS["Shadowmeld"], DS["Lesser Invisibility"]});
local classicStealthAuras = {"Prowl", "Stealth", "Shadowmeld", "Lesser Invisibility"}
DC.IS_STEALTH_BUFF = D:tReverse(D:tMap(classicStealthAuras, function(auraName) return DS[auraName] end));

-- The modern restricted-aura container accepts spell IDs instead
-- of names. Forever needs this list even though its spell behavior
-- otherwise follows the Classic branch.
if DC.FOREVER then
DC.MN_STEALTH_BUFFS = D:tReverse(D:tMap(classicStealthAuras, function(auraName) return DSI[auraName] end));
end

DC.IS_HARMFULL_DEBUFF = D:tReverse({DC.DS["MUTATINGINJECTION"]}); --, "Test item"});
DC.IS_DEADLY_DEBUFF = D:tReverse({});
DC.IS_OMNI_DEBUFF = D:tReverse({});
Expand Down
19 changes: 15 additions & 4 deletions Dcr_12_1_Sounds.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,25 @@ if not T._LoadedFiles or not T._LoadedFiles["Dcr_DebuffsFrame.xml"] or not T._Lo
end
T._LoadedFiles["Dcr_12_1_Sounds.lua"] = not DC.MN and "@project-version@";

DC.AURA_SOUND_REGISTRATION = not not (
DC.TWELVE_ONE
and C_UnitAuras
and type(C_UnitAuras.AddAuraSound) == "function"
and type(C_UnitAuras.RemoveAuraSound) == "function"
)

function D:Schedule_MN_SoundsRegistration(delay)
if DC.MN then
if DC.AURA_SOUND_REGISTRATION then
D:ScheduleDelayedCall("12.1RegisterSounds", D.Refresh12_1AuraSounds, delay or 1, D)
end
end


if not DC.TWELVE_ONE or not C_UnitAuras or type(C_UnitAuras.AddAuraSound) ~= "function" then
if not DC.AURA_SOUND_REGISTRATION then
-- Other client paths still call these methods while handling saved sound
-- settings. Keep those paths safe when aura-sound registration is absent.
function D:AddKnownSpellIDToSoundReg() end
function D:RemoveKnownSpellIDFromSoundReg() end
return
end

Expand Down Expand Up @@ -200,8 +211,8 @@ local function buildDesiredRegistrations()
end

function D:Refresh12_1AuraSounds()
if D:InEncounterOrCombat() then
D:Debug("|cFFFF0000Sound registration not possible right now... rescheduling in 5s|r")
if D:AurasRestricted() then
D:Debug("|cFFFF0000Sound registration not possible while auras are restricted... rescheduling in 5s|r")
D:Schedule_MN_SoundsRegistration(5)
return false
end
Expand Down
15 changes: 11 additions & 4 deletions Dcr_DIAG.lua
Original file line number Diff line number Diff line change
Expand Up @@ -692,16 +692,21 @@ local _, _, _, tocversion = GetBuildInfo();
T._CatchAllErrors = false;
T._tocversion = tocversion;

DC.WOWC = WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE
-- WoW Forever (Camelot) reports WOW_PROJECT_MAINLINE because it runs on the
-- modern client, but its classes, spells and ranks follow Classic rules.
DC.FOREVER = tocversion >= 16000 and tocversion < 20000
DC.WOWC = DC.FOREVER or WOW_PROJECT_ID ~= WOW_PROJECT_MAINLINE
-- Titan Reforged uses 38xxx TOCs but follows WotLK class and spell behavior.
DC.TITAN = tocversion >= 38000 and tocversion < 40000
DC.WOTLK = DC.TITAN or (WOW_PROJECT_WRATH_CLASSIC ~= nil and WOW_PROJECT_ID == WOW_PROJECT_WRATH_CLASSIC) -- https://wowpedia.fandom.com/wiki/WOW_PROJECT_ID
DC.CATACLYSM = not DC.TITAN and WOW_PROJECT_CATACLYSM_CLASSIC ~= nil and WOW_PROJECT_ID >= WOW_PROJECT_CATACLYSM_CLASSIC
DC.TWW = tocversion >= 110000
DC.MN = tocversion >= 120000
-- Forever uses the same restricted aura system as Midnight despite its 16xxx
-- interface number, so opt it into the modern aura paths explicitly.
DC.MN = DC.FOREVER or tocversion >= 120000
DC.BCC = tocversion >= 20505 and tocversion < 30000
DC.MOP = tocversion >= 50504 and tocversion < 60000
DC.TWELVE_ONE = tocversion >= 120100
DC.TWELVE_ONE = DC.FOREVER or tocversion >= 120100



Expand Down Expand Up @@ -1020,7 +1025,9 @@ do
["AceAddon-3.0"] = 13,
["AceComm-3.0"] = 14,
["AceConsole-3.0"] = 7,
["AceDB-3.0"] = 29,
-- AceDB 36 adds Forever realm-rule handling and a safe region
-- fallback. Older copies can fail before Decursive initializes.
["AceDB-3.0"] = DC.FOREVER and 36 or 29,
["AceDBOptions-3.0"] = 15,
["AceEvent-3.0"] = 4,
["AceHook-3.0"] = 9,
Expand Down
12 changes: 4 additions & 8 deletions Dcr_DebuffsFrame.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1183,7 +1183,10 @@ function MicroUnitF.prototype:init(Container, Unit, FrameNum, ID) -- {{{
-- AuraButtons become inaccessible to addon code while auras are
-- secret. Configure the display completely inside Blizzard's
-- initializeFrame callback and update only the container later.
ab:SetAuraBorder(border, options)
-- SetAuraBorder was a 12.1 compatibility alias and is absent in
-- Forever. Use the current AuraContainer API on both clients.
ab:ClearDispelTypeTextures()
ab:AddDispelTypeTexture(border, options)
end

local setButton = function(ab, prio)
Expand Down Expand Up @@ -2098,13 +2101,6 @@ local MUF_Status = { -- unused
}


local MF_Textures = { -- unused
"Interface/AddOns/Decursive/Textures/BackDrop-red", -- red
"Interface/AddOns/Decursive/Textures/BackDrop-blue", -- blue
"Interface/AddOns/Decursive/Textures/BackDrop-orange", -- orange
["grey"] = "Interface\\AddOns\\Decursive\\Textures\\BackDrop-grey-medium",
["black"] = "Interface/AddOns/Decursive/Textures/BackDrop",
};


-- }}}
Expand Down
16 changes: 11 additions & 5 deletions Dcr_Events.lua
Original file line number Diff line number Diff line change
Expand Up @@ -423,14 +423,20 @@ do
return currentState
end;

local Combat = Enum.AddOnRestrictionType.Combat
local Encounter = Enum.AddOnRestrictionType.Encounter
local ChallengeMode = Enum.AddOnRestrictionType.ChallengeMode
local PvPMatch = Enum.AddOnRestrictionType.PvPMatch
-- The restriction enums only exist on modern clients. Keep the Classic
-- code path loadable when those optional APIs are absent.
local restrictionTypes = Enum and Enum.AddOnRestrictionType
local Combat = restrictionTypes and restrictionTypes.Combat
local Encounter = restrictionTypes and restrictionTypes.Encounter
local ChallengeMode = restrictionTypes and restrictionTypes.ChallengeMode
local PvPMatch = restrictionTypes and restrictionTypes.PvPMatch

assert(Combat and Encounter and ChallengeMode and PvPMatch)
assert(not DC.TWELVE_ONE or (Combat and Encounter and ChallengeMode and PvPMatch))

function D:InEncounterOrCombat()
if not Combat or not Encounter then
return false
end
return currentState[Combat] ~= 0 or currentState[Encounter] ~= 0
end

Expand Down
14 changes: 8 additions & 6 deletions Decursive.lua
Original file line number Diff line number Diff line change
Expand Up @@ -349,9 +349,11 @@ do
local DebuffHistHashTable = {};

function D:Debuff_History_Add( DebuffName, DebuffType, spellID)
if not canaccessvalue(DebuffName) then -- do not store secret value
if not canaccessvalue(DebuffName) or not DebuffName then -- do not store secret value
return;
end
local spellType = canaccessvalue(DebuffType) and DebuffType and DC.NameToTypes[DebuffType]
local safeSpellID = canaccessvalue(spellID) and type(spellID) == "number" and spellID > 0 and spellID or nil
if not DebuffHistHashTable[DebuffName] then

-- reset iterator if out of boundaries
Expand All @@ -365,19 +367,19 @@ do
end

-- Register the name in the HashTable using the debuff type
DebuffHistHashTable[DebuffName] = (DebuffType and DC.NameToTypes[DebuffType] or DC.NOTYPE);
DebuffHistHashTable[DebuffName] = spellType or DC.NOTYPE;
--D:Debug(DebuffName, DebuffHistHashTable[DebuffName]);

-- Put this debuff in our history
D.DebuffHistory[iterator] = {DebuffName, spellID};
D.DebuffHistory[iterator] = {DebuffName, safeSpellID};

-- This is a useless comment
iterator = iterator + 1;

if DC.MN then
D:AddKnownSpellIDToSoundReg(spellID, DC.NameToTypes[DebuffType])
if DC.AURA_SOUND_REGISTRATION and safeSpellID and spellType then
D:AddKnownSpellIDToSoundReg(safeSpellID, spellType)

D.db.global.t_SpellIDsSoundReg[spellID] = {["spellType"] = DC.NameToTypes[DebuffType], ["from"] = "history", ["enabled"] = true}
D.db.global.t_SpellIDsSoundReg[safeSpellID] = {["spellType"] = spellType, ["from"] = "history", ["enabled"] = true}
end
end

Expand Down
1 change: 1 addition & 0 deletions Decursive.toc
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
## Interface: 120100
## Interface-Retail: 120100
## Interface-Classic: 11509
## Interface-Forever: 16001
## Interface-bcc: 20506
## Interface-Titan: 38002
## Interface-Mists: 50504
Expand Down
Loading