Merge pull request #533 from Entrox-Licher/campaign-exporter-fix
Campaign Exporter Improvements
This commit is contained in:
commit
197bb9aebf
@ -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
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -60,6 +60,7 @@ local GuidReferences = {
|
||||
Trash = "4b8594"
|
||||
},
|
||||
Mythos = {
|
||||
AdditionalPlayerCardsBag = "2cba6b",
|
||||
AllCardsBag = "15bb07",
|
||||
BlessCurseManager = "5933fb",
|
||||
CampaignThePathToCarcosa = "aca04c",
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user