-- **CAMPAIGN** --

-- Needs to Run First
Import "OvermapData"

-- Imports
Import "UIScripts"
Import "UtilityScripts"
Import "DebugScripts"
Import "Color"

Import "WorldContentScripts"
Import "LeagueGenerationScripts"
Import "OvermapScripts"
Import "SwathScripts"
Import "StarPickScripts"
Import "FlightScripts"
Import "NarrationScripts"
Import "GuideBookScripts"
Import "ItemPurchaseScripts"
Import "AudioScripts"
Import "PlayerSkillScripts"
Import "Clickables"

Import "CampaignRecord"

-- UI
Using "Caravan_Button"
Using "Guidebook_Button"
Using "Auden_Blank_01"
Using "ArrowIndicator4"
Using "LoadBomb"
Using "GoalNodeIndicator"
Using "QuestNodeIndicator"
Using "SunbeamLightRoster"
Using "Sunbeam"
Using "SunbeamHaze"
Using "DraftPickedGlow"
Using "BallDropFlare"
Using "BallDropShockwave"
Using "SigilNightwings"
Using "GuidebookAllAnims"
Using "TwoToneGlow01"

-- Demo Ending
Using "SymbolCommonwealth"
Using "SymbolRites"

-- FX
Using "BirdFly"
Using "DeathSplatDecal"
Using "FootprintSplash"
Using "WaterSplash"
Using "WaveEdge"
Using "ThinSmoke"
Using "BlinkDustCloud"
Using "WalkDustLarge"
Using "Halo"
Using "ImpHop"
Using "GoldSparkle"
Using "MoonEclipse01"
Using "Sun01"
Using "EclipseHalo01"
Using "LightningBoltA"
Using "LightningBoltB"
Using "LightningBoltC"
Using "LightningBoltD"
Using "LightningBoltE"
Using "ActiveStarFlash"

-- Star Map
Using "StarConnector"
Using "StarNodeActiveStreakSpawner"
Using "SkillProcFeedbackFx"
Using "CollisionFxBall"

-- Logo
Using "PyreLogoIn"
Using "PyreLogoLoop"
Using "PyreLogoOut"

-- Wagon Interactables
Using "WagonCandleSnuff"
Using "WagonCandleFlameIgnite"
Using "WagonWeb01Clear"
Using "WagonWeb02Clear"
Using "WagonWeb03Clear"
Using "WagonWeb04Clear"

-- Wagon Interactbles (Temp Art, Please Remove)
Using "InkBallBuried"

-- Training Montage
Using "PlayerSmallReceivingTraining"
Using "PlayerMediumReceivingTraining"
Using "PlayerLargePassingTraining"

-- Caravan
Using "Overmap_Caravan_01"
Using "Overmap_Caravan_Moving_01"
Using "Overmap_Caravan_Moving_02"

Using "Overmap_Caravan_Moving_02_UP"
Using "Overmap_Caravan_Moving_02_UP_Loop"
Using "Overmap_Caravan_Moving_02_DOWN"
Using "Overmap_Caravan_Moving_02_DOWN_Loop"

Using "Overmap_Caravan_Flying_TakeOff"
Using "Overmap_Caravan_Flying_Idle"
Using "Overmap_Caravan_Flying_Landing"

Using "Overmap_Caravan_Unpack"
Using "Overmap_Caravan_Unpack_Idle"
Using "Overmap_Caravan_Repack"

Using "Overmap_Caravan_Water"
Using "Overmap_Caravan_Moving_Fidget"
Using "Overmap_Caravan_Jump"
Using "Overmap_Caravan_Moving_Hop"

Using "Overmap_Caravan_Flying_Down_Start"
Using "Overmap_Caravan_Flying_Down_End"

Using "CaravanDustCloud"
Using "CaravanDustRocksA"
Using "CaravanDustRocksB"
Using "CaravanDustRocksC"

-- LockerRooms
Using "LockerRoom_CaravanPortrait01"


-- **START SEQUENCE** --

lostCoachIds = { 50047, 212001, 211998, 211999, 212000 }
titleLogoIds = { 10036, 211006, 212065, 212008, 212070, 212188, 212205, 212178 }
animatedLogoId1 = 10035
animatedLogoId2 = 210333

OnAnyLoad
{
	function( triggerArgs )

		ValidateNodeData()

		HideSwathZero()
		if NarrationRecord["GilmanRetrieval01_Onward_StormWallOpen"] then
			Delete({ Ids = StormWallIds })
		end

		SetupWrapping()

		if not GetConfigOptionValue({ Name = "UseMouse" }) then
			TeleportCursor({ OffsetX = 960, OffsetY = 540, PlayerIndex = 1 })
		end

		local directLoad = GetConfigOptionValue({ Name = "DirectLoad" })
		if GetConfigOptionValue({ Name = "CampaignReady" }) or (directLoad ~= nil and directLoad ~= "") then
			SetConfigOption({ Name = "CampaignReady", Value = true })
			CampaignStartup()
		else
			-- Boot Menu
			BootMenu = true
			FadeOut({ Color = Color.Black })
			OpenMenu({ Name = "PauseScreen", StyleXML = "MainMenuScreen" })
			SetMenuOptions({ Name = "PauseScreen", Item = "CancelButton", Properties = { FadeTarget = 0.0, FadeOpacity = 0.0 } })
			SetConfigOption({ Name = "AllowPause", Value = false })
			TeleportCursor({ OffsetX = 654, OffsetY = 526, PlayerIndex = 1 })
			BootMenuTrackName = "/Music/UrsaIdea4_ACOUSTICmenu"

			SetMenuOptions({ Name = "PauseScreen", Item = "ExitCampaignButton", Properties = { IsVisible = false } })
			if introComplete or cameFromIntroMatch then
				StartupMusic( BootMenuTrackName )
			end

			SetMenuOptions({ Name = "PauseScreen", Item = "CampaignButton", Properties = { HelpTextId = "PauseScreen_CampaignMode", ActivateFunction = "MenuCampaignMode" } })
			--[[
			if introComplete or cameFromIntroMatch then
				SetMenuOptions({ Name = "PauseScreen", Item = "CampaignButton", Properties = { HelpTextId = "PauseScreen_ResumeSP", ActivateFunction = "MenuResumeCampaign" } })
				StartupMusic( BootMenuTrackName )
			else
				SetMenuOptions({ Name = "PauseScreen", Item = "CampaignButton", Properties = { HelpTextId = "PauseScreen_StartSP", ActivateFunction = "MenuSetupNewCampaign" } })
			end
			--]]

			BootMenu = false
		end

	end
}

function CampaignStartup()

	SetMultiplayerMatchOff()
	SetConfigOption({ Name = "CameraFollowCursor", Value = 0.0 })
	SetConfigOption({ Name = "RallyPointAnimation", Value = nil })
	SetConfigOption({ Name = "KillSpeechOnLoad", Value = true })
	SetConfigOption({ Name = "UseCampaignShortMatchIntro", Value = false })
	SetConfigOption({ Name = "GodMode", Value = false })
	SetConfigOption({ Name = "GamepadCursorControl", Value = true })

	SetRichPresence({ Name = "RP_MiscPresence" })

	ToggleControl({ Name = "Start", Enabled = true })

	AddInputBlock({ Name = "CampaignStartup" })

	-- Campaign Music and Ambience
	thread( SetCampaignMusicAndAmbience )

	SetupOvermapFade()

	if not campaign then
		DisableInput({  })
		StartCampaign()
	end

	if allowCaravanFly then
		DiscoverAllLandingPads()
	end

	-- [GK] misc campaign debug stuff
	-- NextTeam.GotGanked = true
	-- NextTeam["AscensionMatchesPlayedWhenGanked"] = 0
	-- League[11].TeamBench[1].MusicStemName = "Guitars"
	-- PlayerTeam.AscensionMatchesPlayed = 2
	-- MatchesPlayedThisSeason = 2
	-- this sets all teams to 2 wins / 2 losses vs. player, so next match is a forfeit
	-- DebugForfeitMatch()
	-- DebugLastSeasonMatch()
	-- CharMascot["RosterStatus"] = "Active"
	-- NarrationRecord["OpenStructure_Match_TizoVsTrueNightwings"] = true
	-- set characters to ascended status
	-- for characterIndex, character in pairs( PlayerTeam.TeamBench ) do
	-- 	character.RosterStatus = "Ascended"
	-- end

	-- Darren: for testing Ascension Song audio, uncomment next line and switch the number
	-- SwitchNextScheduledTeam( 9 )

	-- 2: Accusers
	-- 3: Fate
	-- 4: Dissidents
	-- 5: Withdrawn
	-- 6: Pyrehearts
	-- 7: Essence
	-- 8: Chastity
	-- 9: Tempers
	-- 11: True Nightwings

	PreLoadCampaignBinks()

	SetupOvermapMovesVariables()
	SetupOvermap()
	SetupOvermapPosition()
	SetupOvermapCamera()
	SetupOvermapSwaths()
	SetupTime() -- this needs to run after the above because the NightSky gets inserted into a DayNight that gets hidden
	SetupCaravanControls()
	SetupOvermapAtmosphere()

	campaignRecord = CampaignRecord()

	RemoveInputBlock({ Name = "CampaignStartup" })

	if GetConfigOptionValue({ Name = "BendyMode" }) then
		RestoreTimeOfDayVisuals()
		SetupOvermapCaravanAnimations()
		OvermapSubsequentPresentation()
		OvermapPresentation()
		FadeIn({ Duration = 0.1 })
		return
	end

	-- reset disabled Archjustice VO
	blockMatchVO = false

	continuedFromIntroduction = true
	local justFinishedGameIntroduction = false
	if not introComplete then
		if pvPreviousMap == nil and not GetConfigOptionValue({ Name = "SkipIntroMatch" }) then
			ContinueGameIntroduction( "preIntroMatch" )
			return
		elseif not GetConfigOptionValue({ Name = "SkipSwath0" }) then
			introMatch = false
			cameFromIntroMatch = true
			ContinueGameIntroduction( "postIntroMatch" )
			FireTrigger({ Name = "PickNextMatchVenueStar" })
			waitUntil( "gameIntroductionComplete" )
			justFinishedGameIntroduction = true
		else
			selectedNodeId = 10007
		end
	end

	AddInputBlock({ Name = "CampaignStartupWagon" })

	if selectedNodeId ~= nil and pvPreviousMap == nil then
		-- Game is loading into the end of a travel sequence
		OvermapArrivalPresentation( selectedNodeId )
		if not NodeData[currentNodeId].Unpack then
			QueueAutoUse({ Id = currentNodeId })
		end
	end

	-- Restore temporarily modified character stats after normal matches
	if cameFromSeasonMatch then
		RestoreAttributes()
	end

	if locationMenuSuspended then
		RestoreLocationMenuPresentation()
		RestoreTimeOfDayVisuals()
	end

	SetupOvermapCaravanAnimations()
	PostMatchEvent()

	if cameFromFreePlayMatch or cameFromChallengeMatch then
		RemoveInputBlock({ Name = "CampaignStartupWagon" })
	end

	if openedCaravan then
		waitUntil( "CloseCaravanPresentationComplete" )
	end

	RemoveInputBlock({ Name = "CampaignStartupWagon" })

	-- Move work to next frame
	wait(0.01)

	local doSave = PostMatchOutsideEvent()

	cameFromFreePlayMatch = false
	cameFromChallengeMatch = false
	retryDialogueDisplayed = false
	forfeitMatch = false
	blockFinalSeasonForfeit = false
	rivalryMatch = false

	if introComplete then
		OvermapSubsequentPresentation()
		OvermapPresentation()

		if locationMenuSuspended then
			RestoreLocationMenu()
		end
		AddInputBlock({ Name = "CampaingStartupResume" })
		ShowOvermapUI()
		if QueuedConversation ~= nil then
			thread( CallOutNewDialogue )
		end
	else
		AddInputBlock({ Name = "CampaingStartupResume" })

		FadeIn({ Duration = 0.2 })
		UseableOn({ Id = startingNodeId })
		introComplete = true
		PersistVariable({ Name = "introComplete" })

		cameFromIntroMatch = false
		PersistVariable({ Name = "cameFromIntroMatch" })

	end

	--SetupOvermapCaravanAnimations()

	wait(0.15)
	if not justFinishedGameIntroduction then
		EnableInput({  })
	end

	cameFromSeasonMatch = false
	cameFromAscensionMatch = false

	if doSave then
		DoLocationMenuSave()
	end

	RemoveInputBlock({ Name = "CampaingStartupResume" })

end

function PostMatchEvent()

	AddInputBlock({ Name = "PostMatchEvent" })

	-- if you win the Defense Encounter
	if pvPreviousMap == "ScenarioDefense" then
		local chosenCharacter = GetCharByRef( chosenCharacterRef )
		SelectedCharacter = chosenCharacter
		-- insert win/loss logic
		NarrationSequenceOnce( "NightWatchA_Onward" )
		defenseEncounterResult = "none"
		RemoveInputBlock({ Name = "PostMatchEvent" })
		return
	end

	-- if you win the Gilman Retrieval Encounter
	if pvPreviousMap == "ScenarioRetrieval" then
		-- insert win/loss logic
		NarrationSequenceOnce( "GilmanRetrieval01_Onward" )
		RemoveInputBlock({ Name = "PostMatchEvent" })
		return
	end

	if cameFromFreePlayMatch or cameFromChallengeMatch then
		ShowWagonScenePostMatch()
		SetConfigOption({ Name = "CameraFollowCursor", Value = 0.0 })
		wait(1.7)
		local event = ChoosePostPracticeMatchEvent()
		if event ~= nil then
			NarrationSequence( event )
		end
		CheckGuideBookUnlocks()
		RemoveInputBlock({ Name = "PostMatchEvent" })
		return
	end

	if not cameFromSeasonMatch then
		RemoveInputBlock({ Name = "PostMatchEvent" })
		return
	end

	-- Week 2 / after Ridge match / Demo Ending Exception
	if matchesPlayed == 1 and currentNodeId == 10010 and goalNodeId == 10010 then
		ShowWagonScenePostMatch()
		SetConfigOption({ Name = "CameraFollowCursor", Value = 0.0 })
		wait(1.7)
	-- Week 3 / after Spring match
	elseif matchesPlayed == 2 and currentNodeId == 210298 and goalNodeId == 210298 then
		AwakenBard()
		PreMinstrelGone()
		ShowWagonScenePostMatch()
		SetConfigOption({ Name = "CameraFollowCursor", Value = 0.0 })
		MinstrelGone() -- has a wait in it
	elseif matchesPlayed >= 1 and JustCameFromAnyMatch() then
		ShowWagonScenePostMatch()
		SetConfigOption({ Name = "CameraFollowCursor", Value = 0.0 })
		wait(1.7)
	end

	-- take off immediately after non-ascension matches or later Ascension Matches
	if not JustCameFromAscensionMatch() or PlayerTeam.AscensionMatchesPlayed >= 4 then
		PurgeSideConversations()
		if allowCaravanFly then
			takeoffQueued = true
			PersistVariable({ Name = "takeoffQueued" })
		end
	end

	-- Check GuideBook unlocks after first Ascension Match
	if JustCameFromAscensionMatch() and PlayerTeam.AscensionMatchesPlayed > 1 then
		CheckGuideBookUnlocks()
	end

	PickNarrationEvent()

	CheckSideConversations()

	RemoveInputBlock({ Name = "PostMatchEvent" })
end

function PostMatchOutsideEvent()

	if not cameFromSeasonMatch then
		return false
	end

	-- post-match sequences; follow-up in OvermapScripts
	-- Week 2 / after Ridge match
	if matchesPlayed == 1 and currentNodeId == 10010 and goalNodeId == 10010 then
		NarrationSequence( "Intro_Week2_Onward_Outside" )
	-- Week 3 / after Spring match
	elseif matchesPlayed == 2 and currentNodeId == 210298 and goalNodeId == 210298 then
		if NarrationRecord["SideConversation_Friend_WagonOrigins"] then
			NarrationSequence( "Week3_Onward_Outside_Alt" )
		else
			NarrationSequence( "Week3_Onward_Outside" )
		end
	-- Week 4 / after Canyon match
	elseif matchesPlayed == 3 and currentNodeId == 10004 and goalNodeId == 10004 then
		NarrationSequence( "Week4_Onward_Outside" )
	-- Week 5 / after Lair match
	elseif matchesPlayed == 4 and currentNodeId == 10029 and goalNodeId == 10029 then
		NarrationSequence( "Week5_Onward_Outside" )
	-- Week 6 / after Ship match
	elseif matchesPlayed == 5 and currentNodeId == 10052 and goalNodeId == 10052 then
		NarrationSequence( "Week6_Onward_Outside" )
	-- Week 7 / after Lava match
	elseif matchesPlayed == 6 and currentNodeId == 10040 and goalNodeId == 10040 then
		NarrationSequence( "Week7_Onward_Outside" )
	-- Week 8 / after Woods match
	elseif matchesPlayed == 7 and currentNodeId == 10041 and goalNodeId == 10041 then
		NarrationSequence( "Week8_Onward_Outside" )
	-- Week 9 / after Ascension match
	elseif matchesPlayed == 8 and currentNodeId == 10049 and goalNodeId == nil and not movesAvailableUnknown then
		NarrationSequence( "Week9_Onward_Outside" )
	-- Week 10+ / open structure
	elseif matchesPlayed > 8 and NodeData[currentNodeId]["Category"] == "Arena" then
		if not JustCameFromAscensionMatch() then
			-- Open Structure season weeks
			if not IsAscensionWeek() then
				-- excluding weeks after Ascension Matches due to Moonlight Alcove exception
				if currentNodeId ~= 10049 then
					-- Isle of Khaylmer exception
					if PlayerTeam.AscensionMatchesPlayed == 2 and MatchesPlayedThisSeason == 1 then
						NarrationSequence( "OpenStructure_Onward_01_HiddenArena_Outside" )
					elseif PlayerTeam.AscensionMatchesPlayed > 0 then
						if ActiveNarrationName == "OpenStructure_Onward_StandingsScreenUnlocked_YouWon" or ActiveNarrationName == "OpenStructure_Onward_StandingsScreenUnlocked_YouLost" then
							NarrationSequence( "OpenStructure_Onward_StandingsScreenUnlocked_Outside" )
						else
							NarrationSequence( "OpenStructure_Onward_01_Outside" )
						end
					end
				end
			-- Open Structure Ascension weeks
			else
				FireTrigger({ Name = "EndCurrentMusic" })
				if PlayerTeam.AscensionMatchesPlayed == 1 then
					NarrationSequence( "OpenStructure_Onward_Ascension2_Outside" )
					return true
				elseif PlayerTeam.AscensionMatchesPlayed == 2 then
					NarrationSequence( "OpenStructure_Onward_Ascension3_Outside" )
					return true
				elseif PlayerTeam.AscensionMatchesPlayed == 3 then
					NarrationSequence( "OpenStructure_Onward_Ascension4_Outside" )
					return true
				elseif PlayerTeam.AscensionMatchesPlayed == 4 then
					NarrationSequence( "OpenStructure_Onward_Ascension5_Outside" )
					return true
				elseif PlayerTeam.AscensionMatchesPlayed == 5 then
					NarrationSequence( "OpenStructure_Onward_Ascension6_Outside" )
					return true
				-- Final Liberation Star Pick
				elseif PlayerTeam.AscensionMatchesPlayed == 6 then
					NarrationSequence( "OpenStructure_Onward_Ascension7_Outside" )
					return true
				end
			end
		-- Open Structure Post-Ascension weeks
		else
			if PlayerTeam.AscensionMatchesPlayed == 4 then
				NarrationSequence( "OpenStructure_PostAscension4_Outside" )
			elseif PlayerTeam.AscensionMatchesPlayed == 5 then
				NarrationSequence( "OpenStructure_PostAscension_Outside" )
			elseif PlayerTeam.AscensionMatchesPlayed >= 6 then
				NarrationSequence( "OpenStructure_PostAscension6_Outside" )
			end
		end
	end

	return true

end

-- **EVENTS** --

-- opening splash screen prior to Literacy Test
function SetupOpeningSplash2()
	SetFlagTrue({ Set = "FLAGS", Name = "HIDE_CURSOR" })

	AdjustFullscreenBloom({ Name = "Subtle" })
	openingSplash = true

	wait(0.15)

	MovingHoldCamera({ Enabled = true, Range = { 20, 6 } })

	wait(0.5)
	SetFlagTrue({ Name = "CanSkipOpeningSplash" })
end

OnControlPressed{ "Pass Cast Jump Sprint Select Move Use Start",
	RequiredFlag = "CanSkipOpeningSplash",
	function( triggerArgs )
		SetFlagFalse({ Name = "CanSkipOpeningSplash" })
		openingSplash = false
		SetFlagFalse({ Set = "FLAGS", Name = "HIDE_CURSOR" })

		Rumble({ RightFraction = 0.3, Duration = 0.335 })

		KioskModeAutoRestart()

		notifyExistingWaiters( "OpeningSplashInputDetected" )

	end
}

-- Game Introduction
function ContinueGameIntroduction( args )

	exileCoach = 40049
	exileFriend = 40052
	overMapSky = 40059

	SetRichPresence({ Name = "RP_Campaign_Swath00" })

	-- camera & input
	DisableInput({  })

	-- clamps need to be reset to account for the intro
	if args == "postIntroMatch" then
		useSwathZeroClamps = true
		SetupOvermapClamps()
	else
		SetupOvermapClamps()
	end

	-- fade out all scenes
	SetOpacity({ Name = "Swath_00_Scenes", Fraction = 0, Duration = 0 })
	SetOpacity({ Name = "Swath_00_Montage", Fraction = 0, Duration = 0 })

	wait(0.125) -- this ridiculous wait is for the race condition to hide all of Swath 0 on load
	if swathZeroHidden then
		ShowSwathZero()
	end

	if args ~= "postIntroMatch" then
		StopSound({ Name = "/SFX/Object Ambiences/WastelandAmbience", Duration = 5 })
	end

	-- swath scene 1
	SetOpacity({ Ids = { 50002 }, Fraction = 1, Duration = 0.3 })
	SetOpacity({ Ids = { 50015 }, Fraction = 1, Duration = 0.3, Delay = 5 })

	-- swath montage 1
	SetOpacity({ Ids = { 50002 }, Fraction = 1, Duration = 0.3 })
	SetOpacity({ Ids = { 50015 }, Fraction = 1, Duration = 0.3 })

	if args == "preIntroMatch" then

		SetConfigOption({ Name = "AllowPause", Value = false })

		FireTrigger({ Name = "AddFriendToRoster" })
		FireTrigger({ Name = "AddBadassToRoster" })
		FireTrigger({ Name = "AddJokerToRoster" })

		PassOutInSandfolds()

		CloseRosterDoor()

		-- teleport cursor to position of first tooltip in English using gamepad only
		if not GetConfigOptionValue({ Name = "UseMouse" }) then
			TeleportCursor({ OffsetX = 543, OffsetY = 797 })
		end

		-- tooltip tutorial
		FireTrigger({ Name = "TooltipTutorial" })

		NarrationSequence( "Intro" )

	elseif args == "postIntroMatch" then
		postIntroMatch = true

		SetOpacity({ Ids = titleLogoIds, Fraction = 0.0 })
		SetOpacity({ Ids = lostCoachIds, Fraction = 0.0 })
		SetOpacity({ Name = "BirdsB", Fraction = 0.0 })

		fakeSwathZeroNight = true
		SetOpacity({ Name = "Swath_00_Night01", Fraction = 1, Duration = 0 })

		Teleport({ Id = realOvermapUnit, DestinationId = 50149 })

		AngleTowardTarget({ Id = realOvermapUnit, DestinationId = 40031 })
		SetColor({ Id = realOvermapUnit, Color = Color.White })
		AddToGroup({ Id = realOvermapUnit, Name = "Swath_00_StandingObjects01", DrawGroup = true })

		wait(0.3)

		MusicPlayer( "/Music/ScavengersTheme_MC" )
		SetVolume({ Id = MusicId, Value = 0.0 })
		-- Track loops at 3:15
		SetSoundPosition({ Id = MusicId, Position = 194 * 1000 })
		wait(2.0)
		SetVolume({ Id = MusicId, Value = 1.0, Duration = 0.5 })
		wait(0.02)

		ShowWagonScenePostMatch()
		SetConfigOption({ Name = "CameraFollowCursor", Value = 0.0 })

		NarrationSequence( "Intro_PostMatch" )

		PlaySound({ Name = "/SFX/Object Ambiences/WastelandAmbience" })
		StopSound({ Name = "/SFX/Object Ambiences/WastelandAmbience", Duration = 15 })

		if TitanMode then
			NarrationSequence( "Intro_PostMatch_Outside_TitanMode" )
		else
			NarrationSequence( "Intro_PostMatch_Outside" )
		end

	end
end


function PassOutInSandfolds()

	local startingCameraPosition = 40001

	DisableInput({  })

	SwitchAmbience( "Ambience/Swath1Ambience" )

	-- setup startng camera position
	--LockCamera({ Id = startingCameraPosition, OffsetY = -1000 })
	PanCamera({ Id = startingCameraPosition, Duration = 0.05, EaseIn = 0.05, OffsetY = -300, Retarget = true })
	AdjustZoom({ Fraction = 1.0, LerpTime = 0.1, Duration = 999999 })
	AdjustFullscreenBloom({ Name = "IntroLightSat", Duration = 0.05 })

	SetOpacity({ Ids = lostCoachIds, Fraction = 1 })

	-- used for abridged intro
	SetOpacity({ Ids = titleLogoIds, Fraction = 0.0 })

	SetOpacity({ Name = "Swath_00_Night01", Fraction = 0 })

	wait(0.05)

	-- begin camera motion
	local passOutCameraDuration = 4 * 4
	--local passOutCameraDuration = 1
	--local beginZoomFraction = 1.2
	local beginZoomFraction = 0.8
	--local completeZoomFraction = 0.825
	local completeZoomFraction = 0.825

	AdjustFullscreenBloom({ Name = "Subtle", Duration = passOutCameraDuration/2.2 })
	PanCamera({ Id = startingCameraPosition, Retarget = true, OffsetY = -200, EaseIn = 0.05, EaseOut = 0.3, Duration = passOutCameraDuration })
	FocusCamera({ Fraction = beginZoomFraction, Duration = 0.05, ZoomType = "Ease" })
	FocusCamera({ Fraction = completeZoomFraction, Duration = passOutCameraDuration * 1.1, ZoomType = "Ease", Delay = 0.1 })
	FocusCamera({ Fraction = completeZoomFraction, Duration = passOutCameraDuration * 1.1, ZoomType = "Ease", Delay = 0.1 })

	wait(0.1)

	if skipSentencing then
		FadeIn({ Duration = 3 })
	else
		FadeIn({ Duration = 0.5 })
	end

	local logoDelay = 4
	SetOpacity({ Ids = titleLogoIds, Fraction = 1.0, Duration = 0.5, Delay = logoDelay })
	Activate({ Id = animatedLogoId1, Delay = logoDelay })

	MovingHoldCamera({ Enabled = true, Range = { 20, 5 } })

	wait(logoDelay + 1.9)
	SetupOpeningSplash2()
	waitUntil( "OpeningSplashInputDetected" )

	StopSound({ Name = "/SFX/Menu Sounds/LogoBurnIn", Duration = 0.3 })
	SetOpacity({ Ids = titleLogoIds , Fraction = 0.0, Duration = 0.5 })
	PlayAnimation({ Name = "PyreLogoOut", DestinationId = animatedLogoId1 })
	SetConfigOption({ Name = "AllowPause", Value = true, Delay = 0.5 })
	FadeOutAmbience( 15 )

	ScavengersArrive()

end

function ScavengersArrive()
	--local offscreenCaravanStart = 50148
	local offscreenCaravanStart = 50106
	offscreenCaravanBendies = { 50151, 50150, 50152, 50149 }
	local offscreenCaravanEnd = 50149

	-- prep caravan
	DisableInput({ PlayerIndex = 1 })
	SetOpacity({ Id = realOvermapUnit, Fraction = 1 })
	SetScale({ Id = realOvermapUnit, Fraction = 3 })
	SetColor({ Id = realOvermapUnit, Color = Color.Black })
	SetUnitProperty({ Id = realOvermapUnit, Property = "CollideWithObstacles", Value = false })
	AddToGroup({ Id = realOvermapUnit, Name = "Swath_00_StandingObjects01", DrawGroup = true })

	wait(1)
	Teleport({ Id = realOvermapUnit, DestinationId = offscreenCaravanStart })
	AngleTowardTarget({ Id = realOvermapUnit, DestinationId = 50107 })
	wait(0.1)
	--PanCamera({ Id = 50151, Duration = 4, EaseIn = 0.5, EaseOut = 0.5, OffsetY = -220 })
	--PanCamera({ Id = realOvermapUnit, Duration = 4, EaseIn = 0.2, EaseOut = 1, Delay = 2 })

	--local panDownDuration = 19
	--local panDownDuration = 15.3
	--[[
	local panDownDuration = 15.3
	PanCamera({ Id = 50047, Duration = panDownDuration, EaseIn = 0, EaseOut = 2, OffsetY = 0, Delay = 0 })
	wait(3)
	OffscreenCaravanEntrance( realOvermapUnit )
	]]
	local panDownDuration = 15.3
	--local panDownDuration2 = 10
	PanCamera({ Id = 50047, Duration = panDownDuration, EaseIn = 0, EaseOut = 2, OffsetY = 0, Delay = 0 })
	--PanCamera({ Id = 50047, Duration = panDownDuration2, EaseIn = 0, EaseOut = 2, OffsetY = 0, Delay = panDownDuration, Retarget = true })
	wait(3)
	OffscreenCaravanEntrance2(realOvermapUnit)

	DisableInput({ PlayerIndex = 1 })

	wait(1.3)

	PlaySound({ Name = "/SFX/Leftovers/DoorClose", Id = realOvermapUnit, Delay = 0.35 })

	wait(0.5)
	--MovingHoldCamera({ Enabled = true, Range = { 10, 0 } })
end


function OffscreenCaravanEntrance( caravanId )
	local BendyPath = offscreenCaravanBendies

	DisableInput({ PlayerIndex = 1 })
	SetUnitProperty({ DestinationId = realOvermapUnit, Name = "Speed", Value = 300 })

	CreateBendy({Id = realOvermapUnit, DestinationId = BendyPath})
	EnableBendy({Id = realOvermapUnit})

	FireTrigger({ Name = "PrologueMusic" })
	caravanSoundId = PlaySound({ Name = "/SFX/World Sounds/CaravanAmbience1", Id = realOvermapUnit })

	--local slowFraction = 0.3
	local slowFraction = 0.48
	local bendyLimit = #BendyPath
	for index = 1, bendyLimit, 1 do
		Move({ Id = realOvermapUnit, DestinationId = BendyPath[index] })

		--per node effects
		if BendyPath[index] == 50151 then
			SetColor({ Id = realOvermapUnit, Color = Color.White, Duration = 3 })
			SetScale({ Id = realOvermapUnit, Fraction = 1, Duration = 3 })
		end

		if index == 2 or index == 3 then
			PlayAnimation({ Name = "Overmap_Caravan_Moving_Fidget", DestinationId = realOvermapUnit })
		end

		if index == 4 then
			PlayAnimation({ Name = "Overmap_Caravan_Moving_02", DestinationId = realOvermapUnit })
		end

		if index > 2 then
			AdjustBendySpeed({ Id = realOvermapUnit, Fraction= slowFraction, Duration = 1 })
			--local currentBendyZoom = GetCameraZoom({ })
			--PanCamera({ Id = BendyPath[index], Duration = 1, EaseIn = 0.05, EaseOut = 0.1 })
		--	FocusCamera({ Fraction = currentBendyZoom * 1.03, Duration = 0.3, ZoomType = "Overshoot" })
		end

		if index == 4 then
			slowFraction = slowFraction * 0.5
			AdjustBendySpeed({ Id = realOvermapUnit, Fraction= 0.1, Duration = 8 })
			--local currentBendyZoom = GetCameraZoom({ })
			--PanCamera({ Id = BendyPath[index], Duration = 1, EaseIn = 0.05, EaseOut = 0.1 })
		--	FocusCamera({ Fraction = currentBendyZoom * 1.03, Duration = 0.3, ZoomType = "Overshoot" })
		end

		--check when next node is in range
		local nearestBendy = GetClosest({ Id = realOvermapUnit, DestinationId = BendyPath[index], Distance = 20 })
		while nearestBendy == 0 do
			nearestBendy = GetClosest({ Id = realOvermapUnit, DestinationId =  BendyPath[index], Distance = 15 })
			wait(0.01)
		end

		if BendyPath[index] == 50149 then
			thread(BirdsLeaveCoach, 50014)
			ShakeScreen({ Speed = 150, Distance = 3, FalloffSpeed = 2000, Duration = 0.3, Delay = 0.05 })
			StopSound({ Name = "/SFX/World Sounds/CaravanAmbience1", Duration = 0.5 })
		end

		if index == 1 then
		--	AdjustBendySpeed({ Id = realOvermapUnit, Fraction= 1.5, Duration = 7 })
		end

		if index == 2 then
		--	AdjustBendySpeed({ Id = realOvermapUnit, Fraction= 1.5, Duration = 3 })
		end

		--PlayOverheadAnimation({ Name = "WalkDustLarge", DestinationId = bendyId, IgnoreOverheadOffset = true })
	end
end

function OffscreenCaravanEntrance2( caravanId )
	local BendyPath = { 50106, 50107, 50108, 50149}

	DisableInput({ PlayerIndex = 1 })
	SetUnitProperty({ DestinationId = realOvermapUnit, Name = "Speed", Value = 300 })

	CreateBendy({Id = realOvermapUnit, DestinationId = BendyPath})
	EnableBendy({Id = realOvermapUnit})

	FireTrigger({ Name = "PrologueMusic" })
	caravanSoundId = PlaySound({ Name = "/SFX/World Sounds/CaravanAmbience1", Id = realOvermapUnit })

	SetColor({ Id = realOvermapUnit, Color = Color.Black, Duration = 0.1 })
	SetScale({ Id = realOvermapUnit, Fraction = 5, Duration = 0.1 })

	Rumble({ RightFraction = 0.125, Duration = 4.0, Delay = 1.8 })
	Rumble({ LeftFraction = 0.17, Duration = 1.3, Delay = 5.9 })

	Rumble({ RightFraction = 0.15, Duration = 4.0, Delay = 11 })

	SetUnitProperty({ Name = "CosmeticRotationSpeedMinDelta", DestinationId = realOvermapUnit, Value = math.rad( 12 ) })

	--local slowFraction = 0.3
	local slowFraction = 0.48
	local bendyLimit = #BendyPath
	for index = 1, bendyLimit, 1 do
		Move({ Id = realOvermapUnit, DestinationId = BendyPath[index] })
		--[[
		if index == 1 then
			Move({ Id = realOvermapUnit, DestinationId = BendyPath[index], Delay = 2.5 })
		else
			Move({ Id = realOvermapUnit, DestinationId = BendyPath[index] })
		end
		]]

		--per node effects
		if BendyPath[index] == 50107 then

			SetColor({ Id = realOvermapUnit, Color = Color.White, Duration = 8 })
			SetScale({ Id = realOvermapUnit, Fraction = 1, Duration = 8 })
		end

		if index == 2 then
			PlayAnimation({ Name = "Overmap_Caravan_Moving_Fidget", DestinationId = realOvermapUnit, Delay = 4.5 })
		end

		if index == 3 then
			PlayAnimation({ Name = "Overmap_Caravan_Moving_Fidget", DestinationId = realOvermapUnit })
		end

		if index == 4 then
			PlayAnimation({ Name = "Overmap_Caravan_Moving_02", DestinationId = realOvermapUnit })
		end

		if index > 3 then

		end

		if index == 4 then
			AdjustBendySpeed({ Id = realOvermapUnit, Fraction= slowFraction * 1.2, Duration = 0.05 })
			slowFraction = slowFraction * 0.5
			AdjustBendySpeed({ Id = realOvermapUnit, Fraction= 0.25, Duration = 12, Delay = 0.1 })
		end

		--check when next node is in range
		local nearestBendy = GetClosest({ Id = realOvermapUnit, DestinationId = BendyPath[index], Distance = 20 })
		while nearestBendy == 0 do
			nearestBendy = GetClosest({ Id = realOvermapUnit, DestinationId =  BendyPath[index], Distance = 15 })
			wait(0.01)
		end

		if BendyPath[index] == 50149 then
			wait(.15)
			thread(BirdsLeaveCoach, 50014)
			ShakeScreen({ Speed = 150, Distance = 3, FalloffSpeed = 2000, Duration = 0.3, Delay = 0.05 })
			StopSound({ Name = "/SFX/World Sounds/CaravanAmbience1", Duration = 0.5 })
		end

		if index == 1 then
		end

		if index == 2 then
		end

	end

	SetUnitProperty({ Name = "CosmeticRotationSpeedMinDelta", DestinationId = realOvermapUnit, Value = math.rad( 0 ) })
end

OnTriggerFired
{ "DemoEnding",
	function(triggerArgs)
		demoPan = true

		AddInputBlock({ Name = "DemoEnding" })

		PlayAnimation({Name = "Overmap_Caravan_01", DestinationId = realOvermapUnit })
		AngleTowardTarget({ Id = realOvermapUnit, DestinationId = 40033 })

		local StarStuff = GetGroupWithSubGroups({ Name = "NightSky" })
		SetOpacity({ Names = StarStuff, Fraction = 0 })
		SetParallax({ Names = StarStuff, Parallax = 2, MatchScale = true, Duration = 0.1 })
		SetGroupVisibility({ Names = StarStuff, Visible = true })
		SetOpacity({ Names = DemoGroups, Fraction = 0 })

		-- replace stop graphic with a silent version
		SetUnitProperty({ Name = "StopGraphic", Value = "Overmap_Caravan_Stopping_01_Silent", DestinationId = realOvermapUnit })
		SetUnitProperty({ Name = "MoveGraphic", Value = "Overmap_Caravan_Stopping_02_Silent", DestinationId = realOvermapUnit })

		RemoveWorldText({ DestinationId = locationTextConstant, Duration = 0 })
		thread( SwathContextVisuals, "GoingOut" )
		CloseCaravanPresentation()
		HideOvermapUI()
		HideOvermapLocationIndicators()

		local demoPanEnd = 40026
		local demoPanOffsetY = -1200

		local demoPanDuration = 15

		ClearCameraClamp({ LerpTime = 0.1 })
		FocusCamera({ Fraction = OVERMAP_ZOOM_DEFAULT * 0.7, Duration = demoPanDuration * 1.5, ZoomType = "Ease", Delay = 0.5 })
		MovingHoldCamera({ Enabled = true, Range = { 30, 10 }, Delay = demoPanDuration * 1.5 })

	--	AdjustColorGrading({ Name = "NightMoon", Duration = 8.75, Delay = 0 })
		AdjustFullscreenBloom({ Name = "TestJosh", Duration = 6.75, Delay = 0 })

		local departure = 40007
		local arrival = 40008
		--thread(SwathTransition, departure, arrival, "Forward" )
		thread(DemoBendy, 0.5)

		-- fade in art
		local fadeDelay = 6.95

	--	AdjustColorGrading({ Name = "MeteorStrike", Duration = 0.1, Delay = fadeDelay - 0.1 })
		AdjustFullscreenBloom({ Name = "NewType06", Duration = 0.1, Delay = fadeDelay - 0.01 })
		InsertGroupInFront({ Names = StarStuff, DestinationName = "Swath_01_InteractPoints" })
		InsertGroupInFront({ Names = DemoGroups, DestinationName = "Swath_01_Scripting" })

		SetOpacity({ Names = StarStuff, Fraction = 1, Duration = 0.5, Delay = fadeDelay })
		SetOpacity({ Names = DemoGroups, Fraction = 1, Duration = 0.5, Delay = fadeDelay })
		PlaySound({ Name = "/SFX/World Sounds/MapZoomOut", Delay = fadeDelay })
	--	AdjustColorGrading({ Name = "Off", Duration = 2.0, Delay = fadeDelay + 0.6  })
		AdjustFullscreenBloom({ Name = "Off", Duration = 2.0, Delay = fadeDelay + 0.6  })

		-- fade in logo
		local logoEntranceDelay = 7.15
		Activate({ Id = animatedLogoId2, Delay = logoEntranceDelay })
		StopSound({ Name = "/SFX/Menu Sounds/StoryRecapTextAppearQuiet", Delay = logoEntranceDelay, Duration = 1.0 })
		PlaySound({ Name = "/SFX/Menu Sounds/UIBurn", Delay = logoEntranceDelay })
		Rumble({ RightFraction = 0.2, Duration = 0.3, Delay = logoEntranceDelay })

		wait(fadeDelay)

		MovingHoldCamera({ Enabled = true, Range = { 20, 5 } })
		SetOvermapMusic( "end" )

		--wait(7.5)
		wait(4.5)

		CampaignRecordEnd( campaignRecord )
		campaignRecord = nil
		FireTrigger({ Name = "SetupDemoRestart" })
		RemoveInputBlock({ Name = "DemoEnding" })

		--thread(EndLogoBloomer)
	end
}

function DemoBendy( bendyDelay )
	local BendyPath = { 10010, 40033, 50117, 40037, 40038, 40026, 50004 }

 	if bendyDelay ~= nil and bendyDelay > 0 then
		wait(bendyDelay)
	end

	--local startingSpeed = 200
	local startingSpeed = 150

	AddInputBlock({ Name = "DemoBendy" })
	SetUnitProperty({ DestinationId = realOvermapUnit, Name = "Speed", Value = startingSpeed })

	CreateBendy({Id = realOvermapUnit, DestinationId = BendyPath})
	EnableBendy({Id = realOvermapUnit})

	caravanSoundId = PlaySound({ Name = "/SFX/World Sounds/CaravanAmbience1", Id = realOvermapUnit })
	Rumble({ RightFraction = 0.2, Duration = 0.3 })

	-- caravan
	-- AddToGroup({ Id = realOvermapUnit, Name = "Swath_00_StandingObjects01", DrawGroup = true })
	SetScale({ Id = realOvermapUnit, Fraction = 0.75, Duration = 8, Delay = 5 })
	PlayAnimation({ Name = "Overmap_Caravan_Moving_Hop", DestinationId = realOvermapUnit, Delay = 0.1 })
	Rumble({ RightFraction = 0.22, Duration = 0.25, Delay = 0.2 })
	Rumble({ RightFraction = 0.22, Duration = 0.325, Delay = 0.4 })

	--PlayAnimation({ Name = "Overmap_Caravan_Moving_02", DestinationId = realOvermapUnit, Delay = 1.3 })
	PlayAnimation({ Name = "Overmap_Caravan_Moving_Fidget", DestinationId = realOvermapUnit, Delay = 1.8 })

	CaravanLongJump( 3.8 )

	local bendyLimit = #BendyPath
	for index = 2, bendyLimit, 1 do
		Move({ Id = realOvermapUnit, DestinationId = BendyPath[index] })

		if BendyPath[index] == 50117 then
			AdjustBendySpeed({ Id = realOvermapUnit, Fraction = 0.75, Duration = 0.5, Delay = 0 })
		end

		--check when next node is in range
		local bendyDistance = 15
		if index == bendyLimit then
			bendyDistance = 60
		end

		local nearestBendy = GetClosest({ Id = realOvermapUnit, DestinationId = BendyPath[index], Distance = bendyDistance })
		while nearestBendy == 0 do
			nearestBendy = GetClosest({ Id = realOvermapUnit, DestinationId =  BendyPath[index], Distance = bendyDistance })
			wait(0.01)
		end

		--per node effects
		if BendyPath[index] == 40037 then
			--DemoBendyJump
		end

		if BendyPath[index] == 40053 then
		end

		if index == bendyLimit then
			return
		end
	end
end

function ShowDemoEndingText( demoEndingText, offsetY )

	DemoEndingTextProperties =
	{
		Id = endScreenTextConstant,
		Group = "ScreenOverlay", Text = demoEndingText, Justification = "CENTER",
		ShadowBlur = 0, ShadowColor = {0.141,0.125,0.231,1.0}, ShadowOffset = {0, 5},
		OutlineThickness = 3.0, OutlineColor = {0.141,0.125,0.231,1.0},
		Color = {0.902, 0.816, 1.00}, Font = "AlegreyaSCRegular60", LerpTime = 0.16, Interval = 0.05,
		Scale = 0.6,
		TextSymbolScale = 1.0,
		OffsetY = offsetY,
	}

	DisplayWorldText( DemoEndingTextProperties )

	PlaySound({ Name = "/SFX/Menu Sounds/UIBurn" })

end

-- Demo / KioskMode end screen
OnTriggerFired
{ "SetupDemoRestart",
	function(triggerArgs)

		-- attempt to allow text to live in world so it doesn't swim with movingcamerahold [AR 3/10]
		--[[
		endScreenTextConstant = SpawnObstacle({ Name = "InvisibleTarget", Group = "Scripting", DestinationName = "Player" })
		DrawScreenRelative({ Id = endScreenTextConstant })
		Teleport({ Id = endScreenTextConstant, OffsetX = 1920/2, OffsetY = 560 })
		]]

		-- OffsetX endScreenTextConstant by -50px to align more closely with text portion of Pyre logo
		--endScreenTextConstant = SpawnObstacle({ Name = "InvisibleTarget", Group = "Swath_02_WaterBacking01", DestinationId = 212339, OffsetY = 560, OffsetX = -50 })
		endScreenTextConstant = SpawnObstacle({ Name = "InvisibleTarget", Group = "Swath_02_DemoLogo", DestinationId = 50064, OffsetY = 500, OffsetX = -50 })

		wait(1.25)
		ShowDemoEndingText( "KioskMode_EndScreen_02" )

		PlayOverheadAnimation({ Name = "DemoEndTextShadow", DestinationId = endScreenTextConstant, IgnoreOverheadOffset = true })

		wait(3.5)
		ShowDemoEndingText( "KioskMode_EndScreen_03" )
		PlaySound({ Name = "/Ambience/StarPickerAmbienceLoopQuiet" })
		wait(9.0)
		SetConfigOption({ Name = "AllowPause", Value = false })
		ShowDemoEndingText( "KioskMode_EndScreen_05" )
		SetFlagTrue({ Name = "CanRestartKioskMode" })

	end
}

-- restarts Demo / KioskMode after user input
OnControlPressed{ "Pass Cast Jump Sprint Select Move Use Start",
	RequiredFlag = "CanRestartKioskMode",
	function( triggerArgs )
		SetFlagFalse({ Name = "CanRestartKioskMode" })
		DisableInput({  })

		PlayAnimation({ Name = "PyreLogoOut", DestinationId = animatedLogoId2 })

		StopSound({ Name = "/Ambience/StarPickerAmbienceLoopQuiet", Duration = 2.0 })
		RemoveWorldText({ DestinationId = locationTextConstant, Duration = 0.2 })
		PlaySound({ Name = "/SFX/Menu Sounds/GuideBookClose" })
		FadeOut({ Color = Color.Black, Duration = 1.5 })
		wait(3.5)
		RestartKioskMode()
	end
}

function EndLogoBloomer()
	while true do
		local Blooms = { "Default", "SoftPickup", "StinkweedLighter", "Dream"}
		local randomBloom = GetRandomValue(Blooms)
		local randomBloomDuration = math.random(2, 4)
		AdjustFullscreenBloom({ Name = randomBloom, Duration = randomBloomDuration })
		wait(randomBloomDuration + 1)
	end
end

function TrainingMontage()
	PlaySound({ Name = "/SFX/World Sounds/ChoirZoomIn" })

	StopAnimation({ Names = { "PlayerSmallReceivingTraining", "PlayerMediumReceivingTraining", "PlayerLargePassingTraining"  }, DestinationIds = MontageUnitAnchors, PreventChain = true })
	Destroy({ Ids = MontageUnitAnchors })

	montageUnitAnchor01 = SpawnObstacle({ Name = "InvisibleTarget", DestinationId = realOvermapUnit, Group = "Events" })
	montageUnitAnchor02 = SpawnObstacle({ Name = "InvisibleTarget", DestinationId = realOvermapUnit, Group = "Events" })
	montageUnitAnchor03 = SpawnObstacle({ Name = "InvisibleTarget", DestinationId = realOvermapUnit, Group = "Events" })
	MontageUnitAnchors =  { montageUnitAnchor01, montageUnitAnchor02, montageUnitAnchor03 }
	DrawScreenRelative({ Ids = MontageUnitAnchors })
	Teleport({ Id = montageUnitAnchor01, OffsetX = 0 + 230, OffsetY = 1080 + 0 })
	Teleport({ Id = montageUnitAnchor02, OffsetX = (1920/2) + 230, OffsetY = 1080 + 200})
	Teleport({ Id = montageUnitAnchor03, OffsetX = (1920 - 300), OffsetY = 1080 + 100 })

	--preTestBloom = GetBloomSettingName({ })
	--AdjustFullscreenBloom({ Name = "SaturatedLight", Duration = 0.7 })

	local montageInterval = 0.3

	PlaySound({ Name = "/SFX/Match SFX/FastMoveWhoosh", Delay = 0 })
	PlaySound({ Name = "/SFX/Match SFX/FastMoveWhoosh", Delay = montageInterval * 2 })
	PlaySound({ Name = "/SFX/Match SFX/FastMoveWhoosh", Delay = montageInterval * 3 })

	PlaySound({ Name = "/SFX/Player Sounds/Vocalizations/Jodi/EmoteAttacking", Delay = 0 })
	PlaySound({ Name = "/SFX/Player Sounds/Vocalizations/Hedwyn/EmoteAttacking", Delay = montageInterval * 2 })
	PlaySound({ Name = "/SFX/Player Sounds/Vocalizations/Rukey/EmoteAttacking", Delay = montageInterval * 3 })

	Rumble({ LeftFraction = 0.4, Duration = 0.15, Delay = 0.1 })
	Rumble({ Fraction = 0.3, Duration = 0.15, Delay = montageInterval * 2 })
	Rumble({ RightFraction = 0.35, Duration = 0.15, Delay = montageInterval * 3 })

	PlayOverheadAnimation({ Name = "PlayerLargePassingTraining", DestinationId = montageUnitAnchor01, IgnoreOverheadOffset = true, Color = Color.Black, Scale = 2, Angle = 0, Delay = 0 })
	PlayOverheadAnimation({ Name = "PlayerMediumReceivingTraining", DestinationId = montageUnitAnchor02, IgnoreOverheadOffset = true, Color = Color.Black, Scale = 2.15, Angle = 90, Delay = montageInterval * 2 })
	PlayOverheadAnimation({ Name = "PlayerSmallReceivingTraining", DestinationId = montageUnitAnchor03, IgnoreOverheadOffset = true, Color = Color.Black, Scale = 2.15, Angle = 90, Delay = montageInterval * 3 })

	Move({ Ids = MontageUnitAnchors, Speed = 300, Angle = 90, Delay = 0.1 })
	Stop({ Ids = MontageUnitAnchors, Delay = 0.5 })
	Move({ Ids = MontageUnitAnchors, Speed = 90, Angle = 90, Delay = 0.5 })

	wait(1.485)
	EndTrainingMontage()
end

function EndTrainingMontage()

	--AdjustFullscreenBloom({ Name = preTestBloom, Duration = 0.3 })

	Move({ Id = montageUnitAnchor01, Speed = 4400, Angle = 180, })
	Move({ Id = montageUnitAnchor02, Speed = 4000, Angle = 270, })
	Move({ Id = montageUnitAnchor03, Speed = 4000, Angle = 0, })
	Stop({ Ids = MontageUnitAnchors, Delay = 0.5 })
	PlaySound({ Name = "/SFX/World Sounds/TrainingMontageWhoosh" })

	Rumble({ RightFraction = 0.18, Duration = 0.35, Delay = 0.05 })
end

OnTriggerFired
{ "ShowWagonScenePostMatch",
	function(triggerArgs)
		ShowWagonScenePostMatch()
	end
}

function ShowWagonScenePostMatch()

	SetupSwathAudio( currentlyOccupiedSwath )

	AddInputBlock({ Name = "ShowWagonScenePostMatch" })

	AdjustRadialBlurDistance({ Fraction = 1.5, Duration = 0 })
	AdjustRadialBlurStrength({ Fraction = 1.5, Duration = 0 })

	AdjustRadialBlurDistance({ Fraction = 0, Duration = 0.9, Delay = 0.1 })
	AdjustRadialBlurStrength({ Fraction = 0, Duration = 0.9, Delay = 0.1 })

	FadeIn({ Duration = 1.0, Delay = 1.0 })

	CheckCaravanNightState()
	ShowWagonScene()
	RemoveInputBlock({ Name = "ShowWagonScenePostMatch" })

end

OnTriggerFired
{ "ShowWagonScene",
	function(triggerArgs)
		wait(0.5) -- wait for the narration panel to close
		ShowWagonScene()
	end
}

function ShowWagonScene()

	if ActiveNarrationName == "Prologue_WagonInterior_Bard" or ActiveNarrationName == "Intro_WagonInterior_Bard" then
		SetOvermapMusic( "prologue" )
	end
	if ActiveNarrationName == "PrepareForFirstTakeOff" then
		PlaySound({ Name = "/SFX/World Sounds/MapText", Delay = 0.55 })
	end
	if not introComplete then
		wagonNarrativeSequence = true
	end
	OpenCaravan( false )

end

OnTriggerFired
{ "Prologue_FirstCamp",
	function(triggerArgs)
		EnableBasicChoices()
	end
}

OnKeyPressed{ "Shift M", Name = "SwathZeroCaravanTransition",
	function(triggerArgs)
		AdjustFullscreenBloom({ Name = "NewType08", Duration = 0  })

		ExitMenu({ Name = "DialogueScreen" })

		Teleport({ Id = realOvermapUnit, DestinationId = 10019 })
		LockCamera({ Id = 10019, Duration = 0 })

		FireTrigger({ Name = "GameIntroductionComplete" })
	end
}

SwathZeroSpecialSwathLand = { "Swath_00_StandingObjects01", "Swath_00_Terrain01", "Swath_00_Terrain02", "Swath_00_Terrain03", "Swath_00_Terrain04", "Swath_00_Path01", "Swath_00_ForegroundObjects01", "Swath_00_TerrainInk_01", "Swath_00_TerrainInk_02", "Swath_00_Foreground02", "Swath_00_CliffGround01", "Swath_00_CliffLeft01", "Swath_00_CliffRight01", "Swath_00_FX02", "Swath_00_SandFXEtc", "Swath_00_RightSandFXEtc", "BirdsB" }
SwathZeroSpecialSwathAtmosphere = { "Swath_01_Fog", "Swath_00_FX03","Swath_00_Night01" } -- FX03 has the logo in it

function HideSwathZero()
	swathZeroHidden = true
	SetGroupVisibility({ Names = SwathZeroSpecialSwathLand, Visible = false })
	SetGroupVisibility({ Names = SwathZeroSpecialSwathAtmosphere, Visible = false })
end

function ShowSwathZero()
	swathZeroHidden = false
	SetOpacity({ Name = "Swath_01_Fog", Fraction = 1 })
	SetGroupVisibility({ Names = SwathZeroSpecialSwathLand, Visible = true })
	SetGroupVisibility({ Names = SwathZeroSpecialSwathAtmosphere, Visible = true })
end

function Swath0Bendy( caravanId )
	local BendyPath = { 50149, 40031, 40036, 40039, 40040, 40045, 40053, 40054, 10007 }

--	SetBendyDeceleration({Id = realOvermapUnit, DecelerationScalar = 10 })

	--SetBendyDeceleration({Id = realOvermapUnit, DecelerationScalar = 10 })
	local startingSpeed = 350
	--local startingSpeed = 500

	local overallSwath0BendyCameraDuration = 18
	--local overallSwath0BendyCameraDuration = 21

	DisableInput({ PlayerIndex = 1 })
	SetUnitProperty({ DestinationId = realOvermapUnit, Name = "Speed", Value = startingSpeed })
--	LockCamera({ Id = realOvermapUnit, Duration = 0.3 })
	PanCamera({ Id = 10007, Duration = overallSwath0BendyCameraDuration, EaseOut = 0.5, OffsetY = -200 })
	FocusCamera({ Fraction = OVERMAP_ZOOM_DEFAULT, ZoomType = "Ease", Duration = overallSwath0BendyCameraDuration })

	CreateBendy({Id = realOvermapUnit, DestinationId = BendyPath})
	EnableBendy({Id = realOvermapUnit})

	-- caravan
	AddToGroup({ Id = realOvermapUnit, Name = "Swath_00_StandingObjects01", DrawGroup = true })
	SetScale({ Id = realOvermapUnit, Fraction = 0.75, Duration = 8, Delay = 5 })
	PlayAnimation({ Name = "Overmap_Caravan_Moving_Hop", DestinationId = realOvermapUnit, Delay = 0.1 })

	PlayAnimation({ Name = "Overmap_Caravan_Moving_02", DestinationId = realOvermapUnit, Delay = 1.3 })
	PlayAnimation({ Name = "Overmap_Caravan_Moving_Fidget", DestinationId = realOvermapUnit, Delay = 2.8 })
	Rumble({ RightFraction = 0.2, Duration = 0.2, Delay = 3 })

	thread(CurtainSwathZero, 0.1)
	thread(SwathZeroSwathTransition, overallSwath0BendyCameraDuration/2)

	local bendyLimit = #BendyPath
	for index = 1, bendyLimit, 1 do
		Move({ Id = realOvermapUnit, DestinationId = BendyPath[index] })

		--check when next node is in range
		local bendyDistance = 15
		if index == bendyLimit then
			bendyDistance = 60
		end

		local nearestBendy = GetClosest({ Id = realOvermapUnit, DestinationId = BendyPath[index], Distance = bendyDistance })
		while nearestBendy == 0 do
			nearestBendy = GetClosest({ Id = realOvermapUnit, DestinationId =  BendyPath[index], Distance = bendyDistance })
			wait(0.01)

			local ShakeyFoliage = { 211787, 211571, 211803, 211580, 211805, 310826, 211572, 211802, 211804 }
			if not pulseFoliage and GetClosest({ Id = realOvermapUnit, DestinationIds = ShakeyFoliage, Distance = 50 }) > 0 then
				PlayAnimation({ Name = "Overmap_Caravan_Moving_Fidget", DestinationId = realOvermapUnit, Delay = 0 })
				thread(PulseFoliage, ShakeyFoliage)
			end
		end

		if BendyPath[index] == 40031 then
			SetBendyDeceleration({Id = realOvermapUnit, DecelerationScalar = 8.00 })
		end

		if BendyPath[index] == 40036 then
			SetBendyDeceleration({Id = realOvermapUnit, DecelerationScalar = 1.25 })
		end

		--per node effects
		if BendyPath[index] == 40036 then
			local caravanHopDelay = 1.45
			local caravanHopScaleOutDelay = caravanHopDelay + 1.35
			local caravanLayerDelay = caravanHopScaleOutDelay + 0.15
			--AddToGroup({ Id = 211001, Name = "Swath_00_StandingObjects01", DrawGroup = true })
			RemoveFromGroup({ Id = realOvermapUnit, Name = "Swath_00_StandingObjects01", Delay = caravanLayerDelay })
			AddToGroup({ Id = realOvermapUnit, Name = "Swath_01_Standing01", DrawGroup = true, Delay = 3.3 })
			--SetScale({ Id = realOvermapUnit, Fraction = 0.01, Duration = 0.7, Delay = 0.1 })
			PlayAnimation({ Name = "Overmap_Caravan_Jump", DestinationId = realOvermapUnit, Delay = caravanHopDelay })
			-- PlaySound({ Name = "/VO/Cur_Rukey_82", DestinationId = realOvermapUnit, Delay = caravanHopDelay + 1.0 })
			PauseSound({ Name = "/SFX/World Sounds/CaravanAmbience1", Delay = caravanHopDelay + 0.2, Duration = 0.3 })
			ResumeSound({ Name = "/SFX/World Sounds/CaravanAmbience1", Delay = caravanHopDelay + 2.0, Duration = 0.3 })
			SetScale({ Id = realOvermapUnit, Fraction = 0.01, Duration = 0.1, Delay = caravanHopScaleOutDelay })
			SetOpacity({ Id = realOvermapUnit, Fraction = 0, Duration = 0.1, Delay = caravanHopScaleOutDelay })

			Rumble({ RightFraction = 0.25, Duration = 0.8, Delay = caravanHopDelay })
			Rumble({ LeftFraction = 0.4, Duration = 0.1, Delay = caravanHopScaleOutDelay })
			-- SetSoundCueValue({ Name = "Uphill", Id = caravanSoundId, Value = 1.0, Duration = 0.1, Delay = caravanHopDelay - 0.2 })
			-- SetSoundCueValue({ Name = "Uphill", Id = caravanSoundId, Value = 0.0, Duration = 0.1, Delay = caravanLayerDelay })
		end

		if BendyPath[index] == 40053 then
			SetScale({ Id = realOvermapUnit, Fraction = 1, Duration = 0 })
			SetOpacity({ Id = realOvermapUnit, Fraction = 1, Duration = 0, Delay = 0 })
			StopAnimation({ Name = "Overmap_Caravan_Moving_Fidget", PreventChain = true })
			PlayAnimation({ Name = "Overmap_Caravan_Moving_02", DestinationId = realOvermapUnit, Delay = 0.1 })

			PlayAnimation({ Name = "Overmap_Caravan_Moving_Hop", DestinationId = realOvermapUnit, Delay = 4.375 })

			Rumble({ RightFraction = 0.22, Duration = 0.25, Delay = 0.1 + 4.375 })
			Rumble({ RightFraction = 0.22, Duration = 0.25, Delay = 0.4 + 4.375 })
		end

		if index == bendyLimit then
			useSwathZeroClamps = false
			postSwathZeroTransitionClamps = true
			swathTransitioning = false
			SetupOvermapClamps()

			AdjustBendySpeed({ Id = realOvermapUnit, Fraction= 0.35, Duration = 3 })
			--ShakeScreen({ Speed = 50, Distance = 4, FalloffSpeed = 2000, Duration = 0.3, Delay = 0.9 })
			StopAnimation({ Name = "Overmap_Caravan_Moving_Fidget", PreventChain = true })
			PlayAnimation({ Name = "Overmap_Caravan_Moving_02", DestinationId = realOvermapUnit, Delay = 0.3 })

			return
		end

		if index == 6 then
			thread(ShowSwathNameText, 2.5 )
			thread(HideSwathNameText, 7.5 )
		end


		if index >= 4 then
			--AdjustBendySpeed({ Id = realOvermapUnit, Fraction= 0.6, Duration = 0.1 })
			AdjustBendySpeed({ Id = realOvermapUnit, Fraction= 0.6, Duration = 0.1 })
		end

		--PlayOverheadAnimation({ Name = "WalkDustLarge", DestinationId = bendyId, IgnoreOverheadOffset = true })
	end

end

function SwathZeroSwathTransition( swathTransitionDelay )

	swathTransitioning = true
	if swathTransitionDelay ~= nil and swathTransitionDelay > 0 then
		SetColor({ Names = SwathZeroSpecialSwathAtmosphere, Color = Color.TransparentBlack, Duration = 1.3, Delay = swathTransitionDelay + 0.5 })

		AdjustFullscreenBloom({ Name = "Saturated", Delay = swathTransitionDelay - 1, Duration = 1.5 })
		AdjustFullscreenBloom({ Name = SwathData[currentlyOccupiedSwath]["Bloom"], Duration = 2.5, Delay = swathTransitionDelay + 0.6 })

		SetColor({ Names = SwathZeroSpecialSwathLand, Color = Color.Black, Duration = 1.5, ExcludeType = "OvermapPlayerPerspective", Delay = swathTransitionDelay - 1 })
		wait(swathTransitionDelay)
	end

	local swathZeroTransitionTime = 2.3
	--Move({ Names = SwathZeroSpecialSwathLand, Angle = 270, Speed = 300 / (swathZeroTransitionTime), ExcludeType = "OvermapPlayerPerspective"  })
	--Stop({ Names = SwathZeroSpecialSwathLand, Delay = swathZeroTransitionTime })

	local SwathZeroLeft = { "Swath_00_CliffLeft01" }
	local SwathZeroRight = { "Swath_00_CliffRight01" }
	--Move({ Names = SwathZeroLeft, Speed = 300 / (swathZeroTransitionTime), Angle = 270 - 45, Delay = swathZeroTransitionTime  })
	--Move({ Names = SwathZeroRight, Speed = 300 / (swathZeroTransitionTime), Angle = 270 + 45, Delay = swathZeroTransitionTime })
	--Stop({ Names = SwathZeroLeft, Delay = swathZeroTransitionTime * 10 })
	--Stop({ Names = SwathZeroRight, Delay = swathZeroTransitionTime * 10 })

	fakeSwathZeroNight = false

	thread( SetupDay, "firstday" )
	wait(0.2)

	wait(12.3)
	HideSwathZero()
	SetupSwathAudio( currentlyOccupiedSwath )
end

function CurtainSwathZero( curtainDelay )
	swathZeroCurtained = true
	PersistVariable({ Name = "swathZeroCurtained" })
	local SwathZeroLeft = { "Swath_00_CliffLeft01" }
	local SwathZeroRight = { "Swath_00_CliffRight01" }
	local SwathZeroCenter = { "Swath_00_CliffGround01" }

	if curtainDelay > 0 then
		wait(curtainDelay)
	end
	local curtainSpeed = 34
	Move({ Names = SwathZeroLeft, Speed = curtainSpeed, Angle = 270 - 45, IgnoreChildren = true })
	Move({ Names = SwathZeroRight, Speed = curtainSpeed, Angle = 270 + 45, IgnoreChildren = true })
	Move({ Names = SwathZeroCenter, Speed = 5, Angle = 270, IgnoreChildren = true })

	wait(6.5)
	curtainSpeed = 130

	--Move({ Names = SwathZeroLeft, Speed = curtainSpeed, Angle = 270 - 45  })
	--Move({ Names = SwathZeroRight, Speed = curtainSpeed, Angle = 270 + 45 })
	--Move({ Names = SwathZeroCenter, Speed = 15, Angle = 270 })

end

function CloudBreak( cloudBreakDelay )
	wait( cloudBreakDelay )
	local swathClouds = GetIds({ Name = "Swath_01_Fog" })
	for k, v in pairs(swathClouds) do
		if GetName({ Id = v }) == "CloudTiling01" then
			if CoinFlip() then
				Move({ Id = v, Angle = 0, Speed = 10 })
			else
				Move({ Id = v, Angle = 180, Speed = 10 })
			end
		end
	end
end

function PulseFoliage( foliageTable )
	pulseFoliage = true
	Rumble({ RightFraction = 0.22, Duration = 0.4 })
	for k, v in pairs(foliageTable) do
		thread(CheckReactiveObject, v, "mouseover")
		wait(0.1)
	end
end


OnTriggerFired
{ "SetIntroScene1PostMatchComment",
	function(triggerArgs)
		if Coach.Reason == "CoachChoice01" then
			introScene1PostMatchComment = "FriendIntroComment01"
		elseif Coach.Reason == "CoachChoice07" then
			introScene1PostMatchComment = "FriendIntroComment03"
		else
			introScene1PostMatchComment = "FriendIntroComment02"
		end
	end
}

OnTriggerFired
{ "GameIntroductionComplete",
	function(triggerArgs)

		AddInputBlock({ Name = "GameIntroductionComplete" })

		-- remove 'robed' state from Prologue events
		inRobes = false

		-- toggle off wagonNarrativeSequence for normal WagonScreen function
		wagonNarrativeSequence = false

		local panDuration = 6
		HideObjectiveLog()

		trickCaravan = realOvermapUnit

		caravanSoundId = PlaySound({ Name = "/SFX/World Sounds/CaravanAmbience1", Id = realOvermapUnit })

		Rumble({ Fraction = 0.1, Duration = 0.1 }) -- infinite rumble band aid

		UnlockAchievementOnce( "AchReader" )
		DebugPrint({ Text = "Trying to unlock reader achievement." })

		wait(0.25)

		SwitchAmbience( "Ambience/Swath1Ambience" )

		SetOvermapMusic( "end" )

		PlaySound({ Name = "/SFX/World Sounds/Thunder", Id = realOvermapUnit })
		Shake({ Id = realOvermapUnit, Speed = 40, Distance = 1, Duration = 1.0, FalloffSpeed = 2000, Duration = 1 })
		Rumble({ RightFraction = 0.2, Duration = 1.1 })

		wait(0.75)

		-- Simulating departure from a normal node
		HideOvermapLocationIndicators()
		UseableOn({ Id = startingNodeId })
		QueueAutoUse({ Id = startingNodeId })
		Swath0Bendy({ Id = trickCaravan })

		wait(0.1)

		StopSound({ Name = "/SFX/World Sounds/CaravanAmbience1", Duration = 0.5 })

		--AdjustZoom({ Fraction = OVERMAP_ZOOM_DEFAULT, LerpTime = 3, Duration = 99999  })

		wait(0.7)

		notifyExistingWaiters("gameIntroductionComplete")

		RemoveInputBlock({ Name = "GameIntroductionComplete" })

	end
}

-- Destination Arrival Events
function QueueDialoguePreLocationMenu()

	local nodeData = NodeData[currentNodeId]

	-- Week 1 / after intromatch
	if matchesPlayed == 0 then
		wait(0.25)
		if currentNodeId == 10007 then
			-- for intro
			SetOpacity({ Ids = titleLogoIds, Fraction = 0.0 })
			FireTrigger({ Name = "PlayIntroMusic" })
			FireTrigger({ Name = "AddFriendToRoster" })
			FireTrigger({ Name = "AddBadassToRoster" })
			FireTrigger({ Name = "AddJokerToRoster" })

			if GetConfigOptionValue({ Name = "SkipSwath0" }) then
				UpdateCurrentDate()
			end

			-- NarrationSequence( "Intro_EnteredSwath1" )
		elseif currentNodeId == 10008 then
			-- NarrationSequence( "Intro_Week1_ArrivedAtHollowroot" )
		elseif currentNodeId == 10009 then
			-- NarrationSequence( "Intro_Week1_ArrivedAtBloomingpool" )
		elseif currentNodeId == 10010 then
			NarrationSequence( "Intro_Week1_ArrivedAtMatchSite" )
			return true
		end
	-- Week 2 / after Ridge match
	elseif matchesPlayed == 1 then
		wait(0.25)
		if currentNodeId == 40008 then
			-- NarrationSequence( "EnteredSwath2" )
		-- elseif currentNodeId == 10016 then
		-- Scoped Campaign: Beetle Beach
		elseif currentNodeId == 10016 then
			NarrationSequence( "Week2_ArrivedAtFirstCamp" )
			return true
		elseif currentNodeId == 210298 then
			NarrationSequence( "Week2_ArrivedAtFirstShop" )
			return true
		end
	-- Week 3 / after Spring match
	elseif matchesPlayed == 2 then
		wait(0.25)
		if currentNodeId == 40008 then
			NarrationSequence( "Week3_ArrivedAtNightWatch" )
			return true
		elseif currentNodeId == 10004 then
			NarrationSequence( "Week3_ArrivedAtMatchSite" )
			return true
		end
	-- Week 4 / after Canyon match
	elseif matchesPlayed == 3 then
		wait(0.25)
		if currentNodeId == 10031 then
			blockSideConversationsHere = true
		elseif currentNodeId == 10029 then
			-- hope loss event on arrival unless you took the 'fast' route
			if not NarrationRecord["ExplorePlaguemont_01"] then
				NarrationSequence( "Week4_ArrivedAtMatchSite" )
			else
				NarrationSequence( "Week4_ArrivedAtMatchSite_Alt" )
			end
			return true
		end
	-- Week 5 / after Lair match
	elseif matchesPlayed == 4 then
		if currentNodeId == 10028 then
			NarrationSequence( "Week5_ArrivedAtBigBertrudes" )
			return true
		elseif currentNodeId == 40154 then
			-- these types of events can be merged with the node events on arrival
			-- NarrationSequence( "EnteredSwath4" )
			return true
		elseif currentNodeId == 10052 then
			NarrationSequence( "Week5_ArrivedAtMatchSite" )
			return true
		end	-- Week 6 / after Ship match
	elseif matchesPlayed == 5 then
		if currentNodeId == 10067 then
			NarrationSequence( "EnteredSwath7" )
			return true
		elseif currentNodeId == 10040 then
			blockSideConversationsHere = true
			NarrationSequence( "Week6_ArrivedAtMatchSite" )
			return true
		end
	-- Week 7 / after Lava match
	elseif matchesPlayed == 6 then
		if currentNodeId == 10044 or currentNodeId == 10078 then
			NarrationSequence( "Week7_CampingInWoods" )
			return true
		elseif currentNodeId == 10041 then
			NarrationSequence( "Week7_ArrivedAtMatchSite" )
			return true
		end
	-- Week 8 / after Forest match
	elseif matchesPlayed == 7 then
		if currentNodeId == 10077 then
			NarrationSequence( "Week8_NearSwath9" )
			return true
		elseif currentNodeId == 10049 then
			NarrationSequence( "Week8_ArrivedAtMatchSite" )
			return true
		end
	-- Week 9 / after Ascension match / Open Structure
	elseif matchesPlayed >= 8 then
		-- at Moonlight Alcove
		if currentNodeId == 10051 then
			if allowCaravanFly then
				takeoffQueued = true
				PersistVariable({ Name = "takeoffQueued" })
			end
			if PlayerTeam.AscensionMatchesPlayed == 1 then
				NarrationSequenceOnce( "ArrivedAtOpenStructure" )
				return true
			elseif PlayerTeam.AscensionMatchesPlayed == 2 then
				NarrationSequenceOnce( "ArrivedAtMoonlightAlcove_02" )
				return true
			--[[
			elseif PlayerTeam.AscensionMatchesPlayed == 3 then
				NarrationSequenceOnce( "ArrivedAtMoonlightAlcove_03" )
				return true
			elseif PlayerTeam.AscensionMatchesPlayed == 4 then
				NarrationSequenceOnce( "ArrivedAtMoonlightAlcove_04" )
				return true
			elseif PlayerTeam.AscensionMatchesPlayed == 5 then
				NarrationSequenceOnce( "ArrivedAtMoonlightAlcove_05" )
				return true
			elseif PlayerTeam.AscensionMatchesPlayed == 6 then
				NarrationSequenceOnce( "ArrivedAtMoonlightAlcove_06" )
				return true
			]]--
			end
		end
		-- at Isle of Khaylmer
		if currentNodeId == 10071 then
			NarrationSequenceOnce( "ArrivedAtHiddenMatchSite" )
		end
		-- Falcon Ron Encounter
		if NarrationRecord["Junction_ShopKeeper_01_TakeHim"] then
			NarrationSequenceOnce( "ArrivedAtMatchSite_WithRon" )
		elseif NarrationRecord["Junction_ShopKeeper_01_LeaveHim"] then
			NarrationSequenceOnce( "ArrivedAtMatchSite_WithoutRon" )
		end

		-- Oralech in Wagon - when you reach the match site
		if NarrationRecord["Junction_Nightwing_01"] and currentNodeId == goalNodeId then
			NarrationSequenceOnce( "ArrivedAtMatchSiteAfterNightwingJunction" )
		end

		-- Landing Pad Events: only for weeks following Ascension Matches
		if nodeData.LandingPad and caravanLandedRecently then
			local swathData = SwathData[currentlyOccupiedSwath]
			local landingPadEvent = nil
			-- landing in swath 9
			if currentlyOccupiedSwath == 9 then
				if PlayerTeam.AscensionMatchesPlayed == 1 then
					landingPadEvent = "Ascension2_Landing"
				elseif PlayerTeam.AscensionMatchesPlayed == 2 then
					landingPadEvent = "Ascension3_Landing"
				elseif PlayerTeam.AscensionMatchesPlayed == 3 then
					landingPadEvent = "Ascension4_Landing"
				elseif PlayerTeam.AscensionMatchesPlayed == 4 then
					landingPadEvent = "Ascension5_Landing"
				elseif PlayerTeam.AscensionMatchesPlayed == 5 then
					landingPadEvent = "Ascension6_Landing"
				elseif PlayerTeam.AscensionMatchesPlayed == 6 then
					landingPadEvent = "Ascension7_Landing"
				end
				NarrationSequenceOnce( landingPadEvent )
				return true
			elseif swathData.LandingEvent ~= nil or swathData.LandingEventAlt ~= nil then
				if currentlyOccupiedSwath == 3 and CharDiva.RosterStatus == "Active" then
					-- special case: arriving in swath 3 with Bertrude
					landingPadEvent = swathData.LandingEventAlt
				else
					if PlayerTeam.AscensionMatchesPlayed == 1 and MatchesPlayedThisSeason == 0 then
						-- standard first-time landing in swath event
						landingPadEvent = swathData.LandingEvent
					else
						if swathData.LandingEvent ~= nil and not NarrationRecord[swathData.LandingEvent] then
							-- Play the short event only if the original was not played
							landingPadEvent = swathData.LandingEvent.."_Short"
						end
					end
				end
				NarrationSequenceOnce( landingPadEvent )
				return true
			elseif currentlyOccupiedSwath == 3 and not NarrationRecord["FirstLanding_Swath_03_WithDiva"] then
				-- landing in Swath 3 without Bertrude
				landingPadEvent = GetNextRemainingEvent( LosingHopeEvents )
				NarrationSequence( landingPadEvent )
				return true
			else
				if PlayerTeam.AscensionMatchesPlayed > 2 and not NarrationRecord["OpenStructure_LandingPad_07_Unlucky"] then
					landingPadEvent = "OpenStructure_LandingPad_07_Unlucky"
					NarrationSequenceOnce( landingPadEvent )
					return true
				end
			end
		end

		-- Season Week Goal Node Events
		if not IsAscensionWeek() and currentNodeId == goalNodeId then
			if PlayerTeam.AscensionMatchesPlayed == 1 then
				-- Jodi + Pamitha
				--[[
				if MatchesPlayedThisSeason == 0 then
					if CharBadass.RosterStatus ~= "Ascended" and CharVamp.RosterStatus ~= "Ascended" then
						NarrationSequenceOnce( "OpenStructure_JodiPamitha_ArrivedAtMatchSite_01" )
						return true
					end
				end
				]]--
			end
		end

		local nodeEvent = nodeData.TravelEvent
		-- Downer / Bad Luck Events
		if nodeEvent ~= nil then
			if nodeEvent == "OpenStructure_BadLuck_MinusAttitude_01" then
				NarrationSequence( "OpenStructure_BrokenWagon_01" )
				return true
			elseif nodeEvent == "OpenStructure_BadLuck_MinusSpeed_01" then
				NarrationSequence( "OpenStructure_EscapedImps_01" )
				return true
			elseif nodeEvent == "OpenStructure_BadLuck_LoseTime_01" or nodeEvent == "OpenStructure_Voyage_Storm_01" then
				if not NarrationRecord["OpenStructure_FoulWeather_01"] then
					NarrationSequence( "OpenStructure_FoulWeather_01" )
					return true
				else
					NarrationSequence( "OpenStructure_FoulWeather_02" )
					return true
				end
			end
		end

		-- Pre-Ascension Match Events
		if currentNodeId == 10049 then
			if PlayerTeam.AscensionMatchesPlayed == 1 then
				if LastAscendedCharacter.RosterStatus == "Ascended" then
					NarrationSequenceOnce( "OpenStructure_ArrivedAtAscensionMatch_01" )
					return true
				else
					NarrationSequenceOnce( "OpenStructure_ArrivedAtAscensionMatch_01B" )
					return true
				end
			-- elseif PlayerTeam.AscensionMatchesPlayed == 2 then
			elseif PlayerTeam.AscensionMatchesPlayed == 3 then
				if LastAscendedCharacter.RosterStatus == "Ascended" then
					NarrationSequenceOnce( "OpenStructure_ArrivedAtAscensionMatch_03" )
					return true
				else
					NarrationSequenceOnce( "OpenStructure_ArrivedAtAscensionMatch_03B" )
					return true
				end
			-- elseif PlayerTeam.AscensionMatchesPlayed == 4 then
			-- elseif PlayerTeam.AscensionMatchesPlayed == 5 then
			elseif PlayerTeam.AscensionMatchesPlayed == 6 then
				NarrationSequenceOnce( "OpenStructure_ArrivedAtAscensionMatch_06" )
				return true
			end
		end
	end
	DialogueProcSequence()

	return false

end

function EnableBasicChoices( args )

	basicChoices = true
	PersistVariable({ Name = "basicChoices" })

	if args == "cheating" then
		GuideBook[2].Decipherable = true
		NarrationRecord["Intro_Week1_FirstCamp"] = true

		if currentlyOccupiedSwath >= 2 then
			-- Cheat: Enable Locked Screens at the appropriate time
			EnableRosterDoor()
		end

		return
	end

	if LocationMenuOptions ~= nil and currentNodeId ~= goalNodeId then
		if NarrationRecord["Week2_FirstCamp"] then
			-- Add the Study option immediately
			local locOption = AddLocationMenuOption( "PickMeditate", 0, true, nil, false, true )
			locOption.RemoveBasicChoices = true
			locOption.CreateCheckpoint = true
			locOption.Component = "StudyButton"
			SetMenuOptions({ Name = "LocationMenuScreen", Item = locOption.Component, Properties = { Enabled = true, IsVisible = true, HelpTextId = locOption.ChoiceName } })
		end
		if NarrationRecord["Week1_FirstCamp"] or NarrationRecord["Intro_Week1_FirstCamp"] or NarrationRecord["Week2_FirstCamp"] then
			-- Add the Train option immediately
			local locOption = AddLocationMenuOption( "PickTrain", 0, true, nil, false, true )
			locOption.RemoveBasicChoices = true
			locOption.CreateCheckpoint = true
			locOption.Component = "TutorButton"
			SetMenuOptions({ Name = "LocationMenuScreen", Item = locOption.Component, Properties = { Enabled = true, IsVisible = true, HelpTextId = locOption.ChoiceName } })
		end
		if NarrationRecord["Week1_FirstCamp"] or NarrationRecord["Intro_Week1_FirstCamp"] or NarrationRecord["Week2_FirstCamp"] then
			-- Add the Forage option immediately
			local locOption = AddLocationMenuOption( "PickForage", 0, true, nil, false, true )
			locOption.RemoveBasicChoices = true
			locOption.CreateCheckpoint = true
			locOption.Component = "ForageButton"
			SetMenuOptions({ Name = "LocationMenuScreen", Item = locOption.Component, Properties = { Enabled = true, IsVisible = true, HelpTextId = locOption.ChoiceName } })
		end
	end
end

-- **Character Quests**
function UpgradeCharacter( character )

	if character == nil then
		return
	end

	-- upgrade Hedwyn
	if character == CharFriend then
		CharFriend["PlayerAttributeRespawn"] = CharFriend["PlayerAttributeRespawn"] + 5
		CharFriend["PlayerAttributeSpeed"] = CharFriend["PlayerAttributeSpeed"] + 5
		CharFriend["PlayerAttributeAura"] = CharFriend["PlayerAttributeAura"] + 5
	else
	end

	UpdateTooltips( character )
end

-- **Other Scripting**
OnTriggerFired
{ "RukeyInterrogation",
	function(triggerArgs)
		interrogating = true
		wait(0.2)
		PlaySound({ Name = "/SFX/Player Sounds/PlayerSkid" })
		if ActiveNarrationName == "Intro_SideConversation_Joker_01" or ActiveNarrationName == "Kiosk_SideConversation_Joker_01" then
			SetMenuOptions({ Name = "DialogueScreen", Item = "RightCharacter", Properties = { ScaleTarget = 1.4, ScaleSpeed = 1.4 } })
		end
	end
}

OnTriggerFired
{ "PamithaInterrogation",
	function(triggerArgs)
		interrogating = true
		PlaySound({ Name = "/SFX/Match SFX/RobeFlutter" })
		SetMenuOptions({ Name = "DialogueScreen", Item = "RightMidCharacter", Properties = { ScaleTarget = 1.2, ScaleSpeed = 1.6 } })
	end
}

OnTriggerFired
{ "InterrogationComplete",
	function(triggerArgs)
		interrogating = false
	end
}

OnTriggerFired
{ "AddWagonScreenBlock",
	function(triggerArgs)
		blockWagonScreen = true
	end
}

OnTriggerFired
{ "RemoveWagonScreenBlock",
	function(triggerArgs)
		blockWagonScreen = false
	end
}

OnTriggerFired
{ "FriendGetsSick",
	function(triggerArgs)
		CharFriend.Undraftable = "Roster_DraftIneligible_SickReason"
	end
}

function GetNewDayDialogue()

	-- this could occur while the wagon was mid-move, which caused problems
	if caravanMoving then
		return
	end

	-- Week 1 / after intromatch
	if matchesPlayed == 0 then
		if movesAvailable == 1 then
			-- NarrationSequence( "Intro_Week1_ForkedPath" )
			if not caravanMoving and not madeFirstMove then
				-- thread( ShowDeferredHint, "mapmovement" )
			end
		end
	-- Week 2 / after Ridge match
	elseif matchesPlayed == 1 then
		-- Scoped Campaign: Beetle Beach New Day
		if currentNodeId == 10016 then
			NarrationSequence( "Week2_ForkedPath" )
		end
	-- Week 3 / after Spring match
	elseif matchesPlayed == 2 then
		if currentNodeId == 210298 then
			NarrationSequenceOnce( "Week3_FirstDay" )
		elseif currentNodeId == 40008 then
			-- NarrationSequenceOnce( "Week3_PostNightWatch" )
		end
	-- Week 4 / after Canyon match
	elseif matchesPlayed == 3 then
		if currentNodeId == 10004 then
			NarrationSequenceOnce( "Week4_FirstDay" )
		elseif currentNodeId == 10031 then
			NarrationSequence( "Swath3_LosingHope_01" )
		--[[
		else
			if movesAvailable == 4 then
				NarrationSequence( "Swath3_LosingHope_01" )
			elseif movesAvailable == 3 then
				NarrationSequence( "Swath3_LosingHope_02" )
			elseif movesAvailable == 2 then
				NarrationSequence( "Swath3_LosingHope_03" )
			elseif movesAvailable == 1 then
				NarrationSequence( "Swath3_LosingHope_04" )
			elseif movesAvailable == 0 then
				NarrationSequence( "Swath3_LosingHope_05" )
			end ]]--
		end
	-- Week 5 / after Lair match
	elseif matchesPlayed == 4 then
		if currentNodeId == 10028 then
			NarrationSequence( "Week5_Seaworthy" )
		end
	-- Week 6 / after Ship match
	elseif matchesPlayed == 5 then
		if currentNodeId == 10052 then
			-- NarrationSequence( "Week6_FirstDay" )
		elseif currentNodeId == 10067 then
			-- NarrationSequence( "Week6_NearGoal" )
		end
	-- Week 7 / after Lava match
	elseif matchesPlayed == 6 then
		if currentNodeId == 10040 then
			-- NarrationSequence( "Week7_FirstDay" )
		elseif currentNodeId == 10044 or currentNodeId == 10078 then
			-- NarrationSequenceOnce( "Week7_NearVolfred" )
		end
	-- Week 8 / after Forest match
	elseif matchesPlayed == 7 then
		if currentNodeId == 10041 then
			NarrationSequence( "Week8_FirstDay" )
		elseif currentNodeId == 10077 then
			-- NarrationSequenceOnce( "Week8_GoToSwath9" )
		end
	-- Week 9 / after Ascension match
	elseif matchesPlayed == 8 then
		if currentNodeId == 10049 then
			NarrationSequenceOnce( "Week9_FirstDay" )
		elseif currentNodeId == 10051 then
			NarrationSequenceOnce( "PrepareForFirstTakeOff" )
			LockCamera({ Id = realOvermapUnit, Duration = 0.5 })
		end
		if caravanLandedRecently and not NarrationRecord["FirstLanding_DayAfter"] then
			NarrationSequenceOnce( "FirstLanding_DayAfter" )
		end
	-- Week 10+ / Open Structure
	elseif matchesPlayed >= 9 then
		-- at MatchSiteI / Fall of Soliam
		if currentNodeId == 10049 then
			if PlayerTeam.AscensionMatchesPlayed == 2 then
				-- NarrationSequence( "OpenStructure_PrepareForAscension3" )
			elseif PlayerTeam.AscensionMatchesPlayed == 3 then
				NarrationSequence( "OpenStructure_PrepareForAscension4" )
			elseif PlayerTeam.AscensionMatchesPlayed == 4 then
				NarrationSequence( "OpenStructure_PrepareForAscension5" )
			elseif PlayerTeam.AscensionMatchesPlayed == 5 then
				NarrationSequence( "OpenStructure_PrepareForAscension6" )
			elseif PlayerTeam.AscensionMatchesPlayed == 6 then
				NarrationSequence( "OpenStructure_PrepareForAscension7" )
			end
		end

		-- at Moonlight Alcove
		if currentNodeId == 10051 then
			if PlayerTeam.AscensionMatchesPlayed == 2 then
				NarrationSequence( "Ascension3_DayOfFirstTakeOff" )
			-- Scare 1
			elseif PlayerTeam.AscensionMatchesPlayed == 3 then
				NarrationSequence( "OpenStructure_PostScare_01" )
			end
		end

		-- losing hope in Swath 3
		if NodeData[currentNodeId]["Swath"] == 3 then
			if not NarrationRecord["FirstLanding_Swath_03_WithDiva"] then
				if not blockLosingHopeThisWeek then
					NarrationSequence( "OpenStructure_Swath3_LosingHope_01" )
				end
			end
		end

		-- autopilot intro
		if PlayerTeam.AscensionMatchesPlayed == 2 and MatchesPlayedThisSeason == 3 and IsAscensionWeek() then
			--NarrationSequenceOnce( "OpenStructure_AutoPilotIntro" )
		end

		-- Scare 2
		if PlayerTeam.AscensionMatchesPlayed == 4 and MatchesPlayedThisSeason == 1 then
			local currentNode = NodeData[currentNodeId]
			if currentNode.Category ~= "Arena" then
				if NarrationRecord["SideCon_Doc_02_Brighton"] then
					NarrationSequenceOnce( "OpenStructure_PostScare_02_Known" )
				else
					NarrationSequenceOnce( "OpenStructure_PostScare_02_Unknown" )
				end
			end
		end

		-- Last Season Match
		if IsLastSeasonMatch() and IsRivalryPresent() then
			TagWeeklyProtag()
			NarrationSequenceOnce( "OpenStructure_PrepareForLastSeasonMatch" )
		end

		-- final flight / Scare 3
		if PlayerTeam.AscensionMatchesPlayed == 6 and MatchesPlayedThisSeason == 1 then
			NarrationSequenceOnce( "OpenStructure_PrepareForLastTakeOff" )
		end

	end

end

function GetTakeOffDialogue()

	if not NarrationRecord["FirstTakeOff"] then
		AddInputBlock({ Name = "FirstTakeOff" })
		wait(1.35)
		RemoveInputBlock({ Name = "FirstTakeOff" })
		NarrationSequence( "FirstTakeOff" )
		blockSideConversationsHere = false
	elseif PlayerTeam.AscensionMatchesPlayed == 1 and MatchesPlayedThisSeason == 3 then
		--[[ second ascension takeoff -- Cut
		AddInputBlock({ Name = "AscensionTakeOff" })
		wait(1.35)
		RemoveInputBlock({ Name = "AscensionTakeOff" })
		NarrationSequence( "Ascension2_TakeOff" )
		]]--
	elseif PlayerTeam.AscensionMatchesPlayed == 6 and MatchesPlayedThisSeason == 1 then
		-- final flight
		AddInputBlock({ Name = "AscensionTakeOff" })
		wait(1.35)
		RemoveInputBlock({ Name = "AscensionTakeOff" })
		NarrationSequence( "LastTakeOff" )
	end
	SetConfigOption({ Name = "ShowOffscreenIndicators", Value = true })
end

OnTriggerFired
{
	"AddFriendToRoster",
	function( triggerArgs )
		AddCharacterToRoster( CharFriend )
	end
}

OnTriggerFired
{
	"AddBadassToRoster",
	function( triggerArgs )
		AddCharacterToRoster( CharBadass )
	end
}

OnTriggerFired
{
	"AddJokerToRoster",
	function( triggerArgs )
		AddCharacterToRoster( CharJoker )
	end
}

OnTriggerFired
{
	"AddPsychoToRoster",
	function( triggerArgs )
		AddCharacterToRoster( CharPsycho )
	end
}

OnTriggerFired
{
	"AddMascotToRoster",
	function( triggerArgs )
		AddCharacterToRoster( CharMascot )
	end
}

OnTriggerFired
{
	"RemoveRobes",
	function( triggerArgs )
		inRobes = false
	end
}

-- Mascot Introduction / Imp Introduction
OnTriggerFired{ "HideConfirmButtonTrigger",
	function( triggerArgs )
		SetMenuOptions({ Name = "DialogueScreen", Item = "ConfirmButton", Properties = { FadeTarget = 0.0, FadeOpacity = 0.0, IsVisible = false, Enabled = false } })
		SetFlagTrue({ Name = "CheckingForTooltip" })

		wait(11.0)
		if not blockJumpToolTipTutorial then
			DisplayTutorialBox({ HelpTextId = "Info_TizoTooltipInteract", X = 390, Y = 710, Animation = "TutorialBoxSmallIn", Arrow = "Down" })
		end
	end
}

OnTooltipClicked{ "NightWatchA_Onward_Imp_01",
	function( triggerArgs )

		Keywords.TooltipIds["NightWatchA_Onward_Imp_01"] = "NightWatchA_Onward_Imp_02"
		PlaySound({ Name = "/Music/Stingers/ShortSting2" })
		PlaySound({ Name = "/VO/Imp_Tizo_0180__4", Id = CurrentScenePositionTrackers["RightCharacter"], Delay = 0.2 })
		SetMenuOptions({ Name = "DialogueScreen", Item = "DialogueBox", Properties = { ReReadText = true, PrintingSound = null } })

		blockJumpToolTipTutorial = true
		if CurrentTutorialBox == "Info_TizoTooltipInteract" then
			HideTutorialBox()
		end
	end
}

OnTooltipClicked{ "NightWatchA_Onward_Imp_02",
	function( triggerArgs )

		Keywords.TooltipIds["NightWatchA_Onward_Imp_01"] = "NightWatchA_Onward_Imp_03"
		PlaySound({ Name = "/Music/Stingers/ShortSting3" })
		PlaySound({ Name = "/VO/Imp_Tizo_0174__11", Id = CurrentScenePositionTrackers["RightCharacter"], Delay = 0.2 })
		SetMenuOptions({ Name = "DialogueScreen", Item = "DialogueBox", Properties = { ReReadText = true, PrintingSound = null } })
	end
}

OnTooltipClicked{ "NightWatchA_Onward_Imp_03",
	function( triggerArgs )

		Keywords.TooltipIds["NightWatchA_Onward_Imp_01"] = "NightWatchA_Onward_Imp_04"
		PlaySound({ Name = "/Music/Stingers/PlayerScore" })
		PlaySound({ Name = "/VO/Imp_Tizo_0110__5", Id = CurrentScenePositionTrackers["RightCharacter"], Delay = 0.2 })
		SetMenuOptions({ Name = "DialogueScreen", Item = "DialogueBox", Properties = { ReReadText = true, PrintingSound = null } })

		SetFlagFalse({ Name = "CheckingForTooltip" })
		waitScreenTime(0.65)
		SetMenuOptions({ Name = "DialogueScreen", Item = "ConfirmButton", Properties = { FadeTarget = 1.0, IsVisible = true, Enabled = true } })

	end
}

OnTriggerFired
{
	"AddKnightToRoster",
	function( triggerArgs )
		AddCharacterToRoster( CharKnight )

		-- change Pyrehearts team captain
		local newCaptainIndex = RivalPyreheart.CharacterIndex
		League[6].TooltipIds.TeamName = "TeamName06"
		League[6].TeamBench[1] = RivalPyreheart
		RivalPyreheart.CharacterIndex = 1
		League[6].TeamBench[newCaptainIndex] = nil
	end
}

StormWallIds = { 310201, 216040, 310158, 310164, 310165, 312396, 210745, 210972, 211634, 216039, 216395, 216396, 216397, 216398, 216403, 216404, 216405, 310132, 310133, 310134, 310135, 310157, 310159, 310160, 310163, 310166, 310167, 310168, 310200, 310202, 310203, 214108, 214073, 214079, 214091, 214107, 310103, 310469, 310500, 310501, 310506, 310515, 310522 }

function StormWallPresentation()
	AddInputBlock({ Name = "StormWallPresentation" })
	-- presentation for Tempest / storm wall dissipating after Gilman joins
	AdjustColorGrading({ Name = "Sunrise", Duration = 1.0 })
	PanCamera({ Id = currentNodeId, OffsetY = -500, Duration = 4.0, Retarget = true })
	wait(1.0)
	SetOpacity({ Ids = StormWallIds, Fraction = 0, Duration = 1.5 })
	wait(1.0)
	--FadeOut({ Color = Color.White, Duration = 0.3 })
	wait(0.3)
	PlaySound({ Name = "/Music/Stingers/PositiveStinger1" })
	--FadeIn({ Duration = 2.0 })
	wait(2.0)
	AdjustColorGrading({ Name = SwathData[currentlyOccupiedSwath]["ColorGradeDusk"], Duration = 3 })
	wait(3.0)
	RemoveInputBlock({ Name = "StormWallPresentation" })
	NarrationSequence( "GilmanRetrieval01_Onward_StormWallOpen" )
end

OnTriggerFired
{
	"AddVampToRoster",
	function( triggerArgs )
		AddCharacterToRoster( CharVamp )
	end
}

OnTriggerFired
{
	"AddDocToRoster",
	function( triggerArgs )
		CharDoc.Undraftable = nil
		CharDoc.RobedPortrait = "SapVolfred01_Robed"
		AddCharacterToRoster( CharDoc )
		UnlockAchievementOnce( "AchFullRoster" )
		if NarrationRecord["SideCon_Doc_01_Sentence"] then
			DoRosterBioUpdate( CharDoc )
		end
	end
}

OnTriggerFired
{
	"AddDivaToRoster",
	function( triggerArgs )
		AddCharacterToRoster( CharDiva )
		AddConversation( "SideCon_Diva_01", true )
	end
}

OnTriggerFired
{
	"UnlockMeditateEntry", function( triggerArgs )

		-- figure out what happens when this runs out of entries
		if MeditateEntries == nil then
			MeditateEntries = {
				{ DisplayName = "2_Rules" },
				{ DisplayName = "2_BlackAuras" },
				{ DisplayName = "2_Origins" },
				{ DisplayName = "2_Triumvirate" },
				{ DisplayName = "2_Orb" },
				{ DisplayName = "2_Pyre" },
				{ DisplayName = "2_Weapon" },
				{ DisplayName = "2_Capture" },
				{ DisplayName = "2_Ascension" },
				{ DisplayName = "2_Arenas" },
				{ DisplayName = "2_Forfeit" },
				{ DisplayName = "2_Seasons" },
			}
			PersistVariable({ Name = "MeditateEntries" })
		end

		local entry = MeditateEntries[1]["DisplayName"]
		table.remove( MeditateEntries, 1 )

		AddGuideBookEntry( 2, entry )

	end
}

-- Remove "Roster" from Inventory / ItemPurchaseScreen Hack
OnMenuOpened{ "InventoryScreen",
	function( triggerArgs )
		waitScreenTime(0.01)
		if matchesPlayed == 0 then
			SetMenuOptions({ Name = "InventoryScreen", Item = "XButton", Properties = { FadeTarget = 0, Enabled = false} })
		end
	end
}

-- Tooltip Tutorial
OnTooltipViewed{ "Purgatory",
	RequiredFlag = "CheckingForTooltip",
	function( triggerArgs )
		blockPurgatoryTooltipTutorialBox = true
		SetFlagFalse({ Name = "CheckingForTooltip" })
		HideTutorialBox()
		waitScreenTime(0.65)
		SetMenuOptions({ Name = "DialogueScreen", Item = "ConfirmButton", Properties = { FadeTarget = 1.0, IsVisible = true, Enabled = true } })
	end
}

OnTriggerFired{ "CheckForDownsideTooltipTutorialbox",
	function(triggerArgs)
		wait(15)
		if not blockPurgatoryTooltipTutorialBox then
			DisplayTutorialBox({ HelpTextId = "Info_DownsideTooltip", X = 550, Y = 695, Animation = "TutorialBoxSmallIn", Arrow = "Down" })
		end
	end
}

-- Gender Choice
OnTooltipClicked{ "Coach_Gender_String",
	function( triggerArgs )
		ToggleGender()
		PlaySound({ Name = "/SFX/Menu Sounds/PageFlip" })
		SetMenuOptions({ Name = "DialogueScreen", Item = "DialogueBox", Properties = { ReReadText = true, PrintingSound = null } })
	end
}

function GetMatchStoryEvent()

	local eventName = nil

	-- added this flag for Open Structure event carousels, since GetMatchStoryEvent() called more than once / week
	if alreadyPickedEvent then
		return alreadyPickedEvent
	end

	-- True Nightwings exception; had to be moved up [GK 1/30/17]
	if PlayerTeam.AscensionMatchesPlayed == 2 and MatchesPlayedThisSeason == 2 then
		eventName = RemoveFirstIndexValue( League[11]["PreMatchEvents"] )
		alreadyPickedEvent = eventName
		PersistVariable({ Name = "alreadyPickedEvent" })
		return eventName
	end

	-- week one
	if matchesPlayed == 0 then
		eventName = "Intro_Week1_ReachedGoal"
	-- week two
	elseif matchesPlayed == 1 then
		eventName = "Week2_ReachedGoal"
	-- week three
	elseif matchesPlayed == 2 then
		eventName = "Week3_ReachedGoal"
	-- week four
	elseif matchesPlayed == 3 then
		eventName = "Week4_ReachedGoal"
	-- week five
	elseif matchesPlayed == 4 then
		eventName = "Week5_ReachedGoal"
	-- week six
	elseif matchesPlayed == 5 then
		eventName = "Week6_ReachedGoal"
	-- week seven
	elseif matchesPlayed == 6 then
		eventName = "Week7_ReachedGoal"
	-- week eight / first Ascension
	elseif matchesPlayed == 7 then
		eventName = "Week8_ReachedGoal"
	-- open structure
	elseif matchesPlayed > 7 then
		-- for ascension weeks
		if IsAscensionWeek() then
			-- Ascension 2 of 7
			if PlayerTeam.AscensionMatchesPlayed == 1 then
				eventName = "OpenStructure_ReachedGoal_Ascension2"
			-- Ascension 3 of 7
			elseif PlayerTeam.AscensionMatchesPlayed == 2 then
				eventName = "OpenStructure_ReachedGoal_Ascension3"
			-- Ascension 4 of 7
			elseif PlayerTeam.AscensionMatchesPlayed == 3 then
				eventName = "OpenStructure_ReachedGoal_Ascension4"
			-- Ascension 5 of 7
			elseif PlayerTeam.AscensionMatchesPlayed == 4 then
				eventName = "OpenStructure_ReachedGoal_Ascension5"
			-- Ascension 6 of 7
			elseif PlayerTeam.AscensionMatchesPlayed == 5 then
				eventName = "OpenStructure_ReachedGoal_Ascension6"
			-- Ascension 7 of 7
			elseif PlayerTeam.AscensionMatchesPlayed == 6 then
				eventName = "OpenStructure_ReachedGoal_Ascension7"
			end
		-- for standard weeks
		else
			-- pre-match events based on team you are facing
			if not IsEmpty( NextTeam.RivalryPreMatchEvents ) and IsRivalryPresent() then
				eventName = RemoveFirstIndexValue( NextTeam.RivalryPreMatchEvents )
				alreadyPickedEvent = eventName
				PersistVariable({ Name = "alreadyPickedEvent" })
			elseif not IsEmpty( NextTeam.PreMatchEvents ) then
				eventName = RemoveFirstIndexValue( NextTeam.PreMatchEvents )
				alreadyPickedEvent = eventName
				PersistVariable({ Name = "alreadyPickedEvent" })
			-- pre-match Pamitha / Tamitha exceptions
			-- elseif NextTeam["NextTeamIndex"] == 7 and CharVamp["RosterStatus"] == "Active" then
				-- stuff
			-- choose a general event otherwise
			else
				if IsHiddenArena() and not NarrationRecord["OpenStructure_HiddenArena_ReachedGoal_01"] then
					eventName = "OpenStructure_HiddenArena_ReachedGoal_01"
					alreadyPickedEvent = eventName
					PersistVariable({ Name = "alreadyPickedEvent" })
					return eventName
				elseif IsLastSeasonMatch() and not NarrationRecord["OpenStructure_LastSeasonMatch_ReachedGoal_01"] then
					eventName = "OpenStructure_LastSeasonMatch_ReachedGoal_01"
					alreadyPickedEvent = eventName
					PersistVariable({ Name = "alreadyPickedEvent" })
					return eventName
				elseif IsForfeitMatch() then
					eventName = "OpenStructure_ForfeitMatch_ReachedGoal_01"
					alreadyPickedEvent = eventName
					PersistVariable({ Name = "alreadyPickedEvent" })
					return eventName
				elseif not IsEmpty( PlayerTeam.PreMatchEvents ) then
					eventName = GetNextRemainingEvent( PlayerTeam.PreMatchEvents )
					alreadyPickedEvent = eventName
					PersistVariable({ Name = "alreadyPickedEvent" })
				-- for safety
				else
					eventName = "OpenStructure_ReachedGoal_01"
				end
			end
		end
	end

	return eventName

end

function GetJunctionEvent()

	local eventName = nil
	-- week one
	if matchesPlayed == 0 then
		if NarrationRecord["Intro_Week1_ExploreBloomingpool"] then
			-- eventName = "OpenStructure_BadLuck_LoseTime_01"
		end
	-- open structure
	elseif PlayerTeam.AscensionMatchesPlayed == 1 then
		if MatchesPlayedThisSeason == 0 then
			--
		elseif MatchesPlayedThisSeason == 1 then
			-- first messenger imp
			eventName = RemoveFirstIndexValue( JunctionEvents )
		elseif MatchesPlayedThisSeason == 2 then
			-- Jodi + Pamitha subplot
			if CharBadass.RosterStatus ~= "Ascended" and CharVamp.RosterStatus ~= "Ascended" then
				eventName = "OpenStructure_JodiPamitha_01"
			end
		elseif MatchesPlayedThisSeason == 3 then
			--
		end
	elseif PlayerTeam.AscensionMatchesPlayed == 2 then
		if MatchesPlayedThisSeason == 0 then
			--
		elseif MatchesPlayedThisSeason == 1 then
			-- second messenger imp
			eventName = RemoveFirstIndexValue( JunctionEvents )
		elseif MatchesPlayedThisSeason == 2 then
			--
		elseif MatchesPlayedThisSeason == 3 then
			--
		end
	elseif PlayerTeam.AscensionMatchesPlayed == 3 then
		if MatchesPlayedThisSeason == 0 then
			-- Falcon Ron Encounter
			eventName = "Junction_ShopKeeper_01"
		elseif MatchesPlayedThisSeason == 1 then
			-- third messenger imp
			eventName = RemoveFirstIndexValue( JunctionEvents )
		elseif MatchesPlayedThisSeason == 2 then
			--
		end
	elseif PlayerTeam.AscensionMatchesPlayed == 4 then
		if MatchesPlayedThisSeason == 0 then
			-- Oralech in Wagon
			eventName = "Junction_Nightwing_01"
		elseif MatchesPlayedThisSeason == 1 then
			-- fourth messenger imp
			eventName = RemoveFirstIndexValue( JunctionEvents )
		elseif MatchesPlayedThisSeason == 2 then
			--
		end
	elseif PlayerTeam.AscensionMatchesPlayed == 5 then
		if MatchesPlayedThisSeason == 0 then
			--
		elseif MatchesPlayedThisSeason == 1 then
			-- fifth messenger imp (ascension week)
			eventName = RemoveFirstIndexValue( JunctionEvents )
		end
	elseif PlayerTeam.AscensionMatchesPlayed == 6 then
		if MatchesPlayedThisSeason == 0 then
			--
		elseif MatchesPlayedThisSeason == 1 then
			-- sixth messenger imp (ascension week)
			eventName = RemoveFirstIndexValue( JunctionEvents )
		end
	end

	return eventName

end

function GetCampaignLocationMenuEvents()

	local storyEventName = GetNodeStoryEventName( currentNodeData )
	if storyEventName ~= nil then
		local locOption = AddLocationMenuOption( storyEventName )
		locOption.RemoveAfterChosen = true
		locOption.CreateCheckpoint = true
		return
	end

end

OnTriggerFired{ "ChangeTeamName",
	function( triggerArgs )
		local teamPrefix = "The"
		local team = "Something"
		if ActiveNarrationName == "S1W2_TeamName_01" then
			team = "AltTeamName01"
		elseif ActiveNarrationName == "S1W2_TeamName_02" then
			team = "AltTeamName02"
		elseif ActiveNarrationName == "S1W2_TeamName_03" then
			team = "AltTeamName03"
		elseif ActiveNarrationName == "S1W2_TeamName_04" then
			team = "AltTeamName04"
		elseif ActiveNarrationName == "S1W2_TeamName_06" then
			team = "AltTeamName06"
		elseif ActiveNarrationName == "S1W2_TeamName_07" then
			team = "AltTeamName07"
		elseif ActiveNarrationName == "S1W2_TeamName_08" then
			team = "AltTeamName08"
		elseif ActiveNarrationName == "S1W2_TeamName_09" then
			team = "AltTeamName09"
		elseif ActiveNarrationName == "S1W2_TeamName_10" then
			team = "AltTeamName10"
		elseif ActiveNarrationName == "S1W2_TeamName_11" then
			team = "AltTeamName11"
		elseif ActiveNarrationName == "S1W2_TeamName_12" then
			team = "AltTeamName12"
		elseif ActiveNarrationName == "S1W2_TeamName_13" then
			team = "AltTeamName13"
		elseif ActiveNarrationName == "S1W2_TeamName_14" then
			team = "AltTeamName14"
		elseif ActiveNarrationName == "S1W2_TeamName_15" then
			team = "AltTeamName15"
		elseif ActiveNarrationName == "S1W2_TeamName_16" then
			team = "AltTeamName16"
		elseif ActiveNarrationName == "S1W2_TeamName_17" then
			team = "AltTeamName17"
		elseif ActiveNarrationName == "S1W2_TeamName_18" then
			team = "AltTeamName18"
		elseif ActiveNarrationName == "S1W2_TeamName_19" then
			team = "AltTeamName19"
		elseif ActiveNarrationName == "S1W2_TeamName_20" then
			team = "AltTeamName20"
		end
		PlayerTeam.TeamName = team
	end
}

-- Week 1 Events
OnTriggerFired
{
	"SetStoreTutorialItem",
	function( triggerArgs )
		TutorialItem = LootedItem
		PersistVariable({ Name = "TutorialItem" })
	end
}

-- Week 2 Events

-- Week 3 Events
OnTriggerFired
{
	"SetMinstrelLocation",
	function( triggerArgs )
		if CoinFlip() then
			-- Moisteria
			minstrelLocation = NodeData[10023].Location
			NarrationRecord["MinstrelWentNorth"] = true
		else
			-- Fangnose Crest
			minstrelLocation = NodeData[10011].Location
			NarrationRecord["MinstrelWentSouth"] = true
		end
	end
}

-- Week 4 Events
OnTriggerFired
{
	"CheckMoneyQuestStatus",
	function( triggerArgs )
		if PlayerTeam.Money >= 1000 then
			NarrationRecord["MoneyQuest_EarnedEnough"] = true
		end
	end
}

-- Week 9 Events
OnTriggerFired
{
	"RevealOpenStructure",
	function( triggerArgs )

		allowCaravanFly = true
		PersistVariable({ Name = "allowCaravanFly" })
		takeoffQueued = true
		PersistVariable({ Name = "takeoffQueued" })

		DiscoverAllLandingPads()

	end
}

-- Open Structure Events
OnTriggerFired
{
	"SetUpPostAscensionStarPick",
	function( triggerArgs )
		postAscensionOpenStructureStarPick = true
	end
}

function DiscoverAllLandingPads()
	-- note: this no longer discovers Isle of Khaylmer / MatchSiteJ, which is revealed at a later point
	for nodeId, nodeData in pairs( NodeData ) do
		if nodeData.LandingPad and nodeData.Swath ~= 6 then
			-- all LandingPads become enabled
			nodeData.Disabled = false
			-- all LandingPads become Unpack nodes
			nodeData.Unpack = true
			-- all LandingPads discovered
			DiscoverNode( nodeData )
		end
	end
end

 OnTriggerFired
{
	-- used to advance the calendar in several intermission sequences
	"IntermissionCalendar",
	function( triggerArgs )
		local intermissionDuration = math.random(30,40)
		UpdateCurrentDate( intermissionDuration )
	end
}


-- **VISUAL & ART SCRIPTING** --

function SetupWrapping()
	WrapThing({ Name = "Swath_01_Fog", Speed = "10", OffsetX = 4000 })
	--WrapThing({ Name = "Swath_02_Fog", Speed = "30", OffsetX = 2500 })
	WrapThing({ Name = "Swath_03_Fog", Speed = "50", OffsetX = 2500 })
	WrapThing({ Name = "Swath_01_MovingLights", Speed = "10", OffsetX = 2500 })
	WrapThing({ Name = "Swath_02_MovingLights", Speed = "10", OffsetX = 2500 })
end

-- birds.com
function BirdEscape(escapeType, birdID, skipWait)

	if not skipWait then
		wait(SWATH_TRANSITION_TIME + 1.4)
	end

	Teleport({ Name = "BirdsA", DestinationId = realOvermapUnit, OffsetY = 300, OffsetX = 600 })
	SetColor({ Name = "BirdsA", Color = Color.Black })

	if escapeType == nil then
		escapeType = "Chaotic"
	end

	if birdEscapeInProgress then
		return
	end

	birdEscapeInProgress = true

	birdGang = GetGroupName({ Id = birdID })
	birdMap = GetMapName({ })

	--StopSound({ Name = "/SFX/World Sounds/BirdAmbience", Duration = 0.35 })

	if escapeType == "Chaotic" then

		local birdees = GetIds({ Name = birdGang })
		for k, v in pairs(birdees) do
			SetDrawLayer({ Id = v, Layer = "FLYING" })
			local escapeAngle = math.random(0, 360)
			local escapeSpeed = math.random(700, 1100)
			PlayAnimation({ Name = "BirdFly", DestinationId = v })
			SetGoalAngle({ Angle = escapeAngle, Id = v })
			Move({ Id = v, Angle = escapeAngle, Speed = escapeSpeed })
		end
		PlaySound({ Name = "/SFX/Leftovers/BirdFlutter" })
		wait(5.0)
		SetOpacity({ Ids = birdees, Fraction = 0, Duration = 0.25 })
		wait(0.3)
		Delete({ Ids = birdees })

		birdEscapeInProgress = false
	end

	if escapeType == "Organized" then

		local birdees = GetIds({ Name = birdGang })
		for k, v in pairs(birdees) do
			SetDrawLayer({ Id = v, Layer = "FLYING" })
			if birdMap == "Doors01" then
				escapeAngle = -25
			else
				local escapeAngle = GetAngle({ Id = v })
			end
			local escapeSpeed = math.random(700, 1100)
			PlayAnimation({ Name = "BirdFly", DestinationId = v })
			SetGoalAngle({ Angle = escapeAngle, Id = v })
			Move({ Id = v, Angle = escapeAngle, Speed = escapeSpeed })
		end
		--PlaySound({ Name = "/SFX/World Sounds/BirdFlutter" })
		wait(5.0)
		SetOpacity({ Ids = birdees, Fraction = 0, Duration = 0.25 })
		wait(0.3)
		Delete({ Ids = birdees })

		birdEscapeInProgress = false
	end
end

function BirdsLeaveCoach( birdID )

	birdGang = GetGroupName({ Id = birdID })
	birdMap = GetMapName({ })

	local birdees = GetIds({ Name = birdGang })
	for k, v in pairs(birdees) do
		--SetDrawLayer({ Id = v, Layer = "FLYING" })
		local escapeAngle = math.random(30, 160)
		local escapeSpeed = math.random(500, 650)
		PlayAnimation({ Name = "BirdFly", DestinationId = v })
		SetGoalAngle({ Angle = escapeAngle, Id = v })
		Move({ Id = v, Angle = escapeAngle, Speed = escapeSpeed })
	end
	PlaySound({ Name = "/SFX/Leftovers/BirdFlutter" })
	wait(5.0)
	SetOpacity({ Ids = birdees, Fraction = 0, Duration = 0.25 })
	wait(0.3)
	Delete({ Ids = birdees })

	birdEscapeInProgress = false
end

-- Context Art --

OnAnyLoad
{
	function( triggerArgs )
		SetGroupVisibility({ Names = ArchjusticeOvermapGroups, Visible = false })
		HideContextArt()
	end
}

function HideContextArt()
	SetOpacity({ Names = AllSwathContextArtGroups, Fraction = 0 })
	SetGroupVisibility({ Names = AllSwathContextArtGroups, Visible = false })
end

function SwathContextVisuals( contextSwitch, contextDelay )

	if contextDelay ~= nil and contextDelay > 0 then
		wait(contextDelay)
	end

	-- cleaner way will be using GetSubGroups w/o parent group for this to work
	local contextArtGroupNames = nil
	if NodeData[currentNodeId].ContextArtGroup ~= nil then
		contextArtGroupNames = GetGroupWithSubGroups({ Name = NodeData[currentNodeId].ContextArtGroup })
	end

	if contextArtGroupNames == nil then
		return
	end

	if contextSwitch == "ComingIn" then

		SetGroupVisibility({ Names = contextArtGroupNames, Visible = true })

		for k, v in pairs( contextArtGroupNames ) do

			-- need to do better string matching or group naming
			if string.match(v, 'LEFT-$') then
				Move({ Name = v, Angle = 0, Speed = 10, KeepRelativeOffsets = true })
				Stop({ Name = v, Delay = 0.75 })
			elseif string.match(v, 'RIGHT-$') then
				Move({ Name = v, Angle = 180, Speed = 10, KeepRelativeOffsets = true })
				Stop({ Name = v, Delay = 0.75 })
			elseif string.match(v, 'UP-$') then
				Move({ Name = v, Angle = 270, Speed = 10, KeepRelativeOffsets = true })
				Stop({ Name = v, Delay = 0.75 })
			elseif string.match(v, 'DOWN-$') then
				Move({ Name = v, Angle = 90, Speed = 10, KeepRelativeOffsets = true })
				Stop({ Name = v, Delay = 0.75 })
			end
		end
		SetOpacity({ Names = contextArtGroupNames, Fraction = 1, Duration = 0.45 })
	elseif contextSwitch == "GoingOut" then
		SetOpacity({ Names = contextArtGroupNames, Fraction = 0, Duration = 0.3 })
		wait(0.3)
		SetGroupVisibility({ Names = contextArtGroupNames, Visible = false })
	end

end

OnKeyPressed{ "Alt H", Name = "SwathContextVisuals",
	function(triggerArgs)
		LockCamera({ Id = realOvermapUnit, OffsetY = -300 })
		AdjustZoom({ Fraction = 1.0, LerpTime = 0.3, Duration = 999999 })
		if not cheatIn then
			cheatIn = true
			thread( SwathContextVisuals, "ComingIn" )
		elseif cheatIn then
			cheatIn = false
			thread( SwathContextVisuals, "GoingOut" )
		end
	end
}

OnKeyPressed{ "ControlShift G", Name = "UnlockCaravan",
	function( triggerArgs )
		DebugPrint({ Text = "Caravan Free Movement" })
		SetUnitProperty({ DestinationId = GetActiveUnitId({ PlayerIndex = 1 }), Name = "Speed", Value = 500 })
	end
}

function ZoomBlur( bloomTransistionTime, radialBlur )

	--local currentBloom = GetBloomSettingName({ })
	--AdjustFullscreenBloom({ Name = "BlurryZoom", Duration = 0.15 })

	if radialBlur == "RadialBlurOn" then
		AdjustRadialBlurStrength({ Fraction = 1.6, Duration = 0.15 })
		AdjustRadialBlurDistance({ Fraction = 1.6, Duration = 0.15 })
	elseif radialBlur == "RadialBlurSlight" then
		AdjustRadialBlurStrength({ Fraction = 1.35, Duration = 0.15 })
		AdjustRadialBlurDistance({ Fraction = 1.35, Duration = 0.15 })
	end

	wait(bloomTransistionTime)

	--AdjustFullscreenBloom({ Name = currentBloom, Duration = 0.35 })
	AdjustRadialBlurDistance({ Fraction = 0, Duration = 0.2 })
	AdjustRadialBlurStrength({ Fraction = 0, Duration = 0.2 })

end

-- |ARCHJUSTICE / MINSTREL| --

-- minstrel leaving
function PreMinstrelGone()
	minstrelId = 210105
	SetOpacity({ Id = minstrelId, Fraction = 1.0, Duration = 0, Delay = 0.5 })
	minstrelTorches = { }
	for index = 1, 3, 1 do
		local randomOffsetX = math.random(-30, 30)
		local randomOffsetY = math.random(-500, 300)
		local newTorch = SpawnObstacle({ Name = "Torch", DestinationId = minstrelId, Group = "Wagon_06", OffsetX = randomOffsetX, OffsetY = randomOffsetY })
		table.insert(minstrelTorches, newTorch)
		SetColor({ Id = newTorch, Color = { 255, 174, 0, 255 } })
		SetScale({ Id = newTorch, Fraction = 4 })
	end
end

function MinstrelGone()
	wait(1.2)
	local currentMinstrelZoom = GetCameraZoom({ })
	--PanCamera({ Id = minstrelId, Duration = 5.5, OffsetX = -200 })
	PanCamera({ Id = wagonCameraLockPoint, OffsetX = 100, Duration = 3.5 })
	FocusCamera({ Fraction = currentMinstrelZoom * 1.025, Duration = 3.5, ZoomType = "Ease" })
	PlaySound({ Name = "/SFX/World Sounds/MapZoomSlow", Delay = 0.1 })
	Move({ Id = minstrelId, Speed = 80, Angle = 180, Delay = 0.75 })
	SetOpacity({ Id = minstrelId, Fraction = 0.0, Duration = 1.6, Delay = 0.5 })
	SetOpacity({ Ids = minstrelTorches, Fraction = 0, Duration = 0.5, Delay = 1.1 })
	wait(3.5)
	Stop({ Id = minstrelId })
end


function FadePanUpElements()
	local PanUpFadeGroups = {
		"Swath_09_Waterfall01",
		"Swath_09_Waterfall02",
		"Swath_09_Backing01",
		"Swath_07_FadeBack01",
		"Swath_07_CA_10040_Mid_RIGHT",
		"Swath_02_FadeFore01",
		"Swath_02_CA_210298_Fore_LEFT",
		"Swath_02_CA_210298_Mid_LEFT",
		"Swath_02_CA_210298_Fore_RIGHT",
		"Swath_02_CA_210298_Mid_RIGHT",
		"Swath_02_CA_10004_Fore_LEFT",
		"Swath_02_CA_10004_Fore_RIGHT",
		"Swath_02_CA_10004_Mid_LEFT",
		"Swath_02_CA_10004_Mid_RIGHT",
		"Swath_03_CA_10029_Fore_RIGHT",
		"Swath_03_Smoke01_Anims",
		"Swath_05_SeawallFX_01_X",
		"Swath_06_FadeFore01",
		"Swath_06_Lightning",
		"Swath_06_InkFX01",
		--"Swath_07_CA_10041_Fore_LEFT",
		--"Swath_07_CA_10041_Fore_RIGHT",
		--"Swath_07_CA_10041_Mid_LEFT",
		--"Swath_07_CA_10041_Mid_RIGHT",
		"Swath_07_Lighting01",
		"Swath_09_BGHalos02",
		"Patterns01",
	}
	SetOpacity({ Names = PanUpFadeGroups, Fraction = 0, Duration = 0.5 })
end

function PreMatchPresentation()
	activatedPreMatchPresentation = true
	DisableInput({ })
	HideOvermapUI()
	thread(ShowInputDisabledPresentation)
	PlaySound({ Name = "/SFX/World Sounds/MapZoomSlow" })

	FadeForegroundElements()
	AdjustColorGrading({ Name = "Off", Duration = 2.0, Delay = 1.5 })
	FadeOutFlyers({ Names = SpecialOvermapFlyers, Duration = 2.0, Delay = 1.5 })
	overmapRain = false
	StopSound({ Name = currentAmbience2, Duration = 0.3 })
	currentAmbience2 = nil
	SetupConstellationVisuals( StarAlignmentLocations[currentNodeId] )

	SetOpacity({ Ids = { 310428, 210724 }, Fraction = 0, Duration = 0.5, Delay = 3 }) -- Ridge of Gol smoke
	SetOpacity({ Ids = { 210056, 210012 }, Fraction = 0, Duration = 0.5, Delay = 3 }) -- Ridge of Gol smoke

	local lightningGroup = "Swath_0"..currentlyOccupiedSwath.."_Lightning"
	SetGroupVisibility({ Name = lightningGroup, Visible = false })

	FadeForegroundElements()
	FadePanUpElements()

	if StarAlignmentLocations[currentNodeId] ~= nil then
		ClearCameraClamp({ LerpTime = 1 })
		PanCamera({ Id = StarAlignmentLocations[currentNodeId], Duration = 6, EaseIn = 0.2, EaseOut = 1, OffsetY = -250 })
		--AdjustColorGrading({ Name = "Off", Duration = 2.5, Delay = 2.2 }) -- REVERT AFTER PSX
		FocusCamera({ Fraction = 0.4, Duration = 4.8, ZoomType = "Ease", Delay = 1.2 })
	end

	wait(4.25)
	CreateConstellations()
end

ArchjusticeOvermapGroups = { "ArchjusticeTest", "Archjustice", "ArchjusticeBack" }
function SummonArchJustice( summonDuration, summonLine )

	-- allow morning transition
	wait(1.0)

	-- fade out
	thread( FullscreenFadeOut, "Fast" )
	SoundFadeOutAndPause({ SoundId = MusicId, Duration = 5.0 })

	wait(1.3)

	-- setup everything
	SetGroupVisibility({ Names = ArchjusticeOvermapGroups, Visible = true })
	SetScale({ Names = ArchjusticeOvermapGroups, Fraction = 4.0, Delay = "4", Duration = 300 })
	AdjustColorGrading({ Name = "Off", Duration = summonDuration, Delay = 1.0 })
	local cameraCenter = SpawnObstacle({ Name = "InvisibleTarget", DestinationId = realOvermapUnit, Group = "Scripting" })
	DrawScreenRelative({ Id = cameraCenter })
	Teleport({ Id = cameraCenter, OffsetX = 1920/2, OffsetY = 1080/2 })
	Teleport({ Name = ArchjusticeOvermapGroups, DestinationId = cameraCenter, KeepRelativeOffsets = true, DestinationIsScreenRelative = true, RelativeOffsetId = 310341, IgnoreChildren = true })

	wait(0.2)

	-- fade in
	PlaySound({ Name = "/SFX/Match SFX/GoalScored" })
	thread( FullscreenFadeIn, "Fast" )
	PlaySound({ Name = "/Ambience/MatchSiteAAmbience" })
	AdjustColorGrading({ Name = "Scoring", Duration = 0.25 })
	CreateMeteringEntry({ Name = "ArchJustice", DSP = "/Silent/VisualVOcontrol", FalloffTime = 1.0, PropagationTime = -1.0, MaxDistance = 999999 })
	PlaySound({ Name = "/SFX/World Sounds/MapZoomInTight" })
	PlaySound({ Name = "/SFX/Leftovers/TextReveal" })
	local mapBloom = GetBloomSettingName({ })
	AdjustFullscreenBloom({ Name = "BlurryZoom" })
	PlaySpeech({ Name = summonLine, Delay = 0.35 + 0.7 })

	wait(summonDuration)

	-- fade out
	PlaySound({ Name = "/SFX/World Sounds/MapZoomIn" })
	StopSound({ Name = "/Ambience/MatchSiteAAmbience", Duration = 3.0 })
	thread( FullscreenFadeOut, "Fast" )

	wait(1.3)

	-- reset everything
	SetGroupVisibility({ Names = ArchjusticeOvermapGroups, Visible = false })
	AdjustFullscreenBloom({ Name = mapBloom, Duration = 0.05 })
	if SpecialOvermapColorGrade then
		AdjustColorGrading({ Name = SpecialOvermapColorGrade, Duration = 0.05 })
	end

	wait(0.2)

	-- fade in
	thread( FullscreenFadeIn, "Fast" )
	SoundFadeInAndResume({ SoundId = MusicId, Duration = 1.0 })
end

ArchjusticeAppearanceData =
{
	["FirstScare"] =
	{
		AppearanceDuration = 31,
		-- I do so hate to thusly contact you, O Reader.
		AppearanceStartingLine = "/VO/Justice_1075",
		RequiredAscensionMatchesPlayed = 3,
		RequiredMatchesPlayedThisSeason = 0,
		RequiredNodeId = 10051,
	},
	["SecondScare"] =
	{
		AppearanceDuration = 22,
		-- You are nothing, Reader.
		AppearanceStartingLine = "/VO/Justice_1046",
		RequiredAscensionMatchesPlayed = 4,
		RequiredMatchesPlayedThisSeason = 1,
		SkipMatchSite = true,
	},
	["ThirdScare"] =
	{
		AppearanceDuration = 18,
		-- Foolish Reader.
		AppearanceStartingLine = "/VO/Justice_981",
		RequiredAscensionMatchesPlayed = 6,
		RequiredMatchesPlayedThisSeason = 1,
	},
}

ArchjusticeAppearanceRecord = ArchjusticeAppearanceRecord or {}
PersistVariable({ Name = "ArchjusticeAppearanceRecord" })

function CheckArchjusticeAppearance()
	for k, v in pairs( ArchjusticeAppearanceData ) do
		if PlayerTeam.AscensionMatchesPlayed == v.RequiredAscensionMatchesPlayed and MatchesPlayedThisSeason == v.RequiredMatchesPlayedThisSeason and not ArchjusticeAppearanceRecord[k] then
			if v.RequiredNodeId ~= nil and currentNodeId ~= v.RequiredNodeId then
				return
			end
			if v.SkipMatchSite ~= nil then
				local currentNode = NodeData[currentNodeId]
				if currentNode.Category == "Arena" then
					return
				end
			end
			ArchjusticeAppearanceRecord[k] = true
			SummonArchJustice( v.AppearanceDuration, v.AppearanceStartingLine )
		end
	end
end

OnKeyPressed{ "None K",
	function(triggerArgs)
		HideOvermapLocationIndicators()
		--SummonArchJustice(7, "/VO/Match_401" )
		SummonArchJustice( 4, "/VO/Overmap_10" )
		--SummonArchJustice(12.5, "/VO/Match_399")

		--CheckFlyingOvermapState()
	end
}


MagicRing = { 310657, 210142, 313102, 314095, 314083, 314084, 314089, 314090 }
OnAnyLoad
{
	function( triggerArgs )
		SetOpacity({ Ids = MagicRing, Fraction = 0 })
	end
}

OnKeyPressed{ "None H",
	function( triggerArgs )
		SetUnitProperty({ Name = "Speed", DestinationId = realOvermapUnit, Value = 300 })
		LockCamera({ Id = realOvermapUnit, Duration = 0.1 })

		SetGoalAngle({ Id = realOvermapUnit, Angle = 180 })
		SetUnitProperty({ Name = "CollideWithObstacles", DestinationId = realOvermapUnit, Value = false })
		DisableInput({  PlayerIndex = 1 })
		HideOvermapLocationIndicators()
		wait(1.0)

		local travelDistance = 5000
		local caravanGoal = SpawnObstacle({ Name = "InvisibleTarget", DestinationId = realOvermapUnit, OffsetY = 0, OffsetX = -travelDistance }) -- straight left
		Move({ Id = realOvermapUnit, DestinationId = caravanGoal, Mode = "Precise" })

	end
}