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

1639 lines
50 KiB
Plaintext
Executable File

/*//////////////////////////////////////////////////////////////////////////////////--//////////////////////////////////////////////////////////////////////////////////
3dsMax Game Launcher
User configurable preset launcher based on global definitions
Support: Neil Gregory
Date 09/2011
*/--//////////////////////////////////////////////////////////////////////////////////--//////////////////////////////////////////////////////////////////////////////////
filein (RsConfigGetWildWestDir() + "script/3dsmax/_config_files/wildwest_header.ms")
fileIn "pipeline/util/RAG_funcs.ms"
--//////////////////////////////////////////////////////////////////////////////////
--STRUCTS
--//////////////////////////////////////////////////////////////////////////////////
/***
A struct to hold platform launch data
***/
struct PlatformConfigStruct
(
platformName = "",
betaLaunchScript = "",
bankLaunchScript = "",
getDataScript = ""
)
--//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-- Generates container world positions for use by the gamelauncher.ini
-- by ripping them out of the asset xml files which are synced from p4 dirs listed in the assetRoots array
--////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
Struct ContainerPositionsStruct
(
assetRoots = #((RsConfigGetAssetsDir() + "export/levels/gta5/_citye"),
(RsConfigGetAssetsDir() + "export/levels/gta5/_cityw"),
(RsConfigGetAssetsDir() + "export/levels/gta5/_hills"),
(RsConfigGetAssetsDir() + "export/levels/gta5/_prologue")),
containerMap = #(),
fn harvestContainerPositions depotFiles =
(
for xmlPath in depotFiles do
(
--check for type
if matchPattern xmlPath pattern:"*_props*" == false then
(
--make a local path
xmlPath = substituteString xmlPath "//depot" "x:"
if not doesFileExist xmlPath then continue
--print xmlFile
local stream = xmlStreamHandler xmlFile:xmlPath
stream.open()
--filter by class type
local nodelist = stream.root.Selectnodes("./objects/object[@class = \"container\"]")
print nodelist.count
if nodelist.count == 0 then continue
local theContainerNode = nodelist.ItemOf[0]
local containerName = theContainerNode.getattribute "name" --room name
--now get the position
local posNode = theContainerNode.selectNodes("transform/object/position")
local xPos = posNode.ItemOf[0].getattribute "x" --x
local yPos = posNode.ItemOf[0].getattribute "y" --y
local zPos = posNode.ItemOf[0].getattribute "z" --z
--local roomLocation = [xPos as float, yPos as float, zPos as float]
format "roomName: % location: % \n" containerName (xPos+" "+yPos+" "+zPos)
append containerMap (DataPair container:containerName location:(xPos+" "+yPos+" "+zPos))
stream.close()
)
)
--write out the interior config file
for i = 1 to containerMap.count do
(
setINISetting (RsConfigGetWildWestDir() + "etc/config/containerPositions.ini") "Container" containerMap[i].container containerMap[i].location
)
),
--load into gamelauncher
on create do
(
files = #()
for assetsPath in assetRoots do
(
print assetsPath
join files (getDepotFiles assetsPath wildcard:"*.xml" walk:true)
)
depotFiles = for fp in files where fp != "" collect fp.depotFile
gRsPerforce.sync depotFiles
harvestContainerPositions depotFiles
)
)
struct PresetItem
(
name = "",
flags = dotnetobject "RSG.MaxUtils.MaxDictionary"
)
--//////////////////////////////////////////////////////////////////////////////////
struct PresetManager
(
presets = #(),
presetNames = #(),
currentPreset = 0,
--levels = #("testbed", "cptestbed", "waterbed", "gta5"),
levels = #(),
toolsRoot = theProjectToolsRoot,
tempDir = getDir #temp,
configFile = pathConfig.appendPath tempDir "gameLauncher.ini",
globalConfigFile = pathConfig.appendPath toolsRoot "etc/config/generic/gameLauncher.ini",
--to store platform launch/build grab script links
platformDefs = #(),
--//////////////////////////////////////////////////////////////////////////////////
-- Create a new PresetItem and populate it
--//////////////////////////////////////////////////////////////////////////////////
fn createPreset preset cfgFile =
(
--name
thisPreset = PresetItem()
thisPreset.name = substring preset 1 (preset.count - 7)
--flags
aPresetVals = getINISetting cfgFile preset
--thisPreset.flags = for sub in aPresetVals collect (DataPair flag:sub value:(getINISetting globalConfigFile preset sub))
for key in aPresetVals do
(
thisPreset.flags.add key (getINISetting cfgFile preset key)
)
--levels
append levels (thisPreset.flags.Item "Level")
--add to the preset list
append presets thisPreset
return true
),
--////////////////////////////////////////////////////
fn loadGlobalPresets =
(
globalPresets = getINISetting globalConfigFile
for preset in globalPresets where (filterString preset "_")[2] == "Preset" do
(
createPreset preset globalConfigFile
)
),
--////////////////////////////////////////////////////
fn loadLocalPresets =
(
--load local preset section names from the index in the config file
localPresets = getINISetting configFile "localPresetIndex"
for preset in localPresets do
(
createPreset preset configFile
)
),
--////////////////////////////////////////////////////
fn eraseConfigFile =
(
answer = querybox "You sure you want to erase the local config?" title:"Erase Local Config"
if answer == false then
(
return false
)
else
(
try
(
deletefile configFile
)
catch(messagebox "Failed to erase local config" title:"FAIL")
)
),
--////////////////////////////////////////////////////
fn get_presetNames =
(
presetNames = for p in presets collect p.name
),
--//////////////////////////////////////////////////////////////////////////////////
-- Load global and local presets
--//////////////////////////////////////////////////////////////////////////////////
fn loadPresets =
(
--flush current presets
presets = #()
presetNames = #()
--load all presets
loadGlobalPresets()
loadLocalPresets()
--populate presetNames for UI
get_presetNames()
),
--////////////////////////////////////////////////////
fn createLocalPreset newPreset =
(
--iterate through flag dict spitting values
it = newPreset.flags.GetEnumerator()
while it.MoveNext() do
(
thisFlag = it.current
--set it
setINISetting configFile (newPreset.name + "_Preset") thisFlag.key thisFlag.value
)
--add to local preset config index
setINISetting configFile "localPresetIndex" (newPreset.name + "_Preset") "1"
--add this preset to the manager
append presets newPreset
--update presetNames
presetNames = for p in presets collect p.name
--call load local settings to refresh the manager
loadPresets()
),
--////////////////////////////////////////////////////
fn destroyLocalPreset killPreset =
(
--Kill the preset
delINISetting configFile (killPreset + "_Preset")
--kill the preset from the preset index
delINISetting configFile "localPresetIndex" (killPreset + "_Preset")
--call load local settings to refresh the manager
loadPresets()
--call gameLauncher to update the UI
if gameLauncher != undefined then gameLauncher.refreshPresetsUI()
),
--////////////////////////////////////////////////////
fn get_globalPresetNames =
(
gPresetsNames = for p in presets where p.flags.ContainsKey "global" collect p.name
),
--////////////////////////////////////////////////////
fn get_Levels =
(
levels = for p in presets collect presets.flags.Item "Level"
),
--////////////////////////////////////////////////////
on create do
(
gRsPerforce.connect()
--check if we have head rev before syncing
fstat = (gRsPerforce.getFileStats globalConfigFile)[1]
if fstat.item "haveRev" != fstat.item "headRev" then gRsPerforce.p4.run "sync" #(globalConfigFile)
--load global presets
loadPresets()
--load local presets
--loadLocalPresets()
--populate presetNames for UI
--get_presetNames()
)
)
presetManager = PresetManager()
--/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-- GAMELAUNCHER STRUCT
--/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
global gameLauncher
struct GameLauncherStruct
(
assetRoot = theProjectAssetRoot,
toolsRoot = theProjectToolsRoot,
presets = presetManager.presets,
levels = presetManager.levels,
configFile = presetManager.configFile,
globalConfigFile = presetManager.globalConfigFile,
lastLevel = "cptestbed",
lastPreset = "Gta5",
lastCommand = undefined, --the last command arguments string used to launch the game
lastBuildType,
presetValues = #(),
platformList = #(),
releaseList = #("Beta", "Bank Release"),
platform = "PS3",
startLocX = "0.0",
startLocY = "0.0",
startLocZ = "0.0",
startActive = "false",
startInterior = "false",
startInteriorIdx = "1",
startContainer = "false",
startContainerIdx = "1",
flags = #(),
mapAssets = pathConfig.appendPath assetRoot "/export/levels/gta5",
miloRooms = #(),
containerLocs = #(),
rolloutUI = undefined,
presetNamerUI = undefined,
flagsUI = undefined,
windowPos = undefined,
RS_PROJROOT = RsMakeSafeSlashes (systemTools.getEnvVariable "RS_PROJROOT"),
RS_buildBranch = RsMakeSafeSlashes (systemTools.getEnvVariable "RS_BUILDBRANCH"),
--getCurrentPS3BuildPath = (RS_PROJROOT+"/tools/script/util/GET_STABLE_PS3.bat"),
--getCurrent360BuildPath = (RS_PROJROOT+"/tools/script/util/GET_STABLE_XBOX.bat"),
getCurrentBuildPathRoot = (RsConfigGetToolsRootDir() + "/script/util/"),
/***
Build a dictionary of platform script configs
***/
fn getPlatformConfigs =
(
local platformINIDefs = for item in (getINIsetting presetManager.globalConfigFile)
where ((MatchPattern item pattern:"Platform_*") == true)
collect item
local platformConfigProps = getPropNames PlatformConfigStruct
for item in platformINIDefs do
(
local platformConfig = PlatformConfigStruct()
local configDataKeys = getINISetting presetManager.globalConfigFile item
for key in configDataKeys do
(
setProperty platformConfig (key as Name) (getINISetting presetManager.globalConfigFile item key)
)
append presetManager.platformDefs (DataPair name:platformConfig.platformName config:platformConfig)
)
),
/***
Get the level arguments from the ini file.
***/
fn getLevelArguments level =
(
return (getINISetting presetManager.globalConfigFile "Level_Arguments" level)
),
/***
Get a platform config that contains links to the launch scripts or build grab script
***/
fn getPlatformConfig name =
(
local config = undefined
for item in presetManager.platformDefs while (config == undefined) do
(
if (item.name == (name as String)) then
(
config = item.config
)
)
if (config == undefined) do
(
print "unresolved platform config data"
)
--return
config
),
--////////////////////////////////////////////////////
on create do
(
--grab the last viewport position from the config file
cfgWindowPos = getINISetting configFile "Session" "WindowPos" as stringstream
format "cfgWindowPos: %\n" cfgWindowPos
if eof cfgWindowPos == false then
(
windowPosX = readvalue cfgWindowPos
windowPosY = readvalue cfgWindowPos
windowPos = [windowPosX, windowPosY]
)
--get platformList
platformList = getINIsetting presetManager.globalConfigFile "PlatformList"
--setup platform settings
getPlatformConfigs()
/*
--sync the gameLaucherInteriors file from perforce
try
(
--local depotPath = gRsPerforce.local2depot "X:/gta5/tools/wildwest/etc/config/maps/gameLauncherInteriors.ini"
gRsPerforce.sync "//depot/gta5/tools/wildwest/etc/config/maps/gameLauncherInteriors.ini" silent:true
)
catch(print "Couldnt sync the gameLauncherInteriors file")
*/
),
--//////////////////////////////////////////////////////////////////////////////////
-- Save the current main window position to the local config
--//////////////////////////////////////////////////////////////////////////////////
fn saveWindowPos windowPos =
(
--windowPos = GetDialogPos rolloutUI
setINISetting configFile "Session" "WindowPos" (windowPos.x as string + " " + windowPos.y as string)
),
--////////////////////////////////////////////////////
fn loadConfig =
(
lastPreset = getINISetting configFile "Session" "Preset"
--get preset settings
--organise the settings into a dictionary of flagname and values using either DataPair or dotnet dict
--aPresetVals = getINISetting globalConfigFile (lastPreset+"_Preset")
--presetValues = for sub in aPresetVals collect (DataPair flag:sub value:(getINISetting globalConfigFile (lastPreset+"_Preset") sub))
--format "presetValues: % \n" presetValues
--lastlevel = getINISetting globalConfigFile (lastPreset+"_Preset") "Level"
--get the last loaded preset and collect the preset values for the flags it holds
lastPresetIdx = for p = 1 to presets.count where presets[p].name == lastPreset collect p
lastPresetIdx = lastPresetIdx[1]
--set the preset
format "last preset: % \n" lastPreset
if lastPresetIdx != undefined then
(
rolloutUI.ddlPreset.selection = lastPresetIdx
)
else
(
rolloutUI.ddlPreset.selection = 1
)
gameLauncher.setPreset lastPreset
--format "lastLevel: %\n" lastLevel
platform = getINISetting configFile "Session" "Platform"
startLocX = getINISetting configFile "Session" "StartLocX"
startLocY = getINISetting configFile "Session" "StartLocY"
startLocZ = getINISetting configFile "Session" "StartLocZ"
if hasINISetting configFile "Session" "StartActive" then startActive = getINISetting configFile "Session" "StartActive"
if hasINISetting configFile "Session" "StartInterior" then startInterior = getINISetting configFile "Session" "StartInterior"
if hasINISetting configFile "Session" "StartInteriorIdx" then startInteriorIdx = getINISetting configFile "Session" "StartInteriorIdx"
if hasINISetting configFile "Session" "StartContainer" then startContainer = getINISetting configFile "Session" "StartContainer"
if hasINISetting configFile "Session" "StartContainerIdx" then startContainerIdx = getINISetting configFile "Session" "StartContainerIdx"
if hasINISetting configFile "Session" "BuildType" then lastBuildType = (getINISetting configFile "Session" "BuildType") as Integer
),
--////////////////////////////////////////////////////
fn saveConfig =
(
setINISetting configFile "Session" "Preset" lastPreset
--setINISetting configFile "Session" "Level" lastLevel
setINISetting configFile "Session" "Platform" platform
setINISetting configFile "Session" "StartLocX" startLocX
setINISetting configFile "Session" "StartLocY" startLocY
setINISetting configFile "Session" "StartLocZ" startLocZ
setINISetting configFile "Session" "StartActive" (startActive as String)
setINISetting configFile "Session" "StartInterior" (startInterior as String)
setINISetting configFile "Session" "StartInteriorIdx" startInteriorIdx
setINISetting configFile "Session" "StartContainer" (startContainer as String)
setINISetting configFile "Session" "StartContainerIdx" startContainerIdx
setINISetting configFile "Session" "LastCommand" lastCommand
setINISetting configFile "Session" "BuildType" (lastBuildType as String)
),
--////////////////////////////////////////////////////
fn getInteriorsXML =
(
local interiorsXML = (RsProjectGetCommonDir() + "/data/script/xml/InteriorLocationInfo/InteriorsInfo.XML")
local stream = dotNetObject "System.IO.StreamReader" interiorsXML
local XML = dotNetObject "System.Xml.XmlDocument"
XML.load stream
local root = XML.documentElement
local interiorNodeList = root.Selectnodes("info/Item/archetypeName")
local interiorPosList = root.Selectnodes("info/Item/position")
local interiors = for n = 0 to (interiorNodeList.count - 1)
collect
(
local theInteriorName = (interiorNodeList.itemOf n).innerText
local thePosNode = interiorPosList.itemOf n
local x = thePosNode.getAttribute "x"
local y = thePosNode.getAttribute "y"
local z = thePosNode.getAttribute "z"
(theInteriorName+"="+x+" "+y+" "+z)
)
for item in interiors do print item
),
--////////////////////////////////////////////////////
fn killRag =
(
if platform == "360" then
(
HiddenDOSCommand "C:/Program Files (x86)/Microsoft Xbox 360 SDK/bin/win32/xbreboot.exe"
sleep 2
HiddenDOSCommand "taskkill /im xbWatson.exe /f /t"
HiddenDOSCommand "taskkill /im SysTrayRfs.exe /f /t"
HiddenDOSCommand "taskkill /im rag.exe /f /t"
)
else
(
HiddenDOSCommand "taskkill /im SysTrayRfs.exe /f /t"
HiddenDOSCommand "taskkill /im rag.exe /f /t"
)
),
--////////////////////////////////////////////////////
fn getCurrentBuild =
(
sysInfo.currentdir = (RS_PROJROOT+"/tools/script/util/")
local platformConfig = getPlatformConfig platform
local buildScript = getCurrentBuildPathRoot + platformConfig.getDataScript
print buildScript
shellLaunch buildScript ""
),
--////////////////////////////////////////////////////
fn getFilesRecursive root pattern =
(
dir_array = GetDirectories (root+"/*")
for d in dir_array do
join dir_array (GetDirectories (d+"/*"))
my_files = #()
for f in dir_array do
join my_files (getFiles (f + pattern))
my_files
),
--////////////////////////////////////////////////////
fn currentInterior =
(
rooms = for r in miloRooms collect r.room
sort rooms
finds = for o in $objects where classOf o == Gta_MILO collect o.name
idx = findItem rooms finds[1]
),
--////////////////////////////////////////////////////
fn getMiloInst =
(
interior = for o in $objects where classOf o == Gta_MILO collect o.name
if interior == undefined then return
interior = interior[1]
--load the rooms defs from the gameLauncherInteriors.ini file
--print globalConfigFile
iniRooms = sort( getINISetting globalConfigFile "Interior" )
for r in iniRooms do
(
location = getINISetting globalConfigFile "Interior" r as stringstream
xLoc = readValue location
yLoc = readValue location
zLoc = readValue location
append miloRooms (DataPair room:r location:#(xLoc as string, yLoc as string, zLoc as string))
)
--update dropdown interiors list
rooms = for r in miloRooms collect r.room
sort rooms
rolloutUI.ddlInteriors.items = rooms
--now set the ddl item to the currently loaded interior if we have one
--finds = for o in $objects where classOf o == Gta_MILO collect o.name
--idx = findItem rooms finds[1]
idx = gameLauncher.currentInterior()
if idx != 0 then
(
rolloutUI.ddlInteriors.selection = idx
--update field vals
gameLauncher.ddlInteriorsItem idx
)
),
--////////////////////////////////////////////////////
fn currentContainer =
(
cntainers = for c in containerLocs collect c.container
finds = for o in $objects where classOf o == Container collect o.name
idx = findItem cntainers finds[1]
),
--////////////////////////////////////////////////////
fn getContainerLocs =
(
containerINI = sort( getINISetting globalConfigFile "Container" )
for c in containerINI do
(
location = getINISetting globalConfigFile "Container" c as StringStream
xLoc = readValue location
yLoc = readValue location
zLoc = readValue location
append containerLocs (DataPair container:c location:#(xLoc as string, yLoc as string, zLoc as string))
)
cntnr = for c in containerLocs collect c.container
sort cntnr
rolloutUI.ddlContainers.items = cntnr
--set the ddl to the first container that matches in the scene
idx = gameLauncher.currentContainer()
if idx != 0 then
(
rolloutUI.ddlContainers.selection = idx
--update field vals
gameLauncher.ddlContainersItem idx
)
),
--////////////////////////////////////////////////////
fn selectionChanged =
(
sel = $selection[1]
if sel != undefined then
(
pos = sel.position
startLocX = pos.x as string
startLocY = pos.y as string
startLocZ = pos.z as string
--ui
rolloutUI.txtLocX.text = startLocX
rolloutUI.txtLocY.text = startLocY
rolloutUI.txtLocZ.text = startLocZ
)
),
--////////////////////////////////////////////////////
fn updateStartLocUI =
(
rolloutUI.txtLocX.text = startLocX
rolloutUI.txtLocY.text = startLocY
rolloutUI.txtLocZ.text = startLocZ
),
--////////////////////////////////////////////////////
fn ddlInteriorsItem idx =
(
--roomID = miloRooms[idx].room
rolloutUI.ddlInteriors.selection = idx
if idx != 0 then
(
locXYZ = miloRooms[idx].location
startLocX = locXYZ[1]
startLocY = locXYZ[2]
startLocZ = locXYZ[3]
startInteriorIdx = idx as string
gameLauncher.updateStartLocUI()
)
RsRagFuncs.setPlayerPos [startLocX as Float, startLocY as Float, startLocZ as Float]
),
--////////////////////////////////////////////////////
fn ddlContainersItem idx =
(
--roomID = miloRooms[idx].room
rolloutUI.ddlContainers.selection = idx
if idx != 0 then
(
locXYZ = ContainerLocs[idx].location
startLocX = locXYZ[1]
startLocY = locXYZ[2]
startLocZ = locXYZ[3]
startInteriorIdx = idx as string
gameLauncher.updateStartLocUI()
)
RsRagFuncs.setPlayerPos [startLocX as Float, startLocY as Float, startLocZ as Float]
),
--////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
--Create a local preset
--////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
fn createPreset name =
(
fn doIt name =
(
--we continue so close the naming dialog
destroyDialog presetNamerUI
--create a new PresetItem
newPreset = PresetItem()
--set the name
newPreset.name = name
print newPreset.name
--gather current flag settings
--level
newPreset.flags.add "Level" gameLauncher.flagsUI.ddlLevels.selected
--checkboxes
for ctrl in gameLauncher.flagsUI.controls where (classOf ctrl) == checkBoxControl do
(
case ctrl.name of
(
"chk_rdrDebugCamera":
if ctrl.checked then newPreset.flags.add "rdrDebugCamera" "true"
"chk_nopeds":
if ctrl.checked then newPreset.flags.add "nopeds" "true"
"chk_nocars":
if ctrl.checked then newPreset.flags.add "nocars" "true"
"chk_fragtuning":
if ctrl.checked then newPreset.flags.add "fragtuning" "true"
"chk_debugexpr":
if ctrl.checked then newPreset.flags.add "debugexpr" "true"
"chk_loadwaterxml":
if ctrl.checked then newPreset.flags.add "loadwaterxml" "true"
"chk_invincible":
if ctrl.checked then newPreset.flags.add "invincible" "true"
"chk_lan":
if ctrl.checked then newPreset.flags.add "lan" "true"
"chk_noIdleCam":
if ctrl.checked then newPreset.flags.add "noIdleCam" "true"
"chk_nodefrag":
if ctrl.checked then newPreset.flags.add "nodefrag" "true"
)
)
--custom flags
if gameLauncher.flagsUI.txtFlags.text != "--Custom flags--" then
(
newPreset.flags.add "UserDef" gameLauncher.flagsUI.txtFlags.text
)
--save to local config
presetManager.createLocalPreset newPreset
)--END doIt()
-----------------
--Validation
-----------------
--Check against existing profiles
local existing = for p in presets where p.name == name collect p
if existing.count != 0 then --we have an existing preset
(
--check it doesnt clash with a global preset name
clash = for n in presetManager.get_globalPresetNames() where matchPattern n pattern:name ignorecase:true collect n
if clash.count != 0 then
(
messagebox "!!!You can't overwrite a global preset name!!!\nTry another name." title:"Illegal name"
return false
)
--replace if local already exists?
updatePreset = queryBox "A preset of that name already exists!\nDo you want to update it?" title:"Preset Update"
if updatePreset then
(
--destroys existing preset before updating
presetManager.destroyLocalPreset name
doIt name
--update UI presets
rolloutUI.ddlPreset.items = presetManager.presetNames
)
else -- lets call the whole thing off
(
destroyDialog presetNamer
return false
)
)
else --its a new one
(
doIt name
--update UI presets
rolloutUI.ddlPreset.items = presetManager.presetNames
)
),
--////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
--Destroy a local preset
--////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
fn destroyPreset name =
(
--Check for valid preset == local
queryGlobalPreset = for n in presetManager.get_globalPresetNames() where matchPattern n pattern:name ignorecase:true collect n
if queryGlobalPreset.count == 0 then
(
--Confirm user action to kill preset
destroy = queryBox "Are you sure you want to delete this preset?" title:"Destroy Preset?"
if destroy then
(
--Remove from local config
presetManager.destroyLocalPreset name
--setINISetting configFile
--Update UI
rolloutUI.ddlPreset.items = presetManager.presetNames
--Switch to next preset in list
--rolloutUI.ddlPreset.selection
)
else --we'll let this one live
(
return false
)
)
else --This cant be deleted as its a global preset
(
messageBox "This preset cannot be deleted\nIt is not a user preset" title:"Error"
return false
)
),
--////////////////////////////////////////////////////
fn refreshPresetsUI =
(
--get current index
idx = rolloutUI.ddlPreset.selection
--re-populate the preset list
rolloutUI.ddlPreset.items = presetManager.presetNames
--set the index
if idx == 1 then
(
rolloutUI.ddlPreset.selection = 1
)
else
(
rolloutUI.ddlPreset.selection = idx-1
)
--set the lastPreset to this current one in case the user now closes the tool as next time a non existant preset will attmept to be retreived
--lastPreset = rolloutUI.ddlPreset.selected
),
--////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
--This is where the flags settings on a preset change are triggered
--////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
fn setPreset preset =
(
--set the current preset in the presetManager
for p = 1 to presetManager.presets.count where matchPattern presetManager.presets[p].name pattern:rolloutUI.ddlPreset.selected ignorecase:true do
(
presetManager.currentPreset = p
)
--find the preset selected in the preset manager and set the launch level to its associated level
local levelVal = presetManager.presets[presetManager.currentPreset].flags.Item "Level"
gameLauncher.flagsUI.ddlLevels.selected = levelVal
local currentPreset = presetManager.presets[presetManager.currentPreset]
--set checkbox type flags
--flush all false first
for ctrl in gameLauncher.flagsUI.controls where (classOf ctrl) == checkBoxControl do ctrl.checked = false
--now set based on preset
if currentPreset.flags.ContainsKey "rdrDebugCamera" then
gameLauncher.flagsUI.chk_rdrDebugCamera.checked = currentPreset.flags.Item "rdrDebugCamera" as BooleanClass
if currentPreset.flags.ContainsKey "nopeds" then
gameLauncher.flagsUI.chk_nopeds.checked = currentPreset.flags.Item "nopeds" as BooleanClass
if currentPreset.flags.ContainsKey "nocars" then
gameLauncher.flagsUI.chk_nocars.checked = currentPreset.flags.Item "nocars" as BooleanClass
if currentPreset.flags.ContainsKey "fragtuning" then
gameLauncher.flagsUI.chk_fragtuning.checked = currentPreset.flags.Item "fragtuning" as BooleanClass
if currentPreset.flags.ContainsKey "debugexpr" then
gameLauncher.flagsUI.chk_debugexpr.checked = currentPreset.flags.Item "debugexpr" as BooleanClass
if currentPreset.flags.ContainsKey "loadwaterxml" then
gameLauncher.flagsUI.chk_loadwaterxml.checked = currentPreset.flags.Item "loadwaterxml" as BooleanClass
if currentPreset.flags.ContainsKey "invincible" then
gameLauncher.flagsUI.chk_invincible.checked = currentPreset.flags.Item "invincible" as BooleanClass
if currentPreset.flags.ContainsKey "lan" then
gameLauncher.flagsUI.chk_invincible.checked = currentPreset.flags.Item "lan" as BooleanClass
if currentPreset.flags.ContainsKey "noIdleCam" then
gameLauncher.flagsUI.chk_noIdleCam.checked = currentPreset.flags.Item "noIdleCam" as BooleanClass
if currentPreset.flags.ContainsKey "nodefrag" then
gameLauncher.flagsUI.chk_nodefrag.checked = currentPreset.flags.Item "nodefrag" as BooleanClass
--set the custom flag value
if currentPreset.flags.ContainsKey "UserDef" then
(
gameLauncher.flagsUI.txtFlags.text = currentPreset.flags.Item "UserDef"
)
else
(
gameLauncher.flagsUI.txtFlags.text = "--Custom flags--"
)
),
--////////////////////////////////////////////////////
fn initSystem =
(
--load config
gameLauncher.loadConfig()
--set the platform from the local config
rolloutUI.radPlatform.selection = findItem platformList platform
rolloutUI.txtLocX.text = gameLauncher.startLocX
rolloutUI.txtLocY.text = gameLauncher.startLocY
rolloutUI.txtLocZ.text = gameLauncher.startLocZ
startActive = gameLauncher.startActive as BooleanClass
startInterior = gameLauncher.startInterior as BooleanClass
rolloutUI.chkLocation.state = startActive
if startActive then
(
rolloutUI.chkSelection.enabled = true
if startInterior then
(
rolloutUI.chkInterior.enabled = true
rolloutUI.chkInterior.state = true
rolloutUI.ddlInteriors.enabled = true
rolloutUI.ddlInteriors.selection = gameLauncher.startInteriorIdx as Integer
)
rolloutUI.txtLocX.enabled = true
rolloutUI.txtLocY.enabled = true
rolloutUI.txtLocZ.enabled = true
)
else
(
rolloutUI.chkSelection.enabled = false
rolloutUI.chkInterior.enabled = false
rolloutUI.ddlInteriors.enabled = false
rolloutUI.txtLocX.enabled = false
rolloutUI.txtLocY.enabled = false
rolloutUI.txtLocZ.enabled = false
)
if lastBuildType != undefined then
(
rolloutUI.radRelease.state = lastBuildType
)
--set last preset
--idx = findItem presetManager.levels gameLauncher.lastPreset
--rolloutUI.ddlPreset.selection = idx
--gameLauncher.setPreset idx
--GamelauncherUI.setPreset presetManager.levels[idx]
)
/*
on create do
(
--loadConfig()
)
*/
)
gameLauncher = GameLauncherStruct()
--/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-- UI
--/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
if GameLauncherUI != undefined then destroyDialog GameLauncherUI
--////////////////////////////////////////////////////
-- PresetNamer
--////////////////////////////////////////////////////
rollout presetNamer "New Preset" height:50
(
edittext txtName text:"CHANGEME" tooltip:"Provide a name for your new preset"
button btnOK "OK"
on txtName entered txt do
(
if txt != "" or txt != "CHANGEME" then
(
gameLauncher.createPreset txt
)
)
on btnOK pressed do
(
if txtName.text != "" or txtName.text != "CHANGEME" then
(
gameLauncher.createPreset txtName.text
)
)
)
--////////////////////////////////////////////////////
-- Preset flags
--////////////////////////////////////////////////////
rollout flags "Preset" height:250 rolledup:true
(
button btn_savePreset "Save Preset" width:180
dropdownlist ddlLevels width:180 align:#center items:presetManager.levels tooltip:"Game level to load"
edittext txtFlags text:"--Custom flags--" tooltip:"Custom user flags to launch with"
checkbox chk_rdrDebugCamera "rdrCamera" tooltip:"RDR Debug Camera" across:2
checkbox chk_nopeds "nopeds" tooltip:"No peds spawn"
checkbox chk_nocars "nocars" across:2 tooltip:"No cars spawn"
checkbox chk_fragtuning "fragtuning"
checkbox chk_debugexpr "debugexpr" across:2
checkbox chk_loadwaterxml "loadwaterxml"
checkbox chk_invincible "invincible" across:2
checkbox chk_lan "lan" tooltip:"Local MP"
checkbox chk_noIdleCam "noIdleCam" across:2 tooltip:"Disable floating camera"
checkbox chk_nodefrag "nodefrag"
checkbox chk_noWarpCameraPosSet "noWarpCameraPosSet"
--checkbox chkTestFlag8 "testflag"
on flags rolledUp arg do
(
if arg then
(
--GamelauncherUI.ddlLevels.offset = [0,25]
GamelauncherUI.flags.height = 235
GamelauncherUI.height += 210
)
else
(
--GamelauncherUI.ddlLevels.offset = [0,20]
GamelauncherUI.flags.height = 25
GamelauncherUI.height -= 210
)
)
on btn_savePreset pressed do
(
--prompt for a name
createDialog presetNamer
gameLauncher.presetNamerUI = presetNamer
)
)
gameLauncher.flagsUI = flags
--///////////////////////////////////////////////////////
-- Start location from map coords rollout
--///////////////////////////////////////////////////////
rollout MapCoords "Map Co-ords"
(
local mapImg = (RsConfigGetWildWestDir() +"script/3dsMax/UI/coordsMap.bmp")
local coordMap = openBitmap mapImg
--button btn_Warp "Warp!" width:200
bitmap theCoordMap pos:[0,0] width:coordMap.width height:coordMap.height filename:mapImg
on MapCoords open do
(
coordMap = openBitmap mapImg
MapCoords.width = coordMap.width
MapCoords.height = coordMap.height
)
fn getLoc pos =
(
cellWide = 8000.0 / coordMap.width
cellLength = 11500.0 / coordMap.height
cellHigh = 780.0 / 256.0
pixel = (getPixels coordMap pos 1)[1]
posX = (pos.x + (-3500.0 / cellWide)) * cellWide
posY = -1.0 * ((pos.y - (7500.0 / cellLength)) * cellLength)
posZ = 10.0 + (pixel.a * cellHigh)
GamelauncherUI.txtLocX.text = posX as String
GamelauncherUI.txtLocY.text = posY as String
GamelauncherUI.txtLocZ.text = posZ as String
return [posX, posY, posZ]
)
on MapCoords lbuttondown pos do
(
--get coords
--print pos
getLoc pos
gameLauncher.flagsUI.chk_invincible.checked = true
)
on MapCoords lbuttondblclk pos do
(
pos = getLoc pos
RsRagFuncs.setPlayerPos pos
)
)
--////////////////////////////////////////////////////
-- Main UI
--////////////////////////////////////////////////////
rollout GamelauncherUI "Game Launcher" width:220 height:485
(
dotNetControl rsBannerPanel "Panel" pos:[0,0] height:32 width:GamelauncherUI.width
local banner = makeRsBanner dn_Panel:rsBannerPanel versionName:"Dignitas Bound" versionNum:1.01 wiki:"GameLauncher_Max" filename:(getThisScriptFilename())
local mapIconImg = (RsConfigGetWildWestDir() +"script/3dsMax/UI/mapIcon.png")
group "Platform"
(
--radiobuttons radPlatform "" labels:gameLauncher.platformList columns:2
dropdownlist radPlatform "" items:gameLauncher.platformList width:200 offset:[-4,0]
button btnGetBuild "Get Current Build" width:200
button btnKillRag "Kill Rag" width:200 tooltip:"DIE!DIE!DIE!"
)
group " Start Location"
(
checkbox chkLocation "" width:10 offset:[-6, -20] tooltip:"Use a custom start location"
checkbox chkSelection "Selection" tooltip:"Get start location from a selected object" across:3
label lbl_mapLoc "Map:" offset:[30, 0]
button btn_mapLoc "map" width:32 height:32 images:#(mapIconImg, undefined, 1,1,1,1,1) tooltip:"Select point on map"
--btn_mapLoc.images = #(mapIconImg, undefined, 1,1,1,1,1)
--Container
groupbox grpContainer "Container" width:195 height:40 offset:[0, 0] across:3
checkbox chkContainer "" offset:[-55, 18] across:2 tooltip:"Start location from a Container"
dropdownlist ddlContainers width:135 offset:[-75, 14] items:gameLauncher.ContainerLocs tooltip:"Select a Container start location"
--interior
groupbox grpInterior "Interior" width:195 height:40 offset:[0, 0] across:3
checkbox chkInterior "" offset:[-55, 18] across:2 tooltip:"Start location from an interior"
dropdownlist ddlInteriors width:135 offset:[-75, 14] items:gameLauncher.miloRooms tooltip:"Select an interior start location"
edittext txtLocX "" width:60 offset:[-5, 0] across:3 tooltip:"PlayerStart X"
edittext txtLocY "" width:60 offset:[0, 0] tooltip:"PlayerStart Y"
edittext txtLocZ "" width:60 offset:[5, 0] tooltip:"PlayerStart Z"
)
group "Launch"
(
radiobuttons radRelease "" labels:gameLauncher.releaseList columns:2
groupbox grpPreset width:195 height:40 offset:[0, -5] across:4
dropdownlist ddlPreset width:140 align:#left offset:[-42, 8] items:presetManager.presetNames across:3 tooltip:"Preset to launch with"
button btnNewPreset "+" width:20 align:#right offset:[25, 8] tooltip:"Add new launch Preset based on current settings"
button btnKillPreset "-" width:20 align:#right offset:[0, 8] tooltip:"Destroy user launch preset!"
-- LAUNCH BUTTON
button btnLaunch "Launch" width:200 images:#("LaunchButton.bmp", undefined, 2, 1, 2, 1, 1, false) tooltip:"Launch the game using the current chosen preset"
)
subRollout flags width:213 height:25 offset:[-9,0] rolledUp:true
--/////////////////////////////////////
-- FUNCTIONS
--/////////////////////////////////////
/***
Retrieve the platfromLaunch command for the current selected platform
***/
fn platformLaunchCommand platform =
(
local command = undefined
local platformName = gameLauncher.platformList[platform]
local config = gameLauncher.getPlatformConfig platformName
if (config != undefined) then
(
local commandOpts = #(config.betaLaunchScript, config.bankLaunchScript)
local batFile = commandOpts[radRelease.state]
local batPath = gameLauncher.RS_buildBranch
-- If ps3 or xb360 change to dev path to the non-ng version
format "batFile : %\n" batFile
case (batFile) of
(
-- PS3
"game_psn_beta_SNC.bat" : batPath = substituteString batPath "dev_ng" "dev"
"game_psn_bankrelease_SNC.bat" : batPath = substituteString batPath "dev_ng" "dev"
-- XBOX 360
"game_xenon_beta.bat" : batPath = substituteString batPath "dev_ng" "dev"
"game_xenon_bankrelease.bat" : batPath = substituteString batPath "dev_ng" "dev"
)
command = batPath + "/" + batFile
)
--return
command
)
--#--#--#--#--#--#--#--#
--Events dear boy
--#--#--#--#--#--#--#--#
/*
on GamelauncherUI open do
(
)
*/
--////////////////////////////////////////////////////
on GameLauncherUI open do
(
banner.setup()
)
--////////////////////////////////////////////////////
on radPlatform selected val do
(
gameLauncher.platform = gameLauncher.platformList[val]
)
--////////////////////////////////////////////////////
on chkLocation changed arg do
(
if not arg then
(
chkSelection.enabled = false
chkInterior.enabled = false
ddlInteriors.enabled = false
ddlContainers.enabled = false
chkContainer.enabled = false
txtLocX.enabled = false
txtLocY.enabled = false
txtLocZ.enabled = false
gameLauncher.startActive = chkSelection.enabled as string
)
else
(
chkSelection.enabled = true
ddlContainers.enabled = true
chkContainer.enabled = true
chkInterior.enabled = true
if chkInterior.checked == true then ddlInteriors.enabled = true
txtLocX.enabled = true
txtLocY.enabled = true
txtLocZ.enabled = true
gameLauncher.startActive = chkSelection.enabled as string
)
)
--////////////////////////////////////////////////////
on chkSelection changed arg do
(
if arg then
(
chkInterior.enabled = false
ddlInteriors.enabled = false
callbacks.removeScripts id:#gameLauncher
--switch on callback
callbacks.addScript #selectionSetChanged "gameLauncher.selectionChanged()" id:#gameLauncher
)
else
(
callbacks.removeScripts id:#gameLauncher
chkInterior.enabled = true
ddlInteriors.enabled = true
)
)
--////////////////////////////////////////////////////
on btn_mapLoc pressed do
(
windowPos = GetDialogPos GamelauncherUI
createDialog MapCoords pos:[windowPos.x + 230, windowPos.y]
)
--////////////////////////////////////////////////////
-- Container control events
--////////////////////////////////////////////////////
on chkContainer changed arg do
(
if arg then
(
ddlContainers.enabled = true
ddlInteriors.enabled = false
chkInterior.checked = false
--if ddlContainers.items.count == 0 then gameLauncher.getMiloInst()
idx = gameLauncher.currentContainer()
gameLauncher.ddlContainersItem idx
gameLauncher.startContainer = "true"
)
else
(
ddlContainers.enabled = false
gameLauncher.startContainer = "false"
)
)
--////////////////////////////////////////////////////
fn ddlContainerSelector itm =
(
gameLauncher.ddlContainersItem itm
)
--////////////////////////////////////////////////////
on ddlContainers selected arg do ddlContainerSelector arg
--////////////////////////////////////////////////////
-- Interior control events
--////////////////////////////////////////////////////
on chkInterior changed arg do
(
if arg then
(
ddlInteriors.enabled = true
ddlContainers.enabled = false
chkContainer.checked = false
if ddlInteriors.items.count == 0 then gameLauncher.getMiloInst()
idx = gameLauncher.currentInterior()
gameLauncher.ddlInteriorsItem idx
gameLauncher.startInterior = "true"
)
else
(
ddlInteriors.enabled = false
gameLauncher.startInterior = "false"
)
)
--////////////////////////////////////////////////////
fn ddlInteriorSelector itm =
(
gameLauncher.ddlInteriorsItem itm
)
--////////////////////////////////////////////////////
on ddlInteriors selected arg do ddlInteriorSelector arg
--////////////////////////////////////////////////////
on txtLocX changed arg do
(
if arg as float != undefined then
(
gameLauncher.startLocX = arg
)
else
(
t = ""
for a = 1 to (arg.count - 1) do t += arg[a]
gameLauncher.startLocX = t
)
gameLauncher.updateStartLocUI()
)
--////////////////////////////////////////////////////
on txtLocY changed arg do
(
if arg as float != undefined then
(
gameLauncher.startLocY = arg
)
else
(
t = ""
for a = 1 to (arg.count - 1) do t += arg[a]
gameLauncher.startLocY = t
)
gameLauncher.updateStartLocUI()
)
--////////////////////////////////////////////////////
on txtLocZ changed arg do
(
if arg as float != undefined then
(
gameLauncher.startLocZ = arg
)
else
(
t = ""
for a = 1 to (arg.count - 1) do t += arg[a]
gameLauncher.startLocZ = t
)
gameLauncher.updateStartLocUI()
)
--////////////////////////////////////////////////////
on btnGetBuild pressed do
(
gameLauncher.getCurrentBuild()
)
--////////////////////////////////////////////////////
on btnKillRag pressed do
(
gameLauncher.killRag()
)
--////////////////////////////////////////////////////
on ddlPreset selected preset do gameLauncher.setPreset preset
--////////////////////////////////////////////////////
--Save the current setup as a preset
on btnNewPreset pressed do
(
--prompt for a name
createDialog presetNamer
gameLauncher.presetNamerUI = presetNamer
)
--////////////////////////////////////////////////////
--Kill user preset
on btnKillPreset pressed do
(
gameLauncher.destroyPreset ddlPreset.selected
)
--////////////////////////////////////////////////////
-- The function that launches the game with the settings specified by the user
--The launch flags should be taken from the UI so that they can override any preset that was initially selected and the user knows that WYSIWYG
on btnLaunch pressed do
(
--kill RAG first
gameLauncher.killRag()
--set env vars
HiddenDOSCommand "setenv.bat"
--get the level selected
level = gameLauncher.flagsUI.ddlLevels.selected
--get the start postion
x = trimleft txtLocX.text
y = trimleft txtLocY.text
z = trimleft txtLocZ.text
--Platform
local platform = radPlatform.selection
--Launch
DOSCommand "cd /d %RS_BUILDBRANCH%"
local RS_buildBranch = systemTools.getEnvVariable "RS_BUILDBRANCH"
--Init command string
local command = platformLaunchCommand platform
if (command == undefined) then
(
print "Cannot resolve launch command"
messageBox "Cannot find a launch command for this platform\nContact TechArt" title:"Error"
return false
)
--Base flags
local arguments = "-noautoload -previewfolder "
--command += "-noautoload -previewfolder "
--Checkbox type controls
for ctrl in gameLauncher.flagsUI.controls where (classOf ctrl) == checkBoxControl do
(
case ctrl.name of
(
"chk_rdrDebugCamera":
if ctrl.checked then arguments += "-rdrDebugCamera "
"chk_nopeds":
if ctrl.checked then arguments += "-nopeds "
"chk_nocars":
if ctrl.checked then arguments += "-nocars "
"chk_fragtuning":
if ctrl.checked then arguments += "-fragtuning "
"chk_debugexpr":
if ctrl.checked then arguments += "-debugexpr "
"chk_loadwaterxml":
if ctrl.checked then arguments += "-loadwaterxml "
"chk_invincible":
if ctrl.checked then arguments += "-invincible "
"chk_lan":
if ctrl.checked then arguments += "-lan "
"chk_noIdleCam":
if ctrl.checked then arguments += "-noIdleCam "
"chk_nodefrag":
if ctrl.checked then arguments += "-nodefrag "
"chk_noWarpCameraPosSet":
if ctrl.checked then arguments += "-noWarpCameraPosSet "
)
)
--Set level arguments (gets this from the ini file)
arguments += gameLauncher.getLevelArguments level
--location
if chkLocation.checked then arguments += " -playercoords="+x+","+y+","+z+" "
--Append any custom defined flags in the textbox
local customFlags = gameLauncher.flagsUI.txtFlags.text
if customFlags != "--Custom flags--" then
(
arguments += customFlags
)
--3..2..1..0!
format "command: % arguments: %\n" command arguments
--kill the cmd and related conhost if the platform is ps3
case platform of
(
1: --PS3
(
RS_buildBranch = substituteString RS_buildBranch "dev_ng" "dev"
local startInfo = dotnetobject "System.Diagnostics.ProcessStartInfo"
startInfo.createnowindow = true
startInfo.workingdirectory = RS_buildBranch
startInfo.UseShellExecute = false
startInfo.filename = command -- pathConfig.appendPath RS_buildBranch
local proc = dotnetobject "System.Diagnostics.Process"
proc.startinfo = startInfo
startInfo.arguments = arguments
proc.Start()
sleep 2
local conhostProcs = proc.GetProcessesByName "conhost"
local conhostProc = conhostProcs[conhostProcs.count]
proc.kill()
conhostProc.kill()
)
default:
(
HiddenDOSCommand (command + " " + arguments) startpath:RS_buildBranch donotwait:true
)
)
--set config for last used preset
gameLauncher.lastPreset = ddlPreset.selected
gameLauncher.lastCommand = command
gameLauncher.platform = gameLauncher.platformList[radPlatform.selection ]
gameLauncher.lastBuildType = radRelease.state
--gameLauncher.release = gameLauncher.releaseList[radRelease.state]
gameLauncher.saveConfig()
--kill the mapCoords window if open
try( DestroyDialog MapCoords )catch()
)
--////////////////////////////////////////////////////
--shutdown
on GameLauncherUI close do
(
callbacks.removeScripts id:#gameLauncher
--save the current dialog position to the config file
windowPos = GetDialogPos GamelauncherUI
gameLauncher.saveWindowPos windowPos
try( DestroyDialog MapCoords )catch()
)
)
--set the window position
--if gameLauncher.windowPos != undefined then SetDialogPos GamelauncherUI gameLauncher.windowPos
if gameLauncher.windowPos != undefined then
(
createDialog GamelauncherUI pos:[gameLauncher.windowPos.x, gameLauncher.windowPos.y] style:#(#style_titlebar, #style_border, #style_sysmenu, #style_minimizebox)
addSubRollout GamelauncherUI.flags flags
)
else
(
createDialog GamelauncherUI pos:[200, 200] style:#(#style_titlebar, #style_border, #style_sysmenu, #style_minimizebox)
addSubRollout GamelauncherUI.flags flags
)
gameLauncher.rolloutUI = GameLauncherUI
gameLauncher.flagsUI = flags
gameLauncher.initSystem()
gameLauncher.setPreset "preset"
--populate rooms list
gameLauncher.getMiloInst()
gameLauncher.getContainerLocs()