├── .gitignore ├── README.md ├── advancedGameplaySettings.lua ├── gui ├── AdvancedGameplaySettingsScreen.lua ├── GameplaySettingsFoliageFrame.lua ├── GameplaySettingsLandscapingFrame.lua ├── GameplaySettingsPaintFrame.lua ├── GameplaySettingsPlaceableFrame.lua └── GameplaySettingsVehicleFrame.lua ├── icons ├── button_repaint.dds ├── button_repair.dds ├── tab_foliage.dds ├── tab_landscaping.dds ├── tab_paint.dds ├── tab_placeable.dds └── tab_vehicle.dds ├── modDesc.xml ├── store.dds └── xml ├── AdvancedGameplaySettingsScreen.xml ├── GameplaySettingsFoliageFrame.xml ├── GameplaySettingsLandscapingFrame.xml ├── GameplaySettingsPaintFrame.xml ├── GameplaySettingsPlaceableFrame.xml ├── GameplaySettingsVehicleFrame.xml └── guiProfiles.xml /.gitignore: -------------------------------------------------------------------------------- 1 | /.idea 2 | .settings/ 3 | .vscode/* 4 | .DS_Store -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # FS22 AdvancedGameplaySettings 2 | 3 | ``` 4 | author: scfmod 5 | url: https://github.com/scfmod/FS22_advancedGameplaySettings 6 | 7 | If you distribute this mod, always include this info. 8 | 9 | AND DO NOT UPLOAD IT TO MONATERY UPLOAD SERVICES. 10 | THIS CODE IS AVAILABLE TO ANYONE FOR FREE AND YOU CAN USE 11 | IT TO LEARN, FORK AND SPREAD THE KNOWLEDGE. 12 | ``` 13 | 14 | ## How to use 15 | 16 | When ingame press F9 to open settings screen. 17 | 18 | ## Config file 19 | 20 | The configuration is saved when you save the game. You can find the saved XML configuration file in 21 | ``` 22 | ..\My Games\FarmingSimulator22\modSettings\advancedGameplaySettings.xml 23 | ``` 24 | 25 | ## Multiplayer 26 | Multiplayer support has not been tested yet with this version. Full support is planned, so unless you know what you are doing I advice only to use it in singleplayer for now. 27 | 28 | ## Issues and suggestions 29 | 30 | Please use the issues section on GitHub repository to post bugs and/or suggestions for features. 31 | 32 | ## Screenshots 33 | 34 | ### Vehicle 35 | ![vehicle_options](https://user-images.githubusercontent.com/45406107/145823029-c3631308-d0ba-4938-a1b5-0c89e6a9022f.png) 36 | ### Landscaping 37 | ![landscaping_options](https://user-images.githubusercontent.com/45406107/145823011-2a2da9f4-abfe-419f-9098-9834744908ca.png) 38 | ### Foliage 39 | ![foliage_options](https://user-images.githubusercontent.com/45406107/145823004-7d00c44a-cf37-45bb-8825-13fb9a6b105a.png) 40 | ### Paint 41 | ![paint_options](https://user-images.githubusercontent.com/45406107/145823015-88bcf178-6eb9-41bb-b615-38382d9ceff7.png) 42 | ### Placeable 43 | ![placeable_options](https://user-images.githubusercontent.com/45406107/145823019-3a6ea7fd-7638-4653-a0cb-5b692aa6ac84.png) -------------------------------------------------------------------------------- /advancedGameplaySettings.lua: -------------------------------------------------------------------------------- 1 | --[[ 2 | AdvancedGameplaySettings 3 | 4 | author: scfmod 5 | url: https://github.com/scfmod/FS22_advancedGameplaySettings 6 | 7 | If you distribute this mod, always include this info. 8 | 9 | AND DO NOT UPLOAD IT TO MONATERY UPLOAD SERVICES. 10 | THIS CODE IS AVAILABLE TO ANYONE FOR FREE AND YOU CAN USE 11 | IT TO LEARN, FORK AND SPREAD THE KNOWLEDGE. 12 | ]] 13 | local modFolder = g_currentModDirectory 14 | source(modFolder .. 'gui/AdvancedGameplaySettingsScreen.lua') 15 | source(modFolder .. 'gui/GameplaySettingsVehicleFrame.lua') 16 | source(modFolder .. 'gui/GameplaySettingsLandscapingFrame.lua') 17 | source(modFolder .. 'gui/GameplaySettingsPlaceableFrame.lua') 18 | source(modFolder .. 'gui/GameplaySettingsFoliageFrame.lua') 19 | source(modFolder .. 'gui/GameplaySettingsPaintFrame.lua') 20 | 21 | ---@class AdvancedGameplaySettings 22 | ---@field modFolder string 23 | AdvancedGameplaySettings = { 24 | -- Note: Add landscaping options to the landscaping screen 25 | landscaping = { 26 | enableBetterCamera = false, 27 | disableMouseCollision = false, 28 | hardness = 0.2, 29 | strengthRaiseLower = 0.5, -- operation = Landscaping.OPERATION.RAISE or Landscaping.OPERATION.LOWER 30 | strengthFlatten = 0.5, -- operation = Landscaping.OPERATION.FLATTEN [level] 31 | strengthSmooth = 1.0, -- operation = Landscaping.OPERATION.SMOOTH [soften] 32 | strengthSlope = 5.0, -- operation = Landscaping.OPERATION.SLOPE 33 | 34 | costFactor = 1.0, 35 | disableAccessCheck = false, 36 | disableWaterlevelCheck = false, 37 | disableOverlapWithObjectsCheck = false, 38 | }, 39 | foliage = { 40 | costFactor = 1.0, 41 | disableAccessCheck = false, 42 | disableWaterlevelCheck = false, 43 | }, 44 | paint = { 45 | costFactor = 1.0, 46 | disableAccessCheck = false, 47 | disableWaterlevelCheck = false, 48 | }, 49 | placeable = { 50 | costFactor = 1.0, 51 | displacementCostFactor = 1.0, 52 | disableAccessCheck = false, 53 | enableOverlapWithObjects = false, 54 | disablePaintOperation = false, -- NO solution for this yet... 55 | disableTerrainDisplacement = false, 56 | disableRemoveFoliage = false, 57 | }, 58 | -- todo missions?? 59 | mission = {}, 60 | 61 | vehicle = { 62 | enableFrontloaderFix = false, 63 | disableCameraCollision = false, 64 | fuelUsageFactor = 1.0, -- TODO 65 | wearFactor = 1.0, 66 | repairCostFactor = 1.0, 67 | repaintCostFactor = 1.0, 68 | }, 69 | } 70 | 71 | 72 | function AdvancedGameplaySettings:loadMap() 73 | ---@diagnostic disable-next-line: lowercase-global 74 | g_advancedGameplaySettings = self 75 | g_advancedGameplaySettings.modFolder = modFolder 76 | 77 | self:loadFromXML() 78 | 79 | GameSettings.saveToXMLFile = Utils.appendedFunction(GameSettings.saveToXMLFile, 80 | AdvancedGameplaySettings.saveToXML 81 | ) 82 | 83 | -- Load custom GUI presets, profiles 84 | -- g_gui:loadProfiles(modFolder .. 'xml/guiProfiles.xml') 85 | 86 | ---@diagnostic disable-next-line: lowercase-global 87 | g_advancedGameplaySettingsScreen = AdvancedGameplaySettingsScreen.new(nil, nil, g_messageCenter, g_i18n, g_inputBinding) 88 | 89 | g_gui:loadGui(modFolder .. 'xml/GameplaySettingsVehicleFrame.xml', 'GameplaySettingsVehicleFrame', GameplaySettingsVehicleFrame.new(nil, nil), true) 90 | g_gui:loadGui(modFolder .. 'xml/GameplaySettingsLandscapingFrame.xml', 'GameplaySettingsLandscapingFrame', GameplaySettingsLandscapingFrame.new(nil, nil), true) 91 | g_gui:loadGui(modFolder .. 'xml/GameplaySettingsPlaceableFrame.xml', 'GameplaySettingsPlaceableFrame', GameplaySettingsPlaceableFrame.new(nil, nil), true) 92 | g_gui:loadGui(modFolder .. 'xml/GameplaySettingsFoliageFrame.xml', 'GameplaySettingsFoliageFrame', GameplaySettingsFoliageFrame.new(nil, nil), true) 93 | g_gui:loadGui(modFolder .. 'xml/GameplaySettingsPaintFrame.xml', 'GameplaySettingsPaintFrame', GameplaySettingsPaintFrame.new(nil, nil), true) 94 | g_gui:loadGui(modFolder .. 'xml/AdvancedGameplaySettingsScreen.xml', 'AdvancedGameplaySettingsScreen', g_advancedGameplaySettingsScreen) 95 | end 96 | 97 | local function getXMLSettingBool(xmlFile, type, name, default) 98 | g_advancedGameplaySettings:setTypeNameValue(type,name, Utils.getNoNil(getXMLBool(xmlFile, 'gameplaySettings.' .. type .. '.' .. name), default)) 99 | end 100 | 101 | local function setXMLSettingBool(xmlFile, type, name) 102 | local value = g_advancedGameplaySettings:getTypeNameValue(type, name) 103 | -- if value ~= nil then 104 | setXMLBool(xmlFile, 'gameplaySettings.' .. type .. '.' .. name, value) 105 | -- end 106 | end 107 | 108 | local function getXMLSettingFloat(xmlFile, type, name, default) 109 | g_advancedGameplaySettings:setTypeNameValue(type,name, Utils.getNoNil(getXMLFloat(xmlFile, 'gameplaySettings.' .. type .. '.' .. name), default)) 110 | end 111 | 112 | local function setXMLSettingFloat(xmlFile, type, name) 113 | local value = g_advancedGameplaySettings:getTypeNameValue(type, name) 114 | -- if value ~= nil then 115 | setXMLFloat(xmlFile, 'gameplaySettings.' .. type .. '.' .. name, value) 116 | -- end 117 | end 118 | 119 | 120 | function AdvancedGameplaySettings.saveToXML() 121 | local filePath = g_modSettingsDirectory .. 'advancedGameplaySettings.xml' 122 | local xmlFile = createXMLFile('advancedGameplaySetting', filePath, 'gameplaySettings') 123 | 124 | if xmlFile == nil or xmlFile == 0 then 125 | print('AdvancedGameplaySettings.saveToXML: Failed to create XML file') 126 | return 127 | end 128 | 129 | -- Landscaping 130 | setXMLSettingBool(xmlFile, 'landscaping', 'enableBetterCamera') 131 | setXMLSettingBool(xmlFile, 'landscaping', 'disableMouseCollision') 132 | setXMLSettingFloat(xmlFile, 'landscaping', 'hardness') 133 | setXMLSettingFloat(xmlFile, 'landscaping', 'strengthRaiseLower') 134 | setXMLSettingFloat(xmlFile, 'landscaping', 'strengthFlatten') 135 | setXMLSettingFloat(xmlFile, 'landscaping', 'strengthSmooth') 136 | setXMLSettingFloat(xmlFile, 'landscaping', 'strengthSlope') 137 | setXMLSettingFloat(xmlFile, 'landscaping', 'costFactor') 138 | setXMLSettingBool(xmlFile, 'landscaping', 'disableAccessCheck') 139 | setXMLSettingBool(xmlFile, 'landscaping', 'disableWaterlevelCheck') 140 | setXMLSettingBool(xmlFile, 'landscaping', 'disableOverlapWithObjectsCheck') 141 | 142 | -- Foliage 143 | setXMLSettingFloat(xmlFile, 'foliage', 'costFactor') 144 | setXMLSettingBool(xmlFile, 'foliage', 'disableAccessCheck') 145 | setXMLSettingBool(xmlFile, 'foliage', 'disableWaterlevelCheck') 146 | 147 | -- Paint 148 | setXMLSettingFloat(xmlFile, 'paint', 'costFactor') 149 | setXMLSettingBool(xmlFile, 'paint', 'disableAccessCheck') 150 | setXMLSettingBool(xmlFile, 'paint', 'disableWaterlevelCheck') 151 | 152 | -- Placeable 153 | setXMLSettingFloat(xmlFile, 'placeable', 'costFactor') 154 | setXMLSettingFloat(xmlFile, 'placeable', 'displacementCostFactor') 155 | setXMLSettingBool(xmlFile, 'placeable', 'disableAccessCheck') 156 | setXMLSettingBool(xmlFile, 'placeable', 'enableOverlapWithObjects') 157 | setXMLSettingBool(xmlFile, 'placeable', 'disablePaintOperation') 158 | setXMLSettingBool(xmlFile, 'placeable', 'disableTerrainDisplacement') 159 | setXMLSettingBool(xmlFile, 'placeable', 'disableRemoveFoliage') 160 | 161 | -- Vehicle 162 | setXMLSettingBool(xmlFile, 'vehicle', 'enableFrontloaderFix') 163 | setXMLSettingBool(xmlFile, 'vehicle', 'disableCameraCollision') 164 | setXMLSettingFloat(xmlFile, 'vehicle', 'wearFactor') 165 | setXMLSettingFloat(xmlFile, 'vehicle', 'repairCostFactor') 166 | setXMLSettingFloat(xmlFile, 'vehicle', 'repaintCostFactor') 167 | 168 | print('AdvancedGameplaySettings: Saving XML configuration ..') 169 | saveXMLFile(xmlFile) 170 | delete(xmlFile) 171 | end 172 | 173 | function AdvancedGameplaySettings:loadFromXML() 174 | local filePath = g_modSettingsDirectory .. 'advancedGameplaySettings.xml' 175 | 176 | if not fileExists(filePath) then 177 | return 178 | end 179 | 180 | local xmlFile = loadXMLFile('advancedGameplaySettings', filePath) 181 | if xmlFile == nil or xmlFile == 0 then 182 | print('AdvancedGameplaySettings.loadFromXML: Failed to load XML file') 183 | return 184 | end 185 | 186 | -- Landscaping 187 | getXMLSettingBool(xmlFile, 'landscaping', 'enableBetterCamera', false) 188 | getXMLSettingBool(xmlFile, 'landscaping', 'disableMouseCollision', false) 189 | getXMLSettingFloat(xmlFile, 'landscaping', 'hardness', 0.2) 190 | getXMLSettingFloat(xmlFile, 'landscaping', 'strengthRaiseLower', 0.5) 191 | getXMLSettingFloat(xmlFile, 'landscaping', 'strengthFlatten', 0.5) 192 | getXMLSettingFloat(xmlFile, 'landscaping', 'strengthSmooth', 1.0) 193 | getXMLSettingFloat(xmlFile, 'landscaping', 'strengthSlope', 5.0) 194 | getXMLSettingFloat(xmlFile, 'landscaping', 'costFactor', 1.0) 195 | getXMLSettingBool(xmlFile, 'landscaping', 'disableAccessCheck', false) 196 | getXMLSettingBool(xmlFile, 'landscaping', 'disableWaterlevelCheck', false) 197 | getXMLSettingBool(xmlFile, 'landscaping', 'disableOverlapWithObjectsCheck', false) 198 | 199 | -- Foliage 200 | getXMLSettingFloat(xmlFile, 'foliage', 'costFactor', 1.0) 201 | getXMLSettingBool(xmlFile, 'foliage', 'disableAccessCheck', false) 202 | getXMLSettingBool(xmlFile, 'foliage', 'disableWaterlevelCheck', false) 203 | 204 | -- Paint 205 | getXMLSettingFloat(xmlFile, 'paint', 'costFactor', 1.0) 206 | getXMLSettingBool(xmlFile, 'paint', 'disableAccessCheck', false) 207 | getXMLSettingBool(xmlFile, 'paint', 'disableWaterlevelCheck', false) 208 | 209 | -- Placeable 210 | getXMLSettingFloat(xmlFile, 'placeable', 'costFactor', 1.0) 211 | getXMLSettingFloat(xmlFile, 'placeable', 'displacementCostFactor', 1.0) 212 | getXMLSettingBool(xmlFile, 'placeable', 'disableAccessCheck', false) 213 | getXMLSettingBool(xmlFile, 'placeable', 'enableOverlapWithObjects', false) 214 | getXMLSettingBool(xmlFile, 'placeable', 'disablePaintOperation', false) 215 | getXMLSettingBool(xmlFile, 'placeable', 'disableTerrainDisplacement', false) 216 | getXMLSettingBool(xmlFile, 'placeable', 'disableRemoveFoliage', false) 217 | 218 | -- Vehicle 219 | getXMLSettingBool(xmlFile, 'vehicle', 'enableFrontloaderFix', false) 220 | getXMLSettingBool(xmlFile, 'vehicle', 'disableCameraCollision', false) 221 | 222 | -- getXMLSettingFloat(xmlFile, 'vehicle', 'fuelUsageFactor', 1.0) 223 | getXMLSettingFloat(xmlFile, 'vehicle', 'wearFactor', 1.0) 224 | getXMLSettingFloat(xmlFile, 'vehicle', 'repairCostFactor', 1.0) 225 | getXMLSettingFloat(xmlFile, 'vehicle', 'repaintCostFactor', 1.0) 226 | 227 | delete(xmlFile) 228 | end 229 | 230 | function AdvancedGameplaySettings:updateCameraSettings() 231 | if self.landscaping.enableBetterCamera ~= true then 232 | GuiTopDownCamera.ROTATION_MIN_X_FAR = 50 233 | GuiTopDownCamera.ROTATION_MIN_X_NEAR = 10 234 | else 235 | GuiTopDownCamera.ROTATION_MIN_X_FAR = 0 236 | GuiTopDownCamera.ROTATION_MIN_X_NEAR = 0 237 | end 238 | end 239 | 240 | ---@param type string 241 | ---@param name string 242 | ---@param value any 243 | function AdvancedGameplaySettings:setTypeNameValue(type, name, value) 244 | AdvancedGameplaySettings[type][name] = value 245 | 246 | if type == 'landscaping' then 247 | if name == 'enableBetterCamera' then 248 | self:updateCameraSettings() 249 | end 250 | end 251 | end 252 | 253 | function AdvancedGameplaySettings:getTypeNameValue(type, name) 254 | return AdvancedGameplaySettings[type][name] 255 | end 256 | 257 | function AdvancedGameplaySettings:keyEvent(unicode, sym, modifier, isDown) 258 | if not isDown then 259 | return 260 | end 261 | 262 | -- keycode for F9 263 | if sym == 290 then 264 | g_gui:showGui('AdvancedGameplaySettingsScreen') 265 | elseif sym == 289 then -- F8 - DEBUGGING TABLE 266 | DebugUtil.printTableRecursively(g_advancedGameplaySettings) 267 | end 268 | end 269 | 270 | --[[ 271 | Override hardness of landscaping brush tool 272 | ]] 273 | 274 | function AdvancedGameplaySettings.addTerrainDeformationWorldspaceSoftBrush(func, deformationId, x, z, brushType, radius, hardness, strength, terrainBrushId) 275 | local overrideHardness = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('landscaping', 'hardness'), 0.2) 276 | func(deformationId, x, z, brushType, radius, overrideHardness, strength, terrainBrushId) 277 | end 278 | 279 | ---@diagnostic disable-next-line: lowercase-global 280 | addTerrainDeformationWorldspaceSoftBrush = Utils.overwrittenFunction( 281 | addTerrainDeformationWorldspaceSoftBrush, 282 | AdvancedGameplaySettings.addTerrainDeformationWorldspaceSoftBrush 283 | ) 284 | 285 | 286 | --[[ 287 | Frontloader fix 288 | 289 | Prevents locking joints when attaching frontloader to your tractor. 290 | ]] 291 | 292 | ---@diagnostic disable-next-line: unused-local 293 | local overrideJointRotLimit = false 294 | 295 | FrontloaderAttacher.onPreAttachImplement = Utils.prependedFunction(FrontloaderAttacher.onPreAttachImplement, 296 | function() 297 | overrideJointRotLimit = true 298 | end 299 | ) 300 | 301 | FrontloaderAttacher.onPreAttachImplement = Utils.appendedFunction(FrontloaderAttacher.onPreAttachImplement, 302 | function() 303 | overrideJointRotLimit = false 304 | end 305 | ) 306 | 307 | Vehicle.setComponentJointRotLimit = Utils.overwrittenFunction(Vehicle.setComponentJointRotLimit, 308 | ---@param self Vehicle 309 | function(self, func, ...) 310 | if overrideJointRotLimit == true and Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('vehicle', 'enableFrontloaderFix'), false) == true then 311 | return 312 | end 313 | func(self, ...) 314 | end 315 | ) 316 | 317 | 318 | --[[ 319 | Disable camera collision when in vehicle 320 | 321 | Okay so this is a gem.. haha 322 | Basically Giants hardcoded the setting to be only be displayed in General settings UI if there is a mod 323 | loaded named 'FS22_disableVehicleCameraCollision'. 324 | ]] 325 | 326 | 327 | VehicleCamera.getCollisionDistance = Utils.overwrittenFunction(VehicleCamera.getCollisionDistance, 328 | function(self, func, ...) 329 | if Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('vehicle', 'disableCameraCollision'), false) ~= true then 330 | return func(self, ...) 331 | end 332 | 333 | return false, nil 334 | end 335 | ) 336 | 337 | 338 | --[[ 339 | Disable mouse collision on objects when landscaping 340 | ]] 341 | 342 | GuiTopDownCursor.setSelectionMode = Utils.overwrittenFunction(GuiTopDownCursor.setSelectionMode, 343 | ---@param self GuiTopDownCursor 344 | function(self, func, isSelection) 345 | func(self, isSelection) 346 | if isSelection then 347 | self.rayCollisionMask = CollisionMask.ALL - CollisionMask.TRIGGERS - CollisionFlag.FILLABLE 348 | else 349 | if Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('landscaping', 'disableMouseCollision'), false) ~= true then 350 | self.rayCollisionMask = CollisionMask.ALL - CollisionMask.TRIGGERS - CollisionFlag.FILLABLE - CollisionFlag.GROUND_TIP_BLOCKING 351 | else 352 | self.rayCollisionMask = CollisionFlag.TERRAIN 353 | end 354 | end 355 | end 356 | ) 357 | 358 | 359 | --[[ 360 | Override sculpting strength 361 | ]] 362 | 363 | Landscaping.sculpt = Utils.overwrittenFunction(Landscaping.sculpt, 364 | function(self, func, x, y, z, nx, ny, nz, d, minY, maxY, radius, strength, brushShape, operation, smoothingDistance, terrainPaintingLayer, terrainFoliageLayer, terrainFoliageValue) 365 | local newStrength = strength 366 | 367 | if operation == Landscaping.OPERATION.SMOOTH then 368 | newStrength = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('landscaping', 'strengthSmooth'), 1.0) 369 | elseif operation == Landscaping.OPERATION.FLATTEN then 370 | newStrength = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('landscaping', 'strengthFlatten'), 0.5) 371 | elseif operation == Landscaping.OPERATION.SLOPE then 372 | newStrength = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('landscaping', 'strengthSlope'), 5.0) 373 | elseif operation == Landscaping.OPERATION.LOWER or operation == Landscaping.OPERATION.RAISE then 374 | newStrength = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('landscaping', 'strengthRaiseLower'), 0.5) 375 | end 376 | 377 | func(self, x, y, z, nx, ny, nz, d, minY, maxY, radius, newStrength, brushShape, operation, smoothingDistance, terrainPaintingLayer, terrainFoliageLayer, terrainFoliageValue) 378 | end 379 | ) 380 | 381 | 382 | --[[ 383 | Permission override functions 384 | ]] 385 | 386 | function AdvancedGameplaySettings.hasPermission(type) 387 | return function(self, func, ...) 388 | local override = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue(type, 'disableAccessCheck'), false) 389 | 390 | if override ~= true then 391 | return func(self, ...) 392 | end 393 | 394 | return true 395 | end 396 | end 397 | 398 | function AdvancedGameplaySettings.hasAccess(type) 399 | return function(self, func, ...) 400 | local override = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue(type, 'disableAccessCheck'), false) 401 | 402 | if override ~= true then 403 | return func(self, ...) 404 | end 405 | 406 | return nil 407 | end 408 | end 409 | 410 | 411 | --[[ 412 | Landscaping: Override access checks 413 | 414 | Foliage, sculpting, painting 415 | ]] 416 | 417 | 418 | local currentLandscapingOperation = nil 419 | 420 | Landscaping.onSculptingValidated = Utils.prependedFunction(Landscaping.onSculptingValidated, 421 | function(self) 422 | currentLandscapingOperation = self.sculptingOperation 423 | end 424 | ) 425 | 426 | Landscaping.onSculptingValidated = Utils.appendedFunction(Landscaping.onSculptingValidated, 427 | function() 428 | currentLandscapingOperation = nil 429 | end 430 | ) 431 | 432 | Landscaping.isModificationAreaOnOwnedLand = Utils.overwrittenFunction(Landscaping.isModificationAreaOnOwnedLand, 433 | function(self, func, ...) 434 | if currentLandscapingOperation == nil then 435 | return func(self, ...) 436 | end 437 | 438 | return true 439 | end 440 | ) 441 | 442 | -- FOR OVERRIDING ERROR MESSAGES 443 | -- If we don't include this the error messages will prevent us from utilizing the override functions above 444 | 445 | ConstructionBrushPaint.verifyAccess = Utils.overwrittenFunction(ConstructionBrushPaint.verifyAccess, 446 | AdvancedGameplaySettings.hasAccess('paint') 447 | ) 448 | ConstructionBrushPaint.hasPlayerPermission = Utils.overwrittenFunction(ConstructionBrushPaint.hasPlayerPermission, 449 | AdvancedGameplaySettings.hasPermission('paint') 450 | ) 451 | 452 | ConstructionBrushSculpt.verifyAccess = Utils.overwrittenFunction(ConstructionBrushSculpt.verifyAccess, 453 | AdvancedGameplaySettings.hasAccess('landscaping') 454 | ) 455 | ConstructionBrushSculpt.hasPlayerPermission = Utils.overwrittenFunction(ConstructionBrushSculpt.hasPlayerPermission, 456 | AdvancedGameplaySettings.hasPermission('landscaping') 457 | ) 458 | 459 | ConstructionBrushFoliage.verifyAccess = Utils.overwrittenFunction(ConstructionBrushFoliage.verifyAccess, 460 | AdvancedGameplaySettings.hasAccess('foliage') 461 | ) 462 | 463 | ConstructionBrushFoliage.hasPlayerPermission = Utils.overwrittenFunction(ConstructionBrushFoliage.hasPlayerPermission, 464 | AdvancedGameplaySettings.hasPermission('foliage') 465 | ) 466 | 467 | 468 | 469 | --[[ 470 | Override water level validation function 471 | ]] 472 | 473 | function AdvancedGameplaySettings.validateWaterLevel(self, func, y, strength, operation) 474 | local override = false 475 | 476 | if operation == Landscaping.OPERATION.FOLIAGE then 477 | override = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('foliage', 'disableWaterlevelCheck'), false) 478 | elseif operation == Landscaping.OPERATION.PAINT then 479 | override = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('paint','disableWaterlevelCheck'), false) 480 | else -- Sculpt operation 481 | override = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('landscaping', 'disableWaterlevelCheck'), false) 482 | end 483 | 484 | if override ~= true then 485 | return func(self, y, strength, operation) 486 | end 487 | 488 | return true 489 | end 490 | 491 | Landscaping.validateWaterLevel = Utils.overwrittenFunction(Landscaping.validateWaterLevel, 492 | AdvancedGameplaySettings.validateWaterLevel 493 | ) 494 | 495 | 496 | 497 | --[[ 498 | Placeables: Override access checks 499 | 500 | Fence, tree 501 | ]] 502 | 503 | ConstructionBrushTree.verifyAccess = Utils.overwrittenFunction(ConstructionBrushTree.verifyAccess, 504 | AdvancedGameplaySettings.hasAccess('placeable') 505 | ) 506 | ConstructionBrushTree.hasPlayerPermission = Utils.overwrittenFunction(ConstructionBrushTree.hasPlayerPermission, 507 | AdvancedGameplaySettings.hasPermission('placeable') 508 | ) 509 | 510 | ConstructionBrushFence.verifyAccess = Utils.overwrittenFunction(ConstructionBrushFence.verifyAccess, 511 | AdvancedGameplaySettings.hasAccess('placeable') 512 | ) 513 | ConstructionBrushFence.hasPlayerPermission = Utils.overwrittenFunction(ConstructionBrushFence.hasPlayerPermission, 514 | AdvancedGameplaySettings.hasPermission('placeable') 515 | ) 516 | 517 | 518 | 519 | --[[ 520 | Placeable: Override access checks 521 | 522 | Placeable objects, decorations 523 | ]] 524 | 525 | 526 | ConstructionBrushPlaceable.verifyAccess = Utils.overwrittenFunction(ConstructionBrushPlaceable.verifyAccess, 527 | AdvancedGameplaySettings.hasAccess('placeable') 528 | ) 529 | 530 | ConstructionBrushPlaceable.hasPlayerPermission = Utils.overwrittenFunction(ConstructionBrushPlaceable.hasPlayerPermission, 531 | AdvancedGameplaySettings.hasPermission('placeable') 532 | ) 533 | 534 | 535 | --[[ 536 | Landscaping actions 537 | 538 | Override prices 539 | ]] 540 | 541 | function AdvancedGameplaySettings.getPrice(type) 542 | return function(self, func, ...) 543 | local price = func(self, ...) 544 | local factor = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue(type, 'costFactor'), 1.0) 545 | 546 | return price * factor 547 | end 548 | end 549 | 550 | 551 | -- FOLIAGE, PAINTING, SCULPTING 552 | 553 | Landscaping.getCost = Utils.overwrittenFunction( 554 | Landscaping.getCost, 555 | function(self, func, ...) 556 | local cost = func(self, ...) 557 | 558 | local type 559 | 560 | if self.sculptingOperation == Landscaping.OPERATION.FOLIAGE then 561 | type = 'foliage' 562 | elseif self.sculptingOperation == Landscaping.OPERATION.PAINT then 563 | type = 'paint' 564 | else 565 | type = 'landscaping' 566 | end 567 | 568 | local factor = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue(type, 'costFactor'), 1.0) 569 | 570 | return cost * factor 571 | end 572 | ) 573 | 574 | -- PLACEABLES 575 | 576 | Placeable.getPrice = Utils.overwrittenFunction(Placeable.getPrice, 577 | function(self, func) 578 | local price = func(self) 579 | local factor = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('placeable', 'costFactor'), 1.0) 580 | 581 | return price * factor 582 | end 583 | ) 584 | 585 | ConstructionBrushPlaceable.getPrice = Utils.overwrittenFunction(ConstructionBrushPlaceable.getPrice, 586 | AdvancedGameplaySettings.getPrice('placeable') 587 | ) 588 | 589 | ConstructionBrushPlaceable.getDisplacementCost = Utils.overwrittenFunction(ConstructionBrushPlaceable.getDisplacementCost, 590 | function(self, func, ...) 591 | local cost = func(self, ...) 592 | local factor = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('placeable', 'displacementCostFactor'), 1.0) 593 | local disableTerrainDisplacement = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('placeable', 'disableTerrainDisplacement'), false) 594 | 595 | if disableTerrainDisplacement ~= true then 596 | return cost * factor 597 | end 598 | 599 | return 0 600 | end 601 | ) 602 | 603 | -- To override the price on placeable objects (except for trees and fences) we 604 | -- have to do some stuff with BuyPlaceableEvent and EconomyManager .. 605 | 606 | local overrideGetBuyPrice = false 607 | 608 | BuyPlaceableEvent.run = Utils.prependedFunction(BuyPlaceableEvent.run, 609 | function() 610 | overrideGetBuyPrice = true 611 | end 612 | ) 613 | 614 | BuyPlaceableEvent.run = Utils.appendedFunction(BuyPlaceableEvent.run, 615 | function() 616 | overrideGetBuyPrice = false 617 | end 618 | ) 619 | 620 | EconomyManager.getBuyPrice = Utils.overwrittenFunction(EconomyManager.getBuyPrice, 621 | function(self, func, ...) 622 | if overrideGetBuyPrice ~= true then 623 | return func(self, ...) 624 | end 625 | 626 | local price = func(self, ...) 627 | 628 | local factor = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('placeable', 'costFactor'), 1.0) 629 | 630 | return price * factor 631 | end 632 | ) 633 | 634 | -- PLACEABLES: TREES 635 | 636 | ConstructionBrushTree.getPrice = Utils.overwrittenFunction(ConstructionBrushTree.getPrice, 637 | AdvancedGameplaySettings.getPrice('placeable') 638 | ) 639 | 640 | -- PLACEABLES: FENCE 641 | 642 | ConstructionBrushFence.getPrice = Utils.overwrittenFunction(ConstructionBrushFence.getPrice, 643 | AdvancedGameplaySettings.getPrice('placeable') 644 | ) 645 | 646 | 647 | 648 | --[[ 649 | ConstructionBrushFence 650 | 651 | Override overlap check specific for fence 652 | ]] 653 | 654 | 655 | ConstructionBrushFence.boxOverlapCallback = Utils.overwrittenFunction(ConstructionBrushFence.boxOverlapCallback, 656 | function (self, func, ...) 657 | if Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('placeable', 'enableOverlapWithObjects'), false) ~= true then 658 | func(self, ...) 659 | end 660 | end 661 | ) 662 | 663 | 664 | 665 | 666 | --[[ 667 | Override overlap checks for placeables 668 | 669 | getHasOverlap 670 | getHasOverlapWithPlaces 671 | getHasOverlapWithZones 672 | ]] 673 | 674 | PlaceablePlacement.getHasOverlap = Utils.overwrittenFunction(PlaceablePlacement.getHasOverlap, 675 | function (self, func, ...) 676 | if Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('placeable', 'enableOverlapWithObjects'), false) ~= true then 677 | return func(self, ...) 678 | end 679 | 680 | return false 681 | end 682 | ) 683 | 684 | PlaceablePlacement.getHasOverlapWithPlaces = Utils.overwrittenFunction(PlaceablePlacement.getHasOverlapWithPlaces, 685 | function (self, func, ...) 686 | if Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('placeable', 'disableAccessCheck'), false) ~= true then 687 | return func(self, ...) 688 | end 689 | 690 | return false 691 | end 692 | ) 693 | 694 | PlaceablePlacement.getHasOverlapWithZones = Utils.overwrittenFunction(PlaceablePlacement.getHasOverlapWithZones, 695 | function (self, func, ...) 696 | if Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('placeable', 'disableAccessCheck'), false) ~= true then 697 | return func(self, ...) 698 | end 699 | 700 | return false 701 | end 702 | ) 703 | 704 | 705 | --[[ 706 | Disable terrain displacement for placeables 707 | ]] 708 | 709 | PlaceableLeveling.getRequiresLeveling = Utils.overwrittenFunction(PlaceableLeveling.getRequiresLeveling, 710 | function(self, func) 711 | if Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('placeable', 'disableTerrainDisplacement'), false) ~= true then 712 | return func(self) 713 | end 714 | 715 | return false 716 | end 717 | ) 718 | 719 | PlaceableLeveling.getDeformationObjects = Utils.overwrittenFunction(PlaceableLeveling.getDeformationObjects, 720 | function(self, func, terrainRootNode, forBlockingOnly, isBlocking) 721 | if Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('placeable', 'disableTerrainDisplacement'), false) ~= true then 722 | return func(self, terrainRootNode, forBlockingOnly, isBlocking) 723 | end 724 | 725 | return {} 726 | end 727 | ) 728 | 729 | --[[ 730 | Disable removing foliage on terrain when placing objects 731 | ]] 732 | 733 | PlaceableClearAreas.onPostFinalizePlacement = Utils.overwrittenFunction(PlaceableClearAreas.onPostFinalizePlacement, 734 | function(self, func) 735 | if Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('placeable', 'disableRemoveFoliage'), false) ~= true then 736 | return func(self) 737 | end 738 | end 739 | ) 740 | 741 | 742 | --[[ 743 | Override repair and repaint costs 744 | ]] 745 | 746 | 747 | local overrideAddMoney = false 748 | 749 | Wearable.repaintVehicle = Utils.prependedFunction(Wearable.repaintVehicle, 750 | function() 751 | overrideAddMoney = true 752 | end 753 | ) 754 | Wearable.repaintVehicle = Utils.appendedFunction(Wearable.repaintVehicle, 755 | function() 756 | overrideAddMoney = false 757 | end 758 | ) 759 | 760 | Wearable.repairVehicle = Utils.prependedFunction(Wearable.repairVehicle, 761 | function() 762 | overrideAddMoney = true 763 | end 764 | ) 765 | Wearable.repairVehicle = Utils.appendedFunction(Wearable.repairVehicle, 766 | function() 767 | overrideAddMoney = false 768 | end 769 | ) 770 | 771 | FSBaseMission.addMoney = Utils.overwrittenFunction(FSBaseMission.addMoney, 772 | function(self, func, amount, ...) 773 | if overrideAddMoney ~= true then 774 | return func(self, amount, ...) 775 | end 776 | 777 | local factor = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('vehicle', 'repaintCostFactor'), 1.0) 778 | local price = amount * factor 779 | 780 | func(self, price, ...) 781 | end 782 | ) 783 | 784 | --[[ 785 | Override wear and damage amount 786 | ]] 787 | 788 | Wearable.updateDamageAmount = Utils.overwrittenFunction(Wearable.updateDamageAmount, 789 | function(self, func, ...) 790 | local amount = func(self, ...) 791 | local factor = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('vehicle', 'wearFactor'), 1.0) 792 | 793 | return amount * factor 794 | end 795 | ) 796 | 797 | 798 | --[[ 799 | Override FillUnit:addUnitFillLevel 800 | ]] 801 | 802 | -- FillUnit.addFillUnitFillLevel = Utils.overwrittenFunction(FillUnit.addFillUnitFillLevel, 803 | -- function(self, func, farmId, fillUnitIndex, fillLevelDelta, fillTypeIndex, ...) 804 | -- if (fillType ~= FillType.DIESEL and fillType ~= FillType.METHANE and fillType ~= FillType.ELECTRICCHARGE) or fillLevelDelta >= 0 then 805 | -- return func(self, farmId, fillUnitIndex, fillLevelDelta, fillTypeIndex, ...) 806 | -- end 807 | 808 | -- local factor = Utils.getNoNil(g_advancedGameplaySettings:getTypeNameValue('vehicle', 'fuelUsageFactor'), 1.0) 809 | -- local usageDelta = fillLevelDelta * factor 810 | 811 | -- return func(self, farmId, fillUnitIndex, usageDelta, fillTypeIndex, ...) 812 | -- end 813 | -- ) 814 | 815 | -- We also should update spec.lastFuelUsage but cant be arsed really.. 816 | 817 | 818 | 819 | 820 | --[[ 821 | Note on: 822 | Overriding Wearable.getRepairPrice and Wearable.getRepaintPrice 823 | 824 | Some logic points that use the result values will skip repairing/repainting if 825 | the return value from these functions are 0 826 | 827 | So best not to override these ones unless you return at least value > 0 828 | ]] 829 | 830 | 831 | 832 | 833 | --[[ 834 | Repair all vehicles/implements 835 | ]] 836 | 837 | 838 | 839 | function AdvancedGameplaySettings:repairAllVehicles() 840 | for _, vehicle in pairs(g_currentMission.vehicles) do 841 | local spec = vehicle.spec_wearable 842 | if spec ~= nil then 843 | vehicle:repairVehicle() 844 | 845 | -- vehicle:setDamageAmount(0) 846 | -- vehicle:raiseDirtyFlags(vehicle.spec_wearable.dirtyFlag) 847 | end 848 | end 849 | end 850 | 851 | 852 | function AdvancedGameplaySettings:repaintAllVehicles() 853 | for _, vehicle in pairs(g_currentMission.vehicles) do 854 | local spec = vehicle.spec_wearable 855 | if spec ~= nil then 856 | vehicle:repaintVehicle() 857 | 858 | -- for _, data in ipairs(spec.wearableNodes) do 859 | -- vehicle:setNodeWearAmount(data, 0, true) 860 | -- end 861 | -- vehicle:raiseDirtyFlags(spec.dirtyFlag) 862 | end 863 | end 864 | end 865 | 866 | 867 | 868 | --[[ 869 | [NOT IN USE, FOR DOCUMENTATION ONLY] 870 | Override GuiOverlay:loadOverlay 871 | 872 | This is needed to enable custom overlay file with modDir path .. 873 | In guiProfile.xml the standard one is 'g_baseUIFilename' which is hardcoded. 874 | The only way to set your own with a custom path outside game folder is overriding the result of GuiOverlay.loadOverlay function 875 | ]] 876 | 877 | -- function AdvancedGameplaySettings.loadOverlay(self, func, overlay, overlayName, imageSize, profile, xmlFile, key) 878 | -- local _overlay = func(self, overlay, overlayName, imageSize, profile, xmlFile, key) 879 | 880 | -- if _overlay ~= nil and _overlay.filename == 'g_customBaseUIFilename' then 881 | -- _overlay.filename = modFolder .. 'hud/ui_elements.png' 882 | -- end 883 | 884 | -- return _overlay 885 | -- end 886 | 887 | -- GuiOverlay.loadOverlay = Utils.overwrittenFunction( 888 | -- GuiOverlay.loadOverlay, 889 | -- AdvancedGameplaySettings.loadOverlay 890 | -- ) 891 | 892 | 893 | addModEventListener(AdvancedGameplaySettings) -------------------------------------------------------------------------------- /gui/AdvancedGameplaySettingsScreen.lua: -------------------------------------------------------------------------------- 1 | ---@class AdvancedGameplaySettingsScreen 2 | ---@field pageOptionsVehicle GameplaySettingsVehicleFrame 3 | ---@field pageOptionsPlaceable GameplaySettingsPlaceableFrame 4 | ---@field pageOptionsFoliage GameplaySettingsFoliageFrame 5 | ---@field pageOptionsPaint GameplaySettingsPaintFrame 6 | ---@field pageOptionsLandscaping GameplaySettingsFoliageFrame 7 | AdvancedGameplaySettingsScreen = {} 8 | local AdvancedGameplaySettingsScreen_mt = Class(AdvancedGameplaySettingsScreen, TabbedMenuWithDetails) 9 | 10 | AdvancedGameplaySettingsScreen.CONTROLS = { 11 | 'pageOptionsVehicle', 12 | 'pageOptionsPlaceable', 13 | 'pageOptionsPaint', 14 | 'pageOptionsFoliage', 15 | 'pageOptionsLandscaping', 16 | } 17 | 18 | function AdvancedGameplaySettingsScreen.new(target, customMt, messageCenter, l10n, inputManager) 19 | local self = TabbedMenuWithDetails.new(target, customMt or AdvancedGameplaySettingsScreen_mt, messageCenter, l10n, inputManager) 20 | 21 | self:registerControls(AdvancedGameplaySettingsScreen.CONTROLS) 22 | 23 | return self 24 | end 25 | 26 | function AdvancedGameplaySettingsScreen:onGuiSetupFinished() 27 | AdvancedGameplaySettingsScreen:superClass().onGuiSetupFinished(self) 28 | 29 | self.clickBackCallback = self:makeSelfCallback(self.onButtonBack) 30 | 31 | self.pageOptionsVehicle:initialize() 32 | self.pageOptionsPaint:initialize() 33 | self.pageOptionsFoliage:initialize() 34 | self.pageOptionsLandscaping:initialize() 35 | 36 | self:setupPages() 37 | self:setupMenuButtonInfo() 38 | end 39 | 40 | function AdvancedGameplaySettingsScreen:setupPages() 41 | local pages = { 42 | { 43 | self.pageOptionsVehicle, 44 | 'tab_vehicle.png' 45 | }, 46 | { 47 | self.pageOptionsLandscaping, 48 | 'tab_landscaping.png' 49 | }, 50 | { 51 | self.pageOptionsFoliage, 52 | 'tab_foliage.png' 53 | }, 54 | { 55 | self.pageOptionsPaint, 56 | 'tab_paint.png' 57 | }, 58 | { 59 | self.pageOptionsPlaceable, 60 | 'tab_placeable.png' 61 | }, 62 | } 63 | 64 | for i, _page in ipairs(pages) do 65 | local page, icon = unpack(_page) 66 | self:registerPage(page, i) 67 | self:addPageTab(page, g_advancedGameplaySettings.modFolder .. 'icons/' .. icon) 68 | end 69 | 70 | 71 | -- For using UVs: 72 | 73 | -- for i, pageDef in ipairs(pages) do 74 | -- local page, iconUVs = unpack(pageDef) 75 | 76 | -- self:registerPage(page, i) 77 | 78 | -- local normalizedUVs = GuiUtils.getUVs(iconUVs) 79 | -- self:addPageTab(page, g_iconsUIFilename, normalizedUVs) 80 | -- end 81 | end 82 | 83 | function AdvancedGameplaySettingsScreen:setupMenuButtonInfo() 84 | local onButtonBackFunction = self.clickBackCallback 85 | self.defaultMenuButtonInfo = { 86 | { 87 | inputAction = InputAction.MENU_BACK, 88 | text = self.l10n:getText(InGameMenu.L10N_SYMBOL.BUTTON_BACK), 89 | callback = onButtonBackFunction 90 | } 91 | } 92 | self.defaultMenuButtonInfoByActions[InputAction.MENU_BACK] = self.defaultMenuButtonInfo[1] 93 | self.defaultButtonActionCallbacks = { 94 | [InputAction.MENU_BACK] = onButtonBackFunction, 95 | } 96 | end 97 | 98 | function AdvancedGameplaySettingsScreen:exitMenu() 99 | self:changeScreen() 100 | end -------------------------------------------------------------------------------- /gui/GameplaySettingsFoliageFrame.lua: -------------------------------------------------------------------------------- 1 | ---@class GameplaySettingsFoliageFrame 2 | ---@field disableAccessCheck CheckedOptionElement 3 | ---@field disableWaterlevelCheck CheckedOptionElement 4 | ---@field costFactor TextInputElement 5 | ---@field boxLayout BoxLayoutElement 6 | GameplaySettingsFoliageFrame = {} 7 | 8 | local GameplaySettingsFoliageFrame_mt = Class(GameplaySettingsFoliageFrame, TabbedMenuFrameElement) 9 | 10 | GameplaySettingsFoliageFrame.CONTROLS = { 11 | 'costFactor', 12 | 'disableAccessCheck', 13 | 'disableWaterlevelCheck', 14 | 15 | 'boxLayout' 16 | } 17 | 18 | function GameplaySettingsFoliageFrame.new(target, customMt) 19 | local self = TabbedMenuFrameElement.new(target, customMt or GameplaySettingsFoliageFrame_mt) 20 | 21 | self:registerControls(GameplaySettingsFoliageFrame.CONTROLS) 22 | 23 | return self 24 | end 25 | 26 | function GameplaySettingsFoliageFrame:initialize() 27 | self.backButtonInfo = { 28 | inputAction = InputAction.MENU_BACK 29 | } 30 | end 31 | 32 | function GameplaySettingsFoliageFrame:onFrameOpen() 33 | GameplaySettingsFoliageFrame:superClass().onFrameOpen(self) 34 | self:updateGameplaySettings() 35 | 36 | self.boxLayout:invalidateLayout() 37 | 38 | if FocusManager:getFocusedElement() == nil then 39 | self:setSoundSuppressed(true) 40 | FocusManager:setFocus(self.boxLayout) 41 | self:setSoundSuppressed(false) 42 | end 43 | end 44 | 45 | function GameplaySettingsFoliageFrame:updateGameplaySettings() 46 | self.disableAccessCheck:setIsChecked(g_advancedGameplaySettings:getTypeNameValue('foliage', 'disableAccessCheck')) 47 | self.disableWaterlevelCheck:setIsChecked(g_advancedGameplaySettings:getTypeNameValue('foliage', 'disableWaterlevelCheck')) 48 | 49 | self:setElementText(self.costFactor, g_advancedGameplaySettings:getTypeNameValue('foliage', 'costFactor')) 50 | end 51 | 52 | function GameplaySettingsFoliageFrame:setElementText(element, value) 53 | element:setText(string.format('%.2f', value)) 54 | end 55 | 56 | ---@param state number 57 | ---@param element CheckedOptionElement 58 | function GameplaySettingsFoliageFrame:onCheckClick(state, element) 59 | g_advancedGameplaySettings:setTypeNameValue('foliage', element.id, state == CheckedOptionElement.STATE_CHECKED) 60 | end 61 | 62 | 63 | ---@param element TextInputElement 64 | function GameplaySettingsFoliageFrame:onEnterPressedTextInput(element) 65 | local value = tonumber(element.text) 66 | 67 | if value ~= nil then 68 | if value < 0 then 69 | value = 0 70 | end 71 | g_advancedGameplaySettings:setTypeNameValue('foliage', element.id, value) 72 | end 73 | 74 | self:setElementText(element, g_advancedGameplaySettings:getTypeNameValue('foliage', element.id)) 75 | end -------------------------------------------------------------------------------- /gui/GameplaySettingsLandscapingFrame.lua: -------------------------------------------------------------------------------- 1 | ---@class GameplaySettingsLandscapingFrame 2 | ---@field enableBetterCamera CheckedOptionElement 3 | ---@field disableMouseCollision CheckedOptionElement 4 | ---@field hardness TextInputElement 5 | ---@field strengthRaiseLower TextInputElement 6 | ---@field strengthFlatten TextInputElement 7 | ---@field strengthSmooth TextInputElement 8 | ---@field strengthSlope TextInputElement 9 | ---@field costFactor TextInputElement 10 | ---@field disableAccessCheck CheckedOptionElement 11 | ---@field disableWaterlevelCheck CheckedOptionElement 12 | ---@field disableOverlapWithObjectsCheck CheckedOptionElement 13 | ---@field boxLayout BoxLayoutElement 14 | GameplaySettingsLandscapingFrame = {} 15 | 16 | local GameplaySettingsLandscapingFrame_mt = Class(GameplaySettingsLandscapingFrame, TabbedMenuFrameElement) 17 | 18 | GameplaySettingsLandscapingFrame.CONTROLS = { 19 | 'enableBetterCamera', 20 | 'disableMouseCollision', 21 | 'hardness', 22 | 'strengthRaiseLower', 23 | 'strengthFlatten', 24 | 'strengthSmooth', 25 | 'strengthSlope', 26 | 27 | 'costFactor', 28 | 'disableAccessCheck', 29 | 'disableWaterlevelCheck', 30 | 'disableOverlapWithObjectsCheck', 31 | 32 | 'boxLayout', 33 | } 34 | 35 | function GameplaySettingsLandscapingFrame.new(target, customMt) 36 | local self = TabbedMenuFrameElement.new(target, customMt or GameplaySettingsLandscapingFrame_mt) 37 | 38 | self:registerControls(GameplaySettingsLandscapingFrame.CONTROLS) 39 | 40 | return self 41 | end 42 | 43 | function GameplaySettingsLandscapingFrame:initialize() 44 | self.backButtonInfo = { 45 | inputAction = InputAction.MENU_BACK 46 | } 47 | end 48 | 49 | function GameplaySettingsLandscapingFrame:onFrameOpen() 50 | GameplaySettingsLandscapingFrame:superClass().onFrameOpen(self) 51 | self:updateGameplaySettings() 52 | 53 | self.boxLayout:invalidateLayout() 54 | 55 | if FocusManager:getFocusedElement() == nil then 56 | self:setSoundSuppressed(true) 57 | FocusManager:setFocus(self.boxLayout) 58 | self:setSoundSuppressed(false) 59 | end 60 | end 61 | 62 | function GameplaySettingsLandscapingFrame:updateGameplaySettings() 63 | self.disableMouseCollision:setIsChecked(g_advancedGameplaySettings:getTypeNameValue('landscaping', 'disableMouseCollision')) 64 | self.enableBetterCamera:setIsChecked(g_advancedGameplaySettings:getTypeNameValue('landscaping', 'enableBetterCamera')) 65 | 66 | self.disableAccessCheck:setIsChecked(g_advancedGameplaySettings:getTypeNameValue('landscaping', 'disableAccessCheck')) 67 | self.disableWaterlevelCheck:setIsChecked(g_advancedGameplaySettings:getTypeNameValue('landscaping', 'disableWaterlevelCheck')) 68 | self.disableOverlapWithObjectsCheck:setIsChecked(g_advancedGameplaySettings:getTypeNameValue('landscaping', 'disableOverlapWithObjectsCheck')) 69 | 70 | self:setElementText(self.hardness, g_advancedGameplaySettings:getTypeNameValue('landscaping', 'hardness')) 71 | self:setElementText(self.strengthRaiseLower, g_advancedGameplaySettings:getTypeNameValue('landscaping', 'strengthRaiseLower')) 72 | self:setElementText(self.strengthFlatten, g_advancedGameplaySettings:getTypeNameValue('landscaping', 'strengthFlatten')) 73 | self:setElementText(self.strengthSmooth, g_advancedGameplaySettings:getTypeNameValue('landscaping', 'strengthSmooth')) 74 | self:setElementText(self.strengthSlope, g_advancedGameplaySettings:getTypeNameValue('landscaping', 'strengthSlope')) 75 | self:setElementText(self.costFactor, g_advancedGameplaySettings:getTypeNameValue('landscaping', 'costFactor')) 76 | end 77 | 78 | function GameplaySettingsLandscapingFrame:setElementText(element, value) 79 | element:setText(string.format('%.2f', value)) 80 | end 81 | 82 | ---@param state number 83 | ---@param element CheckedOptionElement 84 | function GameplaySettingsLandscapingFrame:onCheckClick(state, element) 85 | g_advancedGameplaySettings:setTypeNameValue('landscaping', element.id, state == CheckedOptionElement.STATE_CHECKED) 86 | end 87 | 88 | ---@param element TextInputElement 89 | function GameplaySettingsLandscapingFrame:onEnterPressedTextInput(element) 90 | local value = tonumber(element.text) 91 | 92 | if value ~= nil then 93 | if element.id == 'costFactor' then 94 | if value < 0 then 95 | value = 0 96 | end 97 | else 98 | if value < 0.01 then 99 | value = 0.01 100 | end 101 | end 102 | g_advancedGameplaySettings:setTypeNameValue('landscaping', element.id, value) 103 | end 104 | 105 | self:setElementText(element, g_advancedGameplaySettings:getTypeNameValue('landscaping', element.id)) 106 | end -------------------------------------------------------------------------------- /gui/GameplaySettingsPaintFrame.lua: -------------------------------------------------------------------------------- 1 | ---@class GameplaySettingsPaintFrame 2 | ---@field disableAccessCheck CheckedOptionElement 3 | ---@field disableWaterlevelCheck CheckedOptionElement 4 | ---@field costFactor TextInputElement 5 | ---@field boxLayout BoxLayoutElement 6 | GameplaySettingsPaintFrame = {} 7 | 8 | local GameplaySettingsPaintFrame_mt = Class(GameplaySettingsPaintFrame, TabbedMenuFrameElement) 9 | 10 | GameplaySettingsPaintFrame.CONTROLS = { 11 | 'costFactor', 12 | 'disableAccessCheck', 13 | 'disableWaterlevelCheck', 14 | 15 | 'boxLayout' 16 | } 17 | 18 | function GameplaySettingsPaintFrame.new(target, customMt) 19 | local self = TabbedMenuFrameElement.new(target, customMt or GameplaySettingsPaintFrame_mt) 20 | 21 | self:registerControls(GameplaySettingsPaintFrame.CONTROLS) 22 | 23 | return self 24 | end 25 | 26 | function GameplaySettingsPaintFrame:initialize() 27 | self.backButtonInfo = { 28 | inputAction = InputAction.MENU_BACK 29 | } 30 | end 31 | 32 | function GameplaySettingsPaintFrame:onFrameOpen() 33 | GameplaySettingsPaintFrame:superClass().onFrameOpen(self) 34 | self:updateGameplaySettings() 35 | 36 | self.boxLayout:invalidateLayout() 37 | 38 | if FocusManager:getFocusedElement() == nil then 39 | self:setSoundSuppressed(true) 40 | FocusManager:setFocus(self.boxLayout) 41 | self:setSoundSuppressed(false) 42 | end 43 | end 44 | 45 | function GameplaySettingsPaintFrame:updateGameplaySettings() 46 | self.disableAccessCheck:setIsChecked(g_advancedGameplaySettings:getTypeNameValue('paint', 'disableAccessCheck')) 47 | self.disableWaterlevelCheck:setIsChecked(g_advancedGameplaySettings:getTypeNameValue('paint', 'disableWaterlevelCheck')) 48 | 49 | self:setElementText(self.costFactor, g_advancedGameplaySettings:getTypeNameValue('paint', 'costFactor')) 50 | end 51 | 52 | function GameplaySettingsPaintFrame:setElementText(element, value) 53 | element:setText(string.format('%.2f', value)) 54 | end 55 | 56 | ---@param state number 57 | ---@param element CheckedOptionElement 58 | function GameplaySettingsPaintFrame:onCheckClick(state, element) 59 | g_advancedGameplaySettings:setTypeNameValue('paint', element.id, state == CheckedOptionElement.STATE_CHECKED) 60 | end 61 | 62 | ---@param element TextInputElement 63 | function GameplaySettingsPaintFrame:onEnterPressedTextInput(element) 64 | local value = tonumber(element.text) 65 | 66 | if value ~= nil then 67 | if value < 0 then 68 | value = 0 69 | end 70 | g_advancedGameplaySettings:setTypeNameValue('paint', element.id, value) 71 | end 72 | 73 | self:setElementText(element, g_advancedGameplaySettings:getTypeNameValue('paint', element.id)) 74 | end -------------------------------------------------------------------------------- /gui/GameplaySettingsPlaceableFrame.lua: -------------------------------------------------------------------------------- 1 | ---@class GameplaySettingsPlaceableFrame 2 | ---@field costFactor TextInputElement 3 | ---@field displacementCostFactor TextInputElement 4 | ---@field disableAccessCheck CheckedOptionElement 5 | ---@field enableOverlapWithObjects CheckedOptionElement 6 | ---@field disablePaintOperation CheckedOptionElement 7 | ---@field disableTerrainDisplacement CheckedOptionElement 8 | ---@field disableRemoveFoliage CheckedOptionElement 9 | ---@field boxLayout BoxLayoutElement 10 | GameplaySettingsPlaceableFrame = {} 11 | 12 | local GameplaySettingsPlaceableFrame_mt = Class(GameplaySettingsPlaceableFrame, TabbedMenuFrameElement) 13 | 14 | GameplaySettingsPlaceableFrame.CONTROLS = { 15 | 'costFactor', 16 | 'displacementCostFactor', 17 | 'disableAccessCheck', 18 | 'enableOverlapWithObjects', 19 | 'disablePaintOperation', 20 | 'disableTerrainDisplacement', 21 | 'disableRemoveFoliage', 22 | 23 | 'boxLayout' 24 | } 25 | 26 | function GameplaySettingsPlaceableFrame.new(target, customMt) 27 | local self = TabbedMenuFrameElement.new(target, customMt or GameplaySettingsPlaceableFrame_mt) 28 | 29 | self:registerControls(GameplaySettingsPlaceableFrame.CONTROLS) 30 | 31 | return self 32 | end 33 | 34 | function GameplaySettingsPlaceableFrame:initialize() 35 | self.backButtonInfo = { 36 | inputAction = InputAction.MENU_BACK 37 | } 38 | end 39 | 40 | function GameplaySettingsPlaceableFrame:onFrameOpen() 41 | GameplaySettingsPlaceableFrame:superClass().onFrameOpen(self) 42 | self:updateGameplaySettings() 43 | 44 | self.boxLayout:invalidateLayout() 45 | 46 | if FocusManager:getFocusedElement() == nil then 47 | self:setSoundSuppressed(true) 48 | FocusManager:setFocus(self.boxLayout) 49 | self:setSoundSuppressed(false) 50 | end 51 | end 52 | 53 | function GameplaySettingsPlaceableFrame:updateGameplaySettings() 54 | self.disableAccessCheck:setIsChecked(g_advancedGameplaySettings:getTypeNameValue('placeable', 'disableAccessCheck')) 55 | self.enableOverlapWithObjects:setIsChecked(g_advancedGameplaySettings:getTypeNameValue('placeable', 'enableOverlapWithObjects')) 56 | self.disablePaintOperation:setIsChecked(g_advancedGameplaySettings:getTypeNameValue('placeable', 'disablePaintOperation')) 57 | self.disableTerrainDisplacement:setIsChecked(g_advancedGameplaySettings:getTypeNameValue('placeable', 'disableTerrainDisplacement')) 58 | self.disableRemoveFoliage:setIsChecked(g_advancedGameplaySettings:getTypeNameValue('placeable', 'disableRemoveFoliage')) 59 | 60 | self.disablePaintOperation:setVisible(false) 61 | 62 | self:setElementText(self.costFactor, g_advancedGameplaySettings:getTypeNameValue('placeable', 'costFactor')) 63 | self:setElementText(self.displacementCostFactor, g_advancedGameplaySettings:getTypeNameValue('placeable', 'displacementCostFactor')) 64 | end 65 | 66 | function GameplaySettingsPlaceableFrame:setElementText(element, value) 67 | element:setText(string.format('%.2f', value)) 68 | end 69 | 70 | ---@param state number 71 | ---@param element CheckedOptionElement 72 | function GameplaySettingsPlaceableFrame:onCheckClick(state, element) 73 | g_advancedGameplaySettings:setTypeNameValue('placeable', element.id, state == CheckedOptionElement.STATE_CHECKED) 74 | end 75 | 76 | ---@param element TextInputElement 77 | function GameplaySettingsPlaceableFrame:onEnterPressedTextInput(element) 78 | local value = tonumber(element.text) 79 | 80 | if value ~= nil then 81 | if value < 0 then 82 | value = 0 83 | end 84 | g_advancedGameplaySettings:setTypeNameValue('placeable', element.id, value) 85 | end 86 | 87 | element:setText(string.format('%.2f', g_advancedGameplaySettings:getTypeNameValue('placeable', element.id))) 88 | end -------------------------------------------------------------------------------- /gui/GameplaySettingsVehicleFrame.lua: -------------------------------------------------------------------------------- 1 | ---@class GameplaySettingsVehicleFrame 2 | ---@field enableFrontloaderFix CheckedOptionElement 3 | ---@field disableCameraCollision CheckedOptionElement 4 | -----@field fuelUsageFactor TextInputElement NOT UN USE 5 | ---@field wearFactor TextInputElement 6 | ---@field repairCostFactor TextInputElement 7 | ---@field buttonRepairAllVehicles ButtonElement 8 | ---@field repaintCostFactor TextInputElement 9 | ---@field buttonRepaintAllVehicles ButtonElement 10 | ---@field boxLayout BoxLayoutElement 11 | GameplaySettingsVehicleFrame = {} 12 | 13 | local GameplaySettingsVehicleFrame_mt = Class(GameplaySettingsVehicleFrame, TabbedMenuFrameElement) 14 | 15 | GameplaySettingsVehicleFrame.CONTROLS = { 16 | 'enableFrontloaderFix', 17 | 'disableCameraCollision', 18 | -- 'fuelUsageFactor', 19 | 'wearFactor', 20 | 'repairCostFactor', 21 | 'buttonRepairAllVehicles', 22 | 'repaintCostFactor', 23 | 'buttonRepaintAllVehicles', 24 | 25 | 26 | 'boxLayout' 27 | } 28 | 29 | function GameplaySettingsVehicleFrame.new(target, customMt) 30 | local self = TabbedMenuFrameElement.new(target, customMt or GameplaySettingsVehicleFrame_mt) 31 | 32 | self:registerControls(GameplaySettingsVehicleFrame.CONTROLS) 33 | 34 | return self 35 | end 36 | 37 | function GameplaySettingsVehicleFrame:initialize() 38 | self.backButtonInfo = { 39 | inputAction = InputAction.MENU_BACK 40 | } 41 | 42 | -- We have to manually link the focus order of the button 43 | -- beforeElement -> button -> afterElement 44 | -- beforeElement <- button <- afterElement 45 | 46 | local beforeElement = self.repairCostFactor 47 | local afterElement = self.repaintCostFactor 48 | FocusManager:linkElements(self.buttonRepairAllVehicles, FocusManager.BOTTOM, beforeElement) 49 | FocusManager:linkElements(self.buttonRepairAllVehicles, FocusManager.TOP, afterElement) 50 | 51 | beforeElement = self.repairCostFactor 52 | afterElement = self.enableFrontloaderFix 53 | FocusManager:linkElements(self.buttonRepaintAllVehicles, FocusManager.BOTTOM, beforeElement) 54 | FocusManager:linkElements(self.buttonRepaintAllVehicles, FocusManager.TOP, afterElement) 55 | end 56 | 57 | function GameplaySettingsVehicleFrame:onFrameOpen() 58 | GameplaySettingsVehicleFrame:superClass().onFrameOpen(self) 59 | self:updateGameplaySettings() 60 | 61 | self.boxLayout:invalidateLayout() 62 | 63 | if FocusManager:getFocusedElement() == nil then 64 | self:setSoundSuppressed(true) 65 | FocusManager:setFocus(self.boxLayout) 66 | self:setSoundSuppressed(false) 67 | end 68 | end 69 | 70 | function GameplaySettingsVehicleFrame:updateGameplaySettings() 71 | self.enableFrontloaderFix:setIsChecked(g_advancedGameplaySettings:getTypeNameValue('vehicle', 'enableFrontloaderFix')) 72 | self.disableCameraCollision:setIsChecked(g_advancedGameplaySettings:getTypeNameValue('vehicle', 'disableCameraCollision')) 73 | 74 | -- self:setElementText(self.fuelUsageFactor,g_advancedGameplaySettings:getTypeNameValue('vehicle', 'fuelUsageFactor') ) 75 | self:setElementText(self.wearFactor, g_advancedGameplaySettings:getTypeNameValue('vehicle', 'wearFactor')) 76 | self:setElementText(self.repairCostFactor, g_advancedGameplaySettings:getTypeNameValue('vehicle', 'repairCostFactor')) 77 | self:setElementText(self.repaintCostFactor, g_advancedGameplaySettings:getTypeNameValue('vehicle', 'repaintCostFactor')) 78 | 79 | self.buttonRepairAllVehicles:setImageFilename(nil, g_advancedGameplaySettings.modFolder .. 'icons/button_repair.png') 80 | self.buttonRepairAllVehicles.icon.uvs = Overlay.DEFAULT_UVS 81 | 82 | self.buttonRepaintAllVehicles:setImageFilename(nil, g_advancedGameplaySettings.modFolder .. 'icons/button_repaint.png') 83 | self.buttonRepaintAllVehicles.icon.uvs = Overlay.DEFAULT_UVS 84 | end 85 | 86 | function GameplaySettingsVehicleFrame:setElementText(element, value) 87 | element:setText(string.format('%.2f', value)) 88 | end 89 | 90 | ---@param state number 91 | ---@param element CheckedOptionElement 92 | function GameplaySettingsVehicleFrame:onCheckClick(state, element) 93 | g_advancedGameplaySettings:setTypeNameValue('vehicle', element.id, state == CheckedOptionElement.STATE_CHECKED) 94 | end 95 | 96 | ---@param element TextInputElement 97 | function GameplaySettingsVehicleFrame:onEnterPressedTextInput(element) 98 | local value = tonumber(element.text) 99 | 100 | if value ~= nil then 101 | if value < 0 then 102 | value = 0 103 | end 104 | g_advancedGameplaySettings:setTypeNameValue('vehicle', element.id, value) 105 | end 106 | 107 | self:setElementText(element, g_advancedGameplaySettings:getTypeNameValue('vehicle', element.id)) 108 | end 109 | 110 | function GameplaySettingsVehicleFrame:onClickRepairAllVehicles() 111 | g_advancedGameplaySettings:repairAllVehicles() 112 | end 113 | 114 | function GameplaySettingsVehicleFrame:onClickRepaintAllVehicles() 115 | g_advancedGameplaySettings:repaintAllVehicles() 116 | end -------------------------------------------------------------------------------- /icons/button_repaint.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scfmod/FS22_advancedGameplaySettings/0a806bd8e72eaa305595467d9c526dd2f39d0e1a/icons/button_repaint.dds -------------------------------------------------------------------------------- /icons/button_repair.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scfmod/FS22_advancedGameplaySettings/0a806bd8e72eaa305595467d9c526dd2f39d0e1a/icons/button_repair.dds -------------------------------------------------------------------------------- /icons/tab_foliage.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scfmod/FS22_advancedGameplaySettings/0a806bd8e72eaa305595467d9c526dd2f39d0e1a/icons/tab_foliage.dds -------------------------------------------------------------------------------- /icons/tab_landscaping.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scfmod/FS22_advancedGameplaySettings/0a806bd8e72eaa305595467d9c526dd2f39d0e1a/icons/tab_landscaping.dds -------------------------------------------------------------------------------- /icons/tab_paint.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scfmod/FS22_advancedGameplaySettings/0a806bd8e72eaa305595467d9c526dd2f39d0e1a/icons/tab_paint.dds -------------------------------------------------------------------------------- /icons/tab_placeable.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scfmod/FS22_advancedGameplaySettings/0a806bd8e72eaa305595467d9c526dd2f39d0e1a/icons/tab_placeable.dds -------------------------------------------------------------------------------- /icons/tab_vehicle.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scfmod/FS22_advancedGameplaySettings/0a806bd8e72eaa305595467d9c526dd2f39d0e1a/icons/tab_vehicle.dds -------------------------------------------------------------------------------- /modDesc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | scfmod 4 | 0.1.4.0 5 | 6 | <en>AdvancedGameplaySettings</en> 7 | 8 | 9 | 10 | 11 | store.dds 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /store.dds: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scfmod/FS22_advancedGameplaySettings/0a806bd8e72eaa305595467d9c526dd2f39d0e1a/store.dds -------------------------------------------------------------------------------- /xml/AdvancedGameplaySettingsScreen.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /xml/GameplaySettingsFoliageFrame.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /xml/GameplaySettingsLandscapingFrame.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /xml/GameplaySettingsPaintFrame.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /xml/GameplaySettingsPlaceableFrame.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /xml/GameplaySettingsVehicleFrame.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /xml/guiProfiles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | 296 | 297 | 298 | 299 | 300 | 301 | 302 | 303 | 304 | 305 | 306 | 307 | 308 | 309 | 310 | --------------------------------------------------------------------------------