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!\n Winner: None
\n NewRound!" , 0 .5 , 0 .5 , 2 , 255 , 0 , 0 , 255 , 255 )
else
textItem = textCreateTextItem ( "The time is out!\n Winner:
" ..leaderText.." with " ..getElementData ( leaderPlayer, "points"
) .."points!\n \n NewRound!" , 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" , -- g etRootElement( ) , "kothHillEnter" )
function kothHillEnter ( player, dim )
if source == hillArea then
outputMessage ( getClientName( player) .." entered the zone!" ,
255 , 255 , 109 , 255 )
end
end
addEventHandler ( "onColShapeLeave" , -- g etRootElement( ) , "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
На этом всё, следите за дальнейшими руководствами на нашем сайте!