Tutorial:Patching Ground Map Scripts
A guide on how to patch the scripts of ground maps with a mod without overriding the entire script.
First Steps
To begin the process of adding changes, a new init.lua file for the ground map must be created in the mod's script folder. From the root folder of the mod, this file is placed in Data/Script/[dungeonNamespace]/ground/[groundMap].
In this file, create a new table to store the mod functions in. This is similar to the table that exists in the vanilla ground script files, in that it will be referenced to call the functions. The typical naming convention is to name them first the base name of the ground map, then a name referencing the mod.
This is how enable_mission_board initalizes its namespace:
local base_camp_2_bulletin = {}
As a final step, make sure to write return (namespace) as the last line of the file, or otherwise the changes won't work!
Adding New Scripts
To add new scripts, a function is added to the namespace defined in the function table. These scripts are set up in the same way that scripts are added to ground maps.
Here is how enable_mission_board adds an action to the Mission_Board ground object:
function base_camp_2_bulletin.Mission_Board_Action(obj, activator)
DEBUG.EnableDbgCoro() --Enable debugging this coroutine
local dungeons_needed = 3 --Number of dungeons needed to unlock the Mission Board
local hero = CH('PLAYER')
GROUND:CharSetAnim(hero, 'None', true)
if SV.MissionPrereq.NumDungeonsCompleted >= dungeons_needed then
local menu = BoardSelectionMenu:new(COMMON.MISSION_BOARD_MISSION)
UI:SetCustomMenu(menu.menu)
UI:WaitForChoice()
else
UI:ResetSpeaker()
UI:WaitShowDialogue(STRINGS:Format(MapStrings['Mission_Board_Locked']))
UI:WaitShowDialogue(STRINGS:Format(MapStrings['Mission_Board_Locked_2'], dungeons_needed - SV.MissionPrereq.NumDungeonsCompleted))
end
GROUND:CharEndAnim(hero)
end
Changing Base Scripts
In order to properly modify base scripts, CURMAPSCR is used as a placeholder. This allows the mod to capture the base function that is run in the map, and then execute it after making its own changes.
As an example, this is how enable_mission_board injects some new code to run when entering the map:
local base_enter = CURMAPSCR.Enter
function base_camp_2_bulletin.Enter(map)
DEBUG.EnableDbgCoro() --Enable debugging this coroutine
if SV.MissionsEnabled == true then
GROUND:Unhide("Mission_Board")
end
if SV.TemporaryFlags.MissionCompleted then
base_camp_2_bulletin.Hand_In_Missions()
end
base_enter(map)
end
Here CURMAPSCR is used to store the original base camp enter function. The mod runs its own code first, and then when done runs the function from the base game in order to execute the regular code.
