Skip to content

Commit

Permalink
Add ingame map editor
Browse files Browse the repository at this point in the history
The ingame map editor allows us to directly create and edit layouts and
prefabs in the game.

Closes #199.
  • Loading branch information
rm-code committed Nov 21, 2017
1 parent 9ff8e66 commit 6bb9923
Show file tree
Hide file tree
Showing 19 changed files with 1,851 additions and 5 deletions.
8 changes: 7 additions & 1 deletion main.lua
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,13 @@ function love.load( args )
gameover = require( 'src.ui.screens.GameOverScreen' ),
loadgame = require( 'src.ui.screens.SavegameScreen' ),
confirm = require( 'src.ui.screens.ConfirmationModal' ),
inputdialog = require( 'src.ui.screens.InputDialog' )
inputdialog = require( 'src.ui.screens.InputDialog' ),
maptest = require( 'src.ui.screens.MapTest' ),
mapeditor = require( 'src.ui.screens.MapEditor' ),
mapeditormenu = require( 'src.ui.screens.MapEditorMenu' ),
prefabeditor = require( 'src.ui.screens.PrefabEditor' ),
prefabeditormenu = require( 'src.ui.screens.PrefabEditorMenu' ),
editorloading = require( 'src.ui.mapeditor.EditorLoadingScreen' )
}

ScreenManager.init( screens, 'bootloading' )
Expand Down
17 changes: 17 additions & 0 deletions res/text/en_EN/ui_text.lua
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ locale.strings = {
['ui_main_menu_new_game'] = "New",
['ui_main_menu_load_game'] = "Load",
['ui_main_menu_options'] = "Options",
['ui_main_menu_mapeditor'] = "Map Editor",
['ui_main_menu_changelog'] = "Changes",
['ui_main_menu_exit'] = "Exit",

Expand All @@ -29,6 +30,22 @@ locale.strings = {
['ui_apply'] = "Apply",
['ui_unsaved_changes'] = "There are unsaved changes. Are you sure you want to quit?",

-- Map Editor
['ui_mapeditor_save'] = "Save Layout",
['ui_mapeditor_load'] = "Load Layout",
['ui_mapeditor_test'] = "Test Map",
['ui_mapeditor_switch'] = "Prefab Editor",
['ui_mapeditor_exit'] = "Exit",
['ui_mapeditor_enter_name'] = "Save layout as:",

-- Prefab Editor
['ui_prefabeditor_save'] = "Save Prefab",
['ui_prefabeditor_load'] = "Load Prefab",
['ui_prefabeditor_test'] = "Test Map",
['ui_prefabeditor_switch'] = "Layout Editor",
['ui_prefabeditor_exit'] = "Exit",
['ui_prefabeditor_enter_name'] = "Save prefab as:",

-- Texture packs
['ui_texturepack'] = "Texture Pack:",

Expand Down
11 changes: 11 additions & 0 deletions res/texturepacks/default/colors.lua
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,17 @@ return {
['ui_changelog_other'] = COLORS.DB16,
['ui_changelog_text'] = COLORS.DB25,

-- ==============================
-- MAP EDITOR
-- ==============================

['parcel_xs'] = COLORS.DB09,
['parcel_s'] = COLORS.DB08,
['parcel_m'] = COLORS.DB05,
['parcel_l'] = COLORS.DB27,
['parcel_xl'] = COLORS.DB25,
['ingame_editor_grid_lines'] = COLORS.DB14,

-- ==============================
-- SYSTEM
-- ==============================
Expand Down
8 changes: 8 additions & 0 deletions res/texturepacks/default/sprites.lua
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,14 @@ return {
['ui_scrollbar_cursor'] = 180,
['ui_scrollbar_element'] = 180,

-- ==============================
-- Prefab Editor
-- ==============================

['prefab_editor_cursor_draw'] = 101,
['prefab_editor_cursor_fill'] = 160,
['prefab_editor_cursor_erase'] = 89,

-- ==============================
-- Creatures
-- ==============================
Expand Down
6 changes: 3 additions & 3 deletions src/map/procedural/ProceduralMapGenerator.lua
Original file line number Diff line number Diff line change
Expand Up @@ -255,9 +255,9 @@ function ProceduralMapGenerator.new()
-- Public Methods
-- ------------------------------------------------

function self:init()
-- Select random layout.
local layout = layouts[love.math.random( #layouts )]
function self:init( nlayout )
-- Use specific layout or select a random one.
local layout = nlayout or layouts[love.math.random( #layouts )]

-- Generate empty parcel grid.
parcelGrid = ParcelGrid.new()
Expand Down
8 changes: 8 additions & 0 deletions src/map/tiles/TileFactory.lua
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,12 @@ function TileFactory.create( x, y, id )
return Tile.new( x, y, template )
end

---
-- Returns the table containing all the tile templates.
-- @treturn table A table containing all templates indexed by their id.
--
function TileFactory.getTemplates()
return tiles
end

return TileFactory
8 changes: 8 additions & 0 deletions src/map/worldobjects/WorldObjectFactory.lua
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,12 @@ function WorldObjectFactory.create( id )
return WorldObject.new( template )
end

---
-- Returns the table containing all the worldobject templates.
-- @treturn table A table containing all templates indexed by their id.
--
function WorldObjectFactory.getTemplates()
return worldobjects
end

return WorldObjectFactory
158 changes: 158 additions & 0 deletions src/ui/ProcMapPainter.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
---
-- This module takes care of drawing the game's map tiles.
-- It uses a spritebatch to optimise the drawing operation since the map
-- remains static and only needs to be updated when the state of the world
-- changes.
-- Only tiles which are marked as dirty will be updated by the MapPainter.
--
-- @module MapPainter
--

-- ------------------------------------------------
-- Required Modules
-- ------------------------------------------------

local Log = require( 'src.util.Log' )
local TexturePacks = require( 'src.ui.texturepacks.TexturePacks' )

-- ------------------------------------------------
-- Module
-- ------------------------------------------------

local MapPainter = {}

-- ------------------------------------------------
-- Constructor
-- ------------------------------------------------

---
-- Generates a new instance of the MapPainter class.
--
function MapPainter.new()
local self = {}

-- ------------------------------------------------
-- Private Attributes
-- ------------------------------------------------

local spritebatch
local tileset
local tw, th

local map

-- ------------------------------------------------
-- Private Methods
-- ------------------------------------------------

---
-- Adds an empty sprite for each tile in the map to the spritebatch, gives
-- each tile a unique identifier and sets it to dirty for the first update.
--
local function initSpritebatch()
map:iterate( function( tile, x, y )
local id = spritebatch:add( tileset:getSprite( 'tile_empty' ), x * tw, y * th )
tile:setSpriteID( id )
tile:setDirty( true )
end)
Log.debug( string.format('Initialised %d tiles.', spritebatch:getCount()), 'MapPainter' )
end

---
-- Selects a color which to use when a tile is drawn based on its contents.
-- @tparam Tile tile The tile to choose a color for.
-- @tparam Faction faction The faction to draw for.
-- @tparam Character character The faction's currently active character.
-- @treturn table A table containing RGBA values.
--
local function selectTileColor( tile )
if not tile:getInventory():isEmpty() then
return TexturePacks.getColor( 'items' )
end

if tile:hasWorldObject() then
return TexturePacks.getColor( tile:getWorldObject():getID() )
end

return TexturePacks.getColor( tile:getID() )
end

local function selectWorldObjectSprite( worldObject )
if worldObject:isOpenable() then
if worldObject:isPassable() then
return tileset:getSprite( worldObject:getID(), 'open' )
else
return tileset:getSprite( worldObject:getID(), 'closed' )
end
end
return tileset:getSprite( worldObject:getID() )
end

---
-- Selects a sprite from the tileset based on the tile and its contents.
-- @tparam Tile tile The tile to choose a sprite for.
-- @tparam Faction faction The faction to draw for.
-- @treturn Quad A quad pointing to a sprite on the tileset.
--
local function selectTileSprite( tile )
if not tile:getInventory():isEmpty() then
return tileset:getSprite( 'items' )
end

if tile:hasWorldObject() then
return selectWorldObjectSprite( tile:getWorldObject() )
end

return tileset:getSprite( tile:getID() )
end

---
-- Updates the spritebatch by going through every tile in the map. Only
-- tiles which have been marked as dirty will be sent to the spritebatch.
--
local function updateSpritebatch()
map:iterate( function( tile, x, y )
if tile:isDirty() then
spritebatch:setColor( selectTileColor( tile, nil, nil ))
spritebatch:set( tile:getSpriteID(), selectTileSprite( tile, nil ), x * tw, y * th )
tile:setDirty( false )
end
end)
end

-- ------------------------------------------------
-- Public Methods
-- ------------------------------------------------

---
-- Initialises the MapPainter.
-- @tparam Map nmap The map to draw.
--
function self:init( nmap )
map = nmap

tileset = TexturePacks.getTileset()
tw, th = tileset:getTileDimensions()
TexturePacks.setBackgroundColor()
spritebatch = love.graphics.newSpriteBatch( tileset:getSpritesheet(), 30000, 'dynamic' )
initSpritebatch()
end

---
-- Draws the game's world.
--
function self:draw()
love.graphics.draw( spritebatch, 0, 0 )
end

---
-- Updates the spritebatch for the game's world.
--
function self:update()
updateSpritebatch()
end

return self
end

return MapPainter
Loading

0 comments on commit 6bb9923

Please sign in to comment.