Merge branch 'main' into optionpanel-2
This commit is contained in:
commit
2e99d57e46
@ -16,22 +16,10 @@
|
||||
</TableLayout>
|
||||
</Panel>
|
||||
|
||||
<Panel id="Options" offsetXY="0 535" active="false">
|
||||
<Panel id="Options" offsetXY="0 535" active="false" showAnimation="Grow" hideAnimation="Shrink">
|
||||
<VerticalLayout height="300" width="500" spacing="10" childAlignment="MiddleCenter">
|
||||
<ToggleButton
|
||||
class="optionButton"
|
||||
id="optionAgenda"
|
||||
onClick="optionClick(Agenda)"
|
||||
>Doom on Agenda</ToggleButton>
|
||||
<ToggleButton
|
||||
class="optionButton"
|
||||
id="optionPlayarea"
|
||||
onClick="optionClick(Playarea)"
|
||||
>Doom in Playarea</ToggleButton>
|
||||
<ToggleButton
|
||||
class="optionButton"
|
||||
id="optionPlayermats"
|
||||
onClick="optionClick(Playermats)"
|
||||
>Doom on Playermats</ToggleButton>
|
||||
<ToggleButton class="optionButton" id="optionAgenda" onClick="optionClick(Agenda)">Doom on Agenda</ToggleButton>
|
||||
<ToggleButton class="optionButton" id="optionPlayarea" onClick="optionClick(Playarea)">Doom in Playarea</ToggleButton>
|
||||
<ToggleButton class="optionButton" id="optionPlayermats" onClick="optionClick(Playermats)">Doom on Playermats</ToggleButton>
|
||||
</VerticalLayout>
|
||||
</Panel>
|
||||
|
@ -10,14 +10,19 @@
|
||||
"g": 1,
|
||||
"r": 1
|
||||
},
|
||||
"CustomUIAssets": [
|
||||
{
|
||||
"Name": "down-arrow",
|
||||
"Type": 0,
|
||||
"URL": "http://cloud-3.steamusercontent.com/ugc/1849291925327196037/A32E84E24065356A759D8676A90FF698A05FE691/"
|
||||
}
|
||||
],
|
||||
"Description": "a2f932",
|
||||
"CustomImage": {
|
||||
"CustomToken": {
|
||||
"MergeDistancePixels": 15,
|
||||
"Stackable": false,
|
||||
"StandUp": false,
|
||||
"Thickness": 0.2
|
||||
},
|
||||
"ImageScalar": 1,
|
||||
"ImageSecondaryURL": "",
|
||||
"ImageURL": "http://cloud-3.steamusercontent.com/ugc/1915746489209870095/5F6A6F2946DBEB81667C15B112F9E35943E61A97/",
|
||||
"WidthScale": 0
|
||||
},
|
||||
"Description": "Moves all objects on the playmat in the chosen direction.",
|
||||
"DragSelectable": true,
|
||||
"GMNotes": "",
|
||||
"GUID": "0f1374",
|
||||
@ -31,22 +36,25 @@
|
||||
"LuaScriptState": "",
|
||||
"LuaScript_path": "Fan-MadeAccessories.aa8b38/DisplacementTool.0f1374.ttslua",
|
||||
"MeasureMovement": false,
|
||||
"Name": "Checker_white",
|
||||
"Name": "Custom_Token",
|
||||
"Nickname": "Displacement Tool",
|
||||
"Snap": true,
|
||||
"Sticky": true,
|
||||
"Tags": [
|
||||
"displacement_excluded"
|
||||
],
|
||||
"Tooltip": true,
|
||||
"Transform": {
|
||||
"posX": 29.557,
|
||||
"posY": 4.094,
|
||||
"posZ": -21.437,
|
||||
"posX": 31.478,
|
||||
"posY": 4.204,
|
||||
"posZ": -20.335,
|
||||
"rotX": 0,
|
||||
"rotY": 270,
|
||||
"rotZ": 0,
|
||||
"scaleX": 1,
|
||||
"scaleX": 1.5,
|
||||
"scaleY": 1,
|
||||
"scaleZ": 1
|
||||
"scaleZ": 1.5
|
||||
},
|
||||
"Value": 0,
|
||||
"XmlUI_path": "Fan-MadeAccessories.aa8b38/DisplacementTool.0f1374.xml"
|
||||
"XmlUI": ""
|
||||
}
|
||||
|
@ -1,62 +1,69 @@
|
||||
---
|
||||
--- Generated by Luanalysis
|
||||
--- Created by Whimsical.
|
||||
--- DateTime: 2022-01-21 1:39 p.m.
|
||||
---
|
||||
|
||||
function onload()
|
||||
self:getRotation(Vector(0, 270, 0))
|
||||
end
|
||||
|
||||
local excluded = {
|
||||
["b7b45b"] = true,
|
||||
["f182ee"] = true,
|
||||
["721ba2"] = true
|
||||
}
|
||||
|
||||
---@type table<string, table<string, any>>
|
||||
local OFFSETS = {
|
||||
left = {
|
||||
axis = "z",
|
||||
offset = 7.67
|
||||
},
|
||||
right = {
|
||||
axis = "z",
|
||||
offset = -7.67
|
||||
},
|
||||
up = {
|
||||
axis = "x",
|
||||
offset = 6.54
|
||||
},
|
||||
down = {
|
||||
axis = "x",
|
||||
offset = -6.54
|
||||
}
|
||||
left = { x = 0.00, y = 0, z = 7.67 },
|
||||
right = { x = 0.00, y = 0, z = -7.67 },
|
||||
up = { x = 6.54, y = 0, z = 0.00 },
|
||||
down = { x = -6.54, y = 0, z = 0.00 }
|
||||
}
|
||||
|
||||
---@param player Player
|
||||
---@param direction string
|
||||
function shift(player, direction)
|
||||
if self:getDescription()=="" then
|
||||
player:broadcast("The description of the displacement tool must contain (only) the GUID for a scripting zone that contains the play field.", Color.RED)
|
||||
return
|
||||
end
|
||||
local UI_offset = 1.15
|
||||
|
||||
local zone = getObjectFromGUID(self:getDescription())
|
||||
local offset = OFFSETS[direction]
|
||||
local buttonParamaters = {}
|
||||
buttonParamaters.function_owner = self
|
||||
buttonParamaters.label = ""
|
||||
buttonParamaters.height = 500
|
||||
buttonParamaters.width = 500
|
||||
buttonParamaters.color = { 0, 0, 0, 0 }
|
||||
|
||||
function onLoad()
|
||||
-- index 0: left
|
||||
buttonParamaters.click_function = "shift_left"
|
||||
buttonParamaters.tooltip = "Move left"
|
||||
buttonParamaters.position = { -UI_offset, 0, 0 }
|
||||
self.createButton(buttonParamaters)
|
||||
|
||||
-- index 1: right
|
||||
buttonParamaters.click_function = "shift_right"
|
||||
buttonParamaters.tooltip = "Move right"
|
||||
buttonParamaters.position = { UI_offset, 0, 0 }
|
||||
self.createButton(buttonParamaters)
|
||||
|
||||
-- index 2: up
|
||||
buttonParamaters.click_function = "shift_up"
|
||||
buttonParamaters.tooltip = "Move up"
|
||||
buttonParamaters.position = { 0, 0, -UI_offset }
|
||||
self.createButton(buttonParamaters)
|
||||
|
||||
-- index 3: down
|
||||
buttonParamaters.click_function = "shift_down"
|
||||
buttonParamaters.tooltip = "Move down"
|
||||
buttonParamaters.position = { 0, 0, UI_offset }
|
||||
self.createButton(buttonParamaters)
|
||||
end
|
||||
|
||||
function shift_left(color) shift(color, "left") end
|
||||
|
||||
function shift_right(color) shift(color, "right") end
|
||||
|
||||
function shift_up(color) shift(color, "up") end
|
||||
|
||||
function shift_down(color) shift(color, "down") end
|
||||
|
||||
function shift(color, direction)
|
||||
local zone = getObjectFromGUID("a2f932")
|
||||
if not zone then
|
||||
player:broadcast("The description of the displacement tool either contains text that is not a GUID or contains a GUID for a scripting zone that does not exist.", Color.RED)
|
||||
broadcastToColor("Scripting zone couldn't be found.", color, "Red")
|
||||
return
|
||||
end
|
||||
|
||||
local adjustment = Vector(0, 0, 0)
|
||||
adjustment[offset.axis] = offset.offset
|
||||
|
||||
---@param object TTSObject
|
||||
for _, object in ipairs(zone:getObjects()) do
|
||||
if not (excluded[object:getGUID():lower()] or object:hasTag("displacement_excluded")) then
|
||||
object:translate(adjustment)
|
||||
for _, object in ipairs(zone.getObjects()) do
|
||||
if not (excluded[object.getGUID()] or object.hasTag("displacement_excluded")) then
|
||||
object.translate(OFFSETS[direction])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,4 +0,0 @@
|
||||
<Button onClick="shift(up)" icon="down-arrow" width="100" height="100" color="#FFFFFF" position="0 -150 -10" />
|
||||
<Button onClick="shift(down)" icon="down-arrow" width="100" height="100" color="#FFFFFF" position="0 150 -10" rotation="0 0 180"/>
|
||||
<Button onClick="shift(left)" icon="down-arrow" width="100" height="100" color="#FFFFFF" position="150 0 -10" rotation="0 0 90" />
|
||||
<Button onClick="shift(right)" icon="down-arrow" width="100" height="100" color="#FFFFFF" position="-150 0 -10" rotation="0 0 270" />
|
@ -18,9 +18,7 @@ function onLoad(savedData)
|
||||
|
||||
-- restore state for option panel
|
||||
for key, bool in pairs(options) do
|
||||
if bool then
|
||||
self.UI.setAttribute("option" .. key, "isOn", 0)
|
||||
end
|
||||
self.UI.setAttribute("option" .. key, "isOn", not bool)
|
||||
end
|
||||
end
|
||||
|
||||
@ -41,7 +39,9 @@ end
|
||||
-- called by the invisible button to change displayed value
|
||||
function addOrSubtract(_, _, isRightClick)
|
||||
local newVal = math.min(math.max(val + (isRightClick and -1 or 1), 0), 99)
|
||||
if val ~= newVal then updateVal(newVal) end
|
||||
if val ~= newVal then
|
||||
updateVal(newVal)
|
||||
end
|
||||
end
|
||||
|
||||
function updateVal(number)
|
||||
@ -55,7 +55,11 @@ function startReset()
|
||||
if options.Agenda then
|
||||
updateVal(0)
|
||||
end
|
||||
getObjectFromGUID("652ff3").call("removeDoom", options)
|
||||
-- call the "Doom-in-Play"-counter
|
||||
local DoomInPlayCounter = getObjectFromGUID("652ff3")
|
||||
if DoomInPlayCounter then
|
||||
DoomInPlayCounter.call("removeDoom", options)
|
||||
end
|
||||
end
|
||||
|
||||
-- XML UI functions
|
||||
|
78
src/core/tour/TourCard.ttslua
Normal file
78
src/core/tour/TourCard.ttslua
Normal file
@ -0,0 +1,78 @@
|
||||
-- Table definition for the tour card layout. This is functionally XMLUI in Lua form, but using
|
||||
-- this for dynamic creation ensures we can handle any player color without needing 10
|
||||
-- near-duplicate definitions in Global.xml
|
||||
|
||||
tourCardTemplate = {
|
||||
tag = "Panel",
|
||||
attributes = {
|
||||
id = "tourCard",
|
||||
height = 195,
|
||||
width = 310,
|
||||
rotation = "0 0 0",
|
||||
position = "0 300 30",
|
||||
showAnimation = "FadeIn",
|
||||
hideAnimation = "FadeOut",
|
||||
active=false,
|
||||
},
|
||||
children = {
|
||||
{
|
||||
tag = "Image",
|
||||
attributes = {
|
||||
id = "tourNarratorImage",
|
||||
height=75,
|
||||
width=50,
|
||||
rectAlignment="UpperLeft"
|
||||
-- Image will be set when the card is updated
|
||||
}
|
||||
},
|
||||
{
|
||||
tag = "Panel",
|
||||
attributes = {
|
||||
color = "#F5F5DC",
|
||||
height = 195,
|
||||
width = 250,
|
||||
rectAlignment = "UpperRight"
|
||||
},
|
||||
children = {
|
||||
{
|
||||
tag = "Text",
|
||||
attributes = {
|
||||
id = "tourText",
|
||||
height = 150,
|
||||
width = 230,
|
||||
rectAlignment = "UpperCenter",
|
||||
offsetXY = "0 -10",
|
||||
resizeTextForBestFit = true,
|
||||
resizeTextMinSize = 10,
|
||||
resizeTextMaxSize = 16,
|
||||
color = "#050505",
|
||||
alignment = "UpperLeft",
|
||||
horizontalOverflow = "wrap",
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
tag = "Button",
|
||||
attributes = {
|
||||
id = "tourNext",
|
||||
height = 30,
|
||||
width = 50,
|
||||
color = "#FF0000",
|
||||
rectAlignment = "LowerRight",
|
||||
offsetXY = "-5 5",
|
||||
},
|
||||
},
|
||||
{
|
||||
tag = "Button",
|
||||
attributes = {
|
||||
id = "tourStop",
|
||||
height = 30,
|
||||
width = 50,
|
||||
color = "#FF0000",
|
||||
rectAlignment = "LowerRight",
|
||||
offsetXY = "-195 5",
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
188
src/core/tour/TourManager.ttslua
Normal file
188
src/core/tour/TourManager.ttslua
Normal file
@ -0,0 +1,188 @@
|
||||
do
|
||||
require("core/tour/TourScript")
|
||||
require("core/tour/TourCard")
|
||||
local TourManager = { }
|
||||
local internal = { }
|
||||
|
||||
-- Base IDs for various tour card UI elements. Actual IDs will have _[playerColor] appended
|
||||
local cardId = "tourCard"
|
||||
local narratorId = "tourNarratorImage"
|
||||
local textId = "tourText"
|
||||
local nextButtonId = "tourNext"
|
||||
local stopButtonId = "tourStop"
|
||||
|
||||
-- Table centerpoint for the camera hook object. Camera handling is a bit erratic so it doesn't
|
||||
-- always land right where you think it's going to, but it's close
|
||||
local CAMERA_HOME = {
|
||||
x = -30.2,
|
||||
y = 60,
|
||||
z = 0,
|
||||
}
|
||||
|
||||
local cameraHookGuid
|
||||
local currentCardIndex
|
||||
|
||||
-- Kicks off the tour by initializing the card and camera hook. A callback on the hook creation
|
||||
-- will then show the first card.
|
||||
-- @param playerColor Player color to start the tour for
|
||||
TourManager.startTour = function(playerColor)
|
||||
currentCardIndex = 1
|
||||
-- Camera gets really screwy when we finalize if we don't start in ThirdPerson before attaching
|
||||
-- to the hook
|
||||
Player["White"].setCameraMode("ThirdPerson")
|
||||
internal.createTourCard("White")
|
||||
-- XML update takes time to load, wait for it to finish then create the hook
|
||||
Wait.condition(
|
||||
function()
|
||||
internal.createCameraHook()
|
||||
end,
|
||||
function()
|
||||
return not Global.UI.loading
|
||||
end
|
||||
)
|
||||
end
|
||||
|
||||
-- Shows the next card in the tour script. This method is exposed (rather than being part of
|
||||
-- internal) because the XMLUI callbacks expect the method to be on the object directly.
|
||||
-- @param playerColor Player color to show the next card for
|
||||
function nextCard(playerColor)
|
||||
internal.hideCard()
|
||||
Wait.time(function()
|
||||
currentCardIndex = currentCardIndex + 1
|
||||
if currentCardIndex > #TOUR_SCRIPT then
|
||||
internal.finalizeTour()
|
||||
else
|
||||
internal.showCurrentCard()
|
||||
end
|
||||
end, 0.3)
|
||||
end
|
||||
|
||||
-- Ends the tour and cleans up the camera. This method is exposed (rather than being part of
|
||||
-- internal) because the XMLUI callbacks expect the method to be on the object directly.
|
||||
-- @param playerColor Player color to end the tour for
|
||||
function stopTour(playerColor)
|
||||
internal.hideCard()
|
||||
Wait.time(function()
|
||||
internal.finalizeTour()
|
||||
end, 0.3)
|
||||
end
|
||||
|
||||
-- Updates the card UI for the script at the current index, moves the camera to the proper
|
||||
-- position, and shows the card.
|
||||
-- @param playerColor Player color to show the current card for
|
||||
internal.showCurrentCard = function(playerColor)
|
||||
internal.updateCardDisplay(currentCardIndex)
|
||||
local hook = getObjectFromGUID(cameraHookGuid)
|
||||
hook.setPositionSmooth(CAMERA_HOME, false, false)
|
||||
local delay = 0.5
|
||||
if TOUR_SCRIPT[currentCardIndex].showObj ~= nil then
|
||||
Wait.time(function()
|
||||
local lookAtObj = getObjectFromGUID(TOUR_SCRIPT[currentCardIndex].showObj)
|
||||
hook.setPositionSmooth(lookAtObj.getPosition(), false, false)
|
||||
end, delay)
|
||||
delay = delay + 0.5
|
||||
end
|
||||
Wait.time(function() Global.UI.show(cardId) end, delay)
|
||||
end
|
||||
|
||||
-- Hides the current card being shown to a player. This can be in preparation for showing the
|
||||
-- next card, or ending the tour.
|
||||
-- @param playerColor Player color to hide the current card for
|
||||
internal.hideCard = function(playerColor)
|
||||
Global.UI.hide(cardId)
|
||||
end
|
||||
|
||||
-- Cleans up all the various resources associated with the tour, and (hopefully) resets the
|
||||
-- camera to the default position. Camera handling is erratic, the final card in the script
|
||||
-- should include instructions for the player to fix it.
|
||||
-- @param playerColor Player color to clean up
|
||||
internal.finalizeTour = function(playerColor)
|
||||
local cameraHook = getObjectFromGUID(cameraHookGuid)
|
||||
cameraHook.destruct()
|
||||
Player["White"].setCameraMode("ThirdPerson")
|
||||
Wait.frames(function()
|
||||
-- This resets to the default camera position. If we don't place the camera exactly at the
|
||||
-- default, camera controls get weird
|
||||
Player["White"].lookAt({position={-22.265,-2.5,5.2575},pitch=64.343,yaw=90.333,distance=104.7})
|
||||
end, 3)
|
||||
end
|
||||
|
||||
-- Updates the card UI to show the appropriate narrator and text.
|
||||
-- @param index Script entry which should be shown
|
||||
-- @param playerColor Player color to update card for
|
||||
internal.updateCardDisplay = function(index, playerColor)
|
||||
Global.UI.setAttribute(narratorId, "image", TOUR_SCRIPT[index].narrator)
|
||||
Global.UI.setAttribute(textId, "text", TOUR_SCRIPT[index].text)
|
||||
end
|
||||
|
||||
-- Creates a small, transparent object which the camera will be attached to in order to move the
|
||||
-- user's view around the table. This should be called only at the beginning of the tour. Once
|
||||
-- creation is complete the user's camera will be attached to the hook and the first card will be
|
||||
-- shown.
|
||||
-- @param playerColor Player color to create the hook for
|
||||
internal.createCameraHook = function(playerColor)
|
||||
local hookData = {
|
||||
Name = "BlockSquare",
|
||||
Transform = {
|
||||
posX = CAMERA_HOME.x,
|
||||
posY = CAMERA_HOME.y,
|
||||
posZ = CAMERA_HOME.z,
|
||||
rotX = 0,
|
||||
rotY = 270.0,
|
||||
rotZ = 0,
|
||||
scaleX = 0.1,
|
||||
scaleY = 0.1,
|
||||
scaleZ = 0.1,
|
||||
},
|
||||
ColorDiffuse = {
|
||||
r = 0,
|
||||
g = 0,
|
||||
b = 0,
|
||||
a = 0,
|
||||
},
|
||||
Locked = true,
|
||||
}
|
||||
|
||||
spawnObjectData({ data = hookData, callback_function = internal.onHookCreated })
|
||||
end
|
||||
|
||||
-- Callback for creation of the camera hook object. Will attach the camera and show the current
|
||||
-- (presumably first) card.
|
||||
-- @param hook Created object
|
||||
internal.onHookCreated = function(hook)
|
||||
cameraHookGuid = hook.getGUID()
|
||||
Player.White.attachCameraToObject({
|
||||
object = hook,
|
||||
offset = { x = -20, y = 30, z = 0 }
|
||||
})
|
||||
internal.showCurrentCard()
|
||||
end
|
||||
|
||||
-- Creates an XMLUI entry in Global for a player-specific tour card. Dynamically creating this
|
||||
-- is somewhat complex, but ensures we can properly handle any player color.
|
||||
-- @param playerColor Player color to create the card for
|
||||
internal.createTourCard = function(playerColor)
|
||||
if Global.UI.getAttributes("cardId_"..playerColor) ~= nil then
|
||||
return
|
||||
end
|
||||
cardId = cardId .. "_" .. playerColor
|
||||
narratorId = narratorId .. "_" .. playerColor
|
||||
textId = textId .. "_" .. playerColor
|
||||
nextButtonId = nextButtonId .. "_" .. playerColor
|
||||
stopButtonId = stopButtonId .. "_" .. playerColor
|
||||
tourCardTemplate.attributes.id = cardId
|
||||
tourCardTemplate.attributes.visibility = playerColor
|
||||
tourCardTemplate.children[1].attributes.id = narratorId
|
||||
tourCardTemplate.children[2].children[1].attributes.id = textId
|
||||
tourCardTemplate.children[3].attributes.id = nextButtonId
|
||||
tourCardTemplate.children[4].attributes.id = stopButtonId
|
||||
tourCardTemplate.children[3].attributes.onClick = self.getGUID().."/nextCard"
|
||||
tourCardTemplate.children[4].attributes.onClick = self.getGUID().."/stopTour"
|
||||
|
||||
local globalXml = Global.UI.getXmlTable()
|
||||
table.insert(globalXml, tourCardTemplate)
|
||||
Global.UI.setXmlTable(globalXml)
|
||||
end
|
||||
|
||||
return TourManager
|
||||
end
|
20
src/core/tour/TourScript.ttslua
Normal file
20
src/core/tour/TourScript.ttslua
Normal file
@ -0,0 +1,20 @@
|
||||
-- Script for the SCED tour. Documentation and definitions to come.
|
||||
|
||||
TOUR_SCRIPT = {
|
||||
{
|
||||
narrator = "Roland",
|
||||
text = "Despite my best efforts, looks like you found us. You may live to regret that.\n\nAs long as you're here though we might as well show you around. Ready to get started?",
|
||||
},
|
||||
{
|
||||
narrator = "Mandy",
|
||||
text = "If you're going to survive this, you'll need a deck. If it's safely hidden away on ArkhamDB you can load it here.",
|
||||
showObj = "a28140",
|
||||
showDist = 30
|
||||
},
|
||||
{
|
||||
narrator = "Daniela",
|
||||
text = "If you're like me and prefer the hands-on approach, you can build a deck yourself.\n\nThese containers have all the Level 0 cards for each class. Once you've had a run-in with the horrors lurking out there, you can find higher level cards to the right.",
|
||||
showObj = "7e47e1",
|
||||
showDist = 40
|
||||
},
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user