2020-09-29 00:28:19 -04:00
|
|
|
-- set true to enable debug logging
|
|
|
|
DEBUG = false
|
|
|
|
-- we use this to turn off collision handling (for clue spawning)
|
|
|
|
-- until after load is complete (probably a better way to do this)
|
|
|
|
COLLISION_ENABLED = false
|
|
|
|
-- position offsets, adjust these to reposition things relative to mat [x,y,z]
|
|
|
|
DRAWN_ENCOUNTER_CARD_OFFSET = {0.98, 0.5, -0.635}
|
|
|
|
DRAWN_CHAOS_TOKEN_OFFSET = {-1.2, 0.5, -0.45}
|
|
|
|
DISCARD_BUTTON_OFFSETS = {
|
|
|
|
{-0.98, 0.2, -0.945},
|
|
|
|
{-0.525, 0.2, -0.945},
|
|
|
|
{-0.07, 0.2, -0.945},
|
|
|
|
{0.39, 0.2, -0.945},
|
|
|
|
{0.84, 0.2, -0.945},
|
|
|
|
}
|
|
|
|
|
|
|
|
-- the position of the global discard pile
|
|
|
|
-- TODO: delegate to global for any auto discard actions
|
|
|
|
DISCARD_POSITION = {-3.85, 3, 10.38}
|
|
|
|
|
|
|
|
function log(message)
|
|
|
|
if DEBUG then
|
|
|
|
print(message)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- builds a function that discards things in searchPostion to discardPostition
|
|
|
|
function makeDiscardHandlerFor(searchPosition, discardPosition)
|
|
|
|
return function (_)
|
|
|
|
local discardItemList = findObjectsAtPosition(searchPosition)
|
|
|
|
for _, obj in ipairs(discardItemList) do
|
|
|
|
obj.setPositionSmooth(discardPosition, false, true)
|
|
|
|
obj.setRotation({0, -90, 0})
|
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- build a discard button at position to discard from searchPosition to discardPosition
|
|
|
|
-- number must be unique
|
|
|
|
function makeDiscardButton(position, searchPosition, discardPosition, number)
|
|
|
|
local handler = makeDiscardHandlerFor(searchPosition, discardPosition)
|
|
|
|
local handlerName = 'handler' .. number
|
|
|
|
self.setVar(handlerName, handler)
|
|
|
|
self.createButton({
|
|
|
|
label = "Discard",
|
|
|
|
click_function= handlerName,
|
|
|
|
function_owner= self,
|
|
|
|
position = position,
|
|
|
|
scale = {0.12, 0.12, 0.12},
|
|
|
|
width = 800,
|
|
|
|
height = 280,
|
|
|
|
font_size = 180,
|
|
|
|
})
|
|
|
|
end
|
|
|
|
|
|
|
|
function onload()
|
|
|
|
self.interactable = DEBUG
|
|
|
|
DATA_HELPER = getObjectFromGUID('708279')
|
|
|
|
PLAYER_CARDS = DATA_HELPER.getTable('PLAYER_CARD_DATA')
|
|
|
|
PLAYER_CARD_TOKEN_OFFSETS = DATA_HELPER.getTable('PLAYER_CARD_TOKEN_OFFSETS')
|
|
|
|
|
|
|
|
-- positions of encounter card slots
|
|
|
|
local encounterSlots = {
|
|
|
|
{1, 0, -0.7},
|
|
|
|
{0.55, 0, -0.7},
|
|
|
|
{0.1, 0, -0.7},
|
|
|
|
{-0.35, 0, -0.7},
|
|
|
|
{-0.8, 0, -0.7}
|
|
|
|
}
|
|
|
|
|
|
|
|
local i = 1
|
|
|
|
while i <= 5 do
|
|
|
|
makeDiscardButton(DISCARD_BUTTON_OFFSETS[i], encounterSlots[i], DISCARD_POSITION, i)
|
|
|
|
i = i + 1
|
|
|
|
end
|
|
|
|
|
|
|
|
self.createButton({
|
|
|
|
label = " ",
|
|
|
|
click_function = "drawEncountercard",
|
|
|
|
function_owner = self,
|
|
|
|
position = {-1.45,0,-0.7},
|
|
|
|
rotation = {0,-15,0},
|
|
|
|
width = 170,
|
|
|
|
height = 255,
|
|
|
|
font_size = 50
|
|
|
|
})
|
|
|
|
|
|
|
|
self.createButton({
|
|
|
|
label=" ",
|
|
|
|
click_function = "drawChaostokenButton",
|
|
|
|
function_owner = self,
|
|
|
|
position = {1.48,0.0,-0.74},
|
|
|
|
rotation = {0,-45,0},
|
|
|
|
width = 125,
|
|
|
|
height = 125,
|
|
|
|
font_size = 50
|
|
|
|
})
|
|
|
|
|
|
|
|
COLLISION_ENABLED = true
|
|
|
|
end
|
|
|
|
|
|
|
|
function findObjectsAtPosition(localPos)
|
|
|
|
local globalPos = self.positionToWorld(localPos)
|
|
|
|
local objList = Physics.cast({
|
|
|
|
origin=globalPos, --Where the cast takes place
|
|
|
|
direction={0,1,0}, --Which direction it moves (up is shown)
|
|
|
|
type=2, --Type. 2 is "sphere"
|
|
|
|
size={2,2,2}, --How large that sphere is
|
|
|
|
max_distance=1, --How far it moves. Just a little bit
|
|
|
|
debug=false --If it displays the sphere when casting.
|
|
|
|
})
|
|
|
|
local decksAndCards = {}
|
|
|
|
for _, obj in ipairs(objList) do
|
|
|
|
if obj.hit_object.tag == "Deck" or obj.hit_object.tag == "Card" then
|
|
|
|
table.insert(decksAndCards, obj.hit_object)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
return decksAndCards
|
|
|
|
end
|
|
|
|
|
|
|
|
function spawnTokenOn(object, offsets, tokenType)
|
|
|
|
local tokenPosition = object.positionToWorld(offsets)
|
|
|
|
spawnToken(tokenPosition, tokenType)
|
|
|
|
end
|
|
|
|
|
|
|
|
-- spawn a group of tokens of the given type on the object
|
|
|
|
function spawnTokenGroup(object, tokenType, tokenCount)
|
|
|
|
local offsets = PLAYER_CARD_TOKEN_OFFSETS[tokenCount]
|
|
|
|
if offsets == nil then
|
|
|
|
error("couldn't find offsets for " .. tokenCount .. ' tokens')
|
|
|
|
end
|
|
|
|
local i = 0
|
|
|
|
while i < tokenCount do
|
|
|
|
local offset = offsets[i + 1]
|
|
|
|
spawnTokenOn(object, offset, tokenType)
|
|
|
|
i = i + 1
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function buildPlayerCardKey(object)
|
|
|
|
return object.getName() .. ':' .. object.getDescription()
|
|
|
|
end
|
|
|
|
|
|
|
|
function getPlayerCardData(object)
|
|
|
|
return PLAYER_CARDS[buildPlayerCardKey(object)] or PLAYER_CARDS[object.getName()]
|
|
|
|
end
|
|
|
|
|
|
|
|
function shouldSpawnTokens(object)
|
|
|
|
-- we assume we shouldn't spawn tokens if in doubt, this should
|
|
|
|
-- only ever happen on load and in that case prevents respawns
|
|
|
|
local spawned = DATA_HELPER.call('getSpawnedPlayerCardGuid', {object.getGUID()})
|
|
|
|
local canSpawn = getPlayerCardData(object)
|
|
|
|
return not spawned and canSpawn
|
|
|
|
end
|
|
|
|
|
|
|
|
function markSpawned(object)
|
|
|
|
local saved = DATA_HELPER.call('setSpawnedPlayerCardGuid', {object.getGUID(), true})
|
|
|
|
if not saved then
|
|
|
|
error('attempt to mark player card spawned before data loaded')
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
function spawnTokensFor(object)
|
|
|
|
local data = getPlayerCardData(object)
|
|
|
|
if data == nil then
|
|
|
|
error('attempt to spawn tokens for ' .. object.getName() .. ': no token data')
|
|
|
|
end
|
|
|
|
log(object.getName() .. '[' .. object.getDescription() .. ']' .. ' : ' .. data['tokenType'] .. ' : ' .. data['tokenCount'])
|
|
|
|
spawnTokenGroup(object, data['tokenType'], data['tokenCount'])
|
|
|
|
markSpawned(object)
|
|
|
|
end
|
|
|
|
|
|
|
|
function onCollisionEnter(collision_info)
|
|
|
|
if not COLLISION_ENABLED then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
local object = collision_info.collision_object
|
|
|
|
-- anything to the left of this is legal to spawn
|
|
|
|
local discardSpawnBoundary = self.positionToWorld({-1.2, 0, 0})
|
|
|
|
local boundaryLocalToCard = object.positionToLocal(discardSpawnBoundary)
|
|
|
|
if boundaryLocalToCard.x > 0 then
|
|
|
|
log('not checking for token spawn, boundary relative is ' .. boundaryLocalToCard.x)
|
|
|
|
return
|
|
|
|
end
|
|
|
|
if not object.is_face_down and shouldSpawnTokens(object) then
|
|
|
|
spawnTokensFor(object)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
-- functions delegated to Global
|
|
|
|
function drawChaostokenButton(object, player, isRightClick)
|
|
|
|
-- local toPosition = self.positionToWorld(DRAWN_CHAOS_TOKEN_OFFSET)
|
|
|
|
Global.call("drawChaostoken", {self, DRAWN_CHAOS_TOKEN_OFFSET, isRightClick})
|
|
|
|
end
|
|
|
|
|
|
|
|
function drawEncountercard(object, player, isRightClick)
|
|
|
|
local toPosition = self.positionToWorld(DRAWN_ENCOUNTER_CARD_OFFSET)
|
|
|
|
Global.call("drawEncountercard", {toPosition, self.getRotation(), isRightClick})
|
|
|
|
end
|
|
|
|
|
|
|
|
function spawnToken(position, tokenType)
|
|
|
|
Global.call('spawnToken', {position, tokenType})
|
2020-09-29 00:19:59 -04:00
|
|
|
end
|