This week's tutorial is how to make a King of the Hill gamemode. The example KOTH script here will monitor a zone (the hill) and give points to a person when they occupy it alone. Every second they remain in the zone, they recieve 1 point. After a certain time limit, the game is over and the person with the highest score wins.
Video footage: scriptvideo6.avi - DivX 5.0 (640x480, 29.97fps)
Forum support thread: forum.mtavc.com
King of the Hill Script: script6.lua
Preparation
At first we set up a timer that will check players location every 500 ms.
kothTimer = setTimer ( "checkHillArea", 500, 0 ) |
addEventHandler ( "onResourceStart", getRootElement(), "kothStart" ) function kothStart ( name ) hillArea = createColSquare ( -2171.0678710938, 678.17950439453, 0, 15, 15 ) |
hillRadar = createRadarArea ( -2183.5678710938, 705.67950439453, 40, -40, 0,
255, 0, 175 ) |
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 |
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 ) |
giveWeapon ( source, 30, 10000 ) end |
function checkHillArea () |
We create a table which stores all the players who are at the area to be captured.
local hillPlayers = getElementsWithinColShape ( hillArea, "player" ) |
for k,v in hillPlayers do
if ( isPlayerDead ( v ) ) then
table.remove(hillPlayers,k)
end
end |
if table.getn ( hillPlayers ) ~= 0 then |
setRadarAreaFlashing ( hillRadar, true )
setRadarAreaColor ( hillRadar, 255, 0, 0, 175 ) |
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 |
if leaders > 3 or leaders == getPlayerCount () or leaderPlayer == false then
textItemSetText ( textItemLeaderScore, "Leader: None" )
else
textItemSetText ( textItemLeaderScore, "Leader: "..leaderText.."
- "..getElementData(leaderPlayer,"points") )
end
end |
function kothEnd ( ) |
killTimer ( kothTimer ) |
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 ) |
local damage = loss * 1.25
local hpLeft = getPlayerHealth ( source ) - damage |
if ( hpLeft > 0 ) then
if ( bodypart == 9 ) then
killPlayer ( source, attacker, weapon, bodypart )
else
setPlayerHealth ( source, hpLeft )
end |
else
killPlayer ( source, attacker, weapon, bodypart )
end
end
end |
When a player enters/leaves the zone, we should output it
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 |
if ( isElementWithinColShape ( source, hillArea ) ) then
r = 255
g = 255
b = 109
a = 255
end |
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 |





