Merge pull request #533 from Entrox-Licher/campaign-exporter-fix

Campaign Exporter Improvements
This commit is contained in:
Chr1Z 2024-01-16 00:25:43 +01:00 committed by GitHub
commit 197bb9aebf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 157 additions and 80 deletions

View File

@ -22,7 +22,7 @@
"ImageURL": "http://cloud-3.steamusercontent.com/ugc/254843371583173230/BECDC34EB4D2C8C5F9F9933C97085F82A2F21AE3/",
"WidthScale": 0
},
"Description": "Saves the state of the table to enable loading the campaign into a new save and keep all current progress.\n\nThis tool will track which campaign you're playing, the entire contents of your campaign log, the contents of your chaos bag, update your health/sanity according to trauma, your ArkhamDB deck IDs, the number of investigators, the page of your campaign guide, and any options you have selected in the options panel.\n\nFor saving trauma values to correct seats, ensure investigators in the campaign log are in the following order: White, Orange, Green, Red\n\n(For custom campaigns, ensure: 1) Campaign Box, Campaign Log, and Campaign Guide each have the corresponding tag, 2)The Campaign Box is on the table when you import or export.",
"Description": "Saves the state of the table to enable loading the campaign into a new save and keep all current progress.\n\nThis tool will track which campaign you're playing, the entire contents of your campaign log, the contents of your chaos bag, update your health/sanity according to trauma, your ArkhamDB deck IDs, the number of investigators, the page of your campaign guide, cards in the Additional Player Cards bag and any options you have selected in the options panel.\n\nFor saving trauma values to correct seats, ensure investigators in the campaign log are in the following order: White, Orange, Green, Red\n\nFor custom campaigns, ensure: 1) Campaign Box, Campaign Log, and Campaign Guide each have the corresponding tag, 2)The Campaign Box is on the table when you import or export.",
"DragSelectable": true,
"GMNotes": "",
"GUID": "334ee3",
@ -53,5 +53,14 @@
"scaleZ": 3.38
},
"Value": 0,
"XmlUI": ""
"XmlUI": "",
"AttachedSnapPoints": [
{
"Position": {
"x": -0.95,
"y": 0.2,
"z": 0
}
}
]
}

View File

@ -6,8 +6,10 @@ local optionPanelApi = require("core/OptionPanelApi")
local playAreaApi = require("core/PlayAreaApi")
local playmatApi = require("playermat/PlaymatApi")
local checkWarning = true
local campaignTokenData = {
Name = "Custom_Model",
Name = "Custom_Model_Bag",
Transform = {
posX = -21.25,
posY = 1.68,
@ -30,7 +32,7 @@ local campaignTokenData = {
ColliderURL = "http://cloud-3.steamusercontent.com/ugc/943949966265929204/A38BB5D72419E6298385556D931877C0A1A55C17/",
Convex = true,
MaterialIndex = 2,
TypeIndex = 0,
TypeIndex = 6,
CustomShader = {
SpecularColor = {
r = 0.7222887,
@ -47,23 +49,12 @@ local campaignTokenData = {
local COLORS = { "White", "Orange", "Green", "Red" }
function onLoad()
self.createButton({
click_function = "findCampaignFromToken",
function_owner = self,
label = "Import",
tooltip = "Load in a campaign save from a token!\n\n(Token can be anywhere on the table, but ensure there is only 1!)",
position = { x = -1, y = 0.2, z = 0 },
font_size = 400,
width = 1400,
height = 600,
scale = { 0.5, 1, 0.5 },
})
self.createButton({
click_function = "createCampaignToken",
function_owner = self,
label = "Export",
tooltip = "Create a campaign save token!\n\n(Ensure all chaos tokens have been unsealed!)",
position = { x = 1, y = 0.2, z = 0 },
tooltip = "Create a campaign save token!",
position = { x = -1, y = 0.21, z = 0 },
font_size = 400,
width = 1400,
height = 600,
@ -71,55 +62,74 @@ function onLoad()
})
end
function onObjectLeaveContainer(container, object)
if container.hasTag("ImporterToken") and checkWarning then
broadcastToAll(
"Removing objects from the Save Coin bag will break functionality. Please replace the objects in the same order they were removed.",
Color.Yellow
)
end
end
function onObjectEnterContainer(container, object)
if container.hasTag("ImporterToken") and checkWarning then
broadcastToAll(
"Adding objects to the Save Coin bag will break functionality. Please remove the objects.",
Color.Yellow
)
end
end
---------------------------------------------------------
-- main import functions (split up to allow for Wait conditions)
---------------------------------------------------------
-- Identifies import token, determines campaign box and downloads it (if needed)
function findCampaignFromToken(_, _, _)
local coin = nil
local coinObjects = getObjectsWithTag("ImporterToken")
if #coinObjects == 0 then
broadcastToAll("Could not find importer token", Color.Red)
elseif #coinObjects > 1 then
broadcastToAll("More than 1 importer token found. Please delete all but 1 importer token", Color.Yellow)
else
coin = coinObjects[1]
local importData = JSON.decode(coin.getGMNotes())
campaignBoxGUID = importData["box"]
local campaignBox = getObjectFromGUID(campaignBoxGUID)
if campaignBox.type == "Generic" then
campaignBox.call("buttonClick_download")
end
Wait.condition(
function()
if #campaignBox.getObjects() > 0 then
placeCampaignFromToken(importData)
else
createCampaignFromToken(importData)
end
end,
function()
local obj = getObjectFromGUID(campaignBoxGUID)
if obj == nil then
return false
else
return obj.type == "Bag" and obj.getLuaScript() ~= ""
end
end,
2,
function() broadcastToAll("Error loading campaign box") end
)
function onCollisionEnter(info)
if info.collision_object.hasTag("ImporterToken") then
importFromToken(info.collision_object)
end
end
-- Identifies import token, determines campaign box and downloads it (if needed)
function importFromToken(coin)
broadcastToAll("Campaign Import Initiated")
local importData = JSON.decode(coin.getGMNotes())
local campaignBoxGUID = importData["box"]
local campaignBox = getObjectFromGUID(campaignBoxGUID)
if not campaignBox then
broadcastToAll("Campaign Box not present on table!", Color.Red)
return
end
if campaignBox.type == "Generic" then
campaignBox.call("buttonClick_download")
end
Wait.condition(
function()
if #campaignBox.getObjects() > 0 then
placeCampaignFromToken(importData, coin)
else
restoreCampaignData(importData, coin)
end
end,
function()
local obj = getObjectFromGUID(campaignBoxGUID)
if obj == nil then
return false
else
return obj.type == "Bag" and obj.getLuaScript() ~= ""
end
end,
2,
function() broadcastToAll("Error loading campaign box") end
)
end
-- After box has been downloaded, places content on table
function placeCampaignFromToken(importData)
function placeCampaignFromToken(importData, coin)
getObjectFromGUID(importData["box"]).call("buttonClick_place")
Wait.condition(
function() createCampaignFromToken(importData) end,
function() restoreCampaignData(importData, coin) end,
function() return findUniqueObjectWithTag("CampaignLog") ~= nil end,
2,
function() broadcastToAll("Error placing campaign box") end
@ -127,11 +137,29 @@ function placeCampaignFromToken(importData)
end
-- After content is placed on table, conducts all the other import operations
function createCampaignFromToken(importData)
function restoreCampaignData(importData, coin)
checkWarning = false
if importData["additionalIndex"] then
guidReferenceApi.getObjectByOwnerAndType("Mythos", "AdditionalPlayerCardsBag").destruct()
if coin.type == "Bag" then
coin.takeObject({index = 0, position = importData["additionalIndex"], callback_function = function(obj) obj.setLock(true) end})
else
spawnObjectJSON({json = importData["additionalIndex"]})
end
end
-- destroy existing campaign log and load saved campaign log
findUniqueObjectWithTag("CampaignLog").destruct()
spawnObjectData({ data = importData["log"] })
if coin.type == "Bag" then
local newLog = coin.takeObject({index = 0, position = importData["log"], callback_function = function(obj) obj.setLock(true) end})
else
spawnObjectData({ data = importData["log"] })
end
coin.destruct()
checkWarning = true
chaosBagApi.setChaosBagState(importData["bag"])
-- populate trauma values
@ -155,7 +183,7 @@ function createCampaignFromToken(importData)
-- Condition function that is called continiously until returs true or timeout is reached
function() return guide.Book.setPage(importData["guide"]) end,
-- Amount of time in seconds until the Wait times out
1,
2,
-- Called if the Wait times out
function() log("Campaign Guide import failed!") end
)
@ -165,19 +193,18 @@ function createCampaignFromToken(importData)
-- destroy Tour Starter token
local tourStarter = guidReferenceApi.getObjectByOwnerAndType("Mythos", "TourStarter")
tourStarter.destruct()
if tourStarter then
tourStarter.destruct()
end
-- restore PlayArea image
playAreaApi.updateSurface(importData["playmat"])
playAreaApi.updateSurface(importData["playarea"])
broadcastToAll("Campaign successfully imported!", Color.Green)
end
-- Creates a campaign token with save data encoded into GM Notes based on the current state of the table
function createCampaignToken(_, playerColor, _)
-- clean up chaos tokens
blessCurseApi.removeAll(playerColor)
chaosBagApi.releaseAllSealedTokens(playerColor)
-- find active campaign
local campaignBox
@ -202,20 +229,19 @@ function createCampaignToken(_, playerColor, _)
return
end
local traumaValues = {
0, 0, 0, 0,
0, 0, 0, 0
}
local counterData = campaignLog.getVar("ref_buttonData")
if counterData ~= nil then
local additionalIndex = guidReferenceApi.getObjectByOwnerAndType("Mythos", "AdditionalPlayerCardsBag")
local traumaValues = { }
local trauma = campaignLog.getVar("returnTrauma")
if trauma ~= nil then
printToAll("Trauma values found in campaign log!", "Green")
for i = 1, 10, 3 do
traumaValues[1 + (i - 1) / 3] = counterData.counter[i].value
traumaValues[5 + (i - 1) / 3] = counterData.counter[i + 1].value
trauma = campaignLog.call("returnTrauma")
for _, val in ipairs(trauma) do
table.insert(traumaValues, val)
end
else
printToAll("Trauma values could not be found in campaign log!", "Yellow")
printToAll("Default values for health and sanity loaded.", "Yellow")
printToAll("Trauma values could not be found in campaign log!", "Yellow")
end
local campaignGuide = findUniqueObjectWithTag("CampaignGuide")
@ -224,19 +250,31 @@ function createCampaignToken(_, playerColor, _)
return
end
-- clean up chaos tokens
blessCurseApi.removeAll(playerColor)
chaosBagApi.releaseAllSealedTokens(playerColor)
local campaignData = {
box = campaignBox.getGUID(),
log = campaignLog.getData(),
log = campaignLog.getPosition(),
bag = chaosBagApi.getChaosBagState(),
trauma = traumaValues,
decks = deckImporterApi.getUiState(),
clueCount = playAreaApi.getInvestigatorCount(),
guide = campaignGuide.Book.getPage(),
playarea = playAreaApi.getSurface(),
options = optionPanelApi.getOptions(),
playmat = playAreaApi.getSurface()
guide = campaignGuide.Book.getPage(),
additionalIndex = additionalIndex.getPosition()
}
campaignTokenData.GMNotes = JSON.encode(campaignData)
campaignTokenData.Nickname = os.date("%b %d ") .. campaignBox.getName() .. " Save"
campaignTokenData.Nickname = campaignBox.getName() .. os.date(" %b %d") .. " Save"
campaignTokenData.ContainedObjects = { }
local indexData = additionalIndex.getData()
indexData.Locked = false
table.insert(campaignTokenData.ContainedObjects, indexData)
local logData = campaignLog.getData()
logData.Locked = false
table.insert(campaignTokenData.ContainedObjects, logData)
spawnObjectData({ data = campaignTokenData })
broadcastToAll("Campaign successfully exported! Save coin object to import on a fresh save", Color.Green)
end
@ -263,3 +301,16 @@ function setTrauma(trauma)
playmatApi.updateCounter(COLORS[i], "HorrorCounter", trauma[i + 4])
end
end
-- gets data from campaign log if possible
function loadTrauma(log)
local trauma = log.getVar("returnTrauma")
if trauma ~= nil then
printToAll("Trauma values found in campaign log!", "Green")
trauma = log.call("returnTrauma")
return trauma
else
return nil
end
end

View File

@ -60,6 +60,7 @@ local GuidReferences = {
Trash = "4b8594"
},
Mythos = {
AdditionalPlayerCardsBag = "2cba6b",
AllCardsBag = "15bb07",
BlessCurseManager = "5933fb",
CampaignThePathToCarcosa = "aca04c",

View File

@ -72,6 +72,7 @@ end
-- yielding. Based on the current count of cards this will require
-- approximately 60 frames to complete.
function buildIndex()
local cardCount = 0
indexingDone = false
if (self.getData().ContainedObjects == nil) then
return 1
@ -80,6 +81,11 @@ function buildIndex()
local cardMetadata = JSON.decode(cardData.GMNotes)
if (cardMetadata ~= nil) then
addCardToIndex(cardData, cardMetadata)
cardCount = cardCount + 1
if cardCount > 9 then
cardCount = 0
coroutine.yield(0)
end
end
end
local hotfixBags = getObjectsWithTag("AllCardsHotfix")
@ -91,12 +97,22 @@ function buildIndex()
local deepCardMetadata = JSON.decode(deepCardData.GMNotes)
if deepCardMetadata ~= nil then
addCardToIndex(deepCardData, deepCardMetadata)
cardCount = cardCount + 1
if cardCount > 9 then
cardCount = 0
coroutine.yield(0)
end
end
end
else
local cardMetadata = JSON.decode(cardData.GMNotes)
if cardMetadata ~= nil then
addCardToIndex(cardData, cardMetadata)
cardCount = cardCount + 1
if cardCount > 9 then
cardCount = 0
coroutine.yield(0)
end
end
end
end