myspace / CommonLua /MapGen /PrefabType.lua
sirnii's picture
Upload 1816 files
b6a38d7 verified
raw
history blame
10.9 kB
local height_tile = const.HeightTileSize
local table_find = table.find
local function CheckProp(name, value)
value = value or false
return function(self) return self[name] == value end
end
local OVRLP_DEL_NONE, OVRLP_DEL_ALL, OVRLP_DEL_IGNORE, OVRLP_DEL_PARTIAL, OVRLP_DEL_SINGLE = false, 0, 1, 2, 3
local function OnObjOverlapItems()
return {
{ value = OVRLP_DEL_NONE, text = "Do nothing" },
{ value = OVRLP_DEL_ALL, text = "Delete the entire collection" },
{ value = OVRLP_DEL_IGNORE, text = "Delete ignoring collections" },
{ value = OVRLP_DEL_PARTIAL, text = "Delete if the collection is outside" },
{ value = OVRLP_DEL_SINGLE, text = "Delete if not in collection" },
}
end
function PrefabRadiusEstimItems()
return {
{ value = "incircle", text = "Incircle (Min)", color = red },
{ value = "excircle", text = "Excircle (Max)", color = green },
{ value = "amean", text = "Arithmetic Mean (Average)", color = yellow },
{ value = "gmean", text = "Geometric Mean (Ellipse)", color = blue },
{ value = "bestfit", text = "Best Fit (Circle)", color = cyan },
}
end
function PrefabRadiusEstimators()
return {
incircle = function(prefab) return prefab.min_radius end,
excircle = function(prefab) return prefab.max_radius end,
amean = function(prefab) return (prefab.min_radius + prefab.max_radius) / 2 end,
gmean = function(prefab) return sqrt(prefab.min_radius * prefab.max_radius) end,
bestfit = function(prefab) return sqrt(prefab.total_area * 7 / 22) end,
}
end
DefineClass.PrefabType = {
__parents = { "Preset", },
properties = {
{ category = "General", id = "OnObjOverlap", name = "On Object Overlap", editor = "choice", default = OVRLP_DEL_ALL, items = OnObjOverlapItems },
{ category = "General", id = "RespectBounds", name = "Respect Type Bounds", editor = "bool", default = true, help = "Disable prefab objects spill beyond the their prefab type boundaries. Doesn't affect POI prefabs as they can share multiple prefab types." },
{ category = "General", id = "OverlapReduct", name = "Lim Excircle Overlap", editor = "number", default = 1, min = 0, max = 4, slider = true, help = "Prioritize prefabs with better incircle to excircle radius ratio (the best being 1, a perfect circle)" },
{ category = "General", id = "FitEffort", name = "Prefab Fit Effort", editor = "number", default = 1, min = 0, max = 4, slider = true, help = "Prioritize prefabs fitting better the available space (using the radius estimate)" },
{ category = "General", id = "RadiusEstim", name = "Radius Estimate", editor = "choice", default = "bestfit", items = PrefabRadiusEstimItems, help = "Used to estimate the prefab real form by a circle when fitting prefabs" },
{ category = "General", id = "PlaceRadius", name = "Min Prefab Radius", editor = "number", default = height_tile, scale = "m", help = "Ignore prefabs with radius estimate below that value" },
{ category = "General", id = "FitPasses", name = "Max Fit Passes", editor = "number", default = 5, min = 1, max = 5, slider = true, help = "Maximum number of prefab fitting passes" },
{ category = "General", id = "MinFillRatio", name = "Min Fill Ratio (%)", editor = "number", default = 100, min = 0, max = 100, slider = true, help = "How much of the prefab type surface would be filled at least (actual value can be bigger, but not lesser)" },
{ category = "General", id = "MaxFillError", name = "Max Fill Err (%)", editor = "number", default = 10, min = 0, max = 1000, scale = 10, slider = true, help = "How much of the prefab type surface specified to be filled could remain unfilled" },
{ category = "General", id = "Tags", name = "Tags", editor = "set", default = empty_table, items = PrefabTagsCombo },
{ category = "Terrain", id = "Transition", name = "Transition", editor = "number", default = 0, scale = "m", granularity = height_tile, help = "Transition zone for texture dithering" },
{ category = "Terrain", id = "TexturingOrder", name = "Texturing Order", editor = "number", default = 0, help = "Sort key used when applying prefab type terrain. Types with equal order are compared based on the descending transition dist." },
{ category = "Terrain", id = "TextureMain", name = "Main Texture", editor = "choice", default = "", items = GetTerrainNamesCombo(), },
{ category = "Terrain", id = "GrassMain", name = "Main Grass (%)", editor = "number", default = 100, min = 0, max = 200, slider = true, no_edit = CheckProp("TextureMain", "") },
{ category = "Terrain", id = "PreviewMain", name = "Main Preview", editor = "image", default = false, img_size = 128, img_box = 1, base_color_map = true, dont_save = true, no_edit = CheckProp("TextureMain", "") },
{ category = "Terrain", id = "TextureFlow", name = "Flow Texture", editor = "choice", default = "", items = GetTerrainNamesCombo(), },
{ category = "Terrain", id = "GrassFlow", name = "Flow Grass (%)", editor = "number", default = 100, min = 0, max = 200, slider = true, no_edit = CheckProp("TextureFlow", "") },
{ category = "Terrain", id = "FlowStrength", name = "Flow Strength", editor = "number", default = 100, min = 0, max = 200, scale = 100, slider = true },
{ category = "Terrain", id = "FlowContrast", name = "Flow Contrast", editor = "number", default = 100, min = 0, max = 300, scale = 100, slider = true },
{ category = "Terrain", id = "PreviewFlow", name = "Flow Preview", editor = "image", default = false, img_size = 128, img_box = 1, base_color_map = true, dont_save = true, no_edit = CheckProp("TextureFlow", "") },
{ category = "Terrain", id = "TextureNoise", name = "Noise Texture", editor = "choice", default = "", items = GetTerrainNamesCombo(), },
{ category = "Terrain", id = "GrassNoise", name = "Noise Grass (%)", editor = "number", default = 100, min = 0, max = 200, slider = true, no_edit = CheckProp("TextureNoise", "") },
{ category = "Terrain", id = "PreviewNoise", name = "Noise Preview", editor = "image", default = false, img_size = 128, img_box = 1, base_color_map = true, dont_save = true, no_edit = CheckProp("TextureNoise", "") },
{ category = "Terrain", id = "HeightModulated",name = "Height Modulated", editor = "bool", default = false, },
{ category = "Terrain", id = "NoiseStrength", name = "Noise Strength", editor = "number", default = 100, min = 0, max = 200, scale = 100, slider = true },
{ category = "Terrain", id = "NoiseContrast", name = "Noise Contrast", editor = "number", default = 100, min = 0, max = 300, scale = 100, slider = true },
{ category = "Terrain", id = "NoisePreset", name = "Noise Pattern", editor = "preset_id", default = "", preset_class = "NoisePreset" },
{ category = "Terrain", id = "NoisePreview", name = "Noise Preview", editor = "grid", default = false, no_edit = function(self) return self.NoisePreset == "" end, frame = 1, min = 64, dont_save = true, read_only = true },
{ category = "Editor", id = "OverlayColor", name = "Overlay Color", editor = "color", default = false, alpha = false },
{ category = "Editor", id = "FillPrefabList", name = "Fill Prefab List", editor = "string_list", default = false, read_only = true, dont_save = true },
{ category = "Editor", id = "POIPrefabList", name = "POI Prefab List", editor = "string_list", default = false, read_only = true, dont_save = true },
{ category = "Editor", id = "POIList", name = "POI List", editor = "string_list", default = false, read_only = true, dont_save = true },
},
EditorMenubarName = "Prefab Types",
EditorMenubar = "Map.Generate",
EditorIcon = "CommonAssets/UI/Icons/puzzle.png",
EditorView = Untranslated("<Id> <style GedConsole>[<SortKey>]</style>"),
StoreAsTable = false,
GlobalMap = "PrefabTypeToPreset",
HasSortKey = true,
GetPreviewMain = function(self) return GetTerrainTexturePreview(self.TextureMain) end,
GetPreviewFlow = function(self) return GetTerrainTexturePreview(self.TextureFlow) end,
GetPreviewNoise = function(self) return GetTerrainTexturePreview(self.TextureNoise) end,
GetNoisePreview = function(self) return GetNoisePreview(self.NoisePreset) end,
}
function PrefabType:Compare(other)
local sa, sb = self.SortKey, other.SortKey
if sa ~= sb then
return sa < sb
end
local ba, bb = self.RespectBounds and 1 or 0, other.RespectBounds and 1 or 0
if ba ~= bb then
return ba > bb
end
local ooa, oob = (self.OnObjOverlap or -1), (other.OnObjOverlap or -1)
if ooa ~= oob then
return ooa > oob
end
return self.id < other.id
end
function PrefabType:GetPOIPrefabList()
local names = {}
local prefabs = PrefabMarkers or empty_table
local poi_to_preset = PrefabPoiToPreset or empty_table
local ptype = self.id
for _, prefab in ipairs(prefabs) do
local poi_type = prefab and prefab.poi_type or ""
if poi_type ~= "" then
local preset = poi_to_preset[poi_type]
for _, group in pairs(preset and preset.PrefabTypeGroups) do
if table_find(group.types, ptype) then
names[#names + 1] = prefabs[prefab]
break
end
end
end
end
if #names == 0 then return end
table.sort(names)
return names
end
function PrefabType:GetPOIList()
local ptype = self.id
local list = {}
for name, preset in pairs(PrefabPoiToPreset) do
for _, group in pairs(preset.PrefabTypeGroups) do
if table_find(group.types, ptype) then
list[#list + 1] = name
break
end
end
end
table.sort(list)
return list
end
function PrefabType:GetFullPrefabList()
local names = {}
local prefabs = PrefabMarkers or empty_table
local ptype = self.id
for _, prefab in ipairs(prefabs) do
local poi_type = prefab and prefab.poi_type or ""
if poi_type == "" and (prefab.type == "" or prefab.type == ptype) then
names[#names + 1] = prefabs[prefab]
end
end
if #names == 0 then return end
table.sort(names)
return names
end
function GetPrefabTypeList()
return table.keys(PrefabTypeToPreset, true)
end
function GetPrefabTypeTags(add_empty)
local tags = {}
for ptype, preset in pairs(PrefabTypeToPreset) do
for tag in pairs(preset and preset.Tags or empty_table) do
if tag ~= "" then
tags[tag] = true
end
end
end
tags = table.keys(tags, true)
if add_empty then
table.insert(tags, 1, add_empty)
end
return tags
end
function OnMsg.GedPropertyEdited(_, obj)
if IsKindOf(obj, "NoisePreset") then
ForEachPreset("PrefabType", function(ptype)
if ptype.NoisePreset == obj.id then
ObjModified(ptype)
end
end)
end
end