2019-01-27 09:40:29 -08:00
-- simple ctf robot, rnd
--instructions: build game arena and place blue/red buttons as flags. edit flag positions below
--you must register 'keyboard' events by placing robot with same 'id' as robot running this code at 'event register' positions - default (32*i,64*j+1, 32*k)
2018-04-03 15:21:12 -07:00
2019-01-27 09:40:29 -08:00
if not ctf then
_G.minetest . forceload_block ( self.pos ( ) , true )
ctf = {
[ 1 ] = { state = 1 , flagnode = " basic_robot:button8080FF " , pos = { x =- 18 , y = 502 , z = 110 } , name = " blue " , owner = " " , score = 0 } , -- team[1]
[ 2 ] = { state = 1 , flagnode = " basic_robot:buttonFF8080 " , pos = { x =- 18 , y = 502 , z = 80 } , name = " red " , owner = " " , score = 0 } , -- team[2]
}
teams = { } -- example : {["rnd"] = {1,0, player, health points at start}}; -- team, ownership of flag
maxscore = 3 ;
t = 0
teamid = 1 ; -- team selector when joining
gamestate = 0 ;
self.listen ( 1 )
self.spam ( 1 )
get_id = function ( pos )
local range = 1000 ;
return pos.x + range * pos.y + range ^ 2 * pos.z
2018-04-03 15:21:12 -07:00
end
2019-01-27 09:40:29 -08:00
flag_id = { } ; for i = 1 , # ctf do flag_id [ get_id ( ctf [ i ] . pos ) ] = i end
render_flags = function ( )
for i = 1 , # ctf do minetest.set_node ( ctf [ i ] . pos , { name = ctf [ i ] . flagnode } ) end
2018-04-03 15:21:12 -07:00
end
2019-01-27 09:40:29 -08:00
end
2018-04-03 15:21:12 -07:00
2019-01-27 09:40:29 -08:00
if gamestate == 0 then -- welcome
say ( colorize ( " red " , " #CAPTURE THE FLAG GAME. say ' \\ join' to join game. to start game one of joined players says ' \\ start' " ) )
gamestate = 1
elseif gamestate == 1 then
speaker , msg = self.listen_msg ( )
if msg == " join " then
local pl = minetest.get_player_by_name ( speaker ) ;
teams [ speaker ] = { teamid , 0 , pl , 20 } ; pl : set_hp ( 20 )
local msg1 = " " ; local msg2 = " "
for k , v in pairs ( teams ) do
if v [ 1 ] == 1 then msg1 = msg1 .. k .. " " elseif v [ 1 ] == 2 then msg2 = msg2 .. k .. " " end
end
say ( colorize ( " yellow " , " #CTF : " .. speaker .. " joined team " .. ctf [ teamid ] . name .. " . TEAM " .. ctf [ 1 ] . name .. " : " .. msg1 .. " , TEAM " .. ctf [ 2 ] . name .. " : " .. msg2 ) )
teamid = 3 - teamid ; -- 1,2
elseif msg == " start " then -- game start
if teams [ speaker ] then
gamestate = 2
keyboard.get ( ) -- clear keyboard buffer
say ( colorize ( " red " , " #CTF GAME STARTED. GET ENEMY FLAG AND BRING IT BACK TO YOUR FLAG. DONT LET YOUR HEALTH GO BELOW 3 HEARTS OR YOU ARE OUT. " ) )
for k , _ in pairs ( teams ) do -- teleport players
local data = teams [ k ] ; data [ 3 ] : setpos ( ctf [ data [ 1 ] ] . pos )
end
render_flags ( )
2018-04-03 15:21:12 -07:00
end
2019-01-27 09:40:29 -08:00
end
elseif gamestate == 2 then
speaker , msg = self.listen_msg ( )
if msg == " score " then
local msg1 = " " ; local msg2 = " "
for k , v in pairs ( teams ) do
if v [ 1 ] == 1 then msg1 = msg1 .. k .. " " elseif v [ 1 ] == 2 then msg2 = msg2 .. k .. " " end
2018-04-03 15:21:12 -07:00
end
2019-01-27 09:40:29 -08:00
say ( colorize ( " yellow " , " SCORE " .. ctf [ 1 ] . score .. " / " .. ctf [ 2 ] . score ) .. " \n " .. colorize ( " yellow " , " TEAM " .. ctf [ 1 ] . name .. " : " .. msg1 .. " , TEAM " .. ctf [ 2 ] . name .. " : " .. msg2 ) )
end
2018-04-03 15:21:12 -07:00
2019-01-27 09:40:29 -08:00
-- check player health
for k , v in pairs ( teams ) do
local hp = teams [ k ] [ 3 ] : get_hp ( ) ;
if not hp or hp < 6 then -- teams[k][4]
local cflag = teams [ k ] [ 2 ] ;
if cflag > 0 then -- drop flag
ctf [ cflag ] . state = 1
ctf [ cflag ] . owner = " "
minetest.set_node ( ctf [ cflag ] . pos , { name = ctf [ cflag ] . flagnode } )
say ( colorize ( " red " , " #CTF " .. k .. " dropped " .. ctf [ cflag ] . name .. " flag! " ) )
end
if not hp then -- player left
say ( colorize ( " yellow " , " #CTF " .. k .. " left the game! " ) )
teams [ k ] = nil
else -- reset player
say ( colorize ( " yellow " , " #CTF " .. k .. " resetted! " ) )
v [ 2 ] = 0 -- player has no flag
v [ 3 ] : set_hp ( 20 )
v [ 3 ] : setpos ( ctf [ v [ 1 ] ] . pos )
end
2018-04-03 15:21:12 -07:00
2019-01-27 09:40:29 -08:00
end
2018-04-03 15:21:12 -07:00
end
2019-01-27 09:40:29 -08:00
event = keyboard.get ( )
if event and teams [ event.puncher ] then
--say(serialize(event))
local punch_id = get_id ( { x = event.x , y = event.y , z = event.z } ) ;
local flag = flag_id [ punch_id ] ;
if flag then
local state = ctf [ flag ] . state
local puncher = event.puncher ;
if state == 1 then -- flag is here, ready to be taken or capture of enemy flag
if teams [ puncher ] [ 1 ] ~= flag then -- take
say ( colorize ( " red " , " #CTF " .. puncher .. " has taken " .. ctf [ flag ] . name .. " flag ! " ) )
ctf [ flag ] . state = 2 ;
ctf [ flag ] . owner = puncher ;
teams [ puncher ] [ 2 ] = flag ;
minetest.set_node ( ctf [ flag ] . pos , { name = " basic_robot:buttonFFFF80 " } )
else -- capture?
if teams [ puncher ] [ 2 ] > 0 then
local cflag = teams [ puncher ] [ 2 ] -- puncher has this flag
local data = ctf [ cflag ] ;
local team = teams [ puncher ] [ 1 ] ;
ctf [ team ] . score = ctf [ team ] . score + 1
ctf [ team ] . owner = " "
ctf [ cflag ] . state = 1 ; -- reset captured flag state
minetest.set_node ( ctf [ cflag ] . pos , { name = ctf [ cflag ] . flagnode } )
teams [ puncher ] [ 2 ] = 0
say ( colorize ( " orange " , " #CTF " .. puncher .. " has captured " .. data.name .. " flag! Team " .. ctf [ team ] . name .. " has score " .. ctf [ team ] . score ) )
if ctf [ team ] . score == maxscore then
say ( colorize ( " yellow " , " #CTF: TEAM " .. ctf [ team ] . name .. " WINS! " ) )
gamestate = 3 ; t = 5 ; -- intermission, duration 5
--reset
teams = { }
for i = 1 , # ctf do ctf [ i ] . state = 1 ctf [ i ] . score = 0 ctf [ i ] . owner = " " end
end
2018-04-03 15:21:12 -07:00
end
2019-01-27 09:40:29 -08:00
2018-04-03 15:21:12 -07:00
end
2019-01-27 09:40:29 -08:00
2018-04-03 15:21:12 -07:00
end
end
2019-01-27 09:40:29 -08:00
--say(serialize(event))
2018-04-03 15:21:12 -07:00
end
2019-01-27 09:40:29 -08:00
elseif gamestate == 3 then -- intermission
if t > 0 then t = t - 1 else gamestate = 0 end
end