File size: 5,216 Bytes
b6a38d7 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 |
local work_modes = {
{ id = 1, name = "Make passable<right>(Alt-1)" },
{ id = 2, name = "Make impassable<right>(Alt-2)" },
{ id = 3, name = "Clear both<right>(Alt-3)" }
}
DefineClass.XPassabilityBrush = {
__parents = { "XEditorBrushTool" },
properties = {
persisted_setting = true, auto_select_all = true,
{ id = "WorkMode", name = "Work Mode", editor = "text_picker", default = 1, max_rows = 3, items = work_modes, },
{ id = "SquareBrush", name = "Square brush", editor = "bool", default = true, no_edit = not const.PassTileSize },
},
ToolSection = "Terrain",
ToolTitle = "Forced passability",
Description = {
"Force sets/clears passability."
},
ActionSortKey = "20",
ActionIcon = "CommonAssets/UI/Editor/Tools/Passability.tga",
ActionShortcut = "Alt-P",
cursor_tile_size = const.PassTileSize
}
function XPassabilityBrush:Init()
hr.TerrainDebugDraw = 1
DbgSetTerrainOverlay("passability")
end
function XPassabilityBrush:Done()
hr.TerrainDebugDraw = 0
end
-- Modify Size metadata depending on the SquareBrush property
if const.PassTileSize then
function XPassabilityBrush:GetPropertyMetadata(prop_id)
local sizex = const.PassTileSize
if prop_id == "Size" and self:IsCursorSquare() then
local help = string.format("1 tile = %sm", _InternalTranslate(FormatAsFloat(sizex, guim, 2)))
return {
id = "Size", name = "Size (tiles)", help = help, editor = "number", slider = true,
default = sizex, scale = sizex, min = sizex, max = 100 * sizex, step = sizex,
persisted_setting = true, auto_select_all = true,
}
end
return table.find_value(self.properties, "id", prop_id)
end
function XPassabilityBrush:GetProperties()
local props = {}
for _, prop in ipairs(self.properties) do
props[#props + 1] = self:GetPropertyMetadata(prop.id)
end
return props
end
function XPassabilityBrush:OnEditorSetProperty(prop_id, old_value, ged)
if prop_id == "SquareBrush" then
self:SetSize(self:GetSize())
end
end
end
function XPassabilityBrush:StartDraw(pt)
XEditorUndo:BeginOp{ passability = true, impassability = true, name = "Changed passability" }
end
function XPassabilityBrush:GetBrushBox()
local radius_in_tiles = self:GetCursorRadius() / self.cursor_tile_size
local normal_radius = (self.cursor_tile_size / 2) + self.cursor_tile_size * radius_in_tiles
local small_radius = normal_radius - self.cursor_tile_size
local cursor_pt = GetTerrainCursor()
local center = point(
DivRound(cursor_pt:x(), self.cursor_tile_size) * self.cursor_tile_size,
DivRound(cursor_pt:y(), self.cursor_tile_size) * self.cursor_tile_size
):SetTerrainZ()
local min = center - point(normal_radius, normal_radius)
local max = center + point(normal_radius, normal_radius)
local size_in_tiles = self:GetSize() / self.cursor_tile_size
-- For an odd-sized brush the radius is asymetrical and needs adjustment
if size_in_tiles > 1 and size_in_tiles % 2 == 0 then
local diff = cursor_pt - center
if diff:x() < 0 and diff:y() < 0 then
min = center - point(normal_radius, normal_radius)
max = center + point(small_radius, small_radius)
elseif diff:x() > 0 and diff:y() < 0 then
min = center - point(small_radius, normal_radius)
max = center + point(normal_radius, small_radius)
elseif diff:x() < 0 and diff:y() > 0 then
min = center - point(normal_radius, small_radius)
max = center + point(small_radius, normal_radius)
else
min = center - point(small_radius, small_radius)
max = center + point(normal_radius, normal_radius)
end
end
return box(min, max)
end
function XPassabilityBrush:Draw(last_pos, pt)
if self:GetSquareBrush() then
local mode = self:GetWorkMode()
local brush_box = self:GetBrushBox()
if mode == 1 then
editor.SetPassableBox(brush_box, true)
elseif mode == 2 then
editor.SetPassableBox(brush_box, false)
editor.SetImpassableBox(brush_box, true)
else
editor.SetPassableBox(brush_box, false)
editor.SetImpassableBox(brush_box, false)
end
return
end
local radius = self:GetSize() / 2
local mode = self:GetWorkMode()
if mode == 1 then
editor.SetPassableCircle(pt, radius, true)
elseif mode == 2 then
editor.SetPassableCircle(pt, radius, false)
editor.SetImpassableCircle(pt, radius, true)
else
editor.SetPassableCircle(pt, radius, false)
editor.SetImpassableCircle(pt, radius, false)
end
end
function XPassabilityBrush:EndDraw(pt1, pt2, invalid_box)
invalid_box = GrowBox(invalid_box, const.PassTileSize * 2)
XEditorUndo:EndOp(nil, invalid_box)
terrain.RebuildPassability(invalid_box)
Msg("EditorPassabilityChanged")
end
function XPassabilityBrush:IsCursorSquare()
return const.PassTileSize and self:GetSquareBrush()
end
function XPassabilityBrush:GetCursorExtraFlags()
return self:IsCursorSquare() and const.mfPassabilityFieldSnapped or 0
end
function XPassabilityBrush:OnShortcut(shortcut, ...)
if shortcut == "Alt-1" or shortcut == "Alt-2" or shortcut == "Alt-3" then
self:SetWorkMode(tonumber(shortcut:sub(-1)))
ObjModified(self)
return "break"
else
return XEditorBrushTool.OnShortcut(self, shortcut, ...)
end
end
function XPassabilityBrush:GetCursorRadius()
local radius = self:GetSize() / 2
return radius, radius
end
|