|
GTA.ru > Сервер > Cкриптинг в MTA: DeathMath > Шестое руководство
Шестое руководство по скриптингу в Multi Theft Auto: DeathMatch
Шестое руководство пояснит вам, как сделать игровой мод "Царь горы"(King of the Hill). Пример скрипта KOTH здесь будет контролировать зону (холм) и давать поинты человеку, когда он занимает один из них. Каждую секунду, когда он остаются в зоне, получает 1 поинт. После определенного времени, игра закончится, и человек с самым высоким счетом побеждает.

Обучающее видео: scriptvideo6.avi - DivX 5.0 (640x480, 29.97fps, 25.1mb)
Готовый скрипт: script6.lua
Подготовка
Сначала мы устанавливаем таймер, который проверяет местоположение игроков каждые 500мс.
kothTimer = setTimer ( "checkHillArea", 500, 0 ) |
Затем, когда скрипт начат, мы начинаем игровой мод koth и создаем площадь, область, которую должны будут захватить игроки.
addEventHandler ( "onResourceStart", getRootElement(), "kothStart" )
function kothStart ( name )
hillArea = createColSquare ( -2171.0678710938, 678.17950439453, 0, 15, 15 ) |
MTA:SA имеет способность создать и управлять областями радара банд Сан Андреаса, такие же, как вы могли видеть в одиночной игре. Чтобы создать их мы используем createRadarArea ( X, Y, sizeX, sizeY, R, G, B, A, [ elements visible to ] )
hillRadar = createRadarArea ( -2183.5678710938, 705.67950439453, 40, -40, 0,
255, 0, 175 ) |
Далее с петлей мы создаем показы текста (способ, который вы узнали из предыдущего руководства), который покажет лидеру и текущие поинты для каждого игрока. Устанавливаем для каждого поинты на 0 с помощью setElementData.
local globalTextDisplay = textCreateDisplay ()
textItemLeaderScore = textCreateTextItem ( "Leader: None", 0.15, 0.3, 0, 255,
0, 0, 255, 1.4 )
textDisplayAddText ( globalTextDisplay, textItemLeaderScore )
for k,v in getElementsByType ( "player" ) do
setElementData ( v, "points", 0 )
local playerTextDisplay = textCreateDisplay ()
local yourScore = textCreateTextItem ( "Score: "..getElementData(v,
"points"), 0.15, 0.7, 0, 255, 0, 0, 255, 1.8 )
textDisplayAddText ( playerTextDisplay, yourScore )
textDisplayAddObserver ( playerTextDisplay, v )
setElementData ( v, "textItemPoints", yourScore )
textDisplayAddObserver ( globalTextDisplay, v )
leaderPlayer = false
end |
И устанавливаем таймер, чтобы закончить раунд через 5 минут:
kothEndTimer = setTimer ( "kothEnd", 300000, 1 )
end |
Для каждого игрока, который присоединяется после того, как начат игровой мод, мы также должны установить показы текста и поинты.
addEventHandler ( "onPlayerJoin", getRootElement(), "kothJoin" )
function kothJoin ()
setElementData ( source, "points", 0 )
local playerTextDisplay = textCreateDisplay ()
local yourScore = textCreateTextItem ( "Score: "..getElementData(source,
"points"), 0.15, 0.7, 0, 255, 0, 0, 255, 1.8 )
textDisplayAddText ( playerTextDisplay, yourScore )
textDisplayAddObserver ( playerTextDisplay, source )
setElementData ( source, "textItemPoints", yourScore )
textDisplayAddObserver ( globalTextDisplay, source )
end |
Когда игрок появляется:
addEventHandler ( "onPlayerSpawn", getRootElement(), "kothSpawn" )
function kothSpawn ( spawnpoint, team ) |
Мы выдаём ему ak-47 (ID 30) с 10000 патронами.
giveWeapon ( source, 30, 10000 )
end |
Главные функции
function checkHillArea () |
Здесь мы перешли на главную функцию, которую вызывают каждые 500мс.
Мы создаем таблицу, которая хранит всех игроков, которые находятся в области для захвата.
local hillPlayers = getElementsWithinColShape ( hillArea, "player" ) |
Проверять каждого игрока в таблице с помощью isPlayerDead() и если он мертв, удалять его из таблицы с помощью table.remove(), таким образом, он не получает поинты, являясь мертвым.
for k,v in hillPlayers do
if ( isPlayerDead ( v ) ) then
table.remove(hillPlayers,k)
end
end |
После того, как мы удалили всех мертвых игроков, мы проверяем, как много пунктов остаётся в таблице:
if table.getn ( hillPlayers ) ~= 0 then |
Если это не 0, мы устанавливаем цвет области радара на красный и заставляем её загореться, как это было когда вы захватывали области в одиночной игре.
setRadarAreaFlashing ( hillRadar, true )
setRadarAreaColor ( hillRadar, 255, 0, 0, 175 ) |
И для каждого игрока в таблице мы должны увеличить их поинты и обновить их показы текста. Таким образом, мы получаем их текущие поинты и показы текста с помощью getElementDat (), добавляем 1 поинт, и обновляем пункты текста с помощью textItemSetText()
for k,v in hillPlayers do
local currentPoints = getElementData ( v, "points" )
local newPoints = currentPoints + 1setElementData ( v, "points",
newPoints )
textItemSetText ( getElementData(v,"textItemPoints"),
"Score: "..newPoints )
end |
Иначе, если нет никаких игроков оставленных в таблице, мы устанавливаем цвет области на зеленый и делаем его, не горящим на радаре.
else
setRadarAreaFlashing ( hillRadar, false )
setRadarAreaColor ( hillRadar, 0, 255, 0, 175 )
end |
Теперь нам надо вывести лидера.
local leaderText = ""
local leaders = 1
for k,v in getElementsByType ( "player" ) do |
Если на данный момент нет никакого лидера, то первый игрок, которого мы получим, и будет им.
if leaderPlayer == false then leaderPlayer = v end |
Далее, если текущий проверенный игрок, не лидер, мы получаем его и лидера поинты
local leaderPoints = getElementData ( leaderPlayer, "points" )
playerPoints = getElementData ( v, "points" ) |
Если игрок имеет больше количество поинтов, чем лидер, мы обновляем лидера
if playerPoints > leaderPoints then
leaders = 1
leaderPlayer = v
leaderText = getClientName ( v ) |
Если они имеют то же самое количество поинтов, то мы имеем двух лидеров
elseif playerPoints == leaderPoints then
leaders = leaders + 1
leaderText = leaderText.."/"..getClientName(v)
end
end
end |
И если есть меньше чем 3 лидера, и сам лидер существует, мы выводим его
if leaders > 3 or leaders == getPlayerCount () or leaderPlayer == false then
textItemSetText ( textItemLeaderScore, "Leader: None" )
else
textItemSetText ( textItemLeaderScore, "Leader: "..leaderText.."
- "..getElementData(leaderPlayer,"points") )
end
end |
Когда мы заканчиваем текущий раунд
Мы убираем главный таймер, таким образом мы не получаем больше поинты
Получите лидеров таким же самым путём как прежде и покажите их с новым показом текста
local leaderText = ""
local leaders = 1
for k,v in getElementsByType ( "player" ) do
if leaderPlayer == false then leaderPlayer = v end
local leaderPoints = getElementData ( leaderPlayer, "points" )
playerPoints = getElementData ( v, "points" )
if v ~= leaderPlayer then
if playerPoints > leaderPoints then
leaders = 1
leaderPlayer = v
leaderText = getClientName ( v )
elseif playerPoints == leaderPoints then
leaders = leaders + 1
leaderText = leaderText.."/"..getClientName(v)
end
else
leaderText = getClientName (leaderPlayer )
end
end
local textDisplayWinner = textCreateDisplay ()
local textItemif leaders > 3 or leaders == getPlayerCount ()
or leaderPlayer == false then
textItem = textCreateTextItem ( "The time is out!\nWinner: None
\nNewRound!", 0.5, 0.5, 2, 255, 0, 0, 255, 255 )
else
textItem = textCreateTextItem ( "The time is out!\nWinner:
"..leaderText.." with "..getElementData ( leaderPlayer, "points"
).."points!\n\nNewRound!", 0.5, 0.5, 2, 255, 0, 0, 255, 255 )
end
textDisplayAddText ( textDisplay, textItem )
for k,v in getElementsByType ( "player" ) do
textDisplayAddObserver ( textDisplayWinner, v )
setElementData ( v, "points", 0 )
textItemSetText ( getElementData(v,"textItemPoints"), "Score: 0" )
end |
И напоследок перезагрузка мода
restartResource ( getThisResource() )
end |
Увеличение повреждения оружия
addEventHandler ( "onPlayerDamage", getRootElement(), "kothDamage" )
function kothDamage ( attacker, weapon, bodypart, loss ) |
Если мы были повреждены игроком, мы устанавливаем новое повреждение, которое является 125 % от предыдущего и проверяем, сколько жизней мы имеем.
local damage = loss * 1.25
local hpLeft = getPlayerHealth ( source ) - damage |
Если больше чем 0, то мы все еще живы, таким образом, мы проверяем часть тела, в которую мы были повреждены. И если это - голова, мы убиваем игрока, если его жизни не изменяются увеличенным повреждением.
if ( hpLeft > 0 ) then
if ( bodypart == 9 ) then
killPlayer ( source, attacker, weapon, bodypart )
else
setPlayerHealth ( source, hpLeft )
end |
Иначе, если результат здоровья игрока равен 0 или меньше, мы его только убиваем.
else
killPlayer ( source, attacker, weapon, bodypart )
end
end
end |
Сообщения
Когда игрок вступает или оставляет зону, мы должны это вывести
addEventHandler ( "onColShapeHit", -- getRootElement(), "kothHillEnter" )
function kothHillEnter ( player, dim )
if source == hillArea then
outputMessage ( getClientName(player).." entered the zone!",
255, 255, 109, 255 )
end
end
addEventHandler ( "onColShapeLeave", -- getRootElement(), "kothHillExit" )
function kothHillExit ( player, dim )
if source == hillArea then
if isPlayerDead ( player ) ~= true then
outputMessage ( getClientName(player).." left the zone!",
255, 255, 109, 255 )
end
end
end |
И наконец мы выводим сообщения о смертях:
addEventHandler ( "onPlayerWasted", getRootElement(),
"KillMessages_onPlayerWasted" )
function KillMessages_onPlayerWasted ( totalammo, killer, killerweapon, bodypart ) |
Установите, ник убитого игрока, цвет сообщения и альфы
local killed_nick = getClientName ( source )
local r,g,b = getPlayerNametagColor( source )
local a = 120 |
Если игрок был в зоне koth, мы устанавливаем Альфу на немного большую переменную, таким образом, мы видим его немного лучше.
if ( isElementWithinColShape ( source, hillArea ) ) then
r = 255
g = 255
b = 109
a = 255
end |
Иначе, мы только выводим сообщения, подобный тому, который был в руководстве 5b.
if ( killer ) then
if (source == killer) then
killed_nick = "himself"
end
local killmessage = getClientName(killer).." killed "..killed_nick
local killerweapon_name = getWeaponNameFromID ( killerweapon )
if ( killerweapon_name ) then
outputMessage( killmessage.." ("
..killerweapon_name..")", r, g, b, a )
else
outputMessage( killmessage, r, g, b, a )
end
else
outputMessage( killed_nick.." died", r, g, b, a )
end
end |
------OUTPUT MESSAGE CODE-----
addEventHandler ( "onResourceStart", getRootElement(), "createTextOnLoad" )
function createTextOnLoad ( name )
local outputMessageTextDisplay = textCreateDisplay ()
local distance = 0.027
local start = 0.25
local size = 1.2
outputMessageTextItem1 = textCreateTextItem ( "", 0.8, start +
distance, 1, 255, 255, 255, 255, size )
outputMessageTextItem2 = textCreateTextItem ( "", 0.8, start +
(distance * 2 ), 1, 255, 255, 255, 255, size )
outputMessageTextItem3 = textCreateTextItem ( "", 0.8, start +
(distance * 3 ),
1, 255, 255, 255, 255, size )
outputMessageTextItem4 = textCreateTextItem ( "", 0.8, start +
(distance * 4 ), 1, 255, 255, 255, 255, size )
outputMessageTextItem5 = textCreateTextItem ( "", 0.8, start +
(distance * 5 ), 1, 255, 255, 255, 255, size )
outputMessageTextItem6 = textCreateTextItem ( "", 0.8, start +
(distance * 6 ), 1, 255, 255, 255, 255, size )
textDisplayAddText ( outputMessageTextDisplay, outputMessageTextItem1 )
textDisplayAddText ( outputMessageTextDisplay, outputMessageTextItem2 )
textDisplayAddText ( outputMessageTextDisplay, outputMessageTextItem3 )
textDisplayAddText ( outputMessageTextDisplay, outputMessageTextItem4 )
textDisplayAddText ( outputMessageTextDisplay, outputMessageTextItem5 )
textDisplayAddText ( outputMessageTextDisplay, outputMessageTextItem6 )
local players = getElementsByType ( "player" )
for k,v in players do
textDisplayAddObserver ( outputMessageTextDisplay, v )
end
end
addEventHandler ( "onPlayerJoin", getRootElement(), "showTextPlayerJoin" )
function showTextPlayerJoin ()
textDisplayAddObserver ( outputMessageTextDisplay, source )
end
function outputMessage ( text, r, g, b, a )
local text2 = textItemGetText ( outputMessageTextItem2 )
local r2,g2,b2,a2 = textItemGetColor ( outputMessageTextItem2 )
local text3 = textItemGetText ( outputMessageTextItem3 )
local r3,g3,b3,a3 = textItemGetColor ( outputMessageTextItem3 )
local text4 = textItemGetText ( outputMessageTextItem4 )
local r4,g4,b4,a4 = textItemGetColor ( outputMessageTextItem4 )
local text5 = textItemGetText ( outputMessageTextItem5 )
local r5,g5,b5,a5 = textItemGetColor ( outputMessageTextItem5 )
local text6 = textItemGetText ( outputMessageTextItem6 )
local r6,g6,b6,a6 = textItemGetColor ( outputMessageTextItem6 )
textItemSetText ( outputMessageTextItem5, text6 )
textItemSetColor ( outputMessageTextItem5, r6, g6, b6, a6 )
textItemSetText ( outputMessageTextItem4, text5 )
textItemSetColor ( outputMessageTextItem4, r5, g5, b5, a5 )
textItemSetText ( outputMessageTextItem3, text4 )
textItemSetColor ( outputMessageTextItem3, r4, g4, b4, a4 )
textItemSetText ( outputMessageTextItem2, text3 )
textItemSetColor ( outputMessageTextItem2, r3, g3, b3, a3 )
textItemSetText ( outputMessageTextItem1, text2 )
textItemSetColor ( outputMessageTextItem1, r2, g2, b2, a2 )
---
textItemSetText ( outputMessageTextItem6, text )
textItemSetColor ( outputMessageTextItem6, r, g, b, a )
--
end |
На этом всё, следите за дальнейшими руководствами на нашем сайте!
|
|