diff --git a/CMakeLists.txt b/CMakeLists.txt index a02a23b92..dcb5b42ff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -195,8 +195,8 @@ if(NOT EXISTS ${dfhack_SOURCE_DIR}/library/xml/codegen.pl endif() # set up versioning. -set(DF_VERSION "0.50.03") -set(DFHACK_RELEASE "alpha0pre1") +set(DF_VERSION "50.05") +set(DFHACK_RELEASE "alpha0") set(DFHACK_PRERELEASE TRUE) set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}") @@ -258,6 +258,7 @@ if(UNIX) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32 -march=i686") endif() string(REPLACE "-DNDEBUG" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + set(CMAKE_INSTALL_RPATH "hack") elseif(MSVC) # for msvc, tell it to always use 8-byte pointers to member functions to avoid confusion set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /vmg /vmm /MP") @@ -447,8 +448,6 @@ endif() file(WRITE "${CMAKE_BINARY_DIR}/dfhack_setarch.txt" ${DFHACK_SETARCH}) install(FILES "${CMAKE_BINARY_DIR}/dfhack_setarch.txt" DESTINATION "${DFHACK_DATA_DESTINATION}") -install(DIRECTORY dfhack-config/ DESTINATION dfhack-config/default) - # build the plugins if(BUILD_PLUGINS) add_subdirectory(plugins) diff --git a/data/CMakeLists.txt b/data/CMakeLists.txt index 412ffa347..8cbd910cb 100644 --- a/data/CMakeLists.txt +++ b/data/CMakeLists.txt @@ -1,20 +1,23 @@ +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/dfhack-config/ + DESTINATION "${DFHACK_DATA_DESTINATION}/data/dfhack-config-defaults") + install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/init/ DESTINATION "${DFHACK_DATA_DESTINATION}/init") install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/base_command_counts.json - DESTINATION "${DFHACK_DATA_DESTINATION}/data/base_command_counts.json") + DESTINATION "${DFHACK_DATA_DESTINATION}/data") install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/quickfort/ DESTINATION "${DFHACK_DATA_DESTINATION}/data/quickfort") install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/orders/ - DESTINATION dfhack-config/orders/library) + DESTINATION "${DFHACK_DATA_DESTINATION}/data/orders") -install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/examples/ - DESTINATION "${DFHACK_DATA_DESTINATION}/examples") +install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/art/ + DESTINATION "${DFHACK_DATA_DESTINATION}/data/art") install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/professions/ - DESTINATION dfhack-config/professions/library) + DESTINATION "${DFHACK_DATA_DESTINATION}/data/professions") install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/blueprints/ DESTINATION blueprints diff --git a/data/art/dfhack.png b/data/art/dfhack.png new file mode 100644 index 000000000..17719f084 Binary files /dev/null and b/data/art/dfhack.png differ diff --git a/dfhack-config/autonick.txt b/data/dfhack-config/autonick.txt similarity index 100% rename from dfhack-config/autonick.txt rename to data/dfhack-config/autonick.txt diff --git a/dfhack-config/dfstatus.lua b/data/dfhack-config/dfstatus.lua similarity index 100% rename from dfhack-config/dfstatus.lua rename to data/dfhack-config/dfstatus.lua diff --git a/dfhack-config/dwarfmonitor.json b/data/dfhack-config/dwarfmonitor.json similarity index 100% rename from dfhack-config/dwarfmonitor.json rename to data/dfhack-config/dwarfmonitor.json diff --git a/dfhack-config/init/default.dfhack.init b/data/dfhack-config/init/default.dfhack.init similarity index 100% rename from dfhack-config/init/default.dfhack.init rename to data/dfhack-config/init/default.dfhack.init diff --git a/dfhack-config/init/default.onLoad.init b/data/dfhack-config/init/default.onLoad.init similarity index 100% rename from dfhack-config/init/default.onLoad.init rename to data/dfhack-config/init/default.onLoad.init diff --git a/dfhack-config/init/default.onMapLoad.init b/data/dfhack-config/init/default.onMapLoad.init similarity index 100% rename from dfhack-config/init/default.onMapLoad.init rename to data/dfhack-config/init/default.onMapLoad.init diff --git a/dfhack-config/init/default.onMapUnload.init b/data/dfhack-config/init/default.onMapUnload.init similarity index 100% rename from dfhack-config/init/default.onMapUnload.init rename to data/dfhack-config/init/default.onMapUnload.init diff --git a/dfhack-config/init/default.onUnload.init b/data/dfhack-config/init/default.onUnload.init similarity index 100% rename from dfhack-config/init/default.onUnload.init rename to data/dfhack-config/init/default.onUnload.init diff --git a/dfhack-config/init/dfhack.init b/data/dfhack-config/init/dfhack.init similarity index 100% rename from dfhack-config/init/dfhack.init rename to data/dfhack-config/init/dfhack.init diff --git a/data/examples/init/onMapLoad_dreamfort.init b/data/dfhack-config/init/examples/onMapLoad_dreamfort.init similarity index 100% rename from data/examples/init/onMapLoad_dreamfort.init rename to data/dfhack-config/init/examples/onMapLoad_dreamfort.init diff --git a/dfhack-config/init/onLoad.init b/data/dfhack-config/init/onLoad.init similarity index 100% rename from dfhack-config/init/onLoad.init rename to data/dfhack-config/init/onLoad.init diff --git a/dfhack-config/init/onMapLoad.init b/data/dfhack-config/init/onMapLoad.init similarity index 100% rename from dfhack-config/init/onMapLoad.init rename to data/dfhack-config/init/onMapLoad.init diff --git a/dfhack-config/init/onMapUnload.init b/data/dfhack-config/init/onMapUnload.init similarity index 100% rename from dfhack-config/init/onMapUnload.init rename to data/dfhack-config/init/onMapUnload.init diff --git a/dfhack-config/init/onUnload.init b/data/dfhack-config/init/onUnload.init similarity index 100% rename from dfhack-config/init/onUnload.init rename to data/dfhack-config/init/onUnload.init diff --git a/data/dfhack-config/overlay.json b/data/dfhack-config/overlay.json new file mode 100644 index 000000000..7ebae0948 --- /dev/null +++ b/data/dfhack-config/overlay.json @@ -0,0 +1,8 @@ +{ + "hotkeys.menu": { + "enabled": true + }, + "unsuspend.overlay": { + "enabled": true + } +} diff --git a/dfhack-config/quickfort/aliases.txt b/data/dfhack-config/quickfort/aliases.txt similarity index 100% rename from dfhack-config/quickfort/aliases.txt rename to data/dfhack-config/quickfort/aliases.txt diff --git a/dfhack-config/quickfort/quickfort.txt b/data/dfhack-config/quickfort/quickfort.txt similarity index 100% rename from dfhack-config/quickfort/quickfort.txt rename to data/dfhack-config/quickfort/quickfort.txt diff --git a/dfhack-config/script-paths.txt b/data/dfhack-config/script-paths.txt similarity index 100% rename from dfhack-config/script-paths.txt rename to data/dfhack-config/script-paths.txt diff --git a/data/dfhack-config/scripts/README.md b/data/dfhack-config/scripts/README.md new file mode 100644 index 000000000..95b67b058 --- /dev/null +++ b/data/dfhack-config/scripts/README.md @@ -0,0 +1,7 @@ +You can put scripts you write or download in this folder and DFHack will find +them. + +If a script in this directory has the same name as a default DFHack script, the + script in this directory will take precedence. + +Everything you add to this folder will be kept safe when you upgrade DFHack. diff --git a/data/examples/README.md b/data/examples/README.md deleted file mode 100644 index fb2b8e3a1..000000000 --- a/data/examples/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# The DFHack Example Configuration File Library - -This folder contains ready-to-use examples of various DFHack configuration -files. You can use them by copying them to appropriate folders where DFHack -and its plugins can find them. You can use them unmodified, or you can -customize them to better suit your preferences. - -For information on each of the files in this library, see the -[DFHack Example Configuration File Guide](https://docs.dfhack.org/en/stable/docs/guides/examples-guide.html). diff --git a/data/init/dfhack.keybindings.init b/data/init/dfhack.keybindings.init index 478b78753..c6620f492 100644 --- a/data/init/dfhack.keybindings.init +++ b/data/init/dfhack.keybindings.init @@ -20,7 +20,7 @@ keybinding add Ctrl-Shift-C hotkeys keybinding add Ctrl-Shift-K gui/cp437-table # an in-game init file editor -keybinding add Alt-S@title|dwarfmode/Default|dungeonmode gui/settings-manager +#keybinding add Alt-S@title|dwarfmode/Default|dungeonmode gui/settings-manager ###################### @@ -28,142 +28,142 @@ keybinding add Alt-S@title|dwarfmode/Default|dungeonmode gui/settings-manager ###################### # quicksave, only in main dwarfmode screen and menu page -keybinding add Ctrl-Alt-S@dwarfmode/Default quicksave +#keybinding add Ctrl-Alt-S@dwarfmode/Default quicksave # toggle the display of water level as 1-7 tiles keybinding add Ctrl-W@dwarfmode|dungeonmode twaterlvl # designate the whole vein for digging -keybinding add Ctrl-V@dwarfmode digv -keybinding add Ctrl-Shift-V@dwarfmode "digv x" +#keybinding add Ctrl-V@dwarfmode digv +#keybinding add Ctrl-Shift-V@dwarfmode "digv x" # clean the selected tile of blood etc -keybinding add Ctrl-C spotclean +#keybinding add Ctrl-C spotclean # destroy the selected item -keybinding add Ctrl-K@dwarfmode autodump-destroy-item +#keybinding add Ctrl-K@dwarfmode autodump-destroy-item # destroy items designated for dump in the selected tile -keybinding add Ctrl-Shift-K@dwarfmode autodump-destroy-here +#keybinding add Ctrl-Shift-K@dwarfmode autodump-destroy-here # apply blueprints to the map (Alt-F for compatibility with LNP Quickfort) -keybinding add Ctrl-Shift-Q@dwarfmode gui/quickfort -keybinding add Alt-F@dwarfmode gui/quickfort +#keybinding add Ctrl-Shift-Q@dwarfmode gui/quickfort +#keybinding add Alt-F@dwarfmode gui/quickfort # show information collected by dwarfmonitor -keybinding add Alt-M@dwarfmode/Default "dwarfmonitor prefs" -keybinding add Ctrl-F@dwarfmode/Default "dwarfmonitor stats" +#keybinding add Alt-M@dwarfmode/Default "dwarfmonitor prefs" +#keybinding add Ctrl-F@dwarfmode/Default "dwarfmonitor stats" # set the zone or cage under the cursor as the default -keybinding add Alt-Shift-I@dwarfmode/Zones "zone set" +#keybinding add Alt-Shift-I@dwarfmode/Zones "zone set" # Stocks plugin -keybinding add Ctrl-Shift-Z@dwarfmode/Default "stocks show" +#keybinding add Ctrl-Shift-Z@dwarfmode/Default "stocks show" # open an overview window summarising some stocks (dfstatus) -keybinding add Ctrl-Shift-I@dwarfmode/Default|dfhack/lua/dfstatus gui/dfstatus +#keybinding add Ctrl-Shift-I@dwarfmode/Default|dfhack/lua/dfstatus gui/dfstatus # change quantity of manager orders -keybinding add Alt-Q@jobmanagement/Main gui/manager-quantity +#keybinding add Alt-Q@jobmanagement/Main gui/manager-quantity # re-check manager orders -keybinding add Alt-R@jobmanagement/Main workorder-recheck +#keybinding add Alt-R@jobmanagement/Main workorder-recheck # set workorder item details (on workorder details screen press D again) -keybinding add D@workquota_details gui/workorder-details +#keybinding add D@workquota_details gui/workorder-details # view combat reports for the selected unit/corpse/spatter -keybinding add Ctrl-Shift-R@dwarfmode|unit|unitlist|joblist|dungeon_monsterstatus|layer_unit_relationship|item|workshop_profile|layer_noblelist|locations|pets|layer_overall_health|textviewer|reportlist|announcelist|layer_military|layer_unit_health|customize_unit|buildinglist|workshop_profile view-unit-reports +#keybinding add Ctrl-Shift-R@dwarfmode|unit|unitlist|joblist|dungeon_monsterstatus|layer_unit_relationship|item|workshop_profile|layer_noblelist|locations|pets|layer_overall_health|textviewer|reportlist|announcelist|layer_military|layer_unit_health|customize_unit|buildinglist|workshop_profile view-unit-reports # view extra unit information -keybinding add Alt-I@dwarfmode/ViewUnits|unitlist gui/unit-info-viewer +#keybinding add Alt-I@dwarfmode/ViewUnits|unitlist gui/unit-info-viewer # boost priority of jobs related to the selected entity -keybinding add Alt-N@dwarfmode|job|joblist|unit|unitlist|joblist|dungeon_monsterstatus|layer_unit_relationship|item|layer_noblelist|locations|pets|layer_overall_health|textviewer|reportlist|announcelist|layer_military|layer_unit_health|customize_unit|buildinglist|textviewer|item|layer_assigntrade|tradegoods|store|assign_display_item|treasurelist do-job-now +#keybinding add Alt-N@dwarfmode|job|joblist|unit|unitlist|joblist|dungeon_monsterstatus|layer_unit_relationship|item|layer_noblelist|locations|pets|layer_overall_health|textviewer|reportlist|announcelist|layer_military|layer_unit_health|customize_unit|buildinglist|textviewer|item|layer_assigntrade|tradegoods|store|assign_display_item|treasurelist do-job-now # export a Dwarf's preferences screen in BBCode to post to a forum -keybinding add Ctrl-Shift-F@textviewer forum-dwarves +#keybinding add Ctrl-Shift-F@textviewer forum-dwarves # q->stockpile - copy & paste stockpiles -keybinding add Alt-P@dwarfmode/QueryBuilding/Some/Stockpile copystock +#keybinding add Alt-P@dwarfmode/QueryBuilding/Some/Stockpile copystock # q->stockpile - load and save stockpile settings out of game -keybinding add Alt-L@dwarfmode/QueryBuilding/Some/Stockpile "gui/stockpiles -load" -keybinding add Alt-S@dwarfmode/QueryBuilding/Some/Stockpile "gui/stockpiles -save" +#keybinding add Alt-L@dwarfmode/QueryBuilding/Some/Stockpile "gui/stockpiles -load" +#keybinding add Alt-S@dwarfmode/QueryBuilding/Some/Stockpile "gui/stockpiles -save" # q->workshop - duplicate the selected job -keybinding add Ctrl-D job-duplicate +#keybinding add Ctrl-D job-duplicate # materials: q->workshop; b->select items -keybinding add Shift-A "job-material ALUNITE" -keybinding add Shift-M "job-material MICROCLINE" -keybinding add Shift-D "job-material DACITE" -keybinding add Shift-R "job-material RHYOLITE" -keybinding add Shift-I "job-material CINNABAR" -keybinding add Shift-B "job-material COBALTITE" -keybinding add Shift-O "job-material OBSIDIAN" -keybinding add Shift-T "job-material ORTHOCLASE" -keybinding add Shift-G "job-material GLASS_GREEN" +#keybinding add Shift-A "job-material ALUNITE" +#keybinding add Shift-M "job-material MICROCLINE" +#keybinding add Shift-D "job-material DACITE" +#keybinding add Shift-R "job-material RHYOLITE" +#keybinding add Shift-I "job-material CINNABAR" +#keybinding add Shift-B "job-material COBALTITE" +#keybinding add Shift-O "job-material OBSIDIAN" +#keybinding add Shift-T "job-material ORTHOCLASE" +#keybinding add Shift-G "job-material GLASS_GREEN" # sort units and items in the on-screen list -keybinding add Alt-Shift-N "sort-units name" "sort-items description" -keybinding add Alt-Shift-R "sort-units arrival" -keybinding add Alt-Shift-T "sort-units profession" "sort-items type material" -keybinding add Alt-Shift-Q "sort-units squad_position" "sort-items quality" +#keybinding add Alt-Shift-N "sort-units name" "sort-items description" +#keybinding add Alt-Shift-R "sort-units arrival" +#keybinding add Alt-Shift-T "sort-units profession" "sort-items type material" +#keybinding add Alt-Shift-Q "sort-units squad_position" "sort-items quality" # browse linked mechanisms -keybinding add Ctrl-M@dwarfmode/QueryBuilding/Some gui/mechanisms +#keybinding add Ctrl-M@dwarfmode/QueryBuilding/Some gui/mechanisms # browse rooms of same owner -keybinding add Alt-R@dwarfmode/QueryBuilding/Some gui/room-list +#keybinding add Alt-R@dwarfmode/QueryBuilding/Some gui/room-list # interface for the liquids plugin - spawn water/magma/obsidian -keybinding add Alt-L@dwarfmode/LookAround gui/liquids +#keybinding add Alt-L@dwarfmode/LookAround gui/liquids # machine power sensitive pressure plate construction -keybinding add Ctrl-Shift-M@dwarfmode/Build/Position/Trap gui/power-meter +#keybinding add Ctrl-Shift-M@dwarfmode/Build/Position/Trap gui/power-meter # siege engine control -keybinding add Alt-A@dwarfmode/QueryBuilding/Some/SiegeEngine gui/siege-engine +#keybinding add Alt-A@dwarfmode/QueryBuilding/Some/SiegeEngine gui/siege-engine # military weapon auto-select -keybinding add Ctrl-W@layer_military/Equip/Customize/View gui/choose-weapons +#keybinding add Ctrl-W@layer_military/Equip/Customize/View gui/choose-weapons # military copy uniform -keybinding add Ctrl-C@layer_military/Uniforms gui/clone-uniform +#keybinding add Ctrl-C@layer_military/Uniforms gui/clone-uniform # minecart Guide path -keybinding add Alt-P@dwarfmode/Hauling/DefineStop/Cond/Guide gui/guide-path +#keybinding add Alt-P@dwarfmode/Hauling/DefineStop/Cond/Guide gui/guide-path # workshop job details -keybinding add Alt-A@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workshop-job +#keybinding add Alt-A@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workshop-job # workflow front-end -keybinding add Alt-W@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workflow -keybinding add Alt-W@overallstatus "gui/workflow status" +#keybinding add Alt-W@dwarfmode/QueryBuilding/Some/Workshop/Job gui/workflow +#keybinding add Alt-W@overallstatus "gui/workflow status" # equivalent to the one above when gui/extended-status is enabled -keybinding add Alt-W@dfhack/lua/status_overlay "gui/workflow status" +#keybinding add Alt-W@dfhack/lua/status_overlay "gui/workflow status" # autobutcher front-end -keybinding add Shift-B@pet/List/Unit gui/autobutcher +#keybinding add Shift-B@pet/List/Unit gui/autobutcher # view pathable tiles from active cursor -keybinding add Alt-Shift-P@dwarfmode/LookAround gui/pathable +#keybinding add Alt-Shift-P@dwarfmode/LookAround gui/pathable # gui/rename script - rename units and buildings -keybinding add Ctrl-Shift-N@dwarfmode|unit|unitlist|joblist|dungeon_monsterstatus|layer_unit_relationship|item|workshop_profile|layer_noblelist|locations|pets|layer_overall_health|textviewer|reportlist|announcelist|layer_military|layer_unit_health|customize_unit|buildinglist gui/rename -keybinding add Ctrl-Shift-T@dwarfmode|unit|unitlist|joblist|dungeon_monsterstatus|layer_unit_relationship|item|workshop_profile|layer_noblelist|locations|pets|layer_overall_health|textviewer|reportlist|announcelist|layer_military|layer_unit_health|customize_unit "gui/rename unit-profession" +#keybinding add Ctrl-Shift-N@dwarfmode|unit|unitlist|joblist|dungeon_monsterstatus|layer_unit_relationship|item|workshop_profile|layer_noblelist|locations|pets|layer_overall_health|textviewer|reportlist|announcelist|layer_military|layer_unit_health|customize_unit|buildinglist gui/rename +#keybinding add Ctrl-Shift-T@dwarfmode|unit|unitlist|joblist|dungeon_monsterstatus|layer_unit_relationship|item|workshop_profile|layer_noblelist|locations|pets|layer_overall_health|textviewer|reportlist|announcelist|layer_military|layer_unit_health|customize_unit "gui/rename unit-profession" ##################### # adv mode bindings # ##################### -keybinding add Ctrl-A@dungeonmode/ConversationSpeak adv-rumors -keybinding add Ctrl-B@dungeonmode adv-bodyswap -keybinding add Ctrl-Shift-B@dungeonmode "adv-bodyswap force" -keybinding add Shift-O@dungeonmode gui/companion-order -keybinding add Ctrl-T@dungeonmode gui/advfort +#keybinding add Ctrl-A@dungeonmode/ConversationSpeak adv-rumors +#keybinding add Ctrl-B@dungeonmode adv-bodyswap +#keybinding add Ctrl-Shift-B@dungeonmode "adv-bodyswap force" +#keybinding add Shift-O@dungeonmode gui/companion-order +#keybinding add Ctrl-T@dungeonmode gui/advfort ######################### @@ -171,4 +171,4 @@ keybinding add Ctrl-T@dungeonmode gui/advfort ######################### # export all information, or just the detailed maps (doesn't handle site maps) -keybinding add Ctrl-A@legends "exportlegends all" +#keybinding add Ctrl-A@legends "exportlegends all" diff --git a/data/init/dfhack.tools.init b/data/init/dfhack.tools.init index 70da533b3..741298109 100644 --- a/data/init/dfhack.tools.init +++ b/data/init/dfhack.tools.init @@ -9,7 +9,7 @@ ############################ # stabilize the cursor of dwarfmode when switching menus -tweak stable-cursor +#tweak stable-cursor # stop stacked liquid/bar/thread/cloth items from lasting forever # if used in reactions that use only a fraction of the dimension. @@ -18,114 +18,116 @@ tweak stable-cursor # make reactions requiring containers usable in advmode - the issue is # that the screen asks for those reagents to be selected directly -tweak advmode-contained +#tweak advmode-contained # support Shift-Enter in Trade and Move Goods to Depot screens for faster # selection; it selects the current item or stack and scrolls down one line -tweak fast-trade +#tweak fast-trade # stop the right list in military->positions from resetting to top all the time -tweak military-stable-assign +#tweak military-stable-assign # in same list, color units already assigned to squads in brown & green -tweak military-color-assigned +#tweak military-color-assigned # make crafted cloth items wear out with time like in old versions (bug 6003) -tweak craft-age-wear +#tweak craft-age-wear # stop adamantine clothing from wearing out (bug 6481) #tweak adamantine-cloth-wear # Add "Select all" and "Deselect all" options to farm plot menus -tweak farm-plot-select +#tweak farm-plot-select # Add Shift-Left/Right controls to import agreement screen -tweak import-priority-category +#tweak import-priority-category # Fixes a crash in the work order contition material list (bug 9905). -tweak condition-material +#tweak condition-material # Adds an option to clear currently-bound hotkeys -tweak hotkey-clear +#tweak hotkey-clear # Allows lowercase letters in embark profile names, and allows exiting the name prompt without saving -tweak embark-profile-name +#tweak embark-profile-name # Reduce performance impact of temperature changes -tweak fast-heat 100 +#tweak fast-heat 100 # Misc. UI tweaks -tweak block-labors # Prevents labors that can't be used from being toggled -tweak burrow-name-cancel -tweak cage-butcher -tweak civ-view-agreement -tweak do-job-now -tweak eggs-fertile -tweak fps-min -tweak hide-priority -tweak kitchen-prefs-all -tweak kitchen-prefs-empty -tweak max-wheelbarrow -tweak partial-items -tweak shift-8-scroll -tweak stone-status-all -tweak title-start-rename -tweak tradereq-pet-gender +#tweak block-labors # Prevents labors that can't be used from being toggled +#tweak burrow-name-cancel +#tweak cage-butcher +#tweak civ-view-agreement +#tweak do-job-now +#tweak eggs-fertile +#tweak fps-min +#tweak hide-priority +#tweak kitchen-prefs-all +#tweak kitchen-prefs-empty +#tweak max-wheelbarrow +#tweak partial-items +#tweak shift-8-scroll +#tweak stone-status-all +#tweak title-start-rename +#tweak tradereq-pet-gender ########################### # Globally acting plugins # ########################### # Display DFHack version on title screen -enable title-version +#enable title-version + +# Allow DFHack tools to overlay functionality and information on the DF screen +enable overlay # Dwarf Manipulator (simple in-game Dwarf Therapist replacement) -enable manipulator +#enable manipulator # Search tool in various screens (by falconne) -enable search +#enable search # Improved build material selection interface (by falconne) -enable automaterial +#enable automaterial # Other interface improvement tools -enable \ - overlay \ - confirm \ - dwarfmonitor \ - mousequery \ - autogems \ - autodump \ - automelt \ - autotrade \ - buildingplan \ - trackstop \ - zone \ - stocks \ - autochop \ - stockpiles +#enable \ +# confirm \ +# dwarfmonitor \ +# mousequery \ +# autogems \ +# autodump \ +# automelt \ +# autotrade \ +# buildingplan \ +# trackstop \ +# zone \ +# stocks \ +# autochop \ +# stockpiles #end a line with a backslash to make it continue to the next line. The \ is deleted for the final command. # Multiline commands are ONLY supported for scripts like dfhack.init. You cannot do multiline command manually on the DFHack console. # You cannot extend a commented line. # You can comment out the extension of a line. # enable mouse controls and sand indicator in embark screen -embark-tools enable sticky sand mouse +#embark-tools enable sticky sand mouse # enable option to enter embark assistant -enable embark-assistant +#enable embark-assistant ########### # Scripts # ########### # write extra information to the gamelog -modtools/extra-gamelog enable +#modtools/extra-gamelog enable # extended status screen (bedrooms page) -enable gui/extended-status +#enable gui/extended-status # add information to item viewscreens -view-item-info enable +#view-item-info enable # a replacement for the "load game" screen -gui/load-screen enable +#gui/load-screen enable diff --git a/dfhack-config/overlay.json b/dfhack-config/overlay.json deleted file mode 100644 index 8b90fc4a4..000000000 --- a/dfhack-config/overlay.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "dwarfmonitor.date": { - "enabled": true - }, - "dwarfmonitor.misery": { - "enabled": true - }, - "dwarfmonitor.weather": { - "enabled": true - }, - "hotkeys.menu": { - "enabled": true - }, - "unsuspend.overlay": { - "enabled": true - } -} diff --git a/docs/Core.rst b/docs/Core.rst index 2296d1ab7..4fb1fdb71 100644 --- a/docs/Core.rst +++ b/docs/Core.rst @@ -21,10 +21,11 @@ DFHack commands can be implemented in any of three ways: same version of DFHack. They are less flexible than scripts, but used for complex or ongoing tasks because they run faster. -:scripts: are Ruby or Lua scripts stored in ``hack/scripts/``. - Because they don't need to be compiled, scripts are - more flexible about versions, and easier to distribute. - Most third-party DFHack addons are scripts. +:scripts: are Ruby or Lua scripts stored in ``hack/scripts/`` or other + directories in the `script-paths`. Because they don't need to + be compiled, scripts are more flexible about versions, and + they are easier to distribute. Most third-party DFHack addons + are scripts. All tools distributed with DFHack are documented `here `. @@ -37,6 +38,8 @@ DFHack commands can be executed in a number of ways: #. Pressing a key combination set up with `keybinding` #. From one of several `init-files`, automatically #. Using `script` to run a batch of commands from a file +#. From an in-game command launcher interface like `gui/launcher`, the + `hotkeys` overlay widget, or `gui/quickcmd`. The DFHack console ------------------ @@ -144,7 +147,7 @@ save-specific init files in the save folders. DFHack looks for init files in three places each time they could be run: #. The :file:`dfhack-config/init` subdirectory in the main DF directory -#. :file:`data/save/{world}/raw`, where ``world`` is the current save, and +#. :file:`data/save/{world}/raw`, where ``{world}`` is the current save, and #. :file:`data/save/{world}/raw/objects` For each of those directories, all matching init files will be executed in @@ -171,7 +174,7 @@ dfhack\*.init On startup, DFHack looks for files of the form ``dfhack*.init`` (where ``*`` is a placeholder for any string, including the empty string). -These files are best used for keybindings and enabling persistent plugins +These files are best used for keybindings and enabling persistent tools which do not require a world to be loaded. @@ -230,9 +233,10 @@ Script paths are folders that DFHack searches to find a script when a command is run. By default, the following folders are searched, in order (relative to the root DF folder): -1. :file:`data/save/{}/raw/scripts` (only if a save is loaded) -2. :file:`raw/scripts` -3. :file:`hack/scripts` +#. :file:`dfhack-config/scripts` +#. :file:`data/save/{}/raw/scripts` (only if a save is loaded) +#. :file:`raw/scripts` +#. :file:`hack/scripts` For example, if ``teleport`` is run, these folders are searched in order for ``teleport.lua`` or ``teleport.rb``, and the first matching file is run. diff --git a/docs/changelog.txt b/docs/changelog.txt index 2c000262b..bfc01b322 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -38,17 +38,24 @@ changelog.txt uses a syntax similar to RST, with a few special sequences: ## Fixes ## Misc Improvements +- Scrollable widgets now react to mouse wheel events when the mouse is over the widget +- the ``dfhack-config/scripts/`` folder is now searched for scripts by default +- `hotkeys`: overlay hotspot widget now shows the DFHack logo in graphics mode and "DFHack" in text mode ## Documentation - `overlay-dev-guide`: added troubleshooting tips and common development workflows - added DFHack architecture diagrams to the dev intro ## API +- ``Gui::getDwarfmodeDims``: now only returns map viewport dimensions; menu dimensions are obsolete +- ``Gui::getDFViewscreen``: returns the topmost underlying DF viewscreen ## Lua - ``gui.View``: ``visible`` and ``active`` can now be functions that return a boolean - ``widgets.Panel``: new attributes to control window dragging and resizing with mouse or keyboard - ``widgets.Window``: Panel subclass with attributes preset for top-level windows +- `overlay`: ``OverlayWidget`` now inherits from ``Panel`` instead of ``Widget`` to get all the frame and mouse integration goodies +- ``dfhack.gui.getDFViewscreen()``: returns the topmost underlying DF viewscreen ## Internals diff --git a/docs/dev/Lua API.rst b/docs/dev/Lua API.rst index 0fa95dd03..8962d795a 100644 --- a/docs/dev/Lua API.rst +++ b/docs/dev/Lua API.rst @@ -965,6 +965,11 @@ Screens the specified type (e.g. ``df.viewscreen_titlest``), or ``nil`` if none match. If ``depth`` is not specified or is less than 1, all viewscreens are checked. +* ``dfhack.gui.getDFViewscreen([skip_dismissed])`` + + Returns the topmost viewscreen not owned by DFHack. If ``skip_dismissed`` is + ``true``, ignores screens already marked to be removed. + General-purpose selections ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1011,7 +1016,7 @@ Fortress mode * ``dfhack.gui.getDwarfmodeViewDims()`` - Returns dimensions of the main fortress mode screen. See ``getPanelLayout()`` + Returns dimensions of the displayed map viewport. See ``getPanelLayout()`` in the ``gui.dwarfmode`` module for a more Lua-friendly version. * ``dfhack.gui.resetDwarfmodeView([pause])`` @@ -1121,7 +1126,8 @@ Other * ``dfhack.gui.getDepthAt(x, y)`` Returns the distance from the z-level of the tile at map coordinates (x, y) to - the closest ground z-level below. Defaults to 0, unless overridden by plugins. + the closest rendered ground z-level below. Defaults to 0, unless overridden by + plugins. Job module ---------- @@ -2161,7 +2167,14 @@ Functions: * ``dfhack.screen.getMousePos()`` - Returns *x,y* of the tile the mouse is over. + Returns *x,y* of the UI interface tile the mouse is over, with the upper left + corner being ``0,0``. To get the map tile coordinate that the mouse is over, + see ``dfhack.gui.getMousePos()``. + +* ``dfhack.screen.getMousePixels()`` + + Returns *x,y* of the screen coordinates the mouse is over in pixels, with the + upper left corner being ``0,0``. * ``dfhack.screen.inGraphicsMode()`` @@ -2355,7 +2368,14 @@ Supported callbacks and fields are: where the above painting functions work correctly. If omitted, the screen is cleared; otherwise it should do that itself. - In order to make a see-through dialog, call ``self._native.parent:render()``. + In order to make a dialog where portions of the parent viewscreen are still + visible in the background, call ``screen:renderParent()``. + + If artifacts are left on the parent even after this function is called, such + as when the window is dragged or is resized, any code can set + ``gui.Screen.request_full_screen_refresh`` to ``true``. Then when + ``screen.renderParent()`` is next called, it will do a full flush of the + graphics and clear the screen of artifacts. * ``function screen:onIdle()`` @@ -2377,13 +2397,13 @@ Supported callbacks and fields are: ``_STRING`` Maps to an integer in range 0-255. Duplicates a separate "STRING_A???" code for convenience. - ``_MOUSE_L, _MOUSE_R`` - If the left or right mouse button is being pressed. + ``_MOUSE_L, _MOUSE_R, _MOUSE_M`` + If the left, right, and/or middle mouse button is being pressed. - ``_MOUSE_L_DOWN, _MOUSE_R_DOWN`` - If the left or right mouse button was just pressed. + ``_MOUSE_L_DOWN, _MOUSE_R_DOWN, _MOUSE_M_DOWN`` + If the left, right, and/or middle mouse button was just pressed. - If this method is omitted, the screen is dismissed on receival of the ``LEAVESCREEN`` key. + If this method is omitted, the screen is dismissed on reception of the ``LEAVESCREEN`` key. * ``function screen:onGetSelectedUnit()`` * ``function screen:onGetSelectedItem()`` @@ -2614,8 +2634,8 @@ and are only documented here for completeness: Registers ``path`` as a `script path `. If ``search_before`` is passed and ``true``, the path will be searched before - the default paths (e.g. ``raw/scripts``, ``hack/scripts``); otherwise, it will - be searched after. + the default paths (e.g. ``dfhack-config/scripts``, ``hack/scripts``); otherwise, + it will be searched after. Returns ``true`` if successful or ``false`` otherwise (e.g. if the path does not exist or has already been registered). @@ -3632,11 +3652,6 @@ considered stable. Misc ---- -* ``USE_GRAPHICS`` - - Contains the value of ``dfhack.screen.inGraphicsMode()``, which cannot be - changed without restarting the game and thus is constant during the session. - * ``CLEAR_PEN`` The black pen used to clear the screen. @@ -4144,6 +4159,8 @@ Base of all the widgets. Inherits from View and has the following attributes: The pen to fill the outer frame with. Defaults to no fill. +.. _panel: + Panel class ----------- @@ -4306,7 +4323,6 @@ Attributes: If it returns false, the character is ignored. :on_change: Change notification callback; used as ``on_change(new_text,old_text)``. :on_submit: Enter key callback; if set the field will handle the key and call ``on_submit(text)``. -:on_submit2: Shift-Enter key callback; if set the field will handle the key and call ``on_submit2(text)``. :key: If specified, the field is disabled until this key is pressed. Must be given as a string. :key_sep: If specified, will be used to customize how the activation key is displayed. See ``token.key_sep`` in the ``Label`` documentation below. @@ -4336,21 +4352,36 @@ You can click where you want the cursor to move or you can use any of the following keyboard hotkeys: - Left/Right arrow: move the cursor one character to the left or right. -- Ctrl-Left/Right arrow: move the cursor one word to the left or right. -- Alt-Left/Right arrow: move the cursor to the beginning/end of the text. +- Ctrl-B/Ctrl-F: move the cursor one word back or forward. +- Ctrl-A/Ctrl-E: move the cursor to the beginning/end of the text. + +The ``EditField`` class also provides the following functions: + +* ``editfield:setCursor([cursor_pos])`` + + Sets the text insert cursor to the specified position. If ``cursor_pos`` is + not specified or is past the end of the current text string, the cursor will + be set to the end of the current input (that is, ``#editfield.text + 1``). + +* ``editfield:setText(text[, cursor_pos])`` + + Sets the input text string and, optionally, the cursor position. If the + cursor position is not specified, it sets it to the end of the string. + +* ``editfield:insert(text)`` + + Inserts the given text at the current cursor position. Scrollbar class --------------- This Widget subclass implements mouse-interactive scrollbars whose bar sizes represent the amount of content currently visible in an associated display -widget (like a `Label class`_ or a `List class`_). By default they are styled -like scrollbars used in the vanilla DF help screens, but they are configurable. +widget (like a `Label class`_ or a `List class`_). They are styled like scrollbars +used in vanilla DF. Scrollbars have the following attributes: -:fg: Specifies the pen for the scroll icons and the active part of the bar. Default is ``COLOR_LIGHTGREEN``. -:bg: Specifies the pen for the background part of the scrollbar. Default is ``COLOR_CYAN``. :on_scroll: A callback called when the scrollbar is scrolled. If the scrollbar is clicked, the callback will be called with one of the following string parameters: "up_large", "down_large", "up_small", or "down_small". If the scrollbar is dragged, the callback will @@ -4377,6 +4408,10 @@ direction. The amount of scrolling done in each case in determined by the associated widget, and after scrolling is complete, the associated widget must call ``scrollbar:update()`` with updated new display info. +If the mouse wheel is scrolled while the mouse is over the Scrollbar widget's +parent view, then the parent is scrolled accordingly. Holding :kbd:`Shift` +while scrolling will result in faster movement. + You can click and drag the scrollbar to scroll to a specific spot, or you can click and hold on the end arrows or in the unfilled portion of the scrollbar to scroll multiple times, just like in a normal browser scrollbar. The speed of @@ -4621,8 +4656,8 @@ It has the following attributes: with an empty list. :on_submit: Enter key or mouse click callback; if specified, the list reacts to the key/click and calls the callback as ``on_submit(index,choice)``. -:on_submit2: Shift-Enter key or shift-mouse click callback; if specified, the list - reacts to the key/click and calls it as ``on_submit2(index,choice)``. +:on_submit2: Shift-click callback; if specified, the list reacts to the click and + calls the callback as ``on_submit2(index,choice)``. :row_height: Height of every row in text lines. :icon_width: If not *nil*, the specified number of character columns are reserved to the left of the list item for the icons. @@ -5455,11 +5490,11 @@ Scripts :local: Any files with the ``.lua`` extension placed into the :file:`hack/scripts` folder -are automatically made available as DFHack commands. The command corresponding to -a script is simply the script's filename, relative to the scripts folder, with -the extension omitted. For example: +(or any other folder in your `script-paths`) are automatically made available as +DFHack commands. The command corresponding to a script is simply the script's +filename, relative to the scripts folder, with the extension omitted. For example: -* :file:`hack/scripts/add-thought.lua` is invoked as ``add-thought`` +* :file:`dfhack-config/scripts/startup.lua` is invoked as ``startup`` * :file:`hack/scripts/gui/teleport.lua` is invoked as ``gui/teleport`` .. note:: @@ -5476,12 +5511,6 @@ the extension omitted. For example: a mod developer would want to run a script from the console, it should not be placed in this folder) -Scripts can also be placed in other folders - by default, these include -:file:`raw/scripts` and :file:`data/save/{region}/raw/scripts`, but additional -folders can be added (for example, a copy of the -:source-scripts:`scripts repository <>` for local development). See -`script-paths` for more information on how to configure this behavior. - Scripts are read from disk when run for the first time, or if they have changed since the last time they were run. @@ -5509,7 +5538,7 @@ General script API * ``dfhack.run_script(name[,args...])`` - Run a Lua script in :file:`hack/scripts/`, as if it were started from the + Run a Lua script in your `script-paths`, as if it were started from the DFHack command-line. The ``name`` argument should be the name of the script without its extension, as it would be used on the command line. @@ -5551,8 +5580,8 @@ Importing scripts Loads a Lua script and returns its environment (i.e. a table of all global functions and variables). This is similar to the built-in ``require()``, but - searches all script paths for the first matching ``name.lua`` file instead - of searching the Lua library paths (like ``hack/lua``). + searches all `script-paths` for the first matching ``name.lua`` file instead + of searching the Lua library paths (like ``hack/lua/``). Most scripts can be made to support ``reqscript()`` without significant changes (in contrast, ``require()`` requires the use of ``mkmodule()`` and diff --git a/docs/dev/overlay-dev-guide.rst b/docs/dev/overlay-dev-guide.rst index e6147f8c3..bce623180 100644 --- a/docs/dev/overlay-dev-guide.rst +++ b/docs/dev/overlay-dev-guide.rst @@ -38,7 +38,7 @@ Overlay widget API ------------------ Overlay widgets are Lua classes that inherit from ``overlay.OverlayWidget`` -(which itself inherits from `widgets.Widget `). The regular +(which itself inherits from `widgets.Panel `). The regular ``onInput(keys)``, ``onRenderFrame(dc, frame_rect)``, and ``onRenderBody(dc)`` functions work as normal, and they are called when the viewscreen that the widget is associated with does its usual input and render processing. The widget @@ -125,6 +125,10 @@ The ``overlay.OverlayWidget`` superclass defines the following class attributes: not annoy the player. Set to 0 to be called at the maximum rate. Be aware that running more often than you really need to will impact game FPS, especially if your widget can run while the game is unpaused. +- ``always_enabled`` (default: ``false``) + Set this to ``true`` if you don't want to let the user disable the widget. + This is useful for widgets that are controlled purely through their + triggers. See `gui/pathable` for an example. Registering a widget with the overlay framework *********************************************** diff --git a/docs/guides/modding-guide.rst b/docs/guides/modding-guide.rst index e602e632d..9fe62bf6a 100644 --- a/docs/guides/modding-guide.rst +++ b/docs/guides/modding-guide.rst @@ -60,9 +60,10 @@ For scripts with the same name, the `order of precedence ` will be: 1. ``own-scripts/`` -2. ``data/save/*/raw/scripts/`` -3. ``raw/scripts/`` -4. ``hack/scripts/`` +2. ``dfhack-config/scripts/`` +3. ``data/save/*/raw/scripts/`` +4. ``raw/scripts/`` +5. ``hack/scripts/`` The structure of the game ------------------------- diff --git a/docs/plugins/autobutcher.rst b/docs/plugins/autobutcher.rst index f288f9073..1a4aa4f91 100644 --- a/docs/plugins/autobutcher.rst +++ b/docs/plugins/autobutcher.rst @@ -12,7 +12,7 @@ watch list. Units will be ignored if they are: * Untamed * Nicknamed (for custom protection; you can use the `rename` ``unit`` tool individually, or `zone` ``nick`` for groups) -* Caged, if and only if the cage is defined as a room (to protect zoos) +* Caged, if and only if the cage is in a zone (to protect zoos) * Trained for war or hunting Creatures who will not reproduce (because they're not interested in the diff --git a/docs/plugins/pathable.rst b/docs/plugins/pathable.rst index f4b89683b..c27172843 100644 --- a/docs/plugins/pathable.rst +++ b/docs/plugins/pathable.rst @@ -7,4 +7,4 @@ pathable :no-command: This plugin provides a Lua API, but no direct commands. See `pathable-api` for -details. +details and `gui/pathable` for the user interface. diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index aee5184c8..87f869493 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -96,6 +96,7 @@ endif() set(MAIN_SOURCES_WINDOWS ${CONSOLE_SOURCES} Hooks-windows.cpp + Hooks.cpp PlugLoad-windows.cpp Process-windows.cpp ) @@ -123,6 +124,7 @@ set(MODULE_HEADERS include/modules/Buildings.h include/modules/Burrows.h include/modules/Constructions.h + include/modules/DFSDL.h include/modules/Designations.h include/modules/EventManager.h include/modules/Filesystem.h @@ -140,6 +142,7 @@ set(MODULE_HEADERS include/modules/Random.h include/modules/Renderer.h include/modules/Screen.h + include/modules/Textures.h include/modules/Translation.h include/modules/Units.h include/modules/World.h @@ -149,6 +152,7 @@ set(MODULE_SOURCES modules/Buildings.cpp modules/Burrows.cpp modules/Constructions.cpp + modules/DFSDL.cpp modules/Designations.cpp modules/EventManager.cpp modules/Filesystem.cpp @@ -165,6 +169,7 @@ set(MODULE_SOURCES modules/Random.cpp modules/Renderer.cpp modules/Screen.cpp + modules/Textures.cpp modules/Translation.cpp modules/Units.cpp modules/World.cpp @@ -374,6 +379,8 @@ if(WIN32) else() set_target_properties(dfhack PROPERTIES COMPILE_FLAGS "-include Export.h" ) set_target_properties(dfhack-client PROPERTIES COMPILE_FLAGS "-include Export.h" ) + add_library(dfhooks SHARED Hooks.cpp) + target_link_libraries(dfhooks dfhack) endif() # effectively disables debug builds... @@ -422,6 +429,9 @@ if(UNIX) install(PROGRAMS ${dfhack_SOURCE_DIR}/package/linux/dfhack-run DESTINATION .) endif() + install(TARGETS dfhooks + LIBRARY DESTINATION . + RUNTIME DESTINATION .) else() # On windows, copy the renamed SDL so DF can still run. install(PROGRAMS ${dfhack_SOURCE_DIR}/package/windows/win${DFHACK_BUILD_ARCH}/SDLreal.dll diff --git a/library/Core.cpp b/library/Core.cpp index eed2de30a..d54218b5c 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -49,9 +49,11 @@ using namespace std; #include "VersionInfo.h" #include "PluginManager.h" #include "ModuleFactory.h" +#include "modules/DFSDL.h" #include "modules/EventManager.h" #include "modules/Filesystem.h" #include "modules/Gui.h" +#include "modules/Textures.h" #include "modules/World.h" #include "modules/Persistence.h" #include "RemoteServer.h" @@ -63,8 +65,8 @@ using namespace std; using namespace DFHack; -#include "df/ui.h" -#include "df/ui_sidebar_menus.h" +#include "df/plotinfost.h" +#include "df/gamest.h" #include "df/world.h" #include "df/world_data.h" #include "df/interfacest.h" @@ -104,6 +106,9 @@ namespace DFHack { DBG_DECLARE(core,keybinding,DebugCategory::LINFO); DBG_DECLARE(core,script,DebugCategory::LINFO); +static const std::string CONFIG_PATH = "dfhack-config/"; +static const std::string CONFIG_DEFAULTS_PATH = "hack/data/dfhack-config-defaults/"; + class MainThread { public: //! MainThread::suspend keeps the main DF thread suspended from Core::Init to @@ -484,9 +489,10 @@ void Core::getScriptPaths(std::vector *dest) { lock_guard lock(script_path_mutex); dest->clear(); - string df_path = this->p->getPath(); + string df_path = this->p->getPath() + "/"; for (auto it = script_paths[0].begin(); it != script_paths[0].end(); ++it) dest->push_back(*it); + dest->push_back(df_path + CONFIG_PATH + "scripts"); if (df::global::world && isWorldLoaded()) { string save = World::ReadWorldFolder(); if (save.size()) @@ -515,7 +521,7 @@ string Core::findScript(string name) bool loadScriptPaths(color_ostream &out, bool silent = false) { using namespace std; - string filename("dfhack-config/script-paths.txt"); + string filename(CONFIG_PATH + "script-paths.txt"); ifstream file(filename); if (!file) { @@ -1014,10 +1020,12 @@ command_result Core::runCommand(color_ostream &con, const std::string &first_, v else if (first == "fpause") { World::SetPauseState(true); +/* TODO: understand how this changes for v50 if (auto scr = Gui::getViewscreenByType()) { scr->worldgen_paused = true; } +*/ con.print("The game was forced to pause!\n"); } else if (first == "cls" || first == "clear") @@ -1299,18 +1307,18 @@ bool Core::loadScriptFile(color_ostream &out, string fname, bool silent) static void run_dfhack_init(color_ostream &out, Core *core) { CoreSuspender lock; - if (!df::global::world || !df::global::ui || !df::global::gview) + if (!df::global::world || !df::global::plotinfo || !df::global::gview) { out.printerr("Key globals are missing, skipping loading dfhack.init.\n"); return; } // load baseline defaults - core->loadScriptFile(out, "dfhack-config/init/default.dfhack.init", false); + core->loadScriptFile(out, CONFIG_PATH + "init/default.dfhack.init", false); // load user overrides std::vector prefixes(1, "dfhack"); - loadScriptFiles(core, out, prefixes, "dfhack-config/init"); + loadScriptFiles(core, out, prefixes, CONFIG_PATH + "init"); } // Load dfhack.init in a dedicated thread (non-interactive console mode) @@ -1326,14 +1334,14 @@ void fInitthread(void * iodata) // A thread function... for the interactive console. void fIOthread(void * iodata) { - static const char * HISTORY_FILE = "dfhack-config/dfhack.history"; + static const std::string HISTORY_FILE = CONFIG_PATH + "dfhack.history"; IODATA * iod = ((IODATA*) iodata); Core * core = iod->core; PluginManager * plug_mgr = ((IODATA*) iodata)->plug_mgr; CommandHistory main_history; - main_history.load(HISTORY_FILE); + main_history.load(HISTORY_FILE.c_str()); Console & con = core->getConsole(); if (plug_mgr == 0) @@ -1374,7 +1382,7 @@ void fIOthread(void * iodata) { // a proper, non-empty command was entered main_history.add(command); - main_history.save(HISTORY_FILE); + main_history.save(HISTORY_FILE.c_str()); } auto rv = core->runCommand(con, command); @@ -1479,11 +1487,14 @@ bool Core::Init() // make it obvious what's going on if someone checks the *.txt files. #ifndef LINUX_BUILD // Don't do this on Linux because it will break PRINT_MODE:TEXT + // this is handled as appropriate in Console-posix.cpp fprintf(stdout, "dfhack: redirecting stdout to stdout.log (again)\n"); - fprintf(stderr, "dfhack: redirecting stderr to stderr.log (again)\n"); - freopen("stdout.log", "w", stdout); - freopen("stderr.log", "w", stderr); + if (!freopen("stdout.log", "w", stdout)) + cerr << "Could not redirect stdout to stdout.log" << endl; #endif + fprintf(stderr, "dfhack: redirecting stderr to stderr.log\n"); + if (!freopen("stderr.log", "w", stderr)) + cerr << "Could not redirect stderr to stderr.log" << endl; Filesystem::init(); @@ -1606,46 +1617,44 @@ bool Core::Init() // initialize data defs virtual_identity::Init(this); + // create config directory if it doesn't already exist + if (!Filesystem::mkdir_recursive(CONFIG_PATH)) + con.printerr("Failed to create config directory: '%s'\n", CONFIG_PATH.c_str()); + // copy over default config files if necessary std::map config_files; std::map default_config_files; - if (Filesystem::listdir_recursive("dfhack-config", config_files, 10, false) != 0) - con.printerr("Failed to list directory: dfhack-config"); - else if (Filesystem::listdir_recursive("dfhack-config/default", default_config_files, 10, false) != 0) - con.printerr("Failed to list directory: dfhack-config/default"); + if (Filesystem::listdir_recursive(CONFIG_PATH, config_files, 10, false) != 0) + con.printerr("Failed to list directory: '%s'\n", CONFIG_PATH.c_str()); + else if (Filesystem::listdir_recursive(CONFIG_DEFAULTS_PATH, default_config_files, 10, false) != 0) + con.printerr("Failed to list directory: '%s'\n", CONFIG_DEFAULTS_PATH.c_str()); else { // ensure all config file directories exist before we start copying files - for (auto it = default_config_files.begin(); it != default_config_files.end(); ++it) - { + for (auto &entry : default_config_files) { // skip over files - if (!it->second) + if (!entry.second) continue; - std::string dirname = "dfhack-config/" + it->first; + std::string dirname = CONFIG_PATH + entry.first; if (!Filesystem::mkdir_recursive(dirname)) - { con.printerr("Failed to create config directory: '%s'\n", dirname.c_str()); - } } // copy files from the default tree that don't already exist in the config tree - for (auto it = default_config_files.begin(); it != default_config_files.end(); ++it) - { + for (auto &entry : default_config_files) { // skip over directories - if (it->second) + if (entry.second) continue; - std::string filename = it->first; - if (config_files.find(filename) == config_files.end()) - { - std::string src_file = std::string("dfhack-config/default/") + filename; + std::string filename = entry.first; + if (!config_files.count(filename)) { + std::string src_file = CONFIG_DEFAULTS_PATH + filename; if (!Filesystem::isfile(src_file)) continue; - std::string dest_file = std::string("dfhack-config/") + filename; + std::string dest_file = CONFIG_PATH + filename; std::ifstream src(src_file, std::ios::binary); std::ofstream dest(dest_file, std::ios::binary); - if (!src.good() || !dest.good()) - { - con.printerr("Copy failed: %s\n", filename.c_str()); + if (!src.good() || !dest.good()) { + con.printerr("Copy failed: '%s'\n", filename.c_str()); continue; } dest << src.rdbuf(); @@ -1664,8 +1673,15 @@ bool Core::Init() return false; } + cerr << "Binding to SDL.\n"; + if (!DFSDL::init(con)) { + fatal("cannot bind SDL libraries"); + return false; + } + cerr << "Initializing textures.\n"; + Textures::init(con); // create mutex for syncing with interactive tasks - cerr << "Initializing Plugins.\n"; + cerr << "Initializing plugins.\n"; // create plugin manager plug_mgr = new PluginManager(this); plug_mgr->init(); @@ -1696,10 +1712,10 @@ bool Core::Init() if (!listen.get()) cerr << "TCP listen failed.\n"; - if (df::global::ui_sidebar_menus) + if (df::global::game) { vector args; - const string & raw = df::global::ui_sidebar_menus->command_line.original; + const string & raw = df::global::game->command_line.original; size_t offset = 0; while (offset < raw.size()) { @@ -1758,6 +1774,9 @@ bool Core::Init() } cerr << "DFHack is running.\n"; + + onStateChange(con, SC_CORE_INITIALIZED); + return true; } /// sets the current hotkey command @@ -1833,17 +1852,10 @@ bool Core::isSuspended(void) return ownerThread.load() == std::this_thread::get_id(); } -void Core::doUpdate(color_ostream &out, bool first_update) +void Core::doUpdate(color_ostream &out) { Lua::Core::Reset(out, "DF code execution"); - if (first_update) { - auto L = Lua::Core::State; - Lua::StackUnwinder top(L); - Lua::CallLuaModuleFunction(out, L, "script-manager", "reload"); - onStateChange(out, SC_CORE_INITIALIZED); - } - // find the current viewscreen df::viewscreen *screen = NULL; if (df::global::gview) @@ -1867,7 +1879,7 @@ void Core::doUpdate(color_ostream &out, bool first_update) strict_virtual_cast(screen); // save data (do this before updating last_world_data_ptr and triggering unload events) - if ((df::global::ui->main.autosave_request && !d->last_autosave_request) || + if ((df::global::plotinfo->main.autosave_request && !d->last_autosave_request) || (is_load_save && !d->was_load_save && strict_virtual_cast(screen))) { doSaveData(out); @@ -1929,7 +1941,7 @@ void Core::doUpdate(color_ostream &out, bool first_update) // Execute per-frame handlers onUpdate(out); - d->last_autosave_request = df::global::ui->main.autosave_request; + d->last_autosave_request = df::global::plotinfo->main.autosave_request; d->was_load_save = is_load_save; out << std::flush; @@ -1946,19 +1958,15 @@ int Core::Update() // Pretend this thread has suspended the core in the usual way, // and run various processing hooks. { - // Initialize the core - bool first_update = false; - if(!started) { - first_update = true; + // Initialize the core Init(); if(errorstate) return -1; - Lua::Core::Reset(con, "core init"); } - doUpdate(out, first_update); + doUpdate(out); } // Let all commands run that require CoreSuspender @@ -2083,9 +2091,9 @@ void Core::handleLoadAndUnloadScripts(color_ostream& out, state_change_event eve const std::vector& set = i->second; // load baseline defaults - this->loadScriptFile(out, "dfhack-config/init/default." + set[0] + ".init", false); + this->loadScriptFile(out, CONFIG_PATH + "init/default." + set[0] + ".init", false); - loadScriptFiles(this, out, set, "dfhack-config/init"); + loadScriptFiles(this, out, set, CONFIG_PATH + "init"); loadScriptFiles(this, out, set, rawFolder); loadScriptFiles(this, out, set, rawFolder + "objects/"); } @@ -2135,6 +2143,13 @@ void Core::onStateChange(color_ostream &out, state_change_event event) switch (event) { + case SC_CORE_INITIALIZED: + { + auto L = Lua::Core::State; + Lua::StackUnwinder top(L); + Lua::CallLuaModuleFunction(con, L, "script-manager", "reload"); + } + break; case SC_WORLD_LOADED: case SC_WORLD_UNLOADED: case SC_MAP_LOADED: @@ -2168,6 +2183,10 @@ void Core::onStateChange(color_ostream &out, state_change_event event) evtlog << std::endl; } } + break; + case SC_VIEWSCREEN_CHANGED: + Textures::init(out); + break; default: break; } @@ -2245,6 +2264,8 @@ int Core::Shutdown ( void ) } // invalidate all modules allModules.clear(); + Textures::cleanup(); + DFSDL::cleanup(); memset(&(s_mods), 0, sizeof(s_mods)); d.reset(); return -1; @@ -2264,16 +2285,17 @@ bool Core::ncurses_wgetch(int in, int & out) } if(in >= KEY_F(1) && in <= KEY_F(8)) { +/* TODO: understand how this changes for v50 int idx = in - KEY_F(1); // FIXME: copypasta, push into a method! - if(df::global::ui && df::global::gview) + if(df::global::plotinfo && df::global::gview) { df::viewscreen * ws = Gui::getCurViewscreen(); if (strict_virtual_cast(ws) && - df::global::ui->main.mode != ui_sidebar_mode::Hotkeys && - df::global::ui->main.hotkeys[idx].cmd == df::ui_hotkey::T_cmd::None) + df::global::plotinfo->main.mode != ui_sidebar_mode::Hotkeys && + df::global::plotinfo->main.hotkeys[idx].cmd == df::ui_hotkey::T_cmd::None) { - setHotkeyCmd(df::global::ui->main.hotkeys[idx].name); + setHotkeyCmd(df::global::plotinfo->main.hotkeys[idx].name); return false; } else @@ -2282,11 +2304,20 @@ bool Core::ncurses_wgetch(int in, int & out) return true; } } +*/ } out = in; return true; } +bool Core::DFH_ncurses_key(int key) +{ + if (getenv("DFHACK_HEADLESS")) + return true; + int dummy; + return !ncurses_wgetch(key, dummy); +} + int UnicodeAwareSym(const SDL::KeyboardEvent& ke) { // Assume keyboard layouts don't change the order of numbers: @@ -2391,7 +2422,7 @@ int Core::DFH_SDL_Event(SDL::Event* ev) bool Core::SelectHotkey(int sym, int modifiers) { // Find the topmost viewscreen - if (!df::global::gview || !df::global::ui) + if (!df::global::gview || !df::global::plotinfo) return false; df::viewscreen *screen = &df::global::gview->view; @@ -2441,15 +2472,17 @@ bool Core::SelectHotkey(int sym, int modifiers) int idx = sym - SDL::K_F1; if(idx >= 0 && idx < 8) { +/* TODO: understand how this changes for v50 if (modifiers & 1) idx += 8; if (strict_virtual_cast(screen) && - df::global::ui->main.mode != ui_sidebar_mode::Hotkeys && - df::global::ui->main.hotkeys[idx].cmd == df::ui_hotkey::T_cmd::None) + df::global::plotinfo->main.mode != ui_sidebar_mode::Hotkeys && + df::global::plotinfo->main.hotkeys[idx].cmd == df::ui_hotkey::T_cmd::None) { - cmd = df::global::ui->main.hotkeys[idx].name; + cmd = df::global::plotinfo->main.hotkeys[idx].name; } +*/ } } } diff --git a/library/DataStatics.cpp b/library/DataStatics.cpp index 275cae584..fe60e5454 100644 --- a/library/DataStatics.cpp +++ b/library/DataStatics.cpp @@ -6,7 +6,7 @@ #include "df/world.h" #include "df/world_data.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "DataIdentity.h" diff --git a/library/Hooks-darwin.cpp b/library/Hooks-darwin.cpp index 723d97970..418cf5472 100644 --- a/library/Hooks-darwin.cpp +++ b/library/Hooks-darwin.cpp @@ -279,9 +279,8 @@ DFhackCExport int DFH_SDL_Init(uint32_t flags) { // reroute stderr fprintf(stderr,"dfhack: attempting to hook in\n"); - freopen("stderr.log", "w", stderr); // we don't reroute stdout until we figure out if this should be done at all - // See: Console-linux.cpp + // See: Console-posix.cpp // find real functions fprintf(stderr,"dfhack: saving real SDL functions\n"); diff --git a/library/Hooks-linux.cpp b/library/Hooks-linux.cpp index cb8ba20db..7a0cdf947 100644 --- a/library/Hooks-linux.cpp +++ b/library/Hooks-linux.cpp @@ -117,12 +117,6 @@ DFhackCExport int wgetch(WINDOW *win) static int (*_SDL_Init)(uint32_t flags) = 0; DFhackCExport int SDL_Init(uint32_t flags) { - // reroute stderr - if (!freopen("stderr.log", "w", stderr)) - fprintf(stderr, "dfhack: failed to reroute stderr\n"); - // we don't reroute stdout until we figure out if this should be done at all - // See: Console-linux.cpp - // find real functions _SDL_Init = (int (*)( uint32_t )) dlsym(RTLD_NEXT, "SDL_Init"); _SDL_Quit = (void (*)( void )) dlsym(RTLD_NEXT, "SDL_Quit"); diff --git a/library/Hooks.cpp b/library/Hooks.cpp new file mode 100644 index 000000000..36af2617c --- /dev/null +++ b/library/Hooks.cpp @@ -0,0 +1,33 @@ +#include "Core.h" +#include "Export.h" + +// called before main event loop starts +DFhackCExport void dfhooks_init() { + DFHack::Core::getInstance().Init(); +} + +// called after main event loops exits +DFhackCExport void dfhooks_shutdown() { + DFHack::Core::getInstance().Shutdown(); +} + +// called in the main event loop +DFhackCExport void dfhooks_update() { + DFHack::Core::getInstance().Update(); +} + +// called just before adding the macro recording/playback overlay +DFhackCExport void dfhooks_prerender() { + // TODO: render overlay widgets that are not attached to a viewscreen +} + +// called for each SDL event, if true is returned, then the event has been +// consumed and further processing shouldn't happen +DFhackCExport bool dfhooks_sdl_event(SDL::Event* event) { + return DFHack::Core::getInstance().DFH_SDL_Event(event); +} +// called for each utf-8 char read from the ncurses input +// key is positive for ncurses keys and negative for everything else +DFhackCExport bool dfhooks_ncurses_key(int key) { + return DFHack::Core::getInstance().DFH_ncurses_key(key); +} diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index ef0b5c3dd..fdd19783a 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -57,6 +57,7 @@ distribution. #include "modules/Materials.h" #include "modules/Random.h" #include "modules/Screen.h" +#include "modules/Textures.h" #include "modules/Translation.h" #include "modules/Units.h" #include "modules/World.h" @@ -1436,17 +1437,8 @@ static int gui_getDwarfmodeViewDims(lua_State *state) lua_newtable(state); Lua::TableInsert(state, "map_x1", dims.map_x1); Lua::TableInsert(state, "map_x2", dims.map_x2); - Lua::TableInsert(state, "menu_x1", dims.menu_x1); - Lua::TableInsert(state, "menu_x2", dims.menu_x2); - Lua::TableInsert(state, "area_x1", dims.area_x1); - Lua::TableInsert(state, "area_x2", dims.area_x2); - Lua::TableInsert(state, "y1", dims.y1); - Lua::TableInsert(state, "y2", dims.y2); Lua::TableInsert(state, "map_y1", dims.map_y1); Lua::TableInsert(state, "map_y2", dims.map_y2); - Lua::TableInsert(state, "menu_on", dims.menu_on); - Lua::TableInsert(state, "area_on", dims.area_on); - Lua::TableInsert(state, "menu_forced", dims.menu_forced); return 1; } @@ -1462,6 +1454,7 @@ static int gui_getMousePos(lua_State *L) static const LuaWrapper::FunctionReg dfhack_gui_module[] = { WRAPM(Gui, getCurViewscreen), + WRAPM(Gui, getDFViewscreen), WRAPM(Gui, getFocusString), WRAPM(Gui, getCurFocus), WRAPM(Gui, getSelectedWorkshopJob), @@ -1679,6 +1672,13 @@ static const luaL_Reg dfhack_job_funcs[] = { { NULL, NULL } }; +/***** Textures module *****/ + +static const LuaWrapper::FunctionReg dfhack_textures_module[] = { + WRAPM(Textures, getDfhackLogoTexposStart), + { NULL, NULL } +}; + /***** Units module *****/ static const LuaWrapper::FunctionReg dfhack_units_module[] = { @@ -2373,6 +2373,11 @@ static int screen_getMousePos(lua_State *L) return Lua::PushPosXY(L, Screen::getMousePos()); } +static int screen_getMousePixels(lua_State *L) +{ + return Lua::PushPosXY(L, Screen::getMousePixels()); +} + static int screen_getWindowSize(lua_State *L) { return Lua::PushPosXY(L, Screen::getWindowSize()); @@ -2452,6 +2457,17 @@ static int screen_findGraphicsTile(lua_State *L) } } +static int screen_raise(lua_State *L) { + df::viewscreen *screen = dfhack_lua_viewscreen::get_pointer(L, 1, false); + + // remove screen from the stack so it doesn't get returned as an output + lua_remove(L, 1); + + Screen::raise(screen); + + return 0; +} + static int screen_hideGuard(lua_State *L) { df::viewscreen *screen = dfhack_lua_viewscreen::get_pointer(L, 1, false); luaL_checktype(L, 2, LUA_TFUNCTION); @@ -2563,12 +2579,14 @@ static int screen_zoom(lua_State *L) static const luaL_Reg dfhack_screen_funcs[] = { { "getMousePos", screen_getMousePos }, + { "getMousePixels", screen_getMousePixels }, { "getWindowSize", screen_getWindowSize }, { "paintTile", screen_paintTile }, { "readTile", screen_readTile }, { "paintString", screen_paintString }, { "fillRect", screen_fillRect }, { "findGraphicsTile", screen_findGraphicsTile }, + CWRAP(raise, screen_raise), CWRAP(hideGuard, screen_hideGuard), CWRAP(show, screen_show), CWRAP(dismiss, screen_dismiss), @@ -3360,6 +3378,7 @@ void OpenDFHackApi(lua_State *state) luaL_setfuncs(state, dfhack_funcs, 0); OpenModule(state, "gui", dfhack_gui_module, dfhack_gui_funcs); OpenModule(state, "job", dfhack_job_module, dfhack_job_funcs); + OpenModule(state, "textures", dfhack_textures_module); OpenModule(state, "units", dfhack_units_module, dfhack_units_funcs); OpenModule(state, "items", dfhack_items_module, dfhack_items_funcs); OpenModule(state, "maps", dfhack_maps_module, dfhack_maps_funcs); diff --git a/library/LuaTools.cpp b/library/LuaTools.cpp index 5b080ce43..c76c65651 100644 --- a/library/LuaTools.cpp +++ b/library/LuaTools.cpp @@ -131,9 +131,16 @@ void DFHack::Lua::GetVector(lua_State *state, std::vector &pvec) } } +static bool trigger_inhibit_l_down = false; +static bool trigger_inhibit_r_down = false; +static bool trigger_inhibit_m_down = false; +static bool inhibit_l_down = false; +static bool inhibit_r_down = false; +static bool inhibit_m_down = false; + void DFHack::Lua::PushInterfaceKeys(lua_State *L, const std::set &keys) { - lua_createtable(L, 0, keys.size() + 5); + lua_createtable(L, 0, keys.size() + 7); for (auto &key : keys) { @@ -154,23 +161,32 @@ void DFHack::Lua::PushInterfaceKeys(lua_State *L, } if (df::global::enabler) { - if (df::global::enabler->mouse_lbut_down) { + if (!inhibit_l_down && df::global::enabler->mouse_lbut_down) { lua_pushboolean(L, true); lua_setfield(L, -2, "_MOUSE_L_DOWN"); + trigger_inhibit_l_down = true; } - if (df::global::enabler->mouse_rbut_down) { + if (!inhibit_r_down && df::global::enabler->mouse_rbut_down) { lua_pushboolean(L, true); lua_setfield(L, -2, "_MOUSE_R_DOWN"); + trigger_inhibit_r_down = true; + } + if (!inhibit_m_down && df::global::enabler->mouse_mbut_down) { + lua_pushboolean(L, true); + lua_setfield(L, -2, "_MOUSE_M_DOWN"); + trigger_inhibit_m_down = true; } if (df::global::enabler->mouse_lbut) { lua_pushboolean(L, true); lua_setfield(L, -2, "_MOUSE_L"); - df::global::enabler->mouse_lbut_down = 0; } if (df::global::enabler->mouse_rbut) { lua_pushboolean(L, true); lua_setfield(L, -2, "_MOUSE_R"); - df::global::enabler->mouse_rbut_down = 0; + } + if (df::global::enabler->mouse_mbut) { + lua_pushboolean(L, true); + lua_setfield(L, -2, "_MOUSE_M"); } } } @@ -2134,4 +2150,24 @@ void DFHack::Lua::Core::Reset(color_ostream &out, const char *where) out.printerr("Common lua context stack top left at %d after %s.\n", top, where); lua_settop(State, 0); } + + if (trigger_inhibit_l_down) { + trigger_inhibit_l_down = false; + inhibit_l_down = true; + } + if (trigger_inhibit_r_down) { + trigger_inhibit_r_down = false; + inhibit_r_down = true; + } + if (trigger_inhibit_m_down) { + trigger_inhibit_m_down = false; + inhibit_m_down = true; + } + + if (!df::global::enabler->mouse_lbut) + inhibit_l_down = false; + if (!df::global::enabler->mouse_rbut) + inhibit_r_down = false; + if (!df::global::enabler->mouse_mbut) + inhibit_m_down = false; } diff --git a/library/PlugLoad-windows.cpp b/library/PlugLoad-windows.cpp index 848d25f50..d6ce8cdbf 100644 --- a/library/PlugLoad-windows.cpp +++ b/library/PlugLoad-windows.cpp @@ -35,7 +35,6 @@ distribution. #include #include "tinythread.h" -#include "../plugins/uicommon.h" /* * Plugin loading functions diff --git a/library/RemoteTools.cpp b/library/RemoteTools.cpp index 1d45a19c0..c8fc810c8 100644 --- a/library/RemoteTools.cpp +++ b/library/RemoteTools.cpp @@ -59,8 +59,8 @@ POSSIBILITY OF SUCH DAMAGE. #include "LuaTools.h" #include "DataDefs.h" -#include "df/ui.h" -#include "df/ui_advmode.h" +#include "df/plotinfost.h" +#include "df/adventurest.h" #include "df/world.h" #include "df/world_data.h" #include "df/unit.h" @@ -375,11 +375,11 @@ static command_result GetDFVersion(color_ostream &stream, static command_result GetWorldInfo(color_ostream &stream, const EmptyMessage *, GetWorldInfoOut *out) { - using df::global::ui; - using df::global::ui_advmode; + using df::global::plotinfo; + using df::global::adventure; using df::global::world; - if (!ui || !world || !Core::getInstance().isWorldLoaded()) + if (!plotinfo || !world || !Core::getInstance().isWorldLoaded()) return CR_NOT_FOUND; df::game_type gt = game_type::DWARF_MAIN; @@ -397,10 +397,10 @@ static command_result GetWorldInfo(color_ostream &stream, case game_type::DWARF_RECLAIM: case game_type::DWARF_UNRETIRE: out->set_mode(GetWorldInfoOut::MODE_DWARF); - out->set_civ_id(ui->civ_id); - out->set_site_id(ui->site_id); - out->set_group_id(ui->group_id); - out->set_race_id(ui->race_id); + out->set_civ_id(plotinfo->civ_id); + out->set_site_id(plotinfo->site_id); + out->set_group_id(plotinfo->group_id); + out->set_race_id(plotinfo->race_id); break; case game_type::ADVENTURE_MAIN: @@ -410,10 +410,10 @@ static command_result GetWorldInfo(color_ostream &stream, if (auto unit = vector_get(world->units.active, 0)) out->set_player_unit_id(unit->id); - if (!ui_advmode) + if (!adventure) break; - if (auto nemesis = vector_get(world->nemesis.all, ui_advmode->player_id)) + if (auto nemesis = vector_get(world->nemesis.all, adventure->player_id)) { if (nemesis->figure) out->set_player_histfig_id(nemesis->figure->id); @@ -613,7 +613,7 @@ static command_result ListUnits(color_ostream &stream, static command_result ListSquads(color_ostream &stream, const ListSquadsIn *in, ListSquadsOut *out) { - auto entity = df::historical_entity::find(df::global::ui->group_id); + auto entity = df::historical_entity::find(df::global::plotinfo->group_id); if (!entity) return CR_NOT_FOUND; diff --git a/library/include/Core.h b/library/include/Core.h index 531d1b581..6c99e62be 100644 --- a/library/include/Core.h +++ b/library/include/Core.h @@ -121,6 +121,12 @@ namespace DFHack friend int ::SDL_Init(uint32_t flags); friend int ::wgetch(WINDOW * w); #endif + friend void ::dfhooks_init(); + friend void ::dfhooks_shutdown(); + friend void ::dfhooks_update(); + friend void ::dfhooks_prerender(); + friend bool ::dfhooks_sdl_event(SDL::Event* event); + friend bool ::dfhooks_ncurses_key(int key); public: /// Get the single Core instance or make one. static Core& getInstance() @@ -202,8 +208,9 @@ namespace DFHack int Shutdown (void); int DFH_SDL_Event(SDL::Event* event); bool ncurses_wgetch(int in, int & out); + bool DFH_ncurses_key(int key); - void doUpdate(color_ostream &out, bool first_update); + void doUpdate(color_ostream &out); void onUpdate(color_ostream &out); void onStateChange(color_ostream &out, state_change_event event); void handleLoadAndUnloadScripts(color_ostream &out, state_change_event event); diff --git a/library/include/DataIdentity.h b/library/include/DataIdentity.h index 711712af7..fd47429b9 100644 --- a/library/include/DataIdentity.h +++ b/library/include/DataIdentity.h @@ -394,6 +394,7 @@ namespace df template class ro_stl_container_identity : public container_identity { + protected: const char *name; public: @@ -419,6 +420,30 @@ namespace df } }; + template + class ro_stl_assoc_container_identity : public ro_stl_container_identity { + type_identity *key_identity; + type_identity *item_identity; + + public: + ro_stl_assoc_container_identity(const char *name, type_identity *key, type_identity *item) + : ro_stl_container_identity(name, item), + key_identity(key), + item_identity(item) + {} + + virtual std::string getFullName(type_identity*) override { + return std::string(ro_stl_assoc_container_identity::name) + "<" + key_identity->getFullName() + ", " + item_identity->getFullName() + ">"; + } + + protected: + virtual void *item_pointer(type_identity *item, void *ptr, int idx) override { + auto iter = (*(T*)ptr).begin(); + for (; idx > 0; idx--) ++iter; + return (void*)&iter->second; + } + }; + class bit_array_identity : public bit_container_identity { public: /* @@ -609,6 +634,10 @@ namespace df static container_identity *get(); }; + template struct identity_traits> { + static container_identity *get(); + }; + template<> struct identity_traits > { static bit_array_identity identity; static bit_container_identity *get() { return &identity; } @@ -679,6 +708,13 @@ namespace df return &identity; } + template + inline container_identity *identity_traits>::get() { + typedef std::map container; + static ro_stl_assoc_container_identity identity("map", identity_traits::get(), identity_traits::get()); + return &identity; + } + template inline bit_container_identity *identity_traits >::get() { static bit_array_identity identity(identity_traits::get()); diff --git a/library/include/DebugManager.h b/library/include/DebugManager.h index 57de0f279..d910efd4a 100644 --- a/library/include/DebugManager.h +++ b/library/include/DebugManager.h @@ -42,13 +42,13 @@ class DebugCategory; /*! * \brief Container holding all registered runtime debug categories * Singleton DebugManager is a minor extension to std::vector that allows signal - * callbacks to be attached from ui code that manages. + * callbacks to be attached from plotinfo code that manages. * * To avoid parallel plugin unload causing issues access to DebugManager must be * protected by mutex. The access mutex will be taken when * DFHack::DebugCategory::~DebugCategory performs unregister calls to * DFHack::DebugManager. The mutex will protect from memory disappearing while - * ui code is accessing or changing the runtime state. + * plotinfo code is accessing or changing the runtime state. * * Signal emitting happens from a locked contexts. Taking the * DFHack::DebugManager::access_mutex_ in a signal callback will results to a diff --git a/library/include/Hooks.h b/library/include/Hooks.h index d17b96acf..5856fb44f 100644 --- a/library/include/Hooks.h +++ b/library/include/Hooks.h @@ -74,3 +74,11 @@ DFhackCExport void * SDL_GetVideoSurface(void); DFhackCExport int SDL_SemWait(vPtr sem); DFhackCExport int SDL_SemPost(vPtr sem); + +// new Hooks API +DFhackCExport void dfhooks_init(); +DFhackCExport void dfhooks_shutdown(); +DFhackCExport void dfhooks_update(); +DFhackCExport void dfhooks_prerender(); +DFhackCExport bool dfhooks_sdl_event(SDL::Event* event); +DFhackCExport bool dfhooks_ncurses_key(int key); diff --git a/library/include/modules/DFSDL.h b/library/include/modules/DFSDL.h new file mode 100644 index 000000000..b5fd119f7 --- /dev/null +++ b/library/include/modules/DFSDL.h @@ -0,0 +1,92 @@ +#pragma once + +#include "Export.h" +#include "ColorText.h" + +namespace DFHack +{ + // SDL stand-in type definitions + typedef signed short SINT16; + typedef void DFSDL_sem; + + typedef struct + { + int16_t x, y; + uint16_t w, h; + } DFSDL_Rect; + typedef struct + { + void *palette; // SDL_Palette* + uint8_t BitsPerPixel; + uint8_t BytesPerPixel; + uint8_t Rloss; + uint8_t Gloss; + uint8_t Bloss; + uint8_t Aloss; + uint8_t Rshift; + uint8_t Gshift; + uint8_t Bshift; + uint8_t Ashift; + uint32_t Rmask; + uint32_t Gmask; + uint32_t Bmask; + uint32_t Amask; + uint32_t colorkey; + uint8_t alpha; + } DFSDL_PixelFormat; + typedef struct + { + uint32_t flags; + DFSDL_PixelFormat* format; + int w, h; + int pitch; + void* pixels; + void* userdata; // as far as i could see DF doesnt use this + int locked; + void* lock_data; + DFSDL_Rect clip_rect; + void* map; + int refcount; + } DFSDL_Surface; + + // ========= + struct DFTileSurface + { + bool paintOver; // draw over original tile? + DFSDL_Surface* surface; // from where it should be drawn + DFSDL_Rect* rect; // from which coords (NULL to draw whole surface) + DFSDL_Rect* dstResize; // if not NULL dst rect will be resized (x/y/w/h will be added to original dst) + }; + +/** + * The DFSDL module - provides access to SDL functions without actually + * requiring build-time linkage to SDL + * \ingroup grp_modules + * \ingroup grp_dfsdl + */ +namespace DFSDL +{ + +/** + * Call this on DFHack init so we can load the SDL functions. Returns false on + * failure. + */ +bool init(DFHack::color_ostream &out); + +/** + * Call this when DFHack is being unloaded. + */ +void cleanup(); + +DFHACK_EXPORT DFSDL_Surface * DFIMG_Load(const char *file); +DFHACK_EXPORT int DFSDL_SetAlpha(DFSDL_Surface *surface, uint32_t flag, uint8_t alpha); +DFHACK_EXPORT DFSDL_Surface * DFSDL_CreateRGBSurface(uint32_t flags, int width, int height, int depth, uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask); +DFHACK_EXPORT int DFSDL_UpperBlit(DFSDL_Surface *src, const DFSDL_Rect *srcrect, DFSDL_Surface *dst, DFSDL_Rect *dstrect); +DFHACK_EXPORT DFSDL_Surface * DFSDL_ConvertSurface(DFSDL_Surface *src, const DFSDL_PixelFormat *fmt, uint32_t flags); +DFHACK_EXPORT void DFSDL_FreeSurface(DFSDL_Surface *surface); +DFHACK_EXPORT int DFSDL_SemWait(DFSDL_sem *sem); +DFHACK_EXPORT int DFSDL_SemPost(DFSDL_sem *sem); + +} + +} diff --git a/library/include/modules/Graphic.h b/library/include/modules/Graphic.h index fa2cc30c6..22a5d4913 100644 --- a/library/include/modules/Graphic.h +++ b/library/include/modules/Graphic.h @@ -33,42 +33,11 @@ distribution. #include #include "Export.h" #include "Module.h" +#include "DFSDL.h" #include namespace DFHack { - // SDL stuff - typedef signed short SINT16; - typedef struct - { - int16_t x, y; - uint16_t w, h; - } DFSDL_Rect; - typedef struct - { - uint32_t flags; - void* format; // PixelFormat* - int w, h; - int pitch; - void* pixels; - void* userdata; // as far as i could see DF doesnt use this - int locked; - void* lock_data; - DFSDL_Rect clip_rect; - void* map; - int refcount; - } DFSDL_Surface; - - // ========= - struct DFTileSurface - { - bool paintOver; // draw over original tile? - DFSDL_Surface* surface; // from where it should be drawn - DFSDL_Rect* rect; // from which coords (NULL to draw whole surface) - DFSDL_Rect* dstResize; // if not NULL dst rect will be resized (x/y/w/h will be added to original dst) - }; - - class DFHACK_EXPORT Graphic : public Module { public: @@ -83,7 +52,6 @@ namespace DFHack private: std::vector funcs; }; - } #endif diff --git a/library/include/modules/Gui.h b/library/include/modules/Gui.h index d0b6f4d15..25415ffa9 100644 --- a/library/include/modules/Gui.h +++ b/library/include/modules/Gui.h @@ -33,7 +33,7 @@ distribution. #include "DataDefs.h" #include "df/init.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/announcement_type.h" #include "df/announcement_flags.h" #include "df/report_init.h" @@ -143,13 +143,10 @@ namespace DFHack static const int MENU_WIDTH = 30; struct DwarfmodeDims { - int map_x1, map_x2, menu_x1, menu_x2, area_x1, area_x2; - int y1, y2; + int map_x1, map_x2; int map_y1, map_y2; - bool menu_on, area_on, menu_forced; rect2d map() { return mkrect_xy(map_x1, map_y1, map_x2, map_y2); } - rect2d menu() { return mkrect_xy(menu_x1, y1, menu_x2, y2); } }; DFHACK_EXPORT DwarfmodeDims getDwarfmodeViewDims(); @@ -184,6 +181,9 @@ namespace DFHack DFHACK_EXPORT df::viewscreen *getViewscreenByIdentity(virtual_identity &id, int n = 1); + /// Get the top-most underlying DF viewscreen (not owned by DFHack) + DFHACK_EXPORT df::viewscreen *getDFViewscreen(bool skip_dismissed = false); + /// Get the top-most viewscreen of the given type from the top `n` viewscreens (or all viewscreens if n < 1) /// returns NULL if none match template @@ -198,18 +198,6 @@ namespace DFHack /// get the size of the window buffer DFHACK_EXPORT bool getWindowSize(int32_t & width, int32_t & height); - /** - *Menu width: - *3:3 - menu and area map closed - *2:3 - menu open single width - *1:3 - menu open double width - *1:2 - menu and area map open - *2:2 - area map open - */ - - DFHACK_EXPORT bool getMenuWidth(uint8_t & menu_width, uint8_t & area_map_width); - DFHACK_EXPORT bool setMenuWidth(const uint8_t menu_width, const uint8_t area_map_width); - namespace Hooks { GUI_HOOK_DECLARE(depth_at, int, (int32_t x, int32_t y)); GUI_HOOK_DECLARE(dwarfmode_view_dims, DwarfmodeDims, ()); diff --git a/library/include/modules/Kitchen.h b/library/include/modules/Kitchen.h index ec161178e..3fde8edf8 100644 --- a/library/include/modules/Kitchen.h +++ b/library/include/modules/Kitchen.h @@ -75,7 +75,7 @@ DFHACK_EXPORT void clearLimits(); DFHACK_EXPORT std::size_t size(); -// Finds the index of a kitchen exclusion in ui.kitchen.exc_types. Returns -1 if not found. +// Finds the index of a kitchen exclusion in plotinfo.kitchen.exc_types. Returns -1 if not found. DFHACK_EXPORT int findExclusion(df::kitchen_exc_type type, df::item_type item_type, int16_t item_subtype, int16_t mat_type, int32_t mat_index); diff --git a/library/include/modules/Renderer.h b/library/include/modules/Renderer.h index 65a9694ab..864efd8c1 100644 --- a/library/include/modules/Renderer.h +++ b/library/include/modules/Renderer.h @@ -5,13 +5,6 @@ #pragma once namespace DFHack { namespace Renderer { - // If the the 'x' parameter points to this value, then the 'y' parameter will - // be interpreted as a boolean flag for whether to return map coordinates (false) - // or text tile coordinates (true). Only TWBT implements this logic, and this - // sentinel value can be removed once DF provides an API for retrieving the - // two sets of coordinates. - DFHACK_EXPORT extern const int32_t GET_MOUSE_COORDS_SENTINEL; - struct DFHACK_EXPORT renderer_wrap : public df::renderer { void set_to_null(); void copy_from_parent(); @@ -19,19 +12,12 @@ namespace DFHack { namespace Renderer { renderer_wrap *parent; renderer_wrap *child; - virtual void update_tile(int32_t x, int32_t y); - virtual void update_all(); - virtual void render(); - virtual void set_fullscreen(); - virtual void zoom(df::zoom_commands z); - virtual void resize(int32_t w, int32_t h); - virtual void grid_resize(int32_t w, int32_t h); virtual ~renderer_wrap() { // All necessary cleanup should be handled by RemoveRenderer() }; - virtual bool get_mouse_coords(int32_t *x, int32_t *y); - virtual bool uses_opengl(); }; + + /* TODO: we can't cat enabler->renderer to renderer_wrap and expect it to work // Returns the renderer instance given on success, or deletes it and returns NULL on failure // Usage: renderer_foo *r = AddRenderer(new renderer_foo) DFHACK_EXPORT renderer_wrap *AddRenderer(renderer_wrap*, bool refresh_screen = false); @@ -42,4 +28,5 @@ namespace DFHack { namespace Renderer { { return (renderer_wrap*)(df::global::enabler ? df::global::enabler->renderer : NULL); } + */ }} diff --git a/library/include/modules/Screen.h b/library/include/modules/Screen.h index 347df1011..bc8a406a0 100644 --- a/library/include/modules/Screen.h +++ b/library/include/modules/Screen.h @@ -222,6 +222,7 @@ namespace DFHack DFHACK_EXPORT void dismiss(df::viewscreen *screen, bool to_first = false); DFHACK_EXPORT bool isDismissed(df::viewscreen *screen); DFHACK_EXPORT bool hasActiveScreens(Plugin *p); + DFHACK_EXPORT void raise(df::viewscreen *screen); /// Retrieve the string representation of the bound key. DFHACK_EXPORT std::string getKeyDisplay(df::interface_key key); diff --git a/library/include/modules/Textures.h b/library/include/modules/Textures.h new file mode 100644 index 000000000..2ef172bff --- /dev/null +++ b/library/include/modules/Textures.h @@ -0,0 +1,34 @@ +#pragma once + +#include "Export.h" +#include "ColorText.h" + +namespace DFHack { + +/** + * The Textures module - loads and provides access to DFHack textures + * \ingroup grp_modules + * \ingroup grp_textures + */ +namespace Textures { + +/** + * Call this on DFHack init and on every viewscreen change so we can reload + * and reindex textures as needed. + */ +void init(DFHack::color_ostream &out); + +/** + * Call this when DFHack is being unloaded. + * + */ +void cleanup(); + +/** + * Get first texpos for the DFHack logo. This texpos and the next 11 make up the + * 4x3 grid of logo textures that can be displayed on the UI layer. + */ +DFHACK_EXPORT long getDfhackLogoTexposStart(); + +} +} diff --git a/library/lua/gui.lua b/library/lua/gui.lua index 02d06bf5f..27484541f 100644 --- a/library/lua/gui.lua +++ b/library/lua/gui.lua @@ -7,17 +7,17 @@ local utils = require('utils') local dscreen = dfhack.screen local getval = utils.getval -USE_GRAPHICS = dscreen.inGraphicsMode() - local to_pen = dfhack.pen.parse -CLEAR_PEN = to_pen{ch=32,fg=0,bg=0} +CLEAR_PEN = to_pen{tile=909, ch=32, fg=0, bg=0} local FAKE_INPUT_KEYS = { _MOUSE_L = true, _MOUSE_R = true, + _MOUSE_M = true, _MOUSE_L_DOWN = true, _MOUSE_R_DOWN = true, + _MOUSE_M_DOWN = true, _STRING = true, } @@ -484,6 +484,10 @@ function View:getMousePos(view_rect) end end +function View:getMouseFramePos() + return self:getMousePos(ViewRect{rect=self.frame_rect}) +end + function View:computeFrame(parent_rect) return mkdims_wh(0,0,parent_rect.width,parent_rect.height) end @@ -599,6 +603,7 @@ end Screen = defclass(Screen, View) Screen.text_input_mode = false +Screen.request_full_screen_refresh = false function Screen:postinit() self:onResize(dscreen.getWindowSize()) @@ -624,6 +629,10 @@ function Screen:renderParent() else dscreen.clear() end + if Screen.request_full_screen_refresh then + df.global.gps.force_full_display_count = 1 + Screen.request_full_screen_refresh = false + end end function Screen:sendInputToParent(...) @@ -658,6 +667,8 @@ function Screen:dismiss() if self._native then dscreen.dismiss(self) end + -- don't leave artifacts behind on the parent screen when we disappear + Screen.request_full_screen_refresh = true end function Screen:onDismiss() @@ -674,9 +685,67 @@ function Screen:onRender() self:render(Painter.new()) end ------------------------- +----------------------------- +-- Z-order swapping screen -- +----------------------------- + +ZScreen = defclass(ZScreen, Screen) + +function ZScreen:onIdle() + if self._native and self._native.parent then + self._native.parent:logic() + end +end + +function ZScreen:render(dc) + self:renderParent() + ZScreen.super.render(self, dc) +end + +local function zscreen_is_top(self) + return dfhack.gui.getCurViewscreen(true) == self._native +end + +function ZScreen:onInput(keys) + if not zscreen_is_top(self) then + if keys._MOUSE_L_DOWN and self:isMouseOver() then + self:raise() + else + self:sendInputToParent(keys) + return + end + end + + if ZScreen.super.onInput(self, keys) then + return + end + if keys.LEAVESCREEN or keys._MOUSE_R_DOWN then + self:dismiss() + return + end + + if not keys._MOUSE_L or not self:isMouseOver() then + self:sendInputToParent(keys) + end +end + +-- move this viewscreen to the top of the stack (if it's not there already) +function ZScreen:raise() + if self:isDismissed() or zscreen_is_top(self) then + return + end + dscreen.raise(self) +end + +-- subclasses should override this and return whether the mouse is over an +-- owned screen element +function ZScreen:isMouseOver() + return false +end + +-------------------------- -- Framed screen object -- ------------------------- +-------------------------- -- Plain grey-colored frame. GREY_FRAME = { @@ -687,21 +756,23 @@ GREY_FRAME = { -- The usual boundary used by the DF screens. Often has fancy pattern in tilesets. BOUNDARY_FRAME = { - frame_pen = to_pen{ ch = 0xDB, fg = COLOR_DARKGREY, bg = COLOR_BLACK }, + frame_pen = to_pen{ ch = 0xDB, fg = COLOR_GREY, bg = COLOR_BLACK }, title_pen = to_pen{ fg = COLOR_BLACK, bg = COLOR_GREY }, - signature_pen = to_pen{ fg = COLOR_BLACK, bg = COLOR_DARKGREY }, + signature_pen = to_pen{ fg = COLOR_BLACK, bg = COLOR_GREY }, } GREY_LINE_FRAME = { - frame_pen = to_pen{ ch = 206, fg = COLOR_GREY, bg = COLOR_BLACK }, - h_frame_pen = to_pen{ ch = 205, fg = COLOR_GREY, bg = COLOR_BLACK }, - v_frame_pen = to_pen{ ch = 186, fg = COLOR_GREY, bg = COLOR_BLACK }, - lt_frame_pen = to_pen{ ch = 201, fg = COLOR_GREY, bg = COLOR_BLACK }, - lb_frame_pen = to_pen{ ch = 200, fg = COLOR_GREY, bg = COLOR_BLACK }, - rt_frame_pen = to_pen{ ch = 187, fg = COLOR_GREY, bg = COLOR_BLACK }, - rb_frame_pen = to_pen{ ch = 188, fg = COLOR_GREY, bg = COLOR_BLACK }, - title_pen = to_pen{ fg = COLOR_BLACK, bg = COLOR_GREY }, - signature_pen = to_pen{ fg = COLOR_DARKGREY, bg = COLOR_BLACK }, + frame_pen = to_pen{ ch=206, fg=COLOR_GREY, bg=COLOR_BLACK }, + t_frame_pen = to_pen{ tile=902, ch=205, fg=COLOR_GREY, bg=COLOR_BLACK }, + l_frame_pen = to_pen{ tile=908, ch=186, fg=COLOR_GREY, bg=COLOR_BLACK }, + b_frame_pen = to_pen{ tile=916, ch=205, fg=COLOR_GREY, bg=COLOR_BLACK }, + r_frame_pen = to_pen{ tile=910, ch=186, fg=COLOR_GREY, bg=COLOR_BLACK }, + lt_frame_pen = to_pen{ tile=901, ch=201, fg=COLOR_GREY, bg=COLOR_BLACK }, + lb_frame_pen = to_pen{ tile=915, ch=200, fg=COLOR_GREY, bg=COLOR_BLACK }, + rt_frame_pen = to_pen{ tile=903, ch=187, fg=COLOR_GREY, bg=COLOR_BLACK }, + rb_frame_pen = to_pen{ tile=917, ch=188, fg=COLOR_GREY, bg=COLOR_BLACK }, + title_pen = to_pen{ fg=COLOR_BLACK, bg=COLOR_GREY }, + signature_pen = to_pen{ fg=COLOR_GREY, bg=COLOR_BLACK }, } function paint_frame(dc,rect,style,title) diff --git a/library/lua/gui/buildings.lua b/library/lua/gui/buildings.lua index ae9219171..8871346f2 100644 --- a/library/lua/gui/buildings.lua +++ b/library/lua/gui/buildings.lua @@ -258,8 +258,8 @@ function BuildingDialog:onSubmitItem(idx, item) end function BuildingDialog:onInput(keys) - if keys.LEAVESCREEN or keys.LEAVESCREEN_ALL then - if self.subviews.back.visible and not keys.LEAVESCREEN_ALL then + if keys.LEAVESCREEN then + if self.subviews.back.visible then self:onGoBack() else self:dismiss() @@ -267,9 +267,9 @@ function BuildingDialog:onInput(keys) self.on_cancel() end end - else - self:inputToSubviews(keys) + return true end + self:inputToSubviews(keys) end function showBuildingPrompt(title, prompt, on_select, on_cancel, build_filter) diff --git a/library/lua/gui/dialogs.lua b/library/lua/gui/dialogs.lua index 952e8f734..e5448986f 100644 --- a/library/lua/gui/dialogs.lua +++ b/library/lua/gui/dialogs.lua @@ -48,7 +48,7 @@ end function MessageBox:onRenderFrame(dc,rect) MessageBox.super.onRenderFrame(self,dc,rect) if self.on_accept then - dc:seek(rect.x1+2,rect.y2):key('LEAVESCREEN'):string('/'):key('MENU_CONFIRM') + dc:seek(rect.x1+2,rect.y2):key('LEAVESCREEN'):string('/'):key('SELECT') end end @@ -59,19 +59,16 @@ function MessageBox:onDestroy() end function MessageBox:onInput(keys) - if keys.MENU_CONFIRM then + if keys.SELECT or keys.LEAVESCREEN then self:dismiss() - if self.on_accept then + if keys.SELECT and self.on_accept then self.on_accept() - end - elseif keys.LEAVESCREEN or (keys.SELECT and not self.on_accept) then - self:dismiss() - if self.on_cancel then + elseif keys.LEAVESCREEN and self.on_cancel then self.on_cancel() end - else - self:inputToSubviews(keys) + return true end + return self:inputToSubviews(keys) end function showMessage(title, text, tcolor, on_close) @@ -132,14 +129,15 @@ function InputBox:onInput(keys) if self.on_input then self.on_input(self.subviews.edit.text) end + return true elseif keys.LEAVESCREEN then self:dismiss() if self.on_cancel then self.on_cancel() end - else - self:inputToSubviews(keys) + return true end + return self:inputToSubviews(keys) end function showInputPrompt(title, text, tcolor, input, on_input, on_cancel, min_width) @@ -238,9 +236,9 @@ function ListBox:onInput(keys) if self.on_cancel then self.on_cancel() end - else - self:inputToSubviews(keys) + return true end + return self:inputToSubviews(keys) end function showListPrompt(title, text, tcolor, choices, on_select, on_cancel, min_width, filter) diff --git a/library/lua/gui/dwarfmode.lua b/library/lua/gui/dwarfmode.lua index db80554cd..bb381be24 100644 --- a/library/lua/gui/dwarfmode.lua +++ b/library/lua/gui/dwarfmode.lua @@ -49,7 +49,7 @@ function enterSidebarMode(sidebar_mode, max_esc) while remaining_esc > 0 do local screen = dfhack.gui.getCurViewscreen(true) focus_string = dfhack.gui.getFocusString(screen) - if df.global.ui.main.mode == df.ui_sidebar_mode.Default and + if df.global.plotinfo.main.mode == df.ui_sidebar_mode.Default and focus_string == 'dwarfmode/Default' then if #navkey > 0 then gui.simulateInput(screen, navkey) end if navkey == 'D_DESIGNATE' then @@ -71,30 +71,9 @@ end function getPanelLayout() local dims = dfhack.gui.getDwarfmodeViewDims() - local area_pos = df.global.ui_menu_width[1] - local menu_pos = df.global.ui_menu_width[0] - - if dims.menu_forced then - menu_pos = area_pos - 1 - end - - local rv = { - menu_pos = menu_pos, - area_pos = area_pos, - map = gui.mkdims_xy(dims.map_x1, dims.map_y1, dims.map_x2, dims.map_y2), + return { + map=gui.mkdims_xy(dims.map_x1, dims.map_y1, dims.map_x2, dims.map_y2), } - - if dims.menu_forced then - rv.menu_forced = true - end - if dims.menu_on then - rv.menu = gui.mkdims_xy(dims.menu_x1, dims.y1, dims.menu_x2, dims.y2) - end - if dims.area_on then - rv.area_map = gui.mkdims_xy(dims.area_x1, dims.y1, dims.area_x2, dims.y2) - end - - return rv end function getCursorPos() @@ -267,6 +246,10 @@ function Viewport:reveal(target,gap,max_scroll,scroll_gap,scroll_z) end MOVEMENT_KEYS = { + KEYBOARD_CURSOR_UP = { 0, -1, 0 }, KEYBOARD_CURSOR_DOWN = { 0, 1, 0 }, + KEYBOARD_CURSOR_LEFT = { -1, 0, 0 }, KEYBOARD_CURSOR_RIGHT = { 1, 0, 0 }, + KEYBOARD_CURSOR_UP_FAST = { 0, -1, 0, true }, KEYBOARD_CURSOR_DOWN_FAST = { 0, 1, 0, true }, + KEYBOARD_CURSOR_LEFT_FAST = { -1, 0, 0, true }, KEYBOARD_CURSOR_RIGHT_FAST = { 1, 0, 0, true }, CURSOR_UP = { 0, -1, 0 }, CURSOR_DOWN = { 0, 1, 0 }, CURSOR_LEFT = { -1, 0, 0 }, CURSOR_RIGHT = { 1, 0, 0 }, CURSOR_UPLEFT = { -1, -1, 0 }, CURSOR_UPRIGHT = { 1, -1, 0 }, @@ -292,7 +275,7 @@ end HOTKEY_KEYS = {} -for i,v in ipairs(df.global.ui.main.hotkeys) do +for i,v in ipairs(df.global.plotinfo.main.hotkeys) do HOTKEY_KEYS['D_HOTKEY'..(i+1)] = v end @@ -450,7 +433,7 @@ function MenuOverlay:init() end if self.sidebar_mode then - self.saved_sidebar_mode = df.global.ui.main.mode + self.saved_sidebar_mode = df.global.plotinfo.main.mode -- what mode should we restore when this window is dismissed? ideally, we'd -- restore the mode that the user has set, but we should fall back to -- restoring the default mode if either of the following conditions are @@ -553,66 +536,4 @@ function MenuOverlay:renderMapOverlay(get_overlay_char_fn, bounds_rect) end end ---fakes a "real" workshop sidebar menu, but on exactly selected workshop -WorkshopOverlay = defclass(WorkshopOverlay, MenuOverlay) -WorkshopOverlay.focus_path="WorkshopOverlay" -WorkshopOverlay.ATTRS={ - workshop=DEFAULT_NIL, -} -function WorkshopOverlay:onAboutToShow(below) - WorkshopOverlay.super.onAboutToShow(self,below) - - if df.global.world.selected_building ~= self.workshop then - error("The workshop overlay tried to show up for incorrect workshop") - end -end -function WorkshopOverlay:onInput(keys) - local allowedKeys={ --TODO add options: job management, profile, etc... - "CURSOR_RIGHT","CURSOR_RIGHT_FAST","CURSOR_LEFT","CURSOR_LEFT_FAST","CURSOR_UP","CURSOR_UP_FAST","CURSOR_DOWN","CURSOR_DOWN_FAST", - "CURSOR_UPRIGHT","CURSOR_UPRIGHT_FAST","CURSOR_UPLEFT","CURSOR_UPLEFT_FAST","CURSOR_DOWNRIGHT","CURSOR_DOWNRIGHT_FAST","CURSOR_DOWNLEFT","CURSOR_DOWNLEFT_FAST", - "CURSOR_UP_Z","CURSOR_DOWN_Z","DESTROYBUILDING","CHANGETAB","SUSPENDBUILDING"} - - if keys.LEAVESCREEN then - self:dismiss() - self:sendInputToParent('LEAVESCREEN') - elseif keys.CHANGETAB then - self:sendInputToParent("CHANGETAB") - self:inputToSubviews(keys) - self:updateLayout() - else - for _,name in ipairs(allowedKeys) do - if keys[name] then - self:sendInputToParent(name) - break - end - end - self:inputToSubviews(keys) - end - if df.global.world.selected_building ~= self.workshop then - self:dismiss() - return - end -end -function WorkshopOverlay:onGetSelectedBuilding() - return self.workshop -end -local function is_slated_for_remove( bld ) - for i,v in ipairs(bld.jobs) do - if v.job_type==df.job_type.DestroyBuilding then - return true - end - end - return false -end -function WorkshopOverlay:render(dc) - self:renderParent() - if df.global.world.selected_building ~= self.workshop then - return - end - if is_slated_for_remove(self.workshop) then - return - end - - WorkshopOverlay.super.render(self, dc) -end return _ENV diff --git a/library/lua/gui/materials.lua b/library/lua/gui/materials.lua index 1fbce4377..eea881768 100644 --- a/library/lua/gui/materials.lua +++ b/library/lua/gui/materials.lua @@ -255,8 +255,8 @@ function MaterialDialog:onSubmitItem(idx, item) end function MaterialDialog:onInput(keys) - if keys.LEAVESCREEN or keys.LEAVESCREEN_ALL then - if self.subviews.back.visible and not keys.LEAVESCREEN_ALL then + if keys.LEAVESCREEN then + if self.subviews.back.visible then self:onGoBack() else self:dismiss() @@ -264,9 +264,9 @@ function MaterialDialog:onInput(keys) self.on_cancel() end end - else - self:inputToSubviews(keys) + return true end + return self:inputToSubviews(keys) end function showMaterialPrompt(title, prompt, on_select, on_cancel, mat_filter) diff --git a/library/lua/gui/widgets.lua b/library/lua/gui/widgets.lua index d6ab4a134..e95410fb2 100644 --- a/library/lua/gui/widgets.lua +++ b/library/lua/gui/widgets.lua @@ -8,6 +8,7 @@ local utils = require('utils') local dscreen = dfhack.screen local getval = utils.getval +local to_pen = dfhack.pen.parse local function show_view(view,vis) if view then @@ -25,16 +26,13 @@ end STANDARDSCROLL = { STANDARDSCROLL_UP = -1, + KEYBOARD_CURSOR_UP = -1, STANDARDSCROLL_DOWN = 1, + KEYBOARD_CURSOR_DOWN = 1, STANDARDSCROLL_PAGEUP = '-page', + KEYBOARD_CURSOR_UP_FAST = '-page', STANDARDSCROLL_PAGEDOWN = '+page', -} - -SECONDSCROLL = { - SECONDSCROLL_UP = -1, - SECONDSCROLL_DOWN = 1, - SECONDSCROLL_PAGEUP = '-page', - SECONDSCROLL_PAGEDOWN = '+page', + KEYBOARD_CURSOR_DOWN_FAST = '+page', } ------------ @@ -89,7 +87,7 @@ Panel.ATTRS { function Panel:init(args) if not self.drag_anchors then - self.drag_anchors = {title=true, frame=false, body=false} + self.drag_anchors = {title=true, frame=false, body=true} end if not self.resize_anchors then self.resize_anchors = {t=false, l=true, r=true, b=true} @@ -305,8 +303,7 @@ function Panel:onInput(keys) return true end if not keys._MOUSE_L_DOWN then return end - local rect = self.frame_rect - local x,y = self:getMousePos(gui.ViewRect{rect=rect}) + local x,y = self:getMouseFramePos() if not x then return end if self.resizable and y == 0 then @@ -365,8 +362,10 @@ function Panel:setKeyboardDragEnabled(enabled) return end if enabled then - local kbd_get_pos = function() return {x=0, y=0} end - Panel_begin_drag(self, kbd_get_pos()) + local kbd_get_pos = function() + return {x=self.frame_rect.x1, y=self.frame_rect.y1} + end + Panel_begin_drag(self) self.kbd_get_pos = kbd_get_pos else Panel_end_drag(self) @@ -441,6 +440,9 @@ end -- if self.autoarrange_subviews is true, lay out visible subviews vertically, -- adding gaps between widgets according to self.autoarrange_gap. function Panel:postUpdateLayout() + -- don't leave artifacts behind on the parent screen when we move + gui.Screen.request_full_screen_refresh = true + if not self.autoarrange_subviews then return end local gap = self.autoarrange_gap @@ -465,7 +467,7 @@ function Panel:onRenderFrame(dc, rect) gui.paint_frame(dc, rect, self.frame_style, self.frame_title) if self.kbd_get_pos then local pos = self.kbd_get_pos() - local pen = dfhack.pen.parse{fg=COLOR_GREEN, bg=COLOR_BLACK} + local pen = to_pen{fg=COLOR_GREEN, bg=COLOR_BLACK} dc:seek(pos.x, pos.y):pen(pen):char(string.char(0xDB)) end if self.drag_offset and not self.kbd_get_pos @@ -654,6 +656,12 @@ function EditField:onRenderBody(dc) dc:string((' '):rep(dc.clip_x2 - dc.x)) end +function EditField:insert(text) + local old = self.text + self:setText(old:sub(1,self.cursor-1)..text..old:sub(self.cursor), + self.cursor + #text) +end + function EditField:onInput(keys) if not self.focus then -- only react to our hotkey @@ -676,22 +684,20 @@ function EditField:onInput(keys) return true end - if keys.SELECT then + if keys.SELECT or keys.CUSTOM_SHIFT_ENTER then if self.key then self:setFocus(false) end - if self.on_submit then - self.on_submit(self.text) - return true - end - return not not self.key - elseif keys.SEC_SELECT then - if self.key then - self:setFocus(false) - end - if self.on_submit2 then - self.on_submit2(self.text) - return true + if keys.CUSTOM_SHIFT_ENTER then + if self.on_submit2 then + self.on_submit2(self.text) + return true + end + else + if self.on_submit then + self.on_submit(self.text) + return true + end end return not not self.key elseif keys._MOUSE_L then @@ -712,8 +718,7 @@ function EditField:onInput(keys) else local cv = string.char(keys._STRING) if not self.on_char or self.on_char(cv, old) then - self:setText(old:sub(1,self.cursor-1)..cv..old:sub(self.cursor), - self.cursor + 1) + self:insert(cv) elseif self.on_char then return self.modal end @@ -722,25 +727,25 @@ function EditField:onInput(keys) self.on_change(self.text, old) end return true - elseif keys.CURSOR_LEFT then + elseif keys.KEYBOARD_CURSOR_LEFT then self:setCursor(self.cursor - 1) return true - elseif keys.A_MOVE_W_DOWN then -- Ctrl-Left (end of prev word) + elseif keys.CUSTOM_CTRL_B then -- back one word local _, prev_word_end = self.text:sub(1, self.cursor-1): - find('.*[%w_%-][^%w_%-]') + find('.*[%w_%-][^%w_%-]') self:setCursor(prev_word_end or 1) return true - elseif keys.A_CARE_MOVE_W then -- Alt-Left (home) + elseif keys.CUSTOM_CTRL_A then -- home self:setCursor(1) return true - elseif keys.CURSOR_RIGHT then + elseif keys.KEYBOARD_CURSOR_RIGHT then self:setCursor(self.cursor + 1) return true - elseif keys.A_MOVE_E_DOWN then -- Ctrl-Right (beginning of next word) + elseif keys.CUSTOM_CTRL_F then -- forward one word local _,next_word_start = self.text:find('[^%w_%-][%w_%-]', self.cursor) self:setCursor(next_word_start) return true - elseif keys.A_CARE_MOVE_E then -- Alt-Right (end) + elseif keys.CUSTOM_CTRL_E then -- end self:setCursor() return true end @@ -759,14 +764,12 @@ SCROLL_DELAY_MS = 20 Scrollbar = defclass(Scrollbar, Widget) Scrollbar.ATTRS{ - fg = COLOR_LIGHTGREEN, - bg = COLOR_CYAN, on_scroll = DEFAULT_NIL, } function Scrollbar:preinit(init_table) init_table.frame = init_table.frame or {} - init_table.frame.w = init_table.frame.w or 1 + init_table.frame.w = init_table.frame.w or 2 end function Scrollbar:init() @@ -824,36 +827,95 @@ local function scrollbar_is_visible(scrollbar) return scrollbar.elems_per_page < scrollbar.num_elems end -local UP_ARROW_CHAR = string.char(24) -local DOWN_ARROW_CHAR = string.char(25) -local NO_ARROW_CHAR = string.char(32) -local BAR_CHAR = string.char(7) -local BAR_BG_CHAR = string.char(179) +local SCROLLBAR_UP_LEFT_PEN = to_pen{tile=922, ch=47, fg=COLOR_CYAN, bg=COLOR_BLACK} +local SCROLLBAR_UP_RIGHT_PEN = to_pen{tile=923, ch=92, fg=COLOR_CYAN, bg=COLOR_BLACK} +local SCROLLBAR_DOWN_LEFT_PEN = to_pen{tile=946, ch=92, fg=COLOR_CYAN, bg=COLOR_BLACK} +local SCROLLBAR_DOWN_RIGHT_PEN = to_pen{tile=947, ch=47, fg=COLOR_CYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_UP_LEFT_PEN = to_pen{tile=930, ch=219, fg=COLOR_CYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_UP_RIGHT_PEN = to_pen{tile=931, ch=219, fg=COLOR_CYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_LEFT_PEN = to_pen{tile=954, ch=219, fg=COLOR_CYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_RIGHT_PEN = to_pen{tile=955, ch=219, fg=COLOR_CYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_CENTER_UP_LEFT_PEN = to_pen{tile=932, ch=219, fg=COLOR_CYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_CENTER_UP_RIGHT_PEN = to_pen{tile=933, ch=219, fg=COLOR_CYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_CENTER_DOWN_LEFT_PEN = to_pen{tile=960, ch=219, fg=COLOR_CYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_CENTER_DOWN_RIGHT_PEN = to_pen{tile=961, ch=219, fg=COLOR_CYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_CENTER_LEFT_PEN = to_pen{tile=940, ch=219, fg=COLOR_CYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_CENTER_RIGHT_PEN = to_pen{tile=941, ch=219, fg=COLOR_CYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_DOWN_LEFT_PEN = to_pen{tile=966, ch=219, fg=COLOR_CYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_DOWN_RIGHT_PEN = to_pen{tile=967, ch=219, fg=COLOR_CYAN, bg=COLOR_BLACK} +local SCROLLBAR_UP_LEFT_HOVER_PEN = to_pen{tile=924, ch=47, fg=COLOR_LIGHTCYAN, bg=COLOR_BLACK} +local SCROLLBAR_UP_RIGHT_HOVER_PEN = to_pen{tile=925, ch=92, fg=COLOR_LIGHTCYAN, bg=COLOR_BLACK} +local SCROLLBAR_DOWN_LEFT_HOVER_PEN = to_pen{tile=936, ch=92, fg=COLOR_LIGHTCYAN, bg=COLOR_BLACK} +local SCROLLBAR_DOWN_RIGHT_HOVER_PEN = to_pen{tile=937, ch=47, fg=COLOR_LIGHTCYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_UP_LEFT_HOVER_PEN = to_pen{tile=930, ch=219, fg=COLOR_LIGHTCYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_UP_RIGHT_HOVER_PEN = to_pen{tile=931, ch=219, fg=COLOR_LIGHTCYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_LEFT_HOVER_PEN = to_pen{tile=954, ch=219, fg=COLOR_LIGHTCYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_RIGHT_HOVER_PEN = to_pen{tile=955, ch=219, fg=COLOR_LIGHTCYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_CENTER_UP_LEFT_HOVER_PEN = to_pen{tile=956, ch=219, fg=COLOR_LIGHTCYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_CENTER_UP_RIGHT_HOVER_PEN = to_pen{tile=957, ch=219, fg=COLOR_LIGHTCYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_CENTER_DOWN_LEFT_HOVER_PEN = to_pen{tile=968, ch=219, fg=COLOR_LIGHTCYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_CENTER_DOWN_RIGHT_HOVER_PEN = to_pen{tile=969, ch=219, fg=COLOR_LIGHTCYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_CENTER_LEFT_HOVER_PEN = to_pen{tile=942, ch=219, fg=COLOR_LIGHTCYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_CENTER_RIGHT_HOVER_PEN = to_pen{tile=943, ch=219, fg=COLOR_LIGHTCYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_DOWN_LEFT_HOVER_PEN = to_pen{tile=966, ch=219, fg=COLOR_LIGHTCYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_DOWN_RIGHT_HOVER_PEN = to_pen{tile=967, ch=219, fg=COLOR_LIGHTCYAN, bg=COLOR_BLACK} +local SCROLLBAR_BAR_BG_LEFT_PEN = to_pen{tile=934, ch=176, fg=COLOR_DARKGREY, bg=COLOR_BLACK} +local SCROLLBAR_BAR_BG_RIGHT_PEN = to_pen{tile=935, ch=176, fg=COLOR_DARKGREY, bg=COLOR_BLACK} function Scrollbar:onRenderBody(dc) -- don't draw if all elements are visible if not scrollbar_is_visible(self) then return end - -- render up arrow if we're not at the top - dc:seek(0, 0):char( - self.top_elem == 1 and NO_ARROW_CHAR or UP_ARROW_CHAR, self.fg, self.bg) + -- determine which elements should be highlighted + local _,hover_y = self:getMousePos() + local hover_up, hover_down, hover_bar = false, false, false + if hover_y == 0 then + hover_up = true + elseif hover_y == dc.height-1 then + hover_down = true + elseif hover_y then + hover_bar = true + end + -- render up arrow + dc:seek(0, 0) + dc:char(nil, hover_up and SCROLLBAR_UP_LEFT_HOVER_PEN or SCROLLBAR_UP_LEFT_PEN) + dc:char(nil, hover_up and SCROLLBAR_UP_RIGHT_HOVER_PEN or SCROLLBAR_UP_RIGHT_PEN) -- render scrollbar body local starty = self.bar_offset + 1 local endy = self.bar_offset + self.bar_height + local midy = (starty + endy)/2 for y=1,dc.height-2 do dc:seek(0, y) if y >= starty and y <= endy then - dc:char(BAR_CHAR, self.fg) + if y == starty and y <= midy - 1 then + dc:char(nil, hover_bar and SCROLLBAR_BAR_UP_LEFT_HOVER_PEN or SCROLLBAR_BAR_UP_LEFT_PEN) + dc:char(nil, hover_bar and SCROLLBAR_BAR_UP_RIGHT_HOVER_PEN or SCROLLBAR_BAR_UP_RIGHT_PEN) + elseif y == midy - 0.5 then + dc:char(nil, hover_bar and SCROLLBAR_BAR_CENTER_UP_LEFT_HOVER_PEN or SCROLLBAR_BAR_CENTER_UP_LEFT_PEN) + dc:char(nil, hover_bar and SCROLLBAR_BAR_CENTER_UP_RIGHT_HOVER_PEN or SCROLLBAR_BAR_CENTER_UP_RIGHT_PEN) + elseif y == midy + 0.5 then + dc:char(nil, hover_bar and SCROLLBAR_BAR_CENTER_DOWN_LEFT_HOVER_PEN or SCROLLBAR_BAR_CENTER_DOWN_LEFT_PEN) + dc:char(nil, hover_bar and SCROLLBAR_BAR_CENTER_DOWN_RIGHT_HOVER_PEN or SCROLLBAR_BAR_CENTER_DOWN_RIGHT_PEN) + elseif y == midy then + dc:char(nil, hover_bar and SCROLLBAR_BAR_CENTER_LEFT_HOVER_PEN or SCROLLBAR_BAR_CENTER_LEFT_PEN) + dc:char(nil, hover_bar and SCROLLBAR_BAR_CENTER_RIGHT_HOVER_PEN or SCROLLBAR_BAR_CENTER_RIGHT_PEN) + elseif y == endy and y >= midy + 1 then + dc:char(nil, hover_bar and SCROLLBAR_BAR_DOWN_LEFT_HOVER_PEN or SCROLLBAR_BAR_DOWN_LEFT_PEN) + dc:char(nil, hover_bar and SCROLLBAR_BAR_DOWN_RIGHT_HOVER_PEN or SCROLLBAR_BAR_DOWN_RIGHT_PEN) + else + dc:char(nil, hover_bar and SCROLLBAR_BAR_LEFT_HOVER_PEN or SCROLLBAR_BAR_LEFT_PEN) + dc:char(nil, hover_bar and SCROLLBAR_BAR_RIGHT_HOVER_PEN or SCROLLBAR_BAR_RIGHT_PEN) + end else - dc:char(BAR_BG_CHAR, self.bg) + dc:char(nil, SCROLLBAR_BAR_BG_LEFT_PEN) + dc:char(nil, SCROLLBAR_BAR_BG_RIGHT_PEN) end end - -- render down arrow if we're not at the bottom - local last_visible_el = self.top_elem + self.elems_per_page - 1 - dc:seek(0, dc.height-1):char( - last_visible_el >= self.num_elems and NO_ARROW_CHAR or DOWN_ARROW_CHAR, - self.fg, self.bg) + -- render down arrow + dc:seek(0, dc.height-1) + dc:char(nil, hover_down and SCROLLBAR_DOWN_LEFT_HOVER_PEN or SCROLLBAR_DOWN_LEFT_PEN) + dc:char(nil, hover_down and SCROLLBAR_DOWN_RIGHT_HOVER_PEN or SCROLLBAR_DOWN_RIGHT_PEN) if not self.on_scroll then return end -- manage state for dragging and continuous scrolling if self.is_dragging then @@ -877,10 +939,26 @@ function Scrollbar:onRenderBody(dc) end function Scrollbar:onInput(keys) - if not keys._MOUSE_L_DOWN or not self.on_scroll - or not scrollbar_is_visible(self) then + if not self.on_scroll or not scrollbar_is_visible(self) then return false end + + if self.parent_view:getMousePos() then + if keys.CONTEXT_SCROLL_UP then + self.on_scroll('up_small') + return true + elseif keys.CONTEXT_SCROLL_DOWN then + self.on_scroll('down_small') + return true + elseif keys.CONTEXT_SCROLL_PAGEUP then + self.on_scroll('up_large') + return true + elseif keys.CONTEXT_SCROLL_PAGEDOWN then + self.on_scroll('down_large') + return true + end + end + if not keys._MOUSE_L_DOWN then return false end local _,y = self:getMousePos() if not y then return false end local scroll_spec = nil @@ -988,13 +1066,13 @@ function render_text(obj,dc,x0,y0,pen,dpen,disabled) if token.tile then x = x + 1 if dc then - dc:char(nil, token.tile) + dc:tile(nil, token.tile) end end if token.text or token.key then local text = ''..(getval(token.text) or '') - local keypen = dfhack.pen.parse(token.key_pen or COLOR_LIGHTGREEN) + local keypen = to_pen(token.key_pen or COLOR_LIGHTGREEN) if dc then local tpen = getval(token.pen) @@ -1027,6 +1105,9 @@ function render_text(obj,dc,x0,y0,pen,dpen,disabled) end if token.key then + if type(token.key) == 'string' and not df.interface_key[token.key] then + error('Invalid interface_key: ' .. token.key) + end local keystr = gui.getKeyDisplay(token.key) local sep = token.key_sep or '' @@ -1244,7 +1325,7 @@ end -- we can't set the text in init() since we may not yet have a frame that we -- can get wrapping bounds from. function WrappedLabel:postComputeFrame() - local wrapped_text = self:getWrappedText(self.frame_body.width-1) + local wrapped_text = self:getWrappedText(self.frame_body.width-3) if not wrapped_text then return end local text = {} for _,line in ipairs(wrapped_text:split(NEWLINE)) do @@ -1619,12 +1700,14 @@ end function List:submit() if self.on_submit and #self.choices > 0 then self.on_submit(self:getSelected()) + return true end end function List:submit2() if self.on_submit2 and #self.choices > 0 then self.on_submit2(self:getSelected()) + return true end end @@ -1632,12 +1715,10 @@ function List:onInput(keys) if self:inputToSubviews(keys) then return true end - if self.on_submit and keys.SELECT then - self:submit() - return true - elseif self.on_submit2 and keys.SEC_SELECT then - self:submit2() - return true + if keys.SELECT then + return self:submit() + elseif keys.CUSTOM_SHIFT_ENTER then + return self:submit2() elseif keys._MOUSE_L_DOWN then local idx = self:getIdxUnderMouse() if idx then diff --git a/library/lua/makeown.lua b/library/lua/makeown.lua index 2b16db1df..3d646b5fc 100644 --- a/library/lua/makeown.lua +++ b/library/lua/makeown.lua @@ -288,11 +288,11 @@ end function make_own(unit) --tweak makeown unit.flags2.resident = false; unit.flags1.merchant = false; unit.flags1.forest = false; - unit.civ_id = df.global.ui.civ_id + unit.civ_id = df.global.plotinfo.civ_id if unit.profession == df.profession.MERCHANT then unit.profession = df.profession.TRADER end if unit.profession2 == df.profession.MERCHANT then unit.profession2 = df.profession.TRADER end fix_clothing_ownership(unit) - if unit.race == df.global.ui.race_id then + if unit.race == df.global.plotinfo.race_id then make_citizen(unit) end end diff --git a/library/modules/Buildings.cpp b/library/modules/Buildings.cpp index 4ec3f11d7..21d63862c 100644 --- a/library/modules/Buildings.cpp +++ b/library/modules/Buildings.cpp @@ -81,14 +81,14 @@ using namespace DFHack; #include "df/job_item.h" #include "df/map_block.h" #include "df/tile_occupancy.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/ui_look_list.h" #include "df/unit.h" #include "df/unit_relationship_type.h" #include "df/world.h" using namespace df::enums; -using df::global::ui; +using df::global::plotinfo; using df::global::world; using df::global::d_init; using df::global::building_next_id; @@ -425,7 +425,7 @@ df::building *Buildings::allocInstance(df::coord pos, df::building_type type, in bld->y1 = bld->y2 = bld->centery = pos.y; bld->z = pos.z; - bld->race = ui->race_id; + bld->race = plotinfo->race_id; if (subtype != -1) bld->setSubtype(subtype); @@ -989,7 +989,7 @@ static void linkRooms(df::building *bld) } if (changed) - df::global::ui->equipment.update.bits.buildings = true; + df::global::plotinfo->equipment.update.bits.buildings = true; */ } @@ -1238,7 +1238,7 @@ bool Buildings::constructWithFilters(df::building *bld, std::vectortax_collection.rooms, linear_index(ui->tax_collection.rooms, bld->id)); + vector_erase_at(plotinfo->tax_collection.rooms, linear_index(plotinfo->tax_collection.rooms, bld->id)); // Assume: not used in punishment // Assume: not used in non-own jobs // Assume: does not affect pathfinding diff --git a/library/modules/Burrows.cpp b/library/modules/Burrows.cpp index 7d62a53db..c2fe45eae 100644 --- a/library/modules/Burrows.cpp +++ b/library/modules/Burrows.cpp @@ -42,14 +42,14 @@ using namespace std; #include "df/block_burrow_link.h" #include "df/burrow.h" #include "df/map_block.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/world.h" using namespace DFHack; using namespace df::enums; using df::global::world; -using df::global::ui; +using df::global::plotinfo; df::burrow *Burrows::findByName(std::string name) { @@ -76,15 +76,17 @@ void Burrows::clearUnits(df::burrow *burrow) burrow->units.clear(); - // Sync ui if active - if (ui && ui->main.mode == ui_sidebar_mode::Burrows && - ui->burrows.in_add_units_mode && ui->burrows.sel_id == burrow->id) +/* TODO: understand how this changes for v50 + // Sync plotinfo if active + if (plotinfo && plotinfo->main.mode == ui_sidebar_mode::Burrows && + plotinfo->burrows.in_add_units_mode && plotinfo->burrows.sel_id == burrow->id) { - auto &sel = ui->burrows.sel_units; + auto &sel = plotinfo->burrows.sel_units; for (size_t i = 0; i < sel.size(); i++) sel[i] = false; } +*/ } bool Burrows::isAssignedUnit(df::burrow *burrow, df::unit *unit) @@ -97,7 +99,7 @@ bool Burrows::isAssignedUnit(df::burrow *burrow, df::unit *unit) void Burrows::setAssignedUnit(df::burrow *burrow, df::unit *unit, bool enable) { - using df::global::ui; + using df::global::plotinfo; CHECK_NULL_POINTER(unit); CHECK_NULL_POINTER(burrow); @@ -113,14 +115,16 @@ void Burrows::setAssignedUnit(df::burrow *burrow, df::unit *unit, bool enable) erase_from_vector(burrow->units, unit->id); } - // Sync ui if active - if (ui && ui->main.mode == ui_sidebar_mode::Burrows && - ui->burrows.in_add_units_mode && ui->burrows.sel_id == burrow->id) +/* TODO: understand how this changes for v50 + // Sync plotinfo if active + if (plotinfo && plotinfo->main.mode == ui_sidebar_mode::Burrows && + plotinfo->burrows.in_add_units_mode && plotinfo->burrows.sel_id == burrow->id) { - int idx = linear_index(ui->burrows.list_units, unit); + int idx = linear_index(plotinfo->burrows.list_units, unit); if (idx >= 0) - ui->burrows.sel_units[idx] = enable; + plotinfo->burrows.sel_units[idx] = enable; } +*/ } void Burrows::listBlocks(std::vector *pvec, df::burrow *burrow) diff --git a/library/modules/DFSDL.cpp b/library/modules/DFSDL.cpp new file mode 100644 index 000000000..a7847fdb5 --- /dev/null +++ b/library/modules/DFSDL.cpp @@ -0,0 +1,120 @@ +#include "Internal.h" + +#include "modules/DFSDL.h" + +#include "Debug.h" +#include "PluginManager.h" + +namespace DFHack { + DBG_DECLARE(core, dfsdl, DebugCategory::LINFO); +} + +using namespace DFHack; + +static DFLibrary *g_sdl_handle = nullptr; +static DFLibrary *g_sdl_image_handle = nullptr; +static const std::vector SDL_LIBS { + "SDLreal.dll", // TODO: change to SDL.dll once we move to dfhooks + "SDL.framework/Versions/A/SDL", + "SDL.framework/SDL", + "libSDL-1.2.so.0" +}; +static const std::vector SDL_IMAGE_LIBS { + "SDL_image.dll", + "SDL_image.framework/Versions/A/SDL_image", + "SDL_image.framework/SDL_image", + "libSDL_image-1.2.so.0" +}; + +DFSDL_Surface * (*g_IMG_Load)(const char *) = nullptr; +int (*g_SDL_SetAlpha)(DFSDL_Surface *, uint32_t, uint8_t) = nullptr; +DFSDL_Surface * (*g_SDL_CreateRGBSurface)(uint32_t, int, int, int, uint32_t, uint32_t, uint32_t, uint32_t); +int (*g_SDL_UpperBlit)(DFSDL_Surface *, const DFSDL_Rect *, DFSDL_Surface *, DFSDL_Rect *); +DFSDL_Surface * (*g_SDL_ConvertSurface)(DFSDL_Surface *, const DFSDL_PixelFormat *, uint32_t); +void (*g_SDL_FreeSurface)(DFSDL_Surface *); +int (*g_SDL_SemWait)(DFSDL_sem *); +int (*g_SDL_SemPost)(DFSDL_sem *); + +bool DFSDL::init(color_ostream &out) { + for (auto &lib_str : SDL_LIBS) { + if ((g_sdl_handle = OpenPlugin(lib_str.c_str()))) + break; + } + if (!g_sdl_handle) { + out.printerr("DFHack could not find SDL\n"); + return false; + } + + for (auto &lib_str : SDL_IMAGE_LIBS) { + if ((g_sdl_image_handle = OpenPlugin(lib_str.c_str()))) + break; + } + if (!g_sdl_image_handle) { + out.printerr("DFHack could not find SDL_image\n"); + return false; + } + + #define bind(handle, name) \ + g_##name = (decltype(g_##name))LookupPlugin(handle, #name); \ + if (!g_##name) { \ + out.printerr("DFHack could not find: " #name "\n"); \ + return false; \ + } + + bind(g_sdl_image_handle, IMG_Load); + bind(g_sdl_handle, SDL_SetAlpha); + bind(g_sdl_handle, SDL_CreateRGBSurface); + bind(g_sdl_handle, SDL_UpperBlit); + bind(g_sdl_handle, SDL_ConvertSurface); + bind(g_sdl_handle, SDL_FreeSurface); + bind(g_sdl_handle, SDL_SemWait); + bind(g_sdl_handle, SDL_SemPost); + #undef bind + + DEBUG(dfsdl,out).print("sdl successfully loaded\n"); + return true; +} + +// It's ok to leave NULLs in the raws list (according to usage in g_src) +void DFSDL::cleanup() { + if (g_sdl_handle) { + ClosePlugin(g_sdl_handle); + g_sdl_handle = nullptr; + } + if (g_sdl_image_handle) { + ClosePlugin(g_sdl_image_handle); + g_sdl_image_handle = nullptr; + } +} + +DFSDL_Surface * DFSDL::DFIMG_Load(const char *file) { + return g_IMG_Load(file); +} + +int DFSDL::DFSDL_SetAlpha(DFSDL_Surface *surface, uint32_t flag, uint8_t alpha) { + return g_SDL_SetAlpha(surface, flag, alpha); +} + +DFSDL_Surface * DFSDL::DFSDL_CreateRGBSurface(uint32_t flags, int width, int height, int depth, uint32_t Rmask, uint32_t Gmask, uint32_t Bmask, uint32_t Amask) { + return g_SDL_CreateRGBSurface(flags, width, height, depth, Rmask, Gmask, Bmask, Amask); +} + +int DFSDL::DFSDL_UpperBlit(DFSDL_Surface *src, const DFSDL_Rect *srcrect, DFSDL_Surface *dst, DFSDL_Rect *dstrect) { + return g_SDL_UpperBlit(src, srcrect, dst, dstrect); +} + +DFSDL_Surface * DFSDL::DFSDL_ConvertSurface(DFSDL_Surface *src, const DFSDL_PixelFormat *fmt, uint32_t flags) { + return g_SDL_ConvertSurface(src, fmt, flags); +} + +void DFSDL::DFSDL_FreeSurface(DFSDL_Surface *surface) { + g_SDL_FreeSurface(surface); +} + +int DFSDL::DFSDL_SemWait(DFSDL_sem *sem) { + return g_SDL_SemWait(sem); +} + +int DFSDL::DFSDL_SemPost(DFSDL_sem *sem) { + return g_SDL_SemPost(sem); +} diff --git a/library/modules/EventManager.cpp b/library/modules/EventManager.cpp index 16f21ffdd..02b1892e9 100644 --- a/library/modules/EventManager.cpp +++ b/library/modules/EventManager.cpp @@ -1,5 +1,6 @@ #include "Core.h" #include "Console.h" +#include "Debug.h" #include "VTableInterpose.h" #include "modules/Buildings.h" #include "modules/Constructions.h" @@ -26,7 +27,7 @@ #include "df/job.h" #include "df/job_list_link.h" #include "df/report.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/unit.h" #include "df/unit_flags1.h" #include "df/unit_inventory_item.h" @@ -43,6 +44,10 @@ #include #include +namespace DFHack { + DBG_DECLARE(eventmanager, log, DebugCategory::LINFO); +} + using namespace std; using namespace DFHack; using namespace EventManager; @@ -63,6 +68,7 @@ static int32_t eventLastTick[EventType::EVENT_MAX]; static const int32_t ticksPerYear = 403200; void DFHack::EventManager::registerListener(EventType::EventType e, EventHandler handler, Plugin* plugin) { + DEBUG(log).print("registering handler %p from plugin %s for event %d\n", handler.eventHandler, plugin->getName().c_str(), e); handlers[e].insert(pair(plugin, handler)); } @@ -78,6 +84,7 @@ int32_t DFHack::EventManager::registerTick(EventHandler handler, int32_t when, P } handler.freq = when; tickQueue.insert(pair(handler.freq, handler)); + DEBUG(log).print("registering handler %p from plugin %s for event TICK\n", handler.eventHandler, plugin->getName().c_str()); handlers[EventType::TICK].insert(pair(plugin,handler)); return when; } @@ -103,6 +110,7 @@ void DFHack::EventManager::unregister(EventType::EventType e, EventHandler handl i++; continue; } + DEBUG(log).print("unregistering handler %p from plugin %s for event %d\n", handler.eventHandler, plugin->getName().c_str(), e); i = handlers[e].erase(i); if ( e == EventType::TICK ) removeFromTickQueue(handler); @@ -110,6 +118,7 @@ void DFHack::EventManager::unregister(EventType::EventType e, EventHandler handl } void DFHack::EventManager::unregisterAll(Plugin* plugin) { + DEBUG(log).print("unregistering all handlers for plugin %s\n", plugin->getName().c_str()); for ( auto i = handlers[EventType::TICK].find(plugin); i != handlers[EventType::TICK].end(); i++ ) { if ( (*i).first != plugin ) break; @@ -268,6 +277,7 @@ void DFHack::EventManager::onStateChange(color_ostream& out, state_change_event multimap copy(handlers[EventType::UNLOAD].begin(), handlers[EventType::UNLOAD].end()); for (auto &key_value : copy) { + DEBUG(log,out).print("calling handler for map unloaded state change event\n"); key_value.second.eventHandler(out, nullptr); } } else if ( event == DFHack::SC_MAP_LOADED ) { @@ -287,14 +297,14 @@ void DFHack::EventManager::onStateChange(color_ostream& out, state_change_event return; if (!df::global::job_next_id) return; - if (!df::global::ui) + if (!df::global::plotinfo) return; if (!df::global::world) return; nextItem = *df::global::item_next_id; nextBuilding = *df::global::building_next_id; - nextInvasion = df::global::ui->invasions.next_id; + nextInvasion = df::global::plotinfo->invasions.next_id; lastJobId = -1 + *df::global::job_next_id; constructions.clear(); @@ -358,6 +368,7 @@ void DFHack::EventManager::manageEvents(color_ostream& out) { CoreSuspender suspender; int32_t tick = df::global::world->frame_counter; + TRACE(log,out).print("processing events at tick %d\n", tick); for ( size_t a = 0; a < EventType::EVENT_MAX; a++ ) { if ( handlers[a].empty() ) @@ -389,6 +400,7 @@ static void manageTickEvent(color_ostream& out) { break; EventHandler &handle = (*tickQueue.begin()).second; tickQueue.erase(tickQueue.begin()); + DEBUG(log,out).print("calling handler for tick event\n"); handle.eventHandler(out, (void*)intptr_t(tick)); toRemove.insert(handle); } @@ -429,6 +441,7 @@ static void manageJobInitiatedEvent(color_ostream& out) { continue; for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for job initiated event\n"); handle.eventHandler(out, (void*)link->item); } } @@ -451,6 +464,7 @@ static void manageJobStartedEvent(color_ostream& out) { for (auto &key_value : copy) { auto &handler = key_value.second; // the jobs must have a worker to start + DEBUG(log,out).print("calling handler for job started event\n"); handler.eventHandler(out, job); } } @@ -561,6 +575,7 @@ static void manageJobCompletedEvent(color_ostream& out) { //still false positive if cancelled at EXACTLY the right time, but experiments show this doesn't happen for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for repeated job completed event\n"); handle.eventHandler(out, (void*)&job0); } continue; @@ -573,6 +588,7 @@ static void manageJobCompletedEvent(color_ostream& out) { for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for job completed event\n"); handle.eventHandler(out, (void*)&job0); } } @@ -607,6 +623,7 @@ static void manageNewUnitActiveEvent(color_ostream& out) { int32_t id = unit->id; if (!activeUnits.count(id)) { activeUnits.emplace(id); + DEBUG(log,out).print("calling handler for new unit event\n"); handler.eventHandler(out, (void*) intptr_t(id)); // intptr_t() avoids cast from smaller type warning } } @@ -630,6 +647,7 @@ static void manageUnitDeathEvent(color_ostream& out) { for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for unit death event\n"); handle.eventHandler(out, (void*)intptr_t(unit->id)); } livingUnits.erase(unit->id); @@ -667,6 +685,7 @@ static void manageItemCreationEvent(color_ostream& out) { continue; for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for item created event\n"); handle.eventHandler(out, (void*)intptr_t(item->id)); } } @@ -694,6 +713,7 @@ static void manageBuildingEvent(color_ostream& out) { buildings.insert(a); for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for created building event\n"); handle.eventHandler(out, (void*)intptr_t(a)); } } @@ -710,6 +730,7 @@ static void manageBuildingEvent(color_ostream& out) { for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for destroyed building event\n"); handle.eventHandler(out, (void*)intptr_t(id)); } a = buildings.erase(a); @@ -733,6 +754,7 @@ static void manageConstructionEvent(color_ostream& out) { // send construction to handlers, because it was removed for (const auto &key_value: copy) { EventHandler handle = key_value.second; + DEBUG(log,out).print("calling handler for destroyed construction event\n"); handle.eventHandler(out, (void*) &construction); } // erase from existent constructions @@ -747,6 +769,7 @@ static void manageConstructionEvent(color_ostream& out) { // send construction to handlers, because it is new for (const auto &key_value: copy) { EventHandler handle = key_value.second; + DEBUG(log,out).print("calling handler for created construction event\n"); handle.eventHandler(out, (void*) &construction); } } @@ -775,6 +798,7 @@ static void manageSyndromeEvent(color_ostream& out) { SyndromeData data(unit->id, b); for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for syndrome event\n"); handle.eventHandler(out, (void*)&data); } } @@ -783,16 +807,17 @@ static void manageSyndromeEvent(color_ostream& out) { } static void manageInvasionEvent(color_ostream& out) { - if (!df::global::ui) + if (!df::global::plotinfo) return; multimap copy(handlers[EventType::INVASION].begin(), handlers[EventType::INVASION].end()); - if ( df::global::ui->invasions.next_id <= nextInvasion ) + if ( df::global::plotinfo->invasions.next_id <= nextInvasion ) return; - nextInvasion = df::global::ui->invasions.next_id; + nextInvasion = df::global::plotinfo->invasions.next_id; for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for invasion event\n"); handle.eventHandler(out, (void*)intptr_t(nextInvasion-1)); } } @@ -834,6 +859,7 @@ static void manageEquipmentEvent(color_ostream& out) { InventoryChangeData data(unit->id, nullptr, &item_new); for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for new item equipped inventory change event\n"); handle.eventHandler(out, (void*)&data); } continue; @@ -849,6 +875,7 @@ static void manageEquipmentEvent(color_ostream& out) { InventoryChangeData data(unit->id, &item_old, &item_new); for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for inventory change event\n"); handle.eventHandler(out, (void*)&data); } } @@ -860,6 +887,7 @@ static void manageEquipmentEvent(color_ostream& out) { InventoryChangeData data(unit->id, &i, nullptr); for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for dropped item inventory change event\n"); handle.eventHandler(out, (void*)&data); } } @@ -913,6 +941,7 @@ static void manageReportEvent(color_ostream& out) { df::report* report = reports[idx]; for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for report event\n"); handle.eventHandler(out, (void*)intptr_t(report->id)); } lastReport = report->id; @@ -990,6 +1019,7 @@ static void manageUnitAttackEvent(color_ostream& out) { alreadyDone[data.attacker][data.defender] = 1; for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for unit1 attack unit attack event\n"); handle.eventHandler(out, (void*)&data); } } @@ -1002,6 +1032,7 @@ static void manageUnitAttackEvent(color_ostream& out) { alreadyDone[data.attacker][data.defender] = 1; for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for unit2 attack unit attack event\n"); handle.eventHandler(out, (void*)&data); } } @@ -1013,6 +1044,7 @@ static void manageUnitAttackEvent(color_ostream& out) { alreadyDone[data.attacker][data.defender] = 1; for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for unit1 killed unit attack event\n"); handle.eventHandler(out, (void*)&data); } } @@ -1024,6 +1056,7 @@ static void manageUnitAttackEvent(color_ostream& out) { alreadyDone[data.attacker][data.defender] = 1; for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for unit2 killed unit attack event\n"); handle.eventHandler(out, (void*)&data); } } @@ -1282,6 +1315,7 @@ static void manageInteractionEvent(color_ostream& out) { //fire event for (auto &key_value : copy) { EventHandler &handle = key_value.second; + DEBUG(log,out).print("calling handler for interaction event\n"); handle.eventHandler(out, (void*)&data); } //TODO: deduce attacker from latest defend event first diff --git a/library/modules/Gui.cpp b/library/modules/Gui.cpp index c23d7712d..bf2b2e745 100644 --- a/library/modules/Gui.cpp +++ b/library/modules/Gui.cpp @@ -61,12 +61,12 @@ using namespace DFHack; #include "df/general_ref.h" #include "df/global_objects.h" #include "df/graphic.h" +#include "df/graphic_viewportst.h" #include "df/historical_figure.h" #include "df/interfacest.h" #include "df/item_corpsepiecest.h" #include "df/item_corpsest.h" #include "df/job.h" -#include "df/layer_object_listst.h" #include "df/occupation.h" #include "df/plant.h" #include "df/popup_message.h" @@ -74,10 +74,10 @@ using namespace DFHack; #include "df/report_zoom_type.h" #include "df/route_stockpile_link.h" #include "df/stop_depart_condition.h" -#include "df/ui_advmode.h" -#include "df/ui_build_selector.h" +#include "df/adventurest.h" +#include "df/buildreq.h" #include "df/ui_look_list.h" -#include "df/ui_sidebar_menus.h" +#include "df/gamest.h" #include "df/ui_unit_view_mode.h" #include "df/unit.h" #include "df/unit_inventory_item.h" @@ -101,9 +101,9 @@ using df::global::gps; using df::global::gview; using df::global::init; using df::global::selection_rect; -using df::global::ui; +using df::global::plotinfo; using df::global::ui_menu_width; -using df::global::ui_sidebar_menus; +using df::global::game; using df::global::world; /* TODO: understand how this changes for v50 @@ -143,6 +143,7 @@ static std::map getFocusStringHandlers DEFINE_GET_FOCUS_STRING_HANDLER(dwarfmode) { +/* TODO: understand how this changes for v50 using namespace df::enums::ui_sidebar_mode; using df::global::ui_workshop_in_add; @@ -157,9 +158,9 @@ DEFINE_GET_FOCUS_STRING_HANDLER(dwarfmode) using df::global::ui_building_assign_items; using df::global::ui_building_in_assign; - focus += "/" + enum_item_key(ui->main.mode); + focus += "/" + enum_item_key(plotinfo->main.mode); - switch (ui->main.mode) + switch (plotinfo->main.mode) { case QueryBuilding: if (df::building *selected = world->selected_building) @@ -303,39 +304,38 @@ DEFINE_GET_FOCUS_STRING_HANDLER(dwarfmode) break; case Burrows: - if (ui->burrows.in_confirm_delete) + if (plotinfo->burrows.in_confirm_delete) focus += "/ConfirmDelete"; - else if (ui->burrows.in_add_units_mode) + else if (plotinfo->burrows.in_add_units_mode) focus += "/AddUnits"; - else if (ui->burrows.in_edit_name_mode) + else if (plotinfo->burrows.in_edit_name_mode) focus += "/EditName"; - else if (ui->burrows.in_define_mode) + else if (plotinfo->burrows.in_define_mode) focus += "/Define"; else focus += "/List"; break; -/* TODO: understand how this changes for v50 case Hauling: - if (ui->hauling.in_assign_vehicle) + if (plotinfo->hauling.in_assign_vehicle) { - auto vehicle = vector_get(ui->hauling.vehicles, ui->hauling.cursor_vehicle); + auto vehicle = vector_get(plotinfo->hauling.vehicles, plotinfo->hauling.cursor_vehicle); focus += "/AssignVehicle/" + std::string(vehicle ? "Some" : "None"); } else { - int idx = ui->hauling.cursor_top; - auto route = vector_get(ui->hauling.view_routes, idx); - auto stop = vector_get(ui->hauling.view_stops, idx); + int idx = plotinfo->hauling.cursor_top; + auto route = vector_get(plotinfo->hauling.view_routes, idx); + auto stop = vector_get(plotinfo->hauling.view_stops, idx); std::string tag = stop ? "Stop" : (route ? "Route" : "None"); - if (ui->hauling.in_name) + if (plotinfo->hauling.in_name) focus += "/Rename/" + tag; - else if (ui->hauling.in_stop) + else if (plotinfo->hauling.in_stop) { - int sidx = ui->hauling.cursor_stop; - auto cond = vector_get(ui->hauling.stop_conditions, sidx); - auto link = vector_get(ui->hauling.stop_links, sidx); + int sidx = plotinfo->hauling.cursor_stop; + auto cond = vector_get(plotinfo->hauling.stop_conditions, sidx); + auto link = vector_get(plotinfo->hauling.stop_links, sidx); focus += "/DefineStop"; @@ -354,22 +354,22 @@ DEFINE_GET_FOCUS_STRING_HANDLER(dwarfmode) focus += "/Select/" + tag; } break; -*/ default: break; } +*/ } /* TODO: understand how this changes for v50 DEFINE_GET_FOCUS_STRING_HANDLER(dungeonmode) { - using df::global::ui_advmode; + using df::global::adventure; - if (!ui_advmode) + if (!adventure) return; - focus += "/" + enum_item_key(ui_advmode->menu); + focus += "/" + enum_item_key(adventure->menu); } DEFINE_GET_FOCUS_STRING_HANDLER(unitlist) @@ -667,14 +667,15 @@ bool Gui::cursor_hotkey(df::viewscreen *top) bool Gui::workshop_job_hotkey(df::viewscreen *top) { + if (!dwarfmode_hotkey(top)) + return false; + +/* TODO: understand how this changes for v50 using namespace ui_sidebar_mode; using df::global::ui_workshop_in_add; using df::global::ui_workshop_job_cursor; - if (!dwarfmode_hotkey(top)) - return false; - - switch (ui->main.mode) { + switch (plotinfo->main.mode) { case QueryBuilding: { if (!ui_workshop_job_cursor) // allow missing @@ -699,17 +700,19 @@ bool Gui::workshop_job_hotkey(df::viewscreen *top) default: return false; } +*/ return false; } bool Gui::build_selector_hotkey(df::viewscreen *top) { - using namespace ui_sidebar_mode; - using df::global::ui_build_selector; - if (!dwarfmode_hotkey(top)) return false; - switch (ui->main.mode) { +/* TODO: understand how this changes for v50 + using namespace ui_sidebar_mode; + using df::global::ui_build_selector; + + switch (plotinfo->main.mode) { case Build: { if (!ui_build_selector) // allow missing @@ -726,20 +729,23 @@ bool Gui::build_selector_hotkey(df::viewscreen *top) default: return false; } +*/ return false; } bool Gui::view_unit_hotkey(df::viewscreen *top) { - using df::global::ui_selected_unit; - if (!dwarfmode_hotkey(top)) return false; - if (ui->main.mode != ui_sidebar_mode::ViewUnits) +/* TODO: understand how this changes for v50 + using df::global::ui_selected_unit; + + if (plotinfo->main.mode != ui_sidebar_mode::ViewUnits) return false; if (!ui_selected_unit) // allow missing return false; return vector_get(world->units.active, *ui_selected_unit) != NULL; +*/ return false; } bool Gui::unit_inventory_hotkey(df::viewscreen *top) @@ -826,6 +832,7 @@ df::job *Gui::getSelectedJob(color_ostream &out, bool quiet) df::unit *Gui::getAnyUnit(df::viewscreen *top) { +/* TODO: understand how this changes for v50 using namespace ui_sidebar_mode; using df::global::ui_look_cursor; using df::global::ui_look_list; @@ -834,7 +841,6 @@ df::unit *Gui::getAnyUnit(df::viewscreen *top) using df::global::ui_building_assign_units; using df::global::ui_building_item_cursor; -/* TODO: understand how this changes for v50 if (VIRTUAL_CAST_VAR(screen, df::viewscreen_unitst, top)) { return screen->unit; @@ -1011,19 +1017,19 @@ df::unit *Gui::getAnyUnit(df::viewscreen *top) if (!Gui::dwarfmode_hotkey(top)) return NULL; - if (!ui) + if (!plotinfo) return NULL; // general assigning units in building, i.e. (q)uery cage -> (a)ssign if (ui_building_in_assign && *ui_building_in_assign && ui_building_assign_units && ui_building_item_cursor - && ui->main.mode != Zones) // dont show for (i) zone + && plotinfo->main.mode != Zones) // dont show for (i) zone return vector_get(*ui_building_assign_units, *ui_building_item_cursor); - if (ui->follow_unit != -1) - return df::unit::find(ui->follow_unit); + if (plotinfo->follow_unit != -1) + return df::unit::find(plotinfo->follow_unit); - switch (ui->main.mode) { + switch (plotinfo->main.mode) { case ViewUnits: { if (!ui_selected_unit || !world) @@ -1041,8 +1047,8 @@ df::unit *Gui::getAnyUnit(df::viewscreen *top) } case Burrows: { - if (ui->burrows.in_add_units_mode) - return vector_get(ui->burrows.list_units, ui->burrows.unit_cursor_pos); + if (plotinfo->burrows.in_add_units_mode) + return vector_get(plotinfo->burrows.list_units, plotinfo->burrows.unit_cursor_pos); return NULL; } @@ -1108,13 +1114,13 @@ df::unit *Gui::getSelectedUnit(color_ostream &out, bool quiet) df::item *Gui::getAnyItem(df::viewscreen *top) { +/* TODO: understand how this changes for v50 using namespace ui_sidebar_mode; using df::global::ui_look_cursor; using df::global::ui_look_list; using df::global::ui_unit_view_mode; using df::global::ui_building_item_cursor; -/* TODO: understand how this changes for v50 if (VIRTUAL_CAST_VAR(screen, df::viewscreen_textviewerst, top)) { // return the main item if the parent screen is a viewscreen_itemst @@ -1190,16 +1196,16 @@ df::item *Gui::getAnyItem(df::viewscreen *top) if (!Gui::dwarfmode_hotkey(top)) return NULL; - switch (ui->main.mode) { + switch (plotinfo->main.mode) { case ViewUnits: { - if (!ui_unit_view_mode || !ui_look_cursor || !ui_sidebar_menus) + if (!ui_unit_view_mode || !ui_look_cursor || !game) return NULL; if (ui_unit_view_mode->value != df::ui_unit_view_mode::Inventory) return NULL; - auto inv_item = vector_get(ui_sidebar_menus->unit.inv_items, *ui_look_cursor); + auto inv_item = vector_get(game->unit.inv_items, *ui_look_cursor); return inv_item ? inv_item->item : NULL; } case LookAround: @@ -1248,11 +1254,11 @@ df::item *Gui::getSelectedItem(color_ostream &out, bool quiet) df::building *Gui::getAnyBuilding(df::viewscreen *top) { +/* TODO: understand how this changes for v50 using namespace ui_sidebar_mode; using df::global::ui_look_list; using df::global::ui_look_cursor; -/* TODO: understand how this changes for v50 if (VIRTUAL_CAST_VAR(screen, df::viewscreen_buildinglistst, top)) return vector_get(screen->buildings, screen->cursor); @@ -1265,7 +1271,7 @@ df::building *Gui::getAnyBuilding(df::viewscreen *top) if (!Gui::dwarfmode_hotkey(top)) return NULL; - switch (ui->main.mode) { + switch (plotinfo->main.mode) { case LookAround: { if (!ui_look_list || !ui_look_cursor) @@ -1287,8 +1293,8 @@ df::building *Gui::getAnyBuilding(df::viewscreen *top) case ZonesPitInfo: case ZonesHospitalInfo: { - if (ui_sidebar_menus) - return ui_sidebar_menus->zone.selected; + if (game) + return game->zone.selected; return NULL; } default: @@ -1321,13 +1327,15 @@ df::plant *Gui::getAnyPlant(df::viewscreen *top) if (Gui::dwarfmode_hotkey(top)) { - if (!cursor || !ui || !world) + if (!cursor || !plotinfo || !world) return nullptr; - if (ui->main.mode == ui_sidebar_mode::LookAround) +/* TODO: understand how this changes for v50 + if (plotinfo->main.mode == ui_sidebar_mode::LookAround) { return Maps::getPlantAtTile(cursor->x, cursor->y, cursor->z); } +*/ } return nullptr; @@ -1865,6 +1873,12 @@ bool Gui::autoDFAnnouncement(df::announcement_type type, df::coord pos, std::str return autoDFAnnouncement(r, message); } +static df::viewscreen * do_skip_dismissed(df::viewscreen * ws) { + while (ws && Screen::isDismissed(ws) && ws->parent) + ws = ws->parent; + return ws; +} + df::viewscreen *Gui::getCurViewscreen(bool skip_dismissed) { if (!gview) @@ -1875,10 +1889,7 @@ df::viewscreen *Gui::getCurViewscreen(bool skip_dismissed) ws = ws->child; if (skip_dismissed) - { - while (ws && Screen::isDismissed(ws) && ws->parent) - ws = ws->parent; - } + ws = do_skip_dismissed(ws); return ws; } @@ -1898,6 +1909,16 @@ df::viewscreen *Gui::getViewscreenByIdentity (virtual_identity &id, int n) return NULL; } +df::viewscreen *Gui::getDFViewscreen(bool skip_dismissed) { + df::viewscreen *screen = Gui::getCurViewscreen(skip_dismissed); + while (screen && dfhack_viewscreen::is_instance(screen)) { + screen = screen->parent; + if (skip_dismissed) + screen = do_skip_dismissed(screen); + } + return screen; +} + df::coord Gui::getViewportPos() { if (!df::global::window_x || !df::global::window_y || !df::global::window_z) @@ -1919,47 +1940,14 @@ Gui::DwarfmodeDims getDwarfmodeViewDims_default() { Gui::DwarfmodeDims dims; - auto ws = Screen::getWindowSize(); - dims.y1 = 1; - dims.y2 = ws.y-2; - - dims.map_x1 = 1; - dims.map_x2 = ws.x-2; - dims.map_y1 = dims.y1; - dims.map_y2 = dims.y2; - - dims.area_x1 = dims.area_x2 = dims.menu_x1 = dims.menu_x2 = -1; - dims.menu_forced = false; + bool use_graphics = Screen::inGraphicsMode(); + auto dimx = use_graphics ? gps->main_viewport->dim_x : gps->dimx; + auto dimy = use_graphics ? gps->main_viewport->dim_y : gps->dimy; - int menu_pos = (ui_menu_width ? (*ui_menu_width)[0] : 2); - int area_pos = (ui_menu_width ? (*ui_menu_width)[1] : 3); - - if (ui && ui->main.mode != ui_sidebar_mode::Default && ui->main.mode != ui_sidebar_mode::ArenaWeather && menu_pos >= area_pos) - { - dims.menu_forced = true; - menu_pos = area_pos-1; - } - - dims.area_on = (area_pos < 3); - dims.menu_on = (menu_pos < area_pos); - - if (dims.menu_on) - { - dims.menu_x2 = ws.x - 2; - dims.menu_x1 = dims.menu_x2 - Gui::MENU_WIDTH + 1; - if (menu_pos == 1) - dims.menu_x1 -= Gui::AREA_MAP_WIDTH + 1; - dims.map_x2 = dims.menu_x1 - 2; - } - if (dims.area_on) - { - dims.area_x2 = ws.x-2; - dims.area_x1 = dims.area_x2 - Gui::AREA_MAP_WIDTH + 1; - if (dims.menu_on) - dims.menu_x2 = dims.area_x1 - 2; - else - dims.map_x2 = dims.area_x1 - 2; - } + dims.map_x1 = 0; + dims.map_x2 = dimx - 1; + dims.map_y1 = 0; + dims.map_y2 = dimy - 1; return dims; } @@ -1974,11 +1962,13 @@ void Gui::resetDwarfmodeView(bool pause) { using df::global::cursor; - if (ui) + if (plotinfo) { - ui->follow_unit = -1; - ui->follow_item = -1; - ui->main.mode = ui_sidebar_mode::Default; + plotinfo->follow_unit = -1; + plotinfo->follow_item = -1; +/* TODO: understand how this changes for v50 + plotinfo->main.mode = ui_sidebar_mode::Default; +*/ } if (selection_rect) @@ -2034,8 +2024,8 @@ bool Gui::revealInDwarfmodeMap(int32_t x, int32_t y, int32_t z, bool center) *window_x = clip_range(new_win_x, 0, (world->map.x_count - w)); *window_y = clip_range(new_win_y, 0, (world->map.y_count - h)); *window_z = clip_range(new_win_z, 0, (world->map.z_count - 1)); - ui_sidebar_menus->minimap.need_render = true; - ui_sidebar_menus->minimap.need_scan = true; + game->minimap.need_render = true; + game->minimap.need_scan = true; return true; } @@ -2081,10 +2071,10 @@ bool Gui::refreshSidebar() bool Gui::inRenameBuilding() { - if (!ui_sidebar_menus) + if (!game) return false; /* TODO: understand how this changes for v50 - return ui_sidebar_menus->barracks.in_rename; + return game->barracks.in_rename; */ return false; } @@ -2150,24 +2140,33 @@ bool Gui::setDesignationCoords (const int32_t x, const int32_t y, const int32_t df::coord Gui::getMousePos() { df::coord pos; -/* TODO: understand how this changes for v50 - if (gps && gps->mouse_x > -1) { - // return invalid coords if the cursor is not over the map - DwarfmodeDims dims = getDwarfmodeViewDims(); - if (gps->mouse_x < dims.map_x1 || gps->mouse_x > dims.map_x2 || - gps->mouse_y < dims.map_y1 || gps->mouse_y > dims.map_y2) { - return pos; - } + if (gps && gps->precise_mouse_x > -1) { pos = getViewportPos(); - pos.x += gps->mouse_x - 1; - pos.y += gps->mouse_y - 1; + if (Screen::inGraphicsMode()) { + int32_t map_tile_pixels = gps->viewport_zoom_factor / 4; + pos.x += gps->precise_mouse_x / map_tile_pixels; + pos.y += gps->precise_mouse_y / map_tile_pixels; + } else { + pos.x += gps->mouse_x; + pos.y += gps->mouse_y; + } } -*/ + if (!Maps::isValidTilePos(pos.x, pos.y, pos.z)) + return df::coord(); return pos; } int getDepthAt_default (int32_t x, int32_t y) { + auto &main_vp = gps->main_viewport; + if (x < 0 || x >= main_vp->dim_x || y < 0 || y >= main_vp->dim_y) + return 0; + const size_t num_viewports = gps->viewport.size(); + const size_t index = (x * main_vp->dim_y) + y; + for (size_t depth = 0; depth < num_viewports; ++depth) { + if (gps->viewport[depth]->screentexpos_background[index]) + return depth; + } return 0; } @@ -2190,17 +2189,3 @@ bool Gui::getWindowSize (int32_t &width, int32_t &height) return false; } } - -bool Gui::getMenuWidth(uint8_t &menu_width, uint8_t &area_map_width) -{ - menu_width = (*ui_menu_width)[0]; - area_map_width = (*ui_menu_width)[1]; - return true; -} - -bool Gui::setMenuWidth(const uint8_t menu_width, const uint8_t area_map_width) -{ - (*ui_menu_width)[0] = menu_width; - (*ui_menu_width)[1] = area_map_width; - return true; -} diff --git a/library/modules/Items.cpp b/library/modules/Items.cpp index 14c637dc8..11d170725 100644 --- a/library/modules/Items.cpp +++ b/library/modules/Items.cpp @@ -87,7 +87,7 @@ using namespace std; #include "df/reaction_product_itemst.h" #include "df/tool_uses.h" #include "df/trapcomp_flags.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/unit.h" #include "df/unit_inventory_item.h" #include "df/vehicle.h" @@ -100,7 +100,7 @@ using namespace std; using namespace DFHack; using namespace df::enums; using df::global::world; -using df::global::ui; +using df::global::plotinfo; using df::global::ui_selected_unit; using df::global::proj_next_id; @@ -922,11 +922,13 @@ static bool detachItem(MapExtras::MapCache &mc, df::item *item) case general_ref_type::UNIT_HOLDER: if (auto unit = ref->getUnit()) { +/* TODO: understand how this changes for v50 // Unit view sidebar holds inventory item pointers - if (ui->main.mode == ui_sidebar_mode::ViewUnits && + if (plotinfo->main.mode == ui_sidebar_mode::ViewUnits && (!ui_selected_unit || vector_get(world->units.active, *ui_selected_unit) == unit)) return false; +*/ for (int i = unit->inventory.size()-1; i >= 0; i--) { @@ -1532,7 +1534,7 @@ int32_t Items::createItem(df::item_type item_type, int16_t item_subtype, int16_t df::enums::game_type::game_type type = *df::global::gametype; prod->produce(unit, &out_products, &out_items, &in_reag, &in_items, 1, job_skill::NONE, 0, df::historical_entity::find(unit->civ_id), - ((type == df::enums::game_type::DWARF_MAIN) || (type == df::enums::game_type::DWARF_RECLAIM)) ? df::world_site::find(df::global::ui->site_id) : NULL, + ((type == df::enums::game_type::DWARF_MAIN) || (type == df::enums::game_type::DWARF_RECLAIM)) ? df::world_site::find(df::global::plotinfo->site_id) : NULL, NULL); if ( out_items.size() != 1 ) return -1; @@ -1641,9 +1643,9 @@ bool Items::isRouteVehicle(df::item *item) bool Items::isSquadEquipment(df::item *item) { CHECK_NULL_POINTER(item); - if (!ui) + if (!plotinfo) return false; - auto &vec = ui->equipment.items_assigned[item->getType()]; + auto &vec = plotinfo->equipment.items_assigned[item->getType()]; return binsearch_index(vec, &df::item::id, item->id) >= 0; } diff --git a/library/modules/Job.cpp b/library/modules/Job.cpp index ff158caa0..cd574684f 100644 --- a/library/modules/Job.cpp +++ b/library/modules/Job.cpp @@ -43,7 +43,7 @@ using namespace std; #include "DataDefs.h" #include "df/world.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/unit.h" #include "df/building.h" #include "df/job.h" diff --git a/library/modules/Kitchen.cpp b/library/modules/Kitchen.cpp index ac560c687..65e47f528 100644 --- a/library/modules/Kitchen.cpp +++ b/library/modules/Kitchen.cpp @@ -20,13 +20,13 @@ using namespace DFHack; #include "DataDefs.h" #include "df/world.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/item_type.h" #include "df/plant_raw.h" using namespace df::enums; using df::global::world; -using df::global::ui; +using df::global::plotinfo; // Special values used by "seedwatch" plugin to store seed limits const df::enums::item_type::item_type SEEDLIMIT_ITEMTYPE = df::enums::item_type::BAR; @@ -41,12 +41,12 @@ void Kitchen::debug_print(color_ostream &out) { out.print("%2zu: IT:%2i IS:%i MT:%3i MI:%2i ET:%i %s\n", i, - ui->kitchen.item_types[i], - ui->kitchen.item_subtypes[i], - ui->kitchen.mat_types[i], - ui->kitchen.mat_indices[i], - ui->kitchen.exc_types[i], - (ui->kitchen.mat_types[i] >= 419 && ui->kitchen.mat_types[i] <= 618) ? world->raws.plants.all[ui->kitchen.mat_indices[i]]->id.c_str() : "n/a" + plotinfo->kitchen.item_types[i], + plotinfo->kitchen.item_subtypes[i], + plotinfo->kitchen.mat_types[i], + plotinfo->kitchen.mat_indices[i], + plotinfo->kitchen.exc_types[i], + (plotinfo->kitchen.mat_types[i] >= 419 && plotinfo->kitchen.mat_types[i] <= 618) ? world->raws.plants.all[plotinfo->kitchen.mat_indices[i]]->id.c_str() : "n/a" ); } out.print("\n"); @@ -83,11 +83,11 @@ void Kitchen::fillWatchMap(std::map& watchMap) watchMap.clear(); for (std::size_t i = 0; i < size(); ++i) { - if (ui->kitchen.item_subtypes[i] == SEEDLIMIT_ITEMTYPE && - ui->kitchen.item_subtypes[i] == SEEDLIMIT_ITEMSUBTYPE && - ui->kitchen.exc_types[i] == SEEDLIMIT_EXCTYPE) + if (plotinfo->kitchen.item_subtypes[i] == SEEDLIMIT_ITEMTYPE && + plotinfo->kitchen.item_subtypes[i] == SEEDLIMIT_ITEMSUBTYPE && + plotinfo->kitchen.exc_types[i] == SEEDLIMIT_EXCTYPE) { - watchMap[ui->kitchen.mat_indices[i]] = ui->kitchen.mat_types[i]; + watchMap[plotinfo->kitchen.mat_indices[i]] = plotinfo->kitchen.mat_types[i]; } } } @@ -96,10 +96,10 @@ int Kitchen::findLimit(int32_t plant_id) { for (size_t i = 0; i < size(); ++i) { - if (ui->kitchen.item_types[i] == SEEDLIMIT_ITEMTYPE && - ui->kitchen.item_subtypes[i] == SEEDLIMIT_ITEMSUBTYPE && - ui->kitchen.mat_indices[i] == plant_id && - ui->kitchen.exc_types[i] == SEEDLIMIT_EXCTYPE) + if (plotinfo->kitchen.item_types[i] == SEEDLIMIT_ITEMTYPE && + plotinfo->kitchen.item_subtypes[i] == SEEDLIMIT_ITEMSUBTYPE && + plotinfo->kitchen.mat_indices[i] == plant_id && + plotinfo->kitchen.exc_types[i] == SEEDLIMIT_EXCTYPE) { return int(i); } @@ -113,11 +113,11 @@ bool Kitchen::removeLimit(int32_t plant_id) if (i < 0) return false; - ui->kitchen.item_types.erase(ui->kitchen.item_types.begin() + i); - ui->kitchen.item_subtypes.erase(ui->kitchen.item_subtypes.begin() + i); - ui->kitchen.mat_types.erase(ui->kitchen.mat_types.begin() + i); - ui->kitchen.mat_indices.erase(ui->kitchen.mat_indices.begin() + i); - ui->kitchen.exc_types.erase(ui->kitchen.exc_types.begin() + i); + plotinfo->kitchen.item_types.erase(plotinfo->kitchen.item_types.begin() + i); + plotinfo->kitchen.item_subtypes.erase(plotinfo->kitchen.item_subtypes.begin() + i); + plotinfo->kitchen.mat_types.erase(plotinfo->kitchen.mat_types.begin() + i); + plotinfo->kitchen.mat_indices.erase(plotinfo->kitchen.mat_indices.begin() + i); + plotinfo->kitchen.exc_types.erase(plotinfo->kitchen.exc_types.begin() + i); return true; } @@ -129,15 +129,15 @@ bool Kitchen::setLimit(int32_t plant_id, int16_t limit) int i = findLimit(plant_id); if (i < 0) { - ui->kitchen.item_types.push_back(SEEDLIMIT_ITEMTYPE); - ui->kitchen.item_subtypes.push_back(SEEDLIMIT_ITEMSUBTYPE); - ui->kitchen.mat_types.push_back(limit); - ui->kitchen.mat_indices.push_back(plant_id); - ui->kitchen.exc_types.push_back(SEEDLIMIT_EXCTYPE); + plotinfo->kitchen.item_types.push_back(SEEDLIMIT_ITEMTYPE); + plotinfo->kitchen.item_subtypes.push_back(SEEDLIMIT_ITEMSUBTYPE); + plotinfo->kitchen.mat_types.push_back(limit); + plotinfo->kitchen.mat_indices.push_back(plant_id); + plotinfo->kitchen.exc_types.push_back(SEEDLIMIT_EXCTYPE); } else { - ui->kitchen.mat_types[i] = limit; + plotinfo->kitchen.mat_types[i] = limit; } return true; } @@ -146,11 +146,11 @@ void Kitchen::clearLimits() { for (size_t i = 0; i < size(); ++i) { - if (ui->kitchen.item_types[i] == SEEDLIMIT_ITEMTYPE && - ui->kitchen.item_subtypes[i] == SEEDLIMIT_ITEMSUBTYPE && - ui->kitchen.exc_types[i] == SEEDLIMIT_EXCTYPE) + if (plotinfo->kitchen.item_types[i] == SEEDLIMIT_ITEMTYPE && + plotinfo->kitchen.item_subtypes[i] == SEEDLIMIT_ITEMSUBTYPE && + plotinfo->kitchen.exc_types[i] == SEEDLIMIT_EXCTYPE) { - removeLimit(ui->kitchen.mat_indices[i]); + removeLimit(plotinfo->kitchen.mat_indices[i]); --i; } } @@ -158,7 +158,7 @@ void Kitchen::clearLimits() size_t Kitchen::size() { - return ui->kitchen.item_types.size(); + return plotinfo->kitchen.item_types.size(); } int Kitchen::findExclusion(df::kitchen_exc_type type, @@ -167,11 +167,11 @@ int Kitchen::findExclusion(df::kitchen_exc_type type, { for (size_t i = 0; i < size(); i++) { - if (ui->kitchen.item_types[i] == item_type && - ui->kitchen.item_subtypes[i] == item_subtype && - ui->kitchen.mat_types[i] == mat_type && - ui->kitchen.mat_indices[i] == mat_index && - ui->kitchen.exc_types[i] == type) + if (plotinfo->kitchen.item_types[i] == item_type && + plotinfo->kitchen.item_subtypes[i] == item_subtype && + plotinfo->kitchen.mat_types[i] == mat_type && + plotinfo->kitchen.mat_indices[i] == mat_index && + plotinfo->kitchen.exc_types[i] == type) { return int(i); } @@ -186,11 +186,11 @@ bool Kitchen::addExclusion(df::kitchen_exc_type type, if (findExclusion(type, item_type, item_subtype, mat_type, mat_index) >= 0) return false; - ui->kitchen.item_types.push_back(item_type); - ui->kitchen.item_subtypes.push_back(item_subtype); - ui->kitchen.mat_types.push_back(mat_type); - ui->kitchen.mat_indices.push_back(mat_index); - ui->kitchen.exc_types.push_back(type); + plotinfo->kitchen.item_types.push_back(item_type); + plotinfo->kitchen.item_subtypes.push_back(item_subtype); + plotinfo->kitchen.mat_types.push_back(mat_type); + plotinfo->kitchen.mat_indices.push_back(mat_index); + plotinfo->kitchen.exc_types.push_back(type); return true; } @@ -202,10 +202,10 @@ bool Kitchen::removeExclusion(df::kitchen_exc_type type, if (i < 0) return false; - ui->kitchen.item_types.erase(ui->kitchen.item_types.begin() + i); - ui->kitchen.item_subtypes.erase(ui->kitchen.item_subtypes.begin() + i); - ui->kitchen.mat_types.erase(ui->kitchen.mat_types.begin() + i); - ui->kitchen.mat_indices.erase(ui->kitchen.mat_indices.begin() + i); - ui->kitchen.exc_types.erase(ui->kitchen.exc_types.begin() + i); + plotinfo->kitchen.item_types.erase(plotinfo->kitchen.item_types.begin() + i); + plotinfo->kitchen.item_subtypes.erase(plotinfo->kitchen.item_subtypes.begin() + i); + plotinfo->kitchen.mat_types.erase(plotinfo->kitchen.mat_types.begin() + i); + plotinfo->kitchen.mat_indices.erase(plotinfo->kitchen.mat_indices.begin() + i); + plotinfo->kitchen.exc_types.erase(plotinfo->kitchen.exc_types.begin() + i); return true; } diff --git a/library/modules/Materials.cpp b/library/modules/Materials.cpp index a52579059..0854a85ce 100644 --- a/library/modules/Materials.cpp +++ b/library/modules/Materials.cpp @@ -42,7 +42,7 @@ using namespace std; #include "MiscUtils.h" #include "df/world.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/item.h" #include "df/creature_raw.h" #include "df/caste_raw.h" @@ -68,7 +68,7 @@ using namespace DFHack; using namespace df::enums; using df::global::world; -using df::global::ui; +using df::global::plotinfo; bool MaterialInfo::decode(df::item *item) { @@ -516,7 +516,7 @@ void MaterialInfo::getMatchBits(df::job_item_flags2 &ok, df::job_item_flags2 &ma TEST(fire_safe, material->heat.melting_point > 11000); TEST(magma_safe, material->heat.melting_point > 12000); TEST(deep_material, FLAG(inorganic, inorganic_flags::SPECIAL)); - TEST(non_economic, !inorganic || !(ui && vector_get(ui->economic_stone, index))); + TEST(non_economic, !inorganic || !(plotinfo && vector_get(plotinfo->economic_stone, index))); TEST(plant, plant); TEST(silk, MAT_FLAG(SILK)); diff --git a/library/modules/Renderer.cpp b/library/modules/Renderer.cpp index b746a149c..e134fa4f3 100644 --- a/library/modules/Renderer.cpp +++ b/library/modules/Renderer.cpp @@ -7,10 +7,9 @@ using df::global::enabler; using df::global::gps; using DFHack::Renderer::renderer_wrap; +/* static renderer_wrap *original_renderer = NULL; -const int32_t Renderer::GET_MOUSE_COORDS_SENTINEL = 0xcd1aa471; - bool init() { if (!original_renderer) @@ -156,3 +155,4 @@ bool Renderer::renderer_wrap::get_mouse_coords(int32_t* x, int32_t* y) { bool Renderer::renderer_wrap::uses_opengl() { return parent->uses_opengl(); }; +*/ diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp index 38611e5ce..65817aa93 100644 --- a/library/modules/Screen.cpp +++ b/library/modules/Screen.cpp @@ -34,6 +34,7 @@ using namespace std; #include "modules/Renderer.h" #include "modules/Screen.h" #include "modules/GuiHooks.h" +#include "Debug.h" #include "MemAccess.h" #include "VersionInfo.h" #include "Types.h" @@ -49,10 +50,11 @@ using namespace DFHack; #include "DataDefs.h" #include "df/init.h" -#include "df/texture_handler.h" -#include "df/tile_page.h" +#include "df/texture_handlerst.h" +#include "df/tile_pagest.h" #include "df/interfacest.h" #include "df/enabler.h" +#include "df/graphic_viewportst.h" #include "df/unit.h" #include "df/item.h" #include "df/job.h" @@ -72,30 +74,29 @@ using Screen::PenArray; using std::string; +namespace DFHack { + DBG_DECLARE(core, screen, DebugCategory::LINFO); +} + + /* * Screen painting API. */ -// returns text grid coordinates, even if the game map is scaled differently +// returns ui grid coordinates, even if the game map is scaled differently df::coord2d Screen::getMousePos() { - int32_t pixelx = 0, pixely = 0, tilex = 0, tiley = 0; - if (!enabler || !enabler->renderer->get_mouse_coords( - &pixelx, &pixely, &tilex, &tiley)) { + if (!gps) return df::coord2d(-1, -1); - } - return df::coord2d(tilex, tiley); + return df::coord2d(gps->mouse_x, gps->mouse_y); } // returns the screen pixel coordinates df::coord2d Screen::getMousePixels() { - int32_t pixelx = 0, pixely = 0, tilex = 0, tiley = 0; - if (!enabler || !enabler->renderer->get_mouse_coords( - &pixelx, &pixely, &tilex, &tiley)) { + if (!gps) return df::coord2d(-1, -1); - } - return df::coord2d(pixelx, pixely); + return df::coord2d(gps->precise_mouse_x, gps->precise_mouse_y); } df::coord2d Screen::getWindowSize() @@ -114,25 +115,88 @@ bool Screen::inGraphicsMode() return init && init->display.flag.is_set(init_display_flags::USE_GRAPHICS); } +static bool doSetTile_map(const Pen &pen, int x, int y) { + size_t max_index = gps->main_viewport->dim_x * gps->main_viewport->dim_y - 1; + size_t index = (x * gps->main_viewport->dim_y) + y; + + if (index < 0 || index > max_index) + return false; + + long texpos = pen.tile; + if (texpos == 0) { + texpos = init->font.large_font_texpos[(uint8_t)pen.ch]; + } + gps->main_viewport->screentexpos_interface[index] = texpos; + return true; +} + static bool doSetTile_default(const Pen &pen, int x, int y, bool map) { - auto dim = Screen::getWindowSize(); - if (x < 0 || x >= dim.x || y < 0 || y >= dim.y) + bool use_graphics = Screen::inGraphicsMode(); + + if (map && use_graphics) + return doSetTile_map(pen, x, y); + + size_t index = (x * gps->dimy) + y; + uint8_t *screen = &gps->screen[index * 8]; + + if (screen > gps->screen_limit) return false; -/* TODO: understand how this changes for v50 - int index = ((x * gps->dimy) + y); - auto screen = gps->screen + index*4; - screen[0] = uint8_t(pen.ch); - screen[1] = uint8_t(pen.fg) & 15; - screen[2] = uint8_t(pen.bg) & 15; - screen[3] = uint8_t(pen.bold) & 1; - gps->screentexpos[index] = pen.tile; - gps->screentexpos_addcolor[index] = (pen.tile_mode == Screen::Pen::CharColor); - gps->screentexpos_grayscale[index] = (pen.tile_mode == Screen::Pen::TileColor); - gps->screentexpos_cf[index] = pen.tile_fg; - gps->screentexpos_cbr[index] = pen.tile_bg; -*/ + long *texpos = &gps->screentexpos[index]; + long *texpos_lower = &gps->screentexpos_lower[index]; + uint32_t *flag = &gps->screentexpos_flag[index]; + + *screen = 0; + *texpos = 0; + *texpos_lower = 0; + gps->screentexpos_anchored[index] = 0; + // keep SCREENTEXPOS_FLAG_ANCHOR_SUBORDINATE so occluded anchored textures + // don't appear corrupted + *flag &= 4; + + if (gps->top_in_use) { + screen = &gps->screen_top[index * 8]; + texpos = &gps->screentexpos_top[index]; + texpos_lower = &gps->screentexpos_top_lower[index]; + flag = &gps->screentexpos_top_flag[index]; + + *screen = 0; + *texpos = 0; + *texpos_lower = 0; + gps->screentexpos_top_anchored[index] = 0; + *flag &= 4; // keep SCREENTEXPOS_FLAG_ANCHOR_SUBORDINATE + } + + uint8_t fg = pen.fg | (pen.bold << 3); + uint8_t bg = pen.bg; + + if (pen.tile_mode == Screen::Pen::CharColor) + *flag |= 2; // SCREENTEXPOS_FLAG_ADDCOLOR + else if (pen.tile_mode == Screen::Pen::TileColor) { + *flag |= 1; // SCREENTEXPOS_FLAG_GRAYSCALE + if (pen.tile_fg) + fg = pen.tile_fg; + if (pen.tile_bg) + bg = pen.tile_bg; + } + + if (pen.tile && use_graphics) { + *texpos = pen.tile; + } else { + screen[0] = uint8_t(pen.ch); + *texpos_lower = 909; + } + + auto rgb_fg = &gps->uccolor[fg][0]; + auto rgb_bg = &gps->uccolor[bg][0]; + screen[1] = rgb_fg[0]; + screen[2] = rgb_fg[1]; + screen[3] = rgb_fg[2]; + screen[4] = rgb_bg[0]; + screen[5] = rgb_bg[1]; + screen[6] = rgb_bg[2]; + return true; } @@ -150,39 +214,83 @@ bool Screen::paintTile(const Pen &pen, int x, int y, bool map) return true; } -static Pen doGetTile_default(int x, int y, bool map) -{ - auto dim = Screen::getWindowSize(); - if (x < 0 || x >= dim.x || y < 0 || y >= dim.y) - return Pen(0,0,0,-1); +static Pen doGetTile_map(int x, int y) { + size_t max_index = gps->main_viewport->dim_x * gps->main_viewport->dim_y - 1; + size_t index = (x * gps->main_viewport->dim_y) + y; -/* TODO: understand how this changes for v50 - int index = x*dim.y + y; - auto screen = gps->screen + index*4; - if (screen[3] & 0x80) - return Pen(0,0,0,-1); + if (index < 0 || index > max_index) + return Pen(0, 0, 0, -1); - Pen pen( - screen[0], screen[1], screen[2], screen[3]?true:false, - gps->screentexpos[index] - ); + int tile = gps->main_viewport->screentexpos[index]; + if (tile == 0) + tile = gps->main_viewport->screentexpos_item[index]; + if (tile == 0) + tile = gps->main_viewport->screentexpos_building_one[index]; + if (tile == 0) + tile = gps->main_viewport->screentexpos_background_two[index]; + if (tile == 0) + tile = gps->main_viewport->screentexpos_background[index]; - if (pen.tile) - { - if (gps->screentexpos_grayscale[index]) - { - pen.tile_mode = Screen::Pen::TileColor; - pen.tile_fg = gps->screentexpos_cf[index]; - pen.tile_bg = gps->screentexpos_cbr[index]; - } - else if (gps->screentexpos_addcolor[index]) - { - pen.tile_mode = Screen::Pen::CharColor; + char ch = 0; + uint8_t fg = 0; + uint8_t bg = 0; + return Pen(ch, fg, bg, tile, false); +} + +static uint8_t to_16_bit_color(uint8_t *rgb) { + for (uint8_t c = 0; c < 16; ++c) { + if (rgb[0] == gps->uccolor[c][0] && + rgb[1] == gps->uccolor[c][1] && + rgb[2] == gps->uccolor[c][2]) { + return c; } } + return 0; +} + +static Pen doGetTile_default(int x, int y, bool map) { + if (x < 0 || y < 0) + return Pen(0, 0, 0, -1); + + bool use_graphics = Screen::inGraphicsMode(); - return pen; -*/ return Pen(0,0,0,-1); + if (map && use_graphics) + return doGetTile_map(x, y); + + size_t index = (x * gps->dimy) + y; + uint8_t *screen = &gps->screen[index * 8]; + + if (screen > gps->screen_limit) + return Pen(0, 0, 0, -1); + + long *texpos = &gps->screentexpos[index]; + uint32_t *flag = &gps->screentexpos_flag[index]; + + if (gps->top_in_use && + (gps->screen_top[index * 8] || + (use_graphics && gps->screentexpos_top[index]))) { + screen = &gps->screen_top[index * 8]; + texpos = &gps->screentexpos_top[index]; + flag = &gps->screentexpos_top_flag[index]; + } + + char ch = *screen; + uint8_t fg = to_16_bit_color(&screen[1]); + uint8_t bg = to_16_bit_color(&screen[4]); + int tile = 0; + if (use_graphics) + tile = *texpos; + + if (*flag & 1) { + // TileColor + return Pen(ch, fg&7, bg, !!(fg&8), tile, fg, bg); + } else if (*flag & 2) { + // CharColor + return Pen(ch, fg, bg, tile, true); + } + + // AsIs + return Pen(ch, fg, bg, tile, false); } GUI_HOOK_DEFINE(Screen::Hooks::get_tile, doGetTile_default); @@ -394,6 +502,10 @@ bool Screen::hasActiveScreens(Plugin *plugin) return false; } +void Screen::raise(df::viewscreen *screen) { + Hide swapper(screen, Screen::Hide::RESTORE_AT_TOP); +} + namespace DFHack { namespace Screen { Hide::Hide(df::viewscreen* screen, int flags) : @@ -592,11 +704,13 @@ bool dfhack_viewscreen::key_conflict(df::interface_key key) if (key == interface_key::OPTIONS) return true; +/* TODO: understand how this changes for v50 if (text_input_mode) { if (key == interface_key::HELP || key == interface_key::MOVIES) return true; } +*/ return false; } diff --git a/library/modules/Textures.cpp b/library/modules/Textures.cpp new file mode 100644 index 000000000..70011b627 --- /dev/null +++ b/library/modules/Textures.cpp @@ -0,0 +1,148 @@ +#include "Internal.h" + +#include "modules/DFSDL.h" +#include "modules/Textures.h" + +#include "Debug.h" +#include "PluginManager.h" + +#include "df/enabler.h" + +using df::global::enabler; +using namespace DFHack; +using namespace DFHack::DFSDL; + +namespace DFHack { + DBG_DECLARE(core, textures, DebugCategory::LINFO); +} + +static bool g_loaded = false; +static long g_num_dfhack_textures = 0; +static long g_dfhack_logo_texpos_start = -1; + +// Converts an arbitrary Surface to something like the display format +// (32-bit RGBA), and converts magenta to transparency if convert_magenta is set +// and the source surface didn't already have an alpha channel. +// It also deletes the source surface. +// +// It uses the same pixel format (RGBA, R at lowest address) regardless of +// hardware. +DFSDL_Surface * canonicalize_format(DFSDL_Surface *src) { + DFSDL_PixelFormat fmt; + fmt.palette = NULL; + fmt.BitsPerPixel = 32; + fmt.BytesPerPixel = 4; + fmt.Rloss = fmt.Gloss = fmt.Bloss = fmt.Aloss = 0; +//#if SDL_BYTEORDER == SDL_BIG_ENDIAN +// fmt.Rshift = 24; fmt.Gshift = 16; fmt.Bshift = 8; fmt.Ashift = 0; +//#else + fmt.Rshift = 0; fmt.Gshift = 8; fmt.Bshift = 16; fmt.Ashift = 24; +//#endif + fmt.Rmask = 255 << fmt.Rshift; + fmt.Gmask = 255 << fmt.Gshift; + fmt.Bmask = 255 << fmt.Bshift; + fmt.Amask = 255 << fmt.Ashift; + fmt.colorkey = 0; + fmt.alpha = 255; + + DFSDL_Surface *tgt = DFSDL_ConvertSurface(src, &fmt, 0); // SDL_SWSURFACE + DFSDL_FreeSurface(src); + return tgt; +} + +const uint32_t TILE_WIDTH_PX = 8; +const uint32_t TILE_HEIGHT_PX = 12; + +static size_t load_textures(color_ostream & out, const char * fname, + long *texpos_start) { + DFSDL_Surface *s = DFIMG_Load(fname); + if (!s) { + out.printerr("unable to load textures from '%s'\n", fname); + return 0; + } + + s = canonicalize_format(s); + DFSDL_SetAlpha(s, 0, 255); + int dimx = s->w / TILE_WIDTH_PX; + int dimy = s->h / TILE_HEIGHT_PX; + long count = 0; + for (int y = 0; y < dimy; y++) { + for (int x = 0; x < dimx; x++) { + DFSDL_Surface *tile = DFSDL_CreateRGBSurface(0, // SDL_SWSURFACE + TILE_WIDTH_PX, TILE_HEIGHT_PX, 32, + s->format->Rmask, s->format->Gmask, s->format->Bmask, + s->format->Amask); + DFSDL_SetAlpha(tile, 0,255); + DFSDL_Rect vp; + vp.x = TILE_WIDTH_PX * x; + vp.y = TILE_HEIGHT_PX * y; + vp.w = TILE_WIDTH_PX; + vp.h = TILE_HEIGHT_PX; + DFSDL_UpperBlit(s, &vp, tile, NULL); + if (!count++) + *texpos_start = enabler->textures.raws.size(); + enabler->textures.raws.push_back(tile); + } + } + DFSDL_FreeSurface(s); + + DEBUG(textures,out).print("loaded %ld textures from '%s'\n", count, fname); + return count; +} + +// DFHack could conceivably be loaded at any time, so we need to be able to +// handle loading textures before or after a world is loaded. +// If a world is already loaded, then append our textures to the raws. they'll +// be freed when the world is unloaded and we'll reload when we get to the title +// screen. If it's pre-world, append our textures and then adjust the "init" +// texture count so our textures will no longer be freed when worlds are +// unloaded. +// +void Textures::init(color_ostream &out) { + auto & textures = enabler->textures; + long num_textures = textures.raws.size(); + if (num_textures <= g_dfhack_logo_texpos_start) + g_loaded = false; + + if (g_loaded) + return; + + bool is_pre_world = num_textures == textures.init_texture_size; + + g_num_dfhack_textures = load_textures(out, "hack/data/art/dfhack.png", + &g_dfhack_logo_texpos_start); + + DEBUG(textures,out).print("loaded %ld textures\n", g_num_dfhack_textures); + + if (is_pre_world) + textures.init_texture_size += g_num_dfhack_textures; + + // NOTE: when GL modes are supported, we'll have to re-upload textures here + + g_loaded = true; +} + +// It's ok to leave NULLs in the raws list (according to usage in g_src) +void Textures::cleanup() { + if (!g_loaded) + return; + + auto & textures = enabler->textures; + auto &raws = textures.raws; + size_t texpos_end = g_dfhack_logo_texpos_start + g_num_dfhack_textures; + for (size_t idx = g_dfhack_logo_texpos_start; idx <= texpos_end; ++idx) { + DFSDL_FreeSurface((DFSDL_Surface *)raws[idx]); + raws[idx] = NULL; + } + + if (g_dfhack_logo_texpos_start == textures.init_texture_size - g_num_dfhack_textures) + textures.init_texture_size -= g_num_dfhack_textures; + + g_loaded = false; + g_num_dfhack_textures = 0; + g_dfhack_logo_texpos_start = -1; +} + +long Textures::getDfhackLogoTexposStart() { + return g_dfhack_logo_texpos_start; +} diff --git a/library/modules/Units.cpp b/library/modules/Units.cpp index 20badb1b5..6d5ec7fde 100644 --- a/library/modules/Units.cpp +++ b/library/modules/Units.cpp @@ -73,7 +73,7 @@ using namespace std; #include "df/nemesis_record.h" #include "df/squad.h" #include "df/tile_occupancy.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/unit_inventory_item.h" #include "df/unit_misc_trait.h" #include "df/unit_relationship_type.h" @@ -87,7 +87,7 @@ using namespace std; using namespace DFHack; using namespace df::enums; using df::global::world; -using df::global::ui; +using df::global::plotinfo; using df::global::gamemode; using df::global::gametype; @@ -178,7 +178,7 @@ bool Units::isFortControlled(df::unit *unit) unit->flags2.bits.resident) return false; - return unit->civ_id != -1 && unit->civ_id == ui->civ_id; + return unit->civ_id != -1 && unit->civ_id == plotinfo->civ_id; } // check if creature belongs to the player's civilization @@ -186,7 +186,7 @@ bool Units::isFortControlled(df::unit *unit) bool Units::isOwnCiv(df::unit* unit) { CHECK_NULL_POINTER(unit); - return unit->civ_id == ui->civ_id; + return unit->civ_id == plotinfo->civ_id; } // check if creature belongs to the player's group @@ -199,7 +199,7 @@ bool Units::isOwnGroup(df::unit* unit) for (size_t i = 0; i < histfig->entity_links.size(); i++) { auto link = histfig->entity_links[i]; - if (link->entity_id == ui->group_id && link->getType() == df::histfig_entity_link_type::MEMBER) + if (link->entity_id == plotinfo->group_id && link->getType() == df::histfig_entity_link_type::MEMBER) return true; } return false; @@ -210,7 +210,7 @@ bool Units::isOwnGroup(df::unit* unit) bool Units::isOwnRace(df::unit* unit) { CHECK_NULL_POINTER(unit); - return unit->race == ui->race_id; + return unit->race == plotinfo->race_id; } @@ -622,8 +622,8 @@ bool Units::isDwarf(df::unit *unit) { CHECK_NULL_POINTER(unit); - return unit->race == ui->race_id || - unit->enemy.normal_race == ui->race_id; + return unit->race == plotinfo->race_id || + unit->enemy.normal_race == plotinfo->race_id; } bool Units::isAnimal(df::unit* unit) { @@ -1301,7 +1301,7 @@ bool Units::setLaborValidity(df::unit_labor labor, bool isValid) return false; if (labor == df::unit_labor::NONE) return false; - df::historical_entity *entity = df::historical_entity::find(ui->civ_id); + df::historical_entity *entity = df::historical_entity::find(plotinfo->civ_id); if (!entity || !entity->entity_raw) return false; entity->entity_raw->jobs.permitted_labor[labor] = isValid; @@ -1704,7 +1704,7 @@ std::string Units::getCasteProfessionName(int race, int casteid, df::profession if (pid < (df::profession)0 || !is_valid_enum_item(pid)) return ""; - int16_t current_race = df::global::ui->race_id; + int16_t current_race = df::global::plotinfo->race_id; if (df::global::gamemode && *df::global::gamemode == df::game_mode::ADVENTURE) current_race = world->units.active[0]->race; bool use_race_prefix = (race >= 0 && race != current_race); diff --git a/library/xml b/library/xml index 617d6acc1..d026f34ed 160000 --- a/library/xml +++ b/library/xml @@ -1 +1 @@ -Subproject commit 617d6acc10d499f6b158d3f51776d84c689aac9e +Subproject commit d026f34ed1f7ab79aebb1c5bc8a36ee9b30bd13d diff --git a/plugins/.gitignore b/plugins/.gitignore new file mode 100644 index 000000000..5b0a52473 --- /dev/null +++ b/plugins/.gitignore @@ -0,0 +1 @@ +!buildingplan/ diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt index 3ad19efb4..319600439 100644 --- a/plugins/CMakeLists.txt +++ b/plugins/CMakeLists.txt @@ -2,12 +2,12 @@ include(Plugins.cmake) option(BUILD_STONESENSE "Build stonesense (needs a checkout first)." OFF) if(BUILD_STONESENSE) - add_subdirectory(stonesense) + #add_subdirectory(stonesense) endif() option(BUILD_ISOWORLD "Build isoworld (needs a checkout first)." OFF) if(BUILD_ISOWORLD) - add_subdirectory(isoworld) + #add_subdirectory(isoworld) if(UNIX) if(APPLE) # TODO: add an OSX runner script @@ -21,12 +21,12 @@ endif() option(BUILD_DEV_PLUGINS "Build developer plugins." OFF) if(BUILD_DEV_PLUGINS) - add_subdirectory(devel) + #add_subdirectory(devel) endif() option(BUILD_RUBY "Build ruby binding." ON) if(BUILD_RUBY) - add_subdirectory(ruby) + #add_subdirectory(ruby) endif() install(DIRECTORY lua/ @@ -75,111 +75,108 @@ add_custom_target(generate_proto DEPENDS ${PROJECT_PROTO_TMP_FILES}) set_source_files_properties( Brushes.h PROPERTIES HEADER_FILE_ONLY TRUE ) # Plugins -option(BUILD_SUPPORTED "Build the supported plugins (reveal, probe, etc.)." ON) -if(BUILD_SUPPORTED) - # If you are adding a plugin that you do not intend to commit to the DFHack repo, - # see instructions for adding "external" plugins at the end of this file. - - dfhack_plugin(3dveins 3dveins.cpp) - dfhack_plugin(add-spatter add-spatter.cpp) - dfhack_plugin(autobutcher autobutcher.cpp LINK_LIBRARIES lua) - dfhack_plugin(autochop autochop.cpp) - dfhack_plugin(autoclothing autoclothing.cpp) - dfhack_plugin(autodump autodump.cpp) - dfhack_plugin(autofarm autofarm.cpp) - dfhack_plugin(autogems autogems.cpp LINK_LIBRARIES jsoncpp_static) - add_subdirectory(autolabor) - dfhack_plugin(automaterial automaterial.cpp LINK_LIBRARIES lua) - dfhack_plugin(automelt automelt.cpp) - dfhack_plugin(autonestbox autonestbox.cpp LINK_LIBRARIES lua) - dfhack_plugin(autotrade autotrade.cpp) - dfhack_plugin(blueprint blueprint.cpp LINK_LIBRARIES lua) - dfhack_plugin(burrows burrows.cpp LINK_LIBRARIES lua) - dfhack_plugin(building-hacks building-hacks.cpp LINK_LIBRARIES lua) - add_subdirectory(buildingplan) - dfhack_plugin(changeitem changeitem.cpp) - dfhack_plugin(changelayer changelayer.cpp) - dfhack_plugin(changevein changevein.cpp) - add_subdirectory(channel-safely) - dfhack_plugin(cleanconst cleanconst.cpp) - dfhack_plugin(cleaners cleaners.cpp) - dfhack_plugin(cleanowned cleanowned.cpp) - dfhack_plugin(confirm confirm.cpp LINK_LIBRARIES lua) - dfhack_plugin(createitem createitem.cpp) - dfhack_plugin(cursecheck cursecheck.cpp) - dfhack_plugin(cxxrandom cxxrandom.cpp LINK_LIBRARIES lua) - dfhack_plugin(deramp deramp.cpp) - dfhack_plugin(debug debug.cpp LINK_LIBRARIES jsoncpp_static) - dfhack_plugin(dig dig.cpp) - dfhack_plugin(dig-now dig-now.cpp LINK_LIBRARIES lua) - dfhack_plugin(digFlood digFlood.cpp) - add_subdirectory(diggingInvaders) - dfhack_plugin(dwarfvet dwarfvet.cpp) - dfhack_plugin(dwarfmonitor dwarfmonitor.cpp LINK_LIBRARIES lua) - add_subdirectory(embark-assistant) - dfhack_plugin(embark-tools embark-tools.cpp) - dfhack_plugin(eventful eventful.cpp LINK_LIBRARIES lua) - dfhack_plugin(fastdwarf fastdwarf.cpp) - dfhack_plugin(filltraffic filltraffic.cpp) - dfhack_plugin(fix-unit-occupancy fix-unit-occupancy.cpp) - dfhack_plugin(fixveins fixveins.cpp) - dfhack_plugin(flows flows.cpp) - dfhack_plugin(follow follow.cpp) - dfhack_plugin(forceequip forceequip.cpp) - dfhack_plugin(generated-creature-renamer generated-creature-renamer.cpp) - dfhack_plugin(getplants getplants.cpp) - dfhack_plugin(hotkeys hotkeys.cpp LINK_LIBRARIES lua) - dfhack_plugin(infiniteSky infiniteSky.cpp) - dfhack_plugin(isoworldremote isoworldremote.cpp PROTOBUFS isoworldremote) - dfhack_plugin(jobutils jobutils.cpp) - dfhack_plugin(lair lair.cpp) - dfhack_plugin(liquids liquids.cpp Brushes.h LINK_LIBRARIES lua) - dfhack_plugin(luasocket luasocket.cpp LINK_LIBRARIES clsocket lua dfhack-tinythread) - dfhack_plugin(manipulator manipulator.cpp) - dfhack_plugin(map-render map-render.cpp LINK_LIBRARIES lua) - dfhack_plugin(misery misery.cpp) - dfhack_plugin(mode mode.cpp) - dfhack_plugin(mousequery mousequery.cpp) - dfhack_plugin(nestboxes nestboxes.cpp) - dfhack_plugin(orders orders.cpp LINK_LIBRARIES jsoncpp_static) - dfhack_plugin(overlay overlay.cpp LINK_LIBRARIES lua) - dfhack_plugin(pathable pathable.cpp LINK_LIBRARIES lua) - dfhack_plugin(petcapRemover petcapRemover.cpp) - dfhack_plugin(plants plants.cpp) - dfhack_plugin(probe probe.cpp) - dfhack_plugin(prospector prospector.cpp LINK_LIBRARIES lua) - dfhack_plugin(power-meter power-meter.cpp LINK_LIBRARIES lua) - dfhack_plugin(regrass regrass.cpp) - add_subdirectory(remotefortressreader) - dfhack_plugin(rename rename.cpp LINK_LIBRARIES lua PROTOBUFS rename) - add_subdirectory(rendermax) - dfhack_plugin(reveal reveal.cpp LINK_LIBRARIES lua) - dfhack_plugin(search search.cpp) - dfhack_plugin(seedwatch seedwatch.cpp) - dfhack_plugin(showmood showmood.cpp) - dfhack_plugin(siege-engine siege-engine.cpp LINK_LIBRARIES lua) - dfhack_plugin(sort sort.cpp LINK_LIBRARIES lua) - dfhack_plugin(steam-engine steam-engine.cpp) - add_subdirectory(spectate) - dfhack_plugin(stockflow stockflow.cpp LINK_LIBRARIES lua) - add_subdirectory(stockpiles) - dfhack_plugin(stocks stocks.cpp) - dfhack_plugin(strangemood strangemood.cpp) - dfhack_plugin(tailor tailor.cpp) - dfhack_plugin(tiletypes tiletypes.cpp Brushes.h LINK_LIBRARIES lua) - dfhack_plugin(title-folder title-folder.cpp) - dfhack_plugin(title-version title-version.cpp) - dfhack_plugin(trackstop trackstop.cpp) - dfhack_plugin(tubefill tubefill.cpp) - add_subdirectory(tweak) - dfhack_plugin(workflow workflow.cpp LINK_LIBRARIES lua) - dfhack_plugin(workNow workNow.cpp) - dfhack_plugin(xlsxreader xlsxreader.cpp LINK_LIBRARIES lua xlsxio_read_STATIC zip expat) - dfhack_plugin(zone zone.cpp) - - # If you are adding a plugin that you do not intend to commit to the DFHack repo, - # see instructions for adding "external" plugins at the end of this file. -endif() +# If you are adding a plugin that you do not intend to commit to the DFHack repo, +# see instructions for adding "external" plugins at the end of this file. + +#dfhack_plugin(3dveins 3dveins.cpp) +#dfhack_plugin(add-spatter add-spatter.cpp) +dfhack_plugin(autobutcher autobutcher.cpp LINK_LIBRARIES lua) +#dfhack_plugin(autochop autochop.cpp) +#dfhack_plugin(autoclothing autoclothing.cpp) +#dfhack_plugin(autodump autodump.cpp) +#dfhack_plugin(autofarm autofarm.cpp) +#dfhack_plugin(autogems autogems.cpp LINK_LIBRARIES jsoncpp_static) +#add_subdirectory(autolabor) +#dfhack_plugin(automaterial automaterial.cpp LINK_LIBRARIES lua) +#dfhack_plugin(automelt automelt.cpp) +#dfhack_plugin(autonestbox autonestbox.cpp LINK_LIBRARIES lua) +#dfhack_plugin(autotrade autotrade.cpp) +#dfhack_plugin(blueprint blueprint.cpp LINK_LIBRARIES lua) +#dfhack_plugin(burrows burrows.cpp LINK_LIBRARIES lua) +#dfhack_plugin(building-hacks building-hacks.cpp LINK_LIBRARIES lua) +#add_subdirectory(buildingplan) +#dfhack_plugin(changeitem changeitem.cpp) +#dfhack_plugin(changelayer changelayer.cpp) +#dfhack_plugin(changevein changevein.cpp) +#add_subdirectory(channel-safely) +#dfhack_plugin(cleanconst cleanconst.cpp) +#dfhack_plugin(cleaners cleaners.cpp) +#dfhack_plugin(cleanowned cleanowned.cpp) +#dfhack_plugin(confirm confirm.cpp LINK_LIBRARIES lua) +#dfhack_plugin(createitem createitem.cpp) +#dfhack_plugin(cursecheck cursecheck.cpp) +#dfhack_plugin(cxxrandom cxxrandom.cpp LINK_LIBRARIES lua) +#dfhack_plugin(deramp deramp.cpp) +dfhack_plugin(debug debug.cpp LINK_LIBRARIES jsoncpp_static) +#dfhack_plugin(dig dig.cpp) +#dfhack_plugin(dig-now dig-now.cpp LINK_LIBRARIES lua) +#dfhack_plugin(digFlood digFlood.cpp) +#add_subdirectory(diggingInvaders) +#dfhack_plugin(dwarfvet dwarfvet.cpp) +#dfhack_plugin(dwarfmonitor dwarfmonitor.cpp LINK_LIBRARIES lua) +#add_subdirectory(embark-assistant) +#dfhack_plugin(embark-tools embark-tools.cpp) +dfhack_plugin(eventful eventful.cpp LINK_LIBRARIES lua) +#dfhack_plugin(fastdwarf fastdwarf.cpp) +#dfhack_plugin(filltraffic filltraffic.cpp) +#dfhack_plugin(fix-unit-occupancy fix-unit-occupancy.cpp) +#dfhack_plugin(fixveins fixveins.cpp) +#dfhack_plugin(flows flows.cpp) +#dfhack_plugin(follow follow.cpp) +#dfhack_plugin(forceequip forceequip.cpp) +#dfhack_plugin(generated-creature-renamer generated-creature-renamer.cpp) +#dfhack_plugin(getplants getplants.cpp) +dfhack_plugin(hotkeys hotkeys.cpp LINK_LIBRARIES lua) +#dfhack_plugin(infiniteSky infiniteSky.cpp) +#dfhack_plugin(isoworldremote isoworldremote.cpp PROTOBUFS isoworldremote) +#dfhack_plugin(jobutils jobutils.cpp) +#dfhack_plugin(lair lair.cpp) +#dfhack_plugin(liquids liquids.cpp Brushes.h LINK_LIBRARIES lua) +#dfhack_plugin(luasocket luasocket.cpp LINK_LIBRARIES clsocket lua dfhack-tinythread) +#dfhack_plugin(manipulator manipulator.cpp) +#dfhack_plugin(map-render map-render.cpp LINK_LIBRARIES lua) +#dfhack_plugin(misery misery.cpp) +#dfhack_plugin(mode mode.cpp) +#dfhack_plugin(mousequery mousequery.cpp) +#dfhack_plugin(nestboxes nestboxes.cpp) +#dfhack_plugin(orders orders.cpp LINK_LIBRARIES jsoncpp_static) +dfhack_plugin(overlay overlay.cpp LINK_LIBRARIES lua) +dfhack_plugin(pathable pathable.cpp LINK_LIBRARIES lua) +#dfhack_plugin(petcapRemover petcapRemover.cpp) +#dfhack_plugin(plants plants.cpp) +#dfhack_plugin(probe probe.cpp) +#dfhack_plugin(prospector prospector.cpp LINK_LIBRARIES lua) +#dfhack_plugin(power-meter power-meter.cpp LINK_LIBRARIES lua) +#dfhack_plugin(regrass regrass.cpp) +#add_subdirectory(remotefortressreader) +#dfhack_plugin(rename rename.cpp LINK_LIBRARIES lua PROTOBUFS rename) +#add_subdirectory(rendermax) +dfhack_plugin(reveal reveal.cpp LINK_LIBRARIES lua) +#dfhack_plugin(search search.cpp) +#dfhack_plugin(seedwatch seedwatch.cpp) +#dfhack_plugin(showmood showmood.cpp) +#dfhack_plugin(siege-engine siege-engine.cpp LINK_LIBRARIES lua) +#dfhack_plugin(sort sort.cpp LINK_LIBRARIES lua) +#dfhack_plugin(steam-engine steam-engine.cpp) +#add_subdirectory(spectate) +#dfhack_plugin(stockflow stockflow.cpp LINK_LIBRARIES lua) +#add_subdirectory(stockpiles) +#dfhack_plugin(stocks stocks.cpp) +#dfhack_plugin(strangemood strangemood.cpp) +#dfhack_plugin(tailor tailor.cpp) +#dfhack_plugin(tiletypes tiletypes.cpp Brushes.h LINK_LIBRARIES lua) +#dfhack_plugin(title-folder title-folder.cpp) +#dfhack_plugin(title-version title-version.cpp) +#dfhack_plugin(trackstop trackstop.cpp) +#dfhack_plugin(tubefill tubefill.cpp) +#add_subdirectory(tweak) +#dfhack_plugin(workflow workflow.cpp LINK_LIBRARIES lua) +#dfhack_plugin(workNow workNow.cpp) +#dfhack_plugin(xlsxreader xlsxreader.cpp LINK_LIBRARIES lua xlsxio_read_STATIC zip expat) +#dfhack_plugin(zone zone.cpp) + +# If you are adding a plugin that you do not intend to commit to the DFHack repo, +# see instructions for adding "external" plugins at the end of this file. # this is the skeleton plugin. If you want to make your own, make a copy and then change it option(BUILD_SKELETON "Build the skeleton plugin." OFF) diff --git a/plugins/add-spatter.cpp b/plugins/add-spatter.cpp index 459e28f25..451fffabf 100644 --- a/plugins/add-spatter.cpp +++ b/plugins/add-spatter.cpp @@ -24,7 +24,7 @@ #include "df/job.h" #include "df/job_item.h" #include "df/job_item_ref.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/report.h" #include "df/reaction.h" #include "df/reaction_reagent_itemst.h" @@ -45,7 +45,7 @@ DFHACK_PLUGIN("add-spatter"); DFHACK_PLUGIN_IS_ENABLED(is_enabled); REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); typedef df::reaction_product_item_improvementst improvement_product; diff --git a/plugins/autobutcher.cpp b/plugins/autobutcher.cpp index 81ec0c5df..d75108f3f 100644 --- a/plugins/autobutcher.cpp +++ b/plugins/autobutcher.cpp @@ -712,13 +712,20 @@ static bool hasValidMapPos(df::unit *unit) { && unit->pos.z < world->map.z_count; } -// built cage defined as room (supposed to detect zoo cages) +// built cage in a zone (supposed to detect zoo cages) static bool isInBuiltCageRoom(df::unit *unit) { for (auto building : world->buildings.all) { - // !!! building->isRoom() returns true if the building can be made a room but currently isn't - // !!! except for coffins/tombs which always return false - // !!! using the bool is_room however gives the correct state/value - if (!building->is_room || building->getType() != df::building_type::Cage) + if (building->getType() != df::building_type::Cage) + continue; + + bool in_zone = false; + for (auto relation : building->relations) { + if (relation->getType() == df::building_type::Civzone) { + in_zone = true; + break; + } + } + if (!in_zone) continue; df::building_cagest* cage = (df::building_cagest*)building; diff --git a/plugins/autochop.cpp b/plugins/autochop.cpp index acb8959b9..415a6d322 100644 --- a/plugins/autochop.cpp +++ b/plugins/autochop.cpp @@ -22,7 +22,7 @@ #include "df/plant_tree_tile.h" #include "df/plant_raw.h" #include "df/tile_dig_designation.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/viewscreen_dwarfmodest.h" #include "df/world.h" @@ -45,7 +45,7 @@ using namespace df::enums; #define PLUGIN_VERSION 0.3 DFHACK_PLUGIN("autochop"); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); static int get_log_count(); @@ -499,7 +499,7 @@ public: burrows_column.clear(); - for (df::burrow *burrow : ui->burrows.list) + for (df::burrow *burrow : plotinfo->burrows.list) { string name = burrow->name; if (name.empty()) @@ -820,7 +820,7 @@ struct autochop_hook : public df::viewscreen_dwarfmodest bool isInDesignationMenu() { using namespace df::enums::ui_sidebar_mode; - return (ui->main.mode == DesignateChopTrees); + return (plotinfo->main.mode == DesignateChopTrees); } void sendKey(const df::interface_key &key) diff --git a/plugins/autofarm.cpp b/plugins/autofarm.cpp index 2f8762425..6a4078b56 100644 --- a/plugins/autofarm.cpp +++ b/plugins/autofarm.cpp @@ -5,7 +5,7 @@ #include "DataDefs.h" #include "df/world.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/building_type.h" #include "df/building_farmplotst.h" #include "df/buildings_other_id.h" @@ -30,7 +30,7 @@ using namespace DFHack; using namespace df::enums; using df::global::world; -using df::global::ui; +using df::global::plotinfo; static command_result autofarm(color_ostream& out, std::vector& parameters); @@ -348,7 +348,7 @@ static std::unique_ptr autofarmInstance; DFhackCExport command_result plugin_init(color_ostream& out, std::vector & commands) { - if (world && ui) { + if (world && plotinfo) { commands.push_back( PluginCommand("autofarm", "Automatically manage farm crop selection.", diff --git a/plugins/autogems.cpp b/plugins/autogems.cpp index d296caf7f..8cf419aba 100644 --- a/plugins/autogems.cpp +++ b/plugins/autogems.cpp @@ -33,7 +33,7 @@ using namespace DFHack; DFHACK_PLUGIN("autogems"); DFHACK_PLUGIN_IS_ENABLED(enabled); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(world); typedef int32_t item_id; @@ -242,7 +242,7 @@ struct autogem_hook : public df::viewscreen_dwarfmodest { bool in_menu() { // Determines whether we're looking at the Workshop Orders screen. - return ui->main.mode == ui_sidebar_mode::OrdersWorkshop; + return plotinfo->main.mode == ui_sidebar_mode::OrdersWorkshop; } bool handleInput(std::set *input) { diff --git a/plugins/autolabor/autohauler.cpp b/plugins/autolabor/autohauler.cpp index e7c2530e1..3bb2534f8 100644 --- a/plugins/autolabor/autohauler.cpp +++ b/plugins/autolabor/autohauler.cpp @@ -12,7 +12,7 @@ // DF data structure definition headers #include "DataDefs.h" -#include +#include #include #include #include @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include @@ -47,7 +47,7 @@ using namespace DFHack; using namespace df::enums; DFHACK_PLUGIN("autohauler"); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(world); #define ARRAY_COUNT(array) (sizeof(array)/sizeof((array)[0])) diff --git a/plugins/autolabor/autolabor.cpp b/plugins/autolabor/autolabor.cpp index 76108ddd0..0af4be5e2 100644 --- a/plugins/autolabor/autolabor.cpp +++ b/plugins/autolabor/autolabor.cpp @@ -12,7 +12,7 @@ // DF data structure definition headers #include "DataDefs.h" -#include +#include #include #include #include @@ -32,7 +32,7 @@ #include #include #include -#include +#include #include #include @@ -47,7 +47,7 @@ using namespace DFHack; using namespace df::enums; DFHACK_PLUGIN("autolabor"); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(world); #define ARRAY_COUNT(array) (sizeof(array)/sizeof((array)[0])) @@ -813,7 +813,7 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) // identify dwarfs who are needed for meetings and mark them for exclusion - for (auto& act : ui->activities) + for (auto& act : plotinfo->activities) { if (!act) continue; bool p1 = act->unit_actor == dwarfs[dwarf]; diff --git a/plugins/autolabor/joblabormapper.cpp b/plugins/autolabor/joblabormapper.cpp index 2917b8d3a..690e80881 100644 --- a/plugins/autolabor/joblabormapper.cpp +++ b/plugins/autolabor/joblabormapper.cpp @@ -56,7 +56,7 @@ using std::string; using std::endl; using namespace DFHack; using namespace df::enums; -using df::global::ui; +using df::global::plotinfo; using df::global::world; #include "labormanager.h" diff --git a/plugins/autolabor/labormanager.cpp b/plugins/autolabor/labormanager.cpp index 44817e405..4b43b09c1 100644 --- a/plugins/autolabor/labormanager.cpp +++ b/plugins/autolabor/labormanager.cpp @@ -25,7 +25,7 @@ #include "DataDefs.h" #include -#include +#include #include #include #include @@ -46,7 +46,7 @@ #include #include #include -#include +#include #include #include #include @@ -64,7 +64,7 @@ #include #include #include -#include +#include #include #include #include @@ -82,7 +82,7 @@ using std::string; using std::endl; using namespace DFHack; using namespace df::enums; -using df::global::ui; +using df::global::plotinfo; using df::global::world; #define ARRAY_COUNT(array) (sizeof(array)/sizeof((array)[0])) @@ -948,9 +948,9 @@ private: // identify dwarfs who are needed for meetings and mark them for exclusion - for (size_t i = 0; i < ui->activities.size(); ++i) + for (size_t i = 0; i < plotinfo->activities.size(); ++i) { - df::activity_info *act = ui->activities[i]; + df::activity_info *act = plotinfo->activities[i]; if (!act) continue; bool p1 = act->unit_actor == dwarf->dwarf; @@ -996,11 +996,11 @@ private: for (size_t j = 0; j < dwarf->dwarf->inventory.size(); j++) { - df::unit_inventory_item* ui = dwarf->dwarf->inventory[j]; - if (ui->mode == df::unit_inventory_item::Weapon && ui->item->isWeapon()) + df::unit_inventory_item* plotinfo = dwarf->dwarf->inventory[j]; + if (plotinfo->mode == df::unit_inventory_item::Weapon && plotinfo->item->isWeapon()) { dwarf->armed = true; - df::itemdef_weaponst* weapondef = ((df::item_weaponst*)(ui->item))->subtype; + df::itemdef_weaponst* weapondef = ((df::item_weaponst*)(plotinfo->item))->subtype; df::job_skill weaponsk = (df::job_skill) weapondef->skill_melee; df::job_skill rangesk = (df::job_skill) weapondef->skill_ranged; if (weaponsk == df::job_skill::AXE) @@ -1408,8 +1408,8 @@ public: (isOptionEnabled(CF_ALLOW_HUNTING) && has_butchers) ? 1 : 0; /* add animal trainers */ - for (auto a = df::global::ui->equipment.training_assignments.begin(); - a != df::global::ui->equipment.training_assignments.end(); + for (auto a = df::global::plotinfo->equipment.training_assignments.begin(); + a != df::global::plotinfo->equipment.training_assignments.end(); a++) { labor_needed[df::unit_labor::ANIMALTRAIN]++; diff --git a/plugins/automaterial.cpp b/plugins/automaterial.cpp index 24f2d8e2a..9783d28dc 100644 --- a/plugins/automaterial.cpp +++ b/plugins/automaterial.cpp @@ -21,8 +21,8 @@ #include "df/build_req_choice_specst.h" #include "df/construction_type.h" #include "df/item.h" -#include "df/ui.h" -#include "df/ui_build_selector.h" +#include "df/plotinfost.h" +#include "df/buildreq.h" #include "df/viewscreen_dwarfmodest.h" #include "df/items_other_id.h" #include "df/job.h" @@ -50,7 +50,7 @@ using namespace df::enums; DFHACK_PLUGIN("automaterial"); REQUIRE_GLOBAL(gps); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(ui_build_selector); namespace DFHack { @@ -115,14 +115,14 @@ static inline bool in_material_choice_stage() { return Gui::build_selector_hotkey(Core::getTopViewscreen()) && ui_build_selector->building_type == df::building_type::Construction && - ui->main.mode == ui_sidebar_mode::Build && + plotinfo->main.mode == ui_sidebar_mode::Build && ui_build_selector->stage == 2; } static inline bool in_placement_stage() { return Gui::dwarfmode_hotkey(Core::getTopViewscreen()) && - ui->main.mode == ui_sidebar_mode::Build && + plotinfo->main.mode == ui_sidebar_mode::Build && ui_build_selector && ui_build_selector->building_type == df::building_type::Construction && ui_build_selector->stage == 1; @@ -131,7 +131,7 @@ static inline bool in_placement_stage() static inline bool in_type_choice_stage() { return Gui::dwarfmode_hotkey(Core::getTopViewscreen()) && - ui->main.mode == ui_sidebar_mode::Build && + plotinfo->main.mode == ui_sidebar_mode::Build && ui_build_selector && ui_build_selector->building_type < 0; } @@ -713,7 +713,7 @@ struct jobutils_hook : public df::viewscreen_dwarfmodest if (!box_select_enabled) return; - if (ui->main.mode != df::ui_sidebar_mode::Build || + if (plotinfo->main.mode != df::ui_sidebar_mode::Build || ui_build_selector->building_type != df::building_type::Construction) return; diff --git a/plugins/automelt.cpp b/plugins/automelt.cpp index 4bbb727d7..9ca20e9ea 100644 --- a/plugins/automelt.cpp +++ b/plugins/automelt.cpp @@ -9,7 +9,7 @@ #include "df/building_stockpilest.h" #include "modules/Buildings.h" #include "modules/Items.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "modules/Maps.h" #include "modules/World.h" #include "df/item_quality.h" @@ -21,7 +21,7 @@ DFHACK_PLUGIN("automelt"); REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(world); REQUIRE_GLOBAL(cursor); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); static const string PERSISTENCE_KEY = "automelt/stockpiles"; diff --git a/plugins/autotrade.cpp b/plugins/autotrade.cpp index 623fd5c1e..333e34e95 100644 --- a/plugins/autotrade.cpp +++ b/plugins/autotrade.cpp @@ -15,7 +15,7 @@ #include "df/job.h" #include "df/job_item_ref.h" #include "modules/Job.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/mandate.h" #include "modules/Maps.h" @@ -25,7 +25,7 @@ DFHACK_PLUGIN("autotrade"); REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(world); REQUIRE_GLOBAL(cursor); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); static const string PERSISTENCE_KEY = "autotrade/stockpiles"; diff --git a/plugins/buildingplan/buildingplan-planner.cpp b/plugins/buildingplan/buildingplan-planner.cpp index 4ac11c4e1..07f23150a 100644 --- a/plugins/buildingplan/buildingplan-planner.cpp +++ b/plugins/buildingplan/buildingplan-planner.cpp @@ -6,7 +6,7 @@ #include "df/building_type.h" #include "df/general_ref_building_holderst.h" #include "df/job_item.h" -#include "df/ui_build_selector.h" +#include "df/buildreq.h" #include "modules/Buildings.h" #include "modules/Gui.h" diff --git a/plugins/buildingplan/buildingplan.cpp b/plugins/buildingplan/buildingplan.cpp index e0bc6dd69..cd4e84a6e 100644 --- a/plugins/buildingplan/buildingplan.cpp +++ b/plugins/buildingplan/buildingplan.cpp @@ -1,7 +1,7 @@ #include "df/construction_type.h" #include "df/entity_position.h" #include "df/interface_key.h" -#include "df/ui_build_selector.h" +#include "df/buildreq.h" #include "df/viewscreen_dwarfmodest.h" #include "modules/Gui.h" @@ -18,7 +18,7 @@ DFHACK_PLUGIN("buildingplan"); #define PLUGIN_VERSION "2.0" -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(ui_build_selector); REQUIRE_GLOBAL(world); // used in buildingplan library @@ -455,8 +455,8 @@ struct buildingplan_query_hook : public df::viewscreen_dwarfmodest bool isInPlannedBuildingQueryMode() { - return (ui->main.mode == df::ui_sidebar_mode::QueryBuilding || - ui->main.mode == df::ui_sidebar_mode::BuildingItems) && + return (plotinfo->main.mode == df::ui_sidebar_mode::QueryBuilding || + plotinfo->main.mode == df::ui_sidebar_mode::BuildingItems) && planner.getPlannedBuilding(world->selected_building); } @@ -595,7 +595,7 @@ struct buildingplan_place_hook : public df::viewscreen_dwarfmodest bool isInPlannedBuildingPlacementMode() { - return ui->main.mode == ui_sidebar_mode::Build && + return plotinfo->main.mode == ui_sidebar_mode::Build && df::global::ui_build_selector && df::global::ui_build_selector->stage < 2 && planner.isPlannableBuilding(toBuildingTypeKey(ui_build_selector)); @@ -861,7 +861,7 @@ struct buildingplan_room_hook : public df::viewscreen_dwarfmodest std::vector getNoblePositionOfSelectedBuildingOwner() { std::vector np; - if (ui->main.mode != df::ui_sidebar_mode::QueryBuilding || + if (plotinfo->main.mode != df::ui_sidebar_mode::QueryBuilding || !world->selected_building || !world->selected_building->owner) { @@ -1084,7 +1084,7 @@ DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_chan static bool is_paused() { return World::ReadPauseState() || - ui->main.mode > df::ui_sidebar_mode::Squads || + plotinfo->main.mode > df::ui_sidebar_mode::Squads || !strict_virtual_cast(Gui::getCurViewscreen(true)); } diff --git a/plugins/burrows.cpp b/plugins/burrows.cpp index 029b3c715..c39253488 100644 --- a/plugins/burrows.cpp +++ b/plugins/burrows.cpp @@ -17,7 +17,7 @@ #include "TileTypes.h" #include "DataDefs.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/world.h" #include "df/unit.h" #include "df/burrow.h" @@ -38,7 +38,7 @@ using namespace df::enums; using namespace dfproto; DFHACK_PLUGIN("burrows"); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(world); REQUIRE_GLOBAL(gamemode); @@ -102,11 +102,11 @@ DEFINE_LUA_EVENT_1(onBurrowRename, handle_burrow_rename, df::burrow*); static void detect_burrow_renames(color_ostream &out) { - if (ui->main.mode == ui_sidebar_mode::Burrows && - ui->burrows.in_edit_name_mode && - ui->burrows.sel_id >= 0) + if (plotinfo->main.mode == ui_sidebar_mode::Burrows && + plotinfo->burrows.in_edit_name_mode && + plotinfo->burrows.sel_id >= 0) { - name_burrow_id = ui->burrows.sel_id; + name_burrow_id = plotinfo->burrows.sel_id; } else if (name_burrow_id >= 0) { @@ -222,7 +222,7 @@ static std::map name_lookup; static void parse_names() { - auto &list = ui->burrows.list; + auto &list = plotinfo->burrows.list; grow_burrows.clear(); name_lookup.clear(); diff --git a/plugins/confirm.cpp b/plugins/confirm.cpp index 5cef6376f..499d3f08f 100644 --- a/plugins/confirm.cpp +++ b/plugins/confirm.cpp @@ -36,7 +36,7 @@ using std::vector; DFHACK_PLUGIN("confirm"); DFHACK_PLUGIN_IS_ENABLED(is_enabled); REQUIRE_GLOBAL(gps); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); typedef std::set ikey_set; command_result df_confirm (color_ostream &out, vector & parameters); diff --git a/plugins/createitem.cpp b/plugins/createitem.cpp index 57dbf7244..499814adc 100644 --- a/plugins/createitem.cpp +++ b/plugins/createitem.cpp @@ -16,7 +16,7 @@ #include "DataDefs.h" #include "df/game_type.h" #include "df/world.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/unit.h" #include "df/historical_entity.h" #include "df/world_site.h" @@ -38,7 +38,7 @@ using namespace df::enums; DFHACK_PLUGIN("createitem"); REQUIRE_GLOBAL(cursor); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(gametype); REQUIRE_GLOBAL(cur_year_tick); @@ -78,7 +78,7 @@ bool makeItem (df::reaction_product_itemst *prod, df::unit *unit, bool second_it prod->produce(unit, &out_products, &out_items, &in_reag, &in_items, 1, job_skill::NONE, 0, df::historical_entity::find(unit->civ_id), - (World::isFortressMode()) ? df::world_site::find(ui->site_id) : NULL, NULL); + (World::isFortressMode()) ? df::world_site::find(plotinfo->site_id) : NULL, NULL); if (!out_items.size()) return false; // if we asked to make shoes and we got twice as many as we asked, then we're okay diff --git a/plugins/debug.cpp b/plugins/debug.cpp index f4a22b8d1..a48fd2a05 100644 --- a/plugins/debug.cpp +++ b/plugins/debug.cpp @@ -43,7 +43,7 @@ namespace DFHack { DBG_DECLARE(debug,filter); DBG_DECLARE(debug,init); DBG_DECLARE(debug,command); -DBG_DECLARE(debug,ui); +DBG_DECLARE(debug,plotinfo); DBG_DECLARE(debug,example,DebugCategory::LINFO); } diff --git a/plugins/devel/kittens.cpp b/plugins/devel/kittens.cpp index 89ece51b6..ec1114576 100644 --- a/plugins/devel/kittens.cpp +++ b/plugins/devel/kittens.cpp @@ -33,7 +33,7 @@ using namespace DFHack; DFHACK_PLUGIN("kittens"); DFHACK_PLUGIN_IS_ENABLED(is_enabled); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(world); namespace DFHack { @@ -119,9 +119,9 @@ DFhackCExport command_result plugin_onupdate ( color_ostream &out ) } if(trackmenu_flg) { - if (last_menu != ui->main.mode) + if (last_menu != plotinfo->main.mode) { - last_menu = ui->main.mode; + last_menu = plotinfo->main.mode; out.print("Menu: %d\n",last_menu); } } @@ -157,7 +157,7 @@ command_result trackmenu (color_ostream &out, vector & parameters) else { is_enabled = true; - last_menu = ui->main.mode; + last_menu = plotinfo->main.mode; out.print("Menu: %d\n",last_menu); trackmenu_flg = true; return CR_OK; diff --git a/plugins/devel/stockcheck.cpp b/plugins/devel/stockcheck.cpp index 619fda9fd..796bc2fc9 100644 --- a/plugins/devel/stockcheck.cpp +++ b/plugins/devel/stockcheck.cpp @@ -5,7 +5,7 @@ #include "DataDefs.h" #include "df/world.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/building_stockpilest.h" #include "df/global_objects.h" #include "df/item.h" @@ -24,7 +24,7 @@ using namespace DFHack; using namespace df::enums; using df::global::world; -using df::global::ui; +using df::global::plotinfo; using df::global::selection_rect; using df::building_stockpilest; @@ -35,7 +35,7 @@ DFHACK_PLUGIN("stockcheck"); DFhackCExport command_result plugin_init (color_ostream &out, std::vector &commands) { - if (world && ui) { + if (world && plotinfo) { commands.push_back( PluginCommand("stockcheck", "Check for unprotected rottable items.", stockcheck, false, diff --git a/plugins/devel/stripcaged.cpp b/plugins/devel/stripcaged.cpp index 30d0b0d2b..e96e63fb1 100644 --- a/plugins/devel/stripcaged.cpp +++ b/plugins/devel/stripcaged.cpp @@ -20,7 +20,7 @@ using namespace std; #include "modules/World.h" #include "MiscUtils.h" -#include +#include #include "df/world.h" #include "df/world_raws.h" #include "df/building_def.h" @@ -34,7 +34,7 @@ using namespace DFHack; using namespace df::enums; using df::global::world; using df::global::cursor; -using df::global::ui; +using df::global::plotinfo; using namespace DFHack::Gui; diff --git a/plugins/dig-now.cpp b/plugins/dig-now.cpp index 1bca6784c..9945ee2b0 100644 --- a/plugins/dig-now.cpp +++ b/plugins/dig-now.cpp @@ -20,14 +20,14 @@ #include #include #include -#include +#include #include #include #include #include DFHACK_PLUGIN("dig-now"); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(world); using namespace DFHack; @@ -678,7 +678,7 @@ static void create_boulders(color_ostream &out, df::unit *unit = world->units.active[0]; df::historical_entity *civ = df::historical_entity::find(unit->civ_id); df::world_site *site = World::isFortressMode() ? - df::world_site::find(ui->site_id) : NULL; + df::world_site::find(plotinfo->site_id) : NULL; std::vector in_reag; std::vector in_items; diff --git a/plugins/dig.cpp b/plugins/dig.cpp index 945bf3613..371dd588f 100644 --- a/plugins/dig.cpp +++ b/plugins/dig.cpp @@ -16,7 +16,7 @@ #include "modules/Maps.h" #include "modules/Materials.h" -#include "df/ui_sidebar_menus.h" +#include "df/gamest.h" using std::vector; using std::string; @@ -33,7 +33,7 @@ command_result digcircle (color_ostream &out, vector & parameters); command_result digtype (color_ostream &out, vector & parameters); DFHACK_PLUGIN("dig"); -REQUIRE_GLOBAL(ui_sidebar_menus); +REQUIRE_GLOBAL(game); REQUIRE_GLOBAL(world); REQUIRE_GLOBAL(window_z); @@ -213,7 +213,7 @@ bool lineY (MapExtras::MapCache & MCache, int32_t parse_priority(color_ostream &out, vector ¶meters) { - int32_t default_priority = ui_sidebar_menus->designation.priority; + int32_t default_priority = game->designation.priority; for (auto it = parameters.begin(); it != parameters.end(); ++it) { diff --git a/plugins/diggingInvaders/assignJob.cpp b/plugins/diggingInvaders/assignJob.cpp index 2eaad9eb5..eb74433b8 100644 --- a/plugins/diggingInvaders/assignJob.cpp +++ b/plugins/diggingInvaders/assignJob.cpp @@ -25,7 +25,7 @@ #include "df/job_type.h" #include "df/reaction_product_itemst.h" #include "df/reaction_reagent.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/unit.h" #include "df/unit_inventory_item.h" #include "df/world.h" @@ -252,7 +252,7 @@ int32_t assignJob(color_ostream& out, Edge firstImportantEdge, unordered_map in_items; prod->produce(firstInvader, &out_products, &out_items, &in_reag, &in_items, 1, df::job_skill::NONE, 0, df::historical_entity::find(firstInvader->civ_id), - df::world_site::find(df::global::ui->site_id), NULL); + df::world_site::find(df::global::plotinfo->site_id), NULL); if ( out_items.size() != 1 ) { out.print("%s, %d: wrong size: %zu.\n", __FILE__, __LINE__, out_items.size()); diff --git a/plugins/diggingInvaders/diggingInvaders.cpp b/plugins/diggingInvaders/diggingInvaders.cpp index 457a00e50..cf0047cd8 100644 --- a/plugins/diggingInvaders/diggingInvaders.cpp +++ b/plugins/diggingInvaders/diggingInvaders.cpp @@ -47,7 +47,7 @@ #include "df/tiletype_material.h" #include "df/tiletype_shape.h" #include "df/tiletype_shape_basic.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/unit.h" #include "df/unit_inventory_item.h" #include "df/world.h" diff --git a/plugins/dwarfmonitor.cpp b/plugins/dwarfmonitor.cpp index 4355104a7..2b546bfad 100644 --- a/plugins/dwarfmonitor.cpp +++ b/plugins/dwarfmonitor.cpp @@ -4,7 +4,7 @@ #include "DataDefs.h" #include "df/job.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/unit.h" #include "df/viewscreen_dwarfmodest.h" #include "df/world.h" @@ -53,7 +53,7 @@ using std::deque; DFHACK_PLUGIN("dwarfmonitor"); DFHACK_PLUGIN_IS_ENABLED(is_enabled); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); typedef int16_t activity_type; diff --git a/plugins/dwarfvet.cpp b/plugins/dwarfvet.cpp index 356fda238..75f015975 100644 --- a/plugins/dwarfvet.cpp +++ b/plugins/dwarfvet.cpp @@ -39,7 +39,7 @@ #include "df/job.h" #include "df/general_ref_unit_workerst.h" #include "df/profession.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/unit.h" #include "df/unit_health_info.h" #include "df/unit_health_flags.h" @@ -58,7 +58,7 @@ using namespace std; DFHACK_PLUGIN("dwarfvet"); DFHACK_PLUGIN_IS_ENABLED(dwarfvet_enabled); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(world); static unordered_set tracked_units; @@ -407,7 +407,7 @@ void tickHandler(color_ostream& out, void* data) { if ( !dwarfvet_enabled ) return; CoreSuspender suspend; - int32_t own_race_id = df::global::ui->race_id; + int32_t own_race_id = df::global::plotinfo->race_id; /** * Generate a list of animal hospitals on the map diff --git a/plugins/embark-assistant/finder_ui.cpp b/plugins/embark-assistant/finder_ui.cpp index 1fb845d15..6501f7f21 100644 --- a/plugins/embark-assistant/finder_ui.cpp +++ b/plugins/embark-assistant/finder_ui.cpp @@ -123,7 +123,7 @@ namespace embark_assist { struct states { embark_assist::defs::find_callbacks find_callback; - uis ui; + uis plotinfo; display_maps finder_list; // Don't need the element key, but it's easier to use the same type. uint16_t finder_list_focus; bool finder_list_active; @@ -171,13 +171,13 @@ namespace embark_assist { size_t civ = 0; while (true) { - for (size_t k = 0; k < state->ui[static_cast(i)]->list.size(); k++) { - if (state->ui[static_cast(i) + civ]->current_value == state->ui[static_cast(i) + civ]->list[k].key) { - fprintf(outfile, "[%s:%s]\n", state->finder_list[static_cast(i) + civ].text.c_str(), state->ui[static_cast(i) + civ]->list[k].text.c_str()); + for (size_t k = 0; k < state->plotinfo[static_cast(i)]->list.size(); k++) { + if (state->plotinfo[static_cast(i) + civ]->current_value == state->plotinfo[static_cast(i) + civ]->list[k].key) { + fprintf(outfile, "[%s:%s]\n", state->finder_list[static_cast(i) + civ].text.c_str(), state->plotinfo[static_cast(i) + civ]->list[k].text.c_str()); break; } } -// fprintf(outfile, "[%s:%i]\n", state->finder_list[static_cast(i)].text.c_str(), state->ui[static_cast(i)]->current_value); +// fprintf(outfile, "[%s:%i]\n", state->finder_list[static_cast(i)].text.c_str(), state->plotinfo[static_cast(i)]->current_value); if (i == last_fields) { civ++; @@ -229,10 +229,10 @@ namespace embark_assist { found = false; - for (size_t l = 0; l < state->ui[static_cast(i) + civ]->list.size(); l++) { + for (size_t l = 0; l < state->plotinfo[static_cast(i) + civ]->list.size(); l++) { for (int m = k + 1; m < count; m++) { - if (state->ui[static_cast(i) + civ]->list[l].text.c_str()[m - (k + 1)] != line[m]) { - if (state->ui[static_cast(i) + civ]->list[l].text.c_str()[m - (k + 1)] == '\0' && + if (state->plotinfo[static_cast(i) + civ]->list[l].text.c_str()[m - (k + 1)] != line[m]) { + if (state->plotinfo[static_cast(i) + civ]->list[l].text.c_str()[m - (k + 1)] == '\0' && line[m] == ']') { found = true; } @@ -291,13 +291,13 @@ namespace embark_assist { found = false; - for (size_t l = 0; l < state->ui[static_cast(i) + civ]->list.size(); l++) { + for (size_t l = 0; l < state->plotinfo[static_cast(i) + civ]->list.size(); l++) { for (int m = k + 1; m < count; m++) { - if (state->ui[static_cast(i) + civ]->list[l].text.c_str()[m - (k + 1)] != line[m]) { - if (state->ui[static_cast(i) + civ]->list[l].text.c_str()[m - (k + 1)] == '\0' && + if (state->plotinfo[static_cast(i) + civ]->list[l].text.c_str()[m - (k + 1)] != line[m]) { + if (state->plotinfo[static_cast(i) + civ]->list[l].text.c_str()[m - (k + 1)] == '\0' && line[m] == ']') { - state->ui[static_cast(i) + civ]->current_value = state->ui[static_cast(i) + civ]->list[l].key; - state->ui[static_cast(i) + civ]->current_display_value = l; + state->plotinfo[static_cast(i) + civ]->current_value = state->plotinfo[static_cast(i) + civ]->list[l].key; + state->plotinfo[static_cast(i) + civ]->current_display_value = l; found = true; } @@ -1095,7 +1095,7 @@ namespace embark_assist { if (l < state->civs.size() - 1) { element->current_value = element->list[0].key; - state->ui.push_back(element); + state->plotinfo.push_back(element); element = new ui_lists; element->current_display_value = 0; element->current_index = 0; @@ -1108,7 +1108,7 @@ namespace embark_assist { } element->current_value = element->list[0].key; - state->ui.push_back(element); + state->plotinfo.push_back(element); switch (i) { case fields::x_dim: @@ -1333,21 +1333,21 @@ namespace embark_assist { // off to compensate for the list starting with 1 at index 0. // auto screen = Gui::getViewscreenByType(0); - state->ui[static_cast(fields::x_dim)]->current_display_value = + state->plotinfo[static_cast(fields::x_dim)]->current_display_value = screen->location.embark_pos_max.x - screen->location.embark_pos_min.x; - state->ui[static_cast(fields::x_dim)]->current_index = - state->ui[static_cast(fields::x_dim)]->current_display_value; - state->ui[static_cast(fields::x_dim)]->current_value = - state->ui[static_cast(fields::x_dim)]->current_display_value + 1; + state->plotinfo[static_cast(fields::x_dim)]->current_index = + state->plotinfo[static_cast(fields::x_dim)]->current_display_value; + state->plotinfo[static_cast(fields::x_dim)]->current_value = + state->plotinfo[static_cast(fields::x_dim)]->current_display_value + 1; - state->ui[static_cast(fields::y_dim)]->current_display_value = + state->plotinfo[static_cast(fields::y_dim)]->current_display_value = screen->location.embark_pos_max.y - screen->location.embark_pos_min.y; - state->ui[static_cast(fields::y_dim)]->current_index = - state->ui[static_cast(fields::y_dim)]->current_display_value; - state->ui[static_cast(fields::y_dim)]->current_value = - state->ui[static_cast(fields::y_dim)]->current_display_value + 1; + state->plotinfo[static_cast(fields::y_dim)]->current_index = + state->plotinfo[static_cast(fields::y_dim)]->current_display_value; + state->plotinfo[static_cast(fields::y_dim)]->current_value = + state->plotinfo[static_cast(fields::y_dim)]->current_display_value + 1; } //========================================================================================================== @@ -1360,234 +1360,234 @@ namespace embark_assist { while (true) { switch (i) { case fields::x_dim: - finder.x_dim = state->ui[static_cast(i)]->current_value; + finder.x_dim = state->plotinfo[static_cast(i)]->current_value; break; case fields::y_dim: - finder.y_dim = state->ui[static_cast(i)]->current_value; + finder.y_dim = state->plotinfo[static_cast(i)]->current_value; break; case fields::savagery_calm: finder.savagery[0] = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::savagery_medium: finder.savagery[1] = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::savagery_savage: finder.savagery[2] = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::good: finder.evilness[0] = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::neutral: finder.evilness[1] = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::evil: finder.evilness[2] = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::aquifer: finder.aquifer = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::min_river: finder.min_river = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::max_river: finder.max_river = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::min_waterfall: - finder.min_waterfall = state->ui[static_cast(i)]->current_value; + finder.min_waterfall = state->plotinfo[static_cast(i)]->current_value; break; case fields::flat: finder.flat = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::soil_min_everywhere: finder.soil_min_everywhere = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::freezing: finder.freezing = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::blood_rain: finder.blood_rain = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::syndrome_rain: finder.syndrome_rain = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::reanimation: finder.reanimation = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::clay: finder.clay = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::sand: finder.sand = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::flux: finder.flux = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::coal: finder.coal = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::soil_min: finder.soil_min = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::soil_max: finder.soil_max = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::spire_count_min: - finder.spire_count_min = state->ui[static_cast(i)]->current_value; + finder.spire_count_min = state->plotinfo[static_cast(i)]->current_value; break; case fields::spire_count_max: - finder.spire_count_max = state->ui[static_cast(i)]->current_value; + finder.spire_count_max = state->plotinfo[static_cast(i)]->current_value; break; case fields::magma_min: finder.magma_min = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::magma_max: finder.magma_max = - static_cast(state->ui[static_cast(i)]->current_value); + static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::biome_count_min: - finder.biome_count_min = state->ui[static_cast(i)]->current_value; + finder.biome_count_min = state->plotinfo[static_cast(i)]->current_value; break; case fields::biome_count_max: - finder.biome_count_max = state->ui[static_cast(i)]->current_value; + finder.biome_count_max = state->plotinfo[static_cast(i)]->current_value; break; case fields::region_type_1: - finder.region_type_1 = state->ui[static_cast(i)]->current_value; + finder.region_type_1 = state->plotinfo[static_cast(i)]->current_value; break; case fields::region_type_2: - finder.region_type_2 = state->ui[static_cast(i)]->current_value; + finder.region_type_2 = state->plotinfo[static_cast(i)]->current_value; break; case fields::region_type_3: - finder.region_type_3 = state->ui[static_cast(i)]->current_value; + finder.region_type_3 = state->plotinfo[static_cast(i)]->current_value; break; case fields::biome_1: - finder.biome_1 = state->ui[static_cast(i)]->current_value; + finder.biome_1 = state->plotinfo[static_cast(i)]->current_value; break; case fields::biome_2: - finder.biome_2 = state->ui[static_cast(i)]->current_value; + finder.biome_2 = state->plotinfo[static_cast(i)]->current_value; break; case fields::biome_3: - finder.biome_3 = state->ui[static_cast(i)]->current_value; + finder.biome_3 = state->plotinfo[static_cast(i)]->current_value; break; case fields::min_trees: - finder.min_trees = static_cast(state->ui[static_cast(i)]->current_value); + finder.min_trees = static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::max_trees: - finder.max_trees = static_cast(state->ui[static_cast(i)]->current_value); + finder.max_trees = static_cast(state->plotinfo[static_cast(i)]->current_value); break; case fields::metal_1: - finder.metal_1 = state->ui[static_cast(i)]->current_value; + finder.metal_1 = state->plotinfo[static_cast(i)]->current_value; break; case fields::metal_2: - finder.metal_2 = state->ui[static_cast(i)]->current_value; + finder.metal_2 = state->plotinfo[static_cast(i)]->current_value; break; case fields::metal_3: - finder.metal_3 = state->ui[static_cast(i)]->current_value; + finder.metal_3 = state->plotinfo[static_cast(i)]->current_value; break; case fields::economic_1: - finder.economic_1 = state->ui[static_cast(i)]->current_value; + finder.economic_1 = state->plotinfo[static_cast(i)]->current_value; break; case fields::economic_2: - finder.economic_2 = state->ui[static_cast(i)]->current_value; + finder.economic_2 = state->plotinfo[static_cast(i)]->current_value; break; case fields::economic_3: - finder.economic_3 = state->ui[static_cast(i)]->current_value; + finder.economic_3 = state->plotinfo[static_cast(i)]->current_value; break; case fields::mineral_1: - finder.mineral_1 = state->ui[static_cast(i)]->current_value; + finder.mineral_1 = state->plotinfo[static_cast(i)]->current_value; break; case fields::mineral_2: - finder.mineral_2 = state->ui[static_cast(i)]->current_value; + finder.mineral_2 = state->plotinfo[static_cast(i)]->current_value; break; case fields::mineral_3: - finder.mineral_3 = state->ui[static_cast(i)]->current_value; + finder.mineral_3 = state->plotinfo[static_cast(i)]->current_value; break; case fields::min_necro_neighbors: - finder.min_necro_neighbors = state->ui[static_cast(i)]->current_value; + finder.min_necro_neighbors = state->plotinfo[static_cast(i)]->current_value; break; case fields::max_necro_neighbors: - finder.max_necro_neighbors = state->ui[static_cast(i)]->current_value; + finder.max_necro_neighbors = state->plotinfo[static_cast(i)]->current_value; break; case fields::min_civ_neighbors: - finder.min_civ_neighbors = state->ui[static_cast(i)]->current_value; + finder.min_civ_neighbors = state->plotinfo[static_cast(i)]->current_value; break; case fields::max_civ_neighbors: - finder.max_civ_neighbors = state->ui[static_cast(i)]->current_value; + finder.max_civ_neighbors = state->plotinfo[static_cast(i)]->current_value; break; case fields::neighbors: for (size_t k = 0; k < state->civs.size(); k++) { - finder.neighbors.push_back({ state->civs[k].id, static_cast(state->ui[static_cast(i) + k]->current_value) }); + finder.neighbors.push_back({ state->civs[k].id, static_cast(state->plotinfo[static_cast(i) + k]->current_value) }); } break; } @@ -1641,10 +1641,10 @@ namespace embark_assist { } } else { - if (state->ui[state->finder_list_focus]->current_index > 0) { - state->ui[state->finder_list_focus]->current_index--; + if (state->plotinfo[state->finder_list_focus]->current_index > 0) { + state->plotinfo[state->finder_list_focus]->current_index--; } else { - state->ui[state->finder_list_focus]->current_index = static_cast(state->ui[state->finder_list_focus]->list.size()) - 1; + state->plotinfo[state->finder_list_focus]->current_index = static_cast(state->plotinfo[state->finder_list_focus]->list.size()) - 1; } } @@ -1657,17 +1657,17 @@ namespace embark_assist { } } else { - if (state->ui[state->finder_list_focus]->current_index < state->ui[state->finder_list_focus]->list.size() - 1) { - state->ui[state->finder_list_focus]->current_index++; + if (state->plotinfo[state->finder_list_focus]->current_index < state->plotinfo[state->finder_list_focus]->list.size() - 1) { + state->plotinfo[state->finder_list_focus]->current_index++; } else { - state->ui[state->finder_list_focus]->current_index = 0; + state->plotinfo[state->finder_list_focus]->current_index = 0; } } } else if (input->count(df::interface_key::SELECT)) { if (!state->finder_list_active) { - state->ui[state->finder_list_focus]->current_display_value = state->ui[state->finder_list_focus]->current_index; - state->ui[state->finder_list_focus]->current_value = state->ui[state->finder_list_focus]->list[state->ui[state->finder_list_focus]->current_index].key; + state->plotinfo[state->finder_list_focus]->current_display_value = state->plotinfo[state->finder_list_focus]->current_index; + state->plotinfo[state->finder_list_focus]->current_value = state->plotinfo[state->finder_list_focus]->list[state->plotinfo[state->finder_list_focus]->current_index].key; state->finder_list_active = true; } @@ -1743,7 +1743,7 @@ namespace embark_assist { embark_assist::screen::paintString(active_pen, 21, top_row + i - offset, - state->ui[i]->list[state->ui[i]->current_display_value].text); + state->plotinfo[i]->list[state->plotinfo[i]->current_display_value].text); } else { embark_assist::screen::paintString(normal_pen, 1, top_row + i - offset, state->finder_list[i].text); @@ -1751,38 +1751,38 @@ namespace embark_assist { embark_assist::screen::paintString(white_pen, 21, top_row + i - offset, - state->ui[i]->list[state->ui[i]->current_display_value].text); + state->plotinfo[i]->list[state->plotinfo[i]->current_display_value].text); } } // Implement scrolling lists if they don't fit on the screen. offset = 0; - if (int32_t(state->ui[state->finder_list_focus]->list.size()) > screen_size.y - top_row - 1) { + if (int32_t(state->plotinfo[state->finder_list_focus]->list.size()) > screen_size.y - top_row - 1) { offset = (screen_size.y - top_row - 1) / 2; - if (state->ui[state->finder_list_focus]->current_index < offset) { + if (state->plotinfo[state->finder_list_focus]->current_index < offset) { offset = 0; } else { - offset = state->ui[state->finder_list_focus]->current_index - offset; + offset = state->plotinfo[state->finder_list_focus]->current_index - offset; } - if (int32_t(state->ui[state->finder_list_focus]->list.size() - offset) < screen_size.y - top_row - 1) { - offset = static_cast(state->ui[state->finder_list_focus]->list.size()) - (screen_size.y - top_row - 1); + if (int32_t(state->plotinfo[state->finder_list_focus]->list.size() - offset) < screen_size.y - top_row - 1) { + offset = static_cast(state->plotinfo[state->finder_list_focus]->list.size()) - (screen_size.y - top_row - 1); } } - for (uint16_t i = offset; i < state->ui[state->finder_list_focus]->list.size(); i++) { - if (i == state->ui[state->finder_list_focus]->current_index) { + for (uint16_t i = offset; i < state->plotinfo[state->finder_list_focus]->list.size(); i++) { + if (i == state->plotinfo[state->finder_list_focus]->current_index) { if (!state->finder_list_active) { // Negated expression to get the display lines in the same order as above. - embark_assist::screen::paintString(active_pen, list_column, top_row + i - offset, state->ui[state->finder_list_focus]->list[i].text); + embark_assist::screen::paintString(active_pen, list_column, top_row + i - offset, state->plotinfo[state->finder_list_focus]->list[i].text); } else { - embark_assist::screen::paintString(passive_pen, list_column, top_row + i - offset, state->ui[state->finder_list_focus]->list[i].text); + embark_assist::screen::paintString(passive_pen, list_column, top_row + i - offset, state->plotinfo[state->finder_list_focus]->list[i].text); } } else { - embark_assist::screen::paintString(normal_pen, list_column, top_row + i - offset, state->ui[state->finder_list_focus]->list[i].text); + embark_assist::screen::paintString(normal_pen, list_column, top_row + i - offset, state->plotinfo[state->finder_list_focus]->list[i].text); } } @@ -1823,8 +1823,8 @@ void embark_assist::finder_ui::activate() { void embark_assist::finder_ui::shutdown() { if (embark_assist::finder_ui::state) { - for (uint16_t i = 0; i < embark_assist::finder_ui::state->ui.size(); i++) { - delete embark_assist::finder_ui::state->ui[i]; + for (uint16_t i = 0; i < embark_assist::finder_ui::state->plotinfo.size(); i++) { + delete embark_assist::finder_ui::state->plotinfo[i]; } delete embark_assist::finder_ui::state; diff --git a/plugins/eventful.cpp b/plugins/eventful.cpp index 980b2db9c..dfddab9e8 100644 --- a/plugins/eventful.cpp +++ b/plugins/eventful.cpp @@ -39,7 +39,7 @@ using namespace df::enums; DFHACK_PLUGIN("eventful"); REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); typedef df::reaction_product_itemst item_product; diff --git a/plugins/getplants.cpp b/plugins/getplants.cpp index 6819b6191..4fc82cb97 100644 --- a/plugins/getplants.cpp +++ b/plugins/getplants.cpp @@ -14,7 +14,7 @@ #include "df/plant_growth.h" #include "df/plant_raw.h" #include "df/tile_dig_designation.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/world.h" #include "df/world_data.h" #include "df/world_object_data.h" @@ -32,7 +32,7 @@ using namespace DFHack; using namespace df::enums; DFHACK_PLUGIN("getplants"); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(world); REQUIRE_GLOBAL(cur_year); REQUIRE_GLOBAL(cur_year_tick); @@ -242,7 +242,7 @@ bool ripe(int32_t x, int32_t y, int32_t start, int32_t end) { // Looks in the picked growths vector to see if a matching growth has been marked as picked. bool picked(const df::plant *plant, int32_t growth_subtype) { df::world_data *world_data = world->world_data; - df::world_site *site = df::world_site::find(ui->site_id); + df::world_site *site = df::world_site::find(plotinfo->site_id); int32_t pos_x = site->global_min_x + plant->pos.x / 48; int32_t pos_y = site->global_min_y + plant->pos.y / 48; size_t id = pos_x + pos_y * 16 * world_data->world_width; diff --git a/plugins/jobutils.cpp b/plugins/jobutils.cpp index 5f5994435..35b6f2cb5 100644 --- a/plugins/jobutils.cpp +++ b/plugins/jobutils.cpp @@ -11,8 +11,8 @@ #include "DataDefs.h" #include "df/world.h" -#include "df/ui.h" -#include "df/ui_build_selector.h" +#include "df/plotinfost.h" +#include "df/buildreq.h" #include "df/ui_build_item_req.h" #include "df/build_req_choice_genst.h" #include "df/build_req_choice_specst.h" @@ -33,7 +33,7 @@ using namespace df::enums; DFHACK_PLUGIN("jobutils"); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(ui_build_selector); REQUIRE_GLOBAL(ui_workshop_job_cursor); REQUIRE_GLOBAL(job_next_id); @@ -48,7 +48,7 @@ static command_result job_cmd(color_ostream &out, vector & parameters); DFhackCExport command_result plugin_init (color_ostream &out, std::vector &commands) { - if (!world || !ui) + if (!world || !plotinfo) return CR_FAILURE; commands.push_back( @@ -232,9 +232,9 @@ static command_result job_material(color_ostream &out, vector & paramet else return CR_WRONG_USAGE; - if (ui->main.mode == ui_sidebar_mode::QueryBuilding) + if (plotinfo->main.mode == ui_sidebar_mode::QueryBuilding) return job_material_in_job(out, new_mat); - if (ui->main.mode == ui_sidebar_mode::Build) + if (plotinfo->main.mode == ui_sidebar_mode::Build) return job_material_in_build(out, new_mat); return CR_WRONG_USAGE; diff --git a/plugins/lua/buildingplan.lua b/plugins/lua/buildingplan.lua index 43122a7da..a01a1d0b1 100644 --- a/plugins/lua/buildingplan.lua +++ b/plugins/lua/buildingplan.lua @@ -87,7 +87,7 @@ end -- returns a vector of constructed buildings (usually of size 1, but potentially -- more for constructions) function construct_buildings_from_ui_state() - local uibs = df.global.ui_build_selector + local uibs = df.global.buildreq local world = df.global.world local direction = world.selected_direction local _, width, height = dfhack.buildings.getCorrectSize( diff --git a/plugins/lua/confirm.lua b/plugins/lua/confirm.lua index e36a4fb86..736f13fe1 100644 --- a/plugins/lua/confirm.lua +++ b/plugins/lua/confirm.lua @@ -1,6 +1,6 @@ local _ENV = mkmodule('plugins.confirm') -local ui = df.global.ui +local ui = df.global.plotinfo local confs = {} -- Wraps df.interface_key[foo] functionality but fails with invalid keys diff --git a/plugins/lua/eventful.lua b/plugins/lua/eventful.lua index 1e3170c45..4cbcbeef2 100644 --- a/plugins/lua/eventful.lua +++ b/plugins/lua/eventful.lua @@ -54,10 +54,10 @@ local function onPostSidebar(workshop) if shop_id then if _registeredStuff.shopNonNative and _registeredStuff.shopNonNative[shop_id] then if _registeredStuff.shopNonNative[shop_id].all then - --[[for _,button in ipairs(df.global.ui_sidebar_menus.workshop_job.choices_all) do + --[[for _,button in ipairs(df.global.game.workshop_job.choices_all) do button.is_hidden=true end]] - df.global.ui_sidebar_menus.workshop_job.choices_visible:resize(0) + df.global.game.workshop_job.choices_visible:resize(0) else --todo by name end @@ -72,7 +72,7 @@ local function onPostSidebar(workshop) new_button.job_type=df.job_type.CustomReaction --could be used for other stuff too i guess... new_button.reaction_name=reaction_name new_button.is_custom=true - local wjob=df.global.ui_sidebar_menus.workshop_job + local wjob=df.global.game.workshop_job wjob.choices_all:insert("#",new_button) wjob.choices_visible:insert("#",new_button) end diff --git a/plugins/lua/hotkeys.lua b/plugins/lua/hotkeys.lua index 2fb1bf69e..53885d8fa 100644 --- a/plugins/lua/hotkeys.lua +++ b/plugins/lua/hotkeys.lua @@ -11,15 +11,14 @@ local widgets = require('gui.widgets') HotspotMenuWidget = defclass(HotspotMenuWidget, overlay.OverlayWidget) HotspotMenuWidget.ATTRS{ - default_pos={x=1,y=3}, + default_pos={x=2,y=2}, hotspot=true, - viewscreens={'dwarfmode'}, + viewscreens='all', overlay_onupdate_max_freq_seconds=0, - frame={w=2, h=1} + frame={w=4, h=3} } function HotspotMenuWidget:init() - self:addviews{widgets.Label{text='!'}} self.mouseover = false end @@ -41,6 +40,34 @@ function HotspotMenuWidget:overlay_trigger() mouseover=self.mouseover}:show() end +local dscreen = dfhack.screen + +function HotspotMenuWidget:onRenderBody(dc) + local tpos = dfhack.textures.getDfhackLogoTexposStart() + local x, y = dc.x, dc.y + + if tpos == -1 then + dscreen.paintString(COLOR_WHITE, x, y+0, '!DF!') + dscreen.paintString(COLOR_WHITE, x, y+1, '!Ha!') + dscreen.paintString(COLOR_WHITE, x, y+2, '!ck!') + else + dscreen.paintTile(COLOR_WHITE, x+0, y+0, '!', tpos+0) + dscreen.paintTile(COLOR_WHITE, x+1, y+0, 'D', tpos+1) + dscreen.paintTile(COLOR_WHITE, x+2, y+0, 'F', tpos+2) + dscreen.paintTile(COLOR_WHITE, x+3, y+0, '!', tpos+3) + + dscreen.paintTile(COLOR_WHITE, x+0, y+1, '!', tpos+4) + dscreen.paintTile(COLOR_WHITE, x+1, y+1, 'H', tpos+5) + dscreen.paintTile(COLOR_WHITE, x+2, y+1, 'a', tpos+6) + dscreen.paintTile(COLOR_WHITE, x+3, y+1, '!', tpos+7) + + dscreen.paintTile(COLOR_WHITE, x+0, y+2, '!', tpos+8) + dscreen.paintTile(COLOR_WHITE, x+1, y+2, 'c', tpos+9) + dscreen.paintTile(COLOR_WHITE, x+2, y+2, 'k', tpos+10) + dscreen.paintTile(COLOR_WHITE, x+3, y+2, '!', tpos+11) + end +end + -- register the menu hotspot with the overlay OVERLAY_WIDGETS = {menu=HotspotMenuWidget} @@ -136,9 +163,9 @@ function MenuScreen:init() local help_frame = {w=list_frame.w, l=list_frame.l, r=list_frame.r} if list_frame.t then - help_frame.t = list_frame.t + list_frame.h + 1 + help_frame.t = list_frame.t + list_frame.h else - help_frame.b = list_frame.b + list_frame.h + 1 + help_frame.b = list_frame.b + list_frame.h end self:addviews{ diff --git a/plugins/lua/overlay.lua b/plugins/lua/overlay.lua index 9f2c9029b..4fc375d72 100644 --- a/plugins/lua/overlay.lua +++ b/plugins/lua/overlay.lua @@ -78,7 +78,9 @@ end -- normalize "short form" viewscreen names to "long form" local function normalize_viewscreen_name(vs_name) - if vs_name:match('viewscreen_.*st') then return vs_name end + if vs_name == 'all' or vs_name:match('viewscreen_.*st') then + return vs_name + end return 'viewscreen_' .. vs_name .. 'st' end @@ -177,6 +179,7 @@ end local function do_disable(args, quiet) local disable_fn = function(name, db_entry) + if db_entry.widget.always_enabled then return end overlay_config[name].enabled = false if db_entry.widget.hotspot then active_hotspot_widgets[name] = nil @@ -244,7 +247,7 @@ local function load_widget(name, widget_class) local config = overlay_config[name] config.pos = sanitize_pos(config.pos or widget.default_pos) widget.frame = make_frame(config.pos, widget.frame) - if config.enabled then + if config.enabled or widget.always_enabled then do_enable(name, true, true) else config.enabled = false @@ -416,18 +419,24 @@ function update_hotspot_widgets() end end --- not subject to trigger lock since these widgets are already filtered by --- viewscreen -function update_viewscreen_widgets(vs_name, vs) +local function _update_viewscreen_widgets(vs_name, vs, now_ms) local vs_widgets = active_viewscreen_widgets[vs_name] if not vs_widgets then return end - local now_ms = dfhack.getTickCount() + now_ms = now_ms or dfhack.getTickCount() for name,db_entry in pairs(vs_widgets) do if do_update(name, db_entry, now_ms, vs) then return end end + return now_ms end -function feed_viewscreen_widgets(vs_name, keys) +-- not subject to trigger lock since these widgets are already filtered by +-- viewscreen +function update_viewscreen_widgets(vs_name, vs) + local now_ms = _update_viewscreen_widgets(vs_name, vs, nil) + _update_viewscreen_widgets('all', vs, now_ms) +end + +local function _feed_viewscreen_widgets(vs_name, keys) local vs_widgets = active_viewscreen_widgets[vs_name] if not vs_widgets then return false end for _,db_entry in pairs(vs_widgets) do @@ -439,16 +448,26 @@ function feed_viewscreen_widgets(vs_name, keys) return false end -function render_viewscreen_widgets(vs_name) +function feed_viewscreen_widgets(vs_name, keys) + return _feed_viewscreen_widgets(vs_name, keys) or + _feed_viewscreen_widgets('all', keys) +end + +local function _render_viewscreen_widgets(vs_name, dc) local vs_widgets = active_viewscreen_widgets[vs_name] if not vs_widgets then return false end - local dc = gui.Painter.new() + dc = dc or gui.Painter.new() for _,db_entry in pairs(vs_widgets) do local w = db_entry.widget detect_frame_change(w, function() w:render(dc) end) end end +function render_viewscreen_widgets(vs_name) + local dc = _render_viewscreen_widgets(vs_name, nil) + _render_viewscreen_widgets('all', dc) +end + -- called when the DF window is resized function reposition_widgets() local sr = get_screen_rect() @@ -461,7 +480,7 @@ end -- OverlayWidget (base class of all overlay widgets) -- -- ------------------------------------------------- -- -OverlayWidget = defclass(OverlayWidget, widgets.Widget) +OverlayWidget = defclass(OverlayWidget, widgets.Panel) OverlayWidget.ATTRS{ name=DEFAULT_NIL, -- this is set by the framework to the widget name default_pos={x=DEFAULT_X_POS, y=DEFAULT_Y_POS}, -- 1-based widget screen pos @@ -469,6 +488,7 @@ OverlayWidget.ATTRS{ hotspot=false, -- whether to call overlay_onupdate on all screens viewscreens={}, -- override with associated viewscreen or list of viewscrens overlay_onupdate_max_freq_seconds=5, -- throttle calls to overlay_onupdate + always_enabled=false, -- for overlays that should never be disabled } function OverlayWidget:init() diff --git a/plugins/lua/pathable.lua b/plugins/lua/pathable.lua index b5f5addfc..f3247cffe 100644 --- a/plugins/lua/pathable.lua +++ b/plugins/lua/pathable.lua @@ -2,7 +2,7 @@ local _ENV = mkmodule('plugins.pathable') --[[ -Native functions: (see Plugins.rst for details) +Native functions: (see docs/dev/Lua API.rst for details) - paintScreen(cursor[,skip_unrevealed]) diff --git a/plugins/lua/siege-engine.lua b/plugins/lua/siege-engine.lua index 5d8cc9050..25f405615 100644 --- a/plugins/lua/siege-engine.lua +++ b/plugins/lua/siege-engine.lua @@ -146,7 +146,7 @@ function getBaseUnitWeight(unit) return -30 elseif flags1.diplomat or flags1.merchant or flags1.forest then return -5 - elseif flags1.tame and unit.civ_id == df.global.ui.civ_id then + elseif flags1.tame and unit.civ_id == df.global.plotinfo.civ_id then return -1 end end diff --git a/plugins/lua/stockflow.lua b/plugins/lua/stockflow.lua index 91a3284ff..d6c9fc070 100644 --- a/plugins/lua/stockflow.lua +++ b/plugins/lua/stockflow.lua @@ -234,7 +234,7 @@ function material_reactions(reactions, itemtypes, mat_info) end function clothing_reactions(reactions, mat_info, filter) - local resources = df.historical_entity.find(df.global.ui.civ_id).resources + local resources = df.historical_entity.find(df.global.plotinfo.civ_id).resources local itemdefs = df.global.world.raws.itemdefs local job_types = df.job_type resource_reactions(reactions, job_types.MakeArmor, mat_info, resources.armor_type, itemdefs.armor, {permissible = filter}) @@ -408,7 +408,7 @@ function collect_reactions() -- Reactions defined in the raws. -- Not all reactions are allowed to the civilization. -- That includes "Make sharp rock" by default. - local entity = df.historical_entity.find(df.global.ui.civ_id) + local entity = df.historical_entity.find(df.global.plotinfo.civ_id) if not entity then -- No global civilization; arena mode? -- Anyway, skip remaining reactions, since many depend on the civ. diff --git a/plugins/manipulator.cpp b/plugins/manipulator.cpp index 2d3f3bc0a..6731aa513 100644 --- a/plugins/manipulator.cpp +++ b/plugins/manipulator.cpp @@ -19,7 +19,7 @@ #include "df/activity_event.h" #include "df/world.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/graphic.h" #include "df/enabler.h" #include "df/viewscreen_unitlistst.h" @@ -49,7 +49,7 @@ using namespace df::enums; DFHACK_PLUGIN("manipulator"); DFHACK_PLUGIN_IS_ENABLED(is_enabled); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(enabler); @@ -1972,9 +1972,9 @@ void viewscreen_unitlaborsst::render() Screen::paintTile(Screen::Pen(columns[col_offset].label[0], fg, bg), col_offsets[DISP_COLUMN_LABORS] + col, 1); Screen::paintTile(Screen::Pen(columns[col_offset].label[1], fg, bg), col_offsets[DISP_COLUMN_LABORS] + col, 2); df::profession profession = columns[col_offset].profession; - if ((profession != profession::NONE) && (ui->race_id != -1)) + if ((profession != profession::NONE) && (plotinfo->race_id != -1)) { - auto graphics = world->raws.creatures.all[ui->race_id]->graphics; + auto graphics = world->raws.creatures.all[plotinfo->race_id]->graphics; Screen::paintTile( Screen::Pen(' ', fg, 0, graphics.profession_add_color[creature_graphics_role::DEFAULT][profession], diff --git a/plugins/misery.cpp b/plugins/misery.cpp index 224060c6b..870c4480c 100644 --- a/plugins/misery.cpp +++ b/plugins/misery.cpp @@ -10,7 +10,7 @@ #include "modules/Units.h" #include "df/emotion_type.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/unit.h" #include "df/unit_personality.h" #include "df/unit_soul.h" @@ -24,7 +24,7 @@ DFHACK_PLUGIN("misery"); DFHACK_PLUGIN_IS_ENABLED(is_enabled); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(cur_year); REQUIRE_GLOBAL(cur_year_tick); diff --git a/plugins/mousequery.cpp b/plugins/mousequery.cpp index 124664fa2..1a088141a 100644 --- a/plugins/mousequery.cpp +++ b/plugins/mousequery.cpp @@ -6,8 +6,8 @@ #include "df/viewscreen_dwarfmodest.h" #include "df/world.h" #include "df/items_other_id.h" -#include "df/ui_build_selector.h" -#include "df/ui_sidebar_menus.h" +#include "df/buildreq.h" +#include "df/gamest.h" #include "modules/Gui.h" #include "modules/World.h" @@ -26,7 +26,7 @@ DFHACK_PLUGIN("mousequery"); REQUIRE_GLOBAL(enabler); REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(ui_build_selector); using namespace df::enums::ui_sidebar_mode; @@ -196,7 +196,7 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest bool isInDesignationMenu() { - switch (ui->main.mode) + switch (plotinfo->main.mode) { case DesignateMine: case DesignateRemoveRamps: @@ -230,7 +230,7 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest return true; case Burrows: - return ui->burrows.in_define_mode; + return plotinfo->burrows.in_define_mode; default: return false; @@ -242,7 +242,7 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest if (isInDesignationMenu()) return box_designation_enabled; - switch (ui->main.mode) + switch (plotinfo->main.mode) { case DesignateItemsClaim: case DesignateItemsForbid: @@ -281,8 +281,8 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest { bool selectableMode = isInDesignationMenu() || - ui->main.mode == Stockpiles || - ui->main.mode == Zones; + plotinfo->main.mode == Stockpiles || + plotinfo->main.mode == Zones; if (selectableMode) { @@ -314,7 +314,7 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest } else { - switch (ui->main.mode) + switch (plotinfo->main.mode) { case QueryBuilding: if (cursor_still_here) @@ -369,8 +369,8 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest if (mx < 1 || mx > dims.map_x2 || my < 1 || my > dims.map_y2) return false; - if (ui->main.mode == df::ui_sidebar_mode::Zones || - ui->main.mode == df::ui_sidebar_mode::Stockpiles) + if (plotinfo->main.mode == df::ui_sidebar_mode::Zones || + plotinfo->main.mode == df::ui_sidebar_mode::Stockpiles) { int32_t x, y, z; if (Gui::getDesignationCoords(x, y, z)) @@ -417,8 +417,8 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest enabler->mouse_rbut = 0; using namespace df::enums::ui_sidebar_mode; - if ((ui->main.mode == QueryBuilding || ui->main.mode == BuildingItems || - ui->main.mode == ViewUnits || ui->main.mode == LookAround) || + if ((plotinfo->main.mode == QueryBuilding || plotinfo->main.mode == BuildingItems || + plotinfo->main.mode == ViewUnits || plotinfo->main.mode == LookAround) || (isInTrackableMode() && tracking_enabled)) { sendKey(df::interface_key::LEAVESCREEN); @@ -707,8 +707,8 @@ struct mousequery_hook : public df::viewscreen_dwarfmodest if (Gui::getDesignationCoords(x, y, z)) { color = COLOR_WHITE; - if (ui->main.mode == df::ui_sidebar_mode::Zones || - ui->main.mode == df::ui_sidebar_mode::Stockpiles) + if (plotinfo->main.mode == df::ui_sidebar_mode::Zones || + plotinfo->main.mode == df::ui_sidebar_mode::Stockpiles) { auto dX = abs(x - mpos.x); if (dX > 30) diff --git a/plugins/nestboxes.cpp b/plugins/nestboxes.cpp index 403a8cb37..1908684d4 100644 --- a/plugins/nestboxes.cpp +++ b/plugins/nestboxes.cpp @@ -5,7 +5,7 @@ #include "DataDefs.h" #include "df/world.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/building_nest_boxst.h" #include "df/building_type.h" #include "df/buildings_other_id.h" @@ -26,7 +26,7 @@ using namespace DFHack; using namespace df::enums; using df::global::world; -using df::global::ui; +using df::global::plotinfo; static command_result nestboxes(color_ostream &out, vector & parameters); @@ -67,7 +67,7 @@ static void eggscan(color_ostream &out) DFhackCExport command_result plugin_init (color_ostream &out, std::vector &commands) { - if (world && ui) { + if (world && plotinfo) { commands.push_back( PluginCommand( "nestboxes", diff --git a/plugins/overlay.cpp b/plugins/overlay.cpp index c2a04ac8b..4c7384f3b 100644 --- a/plugins/overlay.cpp +++ b/plugins/overlay.cpp @@ -1,87 +1,18 @@ #include "df/viewscreen_adopt_regionst.h" -#include "df/viewscreen_adventure_logst.h" -#include "df/viewscreen_announcelistst.h" -#include "df/viewscreen_assign_display_itemst.h" -#include "df/viewscreen_barterst.h" -#include "df/viewscreen_buildinglistst.h" -#include "df/viewscreen_buildingst.h" +#include "df/viewscreen_choose_game_typest.h" #include "df/viewscreen_choose_start_sitest.h" -#include "df/viewscreen_civlistst.h" -#include "df/viewscreen_counterintelligencest.h" -#include "df/viewscreen_createquotast.h" -#include "df/viewscreen_customize_unitst.h" -#include "df/viewscreen_dungeonmodest.h" -#include "df/viewscreen_dungeon_monsterstatusst.h" -#include "df/viewscreen_dungeon_wrestlest.h" #include "df/viewscreen_dwarfmodest.h" -#include "df/viewscreen_entityst.h" -#include "df/viewscreen_export_graphical_mapst.h" #include "df/viewscreen_export_regionst.h" #include "df/viewscreen_game_cleanerst.h" -#include "df/viewscreen_image_creator_mode.h" -#include "df/viewscreen_image_creatorst.h" -#include "df/viewscreen_itemst.h" -#include "df/viewscreen_joblistst.h" -#include "df/viewscreen_jobmanagementst.h" -#include "df/viewscreen_jobst.h" -#include "df/viewscreen_justicest.h" -#include "df/viewscreen_kitchenpref_page.h" -#include "df/viewscreen_kitchenprefst.h" -#include "df/viewscreen_layer_arena_creaturest.h" -#include "df/viewscreen_layer_assigntradest.h" -#include "df/viewscreen_layer_choose_language_namest.h" -#include "df/viewscreen_layer_currencyst.h" -#include "df/viewscreen_layer_export_play_mapst.h" -#include "df/viewscreen_layer.h" -#include "df/viewscreen_layer_militaryst.h" -#include "df/viewscreen_layer_musicsoundst.h" -#include "df/viewscreen_layer_noblelistst.h" -#include "df/viewscreen_layer_overall_healthst.h" -#include "df/viewscreen_layer_reactionst.h" -#include "df/viewscreen_layer_squad_schedulest.h" -#include "df/viewscreen_layer_stockpilest.h" -#include "df/viewscreen_layer_stone_restrictionst.h" -#include "df/viewscreen_layer_unit_actionst.h" -#include "df/viewscreen_layer_unit_healthst.h" -#include "df/viewscreen_layer_unit_relationshipst.h" -#include "df/viewscreen_layer_world_gen_param_presetst.h" -#include "df/viewscreen_layer_world_gen_paramst.h" +#include "df/viewscreen_initial_prepst.h" #include "df/viewscreen_legendsst.h" #include "df/viewscreen_loadgamest.h" -#include "df/viewscreen_locationsst.h" -#include "df/viewscreen_meetingst.h" -#include "df/viewscreen_movieplayerst.h" #include "df/viewscreen_new_regionst.h" -#include "df/viewscreen_noblest.h" -#include "df/viewscreen_optionst.h" -#include "df/viewscreen_overallstatusst.h" -#include "df/viewscreen_petitionsst.h" -#include "df/viewscreen_petst.h" -#include "df/viewscreen_pricest.h" -#include "df/viewscreen_reportlistst.h" -#include "df/viewscreen_requestagreementst.h" #include "df/viewscreen_savegamest.h" -#include "df/viewscreen_selectitemst.h" -#include "df/viewscreen_setupadventurest.h" #include "df/viewscreen_setupdwarfgamest.h" -#include "df/viewscreen_storesst.h" -#include "df/viewscreen_textviewerst.h" #include "df/viewscreen_titlest.h" -#include "df/viewscreen_topicmeeting_fill_land_holder_positionsst.h" -#include "df/viewscreen_topicmeetingst.h" -#include "df/viewscreen_topicmeeting_takerequestsst.h" -#include "df/viewscreen_tradeagreementst.h" -#include "df/viewscreen_tradelistst.h" -#include "df/viewscreen_tradegoodsst.h" -#include "df/viewscreen_treasurelistst.h" -#include "df/viewscreen_unitlist_page.h" -#include "df/viewscreen_unitlistst.h" -#include "df/viewscreen_unitst.h" #include "df/viewscreen_update_regionst.h" -#include "df/viewscreen_wagesst.h" -#include "df/viewscreen_workquota_conditionst.h" -#include "df/viewscreen_workquota_detailsst.h" -#include "df/viewscreen_workshop_profilest.h" +#include "df/viewscreen_worldst.h" #include "Debug.h" #include "LuaTools.h" @@ -163,85 +94,20 @@ struct viewscreen_overlay : T { template<> IMPLEMENT_VMETHOD_INTERPOSE_PRIO(screen##_overlay, render, 100); IMPLEMENT_HOOKS(adopt_region) -IMPLEMENT_HOOKS(adventure_log) -IMPLEMENT_HOOKS(announcelist) -IMPLEMENT_HOOKS(assign_display_item) -IMPLEMENT_HOOKS(barter) -IMPLEMENT_HOOKS(buildinglist) -IMPLEMENT_HOOKS(building) +IMPLEMENT_HOOKS(choose_game_type) IMPLEMENT_HOOKS(choose_start_site) -IMPLEMENT_HOOKS(civlist) -IMPLEMENT_HOOKS(counterintelligence) -IMPLEMENT_HOOKS(createquota) -IMPLEMENT_HOOKS(customize_unit) -IMPLEMENT_HOOKS(dungeonmode) -IMPLEMENT_HOOKS(dungeon_monsterstatus) -IMPLEMENT_HOOKS(dungeon_wrestle) IMPLEMENT_HOOKS(dwarfmode) -IMPLEMENT_HOOKS(entity) -IMPLEMENT_HOOKS(export_graphical_map) IMPLEMENT_HOOKS(export_region) IMPLEMENT_HOOKS(game_cleaner) -IMPLEMENT_HOOKS(image_creator) -IMPLEMENT_HOOKS(item) -IMPLEMENT_HOOKS(joblist) -IMPLEMENT_HOOKS(jobmanagement) -IMPLEMENT_HOOKS(job) -IMPLEMENT_HOOKS(justice) -IMPLEMENT_HOOKS(kitchenpref) -IMPLEMENT_HOOKS(layer_arena_creature) -IMPLEMENT_HOOKS(layer_assigntrade) -IMPLEMENT_HOOKS(layer_choose_language_name) -IMPLEMENT_HOOKS(layer_currency) -IMPLEMENT_HOOKS(layer_export_play_map) -IMPLEMENT_HOOKS(layer_military) -IMPLEMENT_HOOKS(layer_musicsound) -IMPLEMENT_HOOKS(layer_noblelist) -IMPLEMENT_HOOKS(layer_overall_health) -IMPLEMENT_HOOKS(layer_reaction) -IMPLEMENT_HOOKS(layer_squad_schedule) -IMPLEMENT_HOOKS(layer_stockpile) -IMPLEMENT_HOOKS(layer_stone_restriction) -IMPLEMENT_HOOKS(layer_unit_action) -IMPLEMENT_HOOKS(layer_unit_health) -IMPLEMENT_HOOKS(layer_unit_relationship) -IMPLEMENT_HOOKS(layer_world_gen_param_preset) -IMPLEMENT_HOOKS(layer_world_gen_param) +IMPLEMENT_HOOKS(initial_prep) IMPLEMENT_HOOKS(legends) IMPLEMENT_HOOKS(loadgame) -IMPLEMENT_HOOKS(locations) -IMPLEMENT_HOOKS(meeting) -IMPLEMENT_HOOKS(movieplayer) IMPLEMENT_HOOKS(new_region) -IMPLEMENT_HOOKS(noble) -IMPLEMENT_HOOKS(option) -IMPLEMENT_HOOKS(overallstatus) -IMPLEMENT_HOOKS(petitions) -IMPLEMENT_HOOKS(pet) -IMPLEMENT_HOOKS(price) -IMPLEMENT_HOOKS(reportlist) -IMPLEMENT_HOOKS(requestagreement) IMPLEMENT_HOOKS(savegame) -IMPLEMENT_HOOKS(selectitem) -IMPLEMENT_HOOKS(setupadventure) IMPLEMENT_HOOKS(setupdwarfgame) -IMPLEMENT_HOOKS(stores) -IMPLEMENT_HOOKS(textviewer) IMPLEMENT_HOOKS(title) -IMPLEMENT_HOOKS(topicmeeting_fill_land_holder_positions) -IMPLEMENT_HOOKS(topicmeeting) -IMPLEMENT_HOOKS(topicmeeting_takerequests) -IMPLEMENT_HOOKS(tradeagreement) -IMPLEMENT_HOOKS(tradegoods) -IMPLEMENT_HOOKS(tradelist) -IMPLEMENT_HOOKS(treasurelist) -IMPLEMENT_HOOKS(unitlist) -IMPLEMENT_HOOKS(unit) IMPLEMENT_HOOKS(update_region) -IMPLEMENT_HOOKS(wages) -IMPLEMENT_HOOKS(workquota_condition) -IMPLEMENT_HOOKS(workquota_details) -IMPLEMENT_HOOKS(workshop_profile) +IMPLEMENT_HOOKS(world) #undef IMPLEMENT_HOOKS @@ -262,85 +128,20 @@ DFhackCExport command_result plugin_enable(color_ostream &out, bool enable) { DEBUG(control).print("%sing interpose hooks\n", enable ? "enabl" : "disabl"); if (INTERPOSE_HOOKS_FAILED(adopt_region) || - INTERPOSE_HOOKS_FAILED(adventure_log) || - INTERPOSE_HOOKS_FAILED(announcelist) || - INTERPOSE_HOOKS_FAILED(assign_display_item) || - INTERPOSE_HOOKS_FAILED(barter) || - INTERPOSE_HOOKS_FAILED(buildinglist) || - INTERPOSE_HOOKS_FAILED(building) || INTERPOSE_HOOKS_FAILED(choose_start_site) || - INTERPOSE_HOOKS_FAILED(civlist) || - INTERPOSE_HOOKS_FAILED(counterintelligence) || - INTERPOSE_HOOKS_FAILED(createquota) || - INTERPOSE_HOOKS_FAILED(customize_unit) || - INTERPOSE_HOOKS_FAILED(dungeonmode) || - INTERPOSE_HOOKS_FAILED(dungeon_monsterstatus) || - INTERPOSE_HOOKS_FAILED(dungeon_wrestle) || + INTERPOSE_HOOKS_FAILED(choose_game_type) || INTERPOSE_HOOKS_FAILED(dwarfmode) || - INTERPOSE_HOOKS_FAILED(entity) || - INTERPOSE_HOOKS_FAILED(export_graphical_map) || INTERPOSE_HOOKS_FAILED(export_region) || INTERPOSE_HOOKS_FAILED(game_cleaner) || - INTERPOSE_HOOKS_FAILED(image_creator) || - INTERPOSE_HOOKS_FAILED(item) || - INTERPOSE_HOOKS_FAILED(joblist) || - INTERPOSE_HOOKS_FAILED(jobmanagement) || - INTERPOSE_HOOKS_FAILED(job) || - INTERPOSE_HOOKS_FAILED(justice) || - INTERPOSE_HOOKS_FAILED(kitchenpref) || - INTERPOSE_HOOKS_FAILED(layer_arena_creature) || - INTERPOSE_HOOKS_FAILED(layer_assigntrade) || - INTERPOSE_HOOKS_FAILED(layer_choose_language_name) || - INTERPOSE_HOOKS_FAILED(layer_currency) || - INTERPOSE_HOOKS_FAILED(layer_export_play_map) || - INTERPOSE_HOOKS_FAILED(layer_military) || - INTERPOSE_HOOKS_FAILED(layer_musicsound) || - INTERPOSE_HOOKS_FAILED(layer_noblelist) || - INTERPOSE_HOOKS_FAILED(layer_overall_health) || - INTERPOSE_HOOKS_FAILED(layer_reaction) || - INTERPOSE_HOOKS_FAILED(layer_squad_schedule) || - INTERPOSE_HOOKS_FAILED(layer_stockpile) || - INTERPOSE_HOOKS_FAILED(layer_stone_restriction) || - INTERPOSE_HOOKS_FAILED(layer_unit_action) || - INTERPOSE_HOOKS_FAILED(layer_unit_health) || - INTERPOSE_HOOKS_FAILED(layer_unit_relationship) || - INTERPOSE_HOOKS_FAILED(layer_world_gen_param_preset) || - INTERPOSE_HOOKS_FAILED(layer_world_gen_param) || + INTERPOSE_HOOKS_FAILED(initial_prep) || INTERPOSE_HOOKS_FAILED(legends) || INTERPOSE_HOOKS_FAILED(loadgame) || - INTERPOSE_HOOKS_FAILED(locations) || - INTERPOSE_HOOKS_FAILED(meeting) || - INTERPOSE_HOOKS_FAILED(movieplayer) || INTERPOSE_HOOKS_FAILED(new_region) || - INTERPOSE_HOOKS_FAILED(noble) || - INTERPOSE_HOOKS_FAILED(option) || - INTERPOSE_HOOKS_FAILED(overallstatus) || - INTERPOSE_HOOKS_FAILED(petitions) || - INTERPOSE_HOOKS_FAILED(pet) || - INTERPOSE_HOOKS_FAILED(price) || - INTERPOSE_HOOKS_FAILED(reportlist) || - INTERPOSE_HOOKS_FAILED(requestagreement) || INTERPOSE_HOOKS_FAILED(savegame) || - INTERPOSE_HOOKS_FAILED(selectitem) || - INTERPOSE_HOOKS_FAILED(setupadventure) || INTERPOSE_HOOKS_FAILED(setupdwarfgame) || - INTERPOSE_HOOKS_FAILED(stores) || - INTERPOSE_HOOKS_FAILED(textviewer) || INTERPOSE_HOOKS_FAILED(title) || - INTERPOSE_HOOKS_FAILED(topicmeeting_fill_land_holder_positions) || - INTERPOSE_HOOKS_FAILED(topicmeeting) || - INTERPOSE_HOOKS_FAILED(topicmeeting_takerequests) || - INTERPOSE_HOOKS_FAILED(tradeagreement) || - INTERPOSE_HOOKS_FAILED(tradegoods) || - INTERPOSE_HOOKS_FAILED(tradelist) || - INTERPOSE_HOOKS_FAILED(treasurelist) || - INTERPOSE_HOOKS_FAILED(unitlist) || - INTERPOSE_HOOKS_FAILED(unit) || INTERPOSE_HOOKS_FAILED(update_region) || - INTERPOSE_HOOKS_FAILED(wages) || - INTERPOSE_HOOKS_FAILED(workquota_condition) || - INTERPOSE_HOOKS_FAILED(workquota_details) || - INTERPOSE_HOOKS_FAILED(workshop_profile)) + INTERPOSE_HOOKS_FAILED(world)) return CR_FAILURE; is_enabled = enable; diff --git a/plugins/pathable.cpp b/plugins/pathable.cpp index e5a9bebcc..7ed7fffd0 100644 --- a/plugins/pathable.cpp +++ b/plugins/pathable.cpp @@ -1,82 +1,97 @@ -#include "Console.h" -#include "Core.h" -#include "DataDefs.h" -#include "DataFuncs.h" -#include "DataIdentity.h" -#include "Export.h" -#include "LuaTools.h" -#include "PluginManager.h" #include "modules/Gui.h" #include "modules/Maps.h" #include "modules/Screen.h" -#include "df/world.h" + +#include "Debug.h" +#include "LuaTools.h" +#include "PluginManager.h" using namespace DFHack; DFHACK_PLUGIN("pathable"); -REQUIRE_GLOBAL(world); + +REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(window_x); REQUIRE_GLOBAL(window_y); REQUIRE_GLOBAL(window_z); +REQUIRE_GLOBAL(world); -DFhackCExport command_result plugin_init(color_ostream &out, std::vector &commands) -{ +namespace DFHack { + DBG_DECLARE(pathable, log, DebugCategory::LINFO); +} + +DFhackCExport command_result plugin_init(color_ostream &out, std::vector &commands) { return CR_OK; } -DFhackCExport command_result plugin_shutdown(color_ostream &out) -{ +DFhackCExport command_result plugin_shutdown(color_ostream &out) { return CR_OK; } -static void paintScreen(df::coord cursor, bool skip_unrevealed = false) -{ - auto dims = Gui::getDwarfmodeViewDims(); - for (int y = dims.map_y1; y <= dims.map_y2; y++) - { - for (int x = dims.map_x1; x <= dims.map_x2; x++) - { - Screen::Pen cur_tile = Screen::readTile(x, y, true); - if (!cur_tile.valid()) - continue; +static void paintScreen(df::coord target, bool skip_unrevealed = false) { + DEBUG(log).print("entering paintScreen\n"); + + bool use_graphics = Screen::inGraphicsMode(); + + int selected_tile_texpos = 0; + Screen::findGraphicsTile("CURSORS", 4, 3, &selected_tile_texpos); - df::coord map_pos( - *window_x + x - dims.map_x1, - *window_y + y - dims.map_y1, - *window_z - ); + auto dims = Gui::getDwarfmodeViewDims().map(); + for (int y = dims.first.y; y <= dims.second.y; ++y) { + for (int x = dims.first.x; x <= dims.second.x; ++x) { + df::coord map_pos(*window_x + x, *window_y + y, *window_z); - // Keep yellow cursor - if (map_pos == cursor) + if (!Maps::isValidTilePos(map_pos)) continue; - if (map_pos.x < 0 || map_pos.x >= world->map.x_count || - map_pos.y < 0 || map_pos.y >= world->map.y_count || - map_pos.z < 0 || map_pos.z >= world->map.z_count) - { + // don't overwrite the target tile + if (!use_graphics && map_pos == target) { + TRACE(log).print("skipping target tile\n"); continue; } - if (skip_unrevealed && !Maps::isTileVisible(map_pos)) + if (skip_unrevealed && !Maps::isTileVisible(map_pos)) { + TRACE(log).print("skipping hidden tile\n"); continue; + } - int color = Maps::canWalkBetween(cursor, map_pos) ? COLOR_GREEN : COLOR_RED; + DEBUG(log).print("scanning map tile at offset %d, %d\n", x, y); + Screen::Pen cur_tile = Screen::readTile(x, y, true); + DEBUG(log).print("tile data: ch=%d, fg=%d, bg=%d, bold=%s\n", + cur_tile.ch, cur_tile.fg, cur_tile.bg, cur_tile.bold ? "true" : "false"); + DEBUG(log).print("tile data: tile=%d, tile_mode=%d, tile_fg=%d, tile_bg=%d\n", + cur_tile.tile, cur_tile.tile_mode, cur_tile.tile_fg, cur_tile.tile_bg); - if (cur_tile.fg && cur_tile.ch != ' ') - { - cur_tile.fg = color; - cur_tile.bg = 0; - } - else - { - cur_tile.fg = 0; - cur_tile.bg = color; + if (!cur_tile.valid()) { + DEBUG(log).print("cannot read tile at offset %d, %d\n", x, y); + continue; } - cur_tile.bold = false; + bool can_walk = Maps::canWalkBetween(target, map_pos); + DEBUG(log).print("tile is %swalkable at offset %d, %d\n", + can_walk ? "" : "not ", x, y); + + if (use_graphics) { + if (map_pos == target) { + cur_tile.tile = selected_tile_texpos; + } else{ + cur_tile.tile = can_walk ? 779 : 782; + } + } else { + int color = can_walk ? COLOR_GREEN : COLOR_RED; + if (cur_tile.fg && cur_tile.ch != ' ') { + cur_tile.fg = color; + cur_tile.bg = 0; + } else { + cur_tile.fg = 0; + cur_tile.bg = color; + } - if (cur_tile.tile) - cur_tile.tile_mode = Screen::Pen::CharColor; + cur_tile.bold = false; + + if (cur_tile.tile) + cur_tile.tile_mode = Screen::Pen::CharColor; + } Screen::paintTile(cur_tile, x, y, true); } diff --git a/plugins/power-meter.cpp b/plugins/power-meter.cpp index c61c3c8ee..f5f4ac63f 100644 --- a/plugins/power-meter.cpp +++ b/plugins/power-meter.cpp @@ -29,8 +29,8 @@ #include "df/machine_info.h" #include "df/report.h" #include "df/tile_designation.h" -#include "df/ui.h" -#include "df/ui_build_selector.h" +#include "df/plotinfost.h" +#include "df/buildreq.h" #include "df/viewscreen_dwarfmodest.h" #include "df/world.h" @@ -43,7 +43,7 @@ using namespace df::enums; DFHACK_PLUGIN("power-meter"); REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(ui_build_selector); static const uint32_t METER_BIT = 0x80000000U; diff --git a/plugins/remotefortressreader/adventure_control.cpp b/plugins/remotefortressreader/adventure_control.cpp index 6fb592d62..2dbf2abc1 100644 --- a/plugins/remotefortressreader/adventure_control.cpp +++ b/plugins/remotefortressreader/adventure_control.cpp @@ -7,7 +7,7 @@ #include "df/adventure_movement_hold_itemst.h" #include "df/adventure_movement_hold_tilest.h" #include "df/adventure_movement_optionst.h" -#include "df/ui_advmode.h" +#include "df/adventurest.h" #include "df/viewscreen.h" #include "modules/Gui.h" @@ -42,7 +42,7 @@ command_result MoveCommand(DFHack::color_ostream &stream, const MoveCommandParam auto viewScreen = getCurViewscreen(); if (!in->has_direction()) return CR_WRONG_USAGE; - if (!df::global::ui_advmode->menu == ui_advmode_menu::Default) + if (!df::global::adventure->menu == ui_advmode_menu::Default) return CR_OK; auto dir = in->direction(); switch (dir.x()) @@ -193,7 +193,7 @@ command_result JumpCommand(DFHack::color_ostream &stream, const MoveCommandParam { if (!in->has_direction()) return CR_WRONG_USAGE; - if (!df::global::ui_advmode->menu == ui_advmode_menu::Default) + if (!df::global::adventure->menu == ui_advmode_menu::Default) return CR_OK; auto dir = in->direction(); keyQueue.push(interface_key::A_JUMP); @@ -233,7 +233,7 @@ command_result JumpCommand(DFHack::color_ostream &stream, const MoveCommandParam command_result MenuQuery(DFHack::color_ostream &stream, const EmptyMessage *in, MenuContents *out) { - auto advUi = df::global::ui_advmode; + auto advUi = df::global::adventure; if (advUi == NULL) return CR_FAILURE; @@ -278,7 +278,7 @@ command_result MenuQuery(DFHack::color_ostream &stream, const EmptyMessage *in, command_result MovementSelectCommand(DFHack::color_ostream &stream, const dfproto::IntMessage *in) { - if (!(df::global::ui_advmode->menu == ui_advmode_menu::MoveCarefully)) + if (!(df::global::adventure->menu == ui_advmode_menu::MoveCarefully)) return CR_OK; int choice = in->value(); int page = choice / 5; @@ -293,7 +293,7 @@ command_result MovementSelectCommand(DFHack::color_ostream &stream, const dfprot command_result MiscMoveCommand(DFHack::color_ostream &stream, const MiscMoveParams *in) { - if (!df::global::ui_advmode->menu == ui_advmode_menu::Default) + if (!df::global::adventure->menu == ui_advmode_menu::Default) return CR_OK; auto type = in->type(); diff --git a/plugins/remotefortressreader/dwarf_control.cpp b/plugins/remotefortressreader/dwarf_control.cpp index 3a5933464..f0147670f 100644 --- a/plugins/remotefortressreader/dwarf_control.cpp +++ b/plugins/remotefortressreader/dwarf_control.cpp @@ -12,9 +12,9 @@ #include "df/job_list_link.h" #include "df/interface_button_construction_building_selectorst.h" #include "df/interface_button_construction_category_selectorst.h" -#include "df/ui.h" -#include "df/ui_build_selector.h" -#include "df/ui_sidebar_menus.h" +#include "df/plotinfost.h" +#include "df/buildreq.h" +#include "df/gamest.h" #include "df/viewscreen.h" #include "df/world.h" @@ -233,7 +233,7 @@ command_result SetPauseState(color_ostream &stream, const SingleBool *in) void CopyBuildMenu(DwarfControl::SidebarState * out) { - auto menus = df::global::ui_sidebar_menus; + auto menus = df::global::game; auto build_selector = df::global::ui_build_selector; if (build_selector->building_type == -1) for (size_t i = 0; i < menus->building.choices_visible.size(); i++) @@ -303,9 +303,9 @@ void CopyBuildMenu(DwarfControl::SidebarState * out) command_result GetSideMenu(DFHack::color_ostream &stream, const dfproto::EmptyMessage *in, DwarfControl::SidebarState *out) { - auto ui = df::global::ui; - out->set_mode((proto::enums::ui_sidebar_mode::ui_sidebar_mode)ui->main.mode); - auto mode = ui->main.mode; + auto plotinfo = df::global::plotinfo; + out->set_mode((proto::enums::ui_sidebar_mode::ui_sidebar_mode)plotinfo->main.mode); + auto mode = plotinfo->main.mode; switch (mode) { case ui_sidebar_mode::Default: @@ -427,25 +427,25 @@ command_result GetSideMenu(DFHack::color_ostream &stream, const dfproto::EmptyMe command_result SetSideMenu(DFHack::color_ostream &stream, const DwarfControl::SidebarCommand *in) { - auto ui = df::global::ui; + auto plotinfo = df::global::plotinfo; if (in->has_mode()) { ui_sidebar_mode::ui_sidebar_mode set_mode = (ui_sidebar_mode::ui_sidebar_mode)in->mode(); - if (ui->main.mode != set_mode) + if (plotinfo->main.mode != set_mode) { - ui->main.mode = ui_sidebar_mode::Default; + plotinfo->main.mode = ui_sidebar_mode::Default; switch (set_mode) { case ui_sidebar_mode::Build: keyQueue.push(interface_key::D_BUILDING); break; default: - ui->main.mode = set_mode; + plotinfo->main.mode = set_mode; break; } } } - switch (ui->main.mode) + switch (plotinfo->main.mode) { case ui_sidebar_mode::Build: if (in->has_action()) @@ -454,7 +454,7 @@ command_result SetSideMenu(DFHack::color_ostream &stream, const DwarfControl::Si if (in->has_menu_index()) index = in->menu_index(); if(ui_build_selector->building_type == -1) - df::global::ui_sidebar_menus->building.cursor = index; + df::global::game->building.cursor = index; if (ui_build_selector->stage == 2) { ui_build_selector->sel_index = index; diff --git a/plugins/remotefortressreader/remotefortressreader.cpp b/plugins/remotefortressreader/remotefortressreader.cpp index 643e92b21..536aa3b0d 100644 --- a/plugins/remotefortressreader/remotefortressreader.cpp +++ b/plugins/remotefortressreader/remotefortressreader.cpp @@ -89,7 +89,7 @@ #endif #include "df/tissue.h" #include "df/tissue_style_raw.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/unit.h" #include "df/unit_inventory_item.h" #include "df/unit_wound.h" @@ -135,9 +135,9 @@ using namespace df::global; #else REQUIRE_GLOBAL(world); REQUIRE_GLOBAL(gps); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(gamemode); -REQUIRE_GLOBAL(ui_advmode); +REQUIRE_GLOBAL(adventure); #endif // Here go all the command declarations... @@ -1887,8 +1887,8 @@ static command_result GetViewInfo(color_ostream &stream, const EmptyMessage *in, if (gamemode && *gamemode == GameMode::ADVENTURE) out->set_follow_unit_id(world->units.active[0]->id); else - out->set_follow_unit_id(ui->follow_unit); - out->set_follow_item_id(ui->follow_item); + out->set_follow_unit_id(plotinfo->follow_unit); + out->set_follow_item_id(plotinfo->follow_item); return CR_OK; } diff --git a/plugins/rename.cpp b/plugins/rename.cpp index 7c46fc908..68186cb74 100644 --- a/plugins/rename.cpp +++ b/plugins/rename.cpp @@ -13,8 +13,8 @@ #include "modules/Screen.h" #include -#include "df/ui.h" -#include "df/ui_sidebar_menus.h" +#include "df/plotinfost.h" +#include "df/gamest.h" #include "df/world.h" #include "df/squad.h" #include "df/unit.h" @@ -49,8 +49,8 @@ using namespace dfproto; DFHACK_PLUGIN("rename"); DFHACK_PLUGIN_IS_ENABLED(is_enabled); -REQUIRE_GLOBAL(ui); -REQUIRE_GLOBAL(ui_sidebar_menus); +REQUIRE_GLOBAL(plotinfo); +REQUIRE_GLOBAL(game); REQUIRE_GLOBAL(world); DFhackCExport command_result plugin_onstatechange(color_ostream &out, state_change_event event); @@ -59,7 +59,7 @@ static command_result rename(color_ostream &out, vector & parameters); DFhackCExport command_result plugin_init (color_ostream &out, std::vector &commands) { - if (world && ui) { + if (world && plotinfo) { commands.push_back(PluginCommand( "rename", "Easily rename things.", @@ -135,9 +135,9 @@ struct dwarf_render_zone_hook : df::viewscreen_dwarfmodest { { INTERPOSE_NEXT(render)(); - if (ui->main.mode == ui_sidebar_mode::Zones && - ui_sidebar_menus && ui_sidebar_menus->zone.selected && - !ui_sidebar_menus->zone.selected->name.empty()) + if (plotinfo->main.mode == ui_sidebar_mode::Zones && + game && game->zone.selected && + !game->zone.selected->name.empty()) { auto dims = Gui::getDwarfmodeViewDims(); int width = dims.menu_x2 - dims.menu_x1 - 1; @@ -146,7 +146,7 @@ struct dwarf_render_zone_hook : df::viewscreen_dwarfmodest { Screen::fillRect(pen, dims.menu_x1, dims.y1+1, dims.menu_x2, dims.y1+1); std::string name; - ui_sidebar_menus->zone.selected->getName(&name); + game->zone.selected->getName(&name); Screen::paintString(pen, dims.menu_x1+1, dims.y1+1, name.substr(0, width)); } } @@ -258,7 +258,7 @@ static bool renameBuilding(df::building *bld, std::string name) static df::squad *getSquadByIndex(unsigned idx) { - auto entity = df::historical_entity::find(ui->group_id); + auto entity = df::historical_entity::find(plotinfo->group_id); if (!entity) return NULL; @@ -361,7 +361,7 @@ static command_result rename(color_ostream &out, vector ¶meters) return CR_WRONG_USAGE; } - ui->main.hotkeys[id-1].name = parameters[2]; + plotinfo->main.hotkeys[id-1].name = parameters[2]; } else if (cmd == "unit") { diff --git a/plugins/rendermax/renderer_light.cpp b/plugins/rendermax/renderer_light.cpp index cc5d569c0..428de3a25 100644 --- a/plugins/rendermax/renderer_light.cpp +++ b/plugins/rendermax/renderer_light.cpp @@ -94,7 +94,7 @@ rect2d getMapViewport() { view_rb=area_x2; } - if (menu_posmain.mode!=0) + if (menu_posmain.mode!=0) { if (menu_pos >= area_pos) menu_pos = area_pos-1; diff --git a/plugins/rendermax/rendermax.cpp b/plugins/rendermax/rendermax.cpp index b7c703e09..6ed22fe77 100644 --- a/plugins/rendermax/rendermax.cpp +++ b/plugins/rendermax/rendermax.cpp @@ -31,7 +31,7 @@ REQUIRE_GLOBAL(cursor); REQUIRE_GLOBAL(enabler); REQUIRE_GLOBAL(gametype); REQUIRE_GLOBAL(gps); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(window_x); REQUIRE_GLOBAL(window_y); REQUIRE_GLOBAL(window_z); diff --git a/plugins/reveal.cpp b/plugins/reveal.cpp index 8d76bd54b..4a05f061f 100644 --- a/plugins/reveal.cpp +++ b/plugins/reveal.cpp @@ -12,6 +12,7 @@ #include "modules/World.h" #include "modules/MapCache.h" #include "modules/Gui.h" +#include "modules/Screen.h" #include "df/block_square_event_frozen_liquidst.h" #include "df/construction.h" @@ -184,16 +185,18 @@ command_result reveal(color_ostream &out, vector & params) else if(params[i] == "help" || params[i] == "?") return CR_WRONG_USAGE; } + auto& con = out; if(params.size() && params[0] == "hell") { no_hell = false; } if(params.size() && params[0] == "demon") { - no_hell = false; - pause = false; + con.printerr("`reveal demon` is currently disabled to prevent a hang due to a bug in the base game\n"); + return CR_FAILURE; + //no_hell = false; + //pause = false; } - auto & con = out; if(revealed != NOT_REVEALED) { con.printerr("Map is already revealed or this is a different map.\n"); @@ -256,9 +259,16 @@ command_result reveal(color_ostream &out, vector & params) revealed = DEMON_REVEALED; } is_active = nopause_state || (revealed == REVEALED); - con.print("Map revealed.\n"); + bool graphics_mode = Screen::inGraphicsMode(); + con.print("Map revealed.\n\n"); + if (graphics_mode) { + con.print("Note that in graphics mode, tiles that are not adjacent to open\n" + "space will not render but can still be examined by hovering over\n" + "them with the mouse. Switching to text mode (in the game settings)\n" + "will allow the display the revealed tiles.\n\n"); + } if(!no_hell) - con.print("Unpausing can unleash the forces of hell, so it has been temporarily disabled.\n"); + con.print("Unpausing can unleash the forces of hell, so it has been temporarily disabled.\n\n"); con.print("Run 'unreveal' to revert to previous state.\n"); return CR_OK; } diff --git a/plugins/search.cpp b/plugins/search.cpp index 9ecae6460..b69480778 100644 --- a/plugins/search.cpp +++ b/plugins/search.cpp @@ -52,7 +52,7 @@ DFHACK_PLUGIN_IS_ENABLED(is_enabled); REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(gview); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(ui_building_assign_units); REQUIRE_GLOBAL(ui_building_in_assign); REQUIRE_GLOBAL(ui_building_item_cursor); @@ -1878,7 +1878,7 @@ class look_menu_search : public look_menu_search_base public: bool can_init(df::viewscreen_dwarfmodest *screen) { - if (ui->main.mode == df::ui_sidebar_mode::LookAround) + if (plotinfo->main.mode == df::ui_sidebar_mode::LookAround) { return look_menu_search_base::can_init(screen); } @@ -1986,7 +1986,7 @@ class burrow_search : public burrow_search_base public: bool can_init(df::viewscreen_dwarfmodest *screen) { - if (ui->main.mode == df::ui_sidebar_mode::Burrows && ui->burrows.in_add_units_mode) + if (plotinfo->main.mode == df::ui_sidebar_mode::Burrows && plotinfo->burrows.in_add_units_mode) { return burrow_search_base::can_init(screen); } @@ -2011,17 +2011,17 @@ public: vector *get_primary_list() { - return &ui->burrows.list_units; + return &plotinfo->burrows.list_units; } vector *get_secondary_list() { - return &ui->burrows.sel_units; + return &plotinfo->burrows.sel_units; } virtual int32_t * get_viewscreen_cursor() { - return &ui->burrows.unit_cursor_pos; + return &plotinfo->burrows.unit_cursor_pos; } @@ -2055,7 +2055,7 @@ class room_assign_search : public room_assign_search_base public: bool can_init(df::viewscreen_dwarfmodest *screen) { - if (ui->main.mode == df::ui_sidebar_mode::QueryBuilding && *ui_building_in_assign) + if (plotinfo->main.mode == df::ui_sidebar_mode::QueryBuilding && *ui_building_in_assign) { return room_assign_search_base::can_init(screen); } diff --git a/plugins/siege-engine.cpp b/plugins/siege-engine.cpp index 55ea4eeab..2fbb1e8c8 100644 --- a/plugins/siege-engine.cpp +++ b/plugins/siege-engine.cpp @@ -47,8 +47,8 @@ #include "df/report.h" #include "df/stockpile_links.h" #include "df/strain_type.h" -#include "df/ui.h" -#include "df/ui_build_selector.h" +#include "df/plotinfost.h" +#include "df/buildreq.h" #include "df/unit.h" #include "df/unit_misc_trait.h" #include "df/unit_relationship_type.h" @@ -72,7 +72,7 @@ DFHACK_PLUGIN("siege-engine"); REQUIRE_GLOBAL(gamemode); REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(ui_build_selector); REQUIRE_GLOBAL(process_jobs); @@ -1477,7 +1477,7 @@ static bool isTired(df::unit *worker) static void releaseTiredWorker(EngineInfo *engine, df::job *job, df::unit *worker) { // If not in siege - auto &sieges = ui->invasions.list; + auto &sieges = plotinfo->invasions.list; for (size_t i = 0; i < sieges.size(); i++) if (sieges[i]->flags.bits.active) diff --git a/plugins/sort.cpp b/plugins/sort.cpp index 630ac9e53..62af2c416 100644 --- a/plugins/sort.cpp +++ b/plugins/sort.cpp @@ -11,7 +11,7 @@ #include "LuaTools.h" #include "DataDefs.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/world.h" #include "df/viewscreen_joblistst.h" #include "df/viewscreen_unitlistst.h" @@ -38,7 +38,7 @@ using namespace DFHack; using namespace df::enums; DFHACK_PLUGIN("sort"); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(world); REQUIRE_GLOBAL(ui_building_in_assign); REQUIRE_GLOBAL(ui_building_item_cursor); @@ -379,11 +379,11 @@ DEFINE_SORT_HANDLER(unit_sorters, dwarfmode, "/Burrows/AddUnits", screen) { PARSE_SPEC("units", parameters); - if (compute_order(*pout, L, top, &order, ui->burrows.list_units)) + if (compute_order(*pout, L, top, &order, plotinfo->burrows.list_units)) { - reorder_cursor(&ui->burrows.unit_cursor_pos, order); - reorder_vector(&ui->burrows.list_units, order); - reorder_vector(&ui->burrows.sel_units, order); + reorder_cursor(&plotinfo->burrows.unit_cursor_pos, order); + reorder_vector(&plotinfo->burrows.list_units, order); + reorder_vector(&plotinfo->burrows.sel_units, order); } } diff --git a/plugins/spectate/pause.cpp b/plugins/spectate/pause.cpp index 5c60e2194..0e4f1707d 100644 --- a/plugins/spectate/pause.cpp +++ b/plugins/spectate/pause.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include @@ -25,12 +25,12 @@ namespace pausing { bool locked_states[announcement_flag_arr_size]; // locked state (re-applied each frame) bool allow_player_pause = true; // toggles player pause ability - using df::global::ui; + using df::global::plotinfo; using namespace df::enums; struct player_pause_hook : df::viewscreen_dwarfmodest { typedef df::viewscreen_dwarfmodest interpose_base; DEFINE_VMETHOD_INTERPOSE(void, feed, (std::set* input)) { - if ((ui->main.mode == ui_sidebar_mode::Default) && !allow_player_pause) { + if ((plotinfo->main.mode == ui_sidebar_mode::Default) && !allow_player_pause) { input->erase(interface_key::D_PAUSE); } INTERPOSE_NEXT(feed)(input); diff --git a/plugins/spectate/spectate.cpp b/plugins/spectate/spectate.cpp index 73574c136..7bf3e1ec2 100644 --- a/plugins/spectate/spectate.cpp +++ b/plugins/spectate/spectate.cpp @@ -37,7 +37,7 @@ namespace DFHack { DFHACK_PLUGIN("spectate"); DFHACK_PLUGIN_IS_ENABLED(enabled); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(pause_state); REQUIRE_GLOBAL(d_init); @@ -106,7 +106,7 @@ namespace SP { out.print(" SETTINGS:\n"); out.print(" %-20s\t%" PRIi32 "\n", "tick-threshold: ", config.tick_threshold); if (following_dwarf) - out.print(" %-21s\t%s[id: %d]\n","FOLLOWING:", our_dorf ? our_dorf->name.first_name.c_str() : "nullptr", df::global::ui->follow_unit); + out.print(" %-21s\t%s[id: %d]\n","FOLLOWING:", our_dorf ? our_dorf->name.first_name.c_str() : "nullptr", df::global::plotinfo->follow_unit); } void SetUnpauseState(bool state) { @@ -311,7 +311,7 @@ namespace SP { // if you're looking at a warning about a local address escaping, it means the unit* from units (which aren't local) size_t idx = follow_any(RNG); our_dorf = units[idx]; - df::global::ui->follow_unit = our_dorf->id; + df::global::plotinfo->follow_unit = our_dorf->id; timestamp = df::global::world->frame_counter; return true; } else { @@ -362,7 +362,7 @@ namespace SP { if (!World::ReadPauseState() && tick - last_tick >= 1) { last_tick = tick; // validate follow state - if (!following_dwarf || !our_dorf || df::global::ui->follow_unit < 0 || tick - timestamp >= config.tick_threshold) { + if (!following_dwarf || !our_dorf || df::global::plotinfo->follow_unit < 0 || tick - timestamp >= config.tick_threshold) { // we're not following anyone following_dwarf = false; if (!config.disengage) { diff --git a/plugins/steam-engine.cpp b/plugins/steam-engine.cpp index 6e3c317d3..ac7803b95 100644 --- a/plugins/steam-engine.cpp +++ b/plugins/steam-engine.cpp @@ -31,8 +31,8 @@ #include "df/power_info.h" #include "df/report.h" #include "df/tile_designation.h" -#include "df/ui.h" -#include "df/ui_build_selector.h" +#include "df/plotinfost.h" +#include "df/buildreq.h" #include "df/viewscreen_dwarfmodest.h" #include "df/workshop_type.h" #include "df/world.h" @@ -48,7 +48,7 @@ DFHACK_PLUGIN("steam-engine"); REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(ui_build_selector); REQUIRE_GLOBAL(cursor); @@ -748,7 +748,7 @@ struct dwarfmode_hook : df::viewscreen_dwarfmodest steam_engine_workshop *get_steam_engine() { - if (ui->main.mode == ui_sidebar_mode::Build && + if (plotinfo->main.mode == ui_sidebar_mode::Build && ui_build_selector->stage == 1 && ui_build_selector->building_type == building_type::Workshop && ui_build_selector->building_subtype == workshop_type::Custom) diff --git a/plugins/stockflow.cpp b/plugins/stockflow.cpp index 65223f603..49d56816b 100644 --- a/plugins/stockflow.cpp +++ b/plugins/stockflow.cpp @@ -26,7 +26,7 @@ DFHACK_PLUGIN_IS_ENABLED(enabled); REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); bool fast = false; @@ -56,15 +56,15 @@ public: if (found) { // Entice the bookkeeper to spend less time update records. - ui->nobles.bookkeeper_precision += ui->nobles.bookkeeper_precision >> 3; + plotinfo->nobles.bookkeeper_precision += plotinfo->nobles.bookkeeper_precision >> 3; if (!bookkeeping) { command_method("start_bookkeeping", out); bookkeeping = true; } } else { // Entice the bookkeeper to update records more often. - ui->nobles.bookkeeper_precision -= ui->nobles.bookkeeper_precision >> 5; - ui->nobles.bookkeeper_cooldown -= ui->nobles.bookkeeper_cooldown >> 2; + plotinfo->nobles.bookkeeper_precision -= plotinfo->nobles.bookkeeper_precision >> 5; + plotinfo->nobles.bookkeeper_cooldown -= plotinfo->nobles.bookkeeper_cooldown >> 2; if (bookkeeping) { command_method("finish_bookkeeping", out); bookkeeping = false; diff --git a/plugins/stockpiles/stockpiles.cpp b/plugins/stockpiles/stockpiles.cpp index aa36e20bd..4b61ff175 100644 --- a/plugins/stockpiles/stockpiles.cpp +++ b/plugins/stockpiles/stockpiles.cpp @@ -21,7 +21,7 @@ #include "df/world_data.h" #include "DataDefs.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/building_stockpilest.h" #include "df/stockpile_settings.h" #include "df/global_objects.h" @@ -42,7 +42,7 @@ using namespace dfstockpiles; DFHACK_PLUGIN ( "stockpiles" ); REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(selection_rect); using df::building_stockpilest; @@ -59,7 +59,7 @@ static bool loadstock_guard ( df::viewscreen *top ); DFhackCExport command_result plugin_init ( color_ostream &out, std::vector &commands ) { - if ( world && ui ) + if ( world && plotinfo ) { commands.push_back(PluginCommand( "copystock", @@ -106,7 +106,7 @@ static bool copystock_guard ( df::viewscreen *top ) if ( !Gui::dwarfmode_hotkey ( top ) ) return false; - switch ( ui->main.mode ) + switch ( plotinfo->main.mode ) { case Stockpiles: return true; @@ -123,10 +123,10 @@ static command_result copystock ( color_ostream &out, vector & paramete // HOTKEY COMMAND: CORE ALREADY SUSPENDED // For convenience: when used in the stockpiles mode, switch to 'q' - if ( ui->main.mode == ui_sidebar_mode::Stockpiles ) + if ( plotinfo->main.mode == ui_sidebar_mode::Stockpiles ) { world->selected_building = NULL; // just in case it contains some kind of garbage - ui->main.mode = ui_sidebar_mode::QueryBuilding; + plotinfo->main.mode = ui_sidebar_mode::QueryBuilding; selection_rect->start_x = -30000; out << "Switched back to query building." << endl; @@ -140,8 +140,8 @@ static command_result copystock ( color_ostream &out, vector & paramete return CR_WRONG_USAGE; } - ui->stockpile.custom_settings = sp->settings; - ui->main.mode = ui_sidebar_mode::Stockpiles; + plotinfo->stockpile.custom_settings = sp->settings; + plotinfo->main.mode = ui_sidebar_mode::Stockpiles; world->selected_stockpile_type = stockpile_category::Custom; out << "Stockpile options copied." << endl; @@ -156,7 +156,7 @@ static bool savestock_guard ( df::viewscreen *top ) if ( !Gui::dwarfmode_hotkey ( top ) ) return false; - switch ( ui->main.mode ) + switch ( plotinfo->main.mode ) { case Stockpiles: return true; @@ -175,7 +175,7 @@ static bool loadstock_guard ( df::viewscreen *top ) if ( !Gui::dwarfmode_hotkey ( top ) ) return false; - switch ( ui->main.mode ) + switch ( plotinfo->main.mode ) { case Stockpiles: return true; diff --git a/plugins/stocks.cpp b/plugins/stocks.cpp index 62c13dcd5..8cc27067c 100644 --- a/plugins/stocks.cpp +++ b/plugins/stocks.cpp @@ -27,7 +27,7 @@ #include "modules/Maps.h" #include "modules/Units.h" #include "df/building_cagest.h" -#include "df/ui_advmode.h" +#include "df/adventurest.h" DFHACK_PLUGIN("stocks"); #define PLUGIN_VERSION 0.13 diff --git a/plugins/stonesense b/plugins/stonesense index 25e7452f0..7b44c9dd0 160000 --- a/plugins/stonesense +++ b/plugins/stonesense @@ -1 +1 @@ -Subproject commit 25e7452f01b49b0a479d2c77a922cabbb7fd1e4c +Subproject commit 7b44c9dd0e0316c3edb66393de08591c95264e1a diff --git a/plugins/strangemood.cpp b/plugins/strangemood.cpp index a5b8e74a4..f6dd1f747 100644 --- a/plugins/strangemood.cpp +++ b/plugins/strangemood.cpp @@ -23,7 +23,7 @@ #include "df/job.h" #include "df/job_item.h" #include "df/map_block.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/unit.h" #include "df/unit_preference.h" #include "df/unit_relationship_type.h" @@ -39,7 +39,7 @@ using namespace df::enums; DFHACK_PLUGIN("strangemood"); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(d_init); REQUIRE_GLOBAL(created_item_count); REQUIRE_GLOBAL(created_item_type); @@ -394,7 +394,7 @@ command_result df_strangemood (color_ostream &out, vector & parameters) out.printerr("Strange moods disabled via debug flag!\n"); return CR_FAILURE; } - if (ui->mood_cooldown && !force) + if (plotinfo->mood_cooldown && !force) { out.printerr("Last strange mood happened too recently!\n"); return CR_FAILURE; @@ -406,7 +406,7 @@ command_result df_strangemood (color_ostream &out, vector & parameters) df::unit *cur = world->units.active[i]; if (Units::isCitizen(cur) && cur->flags1.bits.has_mood) { - ui->mood_cooldown = 1000; + plotinfo->mood_cooldown = 1000; out.printerr("A strange mood is already in progress!\n"); return CR_FAILURE; } @@ -466,12 +466,12 @@ command_result df_strangemood (color_ostream &out, vector & parameters) if (blk->designation[x][y].bits.subterranean && !blk->designation[x][y].bits.hidden) num_revealed_tiles++; } - if (num_revealed_tiles / 2304 < ui->tasks.num_artifacts) + if (num_revealed_tiles / 2304 < plotinfo->tasks.num_artifacts) { out.printerr("Fortress is not eligible for a strange mood at this time - not enough subterranean tiles revealed.\n"); return CR_FAILURE; } - if (num_items / 200 < ui->tasks.num_artifacts) + if (num_items / 200 < plotinfo->tasks.num_artifacts) { out.printerr("Fortress is not eligible for a strange mood at this time - not enough items created\n"); return CR_FAILURE; @@ -544,7 +544,7 @@ command_result df_strangemood (color_ostream &out, vector & parameters) return CR_FAILURE; } - ui->mood_cooldown = 1000; + plotinfo->mood_cooldown = 1000; // If no mood type was specified, pick one randomly if (type == mood_type::None) { @@ -1034,7 +1034,7 @@ command_result df_strangemood (color_ostream &out, vector & parameters) (job->job_type == job_type::StrangeMoodFell) )) { - int extra_items = std::min(rng.df_trandom((ui->tasks.num_artifacts * 20 + moodable_units.size()) / 20 + 1), 7); + int extra_items = std::min(rng.df_trandom((plotinfo->tasks.num_artifacts * 20 + moodable_units.size()) / 20 + 1), 7); df::item_type avoid_type = item_type::NONE; int avoid_glass = 0; switch (skill) diff --git a/plugins/tailor.cpp b/plugins/tailor.cpp index bd11988d0..0a8a82f5b 100644 --- a/plugins/tailor.cpp +++ b/plugins/tailor.cpp @@ -20,7 +20,7 @@ #include "df/job.h" #include "df/job_type.h" #include "df/manager_order.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/world.h" #include "modules/Maps.h" @@ -32,14 +32,14 @@ using namespace DFHack; using namespace std; using df::global::world; -using df::global::ui; +using df::global::plotinfo; DFHACK_PLUGIN("tailor"); #define AUTOENABLE false DFHACK_PLUGIN_IS_ENABLED(enabled); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); class Tailor { // ARMOR, SHOES, HELM, GLOVES, PANTS @@ -261,7 +261,7 @@ private: void create_orders() { - auto entity = world->entities.all[ui->civ_id]; + auto entity = world->entities.all[plotinfo->civ_id]; for (auto& a : needed) { @@ -325,7 +325,7 @@ private: void place_orders() { - auto entity = world->entities.all[ui->civ_id]; + auto entity = world->entities.all[plotinfo->civ_id]; for (auto& o : orders) { diff --git a/plugins/trackstop.cpp b/plugins/trackstop.cpp index d21df0e36..43807ea8c 100644 --- a/plugins/trackstop.cpp +++ b/plugins/trackstop.cpp @@ -26,7 +26,7 @@ DFHACK_PLUGIN("trackstop"); DFHACK_PLUGIN_IS_ENABLED(enabled); REQUIRE_GLOBAL(gps); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(world); /* @@ -44,7 +44,7 @@ struct trackstop_hook : public df::viewscreen_dwarfmodest { }; building_trapst *get_selected_trackstop() { - if (ui->main.mode != ui_sidebar_mode::QueryBuilding) { + if (plotinfo->main.mode != ui_sidebar_mode::QueryBuilding) { // Not in a building's 'q' menu. return nullptr; } @@ -200,7 +200,7 @@ struct roller_hook : public df::viewscreen_dwarfmodest { }; building_rollersst *get_selected_roller() { - if (ui->main.mode != ui_sidebar_mode::QueryBuilding) { + if (plotinfo->main.mode != ui_sidebar_mode::QueryBuilding) { // Not in a building's 'q' menu. return nullptr; } diff --git a/plugins/tweak/tweak.cpp b/plugins/tweak/tweak.cpp index 6d2a46fa8..323f5f932 100644 --- a/plugins/tweak/tweak.cpp +++ b/plugins/tweak/tweak.cpp @@ -21,7 +21,7 @@ #include "DataDefs.h" #include #include "../uicommon.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/world.h" #include "df/unit.h" #include "df/unit_soul.h" @@ -36,8 +36,8 @@ #include "df/viewscreen_dwarfmodest.h" #include "df/viewscreen_kitchenprefst.h" #include "df/viewscreen_layer_unit_actionst.h" -#include "df/ui_build_selector.h" -#include "df/ui_sidebar_menus.h" +#include "df/buildreq.h" +#include "df/gamest.h" #include "df/building_trapst.h" #include "df/building_workshopst.h" #include "df/item_actual.h" @@ -78,7 +78,7 @@ #include "tweaks/block-labors.h" #include "tweaks/burrow-name-cancel.h" #include "tweaks/cage-butcher.h" -#include "tweaks/civ-agreement-ui.h" +#include "tweaks/civ-agreement-plotinfo.h" #include "tweaks/condition-material.h" #include "tweaks/craft-age-wear.h" #include "tweaks/do-job-now.h" @@ -117,14 +117,14 @@ DFHACK_PLUGIN("tweak"); DFHACK_PLUGIN_IS_ENABLED(is_enabled); REQUIRE_GLOBAL(enabler); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(ui_build_selector); REQUIRE_GLOBAL(ui_building_in_assign); REQUIRE_GLOBAL(ui_building_in_resize); REQUIRE_GLOBAL(ui_building_item_cursor); REQUIRE_GLOBAL(ui_look_cursor); REQUIRE_GLOBAL(ui_menu_width); -REQUIRE_GLOBAL(ui_sidebar_menus); +REQUIRE_GLOBAL(game); REQUIRE_GLOBAL(ui_unit_view_mode); REQUIRE_GLOBAL(ui_workshop_in_add); REQUIRE_GLOBAL(world); @@ -449,7 +449,7 @@ static command_result tweak(color_ostream &out, vector ¶meters) // if it happens that the player has 'foreign' units of the same race // (vanilla df: dwarves not from mountainhome) on his map, just grab them if(!Units::isOwnCiv(unit)) - unit->civ_id = ui->civ_id; + unit->civ_id = plotinfo->civ_id; return fix_clothing_ownership(out, unit); } @@ -468,7 +468,7 @@ static command_result tweak(color_ostream &out, vector ¶meters) if(Units::isForest(unit)) unit->flags1.bits.forest = 0; if(!Units::isOwnCiv(unit)) - unit->civ_id = ui->civ_id; + unit->civ_id = plotinfo->civ_id; if(unit->profession == df::profession::MERCHANT) unit->profession = df::profession::TRADER; if(unit->profession2 == df::profession::MERCHANT) diff --git a/plugins/tweak/tweaks/block-labors.h b/plugins/tweak/tweaks/block-labors.h index bc407ed19..df2474400 100644 --- a/plugins/tweak/tweaks/block-labors.h +++ b/plugins/tweak/tweaks/block-labors.h @@ -6,7 +6,7 @@ #include "df/viewscreen_dwarfmodest.h" using namespace DFHack; -using df::global::ui; +using df::global::plotinfo; using df::global::ui_look_cursor; using df::global::ui_unit_view_mode; @@ -15,7 +15,7 @@ struct block_labors_hook : df::viewscreen_dwarfmodest { inline bool valid_mode() { - return ui->main.mode == df::ui_sidebar_mode::ViewUnits && + return plotinfo->main.mode == df::ui_sidebar_mode::ViewUnits && ui_unit_view_mode->value == df::ui_unit_view_mode::T_value::PrefLabor && Gui::getAnyUnit(this); } diff --git a/plugins/tweak/tweaks/burrow-name-cancel.h b/plugins/tweak/tweaks/burrow-name-cancel.h index 2ee84508e..f49e7ae1b 100644 --- a/plugins/tweak/tweaks/burrow-name-cancel.h +++ b/plugins/tweak/tweaks/burrow-name-cancel.h @@ -1,6 +1,6 @@ #include "df/burrow.h" -using df::global::ui; +using df::global::plotinfo; struct burrow_name_cancel_hook : df::viewscreen_dwarfmodest { typedef df::viewscreen_dwarfmodest interpose_base; @@ -9,15 +9,15 @@ struct burrow_name_cancel_hook : df::viewscreen_dwarfmodest { DEFINE_VMETHOD_INTERPOSE(void, feed, (std::set *input)) { - if (ui->main.mode == df::ui_sidebar_mode::Burrows) + if (plotinfo->main.mode == df::ui_sidebar_mode::Burrows) { - bool was_naming = ui->burrows.in_edit_name_mode; + bool was_naming = plotinfo->burrows.in_edit_name_mode; INTERPOSE_NEXT(feed)(input); - df::burrow *burrow = vector_get(ui->burrows.list, ui->burrows.sel_index); + df::burrow *burrow = vector_get(plotinfo->burrows.list, plotinfo->burrows.sel_index); if (!burrow) return; - if (ui->burrows.in_edit_name_mode) + if (plotinfo->burrows.in_edit_name_mode) { if (!was_naming) { @@ -27,7 +27,7 @@ struct burrow_name_cancel_hook : df::viewscreen_dwarfmodest { if (input->count(df::interface_key::LEAVESCREEN)) { // Cancel and restore the old name - ui->burrows.in_edit_name_mode = false; + plotinfo->burrows.in_edit_name_mode = false; burrow->name = old_name; } } diff --git a/plugins/tweak/tweaks/cage-butcher.h b/plugins/tweak/tweaks/cage-butcher.h index 61a989d50..7290746a9 100644 --- a/plugins/tweak/tweaks/cage-butcher.h +++ b/plugins/tweak/tweaks/cage-butcher.h @@ -6,7 +6,7 @@ #include "df/unit.h" using namespace DFHack; -using df::global::ui; +using df::global::plotinfo; using df::global::ui_building_in_assign; using df::global::ui_building_in_resize; using df::global::ui_building_item_cursor; @@ -19,7 +19,7 @@ struct cage_butcher_hook : df::viewscreen_dwarfmodest { if (*ui_building_in_assign || *ui_building_in_resize) return nullptr; - if (ui->main.mode != df::ui_sidebar_mode::QueryBuilding) + if (plotinfo->main.mode != df::ui_sidebar_mode::QueryBuilding) return nullptr; auto cage = virtual_cast(Gui::getAnyBuilding(this)); diff --git a/plugins/tweak/tweaks/eggs-fertile.h b/plugins/tweak/tweaks/eggs-fertile.h index f4fe29569..b264b227f 100644 --- a/plugins/tweak/tweaks/eggs-fertile.h +++ b/plugins/tweak/tweaks/eggs-fertile.h @@ -6,15 +6,15 @@ using namespace DFHack; using namespace df::enums; using df::global::world; -using df::global::ui; +using df::global::plotinfo; struct egg_fertile_hook : df::viewscreen_dwarfmodest { typedef df::viewscreen_dwarfmodest interpose_base; df::building_nest_boxst* getNestBox() { - if (ui->main.mode != ui_sidebar_mode::QueryBuilding && - ui->main.mode != ui_sidebar_mode::BuildingItems) + if (plotinfo->main.mode != ui_sidebar_mode::QueryBuilding && + plotinfo->main.mode != ui_sidebar_mode::BuildingItems) return NULL; return virtual_cast(world->selected_building); } @@ -38,7 +38,7 @@ struct egg_fertile_hook : df::viewscreen_dwarfmodest { has_eggs = true; if (egg->egg_flags.bits.fertile) fertile = true; - if (ui->main.mode == ui_sidebar_mode::BuildingItems) + if (plotinfo->main.mode == ui_sidebar_mode::BuildingItems) { Screen::paintString( Screen::Pen(' ', fertile ? COLOR_LIGHTGREEN : COLOR_LIGHTRED), @@ -50,7 +50,7 @@ struct egg_fertile_hook : df::viewscreen_dwarfmodest { } ++idx; } - if (has_eggs && ui->main.mode == ui_sidebar_mode::QueryBuilding) + if (has_eggs && plotinfo->main.mode == ui_sidebar_mode::QueryBuilding) { Screen::paintString( Screen::Pen(' ', fertile ? COLOR_LIGHTGREEN : COLOR_LIGHTRED), diff --git a/plugins/tweak/tweaks/farm-plot-select.h b/plugins/tweak/tweaks/farm-plot-select.h index 696c7ca2e..7b2e440e1 100644 --- a/plugins/tweak/tweaks/farm-plot-select.h +++ b/plugins/tweak/tweaks/farm-plot-select.h @@ -4,7 +4,7 @@ using namespace df::enums; -using df::global::ui; +using df::global::plotinfo; using df::global::ui_building_item_cursor; using df::global::world; @@ -13,7 +13,7 @@ struct farm_select_hook : df::viewscreen_dwarfmodest { df::building_farmplotst* getFarmPlot() { - if (ui->main.mode != ui_sidebar_mode::QueryBuilding) + if (plotinfo->main.mode != ui_sidebar_mode::QueryBuilding) return NULL; VIRTUAL_CAST_VAR(farm_plot, df::building_farmplotst, world->selected_building); return farm_plot; @@ -44,12 +44,12 @@ struct farm_select_hook : df::viewscreen_dwarfmodest { return false; } - inline int32_t getSelectedCropId() { return ui->selected_farm_crops[*ui_building_item_cursor]; } + inline int32_t getSelectedCropId() { return plotinfo->selected_farm_crops[*ui_building_item_cursor]; } DEFINE_VMETHOD_INTERPOSE(void, feed, (set *input)) { df::building_farmplotst* farm_plot = getFarmPlot(); - if (farm_plot && ui->selected_farm_crops.size() > 0) + if (farm_plot && plotinfo->selected_farm_crops.size() > 0) { if (input->count(interface_key::SELECT_ALL)) { @@ -77,7 +77,7 @@ struct farm_select_hook : df::viewscreen_dwarfmodest { { INTERPOSE_NEXT(render)(); auto farm_plot = getFarmPlot(); - if (!farm_plot || !ui->selected_farm_crops.size()) + if (!farm_plot || !plotinfo->selected_farm_crops.size()) return; if (farm_plot->getBuildStage() != farm_plot->getMaxBuildStage()) return; diff --git a/plugins/tweak/tweaks/hide-priority.h b/plugins/tweak/tweaks/hide-priority.h index ef84a5831..6f096ee82 100644 --- a/plugins/tweak/tweaks/hide-priority.h +++ b/plugins/tweak/tweaks/hide-priority.h @@ -3,7 +3,7 @@ using namespace DFHack; using df::global::gps; -using df::global::ui_sidebar_menus; +using df::global::game; struct hide_priority_hook : df::viewscreen_dwarfmodest { typedef df::viewscreen_dwarfmodest interpose_base; @@ -14,7 +14,7 @@ struct hide_priority_hook : df::viewscreen_dwarfmodest { inline bool valid_mode () { - switch (ui->main.mode) + switch (plotinfo->main.mode) { case df::ui_sidebar_mode::DesignateMine: case df::ui_sidebar_mode::DesignateRemoveRamps: @@ -41,7 +41,7 @@ struct hide_priority_hook : df::viewscreen_dwarfmodest { DEFINE_VMETHOD_INTERPOSE(void, render, ()) { if (!was_valid_mode && valid_mode() && toggled_manually) { - ui_sidebar_menus->designation.priority_set = last_show_priorities_setting; + game->designation.priority_set = last_show_priorities_setting; } INTERPOSE_NEXT(render)(); if (valid_mode()) @@ -51,7 +51,7 @@ struct hide_priority_hook : df::viewscreen_dwarfmodest { { int x = dims.menu_x1 + 1, y = gps->dimy - (gps->dimy > 26 ? 8 : 7); OutputToggleString(x, y, "Show priorities", df::interface_key::CUSTOM_ALT_P, - ui_sidebar_menus->designation.priority_set, true, 0, + game->designation.priority_set, true, 0, COLOR_WHITE, COLOR_LIGHTRED); } } @@ -61,9 +61,9 @@ struct hide_priority_hook : df::viewscreen_dwarfmodest { { if (valid_mode() && input->count(df::interface_key::CUSTOM_ALT_P)) { - ui_sidebar_menus->designation.priority_set = !ui_sidebar_menus->designation.priority_set; + game->designation.priority_set = !game->designation.priority_set; toggled_manually = true; - last_show_priorities_setting = ui_sidebar_menus->designation.priority_set; + last_show_priorities_setting = game->designation.priority_set; } else INTERPOSE_NEXT(feed)(input); diff --git a/plugins/tweak/tweaks/hotkey-clear.h b/plugins/tweak/tweaks/hotkey-clear.h index bc85c112e..8d683a1bd 100644 --- a/plugins/tweak/tweaks/hotkey-clear.h +++ b/plugins/tweak/tweaks/hotkey-clear.h @@ -1,6 +1,6 @@ #include "df/viewscreen_dwarfmodest.h" -using df::global::ui; +using df::global::plotinfo; struct hotkey_clear_hook : df::viewscreen_dwarfmodest { typedef df::viewscreen_dwarfmodest interpose_base; @@ -8,7 +8,7 @@ struct hotkey_clear_hook : df::viewscreen_dwarfmodest { DEFINE_VMETHOD_INTERPOSE(void, render, ()) { INTERPOSE_NEXT(render)(); - if (ui->main.mode == df::ui_sidebar_mode::Hotkeys) + if (plotinfo->main.mode == df::ui_sidebar_mode::Hotkeys) { auto dims = Gui::getDwarfmodeViewDims(); int x = dims.menu_x1 + 1, y = 19; @@ -18,11 +18,11 @@ struct hotkey_clear_hook : df::viewscreen_dwarfmodest { DEFINE_VMETHOD_INTERPOSE(void, feed, (set *input)) { - if (ui->main.mode == df::ui_sidebar_mode::Hotkeys && + if (plotinfo->main.mode == df::ui_sidebar_mode::Hotkeys && input->count(df::interface_key::CUSTOM_C) && - !ui->main.in_rename_hotkey) + !plotinfo->main.in_rename_hotkey) { - auto &hotkey = ui->main.hotkeys[ui->main.selected_hotkey]; + auto &hotkey = plotinfo->main.hotkeys[plotinfo->main.selected_hotkey]; hotkey.name = ""; hotkey.cmd = df::ui_hotkey::T_cmd::None; hotkey.x = 0; diff --git a/plugins/tweak/tweaks/max-wheelbarrow.h b/plugins/tweak/tweaks/max-wheelbarrow.h index a7af186ef..38d704b24 100644 --- a/plugins/tweak/tweaks/max-wheelbarrow.h +++ b/plugins/tweak/tweaks/max-wheelbarrow.h @@ -22,7 +22,7 @@ struct max_wheelbarrow_hook : df::viewscreen_dwarfmodest { df::building_stockpilest* getStockpile() { - if (ui->main.mode != ui_sidebar_mode::QueryBuilding) + if (plotinfo->main.mode != ui_sidebar_mode::QueryBuilding) return NULL; return virtual_cast(world->selected_building); } diff --git a/plugins/tweak/tweaks/shift-8-scroll.h b/plugins/tweak/tweaks/shift-8-scroll.h index 86f7e9fc7..2c1eea23d 100644 --- a/plugins/tweak/tweaks/shift-8-scroll.h +++ b/plugins/tweak/tweaks/shift-8-scroll.h @@ -1,13 +1,13 @@ #include "df/viewscreen_dwarfmodest.h" using namespace df::enums; -using df::global::ui; +using df::global::plotinfo; struct shift_8_scroll_hook : df::viewscreen_dwarfmodest { typedef df::viewscreen_dwarfmodest interpose_base; DEFINE_VMETHOD_INTERPOSE(void, feed, (std::set* input)) { - if (ui->main.mode != ui_sidebar_mode::Default && + if (plotinfo->main.mode != ui_sidebar_mode::Default && input->count(interface_key::CURSOR_UP_FAST) && input->count(interface_key::SECONDSCROLL_PAGEDOWN) ) diff --git a/plugins/tweak/tweaks/stable-cursor.h b/plugins/tweak/tweaks/stable-cursor.h index b08346410..3b628ef04 100644 --- a/plugins/tweak/tweaks/stable-cursor.h +++ b/plugins/tweak/tweaks/stable-cursor.h @@ -6,7 +6,7 @@ using namespace std; using namespace DFHack; using namespace df::enums; -using df::global::ui; +using df::global::plotinfo; using df::global::ui_build_selector; using df::global::ui_menu_width; @@ -18,7 +18,7 @@ struct stable_cursor_hook : df::viewscreen_dwarfmodest bool check_default() { - switch (ui->main.mode) { + switch (plotinfo->main.mode) { case ui_sidebar_mode::Default: return true; diff --git a/plugins/uicommon.h b/plugins/uicommon.h index e7a586585..03914b461 100644 --- a/plugins/uicommon.h +++ b/plugins/uicommon.h @@ -24,7 +24,7 @@ #include "df/dfhack_material_category.h" #include "df/enabler.h" #include "df/item_quality.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/world.h" using namespace std; @@ -217,7 +217,7 @@ static inline char get_string_input(const std::set *input) static inline df::building_stockpilest *get_selected_stockpile() { if (!Gui::dwarfmode_hotkey(Core::getTopViewscreen()) || - df::global::ui->main.mode != ui_sidebar_mode::QueryBuilding) + df::global::plotinfo->main.mode != ui_sidebar_mode::QueryBuilding) { return nullptr; } @@ -227,10 +227,10 @@ static inline df::building_stockpilest *get_selected_stockpile() static inline bool can_trade() { - if (df::global::ui->caravans.size() == 0) + if (df::global::plotinfo->caravans.size() == 0) return false; - for (auto it = df::global::ui->caravans.begin(); it != df::global::ui->caravans.end(); it++) + for (auto it = df::global::plotinfo->caravans.begin(); it != df::global::plotinfo->caravans.end(); it++) { typedef df::caravan_state::T_trade_state state; auto caravan = *it; diff --git a/plugins/workflow.cpp b/plugins/workflow.cpp index 3f132616b..a8f11dec0 100644 --- a/plugins/workflow.cpp +++ b/plugins/workflow.cpp @@ -15,7 +15,7 @@ #include "DataDefs.h" #include "df/world.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/building_workshopst.h" #include "df/building_furnacest.h" #include "df/job.h" @@ -51,7 +51,7 @@ using namespace df::enums; DFHACK_PLUGIN("workflow"); REQUIRE_GLOBAL(world); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(ui_workshop_job_cursor); REQUIRE_GLOBAL(job_next_id); @@ -64,7 +64,7 @@ static void cleanup_state(color_ostream &out); DFhackCExport command_result plugin_init (color_ostream &out, std::vector &commands) { - if (!world || !ui) + if (!world || !plotinfo) return CR_FAILURE; if (ui_workshop_job_cursor && job_next_id) { @@ -1684,7 +1684,7 @@ static command_result workflow_cmd(color_ostream &out, vector & paramet //df::job *job = NULL; if (Gui::dwarfmode_hotkey(Core::getTopViewscreen()) && - ui->main.mode == ui_sidebar_mode::QueryBuilding) + plotinfo->main.mode == ui_sidebar_mode::QueryBuilding) { workshop = world->selected_building; //job = Gui::getSelectedWorkshopJob(out, true); diff --git a/plugins/zone.cpp b/plugins/zone.cpp index a3a0f2431..878014bb0 100644 --- a/plugins/zone.cpp +++ b/plugins/zone.cpp @@ -24,7 +24,7 @@ #include "df/building_chainst.h" #include "df/building_civzonest.h" #include "df/general_ref_building_civzone_assignedst.h" -#include "df/ui.h" +#include "df/plotinfost.h" #include "df/unit.h" #include "df/unit_relationship_type.h" #include "df/viewscreen_dwarfmodest.h" @@ -56,7 +56,7 @@ DFHACK_PLUGIN_IS_ENABLED(is_enabled); REQUIRE_GLOBAL(cursor); REQUIRE_GLOBAL(gps); -REQUIRE_GLOBAL(ui); +REQUIRE_GLOBAL(plotinfo); REQUIRE_GLOBAL(ui_building_item_cursor); REQUIRE_GLOBAL(ui_building_assign_type); REQUIRE_GLOBAL(ui_building_assign_is_marked); @@ -1565,7 +1565,7 @@ static command_result df_zone(color_ostream &out, vector & parameters) if(!race_filter_set && (building_assign || cagezone_assign || unit_slaughter)) { - string own_race_name = Units::getRaceNameById(ui->race_id); + string own_race_name = Units::getRaceNameById(plotinfo->race_id); out.color(COLOR_BROWN); out << "Default filter for " << parameters[0] << ": 'not (race " << own_race_name << " or own civilization)'; use 'race " @@ -2128,14 +2128,14 @@ struct zone_hook : public df::viewscreen_dwarfmodest DEFINE_VMETHOD_INTERPOSE(void, render, ()) { - if ( ( (ui->main.mode == ui_sidebar_mode::ZonesPenInfo || ui->main.mode == ui_sidebar_mode::ZonesPitInfo) && + if ( ( (plotinfo->main.mode == ui_sidebar_mode::ZonesPenInfo || plotinfo->main.mode == ui_sidebar_mode::ZonesPitInfo) && ui_building_assign_type && ui_building_assign_units && ui_building_assign_is_marked && ui_building_assign_items && ui_building_assign_type->size() == ui_building_assign_units->size() && ui_building_item_cursor) // allow mode QueryBuilding, but only for cages (bedrooms will crash DF with this code, chains don't work either etc) || - ( ui->main.mode == ui_sidebar_mode::QueryBuilding && + ( plotinfo->main.mode == ui_sidebar_mode::QueryBuilding && ui_building_in_assign && *ui_building_in_assign && ui_building_assign_type && ui_building_assign_units && ui_building_assign_type->size() == ui_building_assign_units->size() && @@ -2146,7 +2146,7 @@ struct zone_hook : public df::viewscreen_dwarfmodest ) { if (vector_get(*ui_building_assign_units, *ui_building_item_cursor)) - filter.initialize(ui->main.mode); + filter.initialize(plotinfo->main.mode); } else { diff --git a/scripts b/scripts index 57172de9b..55488a935 160000 --- a/scripts +++ b/scripts @@ -1 +1 @@ -Subproject commit 57172de9bdc54490957b046907462f61f0be3e7b +Subproject commit 55488a9350190858efa2f872cda2d627ae2d0cd2 diff --git a/test/library/gui/dwarfmode.lua b/test/library/gui/dwarfmode.lua index 1f3ab6a87..960397e02 100644 --- a/test/library/gui/dwarfmode.lua +++ b/test/library/gui/dwarfmode.lua @@ -36,39 +36,39 @@ function test.enterSidebarMode() end) -- verify expected starting state - expect.eq(df.ui_sidebar_mode.Default, df.global.ui.main.mode) + expect.eq(df.ui_sidebar_mode.Default, df.global.plotinfo.main.mode) expect.eq('dwarfmode/Default', dfhack.gui.getCurFocus(true)) -- get into the orders screen gui.simulateInput(dfhack.gui.getCurViewscreen(true), 'D_JOBLIST') gui.simulateInput(dfhack.gui.getCurViewscreen(true), 'UNITJOB_MANAGER') - expect.eq(df.ui_sidebar_mode.Default, df.global.ui.main.mode) + expect.eq(df.ui_sidebar_mode.Default, df.global.plotinfo.main.mode) expect.eq('jobmanagement/Main', dfhack.gui.getCurFocus(true)) -- get back into default from some deep screen guidm.enterSidebarMode(df.ui_sidebar_mode.Default) - expect.eq(df.ui_sidebar_mode.Default, df.global.ui.main.mode) + expect.eq(df.ui_sidebar_mode.Default, df.global.plotinfo.main.mode) expect.eq('dwarfmode/Default', dfhack.gui.getCurFocus(true)) -- move from default to some other mode guidm.enterSidebarMode(df.ui_sidebar_mode.QueryBuilding) - expect.eq(df.ui_sidebar_mode.QueryBuilding, df.global.ui.main.mode) + expect.eq(df.ui_sidebar_mode.QueryBuilding, df.global.plotinfo.main.mode) expect.str_find('^dwarfmode/QueryBuilding', dfhack.gui.getCurFocus(true)) -- move between non-default modes guidm.enterSidebarMode(df.ui_sidebar_mode.LookAround) - expect.eq(df.ui_sidebar_mode.LookAround, df.global.ui.main.mode) + expect.eq(df.ui_sidebar_mode.LookAround, df.global.plotinfo.main.mode) expect.str_find('^dwarfmode/LookAround', dfhack.gui.getCurFocus(true)) -- get back into default from a supported mode guidm.enterSidebarMode(df.ui_sidebar_mode.Default) - expect.eq(df.ui_sidebar_mode.Default, df.global.ui.main.mode) + expect.eq(df.ui_sidebar_mode.Default, df.global.plotinfo.main.mode) expect.eq('dwarfmode/Default', dfhack.gui.getCurFocus(true)) -- verify that all supported modes lead where we say they'll go for k,v in pairs(guidm.SIDEBAR_MODE_KEYS) do guidm.enterSidebarMode(k) - expect.eq(k, df.global.ui.main.mode, df.ui_sidebar_mode[k]) + expect.eq(k, df.global.plotinfo.main.mode, df.ui_sidebar_mode[k]) end -- end test back in default so the test harness doesn't have to autocorrect guidm.enterSidebarMode(df.ui_sidebar_mode.Default) diff --git a/test/library/utils.lua b/test/library/utils.lua index 509fab8bc..cf2024618 100644 --- a/test/library/utils.lua +++ b/test/library/utils.lua @@ -94,7 +94,7 @@ function test.df_expr_to_ref() dfhack.with_temp_object(df.new('ptr-vector'), function(vec) fake_unit = vec vec:insert('#', df.global.world) - vec:insert('#', df.global.ui) + vec:insert('#', df.global.plotinfo) expect.eq(utils.df_expr_to_ref('unit'), vec) @@ -102,7 +102,7 @@ function test.df_expr_to_ref() expect.eq(df.reinterpret_cast(df.world, utils.df_expr_to_ref('unit[0]').value), df.global.world) expect.eq(utils.df_expr_to_ref('unit[1]'), utils.df_expr_to_ref('unit.1')) - expect.eq(df.reinterpret_cast(df.ui, utils.df_expr_to_ref('unit[1]').value), df.global.ui) + expect.eq(df.reinterpret_cast(df.ui, utils.df_expr_to_ref('unit[1]').value), df.global.plotinfo) expect.error_match('index out of bounds', function() utils.df_expr_to_ref('unit.2') end) expect.error_match('index out of bounds', function() utils.df_expr_to_ref('unit[2]') end) diff --git a/test/quickfort/ecosystem.lua b/test/quickfort/ecosystem.lua index 27dddc5d5..3a4c014e4 100644 --- a/test/quickfort/ecosystem.lua +++ b/test/quickfort/ecosystem.lua @@ -397,7 +397,7 @@ function extra_fns.gui_quantum(pos) local vehicles = assign_minecarts.get_free_vehicles() local confirm_state = confirm.isEnabled() local confirm_conf = confirm.get_conf_data() - local routes = df.global.ui.hauling.routes + local routes = df.global.plotinfo.hauling.routes local num_routes = #routes local next_order_id = df.global.world.manager_order_next_id