myspace / CommonLua /MapGen /BiomeZdit.lua
sirnii's picture
Upload 1816 files
b6a38d7 verified
if not Platform.editor or not Platform.developer then
return
end
local type_tile = const.TypeTileSize
local pct_mul = 100
----
function Biome:CalcTypeMixingPreview()
local preview = NewComputeGrid(256, 256, "U", 16)
self:GetTypeMixingGrid(preview)
self.TypeMixingPreview = preview
return preview
end
function Biome:GetFilteredPrefabsPreview()
return #(self:GetFilteredPrefabs() or empty_table)
end
function Biome:GetTypeMixingPreview()
return self.TypeMixingPreview or self:CalcTypeMixingPreview()
end
local function RecalcTypeMixingPreview(ged)
local parent = ged:GetParentOfKind("SelectedObject", "Biome")
if parent then
parent:CalcTypeMixingPreview()
end
end
function BiomePrefabTypeWeight:OnAfterEditorNew(parent, ged, is_paste)
RecalcTypeMixingPreview(ged)
end
function BiomePrefabTypeWeight:OnAfterEditorDelete(parent, ged)
RecalcTypeMixingPreview(ged)
end
function BiomePrefabTypeWeight:OnEditorSetProperty(prop_id, old_value, ged)
RecalcTypeMixingPreview(ged)
end
----
if FirstLoad then
g_BiomeFiller = false
end
BiomeFiller.dbg_paused = false
BiomeFiller.dbg_interrupt = false
BiomeFiller.dbg_placed_prefabs = false
BiomeFiller.dbg_prefab_types = false
BiomeFiller.dbg_visible_prefabs = false
BiomeFiller.dbg_placed_objects = false
BiomeFiller.dbg_placed_poi = false
BiomeFiller.dbg_obj_to_prefab_mark = false
BiomeFiller.dbg_grid_thread = false
BiomeFiller.dbg_inspect = false
BiomeFiller.dbg_filter_tags = false
BiomeFiller.dbg_filter_name = ""
BiomeFiller.dbg_view_mark = 0
function BiomeFiller:DbgInit()
g_BiomeFiller = self
for _, prop in ipairs(self:GetProperties()) do
if prop.category == "Results" then
self[prop.id] = nil
end
end
self.dbg_paused = nil
self.dbg_interrupt = nil
self.dbg_placed_prefabs = nil
self.dbg_prefab_types = nil
self.dbg_visible_prefabs = nil
self.dbg_placed_objects = nil
self.dbg_placed_poi = nil
self.dbg_obj_to_prefab_mark = nil
self.dbg_inspect = nil
self.dbg_filter_tags = nil
self.dbg_filter_name = nil
self.dbg_view_mark = nil
self:DbgClear()
ObjModified(self)
end
function BiomeFiller:ActionTogglePause()
self.dbg_paused = not self.dbg_paused
Msg(self)
end
function BiomeFiller:ActionInterrupt()
self.dbg_interrupt = true
self.dbg_paused = false
Msg(self)
end
local function DbgGetPalette(grid, name, prefab_list)
local palette, remap = {}, {}
local level_map = GridLevels(grid)
local count = 0
if name == "Types" then
local ptype_to_preset = PrefabTypeToPreset
local idx_to_ptype = GetPrefabTypeList()
local ptypes = {}
for ptype_idx in pairs(level_map) do
local ptype = idx_to_ptype[ptype_idx]
if ptype then
local val = ptypes[ptype]
if not val then
count = count + 1
val = count
ptypes[ptype] = val
local preset = ptype_to_preset[ptype]
local color = preset and preset.OverlayColor or RandColor(xxhash(ptype))
palette[val] = color
end
remap[ptype_idx] = val
end
end
else
local i = 1
local minv, maxv = max_int, 0
for level in pairs(level_map) do
if level ~= 0 then
local val = count % 255 + 1
remap[level] = val
minv = Min(minv, val)
maxv = Max(maxv, val)
count = count + 1
end
end
if count > 0 then
palette[minv] = RGB(128, 128, 128)
palette[maxv] = white
if count > 2 then
count = Min(255, count)
local max_value = 1024
local max_hue = 0
local min_hue = max_value * 2 / 3
for val = minv, maxv do
local hue = min_hue + (max_hue - min_hue) * (val - minv) / (maxv - minv)
palette[val] = HSB(hue, max_value, max_value, max_value)
end
end
end
end
return palette, remap
end
function BiomeFiller:DbgDone()
self.Overlay = nil
self.InspectMode = nil
self.InspectFilter = nil
self:DbgUpdateShow()
self:DbgClear()
GedObjectDeleted(self)
end
BiomeFiller.dbg_overlay_grid = false
function BiomeFiller:DbgClear()
DbgHideTerrainGrid(self.dbg_overlay_grid)
self.dbg_overlay_grid = nil
DbgClear()
editor.ClearSel()
end
function BiomeFiller:OnEditorSetProperty(prop_id, ...)
local prop = self:GetPropertyMetadata(prop_id)
if prop and prop.update_dbg then
self:DbgUpdateShow()
end
return GridOp.OnEditorSetProperty(self, prop_id, ...)
end
function BiomeFiller:GetGridPreview()
local modes = self:GetGridModes()
for key, value in pairs(self.PreviewSet) do
if value then
return modes[key]
end
end
end
BiomeFiller.dbg_palettes = false
function BiomeFiller:DbgUpdate()
self.dbg_palettes = false
self:DbgUpdateShow()
editor.ClearSel()
end
function BiomeFiller:DbgUpdatePalette(name)
name = name or self:DbgGetOverlay()
self.dbg_palettes = self.dbg_palettes or {}
local grid = self:GetGridModes()[name]
local info = self.dbg_palettes[name] or empty_table
local edges = self.OverlayEdges
local prev_grid, prev_edges = info[3], info[5] or false
if grid and (prev_grid ~= grid or prev_edges ~= edges) then
local palette, remap = DbgGetPalette(grid, name, self.PrefabList or empty_table)
local edge
if edges then
edge = GridDest(grid)
GridEdge(grid, edge)
GridNot(edge)
end
local g = GridDest(grid)
GridReplace(grid, g, remap)
if edges then
GridMulDiv(g, edge, 1)
end
info = { palette, remap, grid, g, edges }
self.dbg_palettes[name] = info
end
return table.unpack(info)
end
function BiomeFiller:DbgGetColor(mark)
local overlay = self:DbgGetOverlay() or "Marks"
local palette, remap = self:DbgUpdatePalette(overlay)
local pidx = remap[mark]
return pidx and palette[pidx]
end
function BiomeFiller:DbgGetOverlay()
for ov, value in pairs(self.Overlay) do
if value then
return ov
end
end
end
function BiomeFiller:DbgUpdateShow()
local new_overlay = self:DbgGetOverlay()
DeleteThread(self.dbg_grid_thread)
if not new_overlay then
DbgShowTerrainGrid(false)
else
self.dbg_grid_thread = CreateRealTimeThread(function()
WaitNextFrame(1)
local palette, remap, dgrid, g = self:DbgUpdatePalette(new_overlay)
self.dbg_overlay_grid = g
DbgShowTerrainGrid(g, palette)
end)
end
local new_inspect = false
for ins, value in pairs(self.InspectMode) do
if value then
new_inspect = ins
break
end
end
local filter_tags = false
for tag, value in pairs(self.InspectFilter) do
if value then
filter_tags = table.create_set(filter_tags, tag, true)
end
end
local filter_name = self.InspectPattern
local prefab_to_tags = {}
local function GetPrefabTags(prefab)
local tags = prefab_to_tags[prefab]
if tags == nil then
local poi_tags = prefab.poi_type and table.get(PrefabPoiToPreset, prefab.poi_type, "Tags")
local ptype_tags = prefab.type and table.get(PrefabTypeToPreset, prefab.type, "Tags")
local marker_tags = prefab.tags
tags = {}
table.append(tags, ptype_tags)
table.append(tags, marker_tags)
table.append(tags, poi_tags)
tags = table.keys(tags, true)
prefab_to_tags[prefab] = #tags > 0 and tags or false
end
return tags
end
local function PrefabTagsToStr(tags, sep)
return table.concat(tags, sep or ", ")
end
function DbgShowPrefab(pos, name, color, mark, rmin, rmax)
local prefab = name and PrefabMarkers[name]
local tags = prefab and GetPrefabTags(prefab) or empty_table
if filter_tags then
local found
for _, tag in ipairs(tags) do
if filter_tags[tag] then
found = true
break
end
end
if not found then
return
end
end
if name and filter_name ~= "" and not string.find(name, filter_name) then
return
end
if rmin then
DbgAddCircle(pos, rmin * type_tile, color, -1, guim)
if rmax then
DbgAddCircle(pos, rmax * type_tile, color, -1, guim)
end
end
DbgAddVector(pos, 50*guim, color)
if name then
if mark then
name = name .. " (" .. mark .. ")"
end
local poi_type = prefab and prefab.poi_type or ""
if poi_type ~= "" then
name = name .. " " .. poi_type
end
if #tags > 0 then
name = name .. " [" .. PrefabTagsToStr(tags) .. "]"
end
DbgAddText(name, ValidateZ(pos):AddZ(50*guim), color)
end
return true
end
if self.dbg_inspect ~= new_inspect
or self.dbg_filter_name ~= filter_name
or not table.equal_values(self.dbg_filter_tags, filter_tags) then
self.dbg_inspect = new_inspect
self.dbg_filter_tags = filter_tags
self.dbg_filter_name = filter_name
DbgClear()
DbgStopInspect()
if new_inspect == "Pos" then
DbgInspectThread = CreateMapRealTimeThread(function()
WaitNextFrame(1)
local shown = 0
for mark, info in ipairs(self.PrefabList or empty_table) do
local name, pos = table.unpack(info)
local color = self:DbgGetColor(mark)
if color and DbgShowPrefab(pos, name, color, mark) then
shown = shown + 1
end
end
print("Shown", shown, "prefabs")
end)
elseif new_inspect == "POI" then
DbgInspectThread = CreateMapRealTimeThread(function()
WaitNextFrame(1)
local poi_to_preset = PrefabPoiToPreset
local shown = 0
for mark, info in ipairs(self.PrefabList or empty_table) do
local name, pos = table.unpack(info)
local prefab = PrefabMarkers[name]
local poi_type = prefab and prefab.poi_type or ""
local preset = poi_type ~= "" and poi_to_preset[poi_type]
if preset and DbgShowPrefab(pos, name, preset.OverlayColor, mark, prefab.max_radius) then
shown = shown + 1
end
end
print("Shown", shown, "prefabs")
end)
elseif new_inspect == "Rollover" then
DbgInspectThread = CreateMapRealTimeThread(function()
local last_mark, last_prefab, last_mark, last_click = 0
while DbgInspectThread == CurrentThread() do
DbgClearColors()
local mark = 0
if self.dbg_obj_to_prefab_mark then
local solid, transparent = GetPreciseCursorObj()
local obj = GetTopmostParent(transparent or solid)
mark = obj and self.dbg_obj_to_prefab_mark[obj] or 0
if obj then
DbgSetColor(obj, white)
end
end
if mark == 0 and self.MarkGrid and self.PrefabList then
local pos = DbgGetInspectPos()
mark = GridGetMark(self.MarkGrid, pos) or 0
end
if mark ~= last_mark then
last_mark = mark
DbgClear()
local name, pos, color
if mark ~= 0 then
local info = self.PrefabList[mark] or empty_table
name, pos = table.unpack(info)
pos = pos:SetInvalidZ()
color = self:DbgGetColor(mark) or white
end
if name then
local prefab = PrefabMarkers[name]
DbgShowPrefab(pos, name, color, mark, prefab.min_radius, prefab.max_radius)
end
last_prefab = name
WaitNextFrame(1)
else
WaitNextFrame(10)
end
local tool = GetDialog("XSelectObjectsTool")
local terrain_pos = tool and tool.last_mouse_click
if not terrain_pos then
last_click = nil
elseif terrain_pos ~= last_click then
last_click = terrain_pos
local prefab = PrefabMarkers[last_prefab] or empty_table
self.SelectedPrefab = last_prefab
self.SelectedMark = last_mark
self.SelectedTags = PrefabTagsToStr(GetPrefabTags(prefab))
self.SelectedPoi = prefab.poi_type
self:DbgOnModified()
end
end
end)
end
end
end
local function BiomeFiller_ObjModified(obj)
ObjModified(obj)
end
function BiomeFiller:DbgOnModified()
DelayedCall(20, BiomeFiller_ObjModified, self)
end
local function ChangeSortKey(key, ...)
local keys = {...}
local idx = table.find(keys, key)
return idx and keys[idx + 1] or keys[1]
end
local function GetSortedList(list, key, ...)
local keys = {...}
local sort = {}
for i=1,#keys do
sort[i] = keys[i] == key and "*" or ""
end
list = list or {}
local function CmpItemValues(a, b, k, ...)
if not k then
return
end
local va, vb = a[k], b[k]
if va ~= vb then
return va > vb
end
return CmpItemValues(a, b, ...)
end
table.sort(list, function(a, b)
return CmpItemValues(a, b, key, table.unpack(keys))
end)
return list, keys, sort
end
BiomeFiller.dbg_placed_objects_sort = "count"
function BiomeFiller:ActionSortObjects()
self.dbg_placed_objects_sort = ChangeSortKey(self.dbg_placed_objects_sort, "class", "count")
self:DbgOnModified()
end
function BiomeFiller:GetPlacedObjects()
local list, keys, sort = GetSortedList(self.dbg_placed_objects, self.dbg_placed_objects_sort, "class", "pct", "count")
local tmp = {
string.format("%35s | %6s | %s", table.unpack(sort)),
string.format("%35s | %6s | %s", table.unpack(keys)),
"-------------------------------------------------------------------------------------------",
}
for _, t in ipairs(list) do
local pct = t.pct
tmp[#tmp + 1] = string.format("%35s | %3d.%02d | %d", t.class, pct / pct_mul, pct % pct_mul, t.count)
end
return table.concat(tmp, "\n")
end
BiomeFiller.dbg_placed_prefabs_sort = "impact"
function BiomeFiller:ActionSortPrefabs()
self.dbg_placed_prefabs_sort = ChangeSortKey(self.dbg_placed_prefabs_sort, "name", "count", "objs", "grid", "impact")
self:DbgOnModified()
end
function BiomeFiller:GetPlacedPrefabs()
local list, keys, sort = GetSortedList(self.dbg_placed_prefabs, self.dbg_placed_prefabs_sort, "name", "count", "objs", "load", "place", "grid", "load", "place", "impact")
local tmp = {
string.format("%35s %5s %5s %5s %5s %5s %5s %5s %s", table.unpack(sort)),
string.format("%35s %5s | %5s %5s %5s | %5s %5s %5s | %s", table.unpack(keys)),
"-------------------------------------------------------------------------------------------",
}
for _, t in ipairs(list) do
local prefab = t.prefab
tmp[#tmp + 1] = string.format("%35s %5d | %5d %5d %5d | %5d %5d %5d | %d",
t.name, t.count,
t.objs, t.obj_load_time or 0, t.obj_place_time or 0,
t.grid, t.grid_load_time or 0, t.grid_place_time or 0,
t.impact)
end
return table.concat(tmp, "\n")
end
BiomeFiller.dbg_prefab_types_sort = "area"
function BiomeFiller:ActionSortPrefabTypes()
self.dbg_prefab_types_sort = ChangeSortKey(self.dbg_prefab_types_sort, "name", "area", "prefabs")
self:DbgOnModified()
end
function BiomeFiller:GetPrefabTypes()
local list, keys, sort = GetSortedList(self.dbg_prefab_types, self.dbg_prefab_types_sort, "name", "area", "prefabs")
local tmp = {
string.format("%35s %6s %s", table.unpack(sort)),
string.format("%35s | %6s | %s", table.unpack(keys)),
"-------------------------------------------------------------------------------------------",
}
for _, t in ipairs(list) do
local prefab = t.prefab
local area = t.area or 0
local fully_hidden = t.fully_hidden or 0
tmp[#tmp + 1] = string.format("%35s | %3d.%02d | %d",
t.name, area / pct_mul, area % pct_mul, t.prefabs)
end
return table.concat(tmp, "\n")
end
BiomeFiller.dbg_visible_prefabs_sort = "visible_area"
function BiomeFiller:ActionSortVisible()
self.dbg_visible_prefabs_sort = ChangeSortKey(self.dbg_visible_prefabs_sort, "visible_area", "fully_hidden")
self:DbgOnModified()
end
function BiomeFiller:GetVisiblePrefabs()
local list, keys, sort = GetSortedList(self.dbg_visible_prefabs, self.dbg_visible_prefabs_sort, "name", "visible_area", "fully_hidden")
local tmp = {
string.format("%35s %12s %12s", table.unpack(sort)),
string.format("%35s | %12s | %12s", table.unpack(keys)),
"-------------------------------------------------------------------------------------------",
}
for _, t in ipairs(list) do
local prefab = t.prefab
local visible_area = t.visible_area or 0
local fully_hidden = t.fully_hidden or 0
tmp[#tmp + 1] = string.format("%35s | %9d.%02d | %9d.%02d",
t.name, visible_area / pct_mul, visible_area % pct_mul, fully_hidden / pct_mul, fully_hidden % pct_mul)
end
return table.concat(tmp, "\n")
end
BiomeFiller.dbg_placed_poi_sort = "count"
function BiomeFiller:ActionSortPoi()
self.dbg_placed_poi_sort = ChangeSortKey(self.dbg_placed_poi_sort, "name", "count")
self:DbgOnModified()
end
function BiomeFiller:GetPlacedPOI()
local list, keys, sort = GetSortedList(self.dbg_placed_poi, self.dbg_placed_poi_sort, "name", "count")
local tmp = {
string.format("%35s %s", table.unpack(sort)),
string.format("%35s | %s", table.unpack(keys)),
"-------------------------------------------------------------------------------------------",
}
for _, t in ipairs(list) do
local prefab = t.prefab
tmp[#tmp + 1] = string.format("%35s | %d", t.name, t.count)
end
return table.concat(tmp, "\n")
end
--[[
function BiomeActionImport(ged)
if not g_BiomeFiller then
print("No biome filler found!")
return
end
local props = GetModifiedProperties(g_BiomeFiller) or {}
local preset = BiomeFillerPreset:new()
props.Id = preset:GenerateUniquePresetId("Imported")
preset:SetProperties(props)
preset:PostLoad()
ObjModified(Presets.BiomeFillerPreset)
end
--]]
function BiomeFiller:ViewInspectedPrefab()
local pattern = self.InspectPattern
if pattern == "" then
print("No prefab name selected")
return
end
local unpack = table.unpack
local list = self.PrefabList or empty_table
local last_mark = self.dbg_view_mark
local mark, mark_pos, mark_radius, mark_name
local count = #list
local i = last_mark + 1
for n = 1, count do
if i > count then i = 1 end
local name, pos = unpack(list[i])
if string.find(name, pattern) then
mark, mark_pos, mark_name = i, pos, name
break
end
i = i + 1
end
if not mark then
print("No placed prefabs matching the pattern:", name)
return
end
self.dbg_view_mark = mark
local prefab = PrefabMarkers[mark_name]
local prefab_radius = prefab and prefab.max_radius * type_tile
ViewPos(mark_pos, 2 * prefab_radius)
printf("Shown: %s [%d]", mark_name, mark)
end
function OnMsg.GedPropertyEdited(_, obj)
if IsKindOf(obj, "NoisePreset") then
ForEachPreset("Biome", function(biome)
if biome.TypeMixingPreset == obj.id then
ObjModified(biome)
end
end)
end
end
function Biome:OnEditorSetProperty(prop_id, old_value, ged)
if prop_id == "TypeMixingPreset" then
self:CalcTypeMixingPreview()
else
local prop = self:GetPropertyMetadata(prop_id)
if prop.recalc_curve then
self["CalcCurve" .. prop.recalc_curve](self)
end
end
end
function OnMsg.ChangeMap()
g_BiomeFiller = false
end