123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344 |
- function lobby.load()
- local file = io.open(minetest.get_worldpath() .. '/levels', 'r')
- if file then
- lobby.savedata = minetest.deserialize(file:read('*a'))
- file:close()
- --lobby.savedata.stats = {}
- --lobby.savedata.name_2_id = {}
- --lobby.savedata.id_2_name = {}
- else
- lobby.savedata = {}
- lobby.savedata.IDs = {}
- lobby.savedata.data = {}
- lobby.savedata.stats = {}
- lobby.savedata.name_2_id = {}
- lobby.savedata.id_2_name = {}
- end
- end
- function lobby.save()
- local file = io.open(minetest.get_worldpath() .. '/levels', 'w')
- file:write(minetest.serialize(lobby.savedata))
- file:close()
- end
- function lobby.no_drop(itemstack, dropper, pos)
- return
- end
- function lobby.is_integer(input)
- local number = tonumber(input)
- if number then
- if math.floor(number) == number then
- return true
- end
- end
- end
- local storage = minetest.get_mod_storage()
- function lobby.queue_xp(name, xp) --Queues XP for offline players
- storage:set_int(name, xp)
- end
- function lobby.check_xp_queue(name) --Checks if a player was award xp whilst offline.
- local xp = storage:get_int(name)
- if xp > 0 then
- local player = minetest.get_player_by_name(name)
- lobby.give_xp(player, xp)
- storage:set_int(name, 0)
- minetest.chat_send_player(name, 'Hey, you just got '..xp..' xp!')
- end
- end
- function lobby.give_xp(player, amount)
- local player_attributes = player:get_meta()
- local xp = player_attributes:get_float('xp') or 0
- xp = xp + amount
- player_attributes:set_float('xp', xp)
- sfinv.set_player_inventory_formspec(player)
- end
- function lobby.take_xp(player, amount)
- local player_attributes = player:get_meta()
- local xp = player_attributes:get_float('xp')
- if xp >= amount then
- local xp = xp - amount
- player_attributes:set_float('xp', xp)
- sfinv.set_player_inventory_formspec(player)
- return true
- else
- return false
- end
- end
- function lobby.corpse_entry(pos, map_id)
- local corpse_pos = lobby.corpses[map_id]
- table.insert(corpse_pos, pos)
- lobby.corpses[map_id] = corpse_pos
- end
- function lobby.corpse_removal(map_id)
- local corpse_pos = lobby.corpses[map_id]
- if corpse_pos then
- for key, value in pairs(corpse_pos) do
- minetest.set_node(value, {name='air'})
- end
- end
- end
- function lobby.players_on_level(map_id)
- local survivors = ''
- for _, player in pairs(minetest.get_connected_players()) do
- local rname = player:get_player_name()
- if lobby.game[rname] == map_id then
- survivors = survivors..rname..', '
- end
- end
- return survivors
- end
- function lobby.update_maps(map_id)
- local count = lobby.map[map_id] - 1 or 10
- if count <= 1 then
- lobby.map[map_id] = 0
- lobby.corpse_removal(map_id)
- for _, player in pairs(minetest.get_connected_players()) do
- local rname = player:get_player_name()
- if lobby.game[rname] == map_id or lobby.game[rname] == map_id..'_ghost' then
- minetest.close_formspec(rname, '')
- player:respawn()
- local player_attributes = player:get_meta()
- player:set_nametag_attributes({
- color = {a = 255, r = 255, g = 255, b = 255}
- })
- player:set_properties({visual_size = {x = 10, y = 10}, collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3}})
- player:set_pos(lobby.spawn_pos)
- player_attributes:set_string('mode', 'solo')
- minetest.chat_send_player(rname, 'Kicking you to the lobby')
- player:set_physics_override({speed=1})
- local player_inv = player:get_inventory()
- player_inv:set_list('main', {})
- lobby.game[rname] = 'lobby'
- local idx = sabotage.hud[rname]
- if idx then
- for key,value in pairs(idx) do
- player:hud_remove(value)
- end
- end
- end
- end
- else
- lobby.map[map_id] = count
- end
- end
- function lobby.vote(map_id, force)
- local needed_votes = lobby.map[map_id] - 1
- local actual_votes = lobby.votes[map_id]
- if actual_votes >= needed_votes or force then
- lobby.vote_timer[map_id] = -1
- --Reset vote status and kick player with the highest score.
- local high_score = 0
- local kick = ''
- local traitor = lobby.traitors[map_id]
- for _, player in pairs(minetest.get_connected_players()) do
- local rname = player:get_player_name()
- if lobby.game[rname] == map_id then
- local score = lobby.suspect[rname]
- local player_attributes = player:get_meta()
- if score > high_score then
- high_score = score
- kick = rname
- end
- lobby.suspect[rname] = 0
- player:set_physics_override({speed=1})
- player:set_armor_groups({})
- player_attributes:set_string('voting', 'false')
- end
- end
- if kick == traitor then
- lobby.team_win(map_id)
- elseif needed_votes == 1 and kick ~= traitor then
- lobby.traitor_win(traitor, map_id)
- elseif kick ~= '' then
- lobby.message_to_level(map_id, 'The votes are in, '..kick..' will be kicked.')
- local player = minetest.get_player_by_name(kick)
- local player_attributes = player:get_meta()
- player:set_nametag_attributes({
- color = {a = 0, r = 255, g = 255, b = 255}
- })
- player:set_properties({visual_size = {x = 0, y = 0}, collisionbox = {-0.3, 0.0, -0.3, 0.3, .2, 0.3}})
- player:set_physics_override({speed=1})
- player_attributes:set_string('mode', 'ghost')
- minetest.chat_send_player(kick, 'You were kicked, and are now a ghost. Return to the lobby with the /lobby chat command.')
- lobby.game[kick] = map_id..'_ghost'
- lobby.update_maps(map_id)
- else
- lobby.message_to_level(map_id, 'Nobody was kicked this round.')
- for _, player in pairs(minetest.get_connected_players()) do
- local rname = player:get_player_name()
- if lobby.game[rname] == map_id then
- minetest.close_formspec(rname, 'lobby:voting')
- end
- end
- end
- end
- end
- function lobby.team_win(map_id)
- lobby.corpse_removal(map_id)
- local traitor = lobby.traitors[map_id]
- for _, player in pairs(minetest.get_connected_players()) do
- local rname = player:get_player_name()
- if lobby.game[rname] == map_id then
- local player_attributes = player:get_meta()
- player_attributes:set_string('mode', 'solo')
- minetest.close_formspec(rname, '')
- player:respawn()
- lobby.give_xp(player, 25)
- minetest.chat_send_player(rname, 'The traitor ('..traitor..') was defeated.')
- player:set_pos(lobby.spawn_pos)
- player:set_physics_override({speed=1})
- local player_inv = player:get_inventory()
- player_inv:set_list('main', {})
- lobby.game[rname] = 'lobby'
- local idx = sabotage.hud[rname]
- if idx then
- for key,value in pairs(idx) do
- player:hud_remove(value)
- end
- end
- elseif lobby.game[rname] == map_id..'_ghost' then
- minetest.close_formspec(rname, '')
- player:respawn()
- local player_attributes = player:get_meta()
- player:set_nametag_attributes({
- color = {a = 255, r = 255, g = 255, b = 255}
- })
- player:set_properties({visual_size = {x = 10, y = 10}, collisionbox = {-0.3, 0.0, -0.3, 0.3, 1.7, 0.3}})
- player:set_pos(lobby.spawn_pos)
- player_attributes:set_string('mode', 'solo')
- minetest.chat_send_player(rname, 'The traitor ('..traitor..') was defeated.')
- player:set_physics_override({speed=1})
- local player_inv = player:get_inventory()
- player_inv:set_list('main', {})
- lobby.game[rname] = 'lobby'
- local idx = sabotage.hud[rname]
- if idx then
- for key,value in pairs(idx) do
- player:hud_remove(value)
- end
- end
- end
- end
- lobby.map[map_id] = 0
- local start_time = lobby.play_time[map_id]
- local finish_time = minetest.get_us_time()
- local play_time = (finish_time - start_time)/1000000
- lobby.update_stats(map_id, '', 'team', nil, play_time)
- local game_data = lobby.savedata.data[map_id]
- local map_name
- if game_data then
- map_name = game_data['map_name']
- else
- map_name = map_id
- end
- minetest.chat_send_all('The traitor was defeated on this round in '..map_name)
- end
- function lobby.traitor_win(traitor, map_id)
- local player = minetest.get_player_by_name(traitor)
- lobby.corpse_removal(map_id)
- lobby.give_xp(player, 25)
- minetest.chat_send_player(traitor, 'CONGRATULATIONS!!! You killed all the crew!')
- lobby.game[traitor] = 'lobby'
- player:set_pos(lobby.spawn_pos)
- player:set_physics_override({speed=1})
- local player_inv = player:get_inventory()
- player_inv:set_list('main', {})
- lobby.map[map_id] = 0
- local start_time = lobby.play_time[map_id]
- local finish_time = minetest.get_us_time()
- local play_time = (finish_time - start_time)/1000000
- lobby.update_stats(map_id, '', 'traitor', nil, play_time)
- local game_data = lobby.savedata.data[map_id]
- local map_name = game_data['map_name'] or map_id
- minetest.chat_send_all('The traitor ('..traitor..') was victorious on this round in the '..map_name)
- end
- --[[ is_builder(player: ObjectRef): bool
- Return true if `player` has builder privs.
- --]]
- function lobby.is_builder(player)
- if player == nil then return nil end
- local name = player:get_player_name()
- return minetest.check_player_privs(name, {builder = true})
- end
- --[[ builder_to_player(player: ObjectRef)
- Cast builder into regular player, including switching inventories, revoking privs, etc.
- --]]
- function lobby.builder_to_player(player)
- if player == nil then return end
- local pl_name = player:get_player_name()
- local pl_attr = player:get_meta()
- local pl_priv = minetest.get_player_privs(pl_name)
- local pl_mode = pl_attr:get_string('mode') or ''
- if pl_mode ~= 'builder' then return end
- pl_priv.creative = nil
- pl_priv.fly = nil
- pl_priv.fast = nil
- pl_priv.worldedit = nil
- pl_priv.areas = nil
- minetest.set_player_privs(pl_name, pl_priv)
- pl_attr:set_string('mode', 'solo')
- local inv = player:get_inventory()
- local old_inv = inv:get_list('main')
- inv:set_list('builder', old_inv)
- inv:set_size('main', 16)
- inv:set_list('main', {})
- end
- --[[ player_to_builder(player: ObjectRef)
- Cast regular player into builder, including switching inventories, granting privs, etc.
- Does NOT check if the player has acquired the builder priv. Call lobby.is_builder()
- beforehand to make sure player is allowed to be lifted.
- --]]
- function lobby.player_to_builder(player)
- if player == nil then return end
- local pl_name = player:get_player_name()
- local pl_attr = player:get_meta()
- local pl_priv = minetest.get_player_privs(pl_name)
- local pl_mode = pl_attr:get_string('mode') or ''
- if pl_mode == 'builder' then return end
- pl_priv.creative = true
- pl_priv.fly = true
- pl_priv.fast = true
- minetest.set_player_privs(pl_name, pl_priv)
- pl_attr:set_string('mode', 'builder')
- local inv = player:get_inventory()
- local old_inv = inv:get_list('builder')
- inv:set_list('builder', {})
- inv:set_size('main', 32)
- inv:set_list('main', old_inv)
- end
- function lobby.create_id(player_name)
- local i = 1
- local map_id = player_name..'_'..i
- while lobby.savedata.IDs[map_id] do
- i = i + 1
- map_id = player_name..'_'..i
- end
- return map_id
- end
|