SCED/src/playercards/ClassCardContainer.ttslua
Kevin 83f75c2318 Initial code extraction and commit
Initialize the SCED repository by moving most scripts from TTS objects 
to separate files which are included via require().
2021-10-06 20:37:31 -07:00

272 lines
8.4 KiB
Plaintext

-- Class card bag implementation. Mimics the behavior of the previous SCED
-- card memory bags, but spawns cards from the All Cards Bag instead.
--
-- The All Cards Bag handles indexing of the player cards by class and level, as
-- well as sorting those lists. See that object for more information.
local allCardsBagGuid = "15bb07"
-- Lines which define the card layout area. The X threshold is shared, basic
-- cards have Z > 47 while upgrades have Z < -46
-- Note that the SCED table is rotated, making X the vertical (up the table)
-- axis and Z the side-to-side axis
local CARD_AREA_X_THRESHOLD = 22
local CARD_AREA_BASIC_Z_THRESHOLD = 47
local CARD_AREA_UPGRADED_Z_THRESHOLD = -46
local skillCount = 0
local eventCount = 0
local assetCount = 0
-- Coordinates to begin laying out cards to match the reserved areas of the
-- table. Cards will lay out horizontally, then create additional rows
local startPositions = {
upgrades = {
skill = Vector(58.09966, 1.36, -47.42),
event = Vector(52.94421, 1.36, -47.42),
asset = Vector(40.29005, 1.36, -47.42),
},
level0 = {
skill = Vector(58.38383, 1.36, 92.39036),
event = Vector(53.22857, 1.36, 92.44123),
asset = Vector(40.9602, 1.36, 92.44869),
},
}
-- Amount to shift for the next card (zShift) or next row of cards (xShift)
-- Note that the table rotation is weird, and the X axis is vertical while the
-- Z axis is horizontal
local zShift = -2.29998
local xShift = -3.66572
local yRotation = 270
local cardsPerRow = 20
-- Tracks cards which are placed by this "bag" so they can be recalled
local placedCardGuids = { }
local placedCardsCount = 0
-- In order to mimic the behavior of the previous memory buttons we use a
-- a temporary bag when recalling objects. This bag is tiny and transparent,
-- and will be placed at the same location as this object. Once all placed
-- cards are recalled bag to this bag, it will be destroyed
local recallBag = {
Name = "Bag",
Transform = {
scaleX = 0.01,
scaleY = 0.01,
scaleZ = 0.01,
},
ColorDiffuse = {
r = 0,
g = 0,
b = 0,
a = 0,
},
Locked = true,
Grid = true,
Snap = false,
Tooltip = false,
}
function onLoad(savedData)
createPlaceRecallButtons()
placedCardGuids = { }
placedCardCount = 0
if (savedData ~= nil) then
local saveState = JSON.decode(savedData)
if (saveState.placedCards ~= nil) then
placedCardGuids = saveState.placedCards
end
end
end
function onSave()
local saveState = {
placedCards = placedCardGuids,
}
return JSON.encode(saveState)
end
--Creates recall and place buttons
function createPlaceRecallButtons()
self.createButton({
label="Place", click_function="buttonClick_place", function_owner=self,
position={1,0.1,2.1}, rotation={0,0,0}, height=350, width=800,
font_size=250, color={0,0,0}, font_color={1,1,1}
})
self.createButton({
label="Recall", click_function="buttonClick_recall", function_owner=self,
position={-1,0.1,2.1}, rotation={0,0,0}, height=350, width=800,
font_size=250, color={0,0,0}, font_color={1,1,1}
})
end
-- Spawns the set of cards identified by this objects Name (which should hold
-- the class) and description (whether to spawn basic cards or upgraded)
function buttonClick_place()
-- Cards already on the table, don't spawn more
if (placedCardCount > 0) then
return
end
local cardClass = self.getName()
local isUpgraded = false
if (self.getDescription() == "Upgrades") then
isUpgraded = true
end
skillCount = 0
eventCount = 0
assetCount = 0
local allCardsBag = getObjectFromGUID(allCardsBagGuid)
local cardList = allCardsBag.call("getCardsByClassAndLevel", {class = cardClass, upgraded = isUpgraded})
placeCards(cardList)
end
-- Spawn all cards from the returned index
function placeCards(cardIdList)
local allCardsBag = getObjectFromGUID(allCardsBagGuid)
local indexReady = allCardsBag.call("isIndexReady")
if (not indexReady) then
broadcastToAll("Still loading player cards, please try again in a few seconds", {0.9, 0.2, 0.2})
return
end
for _, cardId in ipairs(cardIdList) do
local card = allCardsBag.call("getCardById", { id = cardId })
placeCard(card.data, card.metadata)
end
end
function placeCard(cardData, cardMetadata)
local destinationPos
if (cardMetadata.type == "Skill") then
destinationPos = getSkillPosition(cardMetadata.level > 0)
elseif (cardMetadata.type == "Event") then
destinationPos = getEventPosition(cardMetadata.level > 0)
elseif (cardMetadata.type == "Asset") then
destinationPos = getAssetPosition(cardMetadata.level > 0)
end
-- Clear the GUID from the card's data so it will get a new GUID on spawn.
-- This solves the issue of duplicate GUIDs being spawned and causing problems
-- with recall
cardData.GUID = nil
local spawnedCard = spawnObjectData({
data = cardData,
position = destinationPos,
rotation = {0, yRotation, 0},
callback_function = recordPlacedCard})
end
-- Returns the table position where the next skill should be placed
-- Param isUpgraded: True if it's an upgraded card (right side of the table),
-- false for a Level 0 card (left side of table)
function getSkillPosition(isUpgraded)
local skillPos
if (isUpgraded) then
skillPos = startPositions.upgrades.skill:copy()
else
skillPos = startPositions.level0.skill:copy()
end
local shift = Vector(div(skillCount, cardsPerRow) * xShift, 0, (skillCount % cardsPerRow) * zShift)
skillPos:add(shift)
skillCount = skillCount + 1
return skillPos
end
-- Returns the table position where the next event should be placed
-- Param isUpgraded: True if it's an upgraded card (right side of the table),
-- false for a Level 0 card (left side of table)
function getEventPosition(isUpgraded)
local eventPos
if (isUpgraded) then
eventPos = startPositions.upgrades.event:copy()
else
eventPos = startPositions.level0.event:copy()
end
local shift = Vector(div(eventCount, cardsPerRow) * xShift, 0, (eventCount % cardsPerRow) * zShift)
eventPos:add(shift)
eventCount = eventCount + 1
return eventPos
end
-- Returns the table position where the next asset should be placed
-- Param isUpgraded: True if it's an upgraded card (right side of the table),
-- false for a Level 0 card (left side of table)
function getAssetPosition(isUpgraded)
local assetPos
if (isUpgraded) then
assetPos = startPositions.upgrades.asset:copy()
else
assetPos = startPositions.level0.asset:copy()
end
local shift = Vector(div(assetCount, cardsPerRow) * xShift, 0, (assetCount % cardsPerRow) * zShift)
assetPos:add(shift)
assetCount = assetCount + 1
return assetPos
end
-- Callback function which adds a spawned card to the tracking list
function recordPlacedCard(spawnedCard)
if (spawnedCard.getName() == "Protecting the Anirniq (2)") then
log("Spawned PtA "..spawnedCard.getGUID())
end
placedCardGuids[spawnedCard.getGUID()] = true
placedCardCount = placedCardCount + 1
end
-- Recalls all spawned cards to the bag, and clears the placedCardGuids list
function buttonClick_recall()
local trash = spawnObjectData({data = recallBag, position = self.getPosition()})
for cardGuid, _ in pairs(placedCardGuids) do
local card = getObjectFromGUID(cardGuid)
if (card ~= nil) then
trash.putObject(card)
placedCardGuids[cardGuid] = nil
placedCardCount = placedCardCount - 1
end
end
if (placedCardCount > 0) then
-- Couldn't recall all the cards, check and pull them from decks
local decksInArea = { }
local allObjects = getAllObjects()
for _, object in ipairs(allObjects) do
if (object.name == "Deck" and isInArea(object)) then
table.insert(decksInArea, object)
end
end
for _, deck in ipairs(decksInArea) do
local cardsInDeck = deck.getObjects()
for i, card in ipairs(cardsInDeck) do
if (placedCardGuids[card.guid]) then
trash.putObject(deck.takeObject({ guid = card.guid }))
break
end
end
end
end
trash.destruct()
-- We've recalled everything we can, some cards may have been moved out of the
-- card area. Just reset at this point.
placedCardGuids = { }
placedCardCount = 0
end
function isInArea(object)
if (object == nil) then
return false
end
local position = object.getPosition()
return position.x > CARD_AREA_X_THRESHOLD
and (position.z > CARD_AREA_BASIC_Z_THRESHOLD
or position.z < CARD_AREA_UPGRADED_Z_THRESHOLD)
end
function div(a,b)
return (a - a % b) / b
end