diff --git a/src/accessories/SearchAssistant.ttslua b/src/accessories/SearchAssistant.ttslua index e1f305c4..8cd9ef67 100644 --- a/src/accessories/SearchAssistant.ttslua +++ b/src/accessories/SearchAssistant.ttslua @@ -1,7 +1,7 @@ local playmatApi = require("playermat/PlaymatApi") -- forward declaration of variables that are used across functions -local matColor, handColor, setAsidePosition, setAsideRotation, drawDeckPosition +local matColor, handColor, setAsidePosition, setAsideRotation, drawDeckPosition, topCardDetected local quickParameters = {} quickParameters.function_owner = self @@ -101,15 +101,18 @@ end function startSearch(messageColor, number) matColor = playmatApi.getMatColorByPosition(self.getPosition()) handColor = playmatApi.getPlayerColor(matColor) + topCardDetected = false -- get draw deck - local drawDeck = playmatApi.getDrawDeck(matColor) - if drawDeck == nil then + local deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + if deckAreaObjects.draw == nil then printToColor(matColor .. " draw deck could not be found!", messageColor, "Red") return end - drawDeckPosition = drawDeck.getPosition() + -- get bounds to know the height of the deck + local bounds = deckAreaObjects.draw.getBounds() + drawDeckPosition = bounds.center + Vector(0, bounds.size.y / 2 + 0.2, 0) printToColor("Place target(s) of search on set aside hand.", messageColor, "Green") -- get playmat orientation @@ -124,23 +127,26 @@ function startSearch(messageColor, number) setAsidePosition = handData.position + offset * handData.right setAsideRotation = { handData.rotation.x, handData.rotation.y + 180, 180 } + -- set y-value + setAsidePosition.y = 1.5 + for i = #handCards, 1, -1 do - handCards[i].setPosition(setAsidePosition - Vector(0, i * 0.3, 0)) + handCards[i].setPosition(setAsidePosition + Vector(0, (#handCards - i) * 0.1, 0)) handCards[i].setRotation(setAsideRotation) end -- handling for Norman Withers - for _, v in ipairs(searchArea(drawDeckPosition)) do - local object = v.hit_object - if object.tag == "Card" and not object.is_face_down then - object.flip() - Wait.time(function() drawDeck = playmatApi.getDrawDeck(matColor) end, 1) - break - end + if deckAreaObjects.topCard then + deckAreaObjects.topCard.flip() + topCardDetected = true end - Wait.time(function() drawDeck.deal(number, handColor) end, 1) searchView() + + Wait.time(function() + deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + deckAreaObjects.draw.deal(number, handColor) + end, 1) end -- place handCards back into deck and optionally shuffle @@ -148,28 +154,19 @@ function endSearch(_, _, isRightClick) local handCards = Player[handColor].getHandObjects() for i = #handCards, 1, -1 do - handCards[i].setPosition(drawDeckPosition + Vector(0, 6 - i * 0.3, 0)) + handCards[i].setPosition(drawDeckPosition + Vector(0, (#handCards - i) * 0.1, 0)) handCards[i].setRotation(setAsideRotation) end - if not isRightClick then - Wait.time(function() - local deck = playmatApi.getDrawDeck(matColor) - if deck ~= nil then - deck.shuffle() - end - end, 2) - end - -- draw set aside cards (from the ground!) - for _, v in ipairs(searchArea(setAsidePosition - Vector(0, 5, 0))) do + for _, v in ipairs(searchArea(setAsidePosition)) do local obj = v.hit_object - if obj.tag == "Deck" then + if obj.type == "Deck" then Wait.time(function() obj.deal(#obj.getObjects(), handColor) end, 1) break - elseif obj.tag == "Card" then + elseif obj.type == "Card" then obj.setPosition(Player[handColor].getHandTransform().position) obj.flip() break @@ -177,6 +174,21 @@ function endSearch(_, _, isRightClick) end normalView() + + -- delay is to wait for cards to enter deck + if not isRightClick then + Wait.time(function() + local deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + if deckAreaObjects.draw then + deckAreaObjects.draw.shuffle() + end + end, #handCards * 0.1) + end + + -- Norman Withers handling + if topCardDetected then + Wait.time(function() playmatApi.flipTopCardFromDeck(matColor) end, #handCards * 0.1) + end end -- utility function diff --git a/src/playercards/cards/ShortSupply.ttslua b/src/playercards/cards/ShortSupply.ttslua index 102696ae..8910ce3a 100644 --- a/src/playercards/cards/ShortSupply.ttslua +++ b/src/playercards/cards/ShortSupply.ttslua @@ -9,7 +9,8 @@ function shortSupply(color) local matColor = playmatApi.getMatColorByPosition(self.getPosition()) -- get draw deck and discard position - local drawDeck = playmatApi.getDrawDeck(matColor) + local deckAreaObjects = playmatApi.getDeckAreaObjects(matColor) + local drawDeck = deckAreaObjects.draw local discardPos = playmatApi.getDiscardPosition(matColor) -- error handling diff --git a/src/playermat/Playmat.ttslua b/src/playermat/Playmat.ttslua index 5465a9cf..21fedb74 100644 --- a/src/playermat/Playmat.ttslua +++ b/src/playermat/Playmat.ttslua @@ -62,19 +62,19 @@ local DECK_DISCARD_AREA = { }, center = { x = -1.82, - y = 0.1, + y = 0.5, z = 0.305 }, size = { x = 0.4, - y = 1, + y = 3, z = 1.1 } } -- local position of draw and discard pile -local DRAW_DECK_POSITION = { x = -1.82, y = 0, z = 0 } -local DISCARD_PILE_POSITION = { x = -1.82, y = 0, z = 0.61 } +local DRAW_DECK_POSITION = { x = -1.82, y = 0.1, z = 0 } +local DISCARD_PILE_POSITION = { x = -1.82, y = 0.1, z = 0.61 } -- global position of encounter discard pile local ENCOUNTER_DISCARD_POSITION = { x = -3.85, y = 1.5, z = 10.38} @@ -418,81 +418,108 @@ end -- draw X cards (shuffle discards if necessary) function drawCardsWithReshuffle(numCards) - getDrawDiscardDecks() + local deckAreaObjects = getDeckAreaObjects() -- Norman Withers handling - if string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" then - local harbinger = false - if topCard ~= nil and topCard.getName() == "The Harbinger" then + local harbinger = false + if deckAreaObjects.topCard and deckAreaObjects.topCard.getName() == "The Harbinger" then + harbinger = true + elseif deckAreaObjects.draw and not deckAreaObjects.draw.is_face_down then + local cards = deckAreaObjects.draw.getObjects() + if cards[#cards].name == "The Harbinger" then harbinger = true - elseif drawDeck ~= nil and not drawDeck.is_face_down then - local cards = drawDeck.getObjects() - if cards[#cards].name == "The Harbinger" then - harbinger = true - end end + end - if harbinger then - printToColor("The Harbinger is on top of your deck, not drawing cards", messageColor) + if harbinger then + printToColor("The Harbinger is on top of your deck, not drawing cards", messageColor) + return + end + + local topCardDetected = false + if deckAreaObjects.topCard ~= nil then + deckAreaObjects.topCard.deal(1, playerColor) + topCardDetected = true + numCards = numCards - 1 + if numCards == 0 then + flipTopCardFromDeck() return end - - if topCard ~= nil then - topCard.deal(numCards, playerColor) - numCards = numCards - 1 - if numCards == 0 then return end - end end local deckSize = 1 - if drawDeck == nil then + if deckAreaObjects.draw == nil then deckSize = 0 - elseif drawDeck.tag == "Deck" then - deckSize = #drawDeck.getObjects() + elseif deckAreaObjects.draw.type == "Deck" then + deckSize = #deckAreaObjects.draw.getObjects() end if deckSize >= numCards then drawCards(numCards) - return + if topCardDetected then flipTopCardFromDeck() end + else + drawCards(deckSize) + if deckAreaObjects.discard ~= nil then + shuffleDiscardIntoDeck() + Wait.time(function() + drawCards(numCards - deckSize) + if topCardDetected then flipTopCardFromDeck() end + end, 1) + end + printToColor("Take 1 horror (drawing card from empty deck)", messageColor) end - - drawCards(deckSize) - if discardPile ~= nil then - shuffleDiscardIntoDeck() - Wait.time(|| drawCards(numCards - deckSize), 1) - end - printToColor("Take 1 horror (drawing card from empty deck)", messageColor) end --- get the draw deck and discard pile objects -function getDrawDiscardDecks() - drawDeck = nil - discardPile = nil - topCard = nil - +-- get the draw deck and discard pile objects and returns the references +function getDeckAreaObjects() + local deckAreaObjects = {} for _, object in ipairs(searchDeckAndDiscardArea(isCardOrDeck)) do if self.positionToLocal(object.getPosition()).z > 0.5 then - discardPile = object + deckAreaObjects.discard = object -- Norman Withers handling - elseif string.match(activeInvestigatorId, "%d%d%d%d%d") == "08004" and not object.is_face_down then - topCard = object + elseif object.type == "Card" and not object.is_face_down then + deckAreaObjects.topCard = object else - drawDeck = object + deckAreaObjects.draw = object end end + return deckAreaObjects end function drawCards(numCards) - if drawDeck == nil then return end - drawDeck.deal(numCards, playerColor) + local deckAreaObjects = getDeckAreaObjects() + if deckAreaObjects.draw then + deckAreaObjects.draw.deal(numCards, playerColor) + end end function shuffleDiscardIntoDeck() - if not discardPile.is_face_down then discardPile.flip() end - discardPile.shuffle() - discardPile.setPositionSmooth(self.positionToWorld(DRAW_DECK_POSITION), false, false) - drawDeck = discardPile - discardPile = nil + local deckAreaObjects = getDeckAreaObjects() + if not deckAreaObjects.discard.is_face_down then + deckAreaObjects.discard.flip() + end + deckAreaObjects.discard.shuffle() + deckAreaObjects.discard.setPositionSmooth(self.positionToWorld(DRAW_DECK_POSITION), false, false) +end + +-- utility function for Norman Withers to flip the top card to the revealed side +function flipTopCardFromDeck() + log("called") + Wait.time(function() + local deckAreaObjects = getDeckAreaObjects() + if deckAreaObjects.topCard then + return + elseif deckAreaObjects.draw then + if deckAreaObjects.draw.type == "Card" then + deckAreaObjects.draw.flip() + else + -- get bounds to know the height of the deck + local bounds = deckAreaObjects.draw.getBounds() + local pos = bounds.center + Vector(0, bounds.size.y / 2 + 0.2, 0) + deckAreaObjects.draw.takeObject({ position = pos, flip = true }) + end + end + end, 0.1) end -- discard a random non-hidden card from hand diff --git a/src/playermat/PlaymatApi.ttslua b/src/playermat/PlaymatApi.ttslua index a051cfe6..a8eeef0b 100644 --- a/src/playermat/PlaymatApi.ttslua +++ b/src/playermat/PlaymatApi.ttslua @@ -54,12 +54,19 @@ do end end - -- Returns the draw deck of the requested playmat + -- Performs a search of the deck area of the requested playmat and returns the result as table ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") - PlaymatApi.getDrawDeck = function(matColor) + PlaymatApi.getDeckAreaObjects = function(matColor) for _, mat in pairs(getMatForColor(matColor)) do - mat.call("getDrawDiscardDecks") - return mat.getVar("drawDeck") + return mat.call("getDeckAreaObjects") + end + end + + -- Flips the top card of the deck (useful after deck manipulation for Norman Withers) + ---@param matColor String Color of the playmat - White, Orange, Green or Red (does not support "All") + PlaymatApi.flipTopCardFromDeck = function(matColor) + for _, mat in pairs(getMatForColor(matColor)) do + return mat.call("flipTopCardFromDeck") end end