diff --git a/[admin]/admin/conf/messages.xml b/[admin]/admin/conf/messages.xml
index d3c46811c..4b75e843f 100644
--- a/[admin]/admin/conf/messages.xml
+++ b/[admin]/admin/conf/messages.xml
@@ -249,6 +249,10 @@
Chatbox cleared$by_admin_4all.
ADMIN: $admin has cleared the chatbox.
+
+ FPS limit set to '$data'$by_admin_4all.
+ ADMIN: $admin has set FPS limit to '$data'
+
diff --git a/[admin]/admin/server/admin_server.lua b/[admin]/admin/server/admin_server.lua
index ff441fcf6..b0a476d11 100644
--- a/[admin]/admin/server/admin_server.lua
+++ b/[admin]/admin/server/admin_server.lua
@@ -608,9 +608,9 @@ function aAction ( type, action, admin, player, data, more )
if ( node ) then
local r, g, b = node["r"], node["g"], node["b"]
- if ( node["all"] ) then outputChatBox ( aStripString ( node["all"] ), root, r, g, b ) end
- if ( node["admin"] ) and ( admin ~= player ) then outputChatBox ( aStripString ( node["admin"] ), admin, r, g, b ) end
- if ( node["player"] ) then outputChatBox ( aStripString ( node["player"] ), player, r, g, b ) end
+ if ( node["all"] ) then outputChatBox ( aStripString ( node["all"] ), root, r, g, b, true ) end
+ if ( node["admin"] ) and ( admin ~= player ) then outputChatBox ( aStripString ( node["admin"] ), admin, r, g, b, true ) end
+ if ( node["player"] ) then outputChatBox ( aStripString ( node["player"] ), player, r, g, b, true ) end
if ( node["log"] ) then outputServerLog ( aStripString ( node["log"] ) ) end
end
end
diff --git a/[editor]/edf/edf.lua b/[editor]/edf/edf.lua
index 903a5a404..99d916dc9 100644
--- a/[editor]/edf/edf.lua
+++ b/[editor]/edf/edf.lua
@@ -884,23 +884,29 @@ end
--Returns an element's scale, or its scale element data, or false
function edfGetElementScale(element)
- local etype = getElementType(element)
- if etype == "object" then
- scale = getObjectScale(element)
- else
- local handle = edfGetHandle(element)
- if handle then
- scale = getObjectScale(handle)
- else
- scale = tonumber(getElementData(element,"scale"))
- end
- end
-
- if scale then
- return scale
- else
- return false
- end
+ local etype = getElementType(element)
+ if etype == "object" then
+ scale = getObjectScale(element)
+ if type(scale) ~= "table" then
+ scale = select(1, scale) or 1
+ end
+ else
+ local handle = edfGetHandle(element)
+ if handle then
+ scale = getObjectScale(handle)
+ if type(scale) == "table" then
+ scale = select(1, scale) or 1
+ end
+ else
+ scale = tonumber(getElementData(element,"scale"))
+ end
+ end
+
+ if scale then
+ return scale
+ else
+ return false
+ end
end
--Sets an element's position, or its posX/Y/Z element data
@@ -965,28 +971,31 @@ end
--Sets an element's scale, or its scale element data
function edfSetElementScale(element, scale)
- local ancestor = edfGetAncestor(element) or element
- setElementData(ancestor, "scale", scale)
- local etype = getElementType(element)
- if etype == "object" then
- if setObjectScale(element, scale) then
- triggerEvent ( "onElementPropertyChanged", ancestor, "scale" )
- return true
- end
- else
- local handle = edfGetHandle(element)
- if handle then
- if setObjectScale(handle, scale) then
- triggerEvent ( "onElementPropertyChanged", ancestor, "scale" )
- return true
- end
- else
- setElementData(element, "scale", scale or 1)
- triggerEvent ( "onElementPropertyChanged", ancestor, "scale" )
- return true
- end
- end
- return false
+ local ancestor = edfGetAncestor(element) or element
+ setElementData(ancestor, "scale", scale)
+ local etype = getElementType(element)
+ if type(scale) == "table" then
+ scale = scale[1]
+ end
+ if etype == "object" then
+ if setObjectScale(element, scale) then
+ triggerEvent ( "onElementPropertyChanged", ancestor, "scale" )
+ return true
+ end
+ else
+ local handle = edfGetHandle(element)
+ if handle then
+ if setObjectScale(handle, scale) then
+ triggerEvent ( "onElementPropertyChanged", ancestor, "scale" )
+ return true
+ end
+ else
+ setElementData(element, "scale", scale or 1)
+ triggerEvent ( "onElementPropertyChanged", ancestor, "scale" )
+ return true
+ end
+ end
+ return false
end
function edfGetElementInterior(element)
diff --git a/[editor]/edf/edf_client.lua b/[editor]/edf/edf_client.lua
index 5a7794486..ae0517331 100644
--- a/[editor]/edf/edf_client.lua
+++ b/[editor]/edf/edf_client.lua
@@ -189,6 +189,9 @@ end
--Sets an element's scale, or its scale element data
function edfSetElementScale(element, scale)
if scale then
+ if type(scale) == "table" then
+ scale = scale[1]
+ end
if isBasic[getElementType(element)] then
return setElementData(element, "scale", scale)
else
diff --git a/[editor]/editor_gui/client/elementproperties.lua b/[editor]/editor_gui/client/elementproperties.lua
index 1a2246d20..e0b6903bb 100644
--- a/[editor]/editor_gui/client/elementproperties.lua
+++ b/[editor]/editor_gui/client/elementproperties.lua
@@ -448,7 +448,7 @@ local function addPropertyControl( controlType, controlLabelName, controlDescrip
if selectedElement then
if newControl:getLabel() == "model" and (elementType == "object" or elementType == "vehicle") then
local minX, minY, minZ = getElementBoundingBox(selectedElement)
- g_minZ = minZ
+ g_minZ = minZ or 0
local handlerFunction = function ()
local minX2, minY2, minZ2 = getElementBoundingBox(selectedElement)
if minX2 and minY2 and minZ2 then
diff --git a/[editor]/editor_gui/client/load.lua b/[editor]/editor_gui/client/load.lua
index f5756e2ac..520d5f691 100644
--- a/[editor]/editor_gui/client/load.lua
+++ b/[editor]/editor_gui/client/load.lua
@@ -75,8 +75,9 @@ function openSearch()
guiGridListSetItemText ( loadDialog.mapsList, row, 3, res["version"], false, false )
end
else
+ local escapedText = string.gsub(string.lower(text), "([%-%.%+%*%?%[%]%^%$%(%)%%])", "%%%1")
for i,res in ipairs(openResources) do
- if string.find(res["friendlyName"],text) then
+ if string.find(res["friendlyName"], escapedText) then
local row = guiGridListAddRow ( loadDialog.mapsList )
guiGridListSetItemText ( loadDialog.mapsList, row, 1, res["friendlyName"], false, false )
guiGridListSetItemText ( loadDialog.mapsList, row, 2, res["gamemodes"], false, false )
diff --git a/[editor]/editor_gui/client/mapsettings_gamemodesettings.lua b/[editor]/editor_gui/client/mapsettings_gamemodesettings.lua
index e9715432a..6b62b0c98 100644
--- a/[editor]/editor_gui/client/mapsettings_gamemodesettings.lua
+++ b/[editor]/editor_gui/client/mapsettings_gamemodesettings.lua
@@ -45,7 +45,10 @@ function refreshGamemodeSettings()
mapsettings.rowValues[subRow] = dataInfo.default
if currentMapSettings.newSettings and currentMapSettings.newSettings[dataName] then
mapsettings.rowValues[subRow] = currentMapSettings.newSettings[dataName]
- mapsettings.gamemodeSettings = copyTable ( mapsettings.rowValues )
+ end
+
+ if currentMapSettings.gamemodeSettings and currentMapSettings.gamemodeSettings[subRow] then
+ mapsettings.rowValues[subRow] = currentMapSettings.gamemodeSettings[subRow]
end
end
if count == 0 then
@@ -58,7 +61,7 @@ function refreshGamemodeSettings()
local row = guiGridListAddRow ( mapsettings.settingsList )
guiGridListSetItemText ( mapsettings.settingsList, row, 1, "No Settings definitions", true, false )
end
- currentMapSettings.newSettings = nil
+ mapsettings.gamemodeSettings = copyTable ( mapsettings.rowValues )
end
local requiredText = { [true]="REQUIRED" }
diff --git a/[editor]/editor_gui/client/options_action.lua b/[editor]/editor_gui/client/options_action.lua
index 4ae1363b3..07149e110 100644
--- a/[editor]/editor_gui/client/options_action.lua
+++ b/[editor]/editor_gui/client/options_action.lua
@@ -35,6 +35,14 @@ function optionsActions.elemScalingSnap(value)
optionsData.elemScalingSnap = tonumber(value)
end
+function optionsActions.randomizeRotation(value)
+ optionsData.randomizeRotation = value
+end
+
+function optionsActions.randomizeRotationAxis(value)
+ optionsData.randomizeRotationAxis = value
+end
+
function optionsActions.enableColPatch(value)
local success, isLoaded = editor_main.toggleColPatch(value)
if success then
@@ -170,7 +178,7 @@ function setEditorMoveSpeeds()
move_cursor.setRotateSpeeds ( dialog.slowElemRotate:getValue(), dialog.normalElemRotate:getValue(), dialog.fastElemRotate:getValue() )
move_freecam.setRotateSpeeds ( dialog.slowElemRotate:getValue(), dialog.normalElemRotate:getValue(), dialog.fastElemRotate:getValue() )
- move_keyboard.setScaleIncrement ( dialog.elemScaling:getValue() )
+ move_keyboard.setScalingSpeeds ( dialog.slowElemScale:getValue(), dialog.normalElemScale:getValue(), dialog.fastElemScale:getValue() )
move_keyboard.toggleAxesLock ( dialog.lockToAxes:getValue() )
end
diff --git a/[editor]/editor_gui/client/options_backend.lua b/[editor]/editor_gui/client/options_backend.lua
index 8866dffde..4dbd9a00a 100644
--- a/[editor]/editor_gui/client/options_backend.lua
+++ b/[editor]/editor_gui/client/options_backend.lua
@@ -17,7 +17,9 @@ local xmlVariants = {
["normalElemRotate"]="rotate_normal_speed",
["fastElemRotate"]="rotate_fast_speed",
["slowElemRotate"]="rotate_slow_speed",
-["elemScaling"]="scaling_increment",
+["normalElemScale"]="scaling_normal_speed",
+["fastElemScale"]="scaling_fast_speed",
+["slowElemScale"]="scaling_slow_speed",
["lockToAxes"]="movement_lock_to_axes",
["autosnap"]="currentbrowser_autosnap",
["tutorialOnStart"]="tutorial_on_start",
@@ -25,11 +27,13 @@ local xmlVariants = {
["enableXYZlines"]="enablexyzlines",
["precisionLevel"]="precisionlevel",
["precisionRotLevel"]="precisionrotlevel",
-["elemScalingSnap"]="scalingSnap",
+["elemScalingSnap"]="elemscalingsnap",
["enablePrecisionSnap"]="enableprecisionsnap",
["enablePrecisionRotation"]="enableprecisionrotation",
["enableColPatch"]="enablecolpatch",
["enableRotPatch"]="enablerotpatch",
+["randomizeRotation"]="enablerandomrot",
+["randomizeRotationAxis"]="randomizerotaxis",
["fov"]="fov",
}
local nodeTypes = {
@@ -49,7 +53,9 @@ local nodeTypes = {
["normalElemRotate"]="progress",
["fastElemRotate"]="progress",
["slowElemRotate"]="progress",
-["elemScaling"]="progress",
+["normalElemScale"]="progress",
+["fastElemScale"]="progress",
+["slowElemScale"]="progress",
["lockToAxes"]="bool",
["autosnap"]="bool",
["tutorialOnStart"]="bool",
@@ -63,6 +69,8 @@ local nodeTypes = {
["enableXYZlines"]="bool",
["enableColPatch"]="bool",
["enableRotPatch"]="bool",
+["randomizeRotation"]="bool",
+["randomizeRotationAxis"]={"X","Y","Z","XY","XZ","YZ","XYZ"},
["fov"]="progress",
}
local defaults = {
@@ -81,20 +89,24 @@ local defaults = {
["slowElemMove"]=.025,
["normalElemRotate"]=2,
["fastElemRotate"]=10,
-["slowElemRotate"]=.25,
-["elemScaling"]=.1,
+["slowElemRotate"]=0.25,
+["normalElemScale"]=0.1,
+["fastElemScale"]=1,
+["slowElemScale"]=0.01,
["lockToAxes"]=false,
["autosnap"]=true,
["tutorialOnStart"]=true,
["enableBox"]=true,
["precisionLevel"]="0.1",
["precisionRotLevel"]="30",
-["elemScalingSnap"]="0.1",
+["elemScalingSnap"]="0.0001",
["enablePrecisionSnap"]=true,
["enablePrecisionRotation"]=false,
["enableXYZlines"]=true,
["enableColPatch"]=false,
["enableRotPatch"]=true,
+["randomizeRotation"]=false,
+["randomizeRotationAxis"]="XYZ",
["fov"]=dxGetStatus()["SettingFOV"],
}
@@ -118,36 +130,74 @@ function loadXMLSettings()
outputMessage ( "Map editor settings could not be created!.", 255,0,0 )
return
end
- --
- local settingsNodes = {}
- for gui,nodeName in pairs(xmlVariants) do
- local node = xmlFindChild ( settingsXML, nodeName, 0 )
- if node then
- settingsNodes[gui] = node
- else
- settingsNodes[gui] = xmlCreateChild ( settingsXML, nodeName )
- end
+ -- check if the entries in the XML are valid, and remove invalid ones
+ local validNodes = {}
+ for _, nodeName in pairs(xmlVariants) do
+ validNodes[nodeName] = true
end
+ local children = xmlNodeGetChildren(settingsXML)
+ for i = #children, 1, -1 do
+ local node = children[i]
+ local nodeName = xmlNodeGetName(node)
+ if not validNodes[nodeName] then
+ xmlDestroyNode(node)
+ end
+ end
+ xmlSaveFile(settingsXML)
+ --
local settingsTable = {}
- for gui,node in pairs(settingsNodes) do
- local value
- if nodeTypes[gui] == "bool" then
- nodeValue = getNodeValue ( node, defaults[gui] )
- value = bools[xmlNodeGetValue ( node )]
- elseif nodeTypes[gui] == "progress" then
- value = tonumber(getNodeValue ( node, defaults[gui] ))
- elseif type(nodeTypes[gui]) == "table" then
- value = tostring(getNodeValue ( node, defaults[gui] ))
- local valid = false
- for key,valuePossibility in pairs(nodeTypes[gui]) do
- if value == valuePossibility then
- valid = true
+ for gui, nodeName in pairs(xmlVariants) do
+ local node = xmlFindChild(settingsXML, nodeName, 0)
+ -- Node should exist after validation, but check anyway
+ if node then
+ local value
+ if nodeTypes[gui] == "bool" then
+ local nodeValue = xmlNodeGetValue(node)
+ value = bools[nodeValue]
+ -- If value is nil (invalid boolean), use default
+ if value == nil then
+ value = defaults[gui]
+ xmlNodeSetValue(node, tostring(value))
+ outputDebugString("Fixed invalid boolean value for " .. nodeName)
end
+ elseif nodeTypes[gui] == "progress" then
+ local nodeValue = xmlNodeGetValue(node)
+ value = tonumber(nodeValue)
+ -- If value is nil or out of range, use default
+ if value == nil then
+ value = defaults[gui]
+ xmlNodeSetValue(node, tostring(value))
+ outputDebugString("Fixed invalid numeric value for " .. nodeName)
+ end
+ elseif type(nodeTypes[gui]) == "table" then
+ local nodeValue = xmlNodeGetValue(node)
+ value = tostring(nodeValue)
+ -- Validate enum values
+ local valid = false
+ for _, valuePossibility in pairs(nodeTypes[gui]) do
+ if value == valuePossibility then
+ valid = true
+ break
+ end
+ end
+ -- If invalid value, use default
+ if not valid then
+ value = defaults[gui]
+ xmlNodeSetValue(node, tostring(value))
+ outputDebugString("Fixed invalid enum value for " .. nodeName)
+ end
+ end
+ settingsTable[gui] = value
+ else
+ -- This should never happen after validation, but as a fallback
+ settingsTable[gui] = defaults[gui]
+ node = xmlCreateChild(settingsXML, nodeName)
+ xmlNodeSetValue(node, tostring(settingsTable[gui]))
+ if node then
+ xmlSaveFile(settingsXML)
end
- if not valid then value = defaults[gui] end
end
- settingsTable[gui] = value
end
inputSettings ( settingsTable )
doActions()
@@ -167,7 +217,10 @@ function createSettingsXML()
local xml = xmlCreateFile ( "settings.xml", "settings" )
for gui,nodeName in pairs(xmlVariants) do
local node = xmlCreateChild ( xml, nodeName )
- xmlNodeSetValue ( node, tostring(defaults[gui]) )
+ if not node then
+ node = xmlCreateChild ( xml, nodeName )
+ xmlNodeSetValue ( node, tostring(defaults[gui]) )
+ end
end
xmlSaveFile ( xml )
xmlUnloadFile ( xml )
@@ -179,7 +232,14 @@ end
function inputSettings ( settingsTable )
for gui,value in pairs(settingsTable) do
- dialog[gui]:setValue(value)
+ if dialog[gui] then
+ dialog[gui]:setValue(value)
+ if nodeTypes[gui] == "progress" then
+ if optionsActions[gui] then
+ optionsActions[gui](value)
+ end
+ end
+ end
end
optionsSettings = settingsTable
end
diff --git a/[editor]/editor_gui/client/options_gui.lua b/[editor]/editor_gui/client/options_gui.lua
index 5963af965..819b1250f 100644
--- a/[editor]/editor_gui/client/options_gui.lua
+++ b/[editor]/editor_gui/client/options_gui.lua
@@ -13,6 +13,7 @@ function createOptionsDialog()
dialog.generalTab = guiCreateTab("General",tabpanel)
dialog.cameraTab = guiCreateTab("Camera",tabpanel)
dialog.movementTab = guiCreateTab("Movement",tabpanel)
+ dialog.advancedTab = guiCreateTab("Advanced",tabpanel)
dialog.ok = guiCreateButton ( 0.5, 0.919444, 0.22857142, 0.05555555, "OK", true, dialog.window )
dialog.cancel = guiCreateButton ( 0.780357142, 0.919444, 0.22857142, 0.05555555, "Cancel", true, dialog.window )
@@ -83,8 +84,6 @@ function createOptionsDialog()
guiCreateLabel ( 0.5, 0.12, 1, 0.1, "Normal element rotation speed:", true, dialog.movementTab )
guiCreateLabel ( 0.5, 0.32, 1, 0.1, "Fast element rotation speed:", true, dialog.movementTab )
guiCreateLabel ( 0.5, 0.52, 1, 0.1, "Slow element rotation speed:", true, dialog.movementTab )
- guiCreateLabel ( 0.5, 0.72, 1, 0.1, "Element scaling:", true, dialog.movementTab )
-
dialog.normalElemMove = editingControl.slider:create{["x"]=0.02,["y"]=0.18,["width"]=0.4,["height"]=0.11,["relative"]=true,["parent"]=dialog.movementTab,
["min"]=0.075,
@@ -110,11 +109,27 @@ function createOptionsDialog()
["min"]=0.01,
["max"]=0.5,
}
- dialog.elemScaling = editingControl.slider:create{["x"]=0.5,["y"]=0.78,["width"]=0.4,["height"]=0.11,["relative"]=true,["parent"]=dialog.movementTab,
- ["min"]=0.01,
- ["max"]=1,
- }
dialog.lockToAxes = editingControl.boolean:create{["x"]=0.02,["y"]=0.78,["width"]=0.4,["height"]=0.1,["relative"]=true,["parent"]=dialog.movementTab,["label"]="Lock movement to axes"}
+ --create advanced settings
+ guiCreateLabel ( 0.5, 0.04, 1, 0.1, "Normal element scaling speed:", true, dialog.advancedTab )
+ guiCreateLabel ( 0.5, 0.24, 1, 0.1, "Fast element scaling speed:", true, dialog.advancedTab )
+ guiCreateLabel ( 0.5, 0.44, 1, 0.1, "Slow element scaling speed:", true, dialog.advancedTab )
+
+ dialog.normalElemScale = editingControl.slider:create{["x"]=0.5,["y"]=0.10,["width"]=0.4,["height"]=0.11,["relative"]=true,["parent"]=dialog.advancedTab,
+ ["min"]=0.01,
+ ["max"]=0.5,
+ }
+ dialog.fastElemScale = editingControl.slider:create{["x"]=0.5,["y"]=0.30,["width"]=0.4,["height"]=0.11,["relative"]=true,["parent"]=dialog.advancedTab,
+ ["min"]=0.5,
+ ["max"]=2,
+ }
+ dialog.slowElemScale = editingControl.slider:create{["x"]=0.5,["y"]=0.50,["width"]=0.4,["height"]=0.11,["relative"]=true,["parent"]=dialog.advancedTab,
+ ["min"]=0.001,
+ ["max"]=0.05,
+ }
+
+ dialog.randomizeRotation = editingControl.boolean:create{["x"]=0.02,["y"]=0.02,["width"]=0.4,["height"]=0.1,["relative"]=true,["parent"]=dialog.advancedTab,["label"]="Randomize rotation on element creation"}
+ dialog.randomizeRotationAxis = editingControl.dropdown:create{["x"]=0.02,["y"]=0.12,["width"]=0.4,["height"]=0.07,["dropWidth"]=0.4,["dropHeight"]=0.5,["relative"]=true,["parent"]=dialog.advancedTab,["rows"]={"X","Y","Z","XY","XZ","YZ","XYZ"}}
--
loadXMLSettings()
addEventHandler ( "onClientGUIClick", dialog.ok, confirmSettings,false )
diff --git a/[editor]/editor_gui/client/outputmessage.lua b/[editor]/editor_gui/client/outputmessage.lua
index 2fb053790..b2419bea0 100644
--- a/[editor]/editor_gui/client/outputmessage.lua
+++ b/[editor]/editor_gui/client/outputmessage.lua
@@ -32,6 +32,11 @@ end
function outputMessage ( text, r, g, b, time )
cleanup()
+
+ if message.outputting then
+ removeHandler()
+ end
+
if type(text) ~= "string" then
return false
end
@@ -48,7 +53,7 @@ function outputMessage ( text, r, g, b, time )
message.y = g_screenY - message.height
if message.width > g_screenX then
message.x = 5
- local movedistance = message.width - screenX*0.75
+ local movedistance = message.width - g_screenX*0.75
local movetime = movedistance/MOVE_SPEED
time = math.max(time,movetime)
--Create our animations
@@ -67,7 +72,7 @@ function outputMessage ( text, r, g, b, time )
table.insert(message.timers, setTimer ( removeHandler, MOVE_DELAY + time, 1 ))
else
- message.x = screenX/2 - message.width/2
+ message.x = g_screenX/2 - message.width/2
doAnimation (setAlpha,
{{ from = 1, to = 140, time = FADE_TIME, fn = setAlpha }})
table.insert(message.timers, setTimer ( function() doAnimation (setAlpha,
diff --git a/[editor]/editor_gui/client/test.lua b/[editor]/editor_gui/client/test.lua
index eaac0ba17..c12d1f700 100644
--- a/[editor]/editor_gui/client/test.lua
+++ b/[editor]/editor_gui/client/test.lua
@@ -4,6 +4,7 @@ local hideDialog
local g_suspended
local inBasicTest = false
local lastTestGamemode
+local lastGridListGamemode
local g_colPatchSetting
function createTestDialog()
@@ -30,6 +31,19 @@ end
function quickTest()
if tutorialVars.blockQuickTest then return end
+ -- get the last gamemode that was addded to the map
+ local rowCount = guiGridListGetRowCount(mapsettings.addedGamemodes)
+ local currentLastGamemode = false
+ if rowCount > 0 then
+ currentLastGamemode = guiGridListGetItemText(mapsettings.addedGamemodes, rowCount - 1, 1)
+ if currentLastGamemode == "" then
+ currentLastGamemode = false
+ end
+ end
+ if lastGridListGamemode ~= currentLastGamemode then
+ lastTestGamemode = currentLastGamemode
+ lastGridListGamemode = currentLastGamemode
+ end
if lastTestGamemode == "" then lastTestGamemode = false end
editor_main.dropElement()
triggerServerEvent ( "testResource",localPlayer, lastTestGamemode )
diff --git a/[editor]/editor_main/client/elementcreation.lua b/[editor]/editor_main/client/elementcreation.lua
index 98b131126..e15057bc2 100644
--- a/[editor]/editor_main/client/elementcreation.lua
+++ b/[editor]/editor_main/client/elementcreation.lua
@@ -14,12 +14,37 @@ addEventHandler("doUnloadEDF", root,
triggerServerEvent("onClientRequestEDF", localPlayer)
+function getRandomRotation()
+ if exports["editor_gui"]:sx_getOptionData("randomizeRotation") ~= true then
+ return {0, 0, 0}
+ end
+
+ local getAxis = exports["editor_gui"]:sx_getOptionData("randomizeRotationAxis")
+ local rotationMap = {
+ ["X"] = function() return {math.random(0, 360), 0, 0} end,
+ ["Y"] = function() return {0, math.random(0, 360), 0} end,
+ ["Z"] = function() return {0, 0, math.random(0, 360)} end,
+ ["XY"] = function() return {math.random(0, 360), math.random(0, 360), 0} end,
+ ["XZ"] = function() return {math.random(0, 360), 0, math.random(0, 360)} end,
+ ["YZ"] = function() return {0, math.random(0, 360), math.random(0, 360)} end,
+ ["XYZ"] = function() return {math.random(0, 360), math.random(0, 360), math.random(0, 360)} end,
+ }
+
+ local rotationFunc = rotationMap[getAxis] or function() return {0, 0, 0} end
+ return rotationFunc()
+end
+
-- sends the element creation request
function doCreateElement ( elementType, resourceName, creationParameters, attachLater, shortcut )
creationParameters = creationParameters or {}
if not creationParameters.position then
local targetX, targetY, targetZ = processCameraLineOfSight()
- creationParameters.position = {targetX, targetY, targetZ + .5}
+ if elementType ~= "object" or elementType ~= "vehicle" then
+ creationParameters.position = nil
+ else
+ creationParameters.position = {targetX, targetY, targetZ + .5}
+ end
+ creationParameters.rotation = getRandomRotation()
end
local requiresCreationBox = false
@@ -50,5 +75,9 @@ function doCloneElement ( element, attachMode )
if getSelectedElement() then
dropElement(true)
end
- triggerServerEvent( "doCloneElement", element, attachMode )
+ local rotationData
+ if exports["editor_gui"]:sx_getOptionData("randomizeRotation") == true then
+ rotationData = getRandomRotation()
+ end
+ triggerServerEvent( "doCloneElement", element, attachMode, rotationData )
end
diff --git a/[editor]/editor_main/meta.xml b/[editor]/editor_main/meta.xml
index 03240d068..701199f01 100644
--- a/[editor]/editor_main/meta.xml
+++ b/[editor]/editor_main/meta.xml
@@ -90,6 +90,9 @@
+
+
+
diff --git a/[editor]/editor_main/server/createdestroy.lua b/[editor]/editor_main/server/createdestroy.lua
index 1a7252326..410c9ec18 100644
--- a/[editor]/editor_main/server/createdestroy.lua
+++ b/[editor]/editor_main/server/createdestroy.lua
@@ -56,7 +56,7 @@ addEventHandler ( "doCreateElement", root,
)
addEventHandler ( "doCloneElement", root,
- function (attachMode,creator)
+ function (attachMode,rotationData,creator)
if client and not isPlayerAllowedToDoEditorAction(client,"createElement") then
editor_gui.outputMessage ("You don't have permissions to clone an element!", client,255,0,0)
return
@@ -69,6 +69,11 @@ addEventHandler ( "doCloneElement", root,
if clone then
outputConsole ( "Cloned '"..getElementType(source).."'." )
+
+ if rotationData then
+ edf.edfSetElementRotation(clone, rotationData[1], rotationData[2], rotationData[3])
+ end
+
setupNewElement(clone, creator or edf.edfGetCreatorResource(source), client, true, false, attachMode)
setLockedElement(source, nil)
else
diff --git a/[editor]/editor_main/server/mapsettingssync.lua b/[editor]/editor_main/server/mapsettingssync.lua
index 603ae2747..5427cf005 100644
--- a/[editor]/editor_main/server/mapsettingssync.lua
+++ b/[editor]/editor_main/server/mapsettingssync.lua
@@ -40,6 +40,7 @@ end
mapSettingDefaults = defaults
currentMapSettings = defaults
currentMapSettings.gamemodeSettings = {}
+currentMapSettings.addedGamemodes = {}
local mapSettingAction = {
timeHour = function ( value )
@@ -127,7 +128,7 @@ function setupMapSettings()
--get the gamemodes
local gamemodes = mapmanager.getGamemodes()
currentMapSettings.availGamemodes = {}
- currentMapSettings.addedGamemodes = {}
+
for k,v in ipairs(gamemodes) do
local name = getResourceName ( v )
if string.lower(name) ~= "freeroam" then
@@ -191,6 +192,9 @@ function passDefaultMapSettings()
end
function passNewMapSettings()
+
+ if loadedMap == false then return end
+
local mapResource = getResourceFromName(loadedMap)
--General settings
diff --git a/[editor]/editor_main/server/saveloadtest_server.lua b/[editor]/editor_main/server/saveloadtest_server.lua
index 9d1f3d507..8ebcc5ce3 100644
--- a/[editor]/editor_main/server/saveloadtest_server.lua
+++ b/[editor]/editor_main/server/saveloadtest_server.lua
@@ -116,7 +116,7 @@ addEventHandler("newResource", root,
triggerClientEvent ( source, "saveloadtest_return", source, "new", true )
triggerEvent("onNewMap", resourceRoot)
dumpSave()
- editor_gui.outputMessage(getPlayerName(client).." started a new map.", root, 255, 0, 0)
+ editor_gui.outputMessage(stripHexCode(getPlayerName(client)).." started a new map.", root, 255, 0, 0)
actionList = {}
currentActionIndex = 0
@@ -138,6 +138,7 @@ function handleOpenResource()
if (isElement(openingSource)) then
triggerClientEvent ( openingSource, "saveloadtest_return", openingSource, "open", true )
playerName = getPlayerName ( openingSource )
+ playerName = stripHexCode( playerName )
end
local outputStr = playerName.." opened map "..tostring(openingResourceName)..". (opening took "..math.floor(getTickCount() - openingStartTick).." ms)"
editor_gui.outputMessage ( outputStr, root, 255, 0, 0 )
@@ -483,7 +484,7 @@ function saveResourceCoroutineFunction ( resourceName, test, theSaver, client, g
if ( returnValue ) then
loadedMap = resourceName
if (theSaver) then
- editor_gui.outputMessage ( getPlayerName(theSaver).." saved to map resource \""..resourceName.."\".", root, 255, 0, 0 )
+ editor_gui.outputMessage ( stripHexCode(getPlayerName(theSaver)).." saved to map resource \""..resourceName.."\".", root, 255, 0, 0 )
end
end
if ( theSaver ) then
@@ -639,7 +640,7 @@ function doQuickSaveCoroutineFunction(saveAs, dump, client)
triggerClientEvent ( client, "saveloadtest_return", client, "save", true )
end
if ( not dump ) then
- editor_gui.outputMessage (getPlayerName(client).." saved the map.", root,255,0,0)
+ editor_gui.outputMessage (stripHexCode(getPlayerName(client)).." saved the map.", root,255,0,0)
dumpSave()
end
else
@@ -685,6 +686,8 @@ function createElementAttributesForSaving(xmlNode, element)
xmlNodeSetAttribute(elementNode, "rotX", toAttribute(round(dataValue[1], 3)))
xmlNodeSetAttribute(elementNode, "rotY", toAttribute(round(dataValue[2], 3)))
xmlNodeSetAttribute(elementNode, "rotZ", toAttribute(round(dataValue[3], 3)))
+ elseif ( dataName == "scale" ) then
+ xmlNodeSetAttribute(elementNode, "scale", toAttribute(round(dataValue, 3)))
elseif ( dataName == "posX" or dataName == "posY" or dataName == "posZ") then
xmlNodeSetAttribute(elementNode, dataName, toAttribute(round(dataValue, 5)))
if (dataName == "posX") then
@@ -943,6 +946,10 @@ addEventHandler("onPlayerLogin", root,
end
)
+function getCurrentMapName()
+ return loadedMap
+end
+
function getBool(var,default)
local result = get(var)
if not result then
diff --git a/[editor]/editor_main/server/util.lua b/[editor]/editor_main/server/util.lua
index 2d35bc49d..3b32e0e75 100644
--- a/[editor]/editor_main/server/util.lua
+++ b/[editor]/editor_main/server/util.lua
@@ -7,6 +7,10 @@ function isPlayerAllowedToDoEditorAction(player,action)
return false
end
+function stripHexCode(text)
+ return text:gsub("#%x%x%x%x%x%x","")
+end
+
function table.subtract(t1, t2)
local find, remove = table.find, table.remove
for i=#t1,1,-1 do
diff --git a/[editor]/move_cursor/move_cursor.lua b/[editor]/move_cursor/move_cursor.lua
index c743a173a..fae8da9bc 100644
--- a/[editor]/move_cursor/move_cursor.lua
+++ b/[editor]/move_cursor/move_cursor.lua
@@ -21,6 +21,7 @@ local centerToBaseDistance
local rotationless
local rotX, rotY, rotZ
+local scale
local collisionless
local minZ
@@ -172,15 +173,13 @@ local function rotateWithMouseWheel(key, keyState)
--Peds dont have their rotation updated with their attached parents
for i,element in ipairs(getAttachedElements(selectedElement)) do
if getElementType(element) == "ped" then
- setElementRotation(element, 0,0,-rotZ)
- setPedRotation(element, rotZ)
+ setElementRotation(element, 0,0,-rotZ, "default", true)
end
end
elseif (elementType == "ped") then
rotZ = rotZ + speed
rotZ = rotZ % 360
- setPedRotation(selectedElement, rotZ)
- setElementRotation(selectedElement, 0,0,-rotZ%360)
+ setElementRotation(selectedElement, 0,0,-rotZ%360, "default", true)
end
end
end
@@ -231,6 +230,7 @@ function attachElement(element)
if (getElementType(element) == "object") then
rotationless = false
rotX, rotY, rotZ = getElementRotation(element)
+ scale = getObjectScale(element)
collisionless = false
_, _, minZ = exports.edf:edfGetElementBoundingBox(element)
end
@@ -240,9 +240,12 @@ function attachElement(element)
rotX, rotY, rotZ = getElementRotation(element)
collisionless = false
_, _, minZ = getElementBoundingBox(element)
+ if (getElementType(element) == "object") then
+ scale = getObjectScale(element)
+ end
elseif (getElementType(element) == "ped") then
rotationless = false
- rotX, rotY, rotZ = 0, 0, getPedRotation(element)
+ _, _, rotZ = getElementRotation(element)
collisionless = false
_, _, minZ = getElementBoundingBox(element)
else
@@ -274,12 +277,17 @@ function detachElement()
rotX, rotY, rotZ = getElementRotation(selectedElement, "ZYX")
triggerServerEvent("syncProperty", localPlayer, "rotation", {rotX, rotY, rotZ}, exports.edf:edfGetAncestor(selectedElement))
end
+ if (getElementType(selectedElement) == "object") then
+ scale = getObjectScale(selectedElement)
+ triggerServerEvent("syncProperty", localPlayer, "scale", {scale}, exports.edf:edfGetAncestor(selectedElement))
+ end
end
selectedElement = nil
-- clear variables
camX, camY, camZ = nil, nil, nil
rotX, rotY, rotZ = nil, nil, nil
+ scale = nil
rotationless = nil
minZ = nil
collisionless = nil
diff --git a/[editor]/move_freecam/move_freecam.lua b/[editor]/move_freecam/move_freecam.lua
index 1de440de9..1155f6cba 100644
--- a/[editor]/move_freecam/move_freecam.lua
+++ b/[editor]/move_freecam/move_freecam.lua
@@ -20,6 +20,7 @@ local centerToBaseDistance
local rotationless
local rotX, rotY, rotZ
+local scale
local collisionless
local minZ
@@ -37,7 +38,7 @@ local mta_getElementRotation = getElementRotation
local function getElementRotation(element)
local elementType = getElementType(element)
if elementType == "player" or elementType == "ped" then
- return 0,0,getPedRotation(element)
+ return mta_getElementRotation(element)
elseif elementType == "object" then
return mta_getElementRotation(element, "ZYX")
elseif elementType == "vehicle" then
@@ -78,15 +79,13 @@ local function rotateWithMouseWheel(key, keyState)
--Peds dont have their rotation updated with their attached parents
for i,element in ipairs(getAttachedElements(selectedElement)) do
if getElementType(element) == "ped" then
- setElementRotation(element, 0,0,-rotZ)
- setPedRotation(element, rotZ)
+ setElementRotation(element, 0,0,-rotZ, "default", true)
end
end
elseif (getElementType(selectedElement) == "ped") then
rotZ = rotZ + speed
rotZ = rotZ % 360
- setPedRotation(selectedElement, rotZ)
- setElementRotation(selectedElement, 0,0,-rotZ%360)
+ setElementRotation(selectedElement, 0,0,-rotZ%360, "default", true)
end
end
end
@@ -195,6 +194,7 @@ function attachElement(element)
if (getElementType(element) == "object") then
rotationless = false
rotX, rotY, rotZ = getElementRotation(element, "ZYX")
+ scale = exports.edf:edfGetElementScale(element)
collisionless = false
_, _, minZ = exports.edf:edfGetElementBoundingBox(element)
centerToBaseDistance = exports.edf:edfGetElementDistanceToBase(element)
@@ -209,12 +209,13 @@ function attachElement(element)
elseif (getElementType(element) == "object") then
rotationless = false
rotX, rotY, rotZ = getElementRotation(element, "ZYX")
+ scale = exports.edf:edfGetElementScale(element)
collisionless = false
_, _, minZ = getElementBoundingBox(element)
centerToBaseDistance = getElementDistanceFromCentreOfMassToBaseOfModel(element)
elseif (getElementType(element) == "ped") then
rotationless = false
- rotX, rotY, rotZ = 0, 0, getPedRotation(element)
+ _, _, rotZ = getElementRotation(element)
collisionless = false
_, _, minZ = getElementBoundingBox(element)
centerToBaseDistance = getElementDistanceFromCentreOfMassToBaseOfModel(element)
@@ -246,6 +247,9 @@ function detachElement()
if hasRotation[getElementType(selectedElement)] then
triggerServerEvent("syncProperty", localPlayer, "rotation", {rotX, rotY, rotZ}, exports.edf:edfGetAncestor(selectedElement))
end
+ if (getElementType(selectedElement) == "object") then
+ triggerServerEvent("syncProperty", localPlayer, "scale", scale, exports.edf:edfGetAncestor(selectedElement))
+ end
end
selectedElement = nil
diff --git a/[editor]/move_keyboard/meta.xml b/[editor]/move_keyboard/meta.xml
index e3664af4d..177d0ad20 100644
--- a/[editor]/move_keyboard/meta.xml
+++ b/[editor]/move_keyboard/meta.xml
@@ -11,8 +11,8 @@
-
-
+
+
diff --git a/[editor]/move_keyboard/move_keyboard.lua b/[editor]/move_keyboard/move_keyboard.lua
index 89af187e4..2a1c14ee1 100644
--- a/[editor]/move_keyboard/move_keyboard.lua
+++ b/[editor]/move_keyboard/move_keyboard.lua
@@ -4,7 +4,7 @@ local lastKEYSTATES = {}
local ignoreAllSurfaces = true
local moveSpeed = {slow = .025, medium = .25, fast = 2} -- meters per frame
local rotateSpeed = {slow = 1, medium = 8, fast = 40} -- degrees per scroll or frame
-local scaleIncrement = 0.1
+local scalingSpeed = {slow = .01, medium = .1, fast = 1}
local isEnabled = false
@@ -13,6 +13,7 @@ local selectedElement
local posX, posY, posZ
local rotX, rotY, rotZ
local scale
+local size
local collisionless
local lockToAxes = false
@@ -53,7 +54,7 @@ local mta_getElementRotation = getElementRotation
local function getElementRotation(element)
local elementType = getElementType(element)
if elementType == "player" or elementType == "ped" then
- return 0,0,getPedRotation(element)
+ return mta_getElementRotation(element, "default", true)
elseif elementType == "object" then
return mta_getElementRotation(element, "ZYX")
elseif elementType == "vehicle" then
@@ -184,8 +185,7 @@ local function onClientRender_keyboard()
-- check if rotation changed
if (tempRot ~= rotZ) then
if (getElementType(selectedElement) == "ped") then
- setElementRotation(selectedElement, 0,0,-tempRot%360)
- setPedRotation(selectedElement, tempRot)
+ setElementRotation(selectedElement, 0,0,-tempRot%360, "default", true)
end
end
rotZ = tempRot
@@ -232,8 +232,7 @@ local function onClientRender_keyboard()
--Peds dont have their rotation updated with their attached parents
for i,element in ipairs(getAttachedElements(selectedElement)) do
if getElementType(element) == "ped" then
- setElementRotation(element, 0,0,-tempRotZ%360)
- setPedRotation(element, tempRotZ%360)
+ setElementRotation(element, 0,0,-tempRotZ%360, "default", true)
end
end
rotX, rotY, rotZ = tempRotX, tempRotY, tempRotZ
@@ -280,8 +279,7 @@ local function onClientRender_keyboard()
-- check if rotation changed
if (tempRot ~= rotZ) then
if (getElementType(selectedElement) == "ped") then
- setElementRotation(selectedElement, 0,0,-tempRot%360)
- setPedRotation(selectedElement, tempRot)
+ setElementRotation(selectedElement, 0,0,-tempRot%360, "default", true)
end
end
rotZ = tempRot
@@ -329,8 +327,7 @@ local function onClientRender_keyboard()
--Peds dont have their rotation updated with their attached parents
for i,element in ipairs(getAttachedElements(selectedElement)) do
if getElementType(element) == "ped" then
- setElementRotation(element, 0,0,-tempRotZ%360)
- setPedRotation(element, tempRotZ%360)
+ setElementRotation(element, 0,0,-tempRotZ%360, "default", true)
end
end
rotX, rotY, rotZ = tempRotX, tempRotY, tempRotZ
@@ -346,29 +343,58 @@ local function onClientRender_keyboard()
rotX, rotY = 0, 0
for i,element in ipairs(getAttachedElements(selectedElement)) do
if getElementType(element) == "ped" then
- setElementRotation(element, 0,0,-rotZ%360)
- setPedRotation(element, rotZ%360)
+ setElementRotation(element, 0,0,-rotZ%360, "default", true)
end
end
elseif (getElementType(selectedElement) == "ped") then
rotZ = 0
- setPedRotation ( selectedElement, 0, 0, 0 )
- setElementRotation ( selectedElement, 0, 0, 0 )
+ setElementRotation ( selectedElement, 0, 0, 0 , "default", true)
end
end
end
end
- -- Scale up/down for objects
- if getElementType(selectedElement) == "object" then
- local currentScale = getObjectScale(selectedElement)
- if getCommandState("element_scale_up") then
- currentScale = currentScale + scaleIncrement
+ -- Scale up/down for objects, markers
+ local speed
+ if (getCommandState("mod_slow_speed")) then
+ speed = scalingSpeed.slow
+ elseif (getCommandState("mod_fast_speed")) then
+ speed = scalingSpeed.fast
+ else
+ speed = scalingSpeed.medium
+ end
+
+ if getElementType(selectedElement) == "object" then
+ scale = getObjectScale(selectedElement)
+ local tempScale = scale
+ local snaplevel = tonumber(exports["editor_gui"]:sx_getOptionData("elemScalingSnap"))
+ if getCommandState("element_scale_up") then
+ tempScale = scale + speed
+ tempScale = roundToLevel(tempScale,snaplevel,"round")
+ elseif getCommandState("element_scale_down") then
+ tempScale = scale - speed
+ tempScale = roundToLevel(tempScale,snaplevel,"round")
+ end
+ if tempScale ~= scale then
+ setObjectScale(selectedElement, tempScale)
+ scale = tempScale
+ end
+ elseif getElementType(selectedElement) == "marker" then
+ size = getMarkerSize(selectedElement)
+ local tempSize = size
+ local snaplevel = tonumber(exports["editor_gui"]:sx_getOptionData("elemScalingSnap"))
+ if getCommandState("element_scale_up") then
+ tempSize = size + speed
+ tempSize = roundToLevel(tempSize,snaplevel,"round")
elseif getCommandState("element_scale_down") then
- currentScale = currentScale - scaleIncrement
- end
- setObjectScale(selectedElement, currentScale)
- end
+ tempSize = size - speed
+ tempSize = roundToLevel(tempSize,snaplevel,"round")
+ end
+ if tempSize ~= size then
+ setMarkerSize(selectedElement, tempSize)
+ size = tempSize
+ end
+ end
end
end
@@ -397,15 +423,13 @@ local function rotateWithMouseWheel(key, keyState)
--Peds dont have their rotation updated with their attached parents
for i,element in ipairs(getAttachedElements(selectedElement)) do
if getElementType(element) == "ped" then
- setElementRotation(element, 0,0,-rotZ)
- setPedRotation(element, rotZ)
+ setElementRotation(element, 0,0,-rotZ, "default", true)
end
end
elseif (getElementType(selectedElement) == "ped") then
rotZ = rotZ + speed
rotZ = rotZ % 360
- setElementRotation(selectedElement, 0,0,-rotZ)
- setPedRotation(selectedElement, rotZ)
+ setElementRotation(selectedElement, 0,0,-rotZ, "default", true)
end
end
@@ -423,7 +447,7 @@ function attachElement(element)
if (getElementType(element) == "vehicle") or (getElementType(element) == "object") then
rotX, rotY, rotZ = getElementRotation(element, "ZYX")
elseif (getElementType(element) == "player") or (getElementType(element) == "ped") then
- rotX, rotY, rotZ = 0,0,getPedRotation ( element )
+ rotX, rotY, rotZ = getElementRotation(element)
end
enable()
return true
@@ -452,6 +476,10 @@ function detachElement()
scale = getObjectScale(selectedElement)
triggerServerEvent("syncProperty", localPlayer, "scale", scale, exports.edf:edfGetAncestor(selectedElement))
end
+ if getElementType(selectedElement) == "marker" then
+ size = getMarkerSize(selectedElement)
+ triggerServerEvent("syncProperty", localPlayer, "size", size, exports.edf:edfGetAncestor(selectedElement))
+ end
end
selectedElement = nil
posX, posY, posZ = nil, nil, nil
@@ -479,8 +507,10 @@ function setRotateSpeeds(slow, medium, fast)
rotateSpeed.fast = fast
end
-function setScaleIncrement(increment)
- scaleIncrement = increment
+function setScalingSpeeds(slow, medium, fast)
+ scalingSpeed.slow = slow
+ scalingSpeed.medium = medium
+ scalingSpeed.fast = fast
end
function getAttachedElement()
@@ -499,8 +529,8 @@ function getRotateSpeeds()
return rotateSpeed.slow, rotateSpeed.medium, rotateSpeed.fast
end
-function getScaleIncrement()
- return scaleIncrement
+function getScalingSpeeds()
+ return scalingSpeed.slow, scalingSpeed.medium, scalingSpeed.fast
end
function toggleAxesLock ( bool )