Download Lua/Tactical/RangeContour.lua from sirnii/myspace: direct link, hf CLI and curl.
- Browser
- Download file 11.6 kB
-
https://huggingface.co/spaces/sirnii/myspace/resolve/main/Lua/Tactical/RangeContour.lua
- Command line
-
hf download hf://spaces/sirnii/myspace/Lua/Tactical/RangeContour.lua
-
curl -L -o RangeContour.lua https://huggingface.co/spaces/sirnii/myspace/resolve/main/Lua/Tactical/RangeContour.lua
11.6 kB
| -- offset against voxel border | |
| const.ContoursOffset = -80 | |
| const.ContoursOffset_Merc = -85 | |
| const.ContoursOffset_BorderlineAttack = const.ContoursOffset -90 | |
| const.ContoursOffset_BorderlineTurn = const.ContoursOffset | |
| -- z offset | |
| const.ContoursOffsetZ = 15*guic | |
| const.ContoursOffsetZ_Merc = const.ContoursOffsetZ +30 | |
| const.ContoursOffsetZ_BorderlineAttack = const.ContoursOffsetZ | |
| const.ContoursOffsetZ_BorderlineTurn = const.ContoursOffsetZ | |
| -- width | |
| const.ContoursWidth = 480 / 5 | |
| const.ContoursWidth_Merc = const.ContoursWidth | |
| const.ContoursWidth_BorderlineAttack = const.ContoursWidth | |
| const.ContoursWidth_BorderlineTurn = const.ContoursWidth | |
| -- turn radius | |
| const.ContoursRadius2D = 180 | |
| const.ContoursRadius2D_Merc = 180 | |
| const.ContoursRadius2D_Merc_Exploration = 500 | |
| const.ContoursRadiusVertical = 80 | |
| const.ContoursRadiusSteps = 8 | |
| -- voxel connectivity | |
| const.ContoursPassConnection = false | |
| const.ContoursTunnelMask = | |
| const.TunnelMaskWalk | |
| | const.TunnelMaskClimbDrop | |
| | const.TunnelTypeLadder | |
| | const.TunnelTypeJumpOver1 | |
| | const.TunnelTypeDoor | |
| | const.TunnelTypeWindow | |
| function GetRangeContour(voxels, contour_width, radius2D, offset, offsetz, voxel_pass_connection, tunnels_mask, exclude_voxels) | |
| if not voxels or #voxels == 0 then | |
| return | |
| end | |
| contour_width = contour_width or const.ContoursWidth | |
| radius2D = radius2D or const.ContoursRadius2D | |
| local radius_vertical = const.ContoursRadiusVertical | |
| offset = offset or const.ContoursOffset | |
| offsetz = offsetz or const.ContoursOffsetZ | |
| voxel_pass_connection = voxel_pass_connection or const.ContoursPassConnection | |
| tunnels_mask = tunnels_mask or const.ContoursTunnelMask | |
| local contours = GetContoursPStr(voxels, voxel_pass_connection, tunnels_mask, contour_width, radius2D, radius_vertical, offset, offsetz) | |
| return contours | |
| end | |
| local function RGBToModifier(r, g, b) | |
| local r = MulDivRound(r, 100, 255) | |
| local g = MulDivRound(g, 100, 255) | |
| local b = MulDivRound(b, 100, 255) | |
| return RGB(r, g, b) | |
| end | |
| function PlaceContourPolyline(contour, color, shader) | |
| local meshes = { | |
| SetVisible = function(self, value) | |
| for _, m in ipairs(self) do | |
| m:SetVisible(value) | |
| end | |
| end | |
| } | |
| shader = shader or "range_contour" | |
| if type(color) == "string" then | |
| color = Mesh.ColorFromTextStyle(color) | |
| else | |
| local r, g, b, opacity = GetRGBA(color) | |
| color = RGBToModifier(r, g, b) | |
| end | |
| for _, v_pstr in ipairs(contour) do | |
| local mesh = PlaceObject("Mesh") | |
| mesh:SetColorModifier(color) | |
| mesh:SetMesh(v_pstr) | |
| if not ProceduralMeshShaders[shader] then | |
| mesh:SetCRMaterial(shader) | |
| else | |
| mesh:SetShader(ProceduralMeshShaders[shader]) | |
| end | |
| mesh:SetPos(0, 0, 0) | |
| table.insert(meshes, mesh) | |
| end | |
| return meshes | |
| end | |
| function PlaceSingleTileStaticContourMesh(color_textstyle_id, pos, exploration) | |
| local r = const.SlabSizeX / 2 + const.ContoursOffset_Merc | |
| local z = const.ContoursOffsetZ_Merc | |
| local contour = GetRectContourPStr(box(-r, -r, z, r, r, z), const.ContoursWidth_Merc, exploration and const.ContoursRadius2D_Merc_Exploration or const.ContoursRadius2D_Merc) | |
| local polyline = PlaceContourPolyline({contour}, color_textstyle_id) | |
| if pos then | |
| polyline[1]:SetPos(pos) | |
| end | |
| return polyline[1] | |
| end | |
| function DestroyMesh(mesh) | |
| if IsValid(mesh) then | |
| mesh:delete() | |
| end | |
| end | |
| function DestroyContourPolyline(meshes) | |
| if not meshes then return end | |
| for _, mesh in ipairs(meshes) do | |
| DestroyMesh(mesh) | |
| end | |
| table.iclear(meshes) | |
| end | |
| function ContourPolylineSetVisible(meshes, visible) | |
| for _, mesh in ipairs(meshes) do | |
| if IsValid(mesh) then | |
| if visible then | |
| mesh:SetEnumFlags(const.efVisible) | |
| else | |
| mesh:ClearEnumFlags(const.efVisible) | |
| end | |
| end | |
| end | |
| end | |
| function ContourPolylineSetColor(meshes, color_textstyle_id) | |
| for _, mesh in ipairs(meshes) do | |
| mesh:SetColorFromTextStyle(color_textstyle_id) | |
| end | |
| end | |
| function ContourPolylineSetShader(meshes, shader) | |
| shader = ProceduralMeshShaders[shader] | |
| for _, mesh in ipairs(meshes) do | |
| if mesh.shader ~= shader then | |
| mesh:SetShader(shader) | |
| end | |
| end | |
| end | |
| function PlaceGroundRectMesh(v_pstr, color_textstyle_id, shader) | |
| shader = shader or "ground_strokes" | |
| local mesh = PlaceObject("Mesh") | |
| if color_textstyle_id then | |
| mesh:SetColorFromTextStyle(color_textstyle_id) | |
| end | |
| mesh:SetMesh(v_pstr) | |
| mesh:SetPos(0, 0, 0) | |
| if IsKindOf(shader, "CRMaterial") then | |
| mesh:SetCRMaterial(shader) | |
| else | |
| mesh:SetShader(ProceduralMeshShaders[shader]) | |
| end | |
| mesh:SetDepthTest(true) | |
| return mesh | |
| end | |
| local reload_prop_ids = {TextColor = true, ShadowColor = true, ShadowSize = true, } | |
| function TextStyle:OnEditorSetProperty(prop_id, old_value, ged) | |
| if self.group == "Zulu Ingame" and reload_prop_ids[prop_id] then | |
| DelayedCall(300, MapForEach, "map", "Mesh", function(mesh) | |
| if mesh.textstyle_id == self.id then | |
| mesh:SetColorFromTextStyle(self.id) | |
| end | |
| end) | |
| end | |
| end | |
| DefineClass.CRM_RangeContourPreset = { | |
| __parents = { "CRMaterial" }, | |
| group = "RangeContourPreset", | |
| properties = { | |
| { uniform = true, id = "depth_softness", editor = "number", default = 0, scale = 1000, min = -2000, max = 2000, slider = true, }, | |
| { uniform = true, id = "fill_color", editor = "color", default = RGB(0, 255, 0) }, | |
| { uniform = true, id = "border_color", editor = "color", default = RGB(255, 255, 255) }, | |
| { uniform = true, id = "dash_color", editor = "color", default = RGB(255, 255, 255) }, | |
| { uniform = true, id = "fill_width", editor = "number", default = 200, scale = 1000, min = 0, max = 1000, slider = true, }, | |
| { uniform = true, id = "border_width", editor = "number", default = 200, scale = 1000, min = 0, max = 1000, slider = true, }, | |
| { uniform = true, id = "border_softness", editor = "number", default = 200, scale = 1000, min = 0, max = 1000, slider = true, }, | |
| { uniform = true, id = "dash_density", editor = "number", scale = 1000, default = 1000, slider = true, min = 0, max = 1000}, | |
| { uniform = true, id = "dash_segment", editor = "number", scale = 1000, default = 1000, slider = true, min = 0, max = 100000}, | |
| { uniform = true, id = "anim_speed", editor = "number", scale = 1000, default = 1000, slider = true, min = 0, max = 10000}, | |
| { uniform = true, id = "grain_strength", editor = "number", scale = 1000, default = 200, slider = true, min = 0, max = 1000}, | |
| { uniform = true, id = "interlacing_strength", editor = "number", scale = 1000, default = 200, slider = true, min = 0, max = 1000}, | |
| }, | |
| shader_id = "range_contour_default", | |
| } | |
| DefineClass.CRM_RangeContourControllerPreset = { | |
| __parents = { "CRMaterial" }, | |
| group = "RangeContourControllerPreset", | |
| shader_id = "combat_border", | |
| properties = { | |
| { id = "contour_base_inside", editor = "preset_id", preset_class = "CRM_RangeContourPreset", default = false, }, | |
| { id = "contour_base_outside", editor = "preset_id", preset_class = "CRM_RangeContourPreset", default = false, }, | |
| { id = "contour_fx_inside", editor = "preset_id", preset_class = "CRM_RangeContourPreset", default = false, }, | |
| { id = "contour_fx_outside", editor = "preset_id", preset_class = "CRM_RangeContourPreset", default = false, }, | |
| { uniform = "integer", id = "fade_inout_start", editor = "number", scale = 1, default = 0, no_edit = true, dont_save = true, }, | |
| { uniform = true, id = "fade_in", editor = "number", scale = 1000, default = 200, min = 0, max = 2000, slider = true, }, | |
| { uniform = true, id = "cursor_alpha_distance", editor = "number", scale = 1000, default = 1000, min = 0, max = 3000, slider = true, }, | |
| { uniform = true, id = "cursor_alpha_falloff", editor = "number", scale = 1000, default = 1000, min = 0, max = 25000, slider = true, }, | |
| { uniform = "integer", id = "pop_in_start", editor = "number", scale = 1, default = 0, no_edit = true, dont_save = true, }, | |
| { id = "pop_delay", editor = "number", scale = 1, default = 0, }, | |
| { uniform = true, id = "pop_in_time", editor = "number", scale = 1000, default = 500, slider = true, min = 0, max = 1200, }, | |
| { uniform = true, id = "pop_in_freq", editor = "number", scale = 1000, default = 200, slider = true, min = 0, max = 1200, }, | |
| { id = "is_inside", editor = "bool", default = false, no_edit = true, dont_save = true, }, | |
| { uniform = true, id = "ZOffset", editor = "number", default = false, scale = 1000, no_edit = true, default = 0, } | |
| }, | |
| } | |
| function CRM_RangeContourControllerPreset:Recreate() | |
| self.dirty = false | |
| local pstr_buffer = self.pstr_buffer | |
| local preset = CRM_RangeContourPreset:GetById(self.is_inside and self.contour_base_inside or self.contour_base_outside) | |
| pstr_buffer = preset:WriteBuffer(pstr_buffer) | |
| local preset2 = CRM_RangeContourPreset:GetById(self.is_inside and self.contour_fx_inside or self.contour_fx_outside) | |
| pstr_buffer = preset2:WriteBuffer(pstr_buffer, 4 * 12) | |
| self:WriteBuffer(pstr_buffer, 4 * 12 * 2 ) | |
| self.pstr_buffer = pstr_buffer | |
| end | |
| function CRM_RangeContourControllerPreset:SetIsInside(value, notimereset) | |
| value = value and true or false | |
| if self.is_inside ~= value then | |
| self.is_inside = value | |
| if not notimereset then | |
| self.fade_inout_start = RealTime() | |
| end | |
| self.dirty = true | |
| end | |
| end | |
| DefineClass.RangeContourMesh = { | |
| __parents = {"Mesh"}, | |
| preset_id = false, | |
| polyline = false, | |
| exclude_polyline = false, | |
| use_exclude_polyline = true, | |
| meshes = false, | |
| dirty_geometry = false, | |
| } | |
| function RangeContourMesh:SetPolyline(polyline, exclude_polyline) | |
| self.polyline = polyline | |
| self.exclude_polyline = exclude_polyline | |
| end | |
| function RangeContourMesh:SetPreset(preset) | |
| if type(preset) == "string" then | |
| preset = CRM_RangeContourControllerPreset:GetById(preset) | |
| end | |
| if self.CRMaterial and preset.id == self.CRMaterial.id then | |
| return | |
| end | |
| self:SetCRMaterial(preset:Clone()) | |
| end | |
| function RangeContourMesh:SetVisible(value) | |
| if not g_PhotoMode then | |
| for _, mesh in ipairs(self.meshes or empty_table) do | |
| mesh:SetVisible(value) | |
| end | |
| if self.visible ~= value then | |
| self.CRMaterial.pop_in_start = RealTime() + self.CRMaterial.pop_delay | |
| self.visible = value | |
| self.CRMaterial.dirty = true | |
| end | |
| end | |
| end | |
| function RangeContourMesh:SetIsInside(value) | |
| self.CRMaterial:SetIsInside(value) | |
| end | |
| function RangeContourMesh:SetUseExcludePolyline(value) | |
| if self.use_exclude_polyline ~= value then | |
| self.use_exclude_polyline = value | |
| self.dirty_geometry = true | |
| end | |
| end | |
| function RangeContourMesh:Recreate(force_geometry) | |
| if #(self.meshes or empty_table) == 0 then | |
| force_geometry = true | |
| end | |
| if force_geometry or self.dirty_geometry then | |
| self.dirty_geometry = false | |
| for _, mesh in ipairs(self.meshes) do | |
| mesh:delete() | |
| end | |
| --self.polyline.side_len = 200 | |
| self.meshes = PlaceContourPolyline(self.polyline, RGB(255, 255, 255), self.CRMaterial, self.use_exclude_polyline and self.exclude_polyline) | |
| else | |
| for _, mesh in ipairs(self.meshes) do | |
| mesh:SetCRMaterial(self.CRMaterial) | |
| end | |
| end | |
| end | |
| function RangeContourMesh:delete() | |
| for _, mesh in ipairs(self.meshes or empty_table) do | |
| mesh:delete() | |
| end | |
| self.meshes = false | |
| Mesh.delete(self) | |
| end | |
| function CRM_RangeContourPreset:Apply() | |
| CRMaterial.Apply(self) | |
| self.cached_uniform_buf = self:GetDataPstr() | |
| if CurrentMap ~= "" then | |
| MapGet("map", "RangeContourMesh", function(o) | |
| if o.preset_id == self.id then | |
| o:Recreate() | |
| end | |
| end) | |
| end | |
| end | |
| RegisterSceneParam({ | |
| id = "CursorPos", type = "float", elements = 3, default = { 0, 0, 0 }, scale = 1000, prop_id = false, | |
| }) | |
| local cursor_pos_table = {0,0,0} | |
| MapRealTimeRepeat("RangeContourSceneParam", 33, function() | |
| local pos = GetCursorPos() | |
| if pos then | |
| cursor_pos_table[1], cursor_pos_table[2], cursor_pos_table[3] = pos:xyz() | |
| local interp_time = next(PauseReasons) and 0 or 33 | |
| SetSceneParamEx(1, "CursorPos", cursor_pos_table, interp_time) | |
| end | |
| end) | |