Download CommonLua/MapGen/BiomeZdit.lua from sirnii/myspace: direct link, hf CLI and curl.
- Browser
- Download file 18.1 kB
-
https://huggingface.co/spaces/sirnii/myspace/resolve/main/CommonLua/MapGen/BiomeZdit.lua
- Command line
-
hf download hf://spaces/sirnii/myspace/CommonLua/MapGen/BiomeZdit.lua
-
curl -L -o BiomeZdit.lua https://huggingface.co/spaces/sirnii/myspace/resolve/main/CommonLua/MapGen/BiomeZdit.lua
18.1 kB
| 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 | |