------------------------------------------------------------------------------------ -- -- File:: EditIPLCullBoxes.ms -- Description:: IPL Cull Box Management - Edit, move, enable/disable, etc. -- -- Author:: Martin Good 0.001) or (xmaxDiff > 0.001) or (yminDiff > 0.001) or (ymaxDiff > 0.001) or (zminDiff > 0.001) or (zmaxDiff > 0.001) ) then ( case CullBoxes[boxNum].marker.wirecolor of ( OffColour: CullBoxes[boxNum].marker.wirecolor = ChangedOffColour ChangedOffColour: CullBoxes[boxNum].marker.wirecolor = ChangedOffColour NewBoxColour: CullBoxes[boxNum].marker.wirecolor = NewBoxColour default: CullBoxes[boxNum].marker.wirecolor = ChangedColour ) ) else ( ResetBox.enabled = false case CullBoxes[boxNum].marker.wirecolor of ( OffColour: CullBoxes[boxNum].marker.wirecolor = OffColour ChangedOffColour: CullBoxes[boxNum].marker.wirecolor = OffColour NewBoxColour: CullBoxes[boxNum].marker.wirecolor = NewBoxColour default: CullBoxes[boxNum].marker.wirecolor = RandomColour CullBoxes[boxNum].name InitialSeed ) ) ) ) -------------------------------------------------------------------------------------------------------------------------------- fn UpdateBoxParams = ( xsize = CullBoxes[BoxList.selection].bounds.xmax - CullBoxes[BoxList.selection].bounds.xmin ysize = CullBoxes[BoxList.selection].bounds.ymax - CullBoxes[BoxList.selection].bounds.ymin zsize = CullBoxes[BoxList.selection].bounds.zmax - CullBoxes[BoxList.selection].bounds.zmin x = (CullBoxes[BoxList.selection].bounds.xmin + CullBoxes[BoxList.selection].bounds.xmax) / 2.0 y = (CullBoxes[BoxList.selection].bounds.ymin + CullBoxes[BoxList.selection].bounds.ymax) / 2.0 z = CullBoxes[BoxList.selection].bounds.zmin CullBoxes[BoxList.selection].marker.pos = [x, y, z] CullBoxes[BoxList.selection].marker.width = xsize CullBoxes[BoxList.selection].marker.length = ysize CullBoxes[BoxList.selection].marker.height = zsize XPosVal.value = CullBoxes[BoxList.selection].marker.pos.x YPosVal.value = CullBoxes[BoxList.selection].marker.pos.y ZPosVal.value = CullBoxes[BoxList.selection].marker.pos.z CheckForBoundsChange BoxList.selection SetStateWidgets BoxList.selection ) -------------------------------------------------------------------------------------------------------------------------------- fn UpdateBBox boxNum= ( XMinVal.value = CullBoxes[boxNum].bounds.xmin = CullBoxes[boxNum].marker.pos.x - (CullBoxes[boxNum].marker.width / 2.0) XMaxVal.value = CullBoxes[boxNum].bounds.xmax = CullBoxes[boxNum].marker.pos.x + (CullBoxes[boxNum].marker.width / 2.0) YMinVal.value = CullBoxes[boxNum].bounds.ymin = CullBoxes[boxNum].marker.pos.y - (CullBoxes[boxNum].marker.length / 2.0) YMaxVal.value = CullBoxes[boxNum].bounds.ymax = CullBoxes[boxNum].marker.pos.y + (CullBoxes[boxNum].marker.length / 2.0) ZMinVal.value = CullBoxes[boxNum].bounds.zmin = CullBoxes[boxNum].marker.pos.z ZMaxVal.value = CullBoxes[boxNum].bounds.zmax = CullBoxes[boxNum].marker.pos.z + CullBoxes[boxNum].marker.height XPosVal.value = CullBoxes[boxNum].marker.pos.x YPosVal.value = CullBoxes[boxNum].marker.pos.y ZPosVal.value = CullBoxes[boxNum].marker.pos.z CheckForBoundsChange boxNum SetStateWidgets boxNum ) -------------------------------------------------------------------------------------------------------------------------------- fn BuildContainerSelection = ( sharedContainers = deepCopy ContainerList.items if (MultiSelectType.selection < 3) then ( for boxnum = 1 to selection.count do ( cbox = findItem BoxList.items selection[boxnum].name if cbox != 0 then ( for index = 1 to sharedContainers.count do ( ContainerSet = findItem CullBoxes[cbox].culledNames sharedContainers[index] case MultiSelectType.selection of ( 1: ( if ContainerSet == 0 then sharedContainers[index] = " " ) 2: ( if ContainerSet != 0 then sharedContainers[index] = " " ) ) ) ) ) ) else ( boxName = MultiSelectType.selected cbox = findItem BoxList.items boxName if cbox != 0 then ( for index = 1 to sharedContainers.count do ( if (findItem CullBoxes[cbox].culledNames sharedContainers[index]) == 0 then sharedContainers[index] = " " ) ) ) sharedList = #() for index = 1 to sharedContainers.count do ( case MultiSelectType.selection of ( 1: ( if sharedContainers[index] != " " then append sharedList index ) -- Set Intersection 2: ( if sharedContainers[index] == " " then append sharedList index ) -- Set Union (inverted) default: (if sharedContainers[index] != " " then append sharedList index ) -- Individual cullbox ) ) ContainerList.selection = sharedList CulledCount.text = sharedList.count as string ) -------------------------------------------------------------------------------------------------------------------------------- fn GenerateNewName NewBoxName = ( checkBoxNames = #() if NewBoxName == "CullBox" then append checkBoxNames "CullBox" -- include default root name so new boxes always have an incremental postfix for index = 1 to CullBoxes.count do ( if (findString CullBoxes[index].name NewBoxName) == 1 then append checkBoxNames CullBoxes[index].name ) if ((checkBoxNames.count > 0) and (findItem checkBoxNames NewBoxName != 0)) then ( nameDuped = true postNum = 0 as integer while nameDuped do ( postNum += 1 nameDuped = false postStr = postNum as string postStr = replace "_New000" (8 - postStr.count) postStr.count postStr for index = 1 to checkBoxNames.count while (not nameDuped) do ( if (NewBoxName + postStr) == checkBoxNames[index] then ( nameDuped = true ) ) ) NewBoxName += postStr ) return NewBoxName ) -------------------------------------------------------------------------------------------------------------------------------- fn renameActiveBox NewName = ( if CullBoxes[BoxList.selection].name != NewName then ( callbacks.removeScripts #nodeRenamed id:#EditIPLCullBoxes nameCheck = GenerateNewName NewName format "Original = % : NewName = % -> Checked = %\n" CullBoxes[BoxList.selection].name NewName nameCheck if nameCheck != NewName then ( warningText = NewName+" : name already used.\nRename as '"+nameCheck+"' instead?" if (queryBox warningText) then ( CullBoxes[BoxList.selection].name = nameCheck ) ActiveBoxName.text = CullBoxes[BoxList.selection].marker.name = CullBoxes[BoxList.selection].name ) else ( CullBoxes[BoxList.selection].marker.name = nameCheck ) CullBoxes[BoxList.selection].name = BoxList.selected = CullBoxes[BoxList.selection].marker.name callbacks.addScript #nodeRenamed "RsEditCullBoxFiles.BoxRenameCallBack()" id:#EditIPLCullBoxes ) ) -------------------------------------------------------------------------------------------------------------------------------- fn SelectCallBack = ( deleteAllChangeHandlers id:#RsEditCullBoxesTransforms if ContainerList.enabled then ( -- Only if ContainerList is enabled == there's data loaded BoxList.enabled = true BoxFound = false BoxCount = 0 if selection.count == 1 then ( for index = 1 to CullBoxes.count do ( if selection[1].name == Cullboxes[index].name then ( BoxList.selection = index CullList.items = BuildCullList CullBoxes[index].culledNames BoxFound = true turnOnWidgets() if (CullBoxes[BoxList.selection].marker.wirecolor == ChangedColour) or (CullBoxes[BoxList.selection].marker.wirecolor == ChangedOffColour) then ( ResetBox.enabled = true ) else ( ResetBox.enabled = false ) if CullBoxes[BoxList.selection].marker.ishidden then ( ShowHideBox.caption = "Show" ) else ( ShowhideBox.caption = "Hide" ) if CullBoxes[BoxList.selection].state then ( ToggleBox.caption = "Switch Off" CullList.enabled = true ) else ( ToggleBox.caption = "Switch On" CullList.enabled = false ) XminVal.value = CullBoxes[index].bounds.xmin XmaxVal.value = CullBoxes[index].bounds.xmax YminVal.value = CullBoxes[index].bounds.ymin YmaxVal.value = CullBoxes[index].bounds.ymax ZminVal.value = CullBoxes[index].bounds.zmin ZmaxVal.value = CullBoxes[index].bounds.zmax XPosVal.value = CullBoxes[index].marker.pos.x YPosVal.value = CullBoxes[index].marker.pos.y ZPosVal.value = CullBoxes[index].marker.pos.z if RAGConnected and (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteStringWidget "Scene/IPL Cull Boxes/Find box by name" selection[1].name --RemoteConnection.WriteBoolWidget "Scene/IPL Cull Boxes/Find next" true ) ) ) /* -- More useful to keep previous multi-selection active if MultiSelectType.items.count > 2 then ( MultiSelectType.selection = 1 MultiSelectType.items = #("Common Culled Areas", "All Culled Areas") )*/ ) else ( if selection.count > 1 then ( --BoxList.enabled = false -- Build shared Culled Area list for ContainerList.items MultiSelectList = #("Common Culled Areas", "All Culled Areas") SelectedContainerList = #() for boxnum = 1 to selection.count do ( append SelectedContainerList selection[boxnum].name ) sort SelectedContainerList join MultiSelectList SelectedContainerList MultiSelectType.items = MultiSelectList BuildContainerSelection() ) ) if (ContainerList.selection.isempty) or (selection.count != 1) then ( AddContainers.enabled = false RemoveContainers.enabled = false ) else ( AddContainers.enabled = true RemoveContainers.enabled = true ) if (BoxFound == false) then --and (WidgetsOn == true) then ( turnOffWidgets() ) ) ) -------------------------------------------------------------------------------------------------------------------------------- fn BoxRenameCallBack = ( if BoxList.selection != 0 then ( renameActiveBox selection[1].name ) ) -------------------------------------------------------------------------------------------------------------------------------- fn FloatToString val = ( -- Not strictly necessary... used to retain the 6 decimal places in the original XML valString = val as string valSplit = filterstring valString "." if valSplit[2] != undefined then valSixDP = valSplit[2]+"000000" else valSixDP = "000000" valString = valSplit[1]+"."+(substring valSixDP 1 6) return valString ) -------------------------------------------------------------------------------------------------------------------------------- fn SaveCullBoxes = ( saveIPLFile = ActiveProjectPath.text + SaveCullBoxFileName.text if saveIPLFile != undefined then ( if (RsIsFileReadOnly saveIPLFile) then ( errorMsg = "File not saved !!!\n\n" + saveIPLFile + " is Read Only" messageBox errorMsg title:"File is Read Only" ) else ( local xml_io = rsta_xml_io() xml_io.new "CIplCullBoxFile" local entries_xn = rsta_xml.makeNode "entries" xml_io.root for index = 1 to CullBoxes.count do ( local item_xn = rsta_xml.makeNode "Item" entries_xn local name_xn = rsta_xml.makeNode "name" item_xn innerText:CullBoxes[index].name local aabb_xn = rsta_xml.makeNode "aabb" item_xn local min_xn = rsta_xml.makeNode "min" aabb_xn min_xn.setAttribute "x" (FloatToString CullBoxes[index].bounds.xmin) min_xn.setAttribute "y" (FloatToString CullBoxes[index].bounds.ymin) min_xn.setAttribute "z" (FloatToString CullBoxes[index].bounds.zmin) min_xn.setAttribute "w" (FloatToString CullBoxes[index].bounds.xmin) local max_xn = rsta_xml.makeNode "max" aabb_xn max_xn.setAttribute "x" (FloatToString CullBoxes[index].bounds.xmax) max_xn.setAttribute "y" (FloatToString CullBoxes[index].bounds.ymax) max_xn.setAttribute "z" (FloatToString CullBoxes[index].bounds.zmax) max_xn.setAttribute "w" (FloatToString CullBoxes[index].bounds.xmax) local cullContHashes_xn = rsta_xml.makeNode "culledContainerHashes" item_xn cullContHashes_xn.setAttribute "content" "int_array" if (not RAGConnected) then ( -- Change the OLD bounds to the new values only if not connected to RAG (ie. guaranteed to be a manual SAVE)... could move this section to Save button presed event CullBoxes[index].oldbounds = CullBoxes[index].bounds if CullBoxes[index].state then BoxColour = RandomColour CullBoxes[index].name InitialSeed else BoxColour = OffColour CullBoxes[index].marker.wirecolor = BoxColour ) -- MAKE INT ARRAY STRING ------------------------------------------------------ int_array_string = "\n" for hashindex = 1 to CullBoxes[index].culledNames.count do ( hashname = (CullBoxes[index].culledNames[hashindex]) nhash = findItem projectNames[ActiveProject.selection] hashname --format "%[%] : %, %\n" CullBoxes[index].name hashname CullBoxes[index].culledNames[hashindex] nhash -- !!! Trace for hash fuck ups if (nhash == 0) then int_array_string += CullBoxes[index].culledNames[hashindex] + "\n" else int_array_string += projectHashes[ActiveProject.selection][nhash] + "\n" ) cullContHashes_xn.InnerText = int_array_string if CullBoxes[index].state then rsta_xml.makeNode "bEnabled" item_xn attr:"value" value:"true" else rsta_xml.makeNode "bEnabled" item_xn attr:"value" value:"false" Progress.value = index * 100.0 / CullBoxes.count ) Progress.value = 0 if RAGConnected and (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/IPL Cull Boxes/Load box list" true if BoxList.selection != 0 then ( RemoteConnection.WriteStringWidget "Scene/IPL Cull Boxes/Find box by name" CullBoxes[BoxList.selection].name RemoteConnection.WriteBoolWidget "Scene/IPL Cull Boxes/Find next" true ) ) else ( xml_io.saveas saveIPLFile messageString = "Cull Boxes saved in " + SaveCullBoxFileName.text messageBox messageString title:"Edit Cull Boxes" ) ) ) ) -------------------------------------------------------------------------------------------------------------------------------- fn LoadCullBoxes = ( errorMessage = "" loadIPLFile = ActiveProjectPath.text + ReadCullBoxFileName.text --loadIPL_name print loadIPLFile if loadIPLFile != undefined then ( if (doesFileExist loadIPLFile) then ( local xml_io = rsta_xml_io xmlFile:loadIPLFile if CullBoxes.count > 0 then ( oldMarkers = #() for index = 1 to CullBoxes.count do ( if (not isDeleted CullBoxes[index].marker) then append oldMarkers CullBoxes[index].marker ) delete oldMarkers ) CullBoxes = #() CullBoxNames = #() DuplicateBoxes = #() clearselection() BoxList.selection = 0 CullList.items = #() turnOffWidgets() local items_xn_array = rsta_xml.getChildren xml_io.root name:"entries/Item" local pb_ammount = 100.0/items_xn_array.count local pb_total = 0.0 for item_xn in items_xn_array do ( -- BOX ------------------------------------------------------------------ Local boxName = (item_xn.SelectSingleNode "name").InnerText Local nextmarker = getNodeByName boxname exact:true if nextmarker == undefined then ( nextmarker = box length:4 width:4 height:4 -- Box is missing, so make a new one nextmarker.name = boxname nextmarker.pos = [0,0,0] ) local min_xn = item_xn.selectSingleNode "aabb/min" local max_xn = item_xn.selectSingleNode "aabb/max" xmax = (max_xn.getAttribute "x") as float ymax = (max_xn.getAttribute "y") as float zmax = (max_xn.getAttribute "z") as float xmin = (min_xn.getAttribute "x") as float ymin = (min_xn.getAttribute "y") as float zmin = (min_xn.getAttribute "z") as float local nextBB = BBox xmin:xmin xmax:xmax ymin:ymin ymax:ymax zmin:zmin zmax:zmax local nextOldBB = BBox xmin:xmin xmax:xmax ymin:ymin ymax:ymax zmin:zmin zmax:zmax local xsize = xmax - xmin local ysize = ymax - ymin local zsize = zmax - zmin nextmarker.width = xsize nextmarker.length = ysize nextmarker.height = zsize local xpos = (xmax + xmin) / 2.0 local ypos = (ymax + ymin) / 2.0 local zpos = zmin nextmarker.pos = [xpos, ypos, zpos] nextmarker.rotation = (quat 0 0 0 1) nextmarker.scale = [1,1,1] local boxon = rsta_xml.get_bool (item_xn.selectSingleNode "bEnabled") if (boxon) then nextmarker.wirecolor = RandomColour nextmarker.name InitialSeed else nextmarker.wirecolor = OffColour -- CULL HASH -------------------------------------------------------------------- local cnamelist = #() local hash_string = (item_xn.selectSingleNode "culledContainerHashes").InnerText local hash_array = filterString hash_string "\n " for hash in hash_array do ( cname = hash FindIndex = findItem projectHashes[ActiveProject.selection] cname if FindIndex != 0 then ( cname = projectNames[ActiveProject.selection][FindIndex] ) append cnamelist cname ) -- IPLCULL BOX -------------------------------------------------------------------- local nextbox = IPLCullBox name:boxname bounds:nextBB oldbounds:nextOldBB culledNames:cnamelist state:boxon marker:nextmarker append CullBoxes nextbox append CullBoxNames boxname Progress.value = (pb_total + pb_ammount) as integer ) ItemRead = true BoxList.items = CullBoxNames SaveCullBoxFile.enabled = true ChangeSaveCullBoxFile.enabled = true SaveCullBoxFileName.enabled = true ContainerList.enabled = true HashDump.enabled = true CleanBoxes.enabled = true CleanType.enabled = true RAGConnect.enabled = true UpdateAllBoxes.enabled = true ShowAll.enabled = true --if RAGConnected then UpdateChanges.enabled = true CreateBox.enabled = true if (RAGConnected and RemoteConnection.IsConnected()) do SaveCullBoxes() ) else errorMessage += loadIPLFile = " doesn't exist \n" ) else errorMessage += "loadIPLFile is undefined\n" -- SHOW ERROR MESSAGE if (errorMessage == "") then SaveCullBoxFile.enabled = true else messageBox errorMessage title:"Edit Cull Boxes" ) -------------------------------------------------------------------------------------------------------------------------------- fn RemoteConnectionUpdate = ( if RAGConnected and (RemoteConnection.IsConnected()) then ( SaveCullBoxes() if BoxList.selection != 0 then ( RemoteConnection.WriteStringWidget "Scene/IPL Cull Boxes/Find box by name" CullBoxes[BoxList.selection].name RemoteConnection.WriteBoolWidget "Scene/IPL Cull Boxes/Find next" true ) ) else ( if RAGConnected then ( messageBox "Connection To RAG Lost\n\nIf the game is still running, try 'Launch RAG UI', and hit 'Connect' again." RAGConnected = false RAGConnect.caption = "Connect" CamXSlider.enabled = false CamYSlider.enabled = false CamZSlider.enabled = false CamOffset.enabled = false --UpdateChanges.enabled = false SelectAtCamera.enabled = false ) ) ) -------------------------------------------------------------------------------------------------------------------------------- -- EVENTS -------------------------------------------------------------------------------------------------------------------------------- on ContainerList selectionEnd do ( if (ContainerList.selection.isempty) or (selection.count != 1) then ( AddContainers.enabled = false RemoveContainers.enabled = false ) else ( AddContainers.enabled = true RemoveContainers.enabled = true ) ) -------------------------------------------------------------------------------------------------------------------------------- on AddContainers pressed do ( if BoxList.selection != 0 then ( previousPadState = PadCulled.state PadCulled.state = true CBoxList = BuildCullList CullBoxes[BoxList.selection].culledNames for index = 1 to ContainerList.selection.count do ( if ContainerList.selection[index] then ( CBoxList[index] = ContainerList.items[index] ) ) --format "\n\n" PadCulled.state = false CullBoxes[BoxList.selection].culledNames = BuildCullList CBoxList PadCulled.state = previousPadState if PadCulled.state then CullList.items = CBoxList else CullList.items = CullBoxes[BoxList.selection].culledNames RemoteConnectionUpdate() ) ) -------------------------------------------------------------------------------------------------------------------------------- on RemoveContainers pressed do ( if BoxList.selection != 0 then ( for index = 1 to ContainerList.selection.count do ( if ContainerList.selection[index] then ( FindIndex = findItem CullBoxes[BoxList.selection].culledNames ContainerList.items[index] if FindIndex != 0 then deleteItem CullBoxes[BoxList.selection].culledNames FindIndex ) ) CullList.items = BuildCullList CullBoxes[BoxList.selection].culledNames RemoteConnectionUpdate() ) ) -------------------------------------------------------------------------------------------------------------------------------- on SelectCulled pressed do ( if BoxList.selection != 0 then ( previousPadState = PadCulled.state PadCulled.state = true CBoxList = BuildCullList CullBoxes[BoxList.selection].culledNames sharedList = #() sharedCount = 0 MaxContainerIndex = ContainerList.items.count if CBoxList.count < MaxContainerIndex then MaxContainerIndex = CBoxList.count for index = 1 to MaxContainerIndex do ( if CBoxList[index] != " " then ( sharedCount += 1 append sharedList index ) ) ContainerList.selection = sharedList CulledCount.text = sharedCount as string PadCulled.state = previousPadState ) ) -------------------------------------------------------------------------------------------------------------------------------- on MultiSelectType selected Arg do ( BuildContainerSelection() ) -------------------------------------------------------------------------------------------------------------------------------- on CleanType selected Arg do ( case Arg of ( 1: (CleanBoxes.text = "Clean Box") default: (CleanBoxes.text = "Clean Boxes") ) ) -------------------------------------------------------------------------------------------------------------------------------- on CleanBoxes pressed do ( fn CleanBox index = ( cpadnamelist = deepcopy ContainerList.items cindex =1 listLength = cpadnamelist.count while cindex <= listLength do ( FindIndex = findItem CullBoxes[index].culledNames cpadnamelist[cindex] if FindIndex == 0 then ( if PadCulled.state then ( cpadnamelist[cindex] = " " cindex += 1 ) else ( deleteItem cpadnamelist cindex listLength -= 1 ) ) else cindex+= 1 ) CullBoxes[index].culledNames = cpadnamelist ) case CleanType.selection of ( 1: ( if BoxList.selection !=0 then CleanBox BoxList.selection ) default: ( for index = 1 to CullBoxes.count do ( CleanBox index Progress.value = index * 100.0 / CullBoxes.count ) Progress.value = 0 ) ) if BoxList.selection != 0 then CullList.items = CullBoxes[BoxList.selection].culledNames ) -------------------------------------------------------------------------------------------------------------------------------- on SelectAtCamera pressed do ( if RAGConnected and (RemoteConnection.IsConnected()) then ( if (RemoteConnection.ReadStringWidget "Camera/Debug director/Active mode" == "Free") then ( camXPos = RemoteConnection.ReadFloatWidget "Camera/Free camera/Position X" camYPos = RemoteConnection.ReadFloatWidget "Camera/Free camera/Position Y" camZPos = RemoteConnection.ReadFloatWidget "Camera/Free camera/Position Z" CamInBoxes = #() format "[%,%,%] : " camXPos camYPos camZPos for index = 1 to CullBoxes.count do ( if ((camXPos > CullBoxes[index].bounds.xmin) and (camXPos < CullBoxes[index].bounds.xmax)) and ((camYPos > CullBoxes[index].bounds.ymin) and (camYPos < CullBoxes[index].bounds.ymax)) and ((camZPos > CullBoxes[index].bounds.zmin) and (camZPos < CullBoxes[index].bounds.zmax)) then ( if CullBoxes[index].state then append CamInBoxes CullBoxes[index].marker format "% " CullBoxes[index].name ) ) format "\n" select CamInBoxes ) else ( messageBox "Game isn't in Free camera mode...\nYou need to switch to get the camera coords." ) ) ) -------------------------------------------------------------------------------------------------------------------------------- fn DoesIPLFileExist = ( if (doesFileExist (ActiveProjectPath.text + ReadCullBoxFileName.text)) then LoadCullBoxFile.enabled = true else LoadCullBoxFile.enabled = false ) -------------------------------------------------------------------------------------------------------------------------------- on ActiveProject selected Arg do ( if ActiveGen.state then ActiveProjectPath.text = NGProjectPath[Arg] else ActiveProjectPath.text = projectPath[Arg] ContainerList.items = projectNames[Arg] DoesIPLFileExist() ) -------------------------------------------------------------------------------------------------------------------------------- on ActiveGen changed Arg do ( if Arg then ActiveProjectPath.text = NGProjectPath[ActiveProject.selection] else ActiveProjectPath.text = projectPath[ActiveProject.selection] DoesIPLFileExist() ) -------------------------------------------------------------------------------------------------------------------------------- on LoadCullBoxFile pressed do LoadCullBoxes() -------------------------------------------------------------------------------------------------------------------------------- on ChangeLoadCullBoxFile pressed do ( loadIPL_name = ActiveProjectPath.text --+ ReadCullBoxFileName.text loadIPLFile = getOpenFileName caption:"Select IPL Cull Box file to load." filename:loadIPL_name types:"meta (*.meta)|*.meta|All Files (*.*)|*.*|" if (doesFileExist loadIPLFile) then ReadCullBoxFileName.text = ((getFilenameFile loadIPLFile) + (getFilenameType loadIPLFile)) ) -------------------------------------------------------------------------------------------------------------------------------- on ReadCullBoxFileName changed Arg do DoesIPLFileExist() -------------------------------------------------------------------------------------------------------------------------------- on ReadCullBoxFileName entered Arg do if LoadCullBoxFile.enabled then LoadCullBoxes() -------------------------------------------------------------------------------------------------------------------------------- on SaveCullBoxFile pressed do ( saveIPL_name = ActiveProjectPath.text + SAveCullBoxFileName.text if (RsIsFileReadOnly saveIPL_name) then ( errorMsg = "Meta file not saved !!!\n\n"+saveIPL_name+" is Read Only" messageBox errorMsg title:"File is Read Only" ) else ( SaveCullBoxes() ) ) -------------------------------------------------------------------------------------------------------------------------------- on ChangeSaveCullBoxFile pressed do ( saveIPL_name = ActiveProjectPath.text + "mapdatacullboxes.meta" saveIPLFile = getSaveFileName caption:"Select IPL Cull Box file to save." filename:saveIPL_name types:"meta (*.meta)|*.meta|All Files (*.*)|*.*|" if (saveIPLFile != undefined) then SaveCullBoxFileName.text = ((getFilenameFile saveIPLFile) + (getFilenameType saveIPLFile)) ) -------------------------------------------------------------------------------------------------------------------------------- on SaveCullBoxFileName entered Arg do ( if Arg != "" then ( saveIPL_name = ActiveProjectPath.text + Arg if (RsIsFileReadOnly saveIPL_name) then ( errorMsg = "Can't save meta file !!!\n\n"+saveIPL_name+" is Read Only" messageBox errorMsg title:"File is Read Only" ) else ( saveMsg = "Save Cull Boxes?\n\n"+saveIPL_name if (queryBox saveMsg) then SaveCullBoxes() ) ) ) -------------------------------------------------------------------------------------------------------------------------------- on BoxList selected Arg do ( -- Assume that the lists are in synch... Arg should be the correct index... CullList.items = CullBoxes[Arg].culledNames if isDeleted CullBoxes[Arg].marker then ( newmarker = box length:4 width:4 height:4 name:CullBoxes[Arg].name newmarker.pos = [0,0,0] newmarker.width = 200.0 ; newmarker.length = 200.0 ; newmarker.height = 200.0 BoxColour = RandomColour newmarker.name InitialSeed newmarker.wirecolor = BoxColour CullBoxes[Arg].marker = newmarker UpdateBoxParams() ) select CullBoxes[Arg].marker ) -------------------------------------------------------------------------------------------------------------------------------- on PadCulled changed Arg do CullList.items = BuildCullList CullList.items -------------------------------------------------------------------------------------------------------------------------------- on XMinVal changed Arg do ( if BoxList.selection != 0 then ( ResetBox.enabled = true CullBoxes[BoxList.selection].bounds.xmin = Arg UpdateBoxParams() ) ) -------------------------------------------------------------------------------------------------------------------------------- on XMinVal entered do RemoteConnectionUpdate() -------------------------------------------------------------------------------------------------------------------------------- on XMaxVal changed Arg do ( if BoxList.selection != 0 then ( ResetBox.enabled = true CullBoxes[BoxList.selection].bounds.xmax = Arg UpdateBoxParams() ) ) -------------------------------------------------------------------------------------------------------------------------------- on XMaxVal entered do RemoteConnectionUpdate() -------------------------------------------------------------------------------------------------------------------------------- on YMinVal changed Arg do ( if BoxList.selection != 0 then ( ResetBox.enabled = true CullBoxes[BoxList.selection].bounds.ymin = Arg UpdateBoxParams() ) ) -------------------------------------------------------------------------------------------------------------------------------- on YMinVal entered do ( RemoteConnectionUpdate() ) -------------------------------------------------------------------------------------------------------------------------------- on YMaxVal changed Arg do ( if BoxList.selection != 0 then ( ResetBox.enabled = true CullBoxes[BoxList.selection].bounds.ymax = Arg UpdateBoxParams() ) ) -------------------------------------------------------------------------------------------------------------------------------- on YMaxVal entered do RemoteConnectionUpdate() -------------------------------------------------------------------------------------------------------------------------------- on ZMinVal changed Arg do ( if BoxList.selection != 0 then ( ResetBox.enabled = true CullBoxes[BoxList.selection].bounds.zmin = Arg UpdateBoxParams() ) ) -------------------------------------------------------------------------------------------------------------------------------- on ZMinVal entered do RemoteConnectionUpdate() -------------------------------------------------------------------------------------------------------------------------------- on ZMaxVal changed Arg do ( if BoxList.selection != 0 then ( ResetBox.enabled = true CullBoxes[BoxList.selection].bounds.zmax = Arg UpdateBoxParams() ) ) -------------------------------------------------------------------------------------------------------------------------------- on ZMaxVal entered do RemoteConnectionUpdate() -------------------------------------------------------------------------------------------------------------------------------- on XPosVal changed Arg do ( if BoxList.selection != 0 then ( ResetBox.enabled = true CullBoxes[BoxList.selection].marker.pos.x = Arg UpdateBBox BoxList.selection ) ) -------------------------------------------------------------------------------------------------------------------------------- on XPosVal entered do RemoteConnectionUpdate() -------------------------------------------------------------------------------------------------------------------------------- on YPosVal changed Arg do ( if BoxList.selection != 0 then ( ResetBox.enabled = true CullBoxes[BoxList.selection].marker.pos.y = Arg UpdateBBox BoxList.selection ) ) -------------------------------------------------------------------------------------------------------------------------------- on YPosVal entered do RemoteConnectionUpdate() -------------------------------------------------------------------------------------------------------------------------------- on ZPosVal changed Arg do ( if BoxList.selection != 0 then ( ResetBox.enabled = true CullBoxes[BoxList.selection].marker.pos.z = Arg UpdateBBox BoxList.selection ) ) -------------------------------------------------------------------------------------------------------------------------------- on ZPosVal entered do RemoteConnectionUpdate() -------------------------------------------------------------------------------------------------------------------------------- on XRelVal entered Val do ( if BoxList.selection != 0 then ( XAdd = Val as float if XAdd != undefined then ( ResetBox.enabled = true CullBoxes[BoxList.selection].marker.pos.x += XAdd UpdateBBox BoxList.selection RemoteConnectionUpdate() ) ) ) -------------------------------------------------------------------------------------------------------------------------------- on YRelVal entered Val do ( if BoxList.selection != 0 then ( YAdd = Val as float if YAdd != undefined then ( ResetBox.enabled = true CullBoxes[BoxList.selection].marker.pos.y += YAdd UpdateBBox BoxList.selection RemoteConnectionUpdate() ) ) ) -------------------------------------------------------------------------------------------------------------------------------- on ZRelVal entered Val do ( if BoxList.selection != 0 then ( ZAdd = Val as float if ZAdd != undefined then ( ResetBox.enabled = true CullBoxes[BoxList.selection].marker.pos.z += ZAdd UpdateBBox BoxList.selection RemoteConnectionUpdate() ) ) ) -------------------------------------------------------------------------------------------------------------------------------- on ResetBox pressed do ( ResetBox.enabled = false CullBoxes[BoxList.selection].bounds.xmin = CullBoxes[BoxList.selection].oldbounds.xmin CullBoxes[BoxList.selection].bounds.xmax = CullBoxes[BoxList.selection].oldbounds.xmax CullBoxes[BoxList.selection].bounds.ymin = CullBoxes[BoxList.selection].oldbounds.ymin CullBoxes[BoxList.selection].bounds.ymax = CullBoxes[BoxList.selection].oldbounds.ymax CullBoxes[BoxList.selection].bounds.zmin = CullBoxes[BoxList.selection].oldbounds.zmin CullBoxes[BoxList.selection].bounds.zmax = CullBoxes[BoxList.selection].oldbounds.zmax case CullBoxes[BoxList.selection].marker.wirecolor of ( ChangedOffColour: CullBoxes[BoxList.selection].marker.wirecolor = OffColour ChangedColour: CullBoxes[BoxList.selection].marker.wirecolor = RandomColour CullBoxes[BoxList.selection].name InitialSeed ) XminVal.value = CullBoxes[BoxList.selection].bounds.xmin XmaxVal.value = CullBoxes[BoxList.selection].bounds.xmax YminVal.value = CullBoxes[BoxList.selection].bounds.ymin YmaxVal.value = CullBoxes[BoxList.selection].bounds.ymax ZminVal.value = CullBoxes[BoxList.selection].bounds.zmin ZmaxVal.value = CullBoxes[BoxList.selection].bounds.zmax UpdateBoxParams() ) -------------------------------------------------------------------------------------------------------------------------------- on UpdateAllBoxes pressed do ( previousSelection = BoxList.selection BoxList.selection = 0 for index = 1 to BoxList.items.count do ( ResetBox.enabled = true UpdateBBox index Progress.value = index * 100.0 / BoxList.items.count ) if previousSelection != 0 then ( BoxList.selection = previousSelection SetStateWidgets BoxList.selection ) Progress.value = 0 ) -------------------------------------------------------------------------------------------------------------------------------- on ActiveBoxColour clicked Arg do ( if BoxList.selection != 0 then ( boxesByColour = #() for index = 1 to BoxList.items.count do ( if CullBoxes[index].marker.wirecolor == ActiveBoxColour.color then ( nextbox = CullBoxes[index].marker append boxesByColour nextbox ) ) select boxesByColour ) ) -------------------------------------------------------------------------------------------------------------------------------- on ActiveBoxName entered Arg do renameActiveBox Arg -------------------------------------------------------------------------------------------------------------------------------- on ToggleBox pressed do ( if ToggleBox.caption == "Switch Off" then ( CullBoxes[BoxList.selection].state = false CullList.enabled = false ToggleBox.caption = "Switch On" ) else ( CullBoxes[BoxList.selection].state = true CullList.enabled = true ToggleBox.caption = "Switch Off" ) case CullBoxes[BoxList.selection].marker.wirecolor of ( OffColour: CullBoxes[BoxList.selection].marker.wirecolor = RandomColour CullBoxes[BoxList.selection].name InitialSeed ChangedOffColour: CullBoxes[BoxList.selection].marker.wirecolor = ChangedColour ChangedColour: CullBoxes[BoxList.selection].marker.wirecolor = ChangedOffColour NewBoxColour: CullBoxes[BoxList.selection].marker.wirecolor = NewBoxColour default: CullBoxes[BoxList.selection].marker.wirecolor = OffColour ) SetStateWidgets BoxList.selection if RAGConnected and (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/IPL Cull Boxes/Toggle box enabled" true ) ) -------------------------------------------------------------------------------------------------------------------------------- on ShowHideBox pressed do ( if CullBoxes[BoxList.selection].marker.ishidden then ( CullBoxes[BoxList.selection].marker.ishidden = false ShowHideBox.caption = "Hide" ) else ( CullBoxes[BoxList.selection].marker.ishidden = true ShowHideBox.caption = "Show" ) ) -------------------------------------------------------------------------------------------------------------------------------- on ShowAll pressed do ( for index = 1 to CullBoxes.count do ( CullBoxes[index].marker.ishidden = false ) ) -------------------------------------------------------------------------------------------------------------------------------- fn MakeNewCullBox = ( newmarker = box length:4 width:4 height:4 if BoxList.selection != 0 then ( newname = CullBoxes[BoxList.selection].marker.name xmin = CullBoxes[BoxList.selection].bounds.xmin ; xmax = CullBoxes[BoxList.selection].bounds.xmax ymin = CullBoxes[BoxList.selection].bounds.ymin ; ymax = CullBoxes[BoxList.selection].bounds.ymax zmin = CullBoxes[BoxList.selection].bounds.zmin ; zmax = CullBoxes[BoxList.selection].bounds.zmax newBB = BBox xmin:xmin xmax:xmax ymin:ymin ymax:ymax zmin:zmin zmax:zmax newOldBB = BBox xmin:xmin xmax:xmax ymin:ymin ymax:ymax zmin:zmin zmax:zmax newmarker.pos = CullBoxes[BoxList.selection].marker.pos newmarker.width = CullBoxes[BoxList.selection].marker.width newmarker.length = CullBoxes[BoxList.selection].marker.length newmarker.height = CullBoxes[BoxList.selection].marker.height cnamelist = CullBoxes[BoxList.selection].culledNames -- #() ) else ( newname = "CullBox_New001" xmax = 100.0 ; ymax = 100.0 ; zmax = 50.0 xmin = -100.0 ; ymin = -100.0 ; zmin = 0.0 newBB = BBox xmin:xmin xmax:xmax ymin:ymin ymax:ymax zmin:zmin zmax:zmax newOldBB = BBox xmin:xmin xmax:xmax ymin:ymin ymax:ymax zmin:zmin zmax:zmax newmarker.pos = [0.0, 0.0, 0.0] newmarker.width = 200.0 ; newmarker.length = 200.0 ; newmarker.height = 50.0 cnamelist = #() ) checkBoxNames = #() -- strip existing "_NewXXX" postfix if (newname.count > 6) then ( if (substring newname (newname.count - 6) 4) == "_New" then newname = substring newname 1 (newname.count - 7) ) newname = GenerateNewName newname newmarker.name = newname --BoxColour = RandomColour newmarker.name InitialSeed newmarker.wirecolor = NewBoxColour newbox = IPLCullBox name:newname bounds:newBB oldbounds:newOldBB culledNames:cnamelist state:true marker:newmarker CullBoxNames = deepCopy BoxList.items append CullBoxes newbox append CullBoxNames newname BoxList.items = CullBoxNames BoxList.selection = CullBoxNames.count -- should be the new box --format "New box : %\n" newbox select newmarker ) -------------------------------------------------------------------------------------------------------------------------------- on CreateBox pressed do ( MakeNewCullBox() RemoteConnectionUpdate() ) -------------------------------------------------------------------------------------------------------------------------------- on RAGConnect pressed do ( if RAGConnected then ( RAGConnected = false RAGConnect.caption = "Connect" RemoteConnection.WriteBoolWidget "Scene/IPL Cull Boxes/Draw boxes" false RemoteConnection.WriteBoolWidget "Scene/IPL Cull Boxes/Show boxes at camera pos" false CamXSlider.enabled = false CamYSlider.enabled = false CamZSlider.enabled = false CamOffset.enabled = false --UpdateChanges.enabled = false SelectAtCamera.enabled = false ShowCurrentlyCulled.enabled = false CullAtCameraPos.enabled = false ) else ( messageText = "This will overwrite \n"+ActiveProjectPath.text+"mapdatacullboxes.meta"+ "\n\nDo you still want to procede?" if (queryBox messageText title:"Connect To Game") then ( --PreviousSelection = BoxList.selection BoxList.selection = 0 -- Selected boxes causes problems if meta file out of synch RemoteConnection.Connect() if ( RemoteConnection.IsConnected() ) then ( SaveIPLFileName = "mapdatacullboxes.meta" RAGConnected = true RAGConnect.caption = "CONNECTED" SelectAtCamera.enabled = true ShowCurrentlyCulled.enabled = true CullAtCameraPos.enabled = true RemoteConnection.WriteBoolWidget "Scene/Create Scene widgets" true RemoteConnection.WriteBoolWidget "Camera/Create camera widgets" true --RemoteConnection.WriteStringWidget "Camera/Debug director/Active mode" "Free" -- This plain doesn't work... though it looks like it's connected to the debug cam switch SaveCullBoxes() --BoxList.selection = PreviousSelection RemoteConnection.SendSyncCommand() RemoteConnection.WriteBoolWidget "Scene/IPL Cull Boxes/Draw boxes" true --RemoteConnection.WriteBoolWidget "Scene/IPL Cull Boxes/Show currently culled" true -- annoying, have added toggle button RemoteConnection.WriteBoolWidget "Scene/IPL Cull Boxes/Show boxes at camera pos" CullAtCameraPos.state --RemoteConnection.SendSyncCommand() /*if BoxList.selection != 0 then ( CamXSlider.enabled = true CamYSlider.enabled = true CamZSlider.enabled = true CamOffset.enabled = true UpdateChanges.enabled = true )*/ ) else ( messageBox "Couldn't connect to game.\nMake sure it's running..." beep:true ) ) ) ) -------------------------------------------------------------------------------------------------------------------------------- on CullAtCameraPos changed Arg do ( if RAGConnected and (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/IPL Cull Boxes/Show boxes at camera pos" Arg ) ) -------------------------------------------------------------------------------------------------------------------------------- on ShowCurrentlyCulled changed Arg do ( if RAGConnected and (RemoteConnection.IsConnected()) then ( RemoteConnection.WriteBoolWidget "Scene/IPL Cull Boxes/Show currently culled" Arg ) ) -------------------------------------------------------------------------------------------------------------------------------- fn CameraWarp = ( warpX = CullBoxes[BoxList.selection].bounds.xmin + (((CullBoxes[BoxList.selection].bounds.xmax - CullBoxes[BoxList.selection].bounds.xmin) + (CamOffset.value * 2)) * CamXSlider.value) warpY = CullBoxes[BoxList.selection].bounds.ymin + (((CullBoxes[BoxList.selection].bounds.ymax - CullBoxes[BoxList.selection].bounds.ymin) + (CamOffset.value * 2)) * CamYSlider.value) warpZ = CullBoxes[BoxList.selection].bounds.zmin + (((CullBoxes[BoxList.selection].bounds.zmax - CullBoxes[BoxList.selection].bounds.zmin) + (CamOffset.value * 2)) * CamZSlider.value) if RAGConnected and (RemoteConnection.IsConnected()) then ( ::RsRagFuncs.setGameDebugCamPos [warpX, warpY, warpZ] ) ) -------------------------------------------------------------------------------------------------------------------------------- on CamXSlider changed Arg do ( if CamYSlider.value < 0.5 then CamYSlider.value = 0.0 else CamYSlider.value = 1.0 if CamZSlider.value < 0.5 then CamZSlider.value = 0.0 else CamZSlider.value = 1.0 CameraWarp() ) -------------------------------------------------------------------------------------------------------------------------------- on CamYSlider changed Arg do ( if CamXSlider.value < 0.5 then CamXSlider.value = 0.0 else CamXSlider.value = 1.0 if CamZSlider.value < 0.5 then CamZSlider.value = 0.0 else CamZSlider.value = 1.0 CameraWarp() ) -------------------------------------------------------------------------------------------------------------------------------- on CamZSlider changed Arg do ( if CamXSlider.value < 0.5 then CamXSlider.value = 0.0 else CamXSlider.value = 1.0 if CamYSlider.value < 0.5 then CamYSlider.value = 0.0 else CamYSlider.value = 1.0 CameraWarp() ) -------------------------------------------------------------------------------------------------------------------------------- on CamOffset changed Arg do CameraWarp() -------------------------------------------------------------------------------------------------------------------------------- on DeleteBox pressed do ( -- Maybe do this by wirecolour... black for deleted.. so it can be undeleted again... -- One for another day... KillBox = BoxList.selection if KillBox != 0 then ( newBoxList = deepcopy BoxList.items deleteItem newBoxList KillBox delete CullBoxes[KillBox].marker deleteItem CullBoxes KillBox BoxList.items = newBoxList select CullBoxes[KillBox - 1].marker remoteConnectionUpdate() ) else ( messageBox "Pick a box in the Cull Boxes list to the right." ) ) -------------------------------------------------------------------------------------------------------------------------------- --- Diagnostic/Maintenance events --- on Diagnosis pressed do ( if BoxList.selection != 0 then ( format "Name : %, Active : %,\nBounds : %,\nOldBounds : %,\nCulled : %\n\n" CullBoxes[BoxList.selection].name CullBoxes[BoxList.selection].state CullBoxes[BoxList.selection].bounds CullBoxes[BoxList.selection].oldbounds CullBoxes[BoxList.selection].culledNames --format "Container List : %\n" ContainerList.selection ) ) -------------------------------------------------------------------------------------------------------------------------------- on HashDump pressed do ( saveHash_name = ActiveProjectPath.text + "HashDump.txt" messageText = "USE WITH CAUTION\n\nThis dumps all unknown container hashes to \n"+saveHash_name+"\n\nand adds a cullbox for every unknown area (potentailly 100s of spurious boxes) so I can maintain the project hash tables.\n\nAre you sure you want to procede?" if (queryBox messageText title:"Dump Hash Table" beep:true) then ( messageText = "Add a cullbox for each unknown container hash?\nPotentially adds 100s of spurious boxes for maintaining the project hash tables." if RAGConnected then messageText += "Will overwrite the meta file!!!\n" boxDump = queryBox messageText title:"Add Unknown Hash Cull Boxes" output_file = createfile saveHash_name KnownBoxNames = deepCopy ContainerList.items UnknownHashes = #() newName = "" projectName = case ActiveProject.selection of ( 1: "V" 2: "Liberty" default: "Unknown" ) NumBoxes = CullBoxes.count for index = 1 to NumBoxes do ( if CullBoxes[index].culledNames.count > 0 then ( for cindex = 1 to CullBoxes[index].culledNames.count do ( newName = CullBoxes[index].culledNames[cindex] debugName = substituteString CullBoxes[index].name "New Box_" "" found = findItem KnownBoxNames newName if found == 0 then ( append KnownBoxNames newName nextline = "\t\tappend "+projectName+"Names \""+ debugName+"\" ; append "+projectName+"Hashes \""+newName+"\"\n" format nextline to:output_file if boxDump then ( newmarker = box length:4 width:4 height:4 name:newName xmax = 100.0 ; ymax = 100.0 ; zmax = 50.0 xmin = -100.0 ; ymin = -100.0 ; zmin = 0.0 newBB = BBox xmin:xmin xmax:xmax ymin:ymin ymax:ymax zmin:zmin zmax:zmax newOldBB = BBox xmin:xmin xmax:xmax ymin:ymin ymax:ymax zmin:zmin zmax:zmax newmarker.pos = [0.0, 0.0, 0.0] newmarker.width = 200.0 ; newmarker.length = 200.0 ; newmarker.height = 50.0 BoxColour = RandomColour newmarker.name InitialSeed newmarker.wirecolor = BoxColour newbox = IPLCullBox name:newName bounds:newBB oldbounds:newOldBB culledNames:#(newName) state:true marker:newmarker append CullBoxes newbox ) if boxDump then ( append UnknownHashes newName ) ) ) ) Progress.value = index * 100.0 / CullBoxes.count ) if boxDump and (numBoxes < CullBoxes.count) then ( newBoxList = deepcopy BoxList.items for index = (BoxList.items.count + 1) to CullBoxes.count do ( append newBoxList CullBoxes[index].name ) BoxList.items = newBoxList ContainerList.items = KnownBoxNames RemoteConnectionUpdate() ) Progress.value = 0 close output_file ) ) -------------------------------------------------------------------------------------------------------------------------------- on RsEditCullBoxFiles open do ( banner.setup() -- CALL BACKS ----------------------------------------------------------------------------------------------- callbacks.addScript #selectionSetChanged "RsEditCullBoxFiles.SelectCallBack()" id:#EditIPLCullBoxes callbacks.addScript #nodeRenamed "RsEditCullBoxFiles.BoxRenameCallBack()" id:#EditIPLCullBoxes -- LOAD IN DATA --------------------------------------------------------------------------------------------- LibertyNames = getINISetting iniFile "Liberty" ContainerList.items = LibertyNames for n in LibertyNames do append LibertyHashes (getINISetting iniFile "Liberty" n) VNames = getINISetting iniFile "GTAV" for n in VNames do append VHashes (getINISetting iniFile "GTAV" n) projectNames =#(VNames, LibertyNames) projectHashes =#(VHashes, LibertyHashes) ) -------------------------------------------------------------------------------------------------------------------------------- on RsEditCullBoxFiles close do ( callbacks.removeScripts id:#EditIPLCullBoxes ) ) CreateDialog RsEditCullBoxFiles width:476 style:#(#style_titlebar, #style_border, #style_sysmenu,#style_toolwindow)