-- -- File:: rockstar/helpers/boundmaterialtoggle.ms -- Description:: Tool for setting flags on RexBound materials. ----------------------------------------------------------------------------- -- HISTORY -- -- 11/1/10 -- by Marissa Warner-Wu -- Cleaning up and making a few small fixes. -- ----------------------------------------------------------------------------- ----------------------------------------------------------------------------- -- Uses ----------------------------------------------------------------------------- filein "rockstar/helpers/boundroom.ms" ----------------------------------------------------------------------------- -- Rollout ----------------------------------------------------------------------------- rollout RsNonClimbRollout "Set Bound Materials" ( struct FlagMap (name, value) struct FaceMaterialMap (materialidx, faceindices=#()) local flagList = #((FlagMap name:"Stairs" value:1), (FlagMap name:"Non Climable" value:2), (FlagMap name:"See Through" value:4), (FlagMap name:"Shoot Through" value:8), (FlagMap name:"Doesn't Prov Cover" value:16), (FlagMap name:"Path" value:32), (FlagMap name:"Non Camera Collide" value:64), (FlagMap name:"No Network Spawn" value:16384)) --//////////////////////////////////////////////////////////// -- interface --//////////////////////////////////////////////////////////// hyperlink lnkHelp "Help?" address:"https://devstar.rockstargames.com/wiki/index.php/Bound_Material_Toggle" align:#right color:(color 0 0 255) hoverColor:(color 0 0 255) visitedColor:(color 0 0 255) button btnCol2Mesh "Collision to mesh" button btnMesh2Col "Mesh to Collision" dropdownlist lstFlags checkbox chkSetPedPop "Set Ped Density" spinner spnPedDensity range:[0,7,0] type:#integer enabled:false align:#left button btnSetFacesToSelBoundMat "Set Selected Faces" button btnSetWholeMeshToSelBoundMat "Set Whole Mesh" button btnUnsetFacesToSelBoundMat "Unset Selected Faces" button btnUnsetWholeMeshToSelBoundMat "Unset Whole Mesh" --//////////////////////////////////////////////////////////// -- functions --//////////////////////////////////////////////////////////// ---------------------------------------------------------------------------------------- -- Function for toggling on/off the passed in flag ---------------------------------------------------------------------------------------- fn ToggleWholeMeshSubMatsToFlag inFlag appendFlags = ( editMesh = selection as array for meshobj in editMesh do ( mat = meshobj.material mapList = #() RsMatGetMapIdsUsedOnObjectWithCount meshobj mapList if mapList.count==1 and mapList[1]==-1 then ( messagebox "Convert to Mesh first with the button above." continue ) for mapId in maplist do ( -- Toggle the passed in flag depending on whether we're setting or unsetting if appendFlags == true then collflags = inFlag else collflags = 0 -- Retain existing flags for flagObj in flagList do ( if flagObj.value != inFlag then ( local currentFlags = RexGetCollisionFlags mat.materiallist[mapId] if undefined==currentFlags or (bit.and currentFlags flagObj.value) == flagObj.value then ( collflags = collflags + flagObj.value ) ) ) print ("succeeded: flags="+(collflags as string)+", "+(RexSetCollisionFlags mat.materiallist[mapId] collflags) as string) if chkSetPedPop.checked == true then RexSetPopDensity mat.materiallist[mapId] (spnPedDensity.value as integer) ) ) ) fn NeedsNewMaterial appendBool inflag currentSubMat = ( if bit.and (RexGetCollisionFlags currentSubMat) inFlag != inFlag and appendBool == true then return true else if bit.and (RexGetCollisionFlags currentSubMat) inFlag == inFlag and appendBool == false then return true else return false ) ---------------------------------------------------------------------------------------- -- Function for toggling on/off the passed in flag for selected faces ---------------------------------------------------------------------------------------- fn ToggleSelectedFacesSubMatsToFlag inFlag appendFlags = ( editMesh = selection as array facematmaplist = #() if editMesh.count != 1 then ( messagebox "Select one object only" ) else ( meshObj = editMesh[1] if classof meshObj.material == Multimaterial then ( faceIdxList = getfaceselection meshObj -- Build an array of material ids and their -- associated faces ids in the current selection for faceIdx in faceIdxList do ( matidx = getFaceMatID meshObj faceIdx matExistsInList = false for facematmap in facematmaplist do ( if facematmap.materialidx == matidx then ( append facematmap.faceindices faceIdx matExistsInList = true ) ) if matExistsInList == false then ( facematmap = FaceMaterialMap faceindices:#(faceIdx) materialidx:matidx append facematmaplist facematmap ) ) -- Create a new submaterial that duplicates the old one -- and includes the additional flag if the additional -- flag is not already set on the material meshMultiMaterial = meshObj.material newsubmatlist = #() for submat in meshMultiMaterial.materiallist do ( append newsubmatlist submat ) i = 1 for facematmap in facematmaplist do ( currentSubMat = meshMultiMaterial.materiallist[facematmap.materialidx] if appendFlags == true then collflags = inFlag else collflags = 0 if NeedsNewMaterial appendFlags inFlag currentSubMat then ( newsubmat = RexBoundMtl() RexSetCollisionName newsubmat (RexGetCollisionName currentSubMat) RexSetProceduralName newsubmat (RexGetProceduralName currentSubMat) --RexSetCollisionFlags newsubmat (RexGetCollisionFlags currentSubMat) --RexSetCollisionFlags newsubmat inFlag -- Retain existing flags for flagObj in flagList do ( if flagObj.value != inFlag then ( if bit.and (RexGetCollisionFlags currentSubMat) flagObj.value == flagObj.value then ( collflags = collflags + flagObj.value ) ) ) RexSetCollisionFlags newsubmat collflags if chkSetPedPop.checked == true then RexSetPopDensity newsubmat (spnPedDensity.value as integer) newsubmat.name = currentSubMat.name + "_DUPLICATE" append newsubmatlist newsubmat for currentface in facematmap.faceindices do ( setFaceMatID meshObj currentface (meshMultiMaterial.materiallist.count + i) ) i = i + 1 ) ) meshMultiMaterial.numsubs = newsubmatlist.count meshMultiMaterial.materiallist = newsubmatlist ) ) ) fn GetFlagValueFromName flagName = ( for flagObj in flaglist do ( if flagObj.name == flagname then return flagObj.value ) ) --//////////////////////////////////////////////////////////// -- events --//////////////////////////////////////////////////////////// on btnCol2Mesh pressed do ( colMeshes = selection as array for colMesh in colMeshes do ( if classof colMesh == Col_mesh then ( col2mesh colMesh ) ) ) on btnMesh2Col pressed do ( meshObjs = selection as array for meshobj in meshObjs do ( if classof meshobj == Editable_Mesh then ( mesh2col meshObj ) ) ) on btnSetWholeMeshToSelBoundMat pressed do ( flagValue = GetFlagValueFromName lstFlags.selected ToggleWholeMeshSubMatsToFlag flagValue true ) on btnUnsetWholeMeshToSelBoundMat pressed do ( flagValue = GetFlagValueFromName lstFlags.selected ToggleWholeMeshSubMatsToFlag flagValue false ) on btnSetFacesToSelBoundMat pressed do ( flagValue = GetFlagValueFromName lstFlags.selected ToggleSelectedFacesSubMatsToFlag flagValue true ) on btnUnsetFacesToSelBoundMat pressed do ( flagValue = GetFlagValueFromName lstFlags.selected ToggleSelectedFacesSubMatsToFlag flagValue false ) on chkSetPedPop changed theState do ( if chkSetPedPop.checked == true then spnPedDensity.enabled = true else spnPedDensity.enabled = false ) on RsNonClimbRollout open do ( flagListNames = #() for flagObj in flagList do ( append flagListNames flagObj.name ) lstFlags.items = flagListNames ) ) try CloseRolloutFloater RsNoClimbUtil catch() RsNoClimbUtil = newRolloutFloater "Bound Material Toggle" 220 385 50 126 addRollout RsNonClimbRollout RsNoClimbUtil addRollout BoundMtlRoomRoll RsNoClimbUtil