Files
2025-09-29 00:52:08 +02:00

1045 lines
29 KiB
Plaintext
Executable File

global gRsZoneViewData, gRsZoneViewFuncs
callbacks.removeScripts id:#RsZoneView
if (gRsZoneViewData != undefined) do
(
RsZoneViewFuncs.CloseTool()
)
-- Struct holding data and control-links for tool:
struct RsZoneViewData
(
ToolName = "PopZone Viewer",
VersionNum = 1.06,
VersionName = "Rhetorical Sun",
ToolWidth = 700, ToolHeight = 400,
zoneDataFolder = (RsConfigGetCommonDir core:True) + "data/levels/" + (RsConfigGetProjectName core:True),
zonebindPath = zoneDataFolder + "/zonebind.meta",
popZonePath = zoneDataFolder + "/popzone.ipl",
ToolDialog = undefined,
ItemListCtrl = undefined,
SelectTimer = undefined,
DoObjects = True,
ViewLabels = True,
ShowPlantIdxClr = False,
ShowDirtClr = False,
ShowAreaClr = True,
DrawWireframe = False,
PopZonesList = #(),
ZoneTypeList = (filterString (GetControlData "RsPopZone" "Zone type") ","),
-- Colours to use when colouring zones by plantsMgrTxdIdx:
-- 0 = nothing - gray
-- 1 = countryside - green
-- 2 = ocean - so blue
-- 3 = Not used yet - bright pink
-- 4 = Not used yet - bright pink
-- 5 = Not used yet - bright pink
-- 6 = Not used yet - bright pink
-- 7 = Default, memory hungry, so RED
plantsMgrClrs = #((color 180 180 180), (color 0 180 0), (color 0 0 180), (red + blue), (red + blue), (red + blue), (red + blue), (red))
)
-- Struct used to hold data for individual popZones:
struct popZoneStruct
(
name, obj, meshNode, meta, boxMin, boxMax, boxSize, boxVol, boxArea, areaName, zoneType=0, dirtColour=(red + blue), subBoxes = #(),
vfxRegion="", plantsIdx=7,
listCtrlRow,
-- Return values for building list-rows:
fn GetListLabels = #("Zone Name", "Zone Type", "Area Name", "VFX Region", "PlantsMgrTxdIdx", "Has Metadata"),
fn GetRowStrings =
(
local zoneName = This.Name
local zoneTypeStr = gRsZoneViewData.ZoneTypeList[This.ZoneType + 1]
local zoneArea = This.AreaName
local hasMeta = (This.Meta != undefined)
return #(zoneName, zoneTypeStr, zoneArea, vfxRegion, plantsIdx, hasMeta)
),
fn getMetaAttrib attribName =
(
if (meta == undefined) or not (meta.ContainsKey attribName) do return undefined
return (meta.Item attribName).Value
),
fn getDirtColour useMeta:meta =
(
local vals = for attribName in #("dirtRed", "dirtGreen", "dirtBlue") collect
(
(useMeta.Item attribName).Value as integer
)
color vals[1] vals[2] vals[3]
),
-- Return colour to use for object:
fn UseObjColour =
(
case of
(
(gRsZoneViewData.ShowPlantIdxClr):(gRsZoneViewData.plantsMgrClrs[plantsIdx + 1])
(gRsZoneViewData.ShowDirtClr):(dirtColour)
Default: --(gRsZoneViewData.ShowAreaClr):
(
-- Set colour-seed based on area-name, to give each area same colour:
seed (getHashValue (toLower areaName) 1)
RsGetRandomColour()
)
)
),
fn generateObj = undo off
(
if (subBoxes.count == 0) do return undefined
local objName = (areaName + ":" + name)
local zoneSize = boxMax - boxMin
local zonePos = boxMin + [zoneSize.x / 2, zoneSize.y / 2, 0]
local colour = UseObjColour()
obj = (Editable_Mesh name:objName wireColor:colour pos:ZonePos backFaceCull:True)
-- Set transform-locks on obj:
setTransformLockFlags obj #{1..9}
if (meshNode == undefined) do
(
local vertPosList = #()
local faceVertLists = #()
for item in subBoxes do
(
local subBoxMin = item.boxMin
local subBoxMax = item.boxMax
local subBoxSize = (subBoxMax - subBoxMin)
subBoxMin.Z = 0
subBoxMax.Z = 0
local corners = #(subBoxMin, [subBoxMax.X, subBoxMin.Y, 0], subBoxMax, [subBoxMin.X, subBoxMax.Y, 0])
local faceVerts = for cornerPos in corners collect
(
local vertNum = findItem vertPosList cornerPos
if (vertNum == 0) do
(
append vertPosList cornerPos
vertNum = vertPosList.count
)
vertNum
)
append faceVertLists [faceVerts[1], faceVerts[2], faceVerts[3]]
append faceVertLists [faceVerts[1], faceVerts[3], faceVerts[4]]
)
-- Create a mesh from the loaded data:
local newMesh = TriMesh()
setMesh newMesh vertices:vertPosList faces:faceVertLists
if (subBoxes.count > 1) then
(
-- Optimise generated mesh:
meshop.optimize newMesh 0.1 1.0 0.0 0.0 saveMatBoundries:false saveSmoothBoundries:false autoEdge:true
)
else
(
-- Hide middle edges:
setEdgeVis newMesh 1 3 False
setEdgeVis newMesh 2 1 False
)
-- Move verts:
meshop.moveVert newMesh #all -ZonePos
-- Invert faces, if using wireframe-mode:
if gRsZoneViewData.DrawWireframe do
(
meshop.flipNormals newMesh #all
)
-- Store mesh seperately for easy retrieval:
meshNode = (createInstance Editable_Mesh)
meshNode.mesh = newMesh
)
-- Retrieve previously-generated mesh:
obj.mesh = (copy meshNode.mesh)
return objzZ
)
)
struct RsZoneViewFuncs
(
fn SetStatusTitle PromptText DoPushPrompt:False =
(
local NewText = gRsZoneViewData.ToolName + (if (PromptText == "") then "" else (": " + PromptText))
gRsZoneViewData.ToolDialog.Text = NewText
if DoPushPrompt do
(
PushPrompt PromptText
)
return OK
),
fn SelectCallback =
(
--print "SELECTY"
-- Focus on ItemList control:
local ItemListCtrl = gRsZoneViewData.ItemListCtrl
ItemListCtrl.Focus()
-- Make sure deferred-selection timer is stopped:
gRsZoneViewData.SelectTimer.Stop()
-- Update list-selections:
local showFirstRow = True
for item in gRsZoneViewData.PopZonesList do
(
local newSel = (isValidNode item.obj) and (item.obj.isSelected)
if (item.listCtrlRow.Selected != newSel) do
(
item.listCtrlRow.Selected = newSel
if newSel and showFirstRow do
(
ItemListCtrl.CurrentCell = item.listCtrlRow.Cells.Item[0]
showFirstRow = False
)
)
)
-- Stop timer again (it'll have been started by the selection-changing above)
gRsZoneViewData.SelectTimer.Stop()
return OK
),
fn genMissingObjs popZones: =
(
if (popZones == unsupplied) do
(
popZones = gRsZoneViewData.PopZonesList
)
local regenItems = for item in popZones where (not isValidNode item.obj) collect item
if (regenItems.count != 0) do
(
SetStatusTitle "Generating Zone Meshes..." DoPushPrompt:True
--local TimeStart = TimeStamp()
for item in regenItems do
(
item.generateObj()
)
completeRedraw()
--format "Time to generate: %s\n" ((TimeStamp() - TimeStart) / 1000)
popPrompt()
)
return OK
),
fn deleteObjs = undo off
(
local popZones = gRsZoneViewData.PopZonesList
local delObjs = for item in popZones where (isValidNode item.obj) collect item.obj
if (delObjs.count != 0) do
(
delete delObjs
)
),
fn preSaveCallback =
(
-- Remove callbacks and objects during save:
gRsZoneViewFuncs.RemoveCallbacks()
gRsZoneViewFuncs.DeleteObjs()
callbacks.addScript #filePostSaveProcess "gRsZoneViewFuncs.postSaveCallback()" id:#RsZoneView
),
fn postSaveCallback =
(
gRsZoneViewFuncs.GenMissingObjs()
gRsZoneViewFuncs.AddCallbacks()
),
-- Called to close the dialog and clear data-struct:
fn CloseTool =
(
--print "CloseTool"
if (gRsZoneViewData != undefined) and (gRsZoneViewData.ToolDialog != undefined) do
(
gRsZoneViewData.ToolDialog.Close()
)
gRsZoneViewData = undefined
return OK
),
-- Called when viewport redraws:
fn viewportDraw =
(
local ToolDialog = if (gRsZoneViewData == undefined) then undefined else gRsZoneViewData.ToolDialog
if (ToolDialog == undefined) or (not ToolDialog.Visible) do
(
gRsZoneViewFuncs.removeCallbacks()
)
if not (gRsZoneViewData.ViewLabels) do return False
local drawClr = White
gw.setTransform (Matrix3 1)
for item in gRsZoneViewData.PopZonesList where (isValidNode item.obj) and (item.listCtrlRow.Selected) do
(
local pos = (gw.wtransPoint item.obj.pos)
gw.wMarker pos #hollowBox color:drawClr
pos.X += 2
pos.Y += 8
gw.wtext pos (" zone: " + item.name) color:drawClr
pos.X += 2
pos.Y += 12
gw.wtext pos (" area: " + item.areaName) color:drawClr
)
gw.enlargeUpdateRect #whole
gw.updateScreen()
return OK
),
fn RemoveCallbacks =
(
callbacks.removeScripts id:#RsZoneView
unregisterRedrawViewsCallback viewportDraw
),
fn AddCallbacks =
(
RemoveCallbacks()
callbacks.addScript #selectionSetChanged "gRsZoneViewFuncs.SelectCallback()" id:#RsZoneView
callbacks.addScript #nodePostDelete "gRsZoneViewFuncs.genMissingObjs()" id:#RsZoneView
callbacks.addScript #filePreSaveProcess "gRsZoneViewFuncs.preSaveCallback()" id:#RsZoneView
callbacks.addScript #filePreOpenProcess "gRsZoneViewFuncs.closeTool()" id:#RsZoneView
callbacks.addScript #preSystemShutdown "gRsZoneViewFuncs.closeTool()" id:#RsZoneView
callbacks.addScript #systemPreReset "gRsZoneViewFuncs.closeTool()" id:#RsZoneView
callbacks.addScript #systemPreNew "gRsZoneViewFuncs.closeTool()" id:#RsZoneView
registerRedrawViewsCallback viewportDraw
),
fn LoadPopZones =
(
gRsZoneViewData.popZonesList = #()
local popZonesList = gRsZoneViewData.popZonesList
local zonebindPath = gRsZoneViewData.zonebindPath
local popZonePath = gRsZoneViewData.popZonePath
local doObjects = gRsZoneViewData.doObjects
format "%\n" zonebindPath
format "%\n" popZonePath
SetStatusTitle "Perforce Sync..."
gRsPerforce.sync #(zonebindPath, popZonePath)
if not doesFileExist zonebindPath do
(
print ("zonebind.meta doesn't exist!\n" + zonebindPath)
return false
)
if not doesFileExist popZonePath do
(
print ("popzone.ipl doesn't exist!\n" + popZonePath)
return false
)
-- Read in PopZone.ipl:
(
SetStatusTitle "Reading PopZone.ipl..." DoPushPrompt:True
local popzoneFile = openFile popZonePath
skipToString popzoneFile "zone"
local continueReading = True
while continueReading and (not eof popzoneFile) do
(
local thisLine = readline popzoneFile
local lineTokens = filterString thisLine ", \t"
case of
(
(lineTokens.count == 0):()
(lineTokens[1] == "end"):(continueReading = False)
Default:
(
local zoneName = (toLower lineTokens[1])
local popZone = popZoneStruct name:zoneName
-- Load sizes:
popZone.boxMin = [lineTokens[2] as float, lineTokens[3] as float, lineTokens[4] as float]
popZone.boxMax = [lineTokens[5] as float, lineTokens[6] as float, lineTokens[7] as float]
popZone.areaName = (lineTokens[8] as string)
popZone.zoneType = (lineTokens[9] as integer)
local boxSize = (popZone.boxMax - popZone.boxMin)
popZone.boxVol = (boxSize.X * boxSize.Y * boxSize.Z)
popZone.boxArea = (boxSize.X * boxSize.Y)
-- Add popzone to list:
append popZonesList popZone
)
)
)
close popzoneFile
popPrompt()
)
-- Read in ZoneBind.meta:
if doObjects do
(
SetStatusTitle "Reading ZoneBind.meta..." DoPushPrompt:True
local metaManager = RsGetMetaDataManager()
metaManager.LoadWithMetaFile zonebindPath
local zoneList = metaManager.FindFirstStructureNamed "zones"
for zoneIdx = 0 to (zoneList.length - 1) do
(
local zoneNode = zoneList.Item zoneIdx
local zoneName = toLower (zoneNode.Item "zoneName").Value
-- Find PopZone(s) with matching name:
local theseZones = for popZone in popZonesList where (popZone.name == zoneName) collect popZone
if (theseZones.count != 0) do
(
local dirtColour = popZoneStruct.getDirtColour useMeta:zoneNode
theseZones.meta = zoneNode
theseZones.dirtColour = dirtColour
)
if (zoneNode.ContainsKey "vfxRegion") do
(
theseZones.vfxRegion = (zoneNode.Item "vfxRegion").Value
)
if (zoneNode.ContainsKey "plantsMgrTxdIdx") do
(
theseZones.plantsIdx = (zoneNode.Item "plantsMgrTxdIdx").Value
)
)
popPrompt()
)
-- Sorts zones from smallest to largest (smallest one is used in-game when zones overlap)
fn sortZoneVols v1 v2 =
(
case of
(
(v1.boxVol < v2.boxVol):-1
(v1.boxVol > v2.boxVol):1
Default:0
)
)
local BoxHashes = #()
-- Find groups of intersecting zones, and chop those up into sub-zone boxes:
if doObjects do
(
local intersectZones = #()
local intersectTested = #{}
intersectTested.count = popZonesList.count
local Cancelled = False
local zoneCount = popZonesList.count
for initialZoneNum = 1 to zoneCount where not intersectTested[initialZoneNum] while (not Cancelled) do
(
SetStatusTitle "Finding intersecting zones..." DoPushPrompt:True
local theseIntersectNums = #(initialZoneNum)
local theseIntersectBits = #{initialZoneNum}
local intersectZoneIdx = 0
while (intersectZoneIdx < theseIntersectNums.count) and (not Cancelled) do
(
--format "% < %; %\n" intersectZoneIdx theseIntersectNums.count (intersectTested as string)
intersectZoneIdx += 1
local intersectZoneNum = theseIntersectNums[intersectZoneIdx]
local thisIntersectZone = popZonesList[intersectZoneNum]
intersectTested[intersectZoneNum] = True
-- Test 'thisIntersectZone' against all zones that haven't been tested yet:
for testZoneNum = 1 to zoneCount where not (intersectTested[testZoneNum] or theseIntersectBits[testZoneNum]) do
(
local testZone = popZonesList[testZoneNum]
-- If zones intersect, add it to 'theseIntersectNums':
if (
(testZone.boxMin.X < thisIntersectZone.boxMax.X) and (testZone.boxMax.X > thisIntersectZone.boxMin.X) and
(testZone.boxMin.Y < thisIntersectZone.boxMax.Y) and (testZone.boxMax.Y > thisIntersectZone.boxMin.Y)
) do
(
append theseIntersectNums testZoneNum
theseIntersectBits[testZoneNum] = True
)
)
Cancelled = keyboard.escPressed
)
PopPrompt()
if (theseIntersectNums.count == 1) then
(
-- Single box that doesn't intersect anything:
local thisZone = popZonesList[initialZoneNum]
append thisZone.subBoxes (dataPair boxMin:thisZone.boxMin boxMax:thisZone.boxMax)
)
else
(
SetStatusTitle "Gridding Zones into sub-boxes..." DoPushPrompt:True
-- Sort cluster of intersecting zones by volume:
-- (smaller zone is used if point is in multiple zones)
local foundZones = for zoneNum in theseIntersectNums collect popZonesList[zoneNum]
qsort foundZones sortZoneVols
-- Build lists of box-edge x/y values:
local xEdges = #()
local yEdges = #()
for popZone in foundZones do
(
join xEdges #(popZone.boxMin.X, popZone.boxMax.X)
join yEdges #(popZone.boxMin.Y, popZone.boxMax.Y)
)
-- Make values unique, sort:
xEdges = (makeUniqueArray xEdges)
yEdges = (makeUniqueArray yEdges)
sort xEdges
sort yEdges
-- Chop each zone up into unique sub-boxes:
for ThisZone in FoundZones while (not Cancelled) do
(
local ZoneMinX = ThisZone.boxMin.X
local ZoneMaxX = ThisZone.boxMax.X
local ZoneMinY = ThisZone.boxMin.Y
local ZoneMaxY = ThisZone.boxMax.Y
local ZoneXEdges = for Val in xEdges where (Val >= ZoneMinX) while (Val <= ZoneMaxX) collect Val
local ZoneYEdges = for Val in yEdges where (Val >= ZoneMinY) while (Val <= ZoneMaxY) collect Val
for y = 1 to (ZoneYEdges.count - 1) do
(
local minVal = [0, ZoneYEdges[y], 0]
local maxVal = [0, ZoneYEdges[y + 1], 0]
for x = 1 to (ZoneXEdges.count - 1) do
(
minVal.x = ZoneXEdges[x]
maxVal.x = ZoneXEdges[x + 1]
local hashArrayIdx = ((abs (0.1 * minVal.X) as integer) + 1)
local hashArray = boxHashes[hashArrayIdx]
-- Collect box, if similar one hasn't already been used:
local isUnique = True
local boxHash = GetHashValue #(minVal, maxVal) 1
local hashArray = boxHashes[hashArrayIdx]
if (hashArray == undefined) then
(
boxHashes[hashArrayIdx] = #(boxHash)
)
else
(
isUnique = (appendIfUnique hashArray boxHash)
)
if isUnique do
(
append ThisZone.SubBoxes (DataPair boxMin:(copy minVal) boxMax:(copy maxVal))
)
)
)
Cancelled = keyboard.escPressed
)
-- Dispose of hash-array data...
for Item in boxHashes where (isKindOf Item Array) do
(
Item.Count == 0
)
PopPrompt()
)
PopPrompt()
)
)
BoxHashes.Count = 0
return True
),
-----------------------------
-- CONTROL EVENTS: --
-----------------------------
-- Event: Triggered by "Draw Labels" tickybox
fn ShowLabel_Changed Sender Args =
(
gRsZoneViewData.ViewLabels = Sender.Checked
CompleteRedraw()
-- Make sure list-selection is retained:
gRsZoneViewFuncs.SelectCallback()
),
-- Event: Triggered by "Wireframe" tickybox
fn Wireframe_Changed Sender Args =
(
gRsZoneViewData.DrawWireframe = Sender.Checked
-- Flip faces to show Wireframe border:
for ThisZone in gRsZoneViewData.PopZonesList do
(
Meshop.FlipNormals ThisZone.MeshNode.Mesh #all
ThisZone.Obj.Mesh = (copy ThisZone.MeshNode.Mesh)
)
-- Inverted-faces trick needs 'Edge Faces' to be active:
if gRsZoneViewData.DrawWireframe do
(
viewport.SetShowEdgeFaces True
)
CompleteRedraw()
-- Make sure list-selection is retained:
gRsZoneViewFuncs.SelectCallback()
),
-- Event: Triggered when radiobuttons are clicked:
fn ShowClrBtn_Changed Sender Args =
(
-- Which button was clicked?
local btnList = Sender.Tag.Value
local btnIdx = (findItem btnList Sender)
local newStates = #{btnIdx}
-- Set states:
gRsZoneViewData.ShowPlantIdxClr = newStates[1]
gRsZoneViewData.ShowDirtClr = newStates[2]
gRsZoneViewData.ShowAreaClr = newStates[3]
-- Set object wirecolours to match new state:
for Item in gRsZoneViewData.PopZonesList where (isValidNode Item.Obj) do
(
Item.Obj.WireColor = (Item.UseObjColour())
)
),
-- Event: Selects objects after timer interval:
fn SelectTimer_Tick Sender Args =
(
--print "SelectTimer_Tick"
Sender.Stop()
gRsZoneViewFuncs.removeCallbacks()
local zoneList = gRsZoneViewData.PopZonesList
local selObjs = for item in zoneList where (item.listCtrlRow.Selected) and (isValidNode item.obj) collect (item.obj)
if (selObjs.count != 0) do
(
select selObjs
max tool ZoomExtents
)
gRsZoneViewFuncs.addCallbacks()
),
-- Event: Called when ItemListCtrl is clicked - brings up rightclick menu:
fn ItemList_Clicked Sender Args =
(
if (args.RowIndex < 0) do return false
local rightClick = args.button.equals args.button.right
if rightClick do
(
-- Exclusive-select row if it's not currently selected:
local clickRow = Sender.Rows.Item[args.RowIndex]
if not clickRow.Selected do
(
sender.ClearSelection()
clickRow.Selected = true
)
-- Rightclick menu:
rcmenu RSmenu_dialogList
(
local ItemListCtrl, SelRows
fn HasSel = (SelRows.Count != 0)
menuItem itmCopy "Copy selected to clipboard" filter:HasSel
on itmCopy picked do
(
-- Build text-list for copying to clipboard:
local copyText = stringStream ""
for SelRowNum = 1 to SelRows.Count do
(
local Row = SelRows[SelRowNum]
for ColNum = 1 to Row.Cells.Count do
(
format "%" row.cells.item[ColNum - 1].value to:copyText
if (ColNum != Row.Cells.Count) do
(
format ", " to:copyText
)
)
if selRowNum != SelRows.Count do
(
format "\n" to:copyText
)
)
setclipboardText (copyText as string)
)
on RSmenu_dialogList open do
(
ItemListCtrl = gRsZoneViewData.ItemListCtrl
SelRows = (for n = 0 to (ItemListCtrl.SelectedRows.count - 1) collect ItemListCtrl.SelectedRows.Item[n])
)
)
popUpMenu RSmenu_dialogList
)
),
-- Event: Triggered when list-selection changes:
fn ItemList_SelChanged Sender Args =
(
--print "ItemList_SelChanged"
-- Reset/start action-deferrer timer:
local selectTimer = gRsZoneViewData.SelectTimer
selectTimer.Stop()
selectTimer.Start()
),
-- Event: Clears list-selection when the form is activated:
fn ToolDialog_Activated sender args =
(
gRsZoneViewData.ItemListCtrl.clearSelection()
),
-- Event: Triggered when ToolDialog is closed
fn ToolDialog_Close Sender Args =
(
--print "ToolDialog_Close"
gRsZoneViewFuncs.RemoveCallbacks()
-- Kill deferred-selection timer:
gRsZoneViewData.SelectTimer.Dispose()
gRsZoneViewFuncs.deleteObjs()
gRsZoneViewData.ToolDialog.Dispose()
gRsZoneViewData.ToolDialog = undefined
),
-----------------------------
-- /CONTROL EVENTS --
-----------------------------
fn CreateTool =
(
-- Add deferred-action selector-timer:
(
local SelectTimer = dotNetObject "Timer"
gRsZoneViewData.SelectTimer = SelectTimer
SelectTimer.Tag = ItemListCtrl
SelectTimer.interval = 200
dotNet.addEventHandler SelectTimer "Tick" SelectTimer_Tick
)
-- Define form:
(
--DotNet properties
local DockStyle_Fill = (dotNetClass "DockStyle").Fill
local SizeType_Absolute = (dotNetClass "SizeType").Absolute
local SizeType_Percent = (dotNetClass "SizeType").Percent
local ToolDialog = (dotNetObject "MaxCustomControls.MaxForm")
gRsZoneViewData.ToolDialog = ToolDialog
SetStatusTitle ""
ToolDialog.Width = gRsZoneViewData.ToolWidth
ToolDialog.Height = gRsZoneViewData.ToolHeight
-- Make list-dialog resizable:
ToolDialog.FormBorderStyle = ToolDialog.FormBorderStyle.Sizable
ToolDialog.MinimizeBox = false
ToolDialog.MaximizeBox = false
ToolDialog.StartPosition = ToolDialog.StartPosition.CenterScreen
dotNet.addEventHandler ToolDialog "Activated" ToolDialog_Activated
dotNet.addEventHandler ToolDialog "FormClosing" ToolDialog_Close
dotNet.setLifetimeControl ToolDialog #dotnet
-- Main layout-table:
(
-- Set up main layout-table, with three rows: Banner, list, extra bits:
local MainTable = dotNetObject "TableLayoutPanel"
MainTable.Dock = DockStyle_Fill
ToolDialog.Controls.Add MainTable
MainTable.cellBorderStyle = MainTable.CellBorderStyle.None
MainTable.RowCount = 3
-- TechArt Banner:
(
MainTable.RowStyles.Add (dotNetObject "RowStyle" SizeType_Absolute 40)
local BannerPanel = dotNetObject "Panel"
BannerPanel.dock = DockStyle_Fill
MainTable.Controls.Add BannerPanel 0 0
local VerNum = gRsZoneViewData.VersionNum
local VerName = gRsZoneViewData.VersionName
local TheBanner = MakeRsBanner dn_Panel:BannerPanel wiki:"PopZone Viewer" versionNum:VerNum versionName:VerName filename:(getThisScriptFilename())
TheBanner.Setup()
)
-- Set up ItemListCtrl:
(
MainTable.RowStyles.Add (dotNetObject "RowStyle" SizeType_Percent 100)
-- Make sure "RsCustomDataGridView" is defined:
RS_CustomDataGrid()
local ItemListCtrl = dotNetObject "RsCustomDataGridView"
gRsZoneViewData.ItemListCtrl = ItemListCtrl
ItemListCtrl.dock = DockStyle_Fill
MainTable.Controls.Add ItemListCtrl 0 1
dotNet.addEventHandler ItemListCtrl "CellMouseUp" ItemList_Clicked
dotNet.addEventHandler ItemListCtrl "SelectionChanged" ItemList_SelChanged
dotNet.setLifetimeControl ItemListCtrl #dotnet
ItemListCtrl.ReadOnly = False
ItemListCtrl.SelectionMode = ItemListCtrl.SelectionMode.FullRowSelect
ItemListCtrl.AllowUserToAddRows = False
ItemListCtrl.AllowUserToDeleteRows = False
ItemListCtrl.AllowUserToOrderColumns = False
ItemListCtrl.AllowUserToResizeColumns = True
ItemListCtrl.AllowUserToResizeRows = False
ItemListCtrl.AllowDrop = False
ItemListCtrl.MultiSelect = True
ItemListCtrl.DefaultCellStyle.WrapMode = ItemListCtrl.DefaultCellStyle.WrapMode.True
ItemListCtrl.AutoSizeRowsMode = ItemListCtrl.AutoSizeRowsMode.AllCells
local textClr = (colorMan.getColor #windowText) * 255
local windowClr = (colorMan.getColor #window) * 255
ItemListCtrl.DefaultCellStyle.backColor = (dotNetClass "System.Drawing.Color").FromArgb windowClr[1] windowClr[2] windowClr[3]
ItemListCtrl.DefaultCellStyle.foreColor = (dotNetClass "System.Drawing.Color").FromArgb textClr[1] textClr[2] textClr[3]
ItemListCtrl.AutoSizeColumnsMode = ItemListCtrl.AutoSizeColumnsMode.Fill
ItemListCtrl.ColumnHeadersVisible = True
-- Add text-columns:
local listLabels = popZoneStruct.GetListLabels()
for n = 1 to listLabels.count do
(
local textCol = dotNetObject "DataGridViewTextBoxColumn"
textCol.ReadOnly = true
-- Set last column-size to fill:
textCol.AutoSizeMode = if (n == listLabels.count) then textCol.AutoSizeMode.Fill else textCol.AutoSizeMode.AllCells
local newColNum = ItemListCtrl.Columns.Add textCol
textCol.HeaderText = listLabels[newColNum + 1]
)
)
-- Set up the rest of the option-controls:
(
MainTable.RowStyles.Add (dotNetObject "RowStyle" SizeType_Absolute 30)
local OptionPanel = dotNetObject "FlowLayoutPanel"
OptionPanel.dock = DockStyle_Fill
MainTable.Controls.Add OptionPanel 0 2
-- "Draw Labels" button
(
local NewCtrl = dotNetObject "CheckBox"
NewCtrl.Text = "Draw Labels for Selected"
NewCtrl.checked = gRsZoneViewData.ViewLabels
NewCtrl.FlatStyle = NewCtrl.FlatStyle.System
NewCtrl.AutoSize = True
dotNet.addEventHandler NewCtrl "CheckedChanged" ShowLabel_Changed
dotNet.setLifetimeControl NewCtrl #dotnet
OptionPanel.Controls.Add NewCtrl
)
-- 'Wireframe' button
(
local NewCtrl = dotNetObject "CheckBox"
NewCtrl.Text = "Wireframe"
NewCtrl.checked = gRsZoneViewData.DrawWireframe
NewCtrl.FlatStyle = NewCtrl.FlatStyle.System
NewCtrl.AutoSize = True
dotNet.addEventHandler NewCtrl "CheckedChanged" Wireframe_Changed
dotNet.setLifetimeControl NewCtrl #dotnet
OptionPanel.Controls.Add NewCtrl
)
-- Label:
(
local NewCtrl = dotNetObject "Label"
NewCtrl.Text = "Show Colours:"
NewCtrl.AutoSize = True
NewCtrl.Margin = dotNetObject "Padding" 0 4 0 0
OptionPanel.Controls.Add NewCtrl
)
-- Object-colour radiobuttons
local ShowClrBtns = #()
for Item in #(dataPair Text:"PlantIdx" Val:gRsZoneViewData.ShowPlantIdxClr, dataPair Text:"Dirt" Val:gRsZoneViewData.ShowDirtClr, dataPair Text:"Area Name" Val:gRsZoneViewData.ShowAreaClr) collect
(
local NewCtrl = dotNetObject "RadioButton"
NewCtrl.Text = Item.Text
NewCtrl.Checked = Item.Val
NewCtrl.Tag = (dotNetMXSValue ShowClrBtns)
NewCtrl.AutoSize = True
dotNet.addEventHandler NewCtrl "CheckedChanged" ShowClrBtn_Changed
dotNet.setLifetimeControl NewCtrl #dotnet
OptionPanel.Controls.Add NewCtrl
append ShowClrBtns NewCtrl
)
)
)
ToolDialog.ShowModeless()
)
-- Force UI to draw:
Windows.ProcessPostedMessages()
-- Load and show data:
(
-- Load data:
SetStatusTitle "Loading Data..."
if (not LoadPopZones()) do
(
RsZoneViewFuncs.CloseTool()
return False
)
-- Add data to list:
(
SetStatusTitle "Showing List..."
local showListData = for item in gRsZoneViewData.popZonesList collect (dataPair zoneData:Item rowStrings:(Item.GetRowStrings()))
local ItemListCtrl = gRsZoneViewData.ItemListCtrl
-- Add list-rows:
for Item in ShowListData do
(
local rowIdx = ItemListCtrl.Rows.Add Item.RowStrings
local ThisRow = ItemListCtrl.Rows.Item[rowIdx]
-- Add number to row's tag, so it remembers it if reordered:
ThisRow.tag = (rowIdx + 1)
-- Link row-control to ZoneData struct:
Item.ZoneData.ListCtrlRow = ThisRow
)
)
)
-- Trigger object-generation:
if gRsZoneViewData.doObjects and (gRsZoneViewData.popZonesList.count != 0) do
(
genMissingObjs popZones:gRsZoneViewData.popZonesList
-- Set up Max callbacks:
addCallbacks()
completeRedraw()
)
SetStatusTitle ""
return OK
)
)
gRsZoneViewData = RsZoneViewData()
gRsZoneViewFuncs = RsZoneViewFuncs()
gRsZoneViewFuncs.CreateTool()