ah_sce_unpacked/unpacked/Custom_Model_Bag The Forgotten Age 0bcf19/Custom_Model_Bag 7 The Depths of Yoth 85286a/Custom_Tile Depths of Yoth Helper 8bfd09.ttslua
2021-02-13 14:46:01 -05:00

320 lines
9.1 KiB
Plaintext

PLAYAREA = {
position = { x=-25, y=4, z=0 },
rotation = { x=0, y=90, z=0 },
scale = { x=37, y=5, z=43 }
}
ASSEMBLY = {
position = { x=68, y=2, z=36 },
rotation = { x=0, y=270, z=180 }
}
SET_ASIDE = {
position = { x=-2.52, y=2, z=14.87 },
rotation = { x=0, y=270, z=180 }
}
EXPLORATION = {
position = { x=-6.33, y=2, z=14.87 },
rotation = { x=0, y=270, z=180 }
}
START = {
position = { x=-30.22, y=2, z=-0.03 },
rotation = { x=0, y=270, z=180 }
}
HEART = 1
STAR = 2
DIAMOND = 3
TRIANGLE = 4
CIRCLE = 5
SQUARE = 6
BACKTICK = 7
TILDE = 8
PARALLEL = 9
T = 10
HOURGLASS = 11
LOCATIONS = {
{ name="City of the Serpents", symbol=DIAMOND, connections={ PARALLEL, BACKTICK, TRIANGLE, T, SQUARE } },
{ name="Bridge over N'kai", symbol=HEART, connections={ PARALLEL, BACKTICK, CIRCLE, TILDE, HOURGLASS } },
{ name="Abandoned Site", symbol=SQUARE, connections={ PARALLEL, DIAMOND, TRIANGLE, TILDE, T } },
{ name="Caverns of Yoth", symbol=BACKTICK, connections={ CIRCLE, HOURGLASS, HEART, TILDE, DIAMOND } },
{ name="Hall of Heresy", symbol=TRIANGLE, connections={ CIRCLE, PARALLEL, T, SQUARE, DIAMOND } },
{ name="Bright Canyon", symbol=CIRCLE, connections={ BACKTICK, TILDE, T, HEART, TRIANGLE } },
{ name="Forked Path", symbol=T, connections={ CIRCLE, DIAMOND, HOURGLASS, SQUARE, TRIANGLE } },
{ name="Crumbling Precipice", symbol=HOURGLASS, connections={ PARALLEL, TILDE, HEART, T, BACKTICK } },
{ name="Broken Passage", symbol=TILDE, connections={ CIRCLE, BACKTICK, HOURGLASS, SQUARE, HEART } },
{ name="Steps of Yoth", symbol=PARALLEL, connections={ HOURGLASS, SQUARE, TRIANGLE, DIAMOND, HEART } }
}
STEPS = "Steps of Yoth"
PERILS = "Perils of Yoth"
function onLoad()
self.createButton({
label="Set Up",
click_function="setup",
function_owner=self,
position={0,0.1,-0.6},
height=120,
width=500,
scale={x=1.75, y=1.75, z=1.75},
font_size=80
})
self.createButton({
label="Update\nConnections",
click_function="updateConnections",
function_owner=self,
position={0,0.1,0.4},
height=240,
width=500,
scale={x=1.75, y=1.75, z=1.75},
font_size=80
})
playarea = getObjectFromGUID("721ba2")
TOKEN_IMAGES = Global.getTable("tokenplayerone")
makeIndexes()
math.randomseed(os.time())
end
function makeIndexes()
nameMap = {}
for i,v in ipairs(LOCATIONS) do
nameMap[v.name] = v
end
end
function getPlayAreaObjects()
return Physics.cast({
origin = PLAYAREA.position,
direction = { x=0, y=1, z=0 },
type = 3,
size = PLAYAREA.scale,
orientation = PLAYAREA.rotation
})
end
function setup(_obj, _color, _alt_click)
local objs = getPlayAreaObjects()
clearLines()
-- make index of all cards in play area and remove all clues and doom
local allCards = {}
for i,v in ipairs(objs) do
local obj = v.hit_object
local name = obj.getName()
if name ~= nil then
if obj.tag == "Card" then
allCards[name] = { card = obj, guid = obj.getGUID() }
elseif obj.tag == "Deck" then
local cards = obj.getObjects()
for j,card in ipairs(cards) do
if card.guid ~= nil and card.name ~= nil then
allCards[card.name] = { deck = obj, guid = card.guid }
end
end
elseif obj.tag == "Tile" then
local props = obj.getCustomObject()
if (props.image == TOKEN_IMAGES.clue and props.image_bottom == TOKEN_IMAGES.doom)
or (props.image == TOKEN_IMAGES.doom and props.image_bottom == TOKEN_IMAGES.clue)
then
Wait.time(|| Global.destroyObject(obj), 1)
end
end
end
end
-- find location cards
local locCards = {}
local notFound = {}
for i,loc in ipairs(LOCATIONS) do
local card = allCards[loc.name]
if card == nil then
table.insert(notFound, loc.name)
else
table.insert(locCards, card)
end
end
if #notFound > 0 then
printToColor("The following locations were not found: " ..
table.concat(notFound, ", "), _color)
printToColor("Place them in the central play area and try again", _color)
return
end
-- Perils of Yoth
local peril = allCards[PERILS]
if peril ~= nil then
if peril.card ~= nil then
placeCard(nil, peril.card, ASSEMBLY)
else
placeCard(peril.deck, peril.guid, ASSEMBLY)
if peril.deck.is_face_down and #peril.deck.getObjects() > 0 then
peril.deck.shuffle()
end
end
end
-- reset clue spawn status and make a deck of all location cards in the
-- assembly area
local spawnedGuids = playarea.getVar("SPAWNED_LOCATION_GUIDS")
for i,loc in ipairs(locCards) do
spawnedGuids[loc.guid] = nil
if loc.card ~= nil then
placeCard(nil, loc.card, ASSEMBLY)
elseif loc.deck ~= nil and #loc.deck.getObjects() > 0 then
placeCard(loc.deck, loc.guid, ASSEMBLY)
else
-- all but one card was taken from deck, so it doesn't exist anymore
Wait.time(|| placeCard(nil, loc.guid, ASSEMBLY), 1)
end
end
playarea.setVar("SPAWNED_LOCATION_GUIDS", spawnedGuids)
Wait.time(setup_2, 2)
end
function setup_2()
local objs = Physics.cast({
origin = ASSEMBLY.position,
direction = { x=0, y=1, z=0 },
type = 3,
size = { x=1, y=1, z=1 },
orientation = ASSEMBLY.rotation
})
local deck = nil
for i,v in ipairs(objs) do
if v.hit_object.tag == "Deck" then
deck = v.hit_object
end
end
local locMap = {}
for i,card in ipairs(deck.getObjects()) do
locMap[card.name] = card.guid
end
-- place Steps of Yoth and Perils of Yoth (if necessary)
placeCard(deck, locMap[STEPS], EXPLORATION)
if locMap[PERILS] ~= nil then
placeCard(deck, locMap[PERILS], EXPLORATION)
end
-- randomly select starting location
deck.shuffle()
placeCard(deck, nil, START, true)
-- assemble exploration deck
for i=1,4 do
placeCard(deck, nil, EXPLORATION)
end
Wait.time(setup_3, 1)
-- move remaining cards to set aside area
deck.setPosition(SET_ASIDE.position)
deck.setName("Set Aside Locations")
end
function setup_3()
local objs = Physics.cast({
origin = EXPLORATION.position,
direction = { x=0, y=1, z=0 },
type = 3,
size = { x=1, y=1, z=1 },
orientation = EXPLORATION.rotation
})
local deck = nil
for i,v in ipairs(objs) do
if v.hit_object.tag == "Deck" then
deck = v.hit_object
end
end
deck.shuffle()
deck.setName("Exploration Deck")
end
function placeCard(deck, card, location, faceup)
if deck ~= nil then
deck.takeObject({
guid = card,
position = location.position,
rotation = location.rotation,
smooth = false,
flip = faceup
})
return
end
if type(card) == "string" then
card = getObjectFromGUID(card)
end
card.setRotation(location.rotation)
card.setPosition(location.position)
if faceup then card.flip() end
end
function updateConnections(obj, color, alt_click)
local objs = getPlayAreaObjects()
local cardObjs = {}
local connObjs = {}
for i,v in ipairs(objs) do
local obj = v.hit_object
local guid = obj.getGUID()
if guid ~= nil and obj.tag == "Card" and not obj.is_face_down then
local name = obj.getName()
local loc = nameMap[name]
if loc ~= nil then
cardObjs[name] = obj
connObjs[loc.symbol] = obj
end
end
end
local lines = {}
for name,obj in pairs(cardObjs) do
for j,conn in ipairs(nameMap[obj.getName()].connections) do
if connObjs[conn] ~= nil then
drawConnection(obj, connObjs[conn], lines)
end
end
end
Global.setVectorLines(lines)
end
function clearLines()
Global.setVectorLines({})
end
function drawConnection(origin, target, lines)
local originPos = origin.getPosition()
local targetPos = target.getPosition()
table.insert(lines, { points={ originPos, targetPos } })
if not connectsTo(target, origin) then
-- draw one-way arrow
local midpoint = originPos:lerp(targetPos, 0.5)
local direction = (targetPos - originPos):normalize()
local arrow1 = direction:copy():rotateOver('y', 45)
local arrow2 = direction:copy():rotateOver('y', -45)
table.insert(lines, { points={ midpoint-arrow1, midpoint, midpoint-arrow2 } })
end
end
function connectsTo(origin, target)
local symbol = nameMap[target.getName()].symbol
for i,conn in ipairs(nameMap[origin.getName()].connections) do
if conn == symbol then return true end
end
return false
end