Навигация по блогу

суббота, 23 апреля 2011 г.

San Andreas FPS Increaser

Недавно вышло обновление для МТА, которое отключает лимит FPS, но работает же он только в МТА, решил сделать и для сингла.
Скачать!

четверг, 14 апреля 2011 г.

Мои не реализованые идеи

Здравствуйте, на связи Crazy ака Сергей. В сегодняшнем посте я хочу рассказать вам о моих некоторых идеях, которые я пытался или хотел воплотить в МТА. В начале я хотел-бы рассказать вам о карте для Race-режима "math-race" (математическая гонка, хотя скорее арифметическая, но это не столь важно). Суть карты состоит в том, чтобы на экране "гонщиков" появлялось какая-нибудь арифметическая операция(напр. 2+2=?) а внизу экрана 4 варианта ответа, и нужно нажать нужную клавишу на клавиатуре, чтобы дать ответ, и если он правильный, то задаем машине гонщика некую скорость. Ну и так, покаместь гонщик не доедет до конца трассы. Данную идею я уже начал реализовывать, но дело далеко не ушло. Трудностей то никаких нет, все довольно легко, но для хорошего генератора случайных операций, нужно потратить немного времени, чего у меня, к сожалению, не всегда очень много.


3D Inventory System

Данную идею я хотел реализовать, после просмотра данного видео:
Но я не хотел делать все как на видео, я хотел сделать вместо HUD'а оружия, само оружие, которое бы вращалось вокруг своей оси. Располагалось бы оно на месте стандартного HUD'a, но вместо него был-бы реальный обьект оружия. Я уже реализовал отрисовку модели на месте HUD, и даже смену его модели, при смене оружия игрока, все-бы хорошо, но я столкнулся с одной проблемой. Когда игрок начинает двигаться, то модель оружия начинает дергаться, и хотя я ставлю позицию модели на событии onClientPreRender (это событие срабатывает перед тем как отрисовать кадр) ничего не выходит. Но я думаю на днях попробовать использовать функцию attachElements, но я еще не знаю как я буду считать относитальные координаты игрока от расположение камеры. Вот скриншот:


На нем Shotgun расположен не там где надо из-за того, что я еще не изменял координаты на те, в которых расположен HUD и это не составит труда, но вот решить тресение объекта, мне покаместь не удалось. Если кому-то надо, вот исходный код этого скрипта на сегодняшний день(клиентский):
Weapons = {
[1]=331,
[2]=333,
[3]=334,
[4]=335,
[5]=336,
[6]=337,
[7]=338,
[8]=339,
[9]=341,
[22]=346,
[23]=347,
[24]=348,
[25]=349,
[26]=350,
[27]=351,
[28]=352,
[29]=353,
[30]=372,
[31]=355,
[33]=356,
[34]=357,
[35]=358,
[36]=359,
[37]=360,
[38]=361,
[16]=362,
[17]=342,
[18]=343,
[39]=344,
[41]=363,
[42]=365,
[43]=366,
[10]=367,
[11]=321,
[12]=322,
[13]=323,
[14]=325,
[15]=326,
[44]=368,
[45]=369,
[46]=371,
[40]=364  }

height,width = guiGetScreenSize()

CurrentWeapon = nil

Rotation = 0

function initialize()
    if getPedWeapon(getLocalPlayer()) ~= 0 then
        CurrentWeapon = createObject(Weapons[getPedWeapon(getLocalPlayer())],0,0,0)
    end
end

function setPosition()
    if CurrentWeapon then
        local x,y,z = getWorldFromScreenPosition(height*0.8,width*0.5,3)
        setElementPosition(CurrentWeapon,x,y,z)
        Rotation = Rotation + 1
        setObjectRotation(CurrentWeapon,0,0,Rotation)
    end
end

function onSwitch()
    if CurrentWeapon then
        destroyElement(CurrentWeapon)
    end
    if getPedWeapon(getLocalPlayer()) ~= 0 then
        CurrentWeapon = createObject(Weapons[getPedWeapon(getLocalPlayer())],0,0,0)
    else
        CurrentWeapon = nil
    end
end

addEventHandler("onClientResourceStart",getResourceRootElement(getThisResource()),initialize)
addEventHandler("onClientPreRender",getRootElement(),setPosition)
addEventHandler("onClientPlayerWeaponSwitch",getRootElement(),onSwitch)

На этом все, следите за обновлениями блога, комментируйте, спрашивайте. На что смогу, на то отвечу. С вами был Crazy, до свидания!

Lua lesson. Part 1

Многие уже видели этот урок, но я решил скопировать его на мой блог.


Типы данных
В Lua существует 8 типов данных:
nil - пустое значение, пустота
boolean - логический, true и false
number - числовой, он может принимать значения как и с плавающей точкой, так и без. То-есть Float и Integer в 1 типе :)
string - строковый тип. Записуется он так: stroka = 'Я строка, бла бла бла' (возможно также использование "" скобок)
function - функция
userdata - пользовательские данные. Записать в этот тип данные нельзя. Он используется только для сравнения (потом расскажу подробнее)
table - таблица, aka массив.
thread - поток, в MTA:SA не используется.

Пример записи каждого типа в переменную:
Код:
//Записуем "пустоту"
a=nil
//Логический тип
a=true
a=false
//Числовой тип
a=10
a=10.5
a=-2.5
//Строковой тип
a='Я строка'
a="Я строка"
//Функция
function addNumbers(a,b)
local c=a b
return c
end
//Пустая таблица
players = {}
//Таблица со значениями, где players[1] это "John"
players = {"John","Petya"}
Немного о аспектах скриптинга в MTA:SA
Скрипт в MTA:SA делится на 2 части:
Функции и ивенты(события)
Также скрипт можно поделить на серверный(выполняется на стороне сервера) и клиентский(выполняется на стороне клиента)
Функция выполняет определенное действие и может вернуть обработанные данные.
Ивенты ака события, просто запускают эти функции в определенное время.
Например при убийстве игрока, в чат пишется сообщение.
Также переменные могут быть локальные (local b=10) и глобальные (b=10)
Разница лишь в том, что локальные будут видны только в определенном месте, все зависит от того, где она создается. Глобальная видно во всем скрипте.
Выражения:
Арифметические операции:
,-,*,/,%(остаток от деления) и ^ (возведение в степень, например 4 в 3 степени - 4^3)
Операции сравнения:
==,~=(не равняется),<,>,<=,>=
Логические операции:
and,or,not
Операция соединения строк:
Соединяются строки с помощью 2 точек, также можно использовать для соединения другие типы
'Я строка'..'бла бла бла'
'Я строка номер '..number
Из чего состоит ресурс в MTA?
Он состоит из:
meta.xml - мета файл, файл с информацией о ресурсе(название,автор,ссылки на скрипты)
Файлов скриптов - текстовый файл с разширением .lua, наш скрипт
Дополнительные файлы - просто дополнительные файлы, такие как картинки, модели и текстуры.
Ok, как писать скрипты?
Пишутся скрипты в любом текстовом редакторе, но обычно используют Notepad с плагином Lua, который показывает синтаксис Lua.

Ок, начинаем. Будем писать ресурс. Сначало идем на wiki.mtasa.com, где найдем нужный ивент и нужные функции. Скрипт будем писать на серверной части. Чтобы решить на какой стороне писать, надо или подумать логически, или подумать какие функции нам надо, и посмотреть на wiki.mtasa.com, на каких сторонах она существует. Желательно, по возможности, писать на серверной части, так как она лучше синхронизирует объекты и машины.
Ну что, идем в раздел "Server-side Events" и находим наш ивент, "onPlayerConnect" и смотрим, что нам возращает этот ивент(раздел parameters)
Все что нам нужно есть, а это ник игрока и его IP. Пишем функцию:
Код:
function playerConnect(pName,pIP)
 outputChatBox("Игрок "..pName.." зашел на сервер с IP адрессом "..pIP)
end
В первой строке мы объявляем саму функцию, задаем параметры pName - имя игрока и pIP - его IP.
Во второй, мы посылаем сообщение всем игрокам на сервере, что зашел игрок с n-ым именем и с n-ым IP адрессом.
В третей строке мы пишем end, чтобы указать что наша функция закончилась (как скобки в других языках)
Можно задать больше параметров, такие как цвет, кому показать и т.п., но вы можете это сделать самостоятельно, найдя описание функции на вики-странице (Server-side functions)
Но у нас ничего работать не будет. Почему? Потому-что мы не привязали эту функцию к дейстивию, мы только ее создали. Чтобы привязать функцию к действию есть функция addEventHandler
пишем код:
Код:
function playerConnect(pName,pIP)
 outputChatBox("Игрок "..pName.." зашел на сервер с IP адрессом "..pIP)
end
addEventHandler("onPlayerConnect",getRootElement(),playerConnect)
Мы добавили 4 строку. Обьясняю:
первый параметр, это название ивента, во втором параметре нам нужно указать к чему именно привязать это действие, мы привязали к функции getRootElement(), которая возращает "дерево" из всех елементов, то-есть привязать ко всем игрокам. 3 параметр, это функция, к которой надо привязать наше действие. Все, сохраняем наш скрипт в любую папку, и называем его как хочем, в конце добавляем разширение .lua.
Скрипт сделан, осталось сделать мета файл.
Пишем мета файл:
Код:
<meta>
  <info author="Ник автора" version="1" type="script" /> 
  <script src="наш скрипт.lua" type="server" /> 
  </meta>  

В поле version пишем версию скрипта, в поле type типо скрипта (map,gamemode,script,misc)
2 строка "привязует" наш скрипт к ресурсу. В поле src пишем имя нашего скрипта, в поле type пишем тип скрипта, то-есть на какой стороне он разположен, клиентской (client) или серверной(server) в нашем случаи на server.
И сохраняем этот файл с именем meta.xml в ту папку, где и находится наш скрипт. Пол дела сделано!
Осталось проверить наш скрипт, заходим в папку с MTA/server/mods/deatmatch/resources и кидаем нашу папку сюда. Теперь запускаем наш сервер, заходим в игру и там в консоли пишем "start &lt;название папки с вашем ресурсом&gt;", например start joinMessage. Все! Теперь выходим с сервера и заходим обратно, и смотрим в наш чат, где высвечуется наше сообщение.
Скоро будет остальные уроки.

понедельник, 11 апреля 2011 г.

The Intro

Здравствуйте дорогие читатели(я надеюсь они у меня есть или будут) моего нового блога "Crazy Studio". Многие из вас знают меня как игрока и скриптера мультиплеера MTA:SA. Но многие думают, что я сделал только пару мелких ресурсов, и на этом мое "творчество" окончено, в чем они ошибаются. Мысль, на создание этого блога, меня подтолкнул Ride, который создал свой блог, и успешно его пополняет новым контентом. Этим решил заняться и я. До этого у меня было много попыток создать блог, но все они были заброшены через 2-3 дня. Но на этот раз, я хочу постараться не забросить этот блог за неделю. Тематика даного блога будет - МТА, и все что с нею связано, в особенности это будет программирование на языке Lua, но не всегда. Сегодняшний пост я хочу написать, о ресурсе который никто не знает, и никогда о нем не слышал, ибо я никому об нем не рассказывал(не волнуйтесь, у меня тонна таких ресурсов;) ) Его название "helicopter-shoot". Как вы уже догадались с названия, этот ресурс связан с вертолетом, а именно стрельбой из вертолета миниганом. Мысль на создания этого ресурса, меня подтолкнуло какой-то видео с YouTube. Создавать его я начал 11.04.11 и "окончил" в тот-же день(почти окончил). Так как в МТА, нету функции стрелятьИзВертолета(x,y,z), то пришлось делать ее самому. Работа ресурса заключается в том, чтобы отслеживать положение направление камеры игрока, который сидит пассажиром в вертолете Sparrow, и при нажатии на клавишу, проверять, находиться ли какой-либо обьект (пед, машина) в этой позиции, и если находиться, то отнимать ему(й) ХП. Так выглядит ресурс из положения пилота:
Как видно, все остается таким самым, если-бы вы сели как пилот без ресурса. Но если мы сядем пассажиром:Мы увидим, что у нас появился прицел, и можем крутить камеру мышкой, куда мы захотим. При нажатии на ЛКМ, в место, куда смотрит курсор, появится простой particle-эффект искр, и если там находится машина или пед, отнимаем ХП:

В идеальности, этот ресурс еще не закончен. Так как я хотел добавить модель минигана к камере (чтобы он двигался за камерой) и звук стрельбы, это все легко добавить, но мне лень. Но с точки зрения работоспособности, этот ресурс полностью рабочий и готов к употреблению ;) Если кому-то из начинающих скриптеров, интересно как он работает, вот вам исходник клиентского файла (вам другой больше и не надо):

thePlayer = getLocalPlayer()
screenX,screenY = guiGetScreenSize()
size = (screenX/1024)*64
x,y,z = 0

function getPositionInFrontOfElement(element,x,y,z)
local matrix = getElementMatrix ( element )
local offX = x * matrix[1][1] + y * matrix[2][1] + z * matrix[3][1] + matrix[4][1]
local offY = x * matrix[1][2] + y * matrix[2][2] + z * matrix[3][2] + matrix[4][2]
local offZ = x * matrix[1][3] + y * matrix[2][3] + z * matrix[3][3] + matrix[4][3]
return offX, offY, offZ
end

function getCoords( cursorX, cursorY, absoluteX, absoluteY, worldX, worldY, worldZ)
x = worldX
y = worldY
z = worldZ
end

function setCoords()
pX,pY,pZ = getPositionInFrontOfElement(thePlayer,1,0,.5)
setElementPosition(object,pX,pY,pZ)
setCameraMatrix(pX,pY,pZ,x,y,z)
end

function drawCur()
dxDrawLine((screenX/2),(screenY/2)-size/2,(screenX/2),(screenY/2)+size/2,tocolor(255,0,0,200),3)
dxDrawLine((screenX/2)-size/2,(screenY/2),(screenX/2)+size/2,(screenY/2),tocolor(255,0,0,200),3)
end

function activate(theCar,seat)
if getElementModel(theCar) == 469 and seat > 0 then
addEventHandler("onClientCursorMove",getRootElement(),getCoords)
addEventHandler("onClientPreRender",getRootElement(),setCoords)
addEventHandler("onClientRender",getRootElement(),drawCur)
object = createObject(362,0,0,0)
timer = setTimer(shoot,100,0)
end
end

function deActivate(theCar,seat)
if getElementModel(theCar) == 469 and seat > 0 then
removeEventHandler("onClientCursorMove",getRootElement(),getCoords)
removeEventHandler("onClientPreRender",getRootElement(),setCoords)
removeEventHandler("onClientRender",getRootElement(),drawCur)
destroyElement(object)
setCameraTarget(thePlayer)
killTimer(timer)
end
end

function shoot()
if getControlState("fire") then
hit,hitX,hitY,hitZ,hitElement = processLineOfSight(pX,pY,pZ,x,y,z)
fxAddBulletImpact(hitX,hitY,hitZ,0,0,1,3,5)
if hitElement then
triggerServerEvent("setHp",hitElement,hitElement)
end
end
end

addEventHandler("onClientPlayerVehicleEnter",getRootElement(),activate)
addEventHandler("onClientPlayerVehicleExit",getRootElement(),deActivate)
Вот на этом и закончился мой первый пост. В ближайшее время, вы сможете скачать все мои завершенные ресурсы с этого сайта, ну а пока я говорю вам пока, и предлагаю вам следить за обновлениями моего блога :)