voxel_knights/mods/game/friends.lua

278 lines
8.6 KiB
Lua

local selected = {}
local function table_remove(table, string)
for k, v in ipairs(table) do
if string == v then
table[k] = nil
return table
end
end
return table
end
local function table_find(t1, string)
for _, v in ipairs(t1) do
if v == string then
return true
end
end
return false
end
local function both_friends(p1, p2)
local name1 = p1:get_player_name()
local name2 = p2:get_player_name()
local p1_f = minetest.deserialize(p1:get_meta():get_string("friends"))
local p2_f = minetest.deserialize(p2:get_meta():get_string("friends"))
if type(p1_f) == "string" then
p1_f = {p1_f}
end
if type(p2_f) == "string" then
p2_f = {p2_f}
end
if table_find(p1_f, name2) == true and table_find(p2_f, name1) == true then
return true
else
return false
end
end
sfinv.register_page("game:friends", {
title = "Friends",
get = function(_, player, context)
local meta = player:get_meta()
local name = player:get_player_name()
local friends = minetest.deserialize(meta:get_string("friends"))
local friends_string = "You have no friends :("
if selected[name] == nil then
selected[name] = 1
end
if type(friends) == "string" then
friends = {friends}
end
if friends ~= nil then
friends_string = ""
for id, n in ipairs(friends) do
local loc = "Aboveground"
local fobj = minetest.get_player_by_name(n)
if fobj and fobj:get_meta():get_string("location") == "dungeon" then
loc = "In the dungeon"
end
if fobj then
if both_friends(player, fobj) == true then
friends_string = friends_string .. "#ffc837"..n.." ("..loc.."),"
else
table.remove(friends, id)
meta:set_string("friends", minetest.serialize(friends))
end
else
friends_string = friends_string .. "#9d9d9d"..n.." (Offline),"
end
end
friends_string = friends_string:sub(1, friends_string:len()-1)
end
local form = "label[0.1,0;Punch a player ingame to add them as a friend]" ..
"textlist[0.1,0.5;4.4,3.1;friends;" .. friends_string .. ";"..selected[name]..";true]" ..
"box[0.1,0.5;4.4,3.1;#000]" ..
"image[0,4.75;1,1;gui_hb_bg.png]" ..
"image[1,4.75;1,1;gui_hb_bg.png]" ..
"image[2,4.75;1,1;gui_hb_bg.png]" ..
"image[3,4.75;1,1;gui_hb_bg.png]" ..
"image[4,4.75;1,1;gui_hb_bg.png]" ..
"image[5,4.75;1,1;gui_hb_bg.png]" ..
"image[6,4.75;1,1;gui_hb_bg.png]" ..
"image[7,4.75;1,1;gui_hb_bg.png]"
if friends ~= nil and friends[selected[name]] ~= nil then
form = form .. "image_button[0.2,3.8;4.4,0.8;button.png;remove_friend;Remove Friend]"
end
if friends ~= nil and friends[selected[name]] ~= nil
and minetest.get_player_by_name(friends[selected[name]]) then
local f = friends[selected[name]]
local join = false
form = form .. "image_button[4.7,3.8;3.3,0.8;button.png;gift;Send Gift]" ..
"list[current_player;gift;5.8,2.8;1,1;0]" ..
"listring[current_player;main]" ..
"listring[current_player;gift]"
if game.party[f] ~= nil and game.party[f] ~= game.party[name] then
form = form .. "image_button_exit[4.7,0.6;3.3,0.8;button.png;join;Join]"
join = true
end
if game.party[name] ~= nil and game.party[f] ~= game.party[name] then
if join == true then
form = form .. "image_button[4.7,1.4;3.3,0.8;button.png;invite;Invite to party]"
else
form = form .. "image_button[4.7,0.6;3.3,0.8;button.png;invite;Invite to party]"
end
end
end
return sfinv.make_formspec(player, context, form, true)
end,
on_player_receive_fields = function(_, player, _, fields)
local name = player:get_player_name()
local inv = player:get_inventory()
local meta = player:get_meta()
local friends = minetest.deserialize(meta:get_string("friends"))
if type(friends) == "string" then
friends = {friends}
end
if fields.friends then
selected[name] = tonumber(fields.friends:sub(fields.friends:find(":")+1))
elseif fields.invite and minetest.get_player_by_name(friends[selected[name]]) then
minetest.chat_send_player(friends[selected[name]], minetest.colorize("#ffc837", name..
" has invited you to join them in the dungeon!"))
minetest.chat_send_player(name, "Invite sent")
elseif fields.join and minetest.get_player_by_name(friends[selected[name]]) then
local friend = minetest.get_player_by_name(friends[selected[name]])
local pos = friend:get_pos()
player:set_pos(pos)
meta:set_string("location", "dungeon")
game.party[name] = game.party[friends[selected[name]]]
game.parties[game.party[name]][name] = 1
game.dungeons = game.dungeons - 1
game.update_inventories()
elseif fields.gift and inv:is_empty("gift") ~= true then
local friend = minetest.get_player_by_name(friends[selected[name]])
local item = inv:get_stack("gift", 1)
if ItemStack(item):get_definition().tradeable == true then
inv:remove_item("gift", item)
friend:get_inventory():add_item("storage", item)
minetest.chat_send_player(name, "Gift sent!")
minetest.chat_send_player(friend:get_player_name(), minetest.colorize("#ffc837", name ..
" sent you " .. item .. "! Look in your storage to see it"))
else
minetest.chat_send_player(name, "That item is not tradable!")
inv:remove_item("gift", item)
inv:add_item("main", item)
end
elseif fields.remove_friend then
local fname = friends[selected[name]]
local fp = minetest.get_player_by_name(fname)
table.remove(friends, selected[name])
meta:set_string("friends", minetest.serialize(friends))
if fp then
local f_friends = minetest.deserialize(fp:get_meta():get_string("friends"))
if type(f_friends) == "string" then
f_friends = {f_friends}
end
fp:get_meta():set_string("friends", minetest.serialize(table_remove(f_friends, name)))
game.update_inventories()
end
end
sfinv.set_page(player, "game:friends")
end
})
function game.show_friend_request_form(from, to)
local form = "size[5,2]" ..
"label[0.1,0.1;Send " ..to.. " a friend request?]" ..
"image_button_exit[0.6,1;4,0.8;button.png;send_request;Send]"
game.friend_requests[from].to = to
minetest.show_formspec(from, "game:friend_request_send", form)
end
minetest.register_on_player_receive_fields(function(player, formname, fields)
local from = player:get_player_name()
if formname == "game:friend_request_send" then
if fields.send_request then
local to = game.friend_requests[from].to
minetest.chat_send_player(to, minetest.colorize("#ffc837", from..
" sent you a friend request. /accept to agree. /decline to decline"))
minetest.chat_send_player(from, "Friend request sent")
game.friend_requests[to].from = from
game.friend_requests[from].to = nil
end
end
end)
minetest.register_chatcommand("accept", {
description = "Accept friend request",
func = function(name)
if game.friend_requests[name].from ~= nil then
local to_meta = minetest.get_player_by_name(name):get_meta()
local from_meta = minetest.get_player_by_name(game.friend_requests[name].from):get_meta()
local to_friends = minetest.deserialize(to_meta:get_string("friends"))
local from_friends = minetest.deserialize(from_meta:get_string("friends"))
if type(to_friends) == "string" then
to_friends = {to_friends}
end
if type(from_friends) == "string" then
from_friends = {from_friends}
end
minetest.chat_send_player(game.friend_requests[name].from, name.." accepted your friend request!")
minetest.chat_send_player(name, "Accepted friend request from "..game.friend_requests[name].from)
if to_friends == nil then
to_friends = game.friend_requests[name].from
else
table.insert(to_friends, game.friend_requests[name].from)
end
if from_friends == nil then
from_friends = name
else
table.insert(from_friends, name)
end
to_meta:set_string("friends", minetest.serialize(to_friends))
from_meta:set_string("friends", minetest.serialize(from_friends))
game.friend_requests[game.friend_requests[name].from].to = nil
game.friend_requests[name].from = nil
game.update_inventories()
else
minetest.chat_send_player(name, "You have no friend requests right now :(")
end
end
})
minetest.register_chatcommand("decline", {
description = "Decline friend request",
func = function(name)
if game.friend_requests[name].from ~= nil then
minetest.chat_send_player(game.friend_requests[name].from, name.." declined your friend request")
minetest.chat_send_player(name, "Declined friend request from "..game.friend_requests[name].from)
game.friend_requests[game.friend_requests[name].from].to = nil
game.friend_requests[name].from = nil
game.update_inventories()
else
minetest.chat_send_player(name, "You have no friend requests right now :(")
end
end
})