diff --git a/modsettings/CustomUIAssets.json b/modsettings/CustomUIAssets.json
index 37fe7bd3..f07b8088 100644
--- a/modsettings/CustomUIAssets.json
+++ b/modsettings/CustomUIAssets.json
@@ -19,6 +19,31 @@
"Type": 0,
"URL": "http://cloud-3.steamusercontent.com/ugc/2038486957000850722/37F0D4848BA08788F79DB2D3FB6D11429CB1F861/"
},
+ {
+ "Name": "Playermat-Guardian-Cache",
+ "Type": 0,
+ "URL": "http://cloud-3.steamusercontent.com/ugc/2444972799638881117/169F4520A94FB186B54E0F2BF4BAC809844C923E/"
+ },
+ {
+ "Name": "Playermat-Mystic-Cache",
+ "Type": 0,
+ "URL": "http://cloud-3.steamusercontent.com/ugc/2444972799638880413/B59966123EA41649EDCBD614167E590C8C105582/"
+ },
+ {
+ "Name": "Playermat-Rogue-Cache",
+ "Type": 0,
+ "URL": "http://cloud-3.steamusercontent.com/ugc/2444972799638880905/CFC02BF5A6140B9B4B92312AD6DC74D8DD61180B/"
+ },
+ {
+ "Name": "Playermat-Seeker-Cache",
+ "Type": 0,
+ "URL": "http://cloud-3.steamusercontent.com/ugc/2444972799638880905/CFC02BF5A6140B9B4B92312AD6DC74D8DD61180B/"
+ },
+ {
+ "Name": "Playermat-Survivor-Cache",
+ "Type": 0,
+ "URL": "http://cloud-3.steamusercontent.com/ugc/2444972799638880687/EEDF8F8BC3266069FECB09775845BE2501310C17/"
+ },
{
"Name": "NavigationOverlayIcon",
"Type": 0,
diff --git a/objects/LuaScriptState.luascriptstate b/objects/LuaScriptState.luascriptstate
index 5fac6212..f8e751f1 100644
--- a/objects/LuaScriptState.luascriptstate
+++ b/objects/LuaScriptState.luascriptstate
@@ -1 +1 @@
-{"acknowledgedUpgradeVersions":[],"chaosTokensGUID":[],"optionPanel":{"cardLanguage":"en","changePlayAreaImage":false,"playAreaConnectionColor":{"a":1,"b":0.4,"g":0.4,"r":0.4},"playAreaConnections":true,"playAreaSnapTags":true,"showAttachmentHelper":false,"showCleanUpHelper":false,"showCYOA":false,"showDisplacementTool":false,"showDrawButton":false,"showHandHelper":false,"showSearchAssistant":false,"showTitleSplash":true,"useClueClickers":false,"useResourceCounters":"disabled","useSnapTags":true}}
+{"acknowledgedUpgradeVersions":[],"chaosTokensGUID":[],"optionPanel":{"cardLanguage":"en","changePlayAreaImage":false,"playAreaConnectionColor":{"a":1,"b":0.4,"g":0.4,"r":0.4},"playAreaConnections":true,"playAreaSnapTags":true,"showAttachmentHelper":false,"showCleanUpHelper":false,"showCYOA":false,"showDisplacementTool":false,"showDrawButton":false,"showHandHelper":false,"showSearchAssistant":false,"showTitleSplash":true,"useClassTexture":true,"useClueClickers":false,"useResourceCounters":"disabled","useSnapTags":true}}
diff --git a/objects/Playermat1White.8b081b.luascriptstate b/objects/Playermat1White.8b081b.luascriptstate
index ec466f0b..37f3fb4a 100644
--- a/objects/Playermat1White.8b081b.luascriptstate
+++ b/objects/Playermat1White.8b081b.luascriptstate
@@ -1 +1 @@
-{"activeInvestigatorClass":"Neutral","activeInvestigatorId":"00000","isDrawButtonVisible":false,"playerColor":"White","slotData":["any","any","any","Tarot","Hand (left)","Hand (right)","Ally","any","any","any","Accessory","Arcane","Arcane","Body"]}
+{"activeInvestigatorClass":"Neutral","activeInvestigatorId":"00000","isClassTextureEnabled":true,"isDrawButtonVisible":false,"playerColor":"White","slotData":["any","any","any","Tarot","Hand (left)","Hand (right)","Ally","any","any","any","Accessory","Arcane","Arcane","Body"]}
diff --git a/objects/Playermat2Orange.bd0ff4.luascriptstate b/objects/Playermat2Orange.bd0ff4.luascriptstate
index c5d912d1..82227cf3 100644
--- a/objects/Playermat2Orange.bd0ff4.luascriptstate
+++ b/objects/Playermat2Orange.bd0ff4.luascriptstate
@@ -1 +1 @@
-{"activeInvestigatorClass":"Neutral","activeInvestigatorId":"00000","isDrawButtonVisible":false,"playerColor":"Orange","slotData":["any","any","any","Tarot","Hand (left)","Hand (right)","Ally","any","any","any","Accessory","Arcane","Arcane","Body"]}
+{"activeInvestigatorClass":"Neutral","activeInvestigatorId":"00000","isClassTextureEnabled":true,"isDrawButtonVisible":false,"playerColor":"Orange","slotData":["any","any","any","Tarot","Hand (left)","Hand (right)","Ally","any","any","any","Accessory","Arcane","Arcane","Body"]}
diff --git a/objects/Playermat3Green.383d8b.luascriptstate b/objects/Playermat3Green.383d8b.luascriptstate
index 9cc6512e..3f44af1d 100644
--- a/objects/Playermat3Green.383d8b.luascriptstate
+++ b/objects/Playermat3Green.383d8b.luascriptstate
@@ -1 +1 @@
-{"activeInvestigatorClass":"Neutral","activeInvestigatorId":"00000","isDrawButtonVisible":false,"playerColor":"Green","slotData":["any","any","any","Tarot","Hand (left)","Hand (right)","Ally","any","any","any","Accessory","Arcane","Arcane","Body"]}
+{"activeInvestigatorClass":"Neutral","activeInvestigatorId":"00000","isClassTextureEnabled":true,"isDrawButtonVisible":false,"playerColor":"Green","slotData":["any","any","any","Tarot","Hand (left)","Hand (right)","Ally","any","any","any","Accessory","Arcane","Arcane","Body"]}
diff --git a/objects/Playermat4Red.0840d5.luascriptstate b/objects/Playermat4Red.0840d5.luascriptstate
index 71a6f128..74f4e1f9 100644
--- a/objects/Playermat4Red.0840d5.luascriptstate
+++ b/objects/Playermat4Red.0840d5.luascriptstate
@@ -1 +1 @@
-{"activeInvestigatorClass":"Neutral","activeInvestigatorId":"00000","isDrawButtonVisible":false,"playerColor":"Red","slotData":["any","any","any","Tarot","Hand (left)","Hand (right)","Ally","any","any","any","Accessory","Arcane","Arcane","Body"]}
+{"activeInvestigatorClass":"Neutral","activeInvestigatorId":"00000","isClassTextureEnabled":true,"isDrawButtonVisible":false,"playerColor":"Red","slotData":["any","any","any","Tarot","Hand (left)","Hand (right)","Ally","any","any","any","Accessory","Arcane","Arcane","Body"]}
diff --git a/src/arkhamdb/ArkhamDb.ttslua b/src/arkhamdb/ArkhamDb.ttslua
index 5ff08a63..f60d8e94 100644
--- a/src/arkhamdb/ArkhamDb.ttslua
+++ b/src/arkhamdb/ArkhamDb.ttslua
@@ -482,7 +482,6 @@ do
---@param uri table
---@param on_success fun(status, vararg): boolean, any
---@param on_error nil|fun(status, vararg): string
- ---@vararg any
---@return Request
function Request.start(uri, on_success, on_error, ...)
local parameters = table.pack(...)
@@ -497,7 +496,6 @@ do
---@param requests Request[]
---@param on_success fun(content: any, vararg: any)
---@param on_error fun(requests: Request, vararg: any)|nil
- ---@vararg any
function Request.with_all(requests, on_success, on_error, ...)
local parameters = table.pack(...)
diff --git a/src/core/DoomInPlayCounter.ttslua b/src/core/DoomInPlayCounter.ttslua
index c97695e8..07029a75 100644
--- a/src/core/DoomInPlayCounter.ttslua
+++ b/src/core/DoomInPlayCounter.ttslua
@@ -1,10 +1,10 @@
local guidReferenceApi = require("core/GUIDReferenceApi")
-local playermatApi = require("playermat/PlayermatApi")
+local playermatApi = require("playermat/PlayermatApi")
local ZONE, TRASH
-local doomURL = "https://i.imgur.com/EoL7yaZ.png"
-local IGNORE_TAG = "DoomCounter_ignore"
-local TOTAL_PLAY_AREA = {
+local doomURL = "https://i.imgur.com/EoL7yaZ.png"
+local IGNORE_TAG = "DoomCounter_ignore"
+local TOTAL_PLAY_AREA = {
upperLeft = {
x = -9,
z = -35
@@ -67,14 +67,14 @@ end
function removeDoom(options)
if options.Playermats then
local count = removeDoomFromList(playermatApi.searchAroundPlayermat("All"))
- if count > 0 then
+ if count > 0 then
broadcastToAll(count .. " doom removed from playermats.", "White")
end
end
if options.Playarea then
local count = removeDoomFromList(ZONE.getObjects())
- if count > 0 then
+ if count > 0 then
broadcastToAll(count .. " doom removed from play area.", "White")
end
end
@@ -96,7 +96,7 @@ end
-- helper function to check if a position is inside an area
function inArea(point, bounds)
return (point.x < bounds.upperLeft.x
- and point.x > bounds.lowerRight.x
- and point.z > bounds.upperLeft.z
- and point.z < bounds.lowerRight.z)
+ and point.x > bounds.lowerRight.x
+ and point.z > bounds.upperLeft.z
+ and point.z < bounds.lowerRight.z)
end
diff --git a/src/core/DownloadBox.ttslua b/src/core/DownloadBox.ttslua
index 21957367..4f1c650a 100644
--- a/src/core/DownloadBox.ttslua
+++ b/src/core/DownloadBox.ttslua
@@ -18,14 +18,14 @@ function onLoad()
if string.match(notes, "................") == "campaigns/return" then
buttonParameters.position.z = 2
- -- official campaign boxes
+ -- official campaign boxes
elseif string.match(notes, ".........") == "campaigns" or self.hasTag("LargeBox") then
buttonParameters.position.z = 6
buttonParameters.height = 500
buttonParameters.width = 1700
buttonParameters.font_size = 350
- -- investigator boxes
+ -- investigator boxes
elseif string.match(notes, ".............") == "investigators" then
buttonParameters.position.z = 7
buttonParameters.height = 850
diff --git a/src/core/Global.ttslua b/src/core/Global.ttslua
index 073d8487..5e7cbb9b 100644
--- a/src/core/Global.ttslua
+++ b/src/core/Global.ttslua
@@ -1433,11 +1433,15 @@ function applyOptionPanelChange(id, state)
if id == "useSnapTags" then
playermatApi.setLimitSnapsByType(state, "All")
- -- option: Draw 1 button
+ -- option: Draw 1 button
elseif id == "showDrawButton" then
playermatApi.showDrawButton(state, "All")
- -- option: Clickable clue counters
+ -- option: Use class texture
+ elseif id == "useClassTexture" then
+ playermatApi.useClassTexture(state, "All")
+
+ -- option: Clickable clue counters
elseif id == "useClueClickers" then
playermatApi.clickableClues(state, "All")
@@ -1445,40 +1449,40 @@ function applyOptionPanelChange(id, state)
local counter = guidReferenceApi.getObjectByOwnerAndType("Mythos", "MasterClueCounter")
counter.setVar("useClickableCounters", state)
- -- option: Play area connection drawing
+ -- option: Play area connection drawing
elseif id == "playAreaConnections" then
playAreaApi.setConnectionDrawState(state)
- -- option: Play area connection color
+ -- option: Play area connection color
elseif id == "playAreaConnectionColor" then
playAreaApi.setConnectionColor(state)
UI.setAttribute(id, "color", "#" .. Color.new(state):toHex())
- -- option: Play area snap tags
+ -- option: Play area snap tags
elseif id == "playAreaSnapTags" then
playAreaApi.setLimitSnapsByType(state)
- -- option: Show clean up helper
+ -- option: Show clean up helper
elseif id == "showCleanUpHelper" then
spawnOrRemoveHelper(state, "Clean Up Helper", { -66, 1.53, 46 })
- -- option: Show hand helper for each player
+ -- option: Show hand helper for each player
elseif id == "showHandHelper" then
spawnOrRemoveHelperForPlayermats("Hand Helper", state)
- -- option: Show search assistant for each player
+ -- option: Show search assistant for each player
elseif id == "showSearchAssistant" then
spawnOrRemoveHelperForPlayermats("Search Assistant", state)
- -- option: Show attachment helper
+ -- option: Show attachment helper
elseif id == "showAttachmentHelper" then
spawnOrRemoveHelper(state, "Attachment Helper", { -62, 1.4, 0 })
- -- option: Show CYOA campaign guides
+ -- option: Show CYOA campaign guides
elseif id == "showCYOA" then
spawnOrRemoveHelper(state, "CYOA Campaign Guides", { 39, 1.3, -20 })
- -- option: Show displacement tool
+ -- option: Show displacement tool
elseif id == "showDisplacementTool" then
spawnOrRemoveHelper(state, "Displacement Tool", { -57, 1.53, 46 })
end
@@ -1580,6 +1584,7 @@ function onClick_defaultSettings()
showHandHelper = false,
showSearchAssistant = false,
showTitleSplash = true,
+ useClassTexture = true,
useClueClickers = false,
useResourceCounters = "disabled",
useSnapTags = true
diff --git a/src/core/PlayArea.ttslua b/src/core/PlayArea.ttslua
index 92f265ca..22447b3f 100644
--- a/src/core/PlayArea.ttslua
+++ b/src/core/PlayArea.ttslua
@@ -133,7 +133,7 @@ function onObjectPickUp(_, object)
local metadata = JSON.decode(object.getGMNotes()) or {}
if metadata.type == "Location" then
-- onCollisionExit sometimes comes 1 frame after onObjectPickUp (rather than before it or in
- -- the same frame). This causes a mismatch in the data between dragging the on-table, and
+ -- the same frame). This causes a mismatch in the data between dragging the on-table, and
-- that one frame draws connectors on the card which then show up as shadows for snap points.
-- Waiting ensures we always do thing in the expected Exit->PickUp order
Wait.frames(function()
@@ -240,7 +240,7 @@ end
---@param card tts__Object Card to (maybe) stop tracking
function maybeUntrackLocation(card)
-- Locked objects no longer collide (hence triggering an exit event) but are still in the play
- -- area. If the object is now locked, don't remove it.
+ -- area. If the object is now locked, don't remove it.
if locations[card.getGUID()] ~= nil and not card.locked then
locations[card.getGUID()] = nil
rebuildConnectionList()
@@ -415,7 +415,7 @@ end
---@param target tts__Object Target card object to connect
---@param vectorOwner tts__Object The object which these lines will be set to. Used for relative
--- positioning and scaling, as well as highlighting connections during a drag operation
----@param lines table List of vector line elements. Mutable, will be updated to add this connector
+---@param lines table List of vector line elements. Mutable, will be updated to add this connector
function addOneWayVector(origin, target, vectorOwner, lines)
-- Start with the BiDi then add the arrow lines to it
addBidirectionalVector(origin, target, vectorOwner, lines)
@@ -445,9 +445,9 @@ end
-- Draws an arrowhead at the given position.
---@param arrowheadPos tts__Vector Centerpoint of the arrowhead to draw (NOT the tip of the arrow)
---@param originPos tts__Vector Origin point of the connection, used to position the arrow arms
----@param vectorOwner tts__Object The object which these lines will be set to. Used for relative
+---@param vectorOwner tts__Object The object which these lines will be set to. Used for relative
--- positioning and scaling, as well as highlighting connections during a drag operation
----@param lines table List of vector line elements. Mutable, will be updated to add this arrow
+---@param lines table List of vector line elements. Mutable, will be updated to add this arrow
function addArrowLines(arrowheadPos, originPos, vectorOwner, lines)
local arrowArm1 = Vector(arrowheadPos):moveTowards(originPos, ARROW_ARM_LENGTH):sub(arrowheadPos):rotateOver("y", -1 * ARROW_ANGLE):add(arrowheadPos)
local arrowArm2 = Vector(arrowheadPos):moveTowards(originPos, ARROW_ARM_LENGTH):sub(arrowheadPos):rotateOver("y", ARROW_ANGLE):add(arrowheadPos)
@@ -462,7 +462,7 @@ function addArrowLines(arrowheadPos, originPos, vectorOwner, lines)
})
end
--- count victory points on locations in play area
+-- Count victory points from locations in play area
---@param highlightOff boolean True if highlighting should be enabled
---@return. Returns the total amount of VP found in the play area
function countVP(highlightOff)
@@ -488,14 +488,15 @@ function countVP(highlightOff)
return totalVP
end
--- checks if a card has clues on it, returns true if clues are on it
+-- Checks if a card has clues on it
---@param card tts__Object Card to check for clues
+---@return boolean hasClues True if card has clues on it
function cardHasClues(card)
local searchResult = searchLib.onObject(card, "isClue")
return #searchResult > 0
end
--- highlights all locations in the play area without metadata
+-- Highlights all locations in the play area without metadata
---@param state boolean True if highlighting should be enabled
function highlightMissingData(state)
for i, obj in pairs(missingData) do
@@ -549,7 +550,7 @@ function shiftContents(playerColor, direction)
Wait.time(drawBaseConnections, 0.1)
end
--- sets the image of the playarea
+-- Sets the image of the playarea
---@param newURL string URL for the new surface image
function updateSurface(newURL)
local customInfo = self.getCustomObject()
@@ -569,6 +570,7 @@ function updateSurface(newURL)
guid = customDataHelper.getGUID()
end
+ self.script_state = onSave()
self.reload()
if guid ~= nil then
@@ -646,7 +648,7 @@ function round(num, numDecimalPlaces)
return math.floor(num * mult + 0.5) / mult
end
--- rebuilds local snap points (could be useful in the future again)
+-- Rebuilds local snap points (could be useful in the future again)
function buildSnaps()
local upperleft = { x = 1.53, z = -1.09 }
local lowerright = { x = -1.53, z = 1.55 }
diff --git a/src/core/PlayAreaSelector.ttslua b/src/core/PlayAreaSelector.ttslua
index e5431e1a..fe32286f 100644
--- a/src/core/PlayAreaSelector.ttslua
+++ b/src/core/PlayAreaSelector.ttslua
@@ -192,7 +192,7 @@ end
function getPlainName(str)
-- remove prefix type 1
str = str:gsub("%w+%-%w%s%-%s", "") -- matches "II-B - Thousand Shapes of Horror 1"
-
+
-- remove prefix type 2
str = str:gsub("%w+%-%w%s", "") -- matches "59-Z Congress of Keys 1"
diff --git a/src/playermat/Playermat.ttslua b/src/playermat/Playermat.ttslua
index 6f2db69c..653308de 100644
--- a/src/playermat/Playermat.ttslua
+++ b/src/playermat/Playermat.ttslua
@@ -60,6 +60,16 @@ local buttonParameters = {
font_size = 180
}
+-- table of texture URLs
+local nameToTexture = {
+ Guardian = "http://cloud-3.steamusercontent.com/ugc/2444972799638881117/169F4520A94FB186B54E0F2BF4BAC809844C923E/",
+ Mystic = "http://cloud-3.steamusercontent.com/ugc/2444972799638880413/B59966123EA41649EDCBD614167E590C8C105582/",
+ Neutral = "http://cloud-3.steamusercontent.com/ugc/2462982115659543571/5D778EA4BC682DAE97E8F59A991BCF8CB3979B04/",
+ Rogue = "http://cloud-3.steamusercontent.com/ugc/2444972799638880905/CFC02BF5A6140B9B4B92312AD6DC74D8DD61180B/",
+ Seeker = "http://cloud-3.steamusercontent.com/ugc/2444972799638880905/CFC02BF5A6140B9B4B92312AD6DC74D8DD61180B/",
+ Survivor = "http://cloud-3.steamusercontent.com/ugc/2444972799638880687/EEDF8F8BC3266069FECB09775845BE2501310C17/"
+}
+
-- translation table for slot names to characters for special font
local slotNameToChar = {
["any"] = "",
@@ -86,12 +96,11 @@ local defaultSlotData = {
-- global variables for access
activeInvestigatorClass = "Neutral"
activeInvestigatorId = "00000"
-
-local isDrawButtonVisible = false
-
--- global variable to report "Dream-Enhancing Serum" status
hasDES = false
+local isClassTextureEnabled = true
+local isDrawButtonVisible = false
+
-- table of type-object reference pairs of all owned objects
local ownedObjects = {}
local matColor = self.getMemo()
@@ -100,6 +109,7 @@ function onSave()
return JSON.encode({
activeInvestigatorClass = activeInvestigatorClass,
activeInvestigatorId = activeInvestigatorId,
+ isClassTextureEnabled = isClassTextureEnabled,
isDrawButtonVisible = isDrawButtonVisible,
playerColor = playerColor,
slotData = slotData
@@ -111,6 +121,7 @@ function onLoad(savedData)
local loadedData = JSON.decode(savedData)
activeInvestigatorClass = loadedData.activeInvestigatorClass
activeInvestigatorId = loadedData.activeInvestigatorId
+ isClassTextureEnabled = loadedData.isClassTextureEnabled
isDrawButtonVisible = loadedData.isDrawButtonVisible
playerColor = loadedData.playerColor
slotData = loadedData.slotData
@@ -879,10 +890,12 @@ function maybeUpdateActiveInvestigator(card)
notes.combatIcons,
notes.agilityIcons
})
+ updateTexture()
elseif activeInvestigatorId ~= "00000" then
activeInvestigatorClass = "Neutral"
activeInvestigatorId = "00000"
ownedObjects.InvestigatorSkillTracker.call("updateStats", { 1, 1, 1, 1 })
+ updateTexture()
else
return
end
@@ -936,7 +949,7 @@ function maybeUpdateActiveInvestigator(card)
count[type] = count[type] + 1
if count[type] > 2 then
- print("More than two extra tokens of the same type are not supported.")
+ printToColor("More than two extra tokens of the same type are not supported.", playerColor)
else
local localSpawnPos = tokenSpawnPos[type][count[type]]
local globalSpawnPos = self.positionToWorld(localSpawnPos):add(Vector(0, 0.2, 0))
@@ -950,6 +963,34 @@ function maybeUpdateActiveInvestigator(card)
end
end
+-- updates the texture of the playermat
+---@param overrideName? string Force a specific texture
+function updateTexture(overrideName)
+ local name = "Neutral"
+
+ -- use class specific texture if enabled
+ if isClassTextureEnabled then
+ name = activeInvestigatorClass
+ end
+
+ -- get new texture URL
+ local newUrl = nameToTexture[name]
+
+ -- override name if valid
+ if nameToTexture[overrideName] then
+ newUrl = nameToTexture[overrideName]
+ end
+
+ -- apply texture
+ local customInfo = self.getCustomObject()
+ if customInfo.image ~= newUrl then
+ self.script_state = onSave()
+ customInfo.image = newUrl
+ self.setCustomObject(customInfo)
+ self.reload()
+ end
+end
+
---------------------------------------------------------
-- manipulation of owned objects
---------------------------------------------------------
@@ -1083,6 +1124,14 @@ function clickableClues(showCounter)
end
end
+-- Toggles the use of class textures
+---@param state boolean Whether the class texture should be used or not
+function useClassTexture(state)
+ if state == isClassTextureEnabled then return end
+ isClassTextureEnabled = state
+ updateTexture()
+end
+
-- removes all clues (moving tokens to the trash and setting counters to 0)
function removeClues()
ownedObjects.ClueCounter.call("removeAllClues", ownedObjects.Trash)
diff --git a/src/playermat/PlayermatApi.ttslua b/src/playermat/PlayermatApi.ttslua
index 284a2f36..aab81bb7 100644
--- a/src/playermat/PlayermatApi.ttslua
+++ b/src/playermat/PlayermatApi.ttslua
@@ -225,6 +225,15 @@ do
end
end
+ -- Toggles the use of class textures for the requested playermat
+ ---@param state boolean Whether the class texture should be used or not
+ ---@param matColor string Color of the playermat - White, Orange, Green, Red or All
+ PlayermatApi.useClassTexture = function(state, matColor)
+ for _, mat in pairs(getMatForColor(matColor)) do
+ mat.call("useClassTexture", state)
+ end
+ end
+
-- Removes all clues (to the trash for tokens and counters set to 0) for the requested playermat
---@param matColor string Color of the playermat - White, Orange, Green, Red or All
PlayermatApi.removeClues = function(matColor)
diff --git a/xml/Global/OptionPanel.xml b/xml/Global/OptionPanel.xml
index d6b0b6dc..ab27fd34 100644
--- a/xml/Global/OptionPanel.xml
+++ b/xml/Global/OptionPanel.xml
@@ -273,6 +273,21 @@
+
+
+
+
+ Use class-specific texture
+
+
+
+
+
+
+
@@ -308,7 +323,7 @@
-
+