137 lines
4.6 KiB
Lua
137 lines
4.6 KiB
Lua
-- 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)
|
|
|
|
if not ctf then
|
|
_G.minetest.forceload_block(self.pos(),true)
|
|
ctf = {
|
|
[1] = {state = 1, flagnode = "basic_robot:button8080FF", pos = {x=-18,y=501,z=17}, name = "blue", owner = "", score = 0}, -- team[1]
|
|
[2] = {state = 1, flagnode = "basic_robot:buttonFF8080", pos = {x=-79,y=501,z=46}, 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
|
|
end
|
|
|
|
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
|
|
end
|
|
|
|
end
|
|
|
|
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 5 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()
|
|
end
|
|
end
|
|
|
|
elseif gamestate == 2 then
|
|
-- check player health
|
|
for k,v in pairs(teams) do
|
|
local hp = teams[k][3]:get_hp();
|
|
if not hp or hp<10 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
|
|
|
|
|
|
|
|
end
|
|
end
|
|
|
|
|
|
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
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
end
|
|
end
|
|
--say(serialize(event))
|
|
end
|
|
elseif gamestate == 3 then -- intermission
|
|
if t>0 then t=t-1 else gamestate = 0 end
|
|
end |