Remove old map editor
Removes the old map editor and files that only it depended on.
17
.gitattributes
vendored
@@ -15,7 +15,6 @@ CorsixTH/Bitmap/flag_travel_east.bmp -text
|
|||||||
CorsixTH/Bitmap/flag_travel_north.bmp -text
|
CorsixTH/Bitmap/flag_travel_north.bmp -text
|
||||||
CorsixTH/Bitmap/flag_travel_south.bmp -text
|
CorsixTH/Bitmap/flag_travel_south.bmp -text
|
||||||
CorsixTH/Bitmap/flag_travel_west.bmp -text
|
CorsixTH/Bitmap/flag_travel_west.bmp -text
|
||||||
CorsixTH/Bitmap/flags32.png -text
|
|
||||||
CorsixTH/Bitmap/fullscreen_border_bottom.bmp -text
|
CorsixTH/Bitmap/fullscreen_border_bottom.bmp -text
|
||||||
CorsixTH/Bitmap/fullscreen_border_bottomleft.bmp -text
|
CorsixTH/Bitmap/fullscreen_border_bottomleft.bmp -text
|
||||||
CorsixTH/Bitmap/fullscreen_border_bottomright.bmp -text
|
CorsixTH/Bitmap/fullscreen_border_bottomright.bmp -text
|
||||||
@@ -32,13 +31,6 @@ CorsixTH/Bitmap/map_cell_outline_east.bmp -text
|
|||||||
CorsixTH/Bitmap/map_cell_outline_north.bmp -text
|
CorsixTH/Bitmap/map_cell_outline_north.bmp -text
|
||||||
CorsixTH/Bitmap/map_cell_outline_south.bmp -text
|
CorsixTH/Bitmap/map_cell_outline_south.bmp -text
|
||||||
CorsixTH/Bitmap/map_cell_outline_west.bmp -text
|
CorsixTH/Bitmap/map_cell_outline_west.bmp -text
|
||||||
CorsixTH/Bitmap/new32.png -text svneol=unset#image/png
|
|
||||||
CorsixTH/Bitmap/open32.png -text svneol=unset#image/png
|
|
||||||
CorsixTH/Bitmap/parcels32.png -text
|
|
||||||
CorsixTH/Bitmap/positions32.png -text
|
|
||||||
CorsixTH/Bitmap/redo32.png -text
|
|
||||||
CorsixTH/Bitmap/save32.png -text svneol=unset#image/png
|
|
||||||
CorsixTH/Bitmap/transparent_walls32.png -text
|
|
||||||
CorsixTH/Bitmap/tree_collapsed.bmp -text
|
CorsixTH/Bitmap/tree_collapsed.bmp -text
|
||||||
CorsixTH/Bitmap/tree_ctrl.dat -text
|
CorsixTH/Bitmap/tree_ctrl.dat -text
|
||||||
CorsixTH/Bitmap/tree_ctrl.pal -text
|
CorsixTH/Bitmap/tree_ctrl.pal -text
|
||||||
@@ -46,7 +38,6 @@ CorsixTH/Bitmap/tree_ctrl.tab -text
|
|||||||
CorsixTH/Bitmap/tree_expanded.bmp -text
|
CorsixTH/Bitmap/tree_expanded.bmp -text
|
||||||
CorsixTH/Bitmap/tree_leaf.bmp -text
|
CorsixTH/Bitmap/tree_leaf.bmp -text
|
||||||
CorsixTH/Bitmap/tree_level.bmp -text
|
CorsixTH/Bitmap/tree_level.bmp -text
|
||||||
CorsixTH/Bitmap/undo32.png -text
|
|
||||||
CorsixTH/CorsixTH.ico -text
|
CorsixTH/CorsixTH.ico -text
|
||||||
CorsixTH/Icon.icns -text
|
CorsixTH/Icon.icns -text
|
||||||
CorsixTH/Levels/Example.map -text
|
CorsixTH/Levels/Example.map -text
|
||||||
@@ -54,11 +45,6 @@ CorsixTH/Levels/avatar.map -text
|
|||||||
CorsixTH/Levels/confined_v5.map -text
|
CorsixTH/Levels/confined_v5.map -text
|
||||||
CorsixTH/Levels/finisham.map -text
|
CorsixTH/Levels/finisham.map -text
|
||||||
CorsixTH/Levels/original08.level -text
|
CorsixTH/Levels/original08.level -text
|
||||||
CorsixTH/Lua/command.lua -text
|
|
||||||
CorsixTH/Lua/command_stack.lua -text
|
|
||||||
CorsixTH/Lua/commands/compound.lua -text
|
|
||||||
CorsixTH/Lua/commands/set_map_cell.lua -text
|
|
||||||
CorsixTH/Lua/commands/set_map_cell_flags.lua -text
|
|
||||||
CorsixTH/Lua/dialogs/resizables/customise.lua -text
|
CorsixTH/Lua/dialogs/resizables/customise.lua -text
|
||||||
CorsixTH/Lua/dialogs/resizables/folder_settings.lua -text
|
CorsixTH/Lua/dialogs/resizables/folder_settings.lua -text
|
||||||
CorsixTH/Lua/dialogs/resizables/update.lua -text
|
CorsixTH/Lua/dialogs/resizables/update.lua -text
|
||||||
@@ -104,7 +90,4 @@ LevelEdit/src/icon256.png -text
|
|||||||
LevelEdit/src/icon32.png -text
|
LevelEdit/src/icon32.png -text
|
||||||
LevelEdit/src/icon48.png -text
|
LevelEdit/src/icon48.png -text
|
||||||
LevelEdit/src/icon64.png -text
|
LevelEdit/src/icon64.png -text
|
||||||
MapEdit/Icon.icns -text
|
|
||||||
MapEdit/MapEdit.ico -text
|
|
||||||
MapEdit/RequiredResources.txt -text
|
|
||||||
WindowsInstaller/welcome.bmp -text
|
WindowsInstaller/welcome.bmp -text
|
||||||
|
@@ -7,7 +7,6 @@
|
|||||||
# - WITH_FREETYPE2
|
# - WITH_FREETYPE2
|
||||||
# - WITH_MOVIES : Activate movies (requires Sound)
|
# - WITH_MOVIES : Activate movies (requires Sound)
|
||||||
# - BUILD_ANIMVIEWER
|
# - BUILD_ANIMVIEWER
|
||||||
# - BUILD_MAPEDITOR
|
|
||||||
# - WITH_LUAJIT : Whether to use LuaJIT 2 instead of Lua51 (default is LuaJIT 2)
|
# - WITH_LUAJIT : Whether to use LuaJIT 2 instead of Lua51 (default is LuaJIT 2)
|
||||||
# - WITH_LIBAV : Whether to use LibAV (as opposed to FFMEPG) when building movies
|
# - WITH_LIBAV : Whether to use LibAV (as opposed to FFMEPG) when building movies
|
||||||
# - WITH_VLD : Build with Visual Leak Detector (requires Visual Studio)
|
# - WITH_VLD : Build with Visual Leak Detector (requires Visual Studio)
|
||||||
@@ -37,7 +36,6 @@ OPTION(WITH_FREETYPE2 "Enhanced Font Support" ON)
|
|||||||
OPTION(WITH_LUAJIT "Use LuaJIT instead of Lua" OFF)
|
OPTION(WITH_LUAJIT "Use LuaJIT instead of Lua" OFF)
|
||||||
OPTION(WITH_LIBAV "Use LibAV instead of FFmpeg" OFF)
|
OPTION(WITH_LIBAV "Use LibAV instead of FFmpeg" OFF)
|
||||||
OPTION(BUILD_ANIMVIEWER "Build the animation viewer as part of the build process" OFF)
|
OPTION(BUILD_ANIMVIEWER "Build the animation viewer as part of the build process" OFF)
|
||||||
OPTION(BUILD_MAPEDITOR "Build the map editor as part of the build process" OFF)
|
|
||||||
IF(MSVC)
|
IF(MSVC)
|
||||||
OPTION(WITH_VLD "Build with Visual Leak Detector for Visual Studio" OFF)
|
OPTION(WITH_VLD "Build with Visual Leak Detector for Visual Studio" OFF)
|
||||||
ENDIF(MSVC)
|
ENDIF(MSVC)
|
||||||
@@ -107,15 +105,6 @@ IF(BUILD_ANIMVIEWER)
|
|||||||
add_subdirectory(AnimView)
|
add_subdirectory(AnimView)
|
||||||
ENDIF(BUILD_ANIMVIEWER)
|
ENDIF(BUILD_ANIMVIEWER)
|
||||||
|
|
||||||
IF(BUILD_MAPEDITOR)
|
|
||||||
IF(WITH_OPENGL)
|
|
||||||
message("Building MapEdit")
|
|
||||||
add_subdirectory(MapEdit)
|
|
||||||
ELSE(WITH_OPENGL)
|
|
||||||
message(FATAL_ERROR "The map editor can only be built when using OpenGL as renderer")
|
|
||||||
ENDIF(WITH_OPENGL)
|
|
||||||
ENDIF(BUILD_MAPEDITOR)
|
|
||||||
|
|
||||||
# Documentation generation, construct 'doc' target (or a message it is disabled).
|
# Documentation generation, construct 'doc' target (or a message it is disabled).
|
||||||
|
|
||||||
# Try to find 'lua'
|
# Try to find 'lua'
|
||||||
@@ -172,14 +161,6 @@ IF (DOXYGEN_FOUND)
|
|||||||
add_dependencies(doc doc_leveledit)
|
add_dependencies(doc doc_leveledit)
|
||||||
|
|
||||||
|
|
||||||
add_custom_target(doc_mapedit
|
|
||||||
${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/DoxyGen/mapedit.doxygen
|
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc
|
|
||||||
COMMENT "Generating API documentation for MapEdit" VERBATIM
|
|
||||||
)
|
|
||||||
add_dependencies(doc doc_mapedit)
|
|
||||||
|
|
||||||
|
|
||||||
add_custom_target(doc_corsixth_engine
|
add_custom_target(doc_corsixth_engine
|
||||||
${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/DoxyGen/corsixth_engine.doxygen
|
${DOXYGEN_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/DoxyGen/corsixth_engine.doxygen
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc
|
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/doc
|
||||||
@@ -223,7 +204,6 @@ IF (DOXYGEN_FOUND)
|
|||||||
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/doc/index.html "<ul>\n")
|
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/doc/index.html "<ul>\n")
|
||||||
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/doc/index.html " <li><a href=\"animview/html/index.html\">Animation viewer documentation</a>\n")
|
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/doc/index.html " <li><a href=\"animview/html/index.html\">Animation viewer documentation</a>\n")
|
||||||
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/doc/index.html " <li><a href=\"leveledit/html/index.html\">Level editor documentation</a>\n")
|
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/doc/index.html " <li><a href=\"leveledit/html/index.html\">Level editor documentation</a>\n")
|
||||||
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/doc/index.html " <li><a href=\"mapedit/html/index.html\">Map editor documentation</a>\n")
|
|
||||||
ENDIF (DOXYGEN_FOUND)
|
ENDIF (DOXYGEN_FOUND)
|
||||||
|
|
||||||
IF (DOXYGEN_FOUND OR LUA_PROGRAM_FOUND)
|
IF (DOXYGEN_FOUND OR LUA_PROGRAM_FOUND)
|
||||||
|
Before Width: | Height: | Size: 342 B |
Before Width: | Height: | Size: 1008 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 413 B |
Before Width: | Height: | Size: 358 B |
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 890 B |
Before Width: | Height: | Size: 353 B |
Before Width: | Height: | Size: 1.6 KiB |
@@ -1,29 +0,0 @@
|
|||||||
--[[ Copyright (c) 2013 Alan Woolley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE. --]]
|
|
||||||
|
|
||||||
class "Command"
|
|
||||||
|
|
||||||
---@type Command
|
|
||||||
local Command = _G["Command"]
|
|
||||||
|
|
||||||
function Command:Command(can_undo)
|
|
||||||
self.can_undo = can_undo
|
|
||||||
end
|
|
||||||
|
|
@@ -1,61 +0,0 @@
|
|||||||
--[[ Copyright (c) 2013 Alan Woolley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE. --]]
|
|
||||||
|
|
||||||
class "CommandStack"
|
|
||||||
|
|
||||||
---@type CommandStack
|
|
||||||
local CommandStack = _G["CommandStack"]
|
|
||||||
|
|
||||||
function CommandStack:CommandStack()
|
|
||||||
self.undo_stack = {}
|
|
||||||
self.redo_stack = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
function CommandStack:redo()
|
|
||||||
if (#self.redo_stack == 0) then
|
|
||||||
print "Nothing left to redo!"
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local cmd = self.redo_stack[#self.redo_stack]
|
|
||||||
table.remove(self.redo_stack, #self.redo_stack)
|
|
||||||
table.insert(self.undo_stack, #self.undo_stack + 1, cmd)
|
|
||||||
cmd:perform()
|
|
||||||
return #self.redo_stack == 0
|
|
||||||
end
|
|
||||||
|
|
||||||
function CommandStack:undo()
|
|
||||||
if (#self.undo_stack == 0) then
|
|
||||||
print "Nothing left to undo!"
|
|
||||||
return
|
|
||||||
end
|
|
||||||
local cmd = self.undo_stack[#self.undo_stack]
|
|
||||||
table.remove(self.undo_stack, #self.undo_stack)
|
|
||||||
table.insert(self.redo_stack, #self.redo_stack + 1, cmd)
|
|
||||||
cmd:undo()
|
|
||||||
return #self.undo_stack == 0
|
|
||||||
end
|
|
||||||
|
|
||||||
function CommandStack:add(cmd)
|
|
||||||
if not cmd.can_undo then
|
|
||||||
self.undo_stack = {}
|
|
||||||
end
|
|
||||||
self.redo_stack = {}
|
|
||||||
table.insert(self.undo_stack, #self.undo_stack + 1, cmd)
|
|
||||||
end
|
|
@@ -1,48 +0,0 @@
|
|||||||
--[[ Copyright (c) 2013 Alan Woolley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE. --]]
|
|
||||||
|
|
||||||
class "CompoundCommand" (Command)
|
|
||||||
|
|
||||||
---@type CompoundCommand
|
|
||||||
local CompoundCommand = _G["CompoundCommand"]
|
|
||||||
|
|
||||||
function CompoundCommand:CompoundCommand()
|
|
||||||
self:Command(true)
|
|
||||||
self.command_list = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
function CompoundCommand:addCommand(cmd)
|
|
||||||
table.insert(self.command_list, #self.command_list + 1, cmd)
|
|
||||||
end
|
|
||||||
|
|
||||||
function CompoundCommand:perform()
|
|
||||||
for i = 1 , #self.command_list do
|
|
||||||
local cmd = self.command_list[i]
|
|
||||||
cmd:perform()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function CompoundCommand:undo()
|
|
||||||
for i = #self.command_list, 1, -1 do
|
|
||||||
local cmd = self.command_list[i]
|
|
||||||
cmd:undo()
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@@ -1,50 +0,0 @@
|
|||||||
--[[ Copyright (c) 2013 Alan Woolley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE. --]]
|
|
||||||
|
|
||||||
class "SetMapCellCommand" (Command)
|
|
||||||
|
|
||||||
---@type SetMapCellCommand
|
|
||||||
local SetMapCellCommand = _G["SetMapCellCommand"]
|
|
||||||
|
|
||||||
function SetMapCellCommand:SetMapCellCommand(map)
|
|
||||||
self:Command(true)
|
|
||||||
self.map = map
|
|
||||||
self.paint_list = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
function SetMapCellCommand:addTile(x_tile, y_tile, ...)
|
|
||||||
local old = {self.map:getCell(x_tile, y_tile)}
|
|
||||||
table.insert(self.paint_list, #self.paint_list + 1, {x = x_tile, y = y_tile, new_flags = {...}, old_flags = old})
|
|
||||||
end
|
|
||||||
|
|
||||||
function SetMapCellCommand:perform()
|
|
||||||
for i = 1 , #self.paint_list do
|
|
||||||
local cell_table = self.paint_list[i]
|
|
||||||
self.map:setCell(cell_table.x, cell_table.y, unpack(cell_table.new_flags))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function SetMapCellCommand:undo()
|
|
||||||
for i = #self.paint_list, 1, -1 do
|
|
||||||
local cell_table = self.paint_list[i]
|
|
||||||
self.map:setCell(cell_table.x, cell_table.y, unpack(cell_table.old_flags))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
@@ -1,49 +0,0 @@
|
|||||||
--[[ Copyright (c) 2013 Alan Woolley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE. --]]
|
|
||||||
|
|
||||||
class "SetMapCellFlagsCommand" (Command)
|
|
||||||
|
|
||||||
---@type SetMapCellFlagsCommand
|
|
||||||
local SetMapCellFlagsCommand = _G["SetMapCellFlagsCommand"]
|
|
||||||
|
|
||||||
function SetMapCellFlagsCommand:SetMapCellFlagsCommand(map)
|
|
||||||
self:Command(true)
|
|
||||||
self.map = map
|
|
||||||
self.paint_list = {}
|
|
||||||
end
|
|
||||||
|
|
||||||
function SetMapCellFlagsCommand:addTile(x_tile, y_tile, ...)
|
|
||||||
local old = {self.map:getCellFlags(x_tile, y_tile)}
|
|
||||||
table.insert(self.paint_list, #self.paint_list + 1, {x = x_tile, y = y_tile, new_flags = {...}, old_flags = old})
|
|
||||||
end
|
|
||||||
|
|
||||||
function SetMapCellFlagsCommand:perform()
|
|
||||||
for i = 1 , #self.paint_list do
|
|
||||||
local cell_table = self.paint_list[i]
|
|
||||||
self.map:setCellFlags(cell_table.x, cell_table.y, unpack(cell_table.new_flags))
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
function SetMapCellFlagsCommand:undo()
|
|
||||||
for i = #self.paint_list, 1, -1 do
|
|
||||||
local cell_table = self.paint_list[i]
|
|
||||||
self.map:setCellFlags(cell_table.x, cell_table.y, unpack(cell_table.old_flags))
|
|
||||||
end
|
|
||||||
end
|
|
@@ -146,9 +146,6 @@ int CorsixTH_lua_main_no_eval(lua_State *L)
|
|||||||
#if defined(IS_CORSIXTH_APP)
|
#if defined(IS_CORSIXTH_APP)
|
||||||
"code = loadfile(\"CorsixTH.app/Contents/Resources/\"..name)\n"
|
"code = loadfile(\"CorsixTH.app/Contents/Resources/\"..name)\n"
|
||||||
"if code then return code end\n"
|
"if code then return code end\n"
|
||||||
#elif defined(IS_MAPEDIT_APP)
|
|
||||||
"code = loadfile(\"MapEdit.app/Contents/Resources/\"..name)\n"
|
|
||||||
"if code then return code end\n"
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
"for num_dotdot = 0, 3 do\n"
|
"for num_dotdot = 0, 3 do\n"
|
||||||
|
@@ -1,200 +0,0 @@
|
|||||||
# Project Declaration
|
|
||||||
PROJECT(MapEdit)
|
|
||||||
# 2.8.3 is required for the wxWidgets finder to know about ribbon
|
|
||||||
CMAKE_MINIMUM_REQUIRED(VERSION 2.8.3)
|
|
||||||
|
|
||||||
# Generate source files list
|
|
||||||
# Note: Done after generating config.h
|
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/CorsixTH/Src/)
|
|
||||||
INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/CorsixTH/Src/)
|
|
||||||
FILE(GLOB_RECURSE mapedit_source_files
|
|
||||||
${CMAKE_SOURCE_DIR}/MapEdit/Src/*.cpp
|
|
||||||
${CMAKE_SOURCE_DIR}/MapEdit/Src/*.c
|
|
||||||
${CMAKE_SOURCE_DIR}/MapEdit/Src/*.h
|
|
||||||
${CMAKE_SOURCE_DIR}/MapEdit/MapEdit.rc
|
|
||||||
${CMAKE_SOURCE_DIR}/CorsixTH/Src/*.h
|
|
||||||
${CMAKE_SOURCE_DIR}/CorsixTH/Src/*.c
|
|
||||||
${CMAKE_SOURCE_DIR}/CorsixTH/Src/*.cpp
|
|
||||||
${CMAKE_SOURCE_DIR}/LFS/*.c
|
|
||||||
${CMAKE_SOURCE_DIR}/LPEG/*.c
|
|
||||||
)
|
|
||||||
|
|
||||||
# Declaration of the executable
|
|
||||||
IF(APPLE)
|
|
||||||
add_definitions(-DIS_MAPEDIT_APP)
|
|
||||||
|
|
||||||
set(corsixth_icon_file ${CMAKE_SOURCE_DIR}/MapEdit/Icon.icns)
|
|
||||||
set_source_files_properties(
|
|
||||||
${corsixth_icon_file}
|
|
||||||
PROPERTIES
|
|
||||||
MACOSX_PACKAGE_LOCATION Resources
|
|
||||||
)
|
|
||||||
set(MACOSX_BUNDLE_ICON_FILE Icon.icns)
|
|
||||||
|
|
||||||
add_executable(MapEdit
|
|
||||||
MACOSX_BUNDLE
|
|
||||||
${mapedit_source_files}
|
|
||||||
${corsixth_icon_file}
|
|
||||||
)
|
|
||||||
|
|
||||||
set_target_properties(MapEdit PROPERTIES LINK_FLAGS_MINSIZEREL "-dead_strip")
|
|
||||||
set_target_properties(MapEdit PROPERTIES XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks")
|
|
||||||
|
|
||||||
#Add an extra step at the end of the build process to copy the resources into the bundle.
|
|
||||||
add_custom_command(TARGET MapEdit
|
|
||||||
POST_BUILD
|
|
||||||
COMMAND rsync -rv --include-from ${CMAKE_SOURCE_DIR}/MapEdit/RequiredResources.txt ${CMAKE_SOURCE_DIR}/CorsixTH/ \${TARGET_BUILD_DIR}/\${FULL_PRODUCT_NAME}/Contents/Resources)
|
|
||||||
|
|
||||||
ELSE()
|
|
||||||
add_executable(MapEdit
|
|
||||||
WIN32
|
|
||||||
${mapedit_source_files}
|
|
||||||
)
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
# Basic platform dependant stuff
|
|
||||||
IF(UNIX)
|
|
||||||
IF(APPLE)
|
|
||||||
# fruit goes here
|
|
||||||
ELSE(APPLE)
|
|
||||||
# regular unix/linux
|
|
||||||
ENDIF(APPLE)
|
|
||||||
ELSE(UNIX)
|
|
||||||
IF(WIN32)
|
|
||||||
# Win32 specific
|
|
||||||
IF(MSVC)
|
|
||||||
# We want to bind against the very latest versions of the MSVC runtimes
|
|
||||||
add_definitions(/D "_BIND_TO_CURRENT_VCLIBS_VERSION=1")
|
|
||||||
ELSE(MSVC)
|
|
||||||
IF(MSYS)
|
|
||||||
# MSYS stuff
|
|
||||||
ELSE(MSYS)
|
|
||||||
# What's left? MINGW? CYGWIN? BORLAND?
|
|
||||||
ENDIF(MSYS)
|
|
||||||
ENDIF(MSVC)
|
|
||||||
ELSE(WIN32)
|
|
||||||
# other OS (not UNIX, not 32/64 bit Windows)
|
|
||||||
ENDIF(WIN32)
|
|
||||||
ENDIF(UNIX)
|
|
||||||
|
|
||||||
# Finding libraries
|
|
||||||
|
|
||||||
# Find WxWidgets
|
|
||||||
SET(CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${PROJECT_SOURCE_DIR}")
|
|
||||||
MESSAGE("Module path: ${CMAKE_MODULE_PATH}")
|
|
||||||
SET(wxWidgets_USE_LIBS gl ribbon core base) # optionally: more than wx std libs
|
|
||||||
FIND_PACKAGE(wxWidgets REQUIRED)
|
|
||||||
IF(wxWidgets_FOUND)
|
|
||||||
LINK_LIBRARIES(${wxWidgets_LIBRARIES})
|
|
||||||
INCLUDE_DIRECTORIES(${wxWidgets_INCLUDE_DIRS})
|
|
||||||
INCLUDE(${wxWidgets_USE_FILE})
|
|
||||||
TARGET_LINK_LIBRARIES(MapEdit ${wxWidgets_LIBRARIES})
|
|
||||||
message(" wxWidgets found")
|
|
||||||
ELSE(wxWidgets_FOUND)
|
|
||||||
message( FATAL_ERROR "error: wxWdigets library (or one of it's components) not found, it is required to build")
|
|
||||||
message( "Make sure the path is correctly defined or set the envirnomental variable WXWIN to the correct location" )
|
|
||||||
ENDIF(wxWidgets_FOUND)
|
|
||||||
|
|
||||||
# Find SDL
|
|
||||||
FIND_PACKAGE(SDL2 REQUIRED)
|
|
||||||
IF(SDL_FOUND)
|
|
||||||
INCLUDE_DIRECTORIES(${SDL_INCLUDE_DIR})
|
|
||||||
TARGET_LINK_LIBRARIES(MapEdit ${SDL_LIBRARY})
|
|
||||||
message( " SDL found" )
|
|
||||||
ELSE(SDL_FOUND)
|
|
||||||
message( FATAL_ERROR "error: SDL library not found, it is required to build")
|
|
||||||
message( "Make sure the path is correctly defined or set the envirnomental variable SDLDIR to the correct location" )
|
|
||||||
ENDIF(SDL_FOUND)
|
|
||||||
|
|
||||||
# Find SDL_mixer
|
|
||||||
IF(CORSIX_TH_USE_SDL_MIXER)
|
|
||||||
FIND_PACKAGE(SDL2_mixer REQUIRED)
|
|
||||||
IF(SDLMIXER_FOUND)
|
|
||||||
TARGET_LINK_LIBRARIES(MapEdit ${SDLMIXER_LIBRARY})
|
|
||||||
INCLUDE_DIRECTORIES(${SDLMIXER_INCLUDE_DIR})
|
|
||||||
message( " SDL_mixer found" )
|
|
||||||
ELSE(SDLMIXER_FOUND)
|
|
||||||
message( "error: SDL_mixer library not found, it was selected to be included")
|
|
||||||
ENDIF(SDLMIXER_FOUND)
|
|
||||||
ENDIF(CORSIX_TH_USE_SDL_MIXER)
|
|
||||||
|
|
||||||
# Find FFMPEG
|
|
||||||
IF(CORSIX_TH_USE_FFMPEG)
|
|
||||||
FIND_PACKAGE(FFmpeg COMPONENTS AVFORMAT AVCODEC AVUTIL SWSCALE SWRESAMPLE REQUIRED)
|
|
||||||
IF(FFMPEG_FOUND)
|
|
||||||
TARGET_LINK_LIBRARIES(MapEdit ${FFMPEG_LIBRARIES})
|
|
||||||
INCLUDE_DIRECTORIES(${FFMPEG_INCLUDE_DIRS})
|
|
||||||
IF(APPLE)
|
|
||||||
TARGET_LINK_LIBRARIES(MapEdit libz.dylib)
|
|
||||||
ENDIF()
|
|
||||||
message(" FFmpeg found")
|
|
||||||
ELSE(FFMPEG_FOUND)
|
|
||||||
message("Error: FFmpeg library not found, even though it was selected to be included")
|
|
||||||
ENDIF(FFMPEG_FOUND)
|
|
||||||
ENDIF(CORSIX_TH_USE_FFMPEG)
|
|
||||||
|
|
||||||
# Find Freetype2
|
|
||||||
IF(CORSIX_TH_USE_FREETYPE2)
|
|
||||||
FIND_PACKAGE(Freetype REQUIRED)
|
|
||||||
IF(FREETYPE_FOUND)
|
|
||||||
TARGET_LINK_LIBRARIES(MapEdit ${FREETYPE_LIBRARIES})
|
|
||||||
INCLUDE_DIRECTORIES(${FREETYPE_INCLUDE_DIRS})
|
|
||||||
IF(APPLE)
|
|
||||||
TARGET_LINK_LIBRARIES(MapEdit libz.dylib)
|
|
||||||
TARGET_LINK_LIBRARIES(MapEdit libbz2.dylib)
|
|
||||||
ENDIF()
|
|
||||||
message(" FreeType2 found")
|
|
||||||
ELSE(FREETYPE_FOUND)
|
|
||||||
message("Error: FreeType2 library not found, even though it was selected to be used")
|
|
||||||
ENDIF(FREETYPE_FOUND)
|
|
||||||
ENDIF(CORSIX_TH_USE_FREETYPE2)
|
|
||||||
|
|
||||||
# Find OpenGL
|
|
||||||
IF(CORSIX_TH_USE_OGL_RENDERER)
|
|
||||||
FIND_PACKAGE(OpenGL REQUIRED)
|
|
||||||
IF(OPENGL_FOUND)
|
|
||||||
TARGET_LINK_LIBRARIES( MapEdit ${OPENGL_gl_LIBRARY})
|
|
||||||
INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR})
|
|
||||||
message( " OpenGL found" )
|
|
||||||
ELSE(OPENGL_FOUND)
|
|
||||||
message( FATAL_ERROR "error: OpenGL library not found, it is required to build")
|
|
||||||
ENDIF(OPENGL_FOUND)
|
|
||||||
ENDIF(CORSIX_TH_USE_OGL_RENDERER)
|
|
||||||
|
|
||||||
# Find Lua
|
|
||||||
FIND_PACKAGE(Lua REQUIRED)
|
|
||||||
IF(Lua_FOUND)
|
|
||||||
TARGET_LINK_LIBRARIES(MapEdit ${LUA_LIBRARY})
|
|
||||||
INCLUDE_DIRECTORIES(${LUA_INCLUDE_DIR})
|
|
||||||
# Special link flags needed on OSX/64bit, according to: http://luajit.org/install.html
|
|
||||||
# If these are not specified, luaL_newstate() returns NULL and we get this:
|
|
||||||
# Fatal error starting CorsixTH: Cannot open Lua state.
|
|
||||||
IF(${CMAKE_SYSTEM_NAME} MATCHES "Darwin" AND LUA_INTERPRETER_TYPE STREQUAL "LuaJIT" AND CMAKE_SIZEOF_VOID_P EQUAL 8)
|
|
||||||
TARGET_LINK_LIBRARIES(MapEdit "-pagezero_size 10000" "-image_base 100000000")
|
|
||||||
ENDIF()
|
|
||||||
message(" ${LUA_INTERPRETER_TYPE} found")
|
|
||||||
ELSE(Lua_FOUND)
|
|
||||||
message(FATAL_ERROR "Error: Lua library not found, it is required to build")
|
|
||||||
ENDIF(Lua_FOUND)
|
|
||||||
|
|
||||||
# Find msinttypes for MSVC
|
|
||||||
IF(MSVC AND NOT CORSIX_TH_HAS_INTTYPES_H)
|
|
||||||
FIND_PATH(MSINTTYPES_INCLUDE_DIRS "inttypes.h" NO_DEFAULT_PATH)
|
|
||||||
MESSAGE(STATUS "Adding include directory: ${MSINTTYPES_INCLUDE_DIRS}")
|
|
||||||
INCLUDE_DIRECTORIES(${MSINTTYPES_INCLUDE_DIRS})
|
|
||||||
SET(CORSIX_TH_HAS_INTTYPES_H 1)
|
|
||||||
ENDIF(MSVC AND NOT CORSIX_TH_HAS_INTTYPES_H)
|
|
||||||
|
|
||||||
IF(APPLE)
|
|
||||||
#Just use the prefix as it's sufficient to just set the prefix to /Applications on Mac.
|
|
||||||
install(TARGETS MapEdit BUNDLE DESTINATION .)
|
|
||||||
|
|
||||||
# Fix the OS X bundle to include required libraries (create a redistributable app)
|
|
||||||
install(CODE "
|
|
||||||
INCLUDE(BundleUtilities)
|
|
||||||
SET(BU_CHMOD_BUNDLE_ITEMS ON)
|
|
||||||
FIXUP_BUNDLE(${CMAKE_INSTALL_PREFIX}/MapEdit.app \"\" \"\")
|
|
||||||
")
|
|
||||||
ELSE()
|
|
||||||
install(TARGETS MapEdit RUNTIME DESTINATION CorsixTH)
|
|
||||||
ENDIF()
|
|
Before Width: | Height: | Size: 134 KiB |
@@ -1,34 +0,0 @@
|
|||||||
// Microsoft Visual C++ generated resource script.
|
|
||||||
//
|
|
||||||
|
|
||||||
#define APSTUDIO_READONLY_SYMBOLS
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Generated from the TEXTINCLUDE 2 resource.
|
|
||||||
//
|
|
||||||
#include "afxres.h"
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
#undef APSTUDIO_READONLY_SYMBOLS
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
// English (U.K.) resources
|
|
||||||
|
|
||||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENG)
|
|
||||||
#ifdef _WIN32
|
|
||||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_UK
|
|
||||||
#pragma code_page(1252)
|
|
||||||
#endif //_WIN32
|
|
||||||
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
//
|
|
||||||
// Icon
|
|
||||||
//
|
|
||||||
|
|
||||||
// Icon with lowest ID value placed first to ensure application icon
|
|
||||||
// remains consistent on all systems.
|
|
||||||
IDI_MAPEDIT ICON "MapEdit.ico"
|
|
||||||
#endif // English (U.K.) resources
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
@@ -1,14 +0,0 @@
|
|||||||
# rsync compatible filter file which is used post-build
|
|
||||||
# to help with copying the required resources into the
|
|
||||||
# bundles for the Mac build.
|
|
||||||
|
|
||||||
- .svn
|
|
||||||
- .DS_Store
|
|
||||||
- CVS
|
|
||||||
+ CorsixTH.lua
|
|
||||||
+ Lua/
|
|
||||||
+ Lua/**
|
|
||||||
+ Bitmap/
|
|
||||||
+ Bitmap/*.png
|
|
||||||
+ Bitmap/aux_ui.*
|
|
||||||
- *
|
|
@@ -1,38 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "app.h"
|
|
||||||
//Darrell: This macro has to be called before the frmMain.h include otherwise
|
|
||||||
//a subsequent SDL include causes main() to be replaced with SDLmain().
|
|
||||||
IMPLEMENT_APP(ThemeHospitalMapEditApp)
|
|
||||||
#include "frmMain.h"
|
|
||||||
|
|
||||||
bool ThemeHospitalMapEditApp::OnInit()
|
|
||||||
{
|
|
||||||
wxImage::AddHandler(new wxPNGHandler);
|
|
||||||
wxTopLevelWindow *pForm = new frmMain;
|
|
||||||
|
|
||||||
pForm->Show(true);
|
|
||||||
SetTopWindow(pForm);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
@@ -1,47 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
// For compilers that support precompilation, includes "wx/wx.h".
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
#pragma hdrstop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// for all others, include the necessary headers (this file is usually all you
|
|
||||||
// need because it includes almost all "standard" wxWidgets headers)
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/wx.h"
|
|
||||||
#endif
|
|
||||||
// ----------------------------
|
|
||||||
#include <wx/glcanvas.h>
|
|
||||||
#ifndef wxUSE_GLCANVAS
|
|
||||||
#error To compile the map editor, wxWidgets must be compiled with OpenGL
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class ThemeHospitalMapEditApp : public wxGLApp
|
|
||||||
{
|
|
||||||
virtual bool OnInit();
|
|
||||||
};
|
|
||||||
|
|
||||||
DECLARE_APP(ThemeHospitalMapEditApp)
|
|
@@ -1,286 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "block_gallery.h"
|
|
||||||
#include <map>
|
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(RibbonBlockGallery, wxRibbonGallery)
|
|
||||||
EVT_BUTTON(wxID_ANY, RibbonBlockGallery::OnExtButton)
|
|
||||||
END_EVENT_TABLE()
|
|
||||||
|
|
||||||
RibbonBlockGallery::RibbonBlockGallery(wxWindow* parent, wxWindowID id)
|
|
||||||
: wxRibbonGallery(parent, id)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
RibbonBlockGallery::~RibbonBlockGallery()
|
|
||||||
{
|
|
||||||
_clearCategories();
|
|
||||||
}
|
|
||||||
|
|
||||||
#define FOREACH(container_t, itr_name, container_name) \
|
|
||||||
for(container_t::iterator itr_name = container_name.begin(), \
|
|
||||||
itr_name##_end = container_name.end(); itr_name != itr_name##_end; \
|
|
||||||
++itr_name)
|
|
||||||
|
|
||||||
void RibbonBlockGallery::_clearCategories()
|
|
||||||
{
|
|
||||||
FOREACH(categorylist_t, itr, m_vCategories)
|
|
||||||
{
|
|
||||||
Unbind(wxEVT_COMMAND_MENU_SELECTED,
|
|
||||||
&RibbonBlockGallery::OnToggleCategory, this, (**itr).iID);
|
|
||||||
delete *itr;
|
|
||||||
}
|
|
||||||
m_vCategories.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RibbonBlockGallery::Populate(THSpriteSheet *pBlocks,
|
|
||||||
const char* sCategory,
|
|
||||||
const char* sSubCategory,
|
|
||||||
lua_State* L,
|
|
||||||
int iInfoIndex)
|
|
||||||
{
|
|
||||||
m_vBlocks.clear();
|
|
||||||
_clearCategories();
|
|
||||||
typedef std::map<wxString, category_t*> category_map_t;
|
|
||||||
category_map_t mapCategories;
|
|
||||||
|
|
||||||
// Extract relevant block information from Lua
|
|
||||||
if(LUA_REGISTRYINDEX < iInfoIndex && iInfoIndex < 0)
|
|
||||||
iInfoIndex = lua_gettop(L) + 1 + iInfoIndex;
|
|
||||||
lua_pushstring(L, sCategory);
|
|
||||||
int iCategoryIndex = lua_gettop(L);
|
|
||||||
lua_pushstring(L, sSubCategory);
|
|
||||||
lua_pushnil(L);
|
|
||||||
int iBaseIndex = lua_gettop(L);
|
|
||||||
while(lua_next(L, iInfoIndex) != 0)
|
|
||||||
{
|
|
||||||
lua_rawgeti(L, -1, 1);
|
|
||||||
if(lua_equal(L, -1, iCategoryIndex))
|
|
||||||
{
|
|
||||||
lua_pop(L, 1);
|
|
||||||
lua_rawgeti(L, -1, 2);
|
|
||||||
if(lua_equal(L, -1, iCategoryIndex + 1))
|
|
||||||
{
|
|
||||||
lua_pop(L, 1);
|
|
||||||
block_t oBlock;
|
|
||||||
oBlock.iBlock = lua_tointeger(L, -2);
|
|
||||||
oBlock.iBaseBlock = 0;
|
|
||||||
wxString sCategory(L"Miscellaneous");
|
|
||||||
lua_rawgeti(L, -1, 3);
|
|
||||||
if(lua_type(L, -1) == LUA_TSTRING)
|
|
||||||
sCategory = lua_tostring(L, -1);
|
|
||||||
oBlock.pCategory = mapCategories[sCategory];
|
|
||||||
if(oBlock.pCategory == NULL)
|
|
||||||
{
|
|
||||||
oBlock.pCategory = new category_t;
|
|
||||||
oBlock.pCategory->bEnabled = true;
|
|
||||||
oBlock.pCategory->sName = sCategory;
|
|
||||||
oBlock.pCategory->iID = wxID_HIGHEST + 1 +
|
|
||||||
mapCategories.size();
|
|
||||||
Bind(wxEVT_COMMAND_MENU_SELECTED,
|
|
||||||
&RibbonBlockGallery::OnToggleCategory, this,
|
|
||||||
oBlock.pCategory->iID);
|
|
||||||
mapCategories[sCategory] = oBlock.pCategory;
|
|
||||||
}
|
|
||||||
lua_pop(L, 1);
|
|
||||||
lua_getfield(L, -1, "base");
|
|
||||||
if(lua_type(L, -1) == LUA_TNUMBER)
|
|
||||||
oBlock.iBaseBlock = lua_tointeger(L, -1);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
m_vBlocks.push_back(oBlock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lua_settop(L, iBaseIndex);
|
|
||||||
}
|
|
||||||
lua_pop(L, 2);
|
|
||||||
|
|
||||||
FOREACH(category_map_t, itr, mapCategories)
|
|
||||||
{
|
|
||||||
m_vCategories.push_back(itr->second);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Load block bitmaps
|
|
||||||
wxSize szLargestBitmap(0, 0);
|
|
||||||
FOREACH(blocklist_t, itr, m_vBlocks)
|
|
||||||
{
|
|
||||||
unsigned int iWidth, iHeight;
|
|
||||||
if(!pBlocks->getSpriteSize(itr->iBlock, &iWidth, &iHeight))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
wxImage imgBlock(iWidth, iHeight);
|
|
||||||
if(!imgBlock.HasAlpha())
|
|
||||||
imgBlock.InitAlpha();
|
|
||||||
|
|
||||||
pBlocks->wxDrawSprite(itr->iBlock, imgBlock.GetData(), imgBlock.GetAlpha());
|
|
||||||
_trimImage(imgBlock);
|
|
||||||
if(imgBlock.GetWidth() > szLargestBitmap.GetWidth())
|
|
||||||
szLargestBitmap.SetWidth(imgBlock.GetWidth());
|
|
||||||
if(imgBlock.GetHeight() > szLargestBitmap.GetHeight())
|
|
||||||
szLargestBitmap.SetHeight(imgBlock.GetHeight());
|
|
||||||
itr->bmpTrimmed = wxBitmap(imgBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make block bitmaps equally sized
|
|
||||||
FOREACH(blocklist_t, itr, m_vBlocks)
|
|
||||||
{
|
|
||||||
if(itr->bmpTrimmed.IsOk() && itr->bmpTrimmed.GetSize() != szLargestBitmap)
|
|
||||||
{
|
|
||||||
wxImage imgBlock = itr->bmpTrimmed.ConvertToImage();
|
|
||||||
_expandImage(imgBlock, szLargestBitmap);
|
|
||||||
itr->bmpTrimmed = wxBitmap(imgBlock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add blocks to gallery
|
|
||||||
_repopulate();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RibbonBlockGallery::_repopulate()
|
|
||||||
{
|
|
||||||
Clear();
|
|
||||||
FOREACH(blocklist_t, itr, m_vBlocks)
|
|
||||||
{
|
|
||||||
if(itr->pCategory->bEnabled && itr->bmpTrimmed.IsOk())
|
|
||||||
{
|
|
||||||
Append(itr->bmpTrimmed, itr->iBlock, (void*)&*itr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Realise();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RibbonBlockGallery::OnToggleCategory(wxCommandEvent& evt)
|
|
||||||
{
|
|
||||||
FOREACH(categorylist_t, itr, m_vCategories)
|
|
||||||
{
|
|
||||||
if((**itr).iID == evt.GetId())
|
|
||||||
{
|
|
||||||
(**itr).bEnabled = !(**itr).bEnabled;
|
|
||||||
_repopulate();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RibbonBlockGallery::SelectAndMakeVisible(int iBlock)
|
|
||||||
{
|
|
||||||
unsigned int iCount = GetCount();
|
|
||||||
for(unsigned int i = 0; i < iCount; ++i)
|
|
||||||
{
|
|
||||||
wxRibbonGalleryItem *pItem = GetItem(i);
|
|
||||||
block_t *pBlock = reinterpret_cast<block_t*>(GetItemClientData(pItem));
|
|
||||||
if(pBlock->iBlock == iBlock)
|
|
||||||
{
|
|
||||||
SetSelection(pItem);
|
|
||||||
EnsureVisible(pItem);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
FOREACH(blocklist_t, itr, m_vBlocks)
|
|
||||||
{
|
|
||||||
if(itr->iBlock == iBlock && !itr->pCategory->bEnabled)
|
|
||||||
{
|
|
||||||
itr->pCategory->bEnabled = true;
|
|
||||||
_repopulate();
|
|
||||||
return SelectAndMakeVisible(iBlock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int RibbonBlockGallery::GetBlock(wxRibbonGalleryItem* pItem, int* pBaseBlock)
|
|
||||||
{
|
|
||||||
block_t *pBlock = reinterpret_cast<block_t*>(GetItemClientData(pItem));
|
|
||||||
if(pBaseBlock)
|
|
||||||
*pBaseBlock = pBlock->iBaseBlock;
|
|
||||||
return pBlock->iBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
void RibbonBlockGallery::_trimImage(wxImage& image)
|
|
||||||
{
|
|
||||||
int iOpaqueTop = 0;
|
|
||||||
int iOpaqueBottom = image.GetHeight() - 1;
|
|
||||||
int iOpaqueLeft = 0;
|
|
||||||
int iOpaqueRight = image.GetWidth() - 1;
|
|
||||||
|
|
||||||
for(; iOpaqueTop <= iOpaqueBottom; ++iOpaqueTop)
|
|
||||||
{
|
|
||||||
for(int iX = iOpaqueLeft; iX <= iOpaqueRight; ++iX)
|
|
||||||
{
|
|
||||||
if(!image.IsTransparent(iX, iOpaqueTop))
|
|
||||||
goto break1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break1:;
|
|
||||||
|
|
||||||
for(; iOpaqueBottom >= iOpaqueTop; --iOpaqueBottom)
|
|
||||||
{
|
|
||||||
for(int iX = iOpaqueLeft; iX <= iOpaqueRight; ++iX)
|
|
||||||
{
|
|
||||||
if(!image.IsTransparent(iX, iOpaqueBottom))
|
|
||||||
goto break2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break2:;
|
|
||||||
|
|
||||||
for(; iOpaqueLeft <= iOpaqueRight; ++iOpaqueLeft)
|
|
||||||
{
|
|
||||||
for(int iY = iOpaqueTop; iY <= iOpaqueBottom; ++iY)
|
|
||||||
{
|
|
||||||
if(!image.IsTransparent(iOpaqueLeft, iY))
|
|
||||||
goto break3;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break3:;
|
|
||||||
|
|
||||||
for(; iOpaqueRight >= iOpaqueLeft; --iOpaqueRight)
|
|
||||||
{
|
|
||||||
for(int iY = iOpaqueTop; iY <= iOpaqueBottom; ++iY)
|
|
||||||
{
|
|
||||||
if(!image.IsTransparent(iOpaqueRight, iY))
|
|
||||||
goto break4;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break4:;
|
|
||||||
|
|
||||||
image = image.Size(wxSize(iOpaqueRight - iOpaqueLeft + 1, iOpaqueBottom - iOpaqueTop + 1),
|
|
||||||
wxPoint(-iOpaqueLeft, -iOpaqueTop));
|
|
||||||
}
|
|
||||||
|
|
||||||
void RibbonBlockGallery::_expandImage(wxImage& image, wxSize size)
|
|
||||||
{
|
|
||||||
image = image.Size(size, wxPoint(
|
|
||||||
(size.GetWidth() - image.GetWidth()) / 2,
|
|
||||||
size.GetHeight() - image.GetHeight()
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
void RibbonBlockGallery::OnExtButton(wxCommandEvent& evt)
|
|
||||||
{
|
|
||||||
wxMenu mnCategories;
|
|
||||||
FOREACH(categorylist_t, itr, m_vCategories)
|
|
||||||
{
|
|
||||||
mnCategories.AppendCheckItem((**itr).iID, (**itr).sName)
|
|
||||||
->Check((**itr).bEnabled);
|
|
||||||
}
|
|
||||||
PopupMenu(&mnCategories);
|
|
||||||
}
|
|
@@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
// For compilers that support precompilation, includes "wx/wx.h".
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
#pragma hdrstop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// for all others, include the necessary headers (this file is usually all you
|
|
||||||
// need because it includes almost all "standard" wxWidgets headers)
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/wx.h"
|
|
||||||
#endif
|
|
||||||
// ----------------------------
|
|
||||||
#include <wx/ribbon/gallery.h>
|
|
||||||
#include <vector>
|
|
||||||
#include "game.h"
|
|
||||||
|
|
||||||
class RibbonBlockGallery : public wxRibbonGallery
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
RibbonBlockGallery(wxWindow* parent, wxWindowID id = wxID_ANY);
|
|
||||||
~RibbonBlockGallery();
|
|
||||||
|
|
||||||
void Populate(THSpriteSheet *pBlocks, const char* sCategory,
|
|
||||||
const char* sSubCategory, lua_State* L, int iInfoIndex);
|
|
||||||
|
|
||||||
bool SelectAndMakeVisible(int iBlock);
|
|
||||||
|
|
||||||
int GetBlock(wxRibbonGalleryItem* pItem, int* pBaseBlock);
|
|
||||||
|
|
||||||
void OnExtButton(wxCommandEvent& evt);
|
|
||||||
void OnToggleCategory(wxCommandEvent& evt);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
struct category_t
|
|
||||||
{
|
|
||||||
wxString sName;
|
|
||||||
bool bEnabled;
|
|
||||||
int iID;
|
|
||||||
};
|
|
||||||
struct block_t
|
|
||||||
{
|
|
||||||
wxBitmap bmpTrimmed;
|
|
||||||
category_t* pCategory;
|
|
||||||
int iBlock;
|
|
||||||
int iBaseBlock;
|
|
||||||
};
|
|
||||||
|
|
||||||
// wxWidgets encourages use of wxArray over std::vector, but this isn't in
|
|
||||||
// wxWidgets core (and never will be), so it doesn't matter ^_^
|
|
||||||
typedef std::vector<block_t> blocklist_t;
|
|
||||||
typedef std::vector<category_t*> categorylist_t;
|
|
||||||
|
|
||||||
blocklist_t m_vBlocks;
|
|
||||||
categorylist_t m_vCategories;
|
|
||||||
|
|
||||||
void _trimImage(wxImage& image);
|
|
||||||
void _expandImage(wxImage& image, wxSize size);
|
|
||||||
void _clearCategories();
|
|
||||||
void _repopulate();
|
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE();
|
|
||||||
};
|
|
@@ -1,448 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
#include "frmMain.h"
|
|
||||||
#include "../../CorsixTH/Src/main.h"
|
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(EmbeddedGamePanel, wxGLCanvas)
|
|
||||||
EVT_MOTION(EmbeddedGamePanel::_onMouseMove)
|
|
||||||
EVT_PAINT(EmbeddedGamePanel::_onPaint)
|
|
||||||
EVT_LEFT_UP(EmbeddedGamePanel::_onLeftUp)
|
|
||||||
EVT_LEFT_DOWN(EmbeddedGamePanel::_onLeftDown)
|
|
||||||
EVT_MIDDLE_UP(EmbeddedGamePanel::_onMiddleUp)
|
|
||||||
EVT_MIDDLE_DOWN(EmbeddedGamePanel::_onMiddleDown)
|
|
||||||
EVT_RIGHT_UP(EmbeddedGamePanel::_onRightUp)
|
|
||||||
EVT_RIGHT_DOWN(EmbeddedGamePanel::_onRightDown)
|
|
||||||
EVT_LEFT_DCLICK(EmbeddedGamePanel::_onLeftDoubleClick)
|
|
||||||
END_EVENT_TABLE()
|
|
||||||
|
|
||||||
IEmbeddedGamePanel::~IEmbeddedGamePanel()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
EmbeddedGamePanel::EmbeddedGamePanel(wxWindow *pParent)
|
|
||||||
: wxGLCanvas(pParent, wxID_ANY, NULL, wxDefaultPosition,
|
|
||||||
wxDefaultSize, 0, wxGLCanvasName, wxNullPalette)
|
|
||||||
, m_pGLCanvas(NULL)
|
|
||||||
, m_pGLContext(NULL)
|
|
||||||
, m_pPrintTarget(NULL)
|
|
||||||
, m_L(NULL)
|
|
||||||
, m_Lthread(NULL)
|
|
||||||
, m_fnExtraLuaInit(NULL)
|
|
||||||
, m_pExtraLuaInitArg(NULL)
|
|
||||||
{
|
|
||||||
m_pGLCanvas = this;
|
|
||||||
m_pGLContext = new wxGLContext(m_pGLCanvas);
|
|
||||||
}
|
|
||||||
|
|
||||||
EmbeddedGamePanel::~EmbeddedGamePanel()
|
|
||||||
{
|
|
||||||
if(m_L)
|
|
||||||
lua_close(m_L);
|
|
||||||
delete m_pGLContext;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmbeddedGamePanel::setExtraLuaInitFunction(lua_CFunction fn, void* arg)
|
|
||||||
{
|
|
||||||
m_fnExtraLuaInit = fn;
|
|
||||||
m_pExtraLuaInitArg = arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmbeddedGamePanel::setLogWindow(frmLog *pLogWindow)
|
|
||||||
{
|
|
||||||
m_pPrintTarget = pLogWindow->getTextControl();
|
|
||||||
}
|
|
||||||
|
|
||||||
THMap* EmbeddedGamePanel::getMap()
|
|
||||||
{
|
|
||||||
THMap *pMap = NULL;
|
|
||||||
int iTop = lua_gettop(m_L);
|
|
||||||
lua_checkstack(m_L, 5);
|
|
||||||
lua_getglobal(m_L, "TheApp");
|
|
||||||
if(!lua_isnil(m_L, -1))
|
|
||||||
{
|
|
||||||
lua_getfield(m_L, -1, "map");
|
|
||||||
if(!lua_isnil(m_L, -1))
|
|
||||||
{
|
|
||||||
lua_getfield(m_L, -1, "th");
|
|
||||||
pMap = reinterpret_cast<THMap*>(lua_touserdata(m_L, -1));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lua_settop(m_L, iTop);
|
|
||||||
return pMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EmbeddedGamePanel::loadLua()
|
|
||||||
{
|
|
||||||
// Create state
|
|
||||||
m_L = luaL_newstate();
|
|
||||||
lua_atpanic(m_L, _l_panic);
|
|
||||||
|
|
||||||
// Save a pointer to ourselves in the registry
|
|
||||||
lua_pushliteral(m_L, "wxWindow");
|
|
||||||
lua_pushlightuserdata(m_L, reinterpret_cast<wxWindow*>(this));
|
|
||||||
lua_settable(m_L, LUA_REGISTRYINDEX);
|
|
||||||
|
|
||||||
// Open default libraries, and override appropriate bits
|
|
||||||
luaL_openlibs(m_L);
|
|
||||||
luaT_execute(m_L, "print = ...", _l_print);
|
|
||||||
|
|
||||||
// Set _MAP_EDITOR to true, to allow scripts to notice that they are
|
|
||||||
// running inside this component, rather than standalone.
|
|
||||||
luaT_execute(m_L, "_MAP_EDITOR = true");
|
|
||||||
|
|
||||||
// Load CorsixTH.lua and perform other initialisation needed by it
|
|
||||||
lua_settop(m_L, 0);
|
|
||||||
lua_pushcfunction(m_L, CorsixTH_lua_stacktrace);
|
|
||||||
lua_pushcfunction(m_L, CorsixTH_lua_main_no_eval);
|
|
||||||
lua_checkstack(m_L, wxTheApp->argc);
|
|
||||||
for(int i = 0; i < wxTheApp->argc; ++ i)
|
|
||||||
lua_pushstring(m_L, wxTheApp->argv[i]);
|
|
||||||
if(lua_pcall(m_L, wxTheApp->argc, 1, 1))
|
|
||||||
{
|
|
||||||
if(m_pPrintTarget)
|
|
||||||
{
|
|
||||||
m_pPrintTarget->AppendText(L"Error initialising Lua: ");
|
|
||||||
m_pPrintTarget->AppendText(lua_tostring(m_L, -1));
|
|
||||||
m_pPrintTarget->AppendText(L"\n");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// NB: CorsixTH_lua_main_no_eval will have loaded CorsixTH.lua and left it
|
|
||||||
// as the top value on the stack, but will not have executed it.
|
|
||||||
// The stack will hence have two things on it: the stacktrace function,
|
|
||||||
// and the loaded CorsixTH.lua
|
|
||||||
|
|
||||||
// Overwrite what CorsixTH_lua_main_no_eval registered for require("sdl")
|
|
||||||
// with our own function that uses wxWidgets to do what SDL would have.
|
|
||||||
luaT_execute(m_L, "package.preload.sdl = ...", _l_open_sdl);
|
|
||||||
|
|
||||||
// Replace the Surface:endFrame() function with our own
|
|
||||||
lua_getglobal(m_L, "require");
|
|
||||||
lua_pushliteral(m_L, "TH");
|
|
||||||
lua_call(m_L, 1, 1);
|
|
||||||
lua_getfield(m_L, -1, "surface");
|
|
||||||
lua_getfield(m_L, -1, "endFrame");
|
|
||||||
lua_pushcclosure(m_L, _l_end_frame, 1);
|
|
||||||
lua_setfield(m_L, -2, "endFrame");
|
|
||||||
lua_pop(m_L, 2);
|
|
||||||
|
|
||||||
// Perform extra initialisation
|
|
||||||
if(m_fnExtraLuaInit)
|
|
||||||
{
|
|
||||||
if(lua_cpcall(m_L, m_fnExtraLuaInit, m_pExtraLuaInitArg) != 0)
|
|
||||||
lua_pop(m_L, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Execute CorsixTH.lua in a coroutine
|
|
||||||
lua_getglobal(m_L, "coroutine");
|
|
||||||
lua_getfield(m_L, -1, "create");
|
|
||||||
lua_replace(m_L, -2);
|
|
||||||
lua_insert(m_L, -2);
|
|
||||||
lua_call(m_L, 1, 1);
|
|
||||||
lua_State *L = lua_tothread(m_L, -1);
|
|
||||||
if(lua_resume(L, 0) != LUA_YIELD)
|
|
||||||
{
|
|
||||||
if(m_pPrintTarget)
|
|
||||||
{
|
|
||||||
// Push debug.traceback onto m_L
|
|
||||||
lua_getglobal(m_L, "debug");
|
|
||||||
lua_getfield(m_L, -1, "traceback");
|
|
||||||
lua_replace(m_L, -2);
|
|
||||||
// Push the thread onto m_L
|
|
||||||
lua_pushvalue(m_L, -2);
|
|
||||||
// Push tostring(errmsg) onto m_L
|
|
||||||
lua_getglobal(m_L, "tostring");
|
|
||||||
lua_xmove(L, m_L, 1);
|
|
||||||
lua_call(m_L, 1, 1);
|
|
||||||
// Push constant 1 onto m_L
|
|
||||||
lua_pushinteger(m_L, 1);
|
|
||||||
// Call debug.traceback(thread, tostring(err), 1)
|
|
||||||
lua_call(m_L, 3, 1);
|
|
||||||
// Display resulting string and pop it
|
|
||||||
m_pPrintTarget->AppendText(L"Error initialising Lua: ");
|
|
||||||
m_pPrintTarget->AppendText(lua_tostring(m_L, -1));
|
|
||||||
m_pPrintTarget->AppendText(L"\n");
|
|
||||||
lua_pop(m_L, 1);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
lua_settop(L, 1);
|
|
||||||
m_Lthread = L;
|
|
||||||
|
|
||||||
// The stack of the Lua states is now as follows:
|
|
||||||
// m_L: stacktrace function, m_Lthread <top
|
|
||||||
// m_Lthread: event dispatch coroutine <top
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EmbeddedGamePanel::_resume(lua_State *L, int iNArgs, int iNRes)
|
|
||||||
{
|
|
||||||
// L will be an event handling coroutine.
|
|
||||||
// Start by sending the event to the coroutine by resuming it with the
|
|
||||||
// event arguments.
|
|
||||||
bool bGood = true;
|
|
||||||
if(lua_resume(L, iNArgs) != LUA_YIELD)
|
|
||||||
{
|
|
||||||
// Error occurred during event processing.
|
|
||||||
bGood = false;
|
|
||||||
// Transfer the error details to m_Lthread
|
|
||||||
int iNTransfer = lua_gettop(L);
|
|
||||||
if(lua_status(L) >= LUA_ERRRUN)
|
|
||||||
iNTransfer = 1;
|
|
||||||
lua_checkstack(m_Lthread, iNTransfer);
|
|
||||||
lua_xmove(L, m_Lthread, iNTransfer);
|
|
||||||
lua_settop(L, 0);
|
|
||||||
// Allow m_Lthread to respond to the error in an appropriate way
|
|
||||||
lua_resume(m_Lthread, iNTransfer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Event processed without errors, and will have returned true if
|
|
||||||
// a redraw needs to occur.
|
|
||||||
if(lua_toboolean(L, -1) != 0)
|
|
||||||
{
|
|
||||||
Refresh(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Leave L with the desired number of return values.
|
|
||||||
lua_settop(L, iNRes);
|
|
||||||
return bGood;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmbeddedGamePanel::_onMouseMove(wxMouseEvent& evt)
|
|
||||||
{
|
|
||||||
// Keep track of relative mouse movements as well as absolute
|
|
||||||
wxPoint ptNew = evt.GetPosition();
|
|
||||||
wxPoint ptDelta = ptNew - m_ptMouse;
|
|
||||||
m_ptMouse = ptNew;
|
|
||||||
|
|
||||||
_dispatchEvent("motion", ptNew.x, ptNew.y, ptDelta.x, ptDelta.y);
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmbeddedGamePanel::_onLeftUp(wxMouseEvent& evt)
|
|
||||||
{
|
|
||||||
_dispatchEvent("buttonup", SDL_BUTTON_LEFT, evt.GetX(), evt.GetY());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmbeddedGamePanel::_onLeftDown(wxMouseEvent& evt)
|
|
||||||
{
|
|
||||||
_dispatchEvent("buttondown", SDL_BUTTON_LEFT, evt.GetX(), evt.GetY());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmbeddedGamePanel::_onLeftDoubleClick(wxMouseEvent& evt)
|
|
||||||
{
|
|
||||||
_dispatchEvent("buttondown", "left_double", evt.GetX(), evt.GetY());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmbeddedGamePanel::_onRightUp(wxMouseEvent& evt)
|
|
||||||
{
|
|
||||||
_dispatchEvent("buttonup", SDL_BUTTON_RIGHT, evt.GetX(), evt.GetY());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmbeddedGamePanel::_onRightDown(wxMouseEvent& evt)
|
|
||||||
{
|
|
||||||
_dispatchEvent("buttondown", SDL_BUTTON_RIGHT, evt.GetX(), evt.GetY());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmbeddedGamePanel::_onMiddleUp(wxMouseEvent& evt)
|
|
||||||
{
|
|
||||||
_dispatchEvent("buttonup", SDL_BUTTON_MIDDLE, evt.GetX(), evt.GetY());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmbeddedGamePanel::_onMiddleDown(wxMouseEvent& evt)
|
|
||||||
{
|
|
||||||
_dispatchEvent("buttondown", SDL_BUTTON_MIDDLE, evt.GetX(), evt.GetY());
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmbeddedGamePanel::_onPaint(wxPaintEvent& evt)
|
|
||||||
{
|
|
||||||
wxPaintDC dc(this);
|
|
||||||
m_pGLContext->SetCurrent(*m_pGLCanvas);
|
|
||||||
|
|
||||||
if(m_L == NULL)
|
|
||||||
{
|
|
||||||
// Its rather hacky to be loading the Lua side of things from within
|
|
||||||
// the paint handler, but Lua needs an OpenGL context to be active, and
|
|
||||||
// we cannot give it one during the EmbeddedGamePanel constructor.
|
|
||||||
loadLua();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the OpenGL projection matrix and Lua window size settings to keep
|
|
||||||
// a 1:1 mapping between world space and screen space
|
|
||||||
const wxSize szClient = GetClientSize();
|
|
||||||
glViewport(0, 0, szClient.x, szClient.y);
|
|
||||||
GLdouble fWidth = (GLdouble)szClient.x;
|
|
||||||
GLdouble fHeight = (GLdouble)szClient.y;
|
|
||||||
THRenderTarget::setGLProjection(fWidth, fHeight);
|
|
||||||
if(m_L)
|
|
||||||
{
|
|
||||||
lua_getglobal(m_L, "TheApp");
|
|
||||||
if(lua_isnil(m_L, -1))
|
|
||||||
lua_pop(m_L, 1);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lua_getfield(m_L, -1, "config");
|
|
||||||
lua_pushinteger(m_L, szClient.x);
|
|
||||||
lua_setfield(m_L, -2, "width");
|
|
||||||
lua_pushinteger(m_L, szClient.y);
|
|
||||||
lua_setfield(m_L, -2, "height");
|
|
||||||
lua_pop(m_L, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Do the actual painting
|
|
||||||
if(m_Lthread)
|
|
||||||
{
|
|
||||||
lua_State *L = lua_tothread(m_Lthread, 1);
|
|
||||||
if(L == NULL)
|
|
||||||
{
|
|
||||||
for(int i = 1; i <= lua_gettop(m_L); ++i)
|
|
||||||
{
|
|
||||||
wxPrintf("m_L stack %i: %s\n", i, lua_typename(m_L, lua_type(m_L, i)));
|
|
||||||
}
|
|
||||||
for(int i = 1; i <= lua_gettop(m_Lthread); ++i)
|
|
||||||
{
|
|
||||||
wxPrintf("m_Lthread stack %i: %s\n", i, lua_typename(m_Lthread, lua_type(m_Lthread, i)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lua_pushliteral(L, "frame");
|
|
||||||
_resume(L, 1, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EmbeddedGamePanel* EmbeddedGamePanel::_getThis(lua_State *L)
|
|
||||||
{
|
|
||||||
lua_pushliteral(L, "wxWindow");
|
|
||||||
lua_gettable(L, LUA_REGISTRYINDEX);
|
|
||||||
EmbeddedGamePanel *pThis = reinterpret_cast<EmbeddedGamePanel*>(
|
|
||||||
reinterpret_cast<wxWindow*>(lua_touserdata(L, -1)));
|
|
||||||
lua_pop(L, 1);
|
|
||||||
return pThis;
|
|
||||||
}
|
|
||||||
|
|
||||||
int EmbeddedGamePanel::_l_print(lua_State *L)
|
|
||||||
{
|
|
||||||
EmbeddedGamePanel *pThis = _getThis(L);
|
|
||||||
if(pThis->m_pPrintTarget)
|
|
||||||
{
|
|
||||||
int iCount = lua_gettop(L);
|
|
||||||
lua_getglobal(L, "tostring");
|
|
||||||
for(int iArg = 1; iArg <= iCount; ++iArg)
|
|
||||||
{
|
|
||||||
lua_pushvalue(L, -1);
|
|
||||||
lua_pushvalue(L, iArg);
|
|
||||||
lua_call(L, 1, 1);
|
|
||||||
pThis->m_pPrintTarget->AppendText(lua_tostring(L, -1));
|
|
||||||
lua_pop(L, 1);
|
|
||||||
if(iArg != iCount)
|
|
||||||
pThis->m_pPrintTarget->AppendText(L"\t");
|
|
||||||
}
|
|
||||||
pThis->m_pPrintTarget->AppendText(L"\n");
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int EmbeddedGamePanel::_l_panic(lua_State *L)
|
|
||||||
{
|
|
||||||
const char *sMessage = lua_tostring(L, -1);
|
|
||||||
::wxMessageBox(wxString(L"Lua Panic!\n") + wxString(sMessage ? sMessage : ""),
|
|
||||||
wxString(L"Lua Panic"), wxOK | wxICON_ERROR | wxCENTRE);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int EmbeddedGamePanel::_l_end_frame(lua_State *L)
|
|
||||||
{
|
|
||||||
// Call the original Surface:endFrame() function
|
|
||||||
lua_pushvalue(L, lua_upvalueindex(1));
|
|
||||||
lua_insert(L, 1);
|
|
||||||
lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);
|
|
||||||
|
|
||||||
// Update the display
|
|
||||||
EmbeddedGamePanel *pThis = _getThis(L);
|
|
||||||
pThis->m_pGLCanvas->SwapBuffers();
|
|
||||||
|
|
||||||
// Return whatever the original returned
|
|
||||||
return lua_gettop(L);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int l_init(lua_State *L)
|
|
||||||
{
|
|
||||||
lua_pushboolean(L, 1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int l_get_fps(lua_State *L)
|
|
||||||
{
|
|
||||||
lua_pushnumber(L, 1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int l_nop(lua_State *L)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int l_get_ticks(lua_State *L)
|
|
||||||
{
|
|
||||||
// Not the same as the game's sdl.getTicks(), but it is sufficient for the
|
|
||||||
// purpose (initialising the random number generator).
|
|
||||||
lua_pushnumber(L, ::wxGetLocalTime());
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const struct luaL_reg sdllib[] = {
|
|
||||||
{"init", l_init},
|
|
||||||
//{"mainloop", coroutine.yield},
|
|
||||||
{"getFPS", l_get_fps},
|
|
||||||
{"trackFPS", l_nop},
|
|
||||||
{"limitFPS", l_nop},
|
|
||||||
{"modifyKeyboardRepeat", l_nop},
|
|
||||||
{"getTicks", l_get_ticks},
|
|
||||||
{NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct luaL_reg sdl_wmlib[] = {
|
|
||||||
{"setIconWin32", l_nop},
|
|
||||||
{"setCaption", l_nop},
|
|
||||||
{"showCursor", l_nop},
|
|
||||||
{NULL, NULL}
|
|
||||||
};
|
|
||||||
|
|
||||||
int EmbeddedGamePanel::_l_open_sdl(lua_State *L)
|
|
||||||
{
|
|
||||||
luaL_register(L, "sdl", sdllib);
|
|
||||||
lua_getglobal(L, "coroutine");
|
|
||||||
lua_getfield(L, -1, "yield");
|
|
||||||
lua_setfield(L, -3, "mainloop");
|
|
||||||
lua_pop(L, 1);
|
|
||||||
lua_newtable(L);
|
|
||||||
lua_pushvalue(L, -1);
|
|
||||||
lua_setfield(L, -3, "wm");
|
|
||||||
luaL_register(L, NULL, sdl_wmlib);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
lua_newtable(L);
|
|
||||||
lua_pushboolean(L, 0);
|
|
||||||
lua_setfield(L, -2, "loaded");
|
|
||||||
lua_setfield(L, -2, "audio");
|
|
||||||
return 1;
|
|
||||||
}
|
|
@@ -1,146 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
// For compilers that support precompilation, includes "wx/wx.h".
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
#pragma hdrstop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// for all others, include the necessary headers (this file is usually all you
|
|
||||||
// need because it includes almost all "standard" wxWidgets headers)
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/wx.h"
|
|
||||||
#endif
|
|
||||||
// ----------------------------
|
|
||||||
#include <wx/glcanvas.h>
|
|
||||||
#include "game.h"
|
|
||||||
#include "frmLog.h"
|
|
||||||
|
|
||||||
class IEmbeddedGamePanel
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
virtual ~IEmbeddedGamePanel();
|
|
||||||
|
|
||||||
virtual void setExtraLuaInitFunction(lua_CFunction fn, void* arg) = 0;
|
|
||||||
virtual void setLogWindow(frmLog *pLogWindow) = 0;
|
|
||||||
virtual bool loadLua() = 0;
|
|
||||||
|
|
||||||
virtual lua_State* getLua() = 0;
|
|
||||||
virtual THMap* getMap() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
//! GUI component which acts as an instance of CorsixTH
|
|
||||||
/*!
|
|
||||||
The component contains a Lua instance which executes the normal CorsixTH
|
|
||||||
Lua scripts. Mouse and keyboard events to the component are forwarded to
|
|
||||||
said Lua instance in the same way as they are for a standalone CorsixTH
|
|
||||||
instance, and the visual representation of the component is what would
|
|
||||||
normally get displayed in a standalone CorsixTH window.
|
|
||||||
|
|
||||||
Lua scripts can tell if they are being executed from within this, as the
|
|
||||||
global variable _MAP_EDITOR will be set to true.
|
|
||||||
*/
|
|
||||||
class EmbeddedGamePanel : public wxGLCanvas, public IEmbeddedGamePanel
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
EmbeddedGamePanel(wxWindow *pParent);
|
|
||||||
~EmbeddedGamePanel();
|
|
||||||
|
|
||||||
void setExtraLuaInitFunction(lua_CFunction fn, void* arg);
|
|
||||||
void setLogWindow(frmLog *pLogWindow);
|
|
||||||
bool loadLua();
|
|
||||||
|
|
||||||
lua_State* getLua() {return m_L;}
|
|
||||||
THMap* getMap();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// OpenGL rendering stuff
|
|
||||||
wxGLCanvas* m_pGLCanvas;
|
|
||||||
wxGLContext* m_pGLContext;
|
|
||||||
|
|
||||||
//! A text control which is used for the output of print() calls
|
|
||||||
wxTextCtrl* m_pPrintTarget;
|
|
||||||
//! The top-level Lua instance
|
|
||||||
lua_State* m_L;
|
|
||||||
//! A substate of m_L which is used for executing the CorsixTH instance,
|
|
||||||
// as this allows the execution to yield and resume "asynchronously".
|
|
||||||
lua_State* m_Lthread;
|
|
||||||
//! A user-supplied function to be called during Lua initialisation.
|
|
||||||
lua_CFunction m_fnExtraLuaInit;
|
|
||||||
//! An argument to m_fnExtraLuaInit, delivered as a light userdata.
|
|
||||||
void* m_pExtraLuaInitArg;
|
|
||||||
//! The last recorded position of the mouse cursor - used to calculate
|
|
||||||
// the difference in position each time the mouse is moved.
|
|
||||||
wxPoint m_ptMouse;
|
|
||||||
|
|
||||||
static int _l_print(lua_State *L);
|
|
||||||
static int _l_panic(lua_State *L);
|
|
||||||
static int _l_open_sdl(lua_State *L);
|
|
||||||
static int _l_end_frame(lua_State *L);
|
|
||||||
static EmbeddedGamePanel* _getThis(lua_State *L);
|
|
||||||
|
|
||||||
void _onPaint(wxPaintEvent& evt);
|
|
||||||
void _onMouseMove(wxMouseEvent& evt);
|
|
||||||
void _onLeftUp(wxMouseEvent& evt);
|
|
||||||
void _onLeftDown(wxMouseEvent& evt);
|
|
||||||
void _onLeftDoubleClick(wxMouseEvent& evt);
|
|
||||||
void _onRightUp(wxMouseEvent& evt);
|
|
||||||
void _onRightDown(wxMouseEvent& evt);
|
|
||||||
void _onMiddleUp(wxMouseEvent& evt);
|
|
||||||
void _onMiddleDown(wxMouseEvent& evt);
|
|
||||||
|
|
||||||
template <typename T1, typename T2, typename T3>
|
|
||||||
void _dispatchEvent(const char* sName, T1 a1, T2 a2, T3 a3)
|
|
||||||
{
|
|
||||||
if(m_Lthread)
|
|
||||||
{
|
|
||||||
lua_State *L = lua_tothread(m_Lthread, 1);
|
|
||||||
lua_pushstring(L, sName);
|
|
||||||
luaT_push(L, a1);
|
|
||||||
luaT_push(L, a2);
|
|
||||||
luaT_push(L, a3);
|
|
||||||
_resume(L, 4, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T1, typename T2, typename T3, typename T4>
|
|
||||||
void _dispatchEvent(const char* sName, T1 a1, T2 a2, T3 a3, T4 a4)
|
|
||||||
{
|
|
||||||
if(m_Lthread)
|
|
||||||
{
|
|
||||||
lua_State *L = lua_tothread(m_Lthread, 1);
|
|
||||||
lua_pushstring(L, sName);
|
|
||||||
luaT_push(L, a1);
|
|
||||||
luaT_push(L, a2);
|
|
||||||
luaT_push(L, a3);
|
|
||||||
luaT_push(L, a4);
|
|
||||||
_resume(L, 5, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool _resume(lua_State *L, int iNArgs, int iNRes);
|
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE();
|
|
||||||
};
|
|
@@ -1,43 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
#include "frmLog.h"
|
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(frmLog, wxFrame)
|
|
||||||
END_EVENT_TABLE()
|
|
||||||
|
|
||||||
frmLog::frmLog()
|
|
||||||
: wxFrame(NULL, wxID_ANY, L"CorsixTH Lua Log Window", wxDefaultPosition,
|
|
||||||
wxSize(400, 480), wxCAPTION | wxRESIZE_BORDER)
|
|
||||||
{
|
|
||||||
m_pTextCtrl = new wxTextCtrl(this, wxID_ANY, L"", wxDefaultPosition,
|
|
||||||
wxDefaultSize, wxTE_READONLY | wxTE_MULTILINE);
|
|
||||||
|
|
||||||
wxSizer *pTopSizer = new wxBoxSizer(wxVERTICAL);
|
|
||||||
pTopSizer->Add(m_pTextCtrl, 1, wxEXPAND);
|
|
||||||
SetSizer(pTopSizer);
|
|
||||||
|
|
||||||
Show();
|
|
||||||
}
|
|
||||||
|
|
||||||
frmLog::~frmLog()
|
|
||||||
{
|
|
||||||
}
|
|
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
// For compilers that support precompilation, includes "wx/wx.h".
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
#pragma hdrstop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// for all others, include the necessary headers (this file is usually all you
|
|
||||||
// need because it includes almost all "standard" wxWidgets headers)
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/wx.h"
|
|
||||||
#endif
|
|
||||||
// ----------------------------
|
|
||||||
|
|
||||||
class frmLog : public wxFrame
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
frmLog();
|
|
||||||
~frmLog();
|
|
||||||
|
|
||||||
wxTextCtrl* getTextControl() {return m_pTextCtrl;}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
wxTextCtrl* m_pTextCtrl;
|
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE();
|
|
||||||
};
|
|
@@ -1,761 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
#include "frmMain.h"
|
|
||||||
#include "th_map_wrapper.h"
|
|
||||||
#include <wx/file.h>
|
|
||||||
#include <wx/filename.h>
|
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(frmMain, wxFrame)
|
|
||||||
EVT_RIBBONBAR_PAGE_CHANGED(wxID_ANY, frmMain::_onRibbonPageChanged)
|
|
||||||
EVT_RIBBONGALLERY_SELECTED(ID_GALLERY_FLOOR1, frmMain::_onFloorGallery1Select)
|
|
||||||
EVT_RIBBONGALLERY_SELECTED(ID_GALLERY_FLOOR2, frmMain::_onFloorGallery2Select)
|
|
||||||
EVT_RIBBONGALLERY_SELECTED(ID_GALLERY_WALL1, frmMain::_onWallGallery1Select)
|
|
||||||
EVT_RIBBONGALLERY_SELECTED(ID_GALLERY_WALL2, frmMain::_onWallGallery2Select)
|
|
||||||
EVT_RIBBONGALLERY_SELECTED(ID_GALLERY_PARCELS, frmMain::_onParcelGallerySelect)
|
|
||||||
EVT_RIBBONBUTTONBAR_CLICKED(wxID_NEW, frmMain::_onNew)
|
|
||||||
EVT_RIBBONBUTTONBAR_CLICKED(wxID_OPEN, frmMain::_onOpen)
|
|
||||||
EVT_RIBBONBUTTONBAR_CLICKED(wxID_SAVE, frmMain::_onSave)
|
|
||||||
EVT_RIBBONBUTTONBAR_CLICKED(wxID_UNDO, frmMain::_onUndo)
|
|
||||||
EVT_RIBBONBUTTONBAR_CLICKED(wxID_REDO, frmMain::_onRedo)
|
|
||||||
EVT_RIBBONBUTTONBAR_DROPDOWN_CLICKED(wxID_SAVE, frmMain::_onSaveMenu)
|
|
||||||
EVT_MENU(ID_SAVE_IN_DROPDOWN, frmMain::_onSaveMenuSave)
|
|
||||||
EVT_MENU(ID_SAVEAS, frmMain::_onSaveMenuSaveAs)
|
|
||||||
EVT_RIBBONBUTTONBAR_CLICKED(ID_VIEW_WALLS, frmMain::_onViewWalls)
|
|
||||||
EVT_RIBBONBUTTONBAR_CLICKED(ID_VIEW_FLAGS, frmMain::_onViewFlags)
|
|
||||||
EVT_RIBBONBUTTONBAR_CLICKED(ID_VIEW_PARCELS, frmMain::_onViewParcels)
|
|
||||||
EVT_RIBBONBUTTONBAR_CLICKED(ID_VIEW_POSITIONS, frmMain::_onViewPositions)
|
|
||||||
EVT_SIZE(frmMain::_onResize)
|
|
||||||
END_EVENT_TABLE()
|
|
||||||
|
|
||||||
frmMain::frmMain()
|
|
||||||
: wxFrame(NULL, wxID_ANY, L"CorsixTH Map Editor",
|
|
||||||
wxDefaultPosition, wxSize(800, 600))
|
|
||||||
{
|
|
||||||
m_sFrameCaption = wxFrame::GetTitle();
|
|
||||||
_setFilename(wxEmptyString);
|
|
||||||
|
|
||||||
wxSizer *pMainSizer = new wxBoxSizer(wxVERTICAL);
|
|
||||||
wxSplitterWindow* pSplitter = new wxSplitterWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxSP_3D);
|
|
||||||
pSplitter->SetMinimumPaneSize(250);
|
|
||||||
wxPanel *pLeftPanel = new wxPanel(pSplitter, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
|
||||||
wxPanel *pRightPanel = new wxPanel(pSplitter, wxID_ANY, wxDefaultPosition, wxDefaultSize);
|
|
||||||
wxSizer *pLeftSizer = new wxBoxSizer(wxVERTICAL);
|
|
||||||
wxSizer *pRightSizer = new wxBoxSizer(wxVERTICAL);
|
|
||||||
|
|
||||||
m_pRibbon = new wxRibbonBar(pLeftPanel, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxRIBBON_BAR_FLOW_VERTICAL | wxRIBBON_BAR_SHOW_PAGE_LABELS);
|
|
||||||
m_pRibbon->SetArtProvider(new wxRibbonMSWArtProvider);
|
|
||||||
m_pRibbon->SetTabCtrlMargins(0, 0);
|
|
||||||
m_pHomePage = new wxRibbonPage(m_pRibbon, wxID_ANY, L"Home");
|
|
||||||
wxRibbonPage* pFloorPage = new wxRibbonPage(m_pRibbon, wxID_ANY, L"Floors");
|
|
||||||
wxRibbonPanel* pFloorSimplePanel = new wxRibbonPanel(pFloorPage, wxID_ANY, L"Simple Tiles");
|
|
||||||
m_pFloorGallery1 = new RibbonBlockGallery(pFloorSimplePanel, ID_GALLERY_FLOOR1);
|
|
||||||
wxRibbonPanel* pFloorDecoratedPanel = new wxRibbonPanel(pFloorPage, wxID_ANY, L"Decorated Tiles");
|
|
||||||
m_pFloorGallery2 = new RibbonBlockGallery(pFloorDecoratedPanel, ID_GALLERY_FLOOR2);
|
|
||||||
wxRibbonPage* pWallPage = new wxRibbonPage(m_pRibbon, wxID_ANY, L"Walls");
|
|
||||||
wxRibbonPanel* pWallWestPanel = new wxRibbonPanel(pWallPage, wxID_ANY, L"West");
|
|
||||||
m_pWallGallery1 = new RibbonBlockGallery(pWallWestPanel, ID_GALLERY_WALL1);
|
|
||||||
wxRibbonPanel* pWallNorthPanel = new wxRibbonPanel(pWallPage, wxID_ANY, L"North");
|
|
||||||
m_pWallGallery2 = new RibbonBlockGallery(pWallNorthPanel, ID_GALLERY_WALL2);
|
|
||||||
m_pRibbon->Realize();
|
|
||||||
|
|
||||||
m_pGamePanel = new ScrollableGamePanel(pRightPanel);
|
|
||||||
m_pGamePanel->setExtraLuaInitFunction(_l_init, this);
|
|
||||||
m_pGamePanel->setLogWindow(m_pLogWindow = new frmLog);
|
|
||||||
wxPoint ptLogWindow = GetPosition();
|
|
||||||
ptLogWindow.x += GetSize().GetWidth();
|
|
||||||
m_pLogWindow->SetPosition(ptLogWindow);
|
|
||||||
|
|
||||||
pLeftSizer->Add(m_pRibbon, 1, wxALL | wxEXPAND);
|
|
||||||
pRightSizer->Add(m_pGamePanel, 1, wxALL | wxEXPAND);
|
|
||||||
pLeftPanel->SetSizer(pLeftSizer);
|
|
||||||
pRightPanel->SetSizer(pRightSizer);
|
|
||||||
pSplitter->SplitVertically(pLeftPanel,pRightPanel);
|
|
||||||
pSplitter->SetSashPosition(250);
|
|
||||||
pMainSizer->Add(pSplitter, 1, wxEXPAND);
|
|
||||||
|
|
||||||
SetSizer(pMainSizer);
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_setFilename(const wxString& sFilename)
|
|
||||||
{
|
|
||||||
m_sFilename = sFilename;
|
|
||||||
wxString sShortName("Untitled");
|
|
||||||
wxFileName oFilename(sFilename);
|
|
||||||
if(!oFilename.GetFullName().empty())
|
|
||||||
sShortName = oFilename.GetFullName();
|
|
||||||
SetTitle(m_sFrameCaption + wxT(" - ") + sShortName);
|
|
||||||
}
|
|
||||||
|
|
||||||
frmMain::~frmMain()
|
|
||||||
{
|
|
||||||
m_pLogWindow->Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_onRibbonPageChanged(wxRibbonBarEvent& evt)
|
|
||||||
{
|
|
||||||
switch(m_pRibbon->GetActivePage())
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
if(m_bViewParcels)
|
|
||||||
_setLuaParcelBrush(m_iParcelBrush);
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
_setLuaBlockBrushFloorTab();
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
_setLuaBlockBrushWallsTab();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
struct do_load_level_t
|
|
||||||
{
|
|
||||||
const char* sData;
|
|
||||||
size_t iLength;
|
|
||||||
frmMain* pThis;
|
|
||||||
};
|
|
||||||
|
|
||||||
void frmMain::_onNew(wxRibbonButtonBarEvent& evt)
|
|
||||||
{
|
|
||||||
do_load_level_t oParams = {NULL, 0, this};
|
|
||||||
lua_State* L = m_pGamePanel->getLua();
|
|
||||||
if(lua_cpcall(L, _l_do_load, reinterpret_cast<void*>(&oParams)) != 0)
|
|
||||||
lua_pop(L, 1);
|
|
||||||
_setFilename(wxEmptyString);
|
|
||||||
m_pGamePanel->Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString frmMain::_getMapsDirectory()
|
|
||||||
{
|
|
||||||
return wxEmptyString;
|
|
||||||
}
|
|
||||||
|
|
||||||
wxString frmMain::_getMapsFilter()
|
|
||||||
{
|
|
||||||
wxString sFilter = wxT("Theme Hospital maps (*.L[0-9]+)|");
|
|
||||||
// *.L[0-9]* isn't quite the right filter, but it is as close as reasonably
|
|
||||||
// possible to *.L[0-9]+ which file filters can reasonably get
|
|
||||||
wxString sTHMapEndings = wxT("");
|
|
||||||
char cSep = ';';
|
|
||||||
for(int i = 0; i < 10; ++i)
|
|
||||||
{
|
|
||||||
if(i == 9) cSep = '|';
|
|
||||||
sTHMapEndings += wxString::Format(L"*.L%i*%c", i, cSep);
|
|
||||||
}
|
|
||||||
sFilter += sTHMapEndings;
|
|
||||||
sFilter += wxT("CorsixTH maps (*.map)|*.map|");
|
|
||||||
sFilter += wxT("All maps (*.map, *.L[0-9]+)|*.map;");
|
|
||||||
sFilter += sTHMapEndings;
|
|
||||||
sFilter += wxT("All files (*.*)|*.*");
|
|
||||||
return sFilter;
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_onOpen(wxRibbonButtonBarEvent& evt)
|
|
||||||
{
|
|
||||||
wxString sDirectory = _getMapsDirectory();
|
|
||||||
wxString sFilter = _getMapsFilter();
|
|
||||||
wxFileDialog oOpenDialog(this, wxFileSelectorPromptStr, sDirectory,
|
|
||||||
wxEmptyString, sFilter, wxFD_OPEN | wxFD_FILE_MUST_EXIST);
|
|
||||||
oOpenDialog.SetFilterIndex(2);
|
|
||||||
if(oOpenDialog.ShowModal() != wxID_OK)
|
|
||||||
return;
|
|
||||||
wxFile fFile;
|
|
||||||
if(!fFile.Open(oOpenDialog.GetPath()))
|
|
||||||
return;
|
|
||||||
size_t iLength = static_cast<size_t>(fFile.Length());
|
|
||||||
char* sData = new (std::nothrow) char[iLength];
|
|
||||||
if(!sData)
|
|
||||||
return;
|
|
||||||
if(fFile.Read(sData, iLength) != iLength)
|
|
||||||
{
|
|
||||||
delete[] sData;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
do_load_level_t oParams = {sData, iLength, this};
|
|
||||||
lua_State* L = m_pGamePanel->getLua();
|
|
||||||
if(lua_cpcall(L, _l_do_load, reinterpret_cast<void*>(&oParams)) != 0)
|
|
||||||
lua_pop(L, 1);
|
|
||||||
delete[] sData;
|
|
||||||
_setFilename(oOpenDialog.GetPath());
|
|
||||||
m_pGamePanel->Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
int frmMain::_l_do_load(lua_State *L)
|
|
||||||
{
|
|
||||||
lua_getglobal(L, "TheApp");
|
|
||||||
lua_getfield(L, -1, "loadLevel");
|
|
||||||
lua_insert(L, -2);
|
|
||||||
do_load_level_t *pParams = reinterpret_cast<do_load_level_t*>(lua_touserdata(L, 1));
|
|
||||||
size_t iLength = pParams->iLength;
|
|
||||||
const char* sData = pParams->sData;
|
|
||||||
lua_pushlstring(L, sData, iLength);
|
|
||||||
if(iLength >= 3 && sData[0] == 'R' && sData[1] == 'N' && sData[2] == 'C')
|
|
||||||
{
|
|
||||||
lua_getglobal(L, "require");
|
|
||||||
lua_pushliteral(L, "rnc");
|
|
||||||
lua_call(L, 1, 1);
|
|
||||||
lua_getfield(L, -1, "decompress");
|
|
||||||
lua_insert(L, -3);
|
|
||||||
lua_call(L, 2, 1);
|
|
||||||
}
|
|
||||||
lua_call(L, 2, 0);
|
|
||||||
|
|
||||||
pParams->pThis->_applyViewWalls();
|
|
||||||
pParams->pThis->_applyViewOverlay();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_onSave(wxRibbonButtonBarEvent& evt)
|
|
||||||
{
|
|
||||||
wxCommandEvent dummy;
|
|
||||||
_onSaveMenuSave(dummy);
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_onSaveMenu(wxRibbonButtonBarEvent& evt)
|
|
||||||
{
|
|
||||||
wxMenu mnuPopup;
|
|
||||||
mnuPopup.Append(ID_SAVE_IN_DROPDOWN, "Save");
|
|
||||||
mnuPopup.Append(ID_SAVEAS, "Save As");
|
|
||||||
evt.PopupMenu(&mnuPopup);
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_onUndo(wxRibbonButtonBarEvent& evt)
|
|
||||||
{
|
|
||||||
_doLuaUndo();
|
|
||||||
}
|
|
||||||
void frmMain::_onRedo(wxRibbonButtonBarEvent& evt)
|
|
||||||
{
|
|
||||||
_doLuaRedo();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct map_save_t
|
|
||||||
{
|
|
||||||
wxFile fFile;
|
|
||||||
|
|
||||||
static void writer(void* pThis_, const unsigned char* pData, size_t iLen)
|
|
||||||
{
|
|
||||||
map_save_t* pThis = reinterpret_cast<map_save_t*>(pThis_);
|
|
||||||
pThis->fFile.Write(reinterpret_cast<const void*>(pData), iLen);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
void frmMain::_onSaveMenuSave(wxCommandEvent& evt)
|
|
||||||
{
|
|
||||||
if(m_sFilename.empty())
|
|
||||||
{
|
|
||||||
_onSaveMenuSaveAs(evt);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
map_save_t oSave;
|
|
||||||
if(oSave.fFile.Open(m_sFilename, wxFile::write))
|
|
||||||
{
|
|
||||||
lua_State* L = m_pGamePanel->getLua();
|
|
||||||
luaT_execute(L, "return TheApp.world.map.th");
|
|
||||||
THMap *pMap = reinterpret_cast<THMap*>(lua_touserdata(L, -1));
|
|
||||||
lua_pop(L, 1);
|
|
||||||
THMapWrapper::autoSetHelipad(pMap);
|
|
||||||
luaT_execute(L, "return TheApp.ui:ScreenToWorld(...)",
|
|
||||||
m_pGamePanel->GetSize().GetWidth() / 2,
|
|
||||||
m_pGamePanel->GetSize().GetHeight() / 2);
|
|
||||||
int iCameraX = (int)lua_tointeger(L, -2);
|
|
||||||
int iCameraY = (int)lua_tointeger(L, -1);
|
|
||||||
lua_pop(L, 2);
|
|
||||||
pMap->setPlayerCameraTile(0, iCameraX, iCameraY);
|
|
||||||
pMap->save(map_save_t::writer, reinterpret_cast<void*>(&oSave));
|
|
||||||
::wxMessageBox(wxT("Map saved."), wxT("Save"), wxOK | wxCENTER |
|
|
||||||
wxICON_INFORMATION, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_onSaveMenuSaveAs(wxCommandEvent& evt)
|
|
||||||
{
|
|
||||||
wxString sDirectory = _getMapsDirectory();
|
|
||||||
wxString sFilter = _getMapsFilter();
|
|
||||||
wxFileDialog oSaveDialog(this, wxFileSelectorPromptStr, sDirectory,
|
|
||||||
m_sFilename, sFilter, wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
|
|
||||||
oSaveDialog.SetFilterIndex(2);
|
|
||||||
if(oSaveDialog.ShowModal() != wxID_OK)
|
|
||||||
return;
|
|
||||||
_setFilename(oSaveDialog.GetPath());
|
|
||||||
_onSaveMenuSave(evt);
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_onViewWalls(wxRibbonButtonBarEvent& evt)
|
|
||||||
{
|
|
||||||
m_bViewWalls = evt.IsChecked();
|
|
||||||
_applyViewWalls();
|
|
||||||
m_pGamePanel->Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_onViewFlags(wxRibbonButtonBarEvent& evt)
|
|
||||||
{
|
|
||||||
m_bViewFlags = evt.IsChecked();
|
|
||||||
_applyViewOverlay();
|
|
||||||
m_pGamePanel->Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_onViewParcels(wxRibbonButtonBarEvent& evt)
|
|
||||||
{
|
|
||||||
m_bViewParcels = evt.IsChecked();
|
|
||||||
_applyViewOverlay();
|
|
||||||
m_pGamePanel->Refresh();
|
|
||||||
|
|
||||||
if(evt.IsChecked())
|
|
||||||
{
|
|
||||||
wxRibbonPanel* pParcelPanel = new wxRibbonPanel(m_pHomePage,
|
|
||||||
ID_PARCEL_PANEL, L"Parcels");
|
|
||||||
wxRibbonGallery* pParcelGallery = new wxRibbonGallery(pParcelPanel,
|
|
||||||
ID_GALLERY_PARCELS);
|
|
||||||
_populateParcelGallery(pParcelGallery);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wxWindow* pParcelPanel = m_pHomePage->FindWindow(ID_PARCEL_PANEL);
|
|
||||||
if(pParcelPanel)
|
|
||||||
pParcelPanel->Destroy();
|
|
||||||
}
|
|
||||||
m_pRibbon->Realize();
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_onViewPositions(wxRibbonButtonBarEvent& evt)
|
|
||||||
{
|
|
||||||
m_bViewPositions = evt.IsChecked();
|
|
||||||
_applyViewOverlay();
|
|
||||||
m_pGamePanel->Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
wxBitmap frmMain::_asBitmap(THSpriteSheet* pSheet, unsigned int iSprite)
|
|
||||||
{
|
|
||||||
unsigned int iWidth, iHeight;
|
|
||||||
pSheet->getSpriteSize(iSprite, &iWidth, &iHeight);
|
|
||||||
wxImage imgSprite;
|
|
||||||
imgSprite.Create(iWidth, iHeight);
|
|
||||||
if(!imgSprite.HasAlpha())
|
|
||||||
imgSprite.InitAlpha();
|
|
||||||
pSheet->wxDrawSprite(iSprite, imgSprite.GetData(), imgSprite.GetAlpha());
|
|
||||||
return wxBitmap(imgSprite);
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_populateParcelGallery(wxRibbonGallery* pGallery)
|
|
||||||
{
|
|
||||||
THSpriteSheet *pBlocksSheet;
|
|
||||||
THSpriteSheet *pOutlineSheet;
|
|
||||||
THSpriteSheet *pFontSheet;
|
|
||||||
{
|
|
||||||
lua_State *L = m_pGamePanel->getLua();
|
|
||||||
luaT_execute(L, "return TheApp.map.blocks");
|
|
||||||
pBlocksSheet = reinterpret_cast<THSpriteSheet*>(lua_touserdata(L, -1));
|
|
||||||
luaT_execute(L, "return TheApp.map.cell_outline");
|
|
||||||
pOutlineSheet = reinterpret_cast<THSpriteSheet*>(lua_touserdata(L, -1));
|
|
||||||
luaT_execute(L, "return TheApp.gfx:loadBuiltinFont()");
|
|
||||||
pFontSheet = reinterpret_cast<THBitmapFont*>(lua_touserdata(L, -1))
|
|
||||||
->getSpriteSheet();
|
|
||||||
lua_pop(L, 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
wxBitmap bmOutline(_asBitmap(pBlocksSheet, 74));
|
|
||||||
wxMemoryDC dcMem;
|
|
||||||
dcMem.SelectObject(bmOutline);
|
|
||||||
for(int i = 0; i < 4; ++i)
|
|
||||||
{
|
|
||||||
dcMem.DrawBitmap(_asBitmap(pOutlineSheet, 18 + i), 0, 0);
|
|
||||||
}
|
|
||||||
dcMem.SelectObject(wxNullBitmap);
|
|
||||||
|
|
||||||
wxBitmap bmNumbers[10];
|
|
||||||
for(int i = 0; i < 10; ++i)
|
|
||||||
{
|
|
||||||
bmNumbers[i] = _asBitmap(pFontSheet, '0' + i - 31);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(intptr_t iParcel = 0; iParcel < 32; ++iParcel)
|
|
||||||
{
|
|
||||||
wxBitmap bmParcel(bmOutline);
|
|
||||||
dcMem.SelectObject(bmParcel);
|
|
||||||
|
|
||||||
char sMsg[8];
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(push)
|
|
||||||
#pragma warning(disable: 4996)
|
|
||||||
#endif
|
|
||||||
sprintf(sMsg, "%i", iParcel);
|
|
||||||
#ifdef _MSC_VER
|
|
||||||
#pragma warning(pop)
|
|
||||||
#endif
|
|
||||||
int iX = 0, iY = 0;
|
|
||||||
for(char* s = sMsg; *s; ++s)
|
|
||||||
{
|
|
||||||
wxBitmap& bm = bmNumbers[*s - '0'];
|
|
||||||
iX += bm.GetWidth();
|
|
||||||
iY = std::max(iY, bm.GetHeight());
|
|
||||||
}
|
|
||||||
iX = (bmParcel.GetWidth() - iX) / 2;
|
|
||||||
iY = (bmParcel.GetHeight() - iY) / 2;
|
|
||||||
|
|
||||||
for(char* s = sMsg; *s; ++s)
|
|
||||||
{
|
|
||||||
wxBitmap& bm = bmNumbers[*s - '0'];
|
|
||||||
dcMem.DrawBitmap(bm, iX, iY);
|
|
||||||
iX += bm.GetWidth();
|
|
||||||
}
|
|
||||||
|
|
||||||
dcMem.SelectObject(wxNullBitmap);
|
|
||||||
pGallery->SetItemClientData(pGallery->Append(bmParcel, iParcel),
|
|
||||||
reinterpret_cast<void*>(iParcel));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_onResize(wxSizeEvent& evt)
|
|
||||||
{
|
|
||||||
wxRect rcLogWindow = wxRect(GetPosition(), m_pLogWindow->GetSize());
|
|
||||||
rcLogWindow.x += evt.GetSize().GetWidth();
|
|
||||||
rcLogWindow.height = evt.GetSize().GetHeight();
|
|
||||||
m_pLogWindow->SetSize(rcLogWindow);
|
|
||||||
evt.Skip();
|
|
||||||
}
|
|
||||||
|
|
||||||
int frmMain::_l_init(lua_State *L)
|
|
||||||
{
|
|
||||||
frmMain *pThis = reinterpret_cast<frmMain*>(lua_touserdata(L, 1));
|
|
||||||
|
|
||||||
THMapWrapper::wrap(L);
|
|
||||||
|
|
||||||
// Create a new environment table: {
|
|
||||||
// [1] = <light userdata pThis>,
|
|
||||||
// }
|
|
||||||
lua_newtable(L);
|
|
||||||
lua_insert(L, 1);
|
|
||||||
lua_rawseti(L, 1, 1);
|
|
||||||
lua_replace(L, LUA_ENVIRONINDEX);
|
|
||||||
// NB: Following functions registered with above environment table
|
|
||||||
|
|
||||||
luaT_execute(L, "MapEditorSetBlocks = ...", _l_set_blocks);
|
|
||||||
luaT_execute(L, "MapEditorSetBlockBrush = ...", _l_set_block_brush);
|
|
||||||
luaT_execute(L, "MapEditorInitWithLuaApp = ...", _l_init_with_lua_app);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
class FullSizeButtonBar : public wxRibbonButtonBar
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
FullSizeButtonBar(wxWindow* parent, wxWindowID id)
|
|
||||||
: wxRibbonButtonBar(parent, id)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual wxSize GetMinSize() const
|
|
||||||
{
|
|
||||||
return DoGetBestSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual wxSize DoGetNextSmallerSize(wxOrientation direction,
|
|
||||||
wxSize relative_to) const
|
|
||||||
{
|
|
||||||
return relative_to;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
int frmMain::_l_init_with_lua_app(lua_State *L)
|
|
||||||
{
|
|
||||||
lua_rawgeti(L, LUA_ENVIRONINDEX, 1);
|
|
||||||
frmMain *pThis = reinterpret_cast<frmMain*>(lua_touserdata(L, -1));
|
|
||||||
lua_pop(L, 1);
|
|
||||||
|
|
||||||
lua_getfield(L, 1, "getBitmapDir");
|
|
||||||
lua_pushvalue(L, 1);
|
|
||||||
lua_call(L, 1, 1);
|
|
||||||
wxString sBitmapDir = lua_tostring(L, -1);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
|
|
||||||
wxRibbonPage* pHomePage = pThis->m_pHomePage;
|
|
||||||
wxRibbonPanel* pFilePanel = new wxRibbonPanel(pHomePage, wxID_ANY, wxT("File"));
|
|
||||||
wxRibbonButtonBar* pFileButtons = new FullSizeButtonBar(pFilePanel, wxID_ANY);
|
|
||||||
#define BITMAP(name) wxBitmap(sBitmapDir + (wxT(name) wxT("32.png")), wxBITMAP_TYPE_PNG)
|
|
||||||
pFileButtons->AddButton(wxID_NEW, wxT("New"), BITMAP("new"));
|
|
||||||
pFileButtons->AddButton(wxID_OPEN, wxT("Load"), BITMAP("open"));
|
|
||||||
pFileButtons->AddHybridButton(wxID_SAVE, wxT("Save"), BITMAP("save"));
|
|
||||||
pFileButtons->AddButton(wxID_UNDO, wxT("Undo"), BITMAP("undo"));
|
|
||||||
pFileButtons->AddButton(wxID_REDO, wxT("Redo"), BITMAP("redo"));
|
|
||||||
|
|
||||||
|
|
||||||
wxRibbonPanel* pViewPanel = new wxRibbonPanel(pHomePage, wxID_ANY, wxT("View"));
|
|
||||||
wxRibbonButtonBar* pViewButtons = new FullSizeButtonBar(pViewPanel, wxID_ANY);
|
|
||||||
pViewButtons->AddToggleButton(ID_VIEW_WALLS, wxT("Walls"), BITMAP("transparent_walls"));
|
|
||||||
pViewButtons->ToggleButton(ID_VIEW_WALLS, pThis->m_bViewWalls = true);
|
|
||||||
pViewButtons->AddToggleButton(ID_VIEW_FLAGS, wxT("Flags"), BITMAP("flags"));
|
|
||||||
pViewButtons->ToggleButton(ID_VIEW_FLAGS, pThis->m_bViewFlags = false);
|
|
||||||
pViewButtons->AddToggleButton(ID_VIEW_PARCELS, wxT("Parcels"), BITMAP("parcels"));
|
|
||||||
pViewButtons->ToggleButton(ID_VIEW_PARCELS, pThis->m_bViewParcels = false);
|
|
||||||
pViewButtons->AddToggleButton(ID_VIEW_POSITIONS, wxT("Positions"), BITMAP("positions"));
|
|
||||||
pViewButtons->ToggleButton(ID_VIEW_POSITIONS, pThis->m_bViewPositions = false);
|
|
||||||
|
|
||||||
|
|
||||||
#undef BITMAP
|
|
||||||
pThis->m_pRibbon->Realise();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_applyViewWalls()
|
|
||||||
{
|
|
||||||
m_pGamePanel->getMap()->setAllWallDrawFlags(m_bViewWalls ? 0 : THDF_Alpha50);
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_applyViewOverlay()
|
|
||||||
{
|
|
||||||
if(m_bViewFlags || m_bViewParcels || m_bViewPositions)
|
|
||||||
{
|
|
||||||
lua_State *L = m_pGamePanel->getLua();
|
|
||||||
luaT_execute(L, "return TheApp.gfx:loadBuiltinFont(), TheApp.map.cell_outline");
|
|
||||||
THFont *pFont = reinterpret_cast<THFont*>(lua_touserdata(L, -2));
|
|
||||||
THSpriteSheet *pSprites = reinterpret_cast<THSpriteSheet*>(lua_touserdata(L, -1));
|
|
||||||
lua_pop(L, 2);
|
|
||||||
|
|
||||||
THMapTypicalOverlay *pFlags = NULL;
|
|
||||||
THMapTypicalOverlay *pParcels = NULL;
|
|
||||||
THMapPositionsOverlay *pPositions = NULL;
|
|
||||||
if(m_bViewFlags)
|
|
||||||
{
|
|
||||||
pFlags = new THMapFlagsOverlay;
|
|
||||||
pFlags->setFont(pFont, false);
|
|
||||||
pFlags->setSprites(pSprites, false);
|
|
||||||
}
|
|
||||||
if(m_bViewParcels)
|
|
||||||
{
|
|
||||||
pParcels = new THMapParcelsOverlay;
|
|
||||||
pParcels->setFont(pFont, false);
|
|
||||||
pParcels->setSprites(pSprites, false);
|
|
||||||
}
|
|
||||||
if(m_bViewPositions)
|
|
||||||
{
|
|
||||||
pPositions = new THMapPositionsOverlay;
|
|
||||||
pPositions->setFont(pFont, false);
|
|
||||||
pPositions->setSprites(pSprites, false);
|
|
||||||
pPositions->setBackgroundSprite(2);
|
|
||||||
}
|
|
||||||
THMapOverlayPair *pOverlays = new THMapOverlayPair;
|
|
||||||
pOverlays->setFirst(pParcels, true);
|
|
||||||
pOverlays->setSecond(pFlags, true);
|
|
||||||
THMapOverlayPair *pOverlays2 = new THMapOverlayPair;
|
|
||||||
pOverlays2->setFirst(pOverlays, true);
|
|
||||||
pOverlays2->setSecond(pPositions, true);
|
|
||||||
m_pGamePanel->getMap()->setOverlay(pOverlays2, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
m_pGamePanel->getMap()->setOverlay(NULL, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int frmMain::_l_set_blocks(lua_State *L)
|
|
||||||
{
|
|
||||||
lua_rawgeti(L, LUA_ENVIRONINDEX, 1);
|
|
||||||
frmMain *pThis = reinterpret_cast<frmMain*>(lua_touserdata(L, -1));
|
|
||||||
lua_pop(L, 1);
|
|
||||||
|
|
||||||
luaL_checktype(L, 1, LUA_TUSERDATA);
|
|
||||||
luaL_checktype(L, 2, LUA_TTABLE);
|
|
||||||
|
|
||||||
pThis->m_iFloorTabBrushF = 0;
|
|
||||||
pThis->m_iFloorTabBrushW1 = 0;
|
|
||||||
pThis->m_iFloorTabBrushW2 = 0;
|
|
||||||
pThis->m_iWallsTabBrushF = 0;
|
|
||||||
pThis->m_iWallsTabBrushW1 = 0;
|
|
||||||
pThis->m_iWallsTabBrushW2 = 0;
|
|
||||||
|
|
||||||
THSpriteSheet *pSheet = reinterpret_cast<THSpriteSheet*>(lua_touserdata(L, 1));
|
|
||||||
pThis->m_pFloorGallery1->Populate(pSheet, "floor", "simple", L, 2);
|
|
||||||
pThis->m_pFloorGallery2->Populate(pSheet, "floor", "decorated", L, 2);
|
|
||||||
pThis->m_pWallGallery1->Populate(pSheet, "wall", "west", L, 2);
|
|
||||||
pThis->m_pWallGallery2->Populate(pSheet, "wall", "north", L, 2);
|
|
||||||
pThis->m_pRibbon->Realize();
|
|
||||||
pThis->Layout();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int frmMain::_l_set_block_brush(lua_State *L)
|
|
||||||
{
|
|
||||||
lua_rawgeti(L, LUA_ENVIRONINDEX, 1);
|
|
||||||
frmMain *pThis = reinterpret_cast<frmMain*>(lua_touserdata(L, -1));
|
|
||||||
lua_pop(L, 1);
|
|
||||||
|
|
||||||
int iBlock;
|
|
||||||
|
|
||||||
if(pThis->m_pRibbon->GetActivePage() == 0)
|
|
||||||
pThis->m_pRibbon->SetActivePage(1);
|
|
||||||
|
|
||||||
wxRibbonGalleryEvent evt(wxEVT_COMMAND_RIBBONGALLERY_SELECTED);
|
|
||||||
if(pThis->m_pRibbon->GetActivePage() == 1)
|
|
||||||
{
|
|
||||||
// Floor
|
|
||||||
iBlock = luaL_checkint(L, 1);
|
|
||||||
if(pThis->m_pFloorGallery1->SelectAndMakeVisible(iBlock))
|
|
||||||
{
|
|
||||||
pThis->m_pFloorGallery2->SetSelection(NULL);
|
|
||||||
evt.SetGallery(pThis->m_pFloorGallery1);
|
|
||||||
}
|
|
||||||
else if(pThis->m_pFloorGallery2->SelectAndMakeVisible(iBlock))
|
|
||||||
{
|
|
||||||
pThis->m_pFloorGallery1->SetSelection(NULL);
|
|
||||||
evt.SetGallery(pThis->m_pFloorGallery2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Wall
|
|
||||||
iBlock = luaL_checkint(L, 2);
|
|
||||||
if(pThis->m_pWallGallery1->SelectAndMakeVisible(iBlock))
|
|
||||||
{
|
|
||||||
pThis->m_pWallGallery2->SetSelection(NULL);
|
|
||||||
evt.SetGallery(pThis->m_pWallGallery1);
|
|
||||||
}
|
|
||||||
else if(pThis->m_pWallGallery2->SelectAndMakeVisible(iBlock))
|
|
||||||
{
|
|
||||||
pThis->m_pWallGallery1->SetSelection(NULL);
|
|
||||||
evt.SetGallery(pThis->m_pWallGallery2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
evt.SetId(evt.GetGallery()->GetId());
|
|
||||||
evt.SetGalleryItem(evt.GetGallery()->GetSelection());
|
|
||||||
pThis->ProcessEvent(evt);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_onFloorGallery1Select(wxRibbonGalleryEvent& evt)
|
|
||||||
{
|
|
||||||
if(evt.GetGalleryItem() != NULL)
|
|
||||||
{
|
|
||||||
m_pFloorGallery2->SetSelection(NULL);
|
|
||||||
int iBaseBlock;
|
|
||||||
int iBlock = m_pFloorGallery1->GetBlock(evt.GetGalleryItem(), &iBaseBlock);
|
|
||||||
if(iBaseBlock != 0)
|
|
||||||
_setLuaBlockBrushFloorTab(iBaseBlock, iBlock, 0);
|
|
||||||
else
|
|
||||||
_setLuaBlockBrushFloorTab(iBlock, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_onFloorGallery2Select(wxRibbonGalleryEvent& evt)
|
|
||||||
{
|
|
||||||
if(evt.GetGalleryItem() != NULL)
|
|
||||||
{
|
|
||||||
m_pFloorGallery1->SetSelection(NULL);
|
|
||||||
int iBaseBlock;
|
|
||||||
int iBlock = m_pFloorGallery2->GetBlock(evt.GetGalleryItem(), &iBaseBlock);
|
|
||||||
if(iBaseBlock != 0)
|
|
||||||
_setLuaBlockBrushFloorTab(iBaseBlock, iBlock, 0);
|
|
||||||
else
|
|
||||||
_setLuaBlockBrushFloorTab(iBlock, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_onParcelGallerySelect(wxRibbonGalleryEvent& evt)
|
|
||||||
{
|
|
||||||
if(evt.GetGalleryItem() != NULL)
|
|
||||||
{
|
|
||||||
_setLuaParcelBrush(static_cast<int>(reinterpret_cast<intptr_t>(
|
|
||||||
evt.GetGallery()->GetItemClientData(evt.GetGalleryItem()))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_setLuaParcelBrush(int iParcel)
|
|
||||||
{
|
|
||||||
m_iParcelBrush = iParcel;
|
|
||||||
lua_State *L = m_pGamePanel->getLua();
|
|
||||||
luaT_execute(L, "_MAP_EDITOR:setBlockBrushParcel(...)", iParcel);
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_onWallGallery1Select(wxRibbonGalleryEvent& evt)
|
|
||||||
{
|
|
||||||
if(evt.GetGalleryItem() != NULL)
|
|
||||||
{
|
|
||||||
m_pWallGallery2->SetSelection(NULL);
|
|
||||||
int iBlock = m_pWallGallery1->GetBlock(evt.GetGalleryItem(), NULL);
|
|
||||||
_setLuaBlockBrushWallsTab(0, 0, iBlock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_onWallGallery2Select(wxRibbonGalleryEvent& evt)
|
|
||||||
{
|
|
||||||
if(evt.GetGalleryItem() != NULL)
|
|
||||||
{
|
|
||||||
m_pWallGallery1->SetSelection(NULL);
|
|
||||||
int iBlock = m_pWallGallery2->GetBlock(evt.GetGalleryItem(), NULL);
|
|
||||||
_setLuaBlockBrushWallsTab(0, iBlock, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_setLuaBlockBrushFloorTab(int iBlockF, int iBlockW1, int iBlockW2)
|
|
||||||
{
|
|
||||||
m_iFloorTabBrushF = iBlockF;
|
|
||||||
m_iFloorTabBrushW1 = iBlockW1;
|
|
||||||
m_iFloorTabBrushW2 = iBlockW2;
|
|
||||||
_setLuaBlockBrushFloorTab();
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_setLuaBlockBrushWallsTab(int iBlockF, int iBlockW1, int iBlockW2)
|
|
||||||
{
|
|
||||||
m_iWallsTabBrushF = iBlockF;
|
|
||||||
m_iWallsTabBrushW1 = iBlockW1;
|
|
||||||
m_iWallsTabBrushW2 = iBlockW2;
|
|
||||||
_setLuaBlockBrushWallsTab();
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_setLuaBlockBrushFloorTab()
|
|
||||||
{
|
|
||||||
_setLuaBlockBrush(m_iFloorTabBrushF, m_iFloorTabBrushW1, m_iFloorTabBrushW2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_setLuaBlockBrushWallsTab()
|
|
||||||
{
|
|
||||||
_setLuaBlockBrush(m_iWallsTabBrushF, m_iWallsTabBrushW1, m_iWallsTabBrushW2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_setLuaBlockBrush(int iBlockF, int iBlockW1, int iBlockW2)
|
|
||||||
{
|
|
||||||
lua_State *L = m_pGamePanel->getLua();
|
|
||||||
luaT_execute(L, "_MAP_EDITOR:setBlockBrush(...)",
|
|
||||||
iBlockF, iBlockW1, iBlockW2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_doLuaUndo()
|
|
||||||
{
|
|
||||||
lua_State *L = m_pGamePanel->getLua();
|
|
||||||
luaT_execute(L, "_MAP_EDITOR:undo()");
|
|
||||||
m_pGamePanel->Refresh();
|
|
||||||
}
|
|
||||||
|
|
||||||
void frmMain::_doLuaRedo()
|
|
||||||
{
|
|
||||||
lua_State *L = m_pGamePanel->getLua();
|
|
||||||
luaT_execute(L, "_MAP_EDITOR:redo()");
|
|
||||||
m_pGamePanel->Refresh();
|
|
||||||
}
|
|
@@ -1,129 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
// For compilers that support precompilation, includes "wx/wx.h".
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
#pragma hdrstop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// for all others, include the necessary headers (this file is usually all you
|
|
||||||
// need because it includes almost all "standard" wxWidgets headers)
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/wx.h"
|
|
||||||
#endif
|
|
||||||
// ----------------------------
|
|
||||||
#include "scrollable_game.h"
|
|
||||||
#include <wx/ribbon/bar.h>
|
|
||||||
#include <wx/ribbon/buttonbar.h>
|
|
||||||
#include <wx/splitter.h>
|
|
||||||
#include "block_gallery.h"
|
|
||||||
|
|
||||||
class frmMain : public wxFrame
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
frmMain();
|
|
||||||
~frmMain();
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
ID_GALLERY_FLOOR1 = wxID_HIGHEST + 1,
|
|
||||||
ID_GALLERY_FLOOR2,
|
|
||||||
ID_GALLERY_WALL1,
|
|
||||||
ID_GALLERY_WALL2,
|
|
||||||
ID_GALLERY_PARCELS,
|
|
||||||
ID_VIEW_WALLS,
|
|
||||||
ID_VIEW_FLAGS,
|
|
||||||
ID_VIEW_PARCELS,
|
|
||||||
ID_VIEW_POSITIONS,
|
|
||||||
ID_PARCEL_PANEL,
|
|
||||||
ID_SAVE_IN_DROPDOWN,
|
|
||||||
ID_SAVEAS
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
wxRibbonBar* m_pRibbon;
|
|
||||||
wxRibbonPage* m_pHomePage;
|
|
||||||
frmLog* m_pLogWindow;
|
|
||||||
ScrollableGamePanel* m_pGamePanel;
|
|
||||||
RibbonBlockGallery* m_pFloorGallery1;
|
|
||||||
RibbonBlockGallery* m_pFloorGallery2;
|
|
||||||
RibbonBlockGallery* m_pWallGallery1;
|
|
||||||
RibbonBlockGallery* m_pWallGallery2;
|
|
||||||
wxString m_sFrameCaption;
|
|
||||||
wxString m_sFilename;
|
|
||||||
bool m_bViewFlags;
|
|
||||||
bool m_bViewParcels;
|
|
||||||
bool m_bViewPositions;
|
|
||||||
bool m_bViewWalls;
|
|
||||||
int m_iFloorTabBrushF;
|
|
||||||
int m_iFloorTabBrushW1;
|
|
||||||
int m_iFloorTabBrushW2;
|
|
||||||
int m_iWallsTabBrushF;
|
|
||||||
int m_iWallsTabBrushW1;
|
|
||||||
int m_iWallsTabBrushW2;
|
|
||||||
int m_iParcelBrush;
|
|
||||||
|
|
||||||
void _applyViewWalls();
|
|
||||||
void _applyViewOverlay();
|
|
||||||
wxString _getMapsDirectory();
|
|
||||||
wxString _getMapsFilter();
|
|
||||||
void _setFilename(const wxString& sFilename);
|
|
||||||
void _onFloorGallery1Select(wxRibbonGalleryEvent& evt);
|
|
||||||
void _onFloorGallery2Select(wxRibbonGalleryEvent& evt);
|
|
||||||
void _onWallGallery1Select(wxRibbonGalleryEvent& evt);
|
|
||||||
void _onWallGallery2Select(wxRibbonGalleryEvent& evt);
|
|
||||||
void _onParcelGallerySelect(wxRibbonGalleryEvent& evt);
|
|
||||||
void _onNew(wxRibbonButtonBarEvent& evt);
|
|
||||||
void _onOpen(wxRibbonButtonBarEvent& evt);
|
|
||||||
void _onSave(wxRibbonButtonBarEvent& evt);
|
|
||||||
void _onUndo(wxRibbonButtonBarEvent& evt);
|
|
||||||
void _onRedo(wxRibbonButtonBarEvent& evt);
|
|
||||||
void _onSaveMenu(wxRibbonButtonBarEvent& evt);
|
|
||||||
void _onSaveMenuSave(wxCommandEvent& evt);
|
|
||||||
void _onSaveMenuSaveAs(wxCommandEvent& evt);
|
|
||||||
void _onResize(wxSizeEvent& evt);
|
|
||||||
void _onViewWalls(wxRibbonButtonBarEvent& evt);
|
|
||||||
void _onViewFlags(wxRibbonButtonBarEvent& evt);
|
|
||||||
void _onViewParcels(wxRibbonButtonBarEvent& evt);
|
|
||||||
void _onViewPositions(wxRibbonButtonBarEvent& evt);
|
|
||||||
void _onRibbonPageChanged(wxRibbonBarEvent& evt);
|
|
||||||
void _populateParcelGallery(wxRibbonGallery* pGallery);
|
|
||||||
static wxBitmap _asBitmap(THSpriteSheet* pSheet, unsigned int iSprite);
|
|
||||||
static int _l_init(lua_State *L);
|
|
||||||
static int _l_init_with_lua_app(lua_State *L);
|
|
||||||
static int _l_set_blocks(lua_State *L);
|
|
||||||
static int _l_set_block_brush(lua_State *L);
|
|
||||||
static int _l_do_load(lua_State *L);
|
|
||||||
void _setLuaBlockBrushFloorTab(int iBlockF, int iBlockW1, int iBlockW2);
|
|
||||||
void _setLuaBlockBrushWallsTab(int iBlockF, int iBlockW1, int iBlockW2);
|
|
||||||
void _setLuaBlockBrushFloorTab();
|
|
||||||
void _setLuaBlockBrushWallsTab();
|
|
||||||
void _setLuaBlockBrush(int iBlockF, int iBlockW1, int iBlockW2);
|
|
||||||
void _setLuaParcelBrush(int iParcel);
|
|
||||||
void _doLuaUndo();
|
|
||||||
void _doLuaRedo();
|
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE();
|
|
||||||
};
|
|
@@ -1,31 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "config.h"
|
|
||||||
#ifndef CORSIX_TH_USE_OGL_RENDERER
|
|
||||||
#error To compile the map editor, the OpenGL rendering engine must be used
|
|
||||||
#endif
|
|
||||||
#include "../../CorsixTH/Src/th_gfx.h"
|
|
||||||
#include "../../CorsixTH/Src/th_lua.h"
|
|
||||||
#include "../../CorsixTH/Src/th_map.h"
|
|
||||||
#include "../../CorsixTH/Src/th_map_overlays.h"
|
|
@@ -1,304 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2009 Peter "Corsix" Cawley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
#include <algorithm>
|
|
||||||
#include "scrollable_game.h"
|
|
||||||
|
|
||||||
BEGIN_EVENT_TABLE(ScrollableGamePanel, wxPanel)
|
|
||||||
EVT_SIZE(ScrollableGamePanel::_onResize)
|
|
||||||
EVT_COMMAND_SCROLL(ID_X_SCROLL, ScrollableGamePanel::_onScroll)
|
|
||||||
EVT_COMMAND_SCROLL(ID_Y_SCROLL, ScrollableGamePanel::_onScroll)
|
|
||||||
EVT_TIMER(wxID_ANY, ScrollableGamePanel::_onTimer)
|
|
||||||
END_EVENT_TABLE()
|
|
||||||
|
|
||||||
ScrollableGamePanel::ScrollableGamePanel(wxWindow *pParent)
|
|
||||||
: wxPanel(pParent)
|
|
||||||
, m_pGamePanel(NULL)
|
|
||||||
, m_pMapScrollX(NULL)
|
|
||||||
, m_pMapScrollY(NULL)
|
|
||||||
, m_bShouldRespondToScroll(true)
|
|
||||||
{
|
|
||||||
wxFlexGridSizer *pSizer = new wxFlexGridSizer(2, 2, 0, 0);
|
|
||||||
pSizer->AddGrowableRow(0, 1);
|
|
||||||
pSizer->AddGrowableCol(0, 1);
|
|
||||||
|
|
||||||
pSizer->Add(m_pGamePanel = new EmbeddedGamePanel(this), 1, wxEXPAND);
|
|
||||||
m_pGamePanel->setExtraLuaInitFunction(_l_extra_init,
|
|
||||||
reinterpret_cast<void*>(this));
|
|
||||||
pSizer->Add(m_pMapScrollY = new wxScrollBar(this, ID_Y_SCROLL,
|
|
||||||
wxDefaultPosition, wxDefaultSize, wxVERTICAL), 0, wxEXPAND);
|
|
||||||
pSizer->Add(m_pMapScrollX = new wxScrollBar(this, ID_X_SCROLL,
|
|
||||||
wxDefaultPosition, wxDefaultSize, wxHORIZONTAL), 0, wxEXPAND);
|
|
||||||
pSizer->AddSpacer(0);
|
|
||||||
|
|
||||||
m_pTimer = new wxTimer(this, wxID_ANY);
|
|
||||||
m_pTimer->Start(100, false);
|
|
||||||
|
|
||||||
SetSizer(pSizer);
|
|
||||||
}
|
|
||||||
|
|
||||||
ScrollableGamePanel::~ScrollableGamePanel()
|
|
||||||
{
|
|
||||||
m_pTimer->Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScrollableGamePanel::setExtraLuaInitFunction(lua_CFunction fn, void* arg)
|
|
||||||
{
|
|
||||||
m_fnExtraInit = fn;
|
|
||||||
m_pExtraInitArg = arg;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScrollableGamePanel::setLogWindow(frmLog *pLogWindow)
|
|
||||||
{
|
|
||||||
m_pGamePanel->setLogWindow(pLogWindow);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ScrollableGamePanel::loadLua()
|
|
||||||
{
|
|
||||||
return m_pGamePanel->loadLua();
|
|
||||||
}
|
|
||||||
|
|
||||||
lua_State* ScrollableGamePanel::getLua()
|
|
||||||
{
|
|
||||||
return m_pGamePanel->getLua();
|
|
||||||
}
|
|
||||||
|
|
||||||
THMap* ScrollableGamePanel::getMap()
|
|
||||||
{
|
|
||||||
return m_pGamePanel->getMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScrollableGamePanel::_onResize(wxSizeEvent& evt)
|
|
||||||
{
|
|
||||||
lua_State *L = m_pGamePanel->getLua();
|
|
||||||
if(!L)
|
|
||||||
goto default_resize;
|
|
||||||
|
|
||||||
// Get old world-coordinates of window center
|
|
||||||
lua_Number fX, fY;
|
|
||||||
lua_getglobal(L, "TheApp");
|
|
||||||
if(lua_isnil(L, -1))
|
|
||||||
{
|
|
||||||
lua_pop(L, 1);
|
|
||||||
goto default_resize;
|
|
||||||
}
|
|
||||||
lua_getfield(L, -1, "ui");
|
|
||||||
if(lua_isnil(L, -1))
|
|
||||||
{
|
|
||||||
lua_pop(L, 2);
|
|
||||||
goto default_resize;
|
|
||||||
}
|
|
||||||
lua_getfield(L, -1, "ScreenToWorld");
|
|
||||||
lua_pushvalue(L, -2);
|
|
||||||
lua_pushinteger(L, m_pGamePanel->GetSize().GetWidth() / 2);
|
|
||||||
lua_pushinteger(L, m_pGamePanel->GetSize().GetHeight() / 2);
|
|
||||||
lua_call(L, 3, 2);
|
|
||||||
fX = lua_tonumber(L, -2) - 1.0;
|
|
||||||
fY = lua_tonumber(L, -1) - 1.0;
|
|
||||||
lua_pop(L, 2);
|
|
||||||
|
|
||||||
// Change window center
|
|
||||||
Layout();
|
|
||||||
|
|
||||||
// Move window center to same world co-ordinates
|
|
||||||
THMap::worldToScreen(fX, fY);
|
|
||||||
lua_getfield(L, -1, "scrollMapTo");
|
|
||||||
lua_insert(L, -2);
|
|
||||||
lua_pushnumber(L, fX);
|
|
||||||
lua_pushnumber(L, fY);
|
|
||||||
lua_call(L, 3, 0);
|
|
||||||
lua_pop(L, 1);
|
|
||||||
return;
|
|
||||||
default_resize:
|
|
||||||
evt.Skip();
|
|
||||||
}
|
|
||||||
|
|
||||||
int ScrollableGamePanel::_l_extra_init(lua_State *L)
|
|
||||||
{
|
|
||||||
ScrollableGamePanel* pThis = reinterpret_cast<ScrollableGamePanel*>(
|
|
||||||
lua_touserdata(L, 1));
|
|
||||||
|
|
||||||
// Perform the original extra initialisation
|
|
||||||
if(pThis->m_fnExtraInit != NULL)
|
|
||||||
{
|
|
||||||
if(lua_cpcall(L, pThis->m_fnExtraInit, pThis->m_pExtraInitArg) != 0)
|
|
||||||
lua_pop(L, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Hook around the MapEditorInitWithLuaApp function
|
|
||||||
lua_getglobal(L, "MapEditorInitWithLuaApp");
|
|
||||||
lua_pushvalue(L, 1);
|
|
||||||
lua_pushcclosure(L, _l_init_with_app, 2);
|
|
||||||
lua_setglobal(L, "MapEditorInitWithLuaApp");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ScrollableGamePanel::_l_init_with_app(lua_State *L)
|
|
||||||
{
|
|
||||||
// Call the original MapEditorInitWithLuaApp function
|
|
||||||
lua_pushvalue(L, lua_upvalueindex(1));
|
|
||||||
if(lua_type(L, -1) == LUA_TNIL)
|
|
||||||
lua_pop(L, 1);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
lua_insert(L, 1);
|
|
||||||
lua_call(L, lua_gettop(L) - 1, LUA_MULTRET);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wrap our _l_on_ui_scroll_map function around GameUI:scrollMap()
|
|
||||||
// 1st upvalue: original GameUI:scrollMap() function
|
|
||||||
// 2nd upvalue: light userdata this
|
|
||||||
// This has to be done with the Lua App initialisation as we need for
|
|
||||||
// dofile() to be the custom dofile() used by CorsixTH, rather than the
|
|
||||||
// default one present at Lua initialisation time.
|
|
||||||
luaT_execute(L, "dofile [[game_ui]]");
|
|
||||||
lua_getglobal(L, "GameUI");
|
|
||||||
lua_getfield(L, -1, "scrollMap");
|
|
||||||
lua_pushvalue(L, lua_upvalueindex(2));
|
|
||||||
lua_pushcclosure(L, _l_on_ui_scroll_map, 2);
|
|
||||||
lua_setfield(L, -2, "scrollMap");
|
|
||||||
|
|
||||||
return lua_gettop(L);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ScrollableGamePanel::_l_on_ui_scroll_map(lua_State *L)
|
|
||||||
{
|
|
||||||
ScrollableGamePanel *pThis = reinterpret_cast<ScrollableGamePanel*>(
|
|
||||||
lua_touserdata(L, lua_upvalueindex(2)));
|
|
||||||
|
|
||||||
// Make a copy of the "self" parameter at the bottom of the stack
|
|
||||||
lua_pushvalue(L, 1);
|
|
||||||
lua_insert(L, 1);
|
|
||||||
|
|
||||||
// Call original GameUI:scrollMap() function
|
|
||||||
lua_pushvalue(L, lua_upvalueindex(1));
|
|
||||||
lua_insert(L, 2);
|
|
||||||
lua_call(L, lua_gettop(L) - 2, LUA_MULTRET);
|
|
||||||
|
|
||||||
if(pThis->m_bShouldRespondToScroll)
|
|
||||||
{
|
|
||||||
int iPanelW, iPanelH;
|
|
||||||
pThis->m_pGamePanel->GetSize(&iPanelW, &iPanelH);
|
|
||||||
|
|
||||||
// Get world co-ordinates of window center
|
|
||||||
lua_checkstack(L, 4);
|
|
||||||
lua_getfield(L, 1, "ScreenToWorld");
|
|
||||||
lua_pushvalue(L, 1);
|
|
||||||
lua_pushinteger(L, iPanelW / 2);
|
|
||||||
lua_pushinteger(L, iPanelH / 2);
|
|
||||||
lua_call(L, 3, 2);
|
|
||||||
lua_Number fX = lua_tonumber(L, -2) - 1.0;
|
|
||||||
lua_Number fY = lua_tonumber(L, -1) - 1.0;
|
|
||||||
lua_pop(L, 2);
|
|
||||||
|
|
||||||
// Get map extents
|
|
||||||
THMap* pMap = pThis->m_pGamePanel->getMap();
|
|
||||||
int iMapH = pMap->getHeight();
|
|
||||||
int iTemp = pMap->getWidth();
|
|
||||||
pMap->worldToScreen(iTemp, iMapH);
|
|
||||||
int iMapW = pMap->getWidth();
|
|
||||||
iTemp = 0;
|
|
||||||
pMap->worldToScreen(iMapW, iTemp);
|
|
||||||
|
|
||||||
// Get screen co-ordinates of window center
|
|
||||||
// We could get these directly from the GameUI, but we'd be delving into
|
|
||||||
// its member variables, and also perhaps not properly accounting for zoom.
|
|
||||||
pMap->worldToScreen(fX, fY);
|
|
||||||
int iX = (int)fX;
|
|
||||||
int iY = (int)fY;
|
|
||||||
|
|
||||||
// Update scrollbars
|
|
||||||
pThis->m_pMapScrollX->SetScrollbar(iX + iMapW, iPanelW, iMapW * 2 + iPanelW, iPanelW);
|
|
||||||
pThis->m_pMapScrollY->SetScrollbar(iY , iPanelH, iMapH + iPanelH, iPanelH);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return results from original call
|
|
||||||
return lua_gettop(L) - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScrollableGamePanel::_onScroll(wxScrollEvent& evt)
|
|
||||||
{
|
|
||||||
_positionMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScrollableGamePanel::_onTimer(wxTimerEvent& evt)
|
|
||||||
{
|
|
||||||
const int KEY_SENSITIVITY = 20;
|
|
||||||
int x = m_pMapScrollX->GetThumbPosition();
|
|
||||||
int y = m_pMapScrollY->GetThumbPosition();
|
|
||||||
bool bChanges = false;
|
|
||||||
|
|
||||||
if(wxGetKeyState(WXK_LEFT))
|
|
||||||
{
|
|
||||||
m_pMapScrollX->SetThumbPosition(std::max(0, x - KEY_SENSITIVITY));
|
|
||||||
bChanges = true;
|
|
||||||
}
|
|
||||||
if(wxGetKeyState(WXK_RIGHT))
|
|
||||||
{
|
|
||||||
m_pMapScrollX->SetThumbPosition(std::min(m_pMapScrollX->GetRange(), x + KEY_SENSITIVITY));
|
|
||||||
bChanges = true;
|
|
||||||
}
|
|
||||||
if(wxGetKeyState(WXK_UP))
|
|
||||||
{
|
|
||||||
m_pMapScrollY->SetThumbPosition(std::max(0, y - KEY_SENSITIVITY));
|
|
||||||
bChanges = true;
|
|
||||||
}
|
|
||||||
if(wxGetKeyState(WXK_DOWN))
|
|
||||||
{
|
|
||||||
m_pMapScrollY->SetThumbPosition(std::min(m_pMapScrollY->GetRange(), y + KEY_SENSITIVITY));
|
|
||||||
bChanges = true;
|
|
||||||
}
|
|
||||||
if (bChanges)
|
|
||||||
{
|
|
||||||
_positionMap();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ScrollableGamePanel::_positionMap()
|
|
||||||
{
|
|
||||||
lua_State *L = getLua();
|
|
||||||
if(!L)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lua_getglobal(L, "TheApp");
|
|
||||||
if(lua_isnil(L, -1))
|
|
||||||
{
|
|
||||||
lua_pop(L, 1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lua_getfield(L, -1, "ui");
|
|
||||||
if(lua_isnil(L, -1))
|
|
||||||
{
|
|
||||||
lua_pop(L, 2);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
lua_replace(L, -2);
|
|
||||||
lua_getfield(L, -1, "scrollMapTo");
|
|
||||||
lua_insert(L, -2);
|
|
||||||
lua_pushinteger(L, m_pMapScrollX->GetThumbPosition() - m_pMapScrollX->GetRange() / 2 + m_pMapScrollX->GetThumbSize() / 2);
|
|
||||||
lua_pushinteger(L, m_pMapScrollY->GetThumbPosition());
|
|
||||||
m_bShouldRespondToScroll = false;
|
|
||||||
lua_call(L, 3, 1);
|
|
||||||
m_bShouldRespondToScroll = true;
|
|
||||||
m_pGamePanel->Refresh(false);
|
|
||||||
}
|
|
@@ -1,79 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2010 Peter "Corsix" Cawley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
// For compilers that support precompilation, includes "wx/wx.h".
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
#pragma hdrstop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// for all others, include the necessary headers (this file is usually all you
|
|
||||||
// need because it includes almost all "standard" wxWidgets headers)
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/wx.h"
|
|
||||||
#endif
|
|
||||||
// ----------------------------
|
|
||||||
#include "embedded_game.h"
|
|
||||||
|
|
||||||
class ScrollableGamePanel : public wxPanel, public IEmbeddedGamePanel
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ScrollableGamePanel(wxWindow *pParent);
|
|
||||||
~ScrollableGamePanel();
|
|
||||||
|
|
||||||
void setExtraLuaInitFunction(lua_CFunction fn, void* arg);
|
|
||||||
void setLogWindow(frmLog *pLogWindow);
|
|
||||||
bool loadLua();
|
|
||||||
|
|
||||||
lua_State* getLua();
|
|
||||||
THMap* getMap();
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
ID_X_SCROLL = wxID_HIGHEST + 1,
|
|
||||||
ID_Y_SCROLL
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
EmbeddedGamePanel* m_pGamePanel;
|
|
||||||
wxScrollBar* m_pMapScrollX;
|
|
||||||
wxScrollBar* m_pMapScrollY;
|
|
||||||
lua_CFunction m_fnExtraInit;
|
|
||||||
void* m_pExtraInitArg;
|
|
||||||
bool m_bShouldRespondToScroll;
|
|
||||||
wxTimer* m_pTimer;
|
|
||||||
|
|
||||||
void _onResize(wxSizeEvent& evt);
|
|
||||||
void _onScroll(wxScrollEvent& evt);
|
|
||||||
void _onTimer(wxTimerEvent& evt);
|
|
||||||
|
|
||||||
static int _l_extra_init(lua_State *L);
|
|
||||||
static int _l_init_with_app(lua_State *L);
|
|
||||||
static int _l_on_ui_scroll_map(lua_State *L);
|
|
||||||
|
|
||||||
DECLARE_EVENT_TABLE();
|
|
||||||
|
|
||||||
private:
|
|
||||||
void _positionMap();
|
|
||||||
};
|
|
@@ -1,391 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2010 Peter "Corsix" Cawley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
#include "th_map_wrapper.h"
|
|
||||||
#include <stack>
|
|
||||||
#include <utility>
|
|
||||||
|
|
||||||
void THMapWrapper::autoSetHelipad(THMap *pMap)
|
|
||||||
{
|
|
||||||
// Search the map for a "H" pattern made up from two ground tiles.
|
|
||||||
// xxxxx
|
|
||||||
// xHxHx
|
|
||||||
// xHHHx
|
|
||||||
// xHxHx
|
|
||||||
// xxxxx
|
|
||||||
for(int iX = 2; iX < pMap->getWidth() - 2; ++iX)
|
|
||||||
{
|
|
||||||
for(int iY = 2; iY < pMap->getHeight() - 2; ++iY)
|
|
||||||
{
|
|
||||||
THMapNode *pNode = pMap->getNodeUnchecked(iX, iY);
|
|
||||||
if((pNode->iBlock[1] | pNode->iBlock[2]) & 0xFF)
|
|
||||||
continue;
|
|
||||||
uint16_t iFloor1 = pNode->iBlock[0] & 0xFF;
|
|
||||||
uint16_t iFloor2 = pNode[-2].iBlock[0] & 0xFF;
|
|
||||||
if(iFloor1 == iFloor2)
|
|
||||||
continue;
|
|
||||||
for(int iDX = -2; iDX <= 2; ++iDX)
|
|
||||||
{
|
|
||||||
for(int iDY = -2; iDY <= 2; ++iDY)
|
|
||||||
{
|
|
||||||
pNode = pMap->getNodeUnchecked(iX + iDX, iY + iDY);
|
|
||||||
if(-1 <= iDX && iDX <= 1 && -1 <= iDY && iDY <= 1)
|
|
||||||
{
|
|
||||||
if((iDX | iDY) == 0)
|
|
||||||
continue;
|
|
||||||
if((pNode->iBlock[1] | pNode->iBlock[2]) & 0xFF)
|
|
||||||
goto next_xy;
|
|
||||||
if((pNode->iBlock[0] & 0xFF) !=
|
|
||||||
(iDX == 0 ? iFloor2 : iFloor1))
|
|
||||||
{
|
|
||||||
goto next_xy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if((pNode->iBlock[0] & 0xFF) != iFloor2)
|
|
||||||
goto next_xy;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pMap->setPlayerHeliportTile(0, iX, iY);
|
|
||||||
return;
|
|
||||||
next_xy:;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void THMapWrapper::wrap(lua_State *L)
|
|
||||||
{
|
|
||||||
luaT_execute(L, "require[[TH]].map.setCell = ...", _l_set_cell);
|
|
||||||
}
|
|
||||||
|
|
||||||
int THMapWrapper::_l_set_cell(lua_State *L)
|
|
||||||
{
|
|
||||||
// Perform same argument handling as normal setCell function
|
|
||||||
THMap* pMap = reinterpret_cast<THMap*>(lua_touserdata(L, 1));
|
|
||||||
int iX = luaL_checkint(L, 2) - 1; // Lua arrays start at 1 - pretend
|
|
||||||
int iY = luaL_checkint(L, 3) - 1; // the map does too.
|
|
||||||
THMapNode* pNode = pMap->getNode(iX, iY);
|
|
||||||
if(pNode == NULL)
|
|
||||||
return luaL_argerror(L, 2, "Map co-ordinates out of bounds");
|
|
||||||
uint16_t iNewBlocks[4] = {
|
|
||||||
pNode->iBlock[0],
|
|
||||||
pNode->iBlock[1],
|
|
||||||
pNode->iBlock[2],
|
|
||||||
pNode->iBlock[3]
|
|
||||||
};
|
|
||||||
if(lua_gettop(L) >= 7)
|
|
||||||
{
|
|
||||||
iNewBlocks[0] = (uint16_t)luaL_checkint(L, 4);
|
|
||||||
iNewBlocks[1] = (uint16_t)luaL_checkint(L, 5);
|
|
||||||
iNewBlocks[2] = (uint16_t)luaL_checkint(L, 6);
|
|
||||||
iNewBlocks[3] = (uint16_t)luaL_checkint(L, 7);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int iLayer = luaL_checkint(L, 4) - 1;
|
|
||||||
if(iLayer < 0 || iLayer >= 4)
|
|
||||||
return luaL_argerror(L, 4, "Layer index is out of bounds (1-4)");
|
|
||||||
int iBlock = luaL_checkint(L, 5);
|
|
||||||
iNewBlocks[iLayer] = (uint16_t)iBlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dispatch the call
|
|
||||||
_do_set_cell(L, pMap, iX, iY, iNewBlocks);
|
|
||||||
|
|
||||||
lua_settop(L, 1);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool THMapWrapper::_isDoorframe(int iTile)
|
|
||||||
{
|
|
||||||
return ms_iDoorframeWallFirst <= iTile && iTile <= ms_iDoorframeWallLast;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool THMapWrapper::_isPassable(int iTile)
|
|
||||||
{
|
|
||||||
iTile &= 0xFF;
|
|
||||||
if(iTile <= 5)
|
|
||||||
return iTile >= 4;
|
|
||||||
else if(iTile <= 0x17)
|
|
||||||
return iTile >= 0xF;
|
|
||||||
else if(iTile <= 0x3A)
|
|
||||||
return iTile >= 0x29;
|
|
||||||
else
|
|
||||||
return iTile == 0x42 || iTile == 0x46 || iTile == 0x4C;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool THMapWrapper::_isWall(int iTile)
|
|
||||||
{
|
|
||||||
iTile &= 0xFF;
|
|
||||||
if(82 <= iTile && iTile <= 155)
|
|
||||||
return true;
|
|
||||||
// NB: 157 through 160 are walls, but not the purposes of defining
|
|
||||||
// hospital tiles.
|
|
||||||
if(161 <= iTile && iTile <= 164)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool THMapWrapper::_isCertainlyHospital(THMap* pMap, int iX, int iY)
|
|
||||||
{
|
|
||||||
THMapNode *pNode = pMap->getNode(iX, iY);
|
|
||||||
if(pNode && (pNode->iFlags & THMN_Passable))
|
|
||||||
{
|
|
||||||
if(_isWall(pNode->iBlock[1]) || _isWall(pNode->iBlock[2]))
|
|
||||||
return true;
|
|
||||||
THMapNode *pNeighbour = pMap->getNode(iX, iY + 1);
|
|
||||||
if(pNeighbour && _isWall(pNeighbour->iBlock[1]))
|
|
||||||
return true;
|
|
||||||
pNeighbour = pMap->getNode(iX + 1, iY);
|
|
||||||
if(pNeighbour && _isWall(pNeighbour->iBlock[2]))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void THMapWrapper::_do_set_cell(lua_State *L, THMap* pMap, int iX, int iY, uint16_t iNewBlocks[4])
|
|
||||||
{
|
|
||||||
THMapNode *pNode = pMap->getNodeUnchecked(iX, iY);
|
|
||||||
|
|
||||||
bool bShouldCheckHospitality = false;
|
|
||||||
bool bWasCertainlyHospital = _isCertainlyHospital(pMap, iX, iY);
|
|
||||||
|
|
||||||
// Check for wall blocks which should have sliding doors
|
|
||||||
bool bShouldCheckNeighbourDoors = false;
|
|
||||||
bool bShouldCheckOwnDoor = false;
|
|
||||||
for(int iDir = 0; iDir <= 1; ++iDir)
|
|
||||||
{
|
|
||||||
uint16_t iOld = pNode->iBlock[1 + iDir] & 0xFF;
|
|
||||||
uint16_t iNew = iNewBlocks[1 + iDir] & 0xFF;
|
|
||||||
if(iOld == iNew)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
bShouldCheckHospitality = true;
|
|
||||||
if(_isDoorframe(iOld) || _isDoorframe(iNew))
|
|
||||||
bShouldCheckNeighbourDoors = true;
|
|
||||||
if((iOld == 0) != (iNew == 0))
|
|
||||||
bShouldCheckOwnDoor = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t iOldFlags = pNode->iFlags;
|
|
||||||
if(_isPassable(iNewBlocks[0]))
|
|
||||||
pNode->iFlags |= THMN_Passable;
|
|
||||||
else
|
|
||||||
pNode->iFlags &=~ THMN_Passable;
|
|
||||||
if(pNode->iFlags != iOldFlags)
|
|
||||||
bShouldCheckHospitality = true;
|
|
||||||
|
|
||||||
pNode->iBlock[0] = iNewBlocks[0];
|
|
||||||
pNode->iBlock[1] = iNewBlocks[1];
|
|
||||||
pNode->iBlock[2] = iNewBlocks[2];
|
|
||||||
pNode->iBlock[3] = iNewBlocks[3];
|
|
||||||
|
|
||||||
if(bShouldCheckOwnDoor)
|
|
||||||
{
|
|
||||||
_check_door(L, pMap, iX, iY, 1, 0) ||
|
|
||||||
_check_door(L, pMap, iX, iY, 0, 1);
|
|
||||||
}
|
|
||||||
if(bShouldCheckNeighbourDoors)
|
|
||||||
{
|
|
||||||
_check_door(L, pMap, iX - 1, iY , 1, 0);
|
|
||||||
_check_door(L, pMap, iX , iY - 1, 0, 1);
|
|
||||||
_check_door(L, pMap, iX + 1, iY , 1, 0);
|
|
||||||
_check_door(L, pMap, iX , iY + 1, 0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::stack<std::pair<int, int> > stkToCheckHospitality;
|
|
||||||
if(bWasCertainlyHospital && !_isCertainlyHospital(pMap, iX, iY))
|
|
||||||
{
|
|
||||||
std::stack<std::pair<int, int> > stkToRemoveHospitality;
|
|
||||||
stkToRemoveHospitality.push(std::make_pair(iX, iY));
|
|
||||||
while(!stkToRemoveHospitality.empty())
|
|
||||||
{
|
|
||||||
int iX = stkToRemoveHospitality.top().first;
|
|
||||||
int iY = stkToRemoveHospitality.top().second;
|
|
||||||
stkToRemoveHospitality.pop();
|
|
||||||
THMapNode *pNode = pMap->getNode(iX, iY);
|
|
||||||
if(pNode && (pNode->iFlags & THMN_Hospital) != 0
|
|
||||||
&& !_isCertainlyHospital(pMap, iX, iY))
|
|
||||||
{
|
|
||||||
stkToCheckHospitality.push(std::make_pair(iX, iY));
|
|
||||||
pNode->iFlags &=~ THMN_Hospital;
|
|
||||||
for(int iDir = 0; iDir <= 1; ++iDir)
|
|
||||||
{
|
|
||||||
for(int iDelta = -1; iDelta <= 1; iDelta += 2)
|
|
||||||
{
|
|
||||||
stkToRemoveHospitality.push(std::make_pair(
|
|
||||||
iX + iDelta * iDir, iY + iDelta * (1 - iDir)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(bShouldCheckHospitality)
|
|
||||||
{
|
|
||||||
stkToCheckHospitality.push(std::make_pair(iX, iY));
|
|
||||||
stkToCheckHospitality.push(std::make_pair(iX - 1, iY ));
|
|
||||||
stkToCheckHospitality.push(std::make_pair(iX , iY - 1));
|
|
||||||
}
|
|
||||||
if(!stkToCheckHospitality.empty())
|
|
||||||
pMap->updatePathfinding();
|
|
||||||
while(!stkToCheckHospitality.empty())
|
|
||||||
{
|
|
||||||
int iX = stkToCheckHospitality.top().first;
|
|
||||||
int iY = stkToCheckHospitality.top().second;
|
|
||||||
stkToCheckHospitality.pop();
|
|
||||||
THMapNode *pNode = pMap->getNode(iX, iY);
|
|
||||||
if(!pNode)
|
|
||||||
continue;
|
|
||||||
bool bShouldBeHospital = false;
|
|
||||||
if(pNode->iFlags & THMN_Passable)
|
|
||||||
{
|
|
||||||
bShouldBeHospital = _isCertainlyHospital(pMap, iX, iY);
|
|
||||||
int iNumHospitalNeighbours = 0;
|
|
||||||
#define CHECK(dir_flag, dx, dy) \
|
|
||||||
if(pNode->iFlags & dir_flag) \
|
|
||||||
{ \
|
|
||||||
iNumHospitalNeighbours += (pMap->getNode(iX + dx, iY + dy) \
|
|
||||||
->iFlags & THMN_Hospital) >> THMN_Hospital_Shift; \
|
|
||||||
}
|
|
||||||
CHECK(THMN_CanTravelN, 0, -1);
|
|
||||||
CHECK(THMN_CanTravelE, 1, 0);
|
|
||||||
CHECK(THMN_CanTravelS, 0, 1);
|
|
||||||
CHECK(THMN_CanTravelW, -1, 0);
|
|
||||||
#undef CHECK
|
|
||||||
if(iNumHospitalNeighbours >= 2)
|
|
||||||
bShouldBeHospital = true;
|
|
||||||
}
|
|
||||||
if(bShouldBeHospital != ((pNode->iFlags & THMN_Hospital) != 0))
|
|
||||||
{
|
|
||||||
if(bShouldBeHospital)
|
|
||||||
{
|
|
||||||
pNode->iFlags |= THMN_Hospital;
|
|
||||||
_check_door_unbuildability(pMap, iX, iY);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
pNode->iFlags &=~ (THMN_Hospital | THMN_Buildable);
|
|
||||||
for(int iDir = 0; iDir <= 1; ++iDir)
|
|
||||||
{
|
|
||||||
for(int iDelta = -1; iDelta <= 1; iDelta += 2)
|
|
||||||
{
|
|
||||||
stkToCheckHospitality.push(std::make_pair(
|
|
||||||
iX + iDelta * iDir, iY + iDelta * (1 - iDir)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void THMapWrapper::_check_door_unbuildability(THMap* pMap, int iX, int iY)
|
|
||||||
{
|
|
||||||
THMapNode *pNode = pMap->getNode(iX, iY);
|
|
||||||
if(!pNode)
|
|
||||||
return;
|
|
||||||
bool bBuildable = (pNode->iFlags & THMN_Hospital) != 0;
|
|
||||||
for(int iDX = -1; iDX <= 1; ++iDX)
|
|
||||||
{
|
|
||||||
for(int iDY = -1; iDY <= 1; ++iDY)
|
|
||||||
{
|
|
||||||
THMapNode *pNode = pMap->getNode(iX + iDX, iY + iDY);
|
|
||||||
if(!pNode || (pNode->iFlags >> 24) != THOB_EntranceRightDoor)
|
|
||||||
continue;
|
|
||||||
bool bIsNorthFacing = (pNode[-1].iFlags >> 24) == THOB_EntranceLeftDoor;
|
|
||||||
if(bIsNorthFacing)
|
|
||||||
{
|
|
||||||
if(iDY != -1)
|
|
||||||
bBuildable = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(iDX != -1)
|
|
||||||
bBuildable = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(bBuildable)
|
|
||||||
pNode->iFlags |= THMN_Buildable;
|
|
||||||
else
|
|
||||||
pNode->iFlags &=~ THMN_Buildable;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool THMapWrapper::_check_door(lua_State *L, THMap* pMap, int iX, int iY, int iDX, int iDY)
|
|
||||||
{
|
|
||||||
bool bShouldHaveDoor = false;
|
|
||||||
THMapNode *pNode = pMap->getNode(iX, iY);
|
|
||||||
if(pNode && !(pNode->iBlock[1] & 0xFF) && !(pNode->iBlock[2] & 0xFF))
|
|
||||||
{
|
|
||||||
THMapNode *pFarNode = pMap->getNode(iX - iDX, iY - iDY);
|
|
||||||
THMapNode *pNearNode = pMap->getNode(iX + iDX, iY + iDY);
|
|
||||||
if(pFarNode && pNearNode)
|
|
||||||
{
|
|
||||||
int iFarBlock = pFarNode->iBlock[1 + iDY] & 0xFF;
|
|
||||||
int iNearBlock = pNearNode->iBlock[1 + iDY] & 0xFF;
|
|
||||||
if(iFarBlock == ms_iDoorframeFarExternal + iDY
|
|
||||||
|| iFarBlock == ms_iDoorframeFarInternal + iDY)
|
|
||||||
{
|
|
||||||
if(iNearBlock == ms_iDoorframeNearExternal + iDY
|
|
||||||
|| iNearBlock == ms_iDoorframeNearInternal + iDY)
|
|
||||||
{
|
|
||||||
bShouldHaveDoor = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
THObjectType eNodeThob = (THObjectType)(pNode->iFlags >> 24);
|
|
||||||
bool bGotDoor = eNodeThob == THOB_EntranceLeftDoor ||
|
|
||||||
eNodeThob == THOB_EntranceRightDoor;
|
|
||||||
if(bGotDoor == bShouldHaveDoor)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if(bShouldHaveDoor)
|
|
||||||
{
|
|
||||||
for(int i = 1; i >= 0; --i)
|
|
||||||
{
|
|
||||||
luaT_execute(L, "TheApp.world:newObject(...)",
|
|
||||||
i == 1 ? "entrance_left_door" : "entrance_right_door",
|
|
||||||
iX + 1 - i * iDX,
|
|
||||||
iY + 1 - i * iDY,
|
|
||||||
iDX == 1 ? "north" : "west");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
luaT_execute(L,
|
|
||||||
"local world = TheApp.world\n"
|
|
||||||
"local door = world:getObject(...)\n"
|
|
||||||
"if door then world:destroyEntity(door)\n"
|
|
||||||
"if door.slave then world:destroyEntity(door.slave) end end\n",
|
|
||||||
iX + 1,
|
|
||||||
iY + 1);
|
|
||||||
}
|
|
||||||
for(int iDX = -1; iDX <= 1; ++iDX)
|
|
||||||
{
|
|
||||||
for(int iDY = -1; iDY <= 1; ++iDY)
|
|
||||||
{
|
|
||||||
_check_door_unbuildability(pMap, iX + iDX, iY + iDY);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bShouldHaveDoor;
|
|
||||||
}
|
|
@@ -1,70 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2010 Peter "Corsix" Cawley
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
|
||||||
this software and associated documentation files (the "Software"), to deal in
|
|
||||||
the Software without restriction, including without limitation the rights to
|
|
||||||
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
|
|
||||||
of the Software, and to permit persons to whom the Software is furnished to do
|
|
||||||
so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
|
||||||
copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
||||||
SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
// For compilers that support precompilation, includes "wx/wx.h".
|
|
||||||
#include "wx/wxprec.h"
|
|
||||||
|
|
||||||
#ifdef __BORLANDC__
|
|
||||||
#pragma hdrstop
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// for all others, include the necessary headers (this file is usually all you
|
|
||||||
// need because it includes almost all "standard" wxWidgets headers)
|
|
||||||
#ifndef WX_PRECOMP
|
|
||||||
#include "wx/wx.h"
|
|
||||||
#endif
|
|
||||||
// ----------------------------
|
|
||||||
#include "game.h"
|
|
||||||
|
|
||||||
class THMapWrapper
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
//! Wrap around the Map class of a Lua state
|
|
||||||
/*!
|
|
||||||
This should be called at the initialisation time of a Lua state (after
|
|
||||||
luaopen_th has been registered to package.preload, but before any map
|
|
||||||
instances have been created). After calling, all map instances created
|
|
||||||
by the state will have this wrapper around them.
|
|
||||||
*/
|
|
||||||
static void wrap(lua_State *L);
|
|
||||||
|
|
||||||
static void autoSetHelipad(THMap *pMap);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
static int _l_set_cell(lua_State *L);
|
|
||||||
static void _do_set_cell(lua_State *L, THMap* pMap, int iX, int iY, uint16_t iNewBlocks[4]);
|
|
||||||
static bool _check_door(lua_State *L, THMap* pMap, int iX, int iY, int iDX, int iDY);
|
|
||||||
static void _check_door_unbuildability(THMap* pMap, int iX, int iY);
|
|
||||||
|
|
||||||
static const int ms_iDoorframeWallFirst = 157;
|
|
||||||
static const int ms_iDoorframeNearExternal = 157;
|
|
||||||
static const int ms_iDoorframeFarExternal = 159;
|
|
||||||
static const int ms_iDoorframeNearInternal = 161;
|
|
||||||
static const int ms_iDoorframeFarInternal = 163;
|
|
||||||
static const int ms_iDoorframeWallLast = 164;
|
|
||||||
|
|
||||||
static bool _isDoorframe(int iTile);
|
|
||||||
static bool _isPassable(int iTile);
|
|
||||||
static bool _isWall(int iTile);
|
|
||||||
static bool _isCertainlyHospital(THMap* pMap, int iX, int iY);
|
|
||||||
};
|
|