-
Posts
1,967 -
Joined
-
Last visited
-
Days Won
1
Everything posted by MX_Master
-
ну тогда еще проще, это оффсеты (offsets) - смещения от точки начала эффекта
-
работает на ура
-
Указывай там 3Д позицию, куда будет направлен эффект. Чем дальше будет эта точка от точки начала эффекта, тем более вытянутый эффект может получится (хотя я не пробовал). Ну а тут на форуме уже были примеры функций для нахождения 3Д точки перед/сзади/сбоку транспорта/игрока/бота
-
Можно просмотреть в COL редакторе те, которые успешно заменяются и те, которые не хотят меняться. Сравнить их свойства, кол-во фигурок и сфер, из которых эта COL'ка сделана. .. означает, что COL'ки, состоящие из нескольких COL моделек - не поддерживаются! Здесь можно найти инфо и редактор.
-
любые "Rotation" для ГУЯ не работают, поэтому я целый класс накатал по работе с DX, чтобы мона было вертеть, крутить картинки, масштабировать их и прочие ДХ фигурки
-
ну загони скрипт сюда, мы попробуем. Если, канеш, с ним все в порядке и с удаленного адреса приходит ответ в нужном формате, то проблема посередине.
-
фаервол блокирует?
-
этот код может узнать только анонс данные сервера, и этим он хорош ну а для для каждого дела свой инструмент (: тут речь шла про имя карты..
-
Function already checks all ACL rights for both files and their resources before any actions. And for client these checks is not needed. I think there's no ACL issues for this function. And i can add wiki changes for this function, if it will be added.
-
название карты можно прекрасно и 100%тно получить без PHP SDK $MAP_NAME = 'Unknown'; $mtasa_ip = '127.0.0.1'; // какой хотите поставьте $mtasa_port = 22003; $mtasa_pre = 'EYE1'; $mtasa_fp = fsockopen( "udp://{$mtasa_ip}", (string) ($mtasa_port+123), $mtasa_errno, $mtasa_errstr, 3 ); if ( $mtasa_fp !== FALSE ) { fwrite( $mtasa_fp, 's' ); $mtasa_packet = fread( $mtasa_fp, 16384 ); fclose($mtasa_fp); if ( substr( $mtasa_packet, 0, 4 ) == $mtasa_pre ) { $mtasa = array(); $pos = 4; $len = ord( substr( $mtasa_packet, $pos, 1 ) ) - 1; $mtasa['gameShortName'] = substr( $mtasa_packet, ++$pos, $len ); $pos += $len; $len = ord( substr( $mtasa_packet, $pos, 1 ) ) - 1; $mtasa['serverPort'] = substr( $mtasa_packet, ++$pos, $len ); $pos += $len; $len = ord( substr( $mtasa_packet, $pos, 1 ) ) - 1; $mtasa['serverName'] = substr( $mtasa_packet, ++$pos, $len ); $pos += $len; $len = ord( substr( $mtasa_packet, $pos, 1 ) ) - 1; $mtasa['gameModeName'] = substr( $mtasa_packet, ++$pos, $len ); $pos += $len; $len = ord( substr( $mtasa_packet, $pos, 1 ) ) - 1; $mtasa['mapName'] = substr( $mtasa_packet, ++$pos, $len ); $MAP_NAME = $mtasa['mapName']; // ... } }
-
от добра добра не ищут (: и я думаю, что там первое слово пишется как "Connected!", что означает факт успешного конекта моя позиция по поводу чата всегда была одинаковой - убрать всё кроме сообщений самих игроков. Поэтому я скорее ЗА то, чем против ТОГО, о чем ты пишешь.
-
My script, which works with files, uses backup system to prevent full data loss if some errors were occurred while writing data. And I always must to create new file with new backup name and write into it content of original file. So I must delete original file and create new one with new data. There's no fileRename or fileCopy functions and this process can take more processor's and hdd's time then just renaming if server contains more players. There's a source patch (0006030, request:0006027) witch adds fileRename function, but no actions and comments about it. And i want to ask: is anything wrong with this code or this feature breaks some other systems?
-
в 1,1 есть функции файлов в клиенте ну если отключат обе, придется что-то вроде toJSON / fromJSON юзать + функции файлов для хранения файлов аккаунтов и прочих настроек. Создание/правку/удаление своих .DBшек sqlite еще никто не сделал
-
anyway loadstring still will be working (:
-
Это клиентский файл, создай новый скрипт в своем моде или ресурсе и в meta.xml укажи его как клиентский.
-
Описание: loadfile ( "путь_к_файлу" ) - это функция языка LUA, которая позволяет прочесть любой файл как LUA скрипт и загрузить его в текущий скрипт в виде функции. Внимание: эта функция считается небезопасной с версии 1.1. Параметры: "путь_к_файлу" - строка, содержащая путь к скрипту, начиная с папки, где находится EXEшник сервера, допустим, "mods/deathmatch/resources/имя_ресурса/имя_скрипта.lua", если скрипт лежит в папке ресурса, или "mods/deathmatch/имя_скрипта.lua", если скрипт лежит рядом с файлом настройки сервера. Возвращаемые значения: функцию - если код файла был без ошибок nil и "строку с кодом ошибки" - если в коде файла найдены ошибки [*]loadstring ( "строка_с_кодом" ) - это функция языка LUA, которая позволяет прочесть любую строку как LUA код и загрузить этот код в текущий скрипт в виде функции. Параметры: "строка_с_кодом" - любая строка, желательно с правильным LUA кодом Возвращаемые значения: функцию - если код в строке был без ошибок nil и "строку с кодом ошибки" - если найдены ошибки в коде строки Области применения: Динамическое подключение других скриптов в текущий скрипт без указания их в meta.xml Выполнение кода, который хранится в виде строки, например, в базе данных, XML файле или другом месте Изменение, проверка и запуск ваших скриптов прямо на сервере. Допустим, вы админ и хотите никуда не выходя с сервера изменить какой-то скрипт вашего ресурса: несколько махинаций с GUI и вы можете открывать/изменять/запускать нужные скрипты. Хранение аккаунтов игроков, настроек, языковых файлов и прочего в виде LUA кода, например в виде таблиц Проверка работоспособности кода перед его выполнением с возможностью узнать текст ошибки Начнем с более простой loadstring: -- в строке нет ошибок local sMyCode = 'local str = "qwerty" \n return str' local fGetQwerty = loadstring(sMyCode) outputChatBox( 'fGetQwerty(): "'..fGetQwerty()..'"' ) -- fGetQwerty(): "qwerty" -- код вверху аналогичен этому local function fGetQwerty() local str = "qwerty" return str end outputChatBox( 'fGetQwerty(): "'..fGetQwerty()..'"' ) -- fGetQwerty(): "qwerty" -- а теперь допустим в коде ошибку local sErrorText sMyCode = 'local str = "qwerty \n return str' -- не завершена строка fGetQwerty, sErrorText = loadstring(sMyCode) outputChatBox( tostring(fGetQwerty) ) -- nil outputChatBox(sErrorText) -- [string "local str = "qwerty ..."]:1: unfinished string near '"qwerty' Здесь мы взяли простую строку, которая может содержать правильный или неправильный LUA код. Загрузили эту строку как LUA код и поместили его в новую функцию, которую мы можем вызвать позднее, когда это нужно. Если код в строке был верный, то loadstring вернула нам переменную типа 'function' или проще говоря, новую функцию. Если код в строке был неверный, то первым значением loadstring вернула nil, а вторым - "строку с текстом ошибки". Теперь loadfile: -- допустим наш ресурс называется "myResource" -- в папке это ресурса есть два скрипта "main.lua" и "include.lua" -- в "meta.xml" мы указали только "main.lua" как серверный скрипт -- допустим, текст файла "include.lua" будет такой -------------- local t = {"qwe","rty","uio"} return t -------------------------- -- текст файла "main.lua" ------------------------ -- имя этого ресурса ("myResource") local sThisResourceName = getResourceName( getThisResource() ) -- путь к скрипту local sPathToFile = 'mods/deathmatch/resources/'..sThisResourceName..'/include.lua' -- загружаем файл и создаем из него функцию local fFunction, sErrorText = loadfile(sPathToFile) if not fFunction then -- если в коде файла есть ошибка или файл не существует outputChatBox('Ошибка в коде файла "'..sPathToFile..'":') outputChatBox(' '..sErrorText) else -- если всё пучком local tTableFromFile = fFunction() -- выполним код файла outputChatBox(' tTableFromFile[2] = "'..tTableFromFile[2]..'"') -- tTableFromFile[2] = "rty" end -------------------------- Здесь мы имеем два скрипта в папке вашего ресурса. Вызываем один скрипт из другого, поместив код вызываемого скрипта в функцию, которую можно позднее запустить. Эта новая функция может ничего и не возвращать, а просто выполнять код подключенного файла, когда мы ее вызываем. Хранение данных в виде LUA кода Допустим, вы хотите сделать свою систему аккаунтов для вашего мода/ресурса. Вы можете выбрать XML или другой формат для хранения данных. Но почему бы не выбрать именно формат LUA таблицы ? Файл с LUA кодом легко можно изменить вручную, а также подгрузить его в скрипт с помощью loadfile. Всё, что в этом случае потребуется, только функция, которая из таблицы создает строку правильного LUA кода с определением таблицы. Все остальное у нас уже есть. Допустим файлы аккаунтов будут иметь следующий вид: return { armour = 33.4, money = 423685, password = "123456", health = 74.6 } Такой файл можно смело подгрузить в ваш скрипт в виде новой функции. Потом выполнить ее и результат положить в какую-то ячейку игрока в общей таблице данных игроков. -- общий список данных игроков local tPlayersData = {} -- пытаемся подключить файл аккаунта local fGetAccountData, sError = loadfile("путь/к/файлу/аккаунта") if fGetAccountData then -- если файл есть и загружен -- player тут это какой-то игрок, допустим, который вошел на сервер tPlayersData[player] = fGetAccountData() else -- аккаунт не существует или ошибка в данных файла аккаунта -- можно воспользоваться sError, чтобы определить причину -- или вывести ее в лог end fGetAccountData = nil -- загруженный файл уже далее не нужен sError = nil -- текст ошибки тоже не нужен Прочесть файл аккаунта мы можем, а как же его изменить? Здесь как раз и нужна функция, которая из таблицы с данными аккаунта создаст правильный LUA код с определением этой таблицы. Далее мы к этому определению таблицы спереди добавим "return " и перезапишем весь файл этой строкой. Начнем с функции конверта таблицы в строку правильного LUA кода: -- заменяет все специальные символы в строке на лексемы local tEscapes = { ["\a"] = '\\a', ["\b"] = '\\b', ["\f"] = '\\f', ["\n"] = '\\n', ["\r"] = '\\r', ["\t"] = '\\t', ["\\"] = '\\', ["\""] = '\\"' } local function fSafeString ( s ) for sSearch, sReplace in pairs(tEscapes) do s = string.gsub( s, sSearch, sReplace ) end for n = 1, 31 do s = string.gsub( s, string.char(n), '\\'..string.format('%03d',n) ) end return s end -- конверт таблицы в строку -- если bIndent = true, то сделает и корректные отступы с переносом на новую строку local sQuote = '"' local sIndent = " " local sNewLine = "\r\n" local sLeftBracket, sRightBracket = '[', ']' local sLeftBrace, sRightBrace = '{', '}' local sEqual = '=' local sIndentedEqual = ' = ' local sSeparator = ',' local nRecurLevel = 0 local nIndentLevel = 0 local tRefs = {} local function fTableToString ( t, bIndent ) if type(t) ~= 'table' then return tostring(t) end nRecurLevel = nRecurLevel + 1 nIndentLevel = nIndentLevel + 1 local tResult, sType = {} for k, v in pairs(t) do sType = type(k) if sType == 'string' then k = fSafeString(k) if not k:find('^%a%w*$') then k = sLeftBracket .. sQuote .. k .. sQuote .. sRightBracket end elseif sType == 'number' then k = sLeftBracket .. tostring(k) .. sRightBracket else k = sLeftBracket .. sQuote .. tostring(k) .. sQuote .. sRightBracket end sType = type(v) if sType == 'string' then v = sQuote .. fSafeString(v) .. sQuote elseif sType == 'table' then if tRefs[v] then v = sQuote .. tostring(v) .. sQuote else v = fTableToString(v, bIndent) end tRefs[v] = true elseif sType == 'number' then v = tostring(v) else v = sQuote .. tostring(v) .. sQuote end if bIndent then table.insert( tResult, string.rep(sIndent,nIndentLevel) .. k .. sIndentedEqual .. v ) else table.insert( tResult, k .. sEqual .. v ) end end local sResult if not bIndent then sResult = sLeftBrace .. table.concat(tResult, sSeparator) .. sRightBrace else sResult = sLeftBrace .. sNewLine .. table.concat(tResult, sSeparator..sNewLine) .. sNewLine .. string.rep(sIndent,nIndentLevel-1) .. sRightBrace end if nRecurLevel <= 1 then tRefs = {} end nRecurLevel = nRecurLevel - 1 nIndentLevel = nIndentLevel - 1 return sResult end Теперь мы можем изменить файл аккаунта: local sAccountPath = "путь/к/файлу/аккаунта" -- удаляем файл аккаунта -- по желанию можно делать и бэкапы перед удалением fileDelete(sAccountPath) -- создаем новый файл аккаунта local uFile = fileCreate(sAccountPath) if not uFile then -- если не удалось создать outputChatBox( 'Файла аккаунта не открывается для записи' ) -- что-то еще else -- файл создался -- записываем строку с определением таблицы в файл if not fileWrite( uFile, 'return ' .. fTableToString(tPlayersData[player], true) ) then outputChatBox( 'Строка данных аккаунта не записалась в файл' ) -- что-то еще end fileClose(uFile) -- сохраним файл end Точно таким же образом мы можем хранить и любые другие данные - языковые файлы, настройки и прочее. t, bIndent
-
Суть бага в названии. Ну а если быть точным: если в МТАСА/ГТАСА у вас FPS больше 47, то прицелившись из оружия ходить в стороны/вперед/назад не совсем получиться, что затрудняет игру, особенно в ДМ модах. Тут я просто хотел выложить свой фикс для этого бага. И, возможно, кто-то сможет внести свои правки, которые улучшат этот скрипт: Это клиентский файл http://pastebin.com/NKfCDJpP --[[ Фикс бага, когда игрок с оружием в руках не может ходить в стороны прицелившись, если его FPS больше 47 MX_Master, 02.04.2011 1:09:46 ]] local uMe = getLocalPlayer() -- я local nFPS = 32 -- текущее значение ФПС local nFrames = 0 -- счетчик ФПС, который раз в сек обнуляется local nBugMinFPS = 47 -- барьер ФПС для бага local bIsMeAiming = false -- флаг: вкл ли сейчас кнопка прицеливания local tMoveKeyState = {} -- таблица текущих состояний кнопок движения local tMoveKeyPairState = {} -- таблица текущих состояний пар (AD,WS) кнопок движения local nTmpControlEnableTime = 70 -- мсек, время на которое включается вспомогательная кнопка движения -- список вспомогательных кнопок движения для каждой кнопки движения local tEnableMoveControl = { ['left'] = 'forwards', ['right'] = 'backwards', ['forwards'] = 'left', ['backwards'] = 'right' } -- список кнопок противодействия для каждой кнопки движения local tMoveOppositeControl = { ['left'] = 'right', ['right'] = 'left', ['forwards'] = 'backwards', ['backwards'] = 'forwards' } -- список названий для пар кнопок движения local tMoveKeyPairName = { ['left'] = 'AD', ['right'] = 'AD', ['forwards'] = 'WS', ['backwards'] = 'WS' } -- список названий для пар противодействующих кнопок движения local tMoveKeyOppositePairName = { ['left'] = 'WS', ['right'] = 'WS', ['forwards'] = 'AD', ['backwards'] = 'AD' } -- фактически - это обработчик для нажатия любых кнопок движения -- при любых их состояниях, но можно вызывать и вручную, указав -- имя кнопки движения local function fEnableMoveControlWhileBUG ( sKey ) if not bIsMeAiming or -- если я не целюсь nFPS < nBugMinFPS or -- или ФПС меньше барьера для бага isPedDucked(uMe) or -- или я на картах сижу ( tMoveKeyState[sKey] and tMoveKeyPairState[ tMoveKeyOppositePairName[sKey] ] ) -- или одновременно нажаты противоположные кнопки движения (AD или WS) then return -- ничо не делаем end -- на короткое время включаем такую кнопку управления, с помощью -- которой, нажатая кнопка начинает движение if ( tMoveKeyState[sKey] and not tMoveKeyState[ tMoveOppositeControl[sKey] ] ) or ( not tMoveKeyState[sKey] and tMoveKeyState[ tMoveOppositeControl[sKey] ] ) then setControlState( tEnableMoveControl[sKey], true ) setTimer( setControlState, nTmpControlEnableTime, 1, tEnableMoveControl[sKey], false ) end end -- включаем счетчик ФПС addEventHandler( 'onClientRender', root, function() nFrames = nFrames + 1 end ) setTimer( function() nFPS = nFrames; nFrames = 0 end, 1000, 0 ) -- включаем мониторинг кнопки прицеливания bindKey( 'aim_weapon', 'down', function() bIsMeAiming = true -- иногда не срабатывает включение движения прицелившись, -- если игрок бежал, нажал кнопку прицеливания и потом кнопку движения. -- поэтому нужно включить движение вручную if tMoveKeyPairState['AD'] then if tMoveKeyState['left'] then fEnableMoveControlWhileBUG('left') else fEnableMoveControlWhileBUG('right') end else if tMoveKeyState['forwards'] then fEnableMoveControlWhileBUG('forwards') else fEnableMoveControlWhileBUG('backwards') end end end ) bindKey( 'aim_weapon', 'up', function() bIsMeAiming = false end ) -- включаем мониторинг кнопок движения (пешком) for sKey in pairs(tEnableMoveControl) do bindKey( sKey, 'both', function ( sKey, sState ) if sState == 'down' then tMoveKeyState[sKey] = true tMoveKeyPairState[ tMoveKeyPairName[sKey] ] = true else tMoveKeyState[sKey] = false if not tMoveKeyState[ tMoveOppositeControl[sKey] ] then tMoveKeyPairState[ tMoveKeyPairName[sKey] ] = false end end fEnableMoveControlWhileBUG(sKey) end ) end Скрипт учитывает только основные нюансы поведения кнопок движения при баге. Поэтому этот фикс может в редких ситуациях не сработать. Желательно, выявить эти закономерности и добавить для них код. Проверено при 60-70 FPS.
-
если ты про SQLite Maestro, то он сохраняет во все, что только можно. Покопайся побащще
-
лисовый просмотрщик веба тут не надо рекламировать ))
-
SQLite Maestro . круче тока яйца в крутую
-
даже на не подводной карте с простыми объектами? если да, то это глобальный косячок
-
viewtopic.php?f=123&t=32315#p341284 http://code.google.com/p/mtasa-blue/downloads/list http://code.google.com/p/mtasa-resources/downloads/list
-
я помню решал ее временами изменением настроек игры и в полноэкране можно было шмалять, идя бочком -- позже -- Добавил ща себе в мод скриптовый фикс этого трабла. 70 ФПС - полет нормальный, игрок целясь ходит куда хочет. Чмок команду МТА в щёчку ((: с таким функционалом можно многие баги самой игры фиксить на лету.
-
Это, кстати, интересная проблема, которая осталась с 1,0,4. Непонятно какая связь между ФПС и тем, что кнопки A,D не пашут, когда игрок прицелился. Они работают в тот момент только, если еще какую-то кнопку нажать.
-
Зря ты мучился, когда так бывает у меня, я вхожу в одиночку и там ставлю Frame Limiter = OFF. Он иногда становится ON и тогда у меня в окне становится ФПС 30, полноэкран - 40, хотя, обычно, 60 и 70 соответственно. Возможно, у кого-то и Vertical Sinc стал ON в одиночке, верните обратно на OFF и ФПС будет максимальным. Ну и в настройках серва нужно выставить фпс 100.