diff --git a/src/playercards/AllCardsBag.ttslua b/src/playercards/AllCardsBag.ttslua index 0e961400..652d4f70 100644 --- a/src/playercards/AllCardsBag.ttslua +++ b/src/playercards/AllCardsBag.ttslua @@ -380,8 +380,9 @@ end -- Constructs a list of available basic weaknesses by starting with the full pool of basic -- weaknesses then removing any which are currently in the play or deck construction areas +---@param traits? string Trait(s) to use as filter ---@return table: Array of weakness IDs which are valid to choose from -function buildAvailableWeaknesses() +function buildAvailableWeaknesses(traits) local weaknessesInPlay = {} local allObjects = getAllObjects() for _, object in ipairs(allObjects) do @@ -399,7 +400,32 @@ function buildAvailableWeaknesses() if (weaknessesInPlay[weaknessId] ~= nil and weaknessesInPlay[weaknessId] > 0) then weaknessesInPlay[weaknessId] = weaknessesInPlay[weaknessId] - 1 else - table.insert(availableWeaknesses, weaknessId) + if traits then + -- split the string into separate traits (separated by "|") + local allowedTraits = {} + for str in traits:gmatch("([^|]+)") do + -- remove dots + str = str:gsub("[%.]", "") + + -- remove leading and trailing whitespace + str = str:match("^%s*(.-)%s*$") + + -- make sure string ends with a dot + str = string.lower(str .. ".") + table.insert(allowedTraits, str) + end + + -- make sure the trait is present on the weakness + local card = cardIdIndex[weaknessId] + for _, allowedTrait in ipairs(allowedTraits) do + if string.contains(string.lower(card.metadata.traits), allowedTrait) then + table.insert(availableWeaknesses, weaknessId) + break + end + end + else + table.insert(availableWeaknesses, weaknessId) + end end end return availableWeaknesses diff --git a/src/playercards/AllCardsBagApi.ttslua b/src/playercards/AllCardsBagApi.ttslua index f2f4cc3b..154aed39 100644 --- a/src/playercards/AllCardsBagApi.ttslua +++ b/src/playercards/AllCardsBagApi.ttslua @@ -25,7 +25,7 @@ do return getAllCardsBag().call("getCardById", { id = id }) end - -- Gets a random basic weakness from the bag. Once a given ID has been returned it + -- Gets a random basic weakness from the bag. Once a given ID has been returned it -- will be removed from the list and cannot be selected again until a reload occurs -- or the indexes are rebuilt, which will refresh the list to include all weaknesses. ---@return string: ID of the selected weakness @@ -80,6 +80,14 @@ do return returnCopyOfList(getAllCardsBag().call("getCardsByCycle", { cycle = cycle, sortByMetadata = sortByMetadata })) end + -- Constructs a list of available basic weaknesses by starting with the full pool of basic + -- weaknesses then removing any which are currently in the play or deck construction areas + ---@param traits? string Trait(s) to use as filter + ---@return table: Array of weakness IDs which are valid to choose from + AllCardsBagApi.buildAvailableWeaknesses = function(traits) + return returnCopyOfList(getAllCardsBag().call("buildAvailableWeaknesses", traits)) + end + AllCardsBagApi.getUniqueWeaknesses = function() return returnCopyOfList(getAllCardsBag().call("getUniqueWeaknesses")) end diff --git a/src/playercards/PlayerCardPanel.ttslua b/src/playercards/PlayerCardPanel.ttslua index dcefb509..09587e62 100644 --- a/src/playercards/PlayerCardPanel.ttslua +++ b/src/playercards/PlayerCardPanel.ttslua @@ -5,6 +5,8 @@ local allCardsBagApi = require("playercards/AllCardsBagApi") local arkhamDb = require("arkhamdb/ArkhamDb") local spawnBag = require("playercards/SpawnBag") +local lastWeaknessTrait = "Madness" + -- Size and position information for the three rows of class buttons local CIRCLE_BUTTON_SIZE = 250 local CLASS_BUTTONS_X_OFFSET = 0.1325 @@ -224,9 +226,10 @@ function createWeaknessButtons() weaknessButtonParams.tooltip = "All Weaknesses" weaknessButtonParams.position = buttonPos self.createButton(weaknessButtonParams) + buttonPos.x = buttonPos.x + MISC_BUTTONS_X_OFFSET weaknessButtonParams.click_function = "spawnRandomWeakness" - weaknessButtonParams.tooltip = "Random Basic Weakness" + weaknessButtonParams.tooltip = "Random Basic Weakness\nRight-click to specify a trait" weaknessButtonParams.position = buttonPos self.createButton(weaknessButtonParams) end @@ -361,9 +364,9 @@ function createXML(showOtherCardsButton) alignment = "MiddleLeft", horizontalOverflow = "wrap", text = "• Select a group to place cards\n" .. - "• Copy the cards you want for your deck\n" .. - "• Select a new group to clear the placed cards and see new ones\n" .. - "• Clear to remove all cards" + "• Copy the cards you want for your deck\n" .. + "• Select a new group to clear the placed cards and see new ones\n" .. + "• Clear to remove all cards" } } } @@ -775,13 +778,32 @@ function spawnWeaknesses() }) end -function spawnRandomWeakness() +function spawnRandomWeakness(_, playerColor, isRightClick) prepareToPlaceCards() - local weaknessId = allCardsBagApi.getRandomWeaknessId() - if (weaknessId == nil) then - broadcastToAll("All basic weaknesses are in play!", { 0.9, 0.2, 0.2 }) - return + + if not isRightClick then + local weaknessId = allCardsBagApi.getRandomWeaknessId() + if weaknessId == nil then + broadcastToAll("All basic weaknesses are in play!", { 0.9, 0.2, 0.2 }) + else + spawnSingleWeakness(weaknessId) + end + else + Player[playerColor].showInputDialog("Specify a trait for the weakness (split multiple eligible traits with '|'):", lastWeaknessTrait, + function(text) + lastWeaknessTrait = text + local availableWeaknesses = allCardsBagApi.buildAvailableWeaknesses(text) + if #availableWeaknesses > 0 then + spawnSingleWeakness(availableWeaknesses[math.random(#availableWeaknesses)]) + else + broadcastToAll("No matching weakness available!", { 0.9, 0.2, 0.2 }) + end + end) end +end + +-- spawn the random weakness +function spawnSingleWeakness(weaknessId) spawnBag.spawn({ name = "randomWeakness", cards = { weaknessId },