minetest.register_on_player_receive_fields(function(player, formname, fields)
   if formname == 'sabotage:traitor' then
      local name = player:get_player_name()
      local map_id = lobby.game[name]
      local pos = sabotage.player_pos[name]
      local meta = minetest.get_meta(pos)
      if fields.sabotage then
         local sabotaged = lobby.sabotage[map_id]
         if sabotaged == true then
            minetest.chat_send_player(name, 'Sorry you can only sabotage one item at a time currently.')
         else
            local chance = meta:get_int('chance') or 1
            local damage = meta:get_int('damage') or 1
            local level = meta:get_int('level') or 1
            local player_attributes = player:get_meta()
            local luck = player_attributes:get_int('luck')
            if math.random(10) + luck >= chance then
               local hurt = math.random(damage)
               local health = player:get_hp()
               local new_health = health - hurt
               player:set_hp(new_health)
            end
            if math.random(10) + luck >= chance then
               local node = minetest.get_node(pos)
               local node_name = node.name
               local def = minetest.registered_nodes[node_name]
               local desc = def.description
               local flip = def.sabotage_switch
               if flip then
                  minetest.swap_node(pos, {name = flip, param2 = node.param2})
               end
               meta:set_string('traitor', name)
               meta:set_string('map_id', map_id)
               lobby.sabotage[map_id] = true
               local time = meta:get_int('timer')
               if time > 0 then
                  sabotage.show_hud_timed(map_id, time, desc)
                  sabotage.timer[map_id] = time
               elseif time == 0 then
                  sabotage.show_hud(map_id, desc)
               end
               local alert = meta:get_string('alert')
               local level = meta:get_int('level') or 0
               local terminate = meta:get_string('terminate')
               lobby.message_to_level(map_id, 'Level has been sabotaged, proceed with caution.')
               lobby.message_to_level(map_id, alert)
               minetest.chat_send_player(name, 'You successfully sabotaged this node')
               lobby.sabotage_level[map_id] = level
               local data = {}
               data.pos = pos
               data.traitor = name
               data.terminate = terminate
               sabotage.data[map_id] = data
            end
         end
      end
   elseif formname == 'sabotage:builder' then
      local name = player:get_player_name()
      local map_id = lobby.game[name]
      local pos = sabotage.player_pos[name]
      local meta = minetest.get_meta(pos)
      if fields.save then
         local timer = math.max((tonumber(fields.timer_input) or 0), 0)
         local chance = math.min((tonumber(fields.chance) or 2), 10)
         local damage = tonumber(fields.damage) or 1
         local alert = fields.alert or ''
         local level = math.min((tonumber(fields.level) or 1), 4)
         local xp = fields.xp or 0
         meta:set_int('timer', timer)
         meta:set_int('chance', chance)
         meta:set_int('damage', damage)
         meta:set_int('level', level)
         meta:set_int('xp', xp)
         meta:set_string('alert', alert)
      elseif fields.terminate then
         meta:set_string('terminate', fields.terminate)
      end
   elseif formname == 'sabotage:player' then
      local name = player:get_player_name()
      local map_id = lobby.game[name]
      if fields.repair then
         local pos = sabotage.player_pos[name]
         local meta = minetest.get_meta(pos)
         local chance = meta:get_int('chance') or 1
         local damage = meta:get_int('damage') or 1
         local terminate = meta:get_string('terminate')
         local player_attributes = player:get_meta()
         local luck = player_attributes:get_int('luck')
         if math.random(10) + luck >= chance then
            local hurt = math.random(damage)
            local health = player:get_hp()
            local new_health = health - hurt
            player:set_hp(new_health)
         end
         if math.random(10) + luck >= chance then
            sabotage.timer[map_id] = 0
            sabotage.finish(map_id, name, 'team')
         end
      end
   end
end)

function sabotage.finish(map_id, name, winner)
   print 'sabotage ended'
   if lobby.map[map_id] then
      local data = sabotage.data[map_id]
      local pos = data.pos
      local traitor = data.traitor
      local terminate = data.terminate
      local node = minetest.get_node(pos)
      local node_name = node.name
      local def = minetest.registered_nodes[node_name]
      local flip = def.sabotage_switch
      if flip then
         minetest.swap_node(pos, {name = flip, param2 = node.param2})
      end
      if lobby.map[map_id] > 1 and lobby.traitors[map_id] == traitor then
         lobby.sabotage_level[map_id] = 5
         lobby.sabotage[map_id] = false
         if terminate == 'true' then
            if winner == 'team' then
               lobby.team_win(map_id)
            else
               lobby.traitor_win(traitor, map_id)
            end
         elseif name then
            local meta = minetest.get_meta(pos)
            local desc = def.description
            local xp = meta:get_int('xp')
            tasks.only_add_xp(xp, name)
            lobby.message_to_level(map_id, desc.. ' was just fixed.')
         end
      end
   end
end
