варианты кастомизации

This commit is contained in:
2026-08-29 14:40:38 +04:00
parent 8340b2c84f
commit d1fd8787dc
3 changed files with 1618 additions and 36 deletions
File diff suppressed because it is too large Load Diff
@@ -5,6 +5,8 @@ CHARACTER_FACING_INCREMENT = 2;
MAX_RACES = 10;
MAX_CLASSES_PER_RACE = 10;
NUM_CHAR_CUSTOMIZATIONS = 5;
MAX_EXTENDED_CHAR_CUSTOMIZATIONS = 20;
EXTENDED_CUSTOMIZATION_ROW_SPACING = 48;
MIN_CHAR_NAME_LENGTH = 2;
CHARACTER_CREATE_ROTATION_START_X = nil;
CHARACTER_ROTATION_INCREMENT = 90;
@@ -809,6 +811,11 @@ local function CharacterCreate_UpdatePersonalizationStep()
end
end
if CharacterCreate_UpdateExtendedCustomization then
CharacterCreate.extendedCustomizationStateKey = nil
CharacterCreate_UpdateExtendedCustomization()
end
CharacterCreate_UpdateGameModeVisibility();
end
@@ -872,6 +879,8 @@ function CharacterCreate_OnLoad(self)
_G["CharacterCustomizationButtonFrame"..i.."Text"]:SetText(_G["CHAR_CUSTOMIZATION"..i.."_DESC"])
end
self.extendedCustomizationElapsed = 0
local backdropColor = FACTION_BACKDROP_COLOR_TABLE["Alliance"]
CharacterCreateNameEdit:SetBackdropBorderColor(backdropColor[1], backdropColor[2], backdropColor[3])
CharacterCreateNameEdit:SetBackdropColor(backdropColor[4], backdropColor[5], backdropColor[6])
@@ -1117,13 +1126,30 @@ function CharacterCreateFrame_OnMouseUp(button)
end
end
function CharacterCreateFrame_OnUpdate()
function CharacterCreateFrame_OnUpdate(elapsed)
if ( CHARACTER_CREATE_ROTATION_START_X ) then
local x = GetCursorPosition();
local diff = (x - CHARACTER_CREATE_ROTATION_START_X) * CHARACTER_ROTATION_CONSTANT;
CHARACTER_CREATE_ROTATION_START_X = GetCursorPosition();
SetCharacterCreateFacing(GetCharacterCreateFacing() + diff);
end
if CharacterCreate_ProcessPendingCustomization
and CharacterCreate_ProcessPendingCustomization(elapsed or 0) then
return
end
CharacterCreate.extendedCustomizationElapsed =
(CharacterCreate.extendedCustomizationElapsed or 0) + (elapsed or 0)
if CharacterCreate.extendedCustomizationElapsed >= 0.10 then
CharacterCreate.extendedCustomizationElapsed = 0
if CharacterCreate_UpdateCustomizationAssetDebug then
local ok, errorText = pcall(CharacterCreate_UpdateCustomizationAssetDebug)
if not ok and CharacterCreate_LogExtendedCustomization then
CharacterCreate_LogExtendedCustomization("update failed: "..tostring(errorText), true)
end
end
end
end
function CharacterCreateEnumerateRaces(...)
@@ -1751,14 +1777,544 @@ function CharacterCreate_ResetState(immediate)
end
end
local EXTENDED_CUSTOMIZATION_SLOT_LABELS = {
[1] = "Цвет кожи",
[2] = "Лицо",
[3] = "Прическа",
[4] = "Цвет волос",
[5] = "Борода и усы",
}
local EXTENDED_CUSTOMIZATION_COMPONENT_LABELS = {
[1] = "Внешность",
[10] = "Цвет кожи",
[11] = "Вариант кожи",
[20] = "Лицо",
[21] = "Верхняя часть лица",
[22] = "Дополнительная особенность лица",
[30] = "Прическа",
[40] = "Цвет волос",
[41] = "Вариант окраски волос",
[50] = "Борода",
[51] = "Усы",
[52] = "Бакенбарды",
[53] = "Особенность лица 1",
[54] = "Особенность лица 2",
[55] = "Нижняя текстура лица",
[56] = "Верхняя текстура лица",
[57] = "Дополнительная текстура лица",
[59] = "Борода и усы",
}
local function CharacterCreate_GetCustomizationState()
-- The stock global is guaranteed to survive all Glue registration passes. The separately
-- registered MoonWell global may exist as a Lua function object while still failing validation,
-- so never prefer it over the verified dispatcher.
local api = GetHairCustomization
local useStockBridge = type(api) == "function"
if not useStockBridge then api = MoonWellGetCharacterCustomizationState end
if type(api) ~= "function" then
CharacterCreate.extendedCustomizationFailure = "MoonWell API недоступен"
return nil
end
local ok, skin, face, hairStyle, hairColor, facialHair, race, sex
if useStockBridge then
ok, skin, face, hairStyle, hairColor, facialHair, race, sex =
pcall(api, "__MoonWellState")
else
ok, skin, face, hairStyle, hairColor, facialHair, race, sex = pcall(api)
end
if not ok or skin == nil or face == nil or hairStyle == nil or hairColor == nil
or facialHair == nil or race == nil or sex == nil then
CharacterCreate.extendedCustomizationFailure = ok
and "Состояние персонажа не готово" or "Ошибка MoonWell API"
return nil
end
CharacterCreate.extendedCustomizationFailure = nil
local state = { skin, face, hairStyle, hairColor, facialHair }
state.race = race
state.sex = sex
return state
end
local function CharacterCreate_ValueCount(values)
local count = 0
for _ in pairs(values) do count = count + 1 end
return count
end
local function CharacterCreate_AttributesAreCoupled(catalog, leftKey, rightKey)
local leftToRight = {}
local rightToLeft = {}
for _, candidate in ipairs(catalog.candidates) do
local left = candidate.attributes[leftKey] or ""
local right = candidate.attributes[rightKey] or ""
if leftToRight[left] and leftToRight[left] ~= right then return false end
if rightToLeft[right] and rightToLeft[right] ~= left then return false end
leftToRight[left] = right
rightToLeft[right] = left
end
return true
end
local function CharacterCreate_BuildComponentGroups(catalog, slot)
local keys = {}
for key, meta in pairs(catalog.meta) do
if CharacterCreate_ValueCount(meta.values) > 1 then keys[#keys + 1] = key end
end
table.sort(keys, function(left, right)
return catalog.meta[left].order < catalog.meta[right].order
end)
local parent = {}
for _, key in ipairs(keys) do parent[key] = key end
local function root(key)
while parent[key] ~= key do
parent[key] = parent[parent[key]]
key = parent[key]
end
return key
end
local function merge(left, right)
left = root(left)
right = root(right)
if left ~= right then parent[right] = left end
end
for leftIndex=1, #keys do
for rightIndex=leftIndex + 1, #keys do
if CharacterCreate_AttributesAreCoupled(catalog, keys[leftIndex], keys[rightIndex]) then
merge(keys[leftIndex], keys[rightIndex])
end
end
end
local groupsByRoot = {}
for _, key in ipairs(keys) do
local keyRoot = root(key)
local group = groupsByRoot[keyRoot]
if not group then
group = { keys = {}, keySet = {}, order = catalog.meta[key].order,
label = catalog.meta[key].label }
groupsByRoot[keyRoot] = group
end
group.keys[#group.keys + 1] = key
group.keySet[key] = true
if catalog.meta[key].order < group.order then
group.order = catalog.meta[key].order
group.label = catalog.meta[key].label
end
end
catalog.groups = {}
for _, group in pairs(groupsByRoot) do catalog.groups[#catalog.groups + 1] = group end
table.sort(catalog.groups, function(left, right) return left.order < right.order end)
if #catalog.groups == 0 and #catalog.candidates > 1 then
catalog.groups[1] = {
keys = {}, keySet = {}, raw = true, order = 1,
label = EXTENDED_CUSTOMIZATION_SLOT_LABELS[slot],
}
end
end
local function CharacterCreate_CustomizationDependency(slot, state)
local dependency = 0
if slot == 2 then dependency = state[1]
elseif slot == 3 or slot == 5 then dependency = state[4]
elseif slot == 4 then dependency = state[3]
end
return dependency
end
local function CharacterCreate_CustomizationCatalogKey(slot, race, sex, state)
local dependency = CharacterCreate_CustomizationDependency(slot, state)
return race..":"..sex..":"..slot..":"..dependency
end
local function CharacterCreate_CallCustomizationCatalogAPI(api, useStockBridge, slot, race,
sex, dependency, index)
if useStockBridge then
if index then
return pcall(api, "__MoonWellCatalog", slot, race, sex, dependency, index)
end
return pcall(api, "__MoonWellCatalog", slot, race, sex, dependency)
end
if index then return pcall(api, slot, race, sex, dependency, index) end
return pcall(api, slot, race, sex, dependency)
end
local function CharacterCreate_BuildCustomizationCatalog(slot, race, sex, state)
CharacterCreate.extendedCustomizationCatalogs = CharacterCreate.extendedCustomizationCatalogs or {}
local key = CharacterCreate_CustomizationCatalogKey(slot, race, sex, state)
local catalog = CharacterCreate.extendedCustomizationCatalogs[slot]
if not catalog or catalog.key ~= key then
catalog = {
key = key, candidates = {}, byRaw = {}, meta = {}, ready = false,
}
CharacterCreate.extendedCustomizationCatalogs[slot] = catalog
end
if catalog.ready then return catalog end
local api = GetHairCustomization
local useStockBridge = type(api) == "function"
if not useStockBridge then api = MoonWellGetCharacterCustomizationCatalog end
if type(api) ~= "function" then return nil end
local dependency = CharacterCreate_CustomizationDependency(slot, state)
local ok, count, componentCount, kind1, kind2, kind3, kind4, kind5, kind6, kind7, kind8 =
CharacterCreate_CallCustomizationCatalogAPI(api, useStockBridge, slot, race, sex,
dependency)
if not ok or type(count) ~= "number" or type(componentCount) ~= "number" then
return nil
end
local kinds = { kind1, kind2, kind3, kind4, kind5, kind6, kind7, kind8 }
for component=1, componentCount do
local keyName = "component_"..component
local kind = kinds[component]
catalog.meta[keyName] = {
key = keyName,
label = EXTENDED_CUSTOMIZATION_COMPONENT_LABELS[kind]
or EXTENDED_CUSTOMIZATION_SLOT_LABELS[slot] or "Внешность",
order = component,
values = {},
}
end
for index=1, count do
local entryOK, raw, value1, value2, value3, value4, value5, value6, value7, value8 =
CharacterCreate_CallCustomizationCatalogAPI(api, useStockBridge, slot, race, sex,
dependency, index)
if not entryOK or raw == nil then return nil end
local values = { value1, value2, value3, value4, value5, value6, value7, value8 }
local candidate = { raw = raw, attributes = {} }
for component=1, componentCount do
local keyName = "component_"..component
local value = tostring(values[component] or 0)
candidate.attributes[keyName] = value
catalog.meta[keyName].values[value] = true
end
catalog.candidates[#catalog.candidates + 1] = candidate
catalog.byRaw[raw] = candidate
end
CharacterCreate_BuildComponentGroups(catalog, slot)
catalog.ready = true
return catalog
end
local function CharacterCreate_GroupSignature(candidate, group)
if group.raw then return tostring(candidate.raw) end
local values = {}
for _, key in ipairs(group.keys) do values[#values + 1] = candidate.attributes[key] or "" end
return table.concat(values, "|")
end
local function CharacterCreate_MatchesOutsideGroup(candidate, current, catalog, group)
if group.raw then return true end
for key in pairs(catalog.meta) do
if not group.keySet[key] and (candidate.attributes[key] or "") ~=
(current.attributes[key] or "") then
return false
end
end
return true
end
local function CharacterCreate_GetGroupChoices(catalog, group, currentRaw)
local current = catalog.byRaw[currentRaw]
if not current then return {}, 0 end
local choices = {}
local signatures = {}
local currentSignature = CharacterCreate_GroupSignature(current, group)
local currentIndex = 0
for _, candidate in ipairs(catalog.candidates) do
if CharacterCreate_MatchesOutsideGroup(candidate, current, catalog, group) then
local signature = CharacterCreate_GroupSignature(candidate, group)
if not signatures[signature] then
signatures[signature] = true
choices[#choices + 1] = candidate
if signature == currentSignature then currentIndex = #choices end
end
end
end
return choices, currentIndex
end
local function CharacterCreate_EnsureCustomizationSelectorFrames()
if CharacterCreate.customizationSelectorFrames then
return CharacterCreate.customizationSelectorFrames
end
local frames = {}
for index=1, MAX_EXTENDED_CHAR_CUSTOMIZATIONS do
local frame = _G["CharacterCustomizationButtonFrame"..index]
if not frame then
frame = CreateFrame("Frame", "MoonWellCharacterCustomizationSelector"..index,
CharacterCreateFrame, "CharacterCustomizationFrameTemplate")
frame:Hide()
end
if frame:GetParent() ~= CharacterCreateFrame then
frame:SetParent(CharacterCreateFrame)
end
frame:SetFrameLevel(CharacterCreateFrame:GetFrameLevel() + 5)
frame:SetID(index)
frames[index] = frame
end
CharacterCreate.customizationSelectorFrames = frames
return frames
end
function CharacterCreate_LogExtendedCustomization(messageText, once)
if once and CharacterCreate.extendedCustomizationLastLog == messageText then return end
if once then CharacterCreate.extendedCustomizationLastLog = messageText end
if type(GetHairCustomization) == "function" then
pcall(GetHairCustomization, "__MoonWellLog", tostring(messageText))
end
end
local function CharacterCreate_ShowCustomizationSelectors(frames, selectors)
local firstY = (#selectors - 1) * EXTENDED_CUSTOMIZATION_ROW_SPACING / 2
local visibleCount = 0
for index, frame in ipairs(frames) do
local selector = selectors[index]
if selector then
frame:ClearAllPoints()
frame:SetPoint("RIGHT", CharacterCreateFrame, "RIGHT", -80,
firstY - (index - 1) * EXTENDED_CUSTOMIZATION_ROW_SPACING)
frame:SetID(index)
local text = _G[frame:GetName().."Text"]
if selector.fallback then
text:SetText(selector.label)
else
text:SetText(string.format("%s: %d/%d",
selector.label, selector.currentIndex, #selector.choices))
end
frame:Show()
visibleCount = visibleCount + 1
else
frame:Hide()
end
end
return visibleCount
end
function CharacterCreate_UpdateExtendedCustomization(activeState)
local customizationVisible = CharacterCreate.personalizationMode
and not CharacterCreate.gameModeSelectionMode
if not customizationVisible then
CharacterCreate.pendingExtendedCustomization = nil
CharacterCreate.extendedCustomizationApplying = false
if CharacterCreate.customizationSelectorFrames then
for _, frame in ipairs(CharacterCreate.customizationSelectorFrames) do frame:Hide() end
end
CharacterCreate.extendedCustomizationStateKey = nil
return
end
local frames = CharacterCreate_EnsureCustomizationSelectorFrames()
local state = activeState or CharacterCreate_GetCustomizationState()
local race = state and state.race or 0
local sex = state and state.sex or -1
local stateKey
if state then
stateKey = string.format("%d:%d:%d:%d:%d:%d:%d", race, sex,
state[1], state[2], state[3], state[4], state[5])
if CharacterCreate.extendedCustomizationStateKey == stateKey then
CharacterCreate_ShowCustomizationSelectors(frames,
CharacterCreate.visibleCustomizationSelectors or {})
return
end
end
local selectors = {}
local catalogCount = 0
if state and race > 0 and (sex == 0 or sex == 1) then
for slot=1, NUM_CHAR_CUSTOMIZATIONS do
local slotSelectorCount = 0
local catalog = CharacterCreate_BuildCustomizationCatalog(slot, race, sex, state)
if catalog then
catalogCount = catalogCount + 1
for _, group in ipairs(catalog.groups) do
local choices, currentIndex = CharacterCreate_GetGroupChoices(
catalog, group, state[slot])
if #choices > 1 and currentIndex > 0 then
selectors[#selectors + 1] = {
slot = slot, group = group, catalog = catalog,
choices = choices, currentIndex = currentIndex,
currentRaw = state[slot],
label = group.label,
}
slotSelectorCount = slotSelectorCount + 1
end
end
end
if slotSelectorCount == 0 then
selectors[#selectors + 1] = {
slot = slot, fallback = true,
label = EXTENDED_CUSTOMIZATION_SLOT_LABELS[slot]
or _G["CHAR_CUSTOMIZATION"..slot.."_DESC"],
}
end
end
end
if #selectors == 0 then
for slot=1, NUM_CHAR_CUSTOMIZATIONS do
selectors[#selectors + 1] = {
slot = slot, fallback = true,
label = EXTENDED_CUSTOMIZATION_SLOT_LABELS[slot]
or _G["CHAR_CUSTOMIZATION"..slot.."_DESC"],
}
end
if CharacterCreate.extendedCustomizationFailure then
selectors[1].label = "MoonWell: "..CharacterCreate.extendedCustomizationFailure
end
end
CharacterCreate.visibleCustomizationSelectors = selectors
local visibleCount = CharacterCreate_ShowCustomizationSelectors(frames, selectors)
CharacterCreate.extendedCustomizationStateKey =
catalogCount == NUM_CHAR_CUSTOMIZATIONS and stateKey or nil
local firstFrame = frames[1]
CharacterCreate_LogExtendedCustomization(string.format(
"layout ready selectors=%d visible=%d catalogs=%d bounds=%.0f..%.0f root=%.0fx%.0f",
#selectors, visibleCount, catalogCount, firstFrame:GetLeft() or -1,
firstFrame:GetRight() or -1, CharacterCreateFrame:GetWidth() or -1,
CharacterCreateFrame:GetHeight() or -1), true)
end
local function CharacterCreate_PrimeMappedCustomization(slot, raw)
local api = GetHairCustomization
if type(api) ~= "function" then return false end
local ok, primed = pcall(api, "__MoonWellPrime", slot, raw)
return ok and primed == true
end
local function CharacterCreate_FinishPendingCustomization(reason)
local pending = CharacterCreate.pendingExtendedCustomization
CharacterCreate.pendingExtendedCustomization = nil
CharacterCreate.extendedCustomizationApplying = false
CharacterCreate.extendedCustomizationStateKey = nil
if reason then
CharacterCreate_LogExtendedCustomization(string.format(
"apply %s slot=%d target=%d steps=%d",
reason, pending and pending.slot or -1, pending and pending.targetRaw or -1,
pending and pending.completedSteps or 0), true)
end
CharacterCreate_UpdateExtendedCustomization()
end
function CharacterCreate_ProcessPendingCustomization(elapsed)
local pending = CharacterCreate.pendingExtendedCustomization
if not pending then return false end
pending.elapsed = (pending.elapsed or 0) + elapsed
if pending.elapsed < 0.02 then return true end
pending.elapsed = 0
local state = CharacterCreate_GetCustomizationState()
if not state then
CharacterCreate_FinishPendingCustomization("cancelled: state unavailable")
return false
end
if state[pending.slot] == pending.targetRaw then
CharacterCreate_FinishPendingCustomization("complete")
return false
end
if pending.remainingSteps <= 0 then
CharacterCreate_FinishPendingCustomization("cancelled: target unreachable")
return false
end
pending.remainingSteps = pending.remainingSteps - 1
pending.completedSteps = pending.completedSteps + 1
CycleCharCustomization(pending.slot, pending.cycleDirection)
return true
end
local function CharacterCreate_CycleExtendedCustomization(selectorIndex, direction)
local selectors = CharacterCreate.visibleCustomizationSelectors
local selector = selectors and selectors[selectorIndex]
if not selector then return false end
if CharacterCreate.pendingExtendedCustomization then return true end
PlaySound("gsCharacterCreationLook")
if selector.fallback then
CycleCharCustomization(selector.slot, direction)
return true
end
local targetIndex = selector.currentIndex + direction
if targetIndex < 1 then targetIndex = #selector.choices end
if targetIndex > #selector.choices then targetIndex = 1 end
local targetRaw = selector.choices[targetIndex].raw
-- The catalog is also a direct raw-value map. Prime the stock field with the mapped neighbour of
-- the target, then make exactly one stock cycle call. Both operations happen inside this click,
-- before a frame is rendered, while the stock call still performs its complete dependency/model
-- refresh. Keep the incremental path only as a compatibility fallback for an older native bridge.
local currentCandidateIndex
local targetCandidateIndex
for candidateIndex, candidate in ipairs(selector.catalog.candidates) do
if candidate.raw == selector.currentRaw then
currentCandidateIndex = candidateIndex
end
if candidate.raw == targetRaw then targetCandidateIndex = candidateIndex end
end
local candidateCount = #selector.catalog.candidates
local cycleDirection = direction
if currentCandidateIndex and targetCandidateIndex and candidateCount > 0 then
local forward = (targetCandidateIndex - currentCandidateIndex) % candidateCount
local backward = (currentCandidateIndex - targetCandidateIndex) % candidateCount
cycleDirection = forward <= backward and 1 or -1
end
if targetCandidateIndex and candidateCount > 1 then
local primeIndex = targetCandidateIndex - cycleDirection
if primeIndex < 1 then primeIndex = candidateCount end
if primeIndex > candidateCount then primeIndex = 1 end
local primeRaw = selector.catalog.candidates[primeIndex].raw
if CharacterCreate_PrimeMappedCustomization(selector.slot, primeRaw) then
CharacterCreate.extendedCustomizationApplying = true
CycleCharCustomization(selector.slot, cycleDirection)
CharacterCreate.extendedCustomizationApplying = false
local appliedState = CharacterCreate_GetCustomizationState()
if appliedState and appliedState[selector.slot] == targetRaw then
CharacterCreate.pendingExtendedCustomization = nil
CharacterCreate.extendedCustomizationStateKey = nil
CharacterCreate_LogExtendedCustomization(string.format(
"apply mapped slot=%d target=%d", selector.slot, targetRaw), true)
CharacterCreate_UpdateExtendedCustomization(appliedState)
return true
end
end
end
CharacterCreate.pendingExtendedCustomization = {
slot = selector.slot,
targetRaw = targetRaw,
cycleDirection = cycleDirection,
remainingSteps = candidateCount,
completedSteps = 0,
elapsed = 0.02,
}
CharacterCreate.extendedCustomizationApplying = true
return true
end
function CharacterCustomization_Left(id)
PlaySound("gsCharacterCreationLook");
CycleCharCustomization(id, -1);
if not CharacterCreate_CycleExtendedCustomization(id, -1) then
PlaySound("gsCharacterCreationLook")
CycleCharCustomization(id, -1)
end
end
function CharacterCustomization_Right(id)
PlaySound("gsCharacterCreationLook");
CycleCharCustomization(id, 1);
if not CharacterCreate_CycleExtendedCustomization(id, 1) then
PlaySound("gsCharacterCreationLook")
CycleCharCustomization(id, 1)
end
end
function CharacterCreate_UpdateCustomizationAssetDebug()
if CharacterCreate.extendedCustomizationApplying then return end
CharacterCreate_UpdateExtendedCustomization(CharacterCreate_GetCustomizationState())
end
function CharacterCreate_Randomize()
@@ -1792,6 +2348,9 @@ function CharacterCreate_UpdateHairCustomization()
CharacterCustomizationButtonFrame3Text:SetText(_G["HAIR_"..GetHairCustomization().."_STYLE"]);
CharacterCustomizationButtonFrame4Text:SetText(_G["HAIR_"..GetHairCustomization().."_COLOR"]);
CharacterCustomizationButtonFrame5Text:SetText(_G["FACIAL_HAIR_"..GetFacialHairCustomization()]);
if CharacterCreate.extendedCustomizationApplying then return end
CharacterCreate.extendedCustomizationStateKey = nil
CharacterCreate_UpdateExtendedCustomization()
end
function SetButtonDesaturated(button, desaturated, r, g, b)
@@ -72,7 +72,7 @@
<Scripts>
<OnClick>
if( self.enable ) then
CharacterClass_OnClick(self:GetID());
CharacterClass_OnClick(self:GetID());
CharacterCreateTooltip:Hide();
end
</OnClick>
@@ -127,27 +127,27 @@
</CheckButton>
<Frame name="CharacterCustomizationFrameTemplate" virtual="true">
<Size>
<AbsDimension x="230" y="32"/>
</Size>
<Layers>
<Layer level="BACKGROUND">
<Texture name="$parentBackground" file="Interface\Glues\CharacterCreate\charactercreate">
<Size>
<AbsDimension x="150" y="34"/>
</Size>
<Anchors>
<Anchor point="CENTER"/>
</Anchors>
<TexCoords left="0.508300781" right="0.656738281" top="0.244140625" bottom="0.279296875"/>
</Texture>
<FontString name="$parentText" inherits="GlueFontHighlightSmall">
<Anchors>
<Anchor point="CENTER" x="0" y="2"/>
</Anchors>
</FontString>
</Layer>
</Layers>
<Size>
<AbsDimension x="230" y="32"/>
</Size>
<Layers>
<Layer level="BACKGROUND">
<Texture name="$parentBackground" file="Interface\Glues\CharacterCreate\charactercreate">
<Size>
<AbsDimension x="180" y="34"/>
</Size>
<Anchors>
<Anchor point="CENTER"/>
</Anchors>
<TexCoords left="0.508300781" right="0.656738281" top="0.244140625" bottom="0.279296875"/>
</Texture>
<FontString name="$parentText" inherits="GlueFontHighlightSmall">
<Anchors>
<Anchor point="CENTER" x="0" y="2"/>
</Anchors>
</FontString>
</Layer>
</Layers>
<Frames>
<Button name="$parentRightButton">
<Size x="24" y="24"/>
@@ -540,7 +540,6 @@
<CheckButton name="CharacterCreateClassButton10" inherits="CharacterCreateClassButtonTemplate" id="10"/>
</Frames>
</Frame>
<!-- Frames de personalización independientes -->
<Frame name="CharacterCustomizationButtonFrame1" inherits="CharacterCustomizationFrameTemplate" id="1">
<Anchors>
<Anchor point="CENTER" x="900" y="150"/>
@@ -832,7 +831,7 @@
</OnClick>
</Scripts>
</Button>
<Button name="CharCreateBackButton" inherits="GlueButtonTemplate" text="BACK">
<Size x="150" y="50"/>
<Anchors>
@@ -858,7 +857,7 @@
</OnUpdate>
</Scripts>
</Button>
</Frames>
<Scripts>
<OnMouseDown>
@@ -868,7 +867,7 @@
CharacterCreateFrame_OnMouseUp(button);
</OnMouseUp>
<OnUpdate>
CharacterCreateFrame_OnUpdate();
CharacterCreateFrame_OnUpdate(arg1);
</OnUpdate>
</Scripts>
</Frame>