2019-04-07 21:32:54 +02:00
|
|
|
--[[
|
|
|
|
|
|
|
|
MIT License
|
|
|
|
|
|
|
|
Copyright (c) 2019 stujones11, Stuart Jones
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
|
|
copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
SOFTWARE.
|
|
|
|
|
|
|
|
]]--
|
|
|
|
|
2016-11-26 20:50:11 +01:00
|
|
|
wield3d = {}
|
2014-05-15 22:14:00 +02:00
|
|
|
|
2016-11-26 20:50:11 +01:00
|
|
|
dofile(minetest.get_modpath(minetest.get_current_modname()).."/location.lua")
|
2013-11-06 21:33:52 +01:00
|
|
|
|
2019-04-07 21:44:32 +02:00
|
|
|
local player_wielding = {}
|
2016-11-26 20:50:11 +01:00
|
|
|
local has_wieldview = minetest.get_modpath("wieldview")
|
2019-04-07 21:32:54 +02:00
|
|
|
local update_time = minetest.settings:get("wield3d_update_time")
|
|
|
|
local verify_time = minetest.settings:get("wield3d_verify_time")
|
2019-04-07 21:44:32 +02:00
|
|
|
local wield_scale = minetest.settings:get("wield3d_scale")
|
|
|
|
|
2019-04-07 21:32:54 +02:00
|
|
|
update_time = update_time and tonumber(update_time) or 1
|
|
|
|
verify_time = verify_time and tonumber(verify_time) or 10
|
2019-04-07 23:09:11 +02:00
|
|
|
wield_scale = wield_scale and tonumber(wield_scale) or 0.25 -- default scale
|
2019-04-07 21:44:32 +02:00
|
|
|
|
2013-11-06 21:33:52 +01:00
|
|
|
local location = {
|
2016-11-26 20:50:11 +01:00
|
|
|
"Arm_Right", -- default bone
|
|
|
|
{x=0, y=5.5, z=3}, -- default position
|
|
|
|
{x=-90, y=225, z=90}, -- default rotation
|
2019-04-07 21:44:32 +02:00
|
|
|
{x=wield_scale, y=wield_scale},
|
2013-11-06 21:33:52 +01:00
|
|
|
}
|
2013-06-30 22:17:16 +02:00
|
|
|
|
2013-11-06 21:33:52 +01:00
|
|
|
local function add_wield_entity(player)
|
2019-04-07 21:32:54 +02:00
|
|
|
if not player or not player:is_player() then
|
|
|
|
return
|
|
|
|
end
|
2014-05-13 21:54:53 +02:00
|
|
|
local name = player:get_player_name()
|
2018-10-21 02:41:07 +02:00
|
|
|
local pos = player:get_pos()
|
2019-04-07 21:32:54 +02:00
|
|
|
if name and pos and not player_wielding[name] then
|
2016-11-26 20:50:11 +01:00
|
|
|
pos.y = pos.y + 0.5
|
2019-04-07 21:32:54 +02:00
|
|
|
local object = minetest.add_entity(pos, "wield3d:wield_entity", name)
|
2013-11-06 21:33:52 +01:00
|
|
|
if object then
|
|
|
|
object:set_attach(player, location[1], location[2], location[3])
|
2016-11-27 19:13:35 +01:00
|
|
|
object:set_properties({
|
|
|
|
textures = {"wield3d:hand"},
|
|
|
|
visual_size = location[4],
|
|
|
|
})
|
2019-04-08 20:25:48 +02:00
|
|
|
player_wielding[name] = {item="", location=location}
|
2013-11-06 21:33:52 +01:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|
2013-06-30 22:17:16 +02:00
|
|
|
|
2019-04-07 21:32:54 +02:00
|
|
|
local function sq_dist(a, b)
|
|
|
|
local x = a.x - b.x
|
|
|
|
local y = a.y - b.y
|
|
|
|
local z = a.z - b.z
|
|
|
|
return x * x + y * y + z * z
|
|
|
|
end
|
2013-06-30 22:17:16 +02:00
|
|
|
|
2019-04-07 21:32:54 +02:00
|
|
|
local wield_entity = {
|
2013-11-06 21:33:52 +01:00
|
|
|
physical = false,
|
2014-05-15 22:14:00 +02:00
|
|
|
collisionbox = {-0.125,-0.125,-0.125, 0.125,0.125,0.125},
|
2013-11-06 21:33:52 +01:00
|
|
|
visual = "wielditem",
|
2019-04-07 21:32:54 +02:00
|
|
|
textures = {"wield3d:hand"},
|
|
|
|
wielder = nil,
|
|
|
|
timer = 0,
|
2019-04-09 21:20:08 +02:00
|
|
|
static_save = false,
|
2019-04-07 21:32:54 +02:00
|
|
|
}
|
2013-06-30 22:17:16 +02:00
|
|
|
|
2019-04-07 21:32:54 +02:00
|
|
|
function wield_entity:on_activate(staticdata)
|
2019-04-09 21:20:08 +02:00
|
|
|
if staticdata and staticdata ~= "" then
|
2019-04-07 21:32:54 +02:00
|
|
|
self.wielder = staticdata
|
2016-11-26 20:50:11 +01:00
|
|
|
return
|
|
|
|
end
|
2019-04-07 21:32:54 +02:00
|
|
|
self.object:remove()
|
|
|
|
end
|
|
|
|
|
|
|
|
function wield_entity:on_step(dtime)
|
|
|
|
if self.wielder == nil then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
self.timer = self.timer + dtime
|
|
|
|
if self.timer < update_time then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
local player = minetest.get_player_by_name(self.wielder)
|
2019-04-08 19:20:34 +02:00
|
|
|
if player == nil or not player:is_player() or
|
2019-04-07 21:32:54 +02:00
|
|
|
sq_dist(player:get_pos(), self.object:get_pos()) > 3 then
|
|
|
|
self.object:remove()
|
|
|
|
return
|
|
|
|
end
|
|
|
|
local wield = player_wielding[self.wielder]
|
|
|
|
local stack = player:get_wielded_item()
|
|
|
|
local item = stack:get_name() or ""
|
|
|
|
if wield and item ~= wield.item then
|
|
|
|
if has_wieldview then
|
|
|
|
local def = minetest.registered_items[item] or {}
|
|
|
|
if def.inventory_image ~= "" then
|
|
|
|
item = ""
|
2013-10-02 23:37:49 +02:00
|
|
|
end
|
2013-06-30 22:17:16 +02:00
|
|
|
end
|
2019-04-07 21:32:54 +02:00
|
|
|
wield.item = item
|
|
|
|
if item == "" then
|
|
|
|
item = "wield3d:hand"
|
|
|
|
end
|
|
|
|
local loc = wield3d.location[item] or location
|
|
|
|
if loc[1] ~= wield.location[1] or
|
|
|
|
not vector.equals(loc[2], wield.location[2]) or
|
|
|
|
not vector.equals(loc[3], wield.location[3]) then
|
|
|
|
self.object:set_attach(player, loc[1], loc[2], loc[3])
|
|
|
|
wield.location = {loc[1], loc[2], loc[3]}
|
|
|
|
end
|
|
|
|
self.object:set_properties({
|
|
|
|
textures = {item},
|
|
|
|
visual_size = loc[4],
|
|
|
|
})
|
|
|
|
end
|
|
|
|
self.timer = 0
|
|
|
|
end
|
|
|
|
|
|
|
|
local function table_iter(t)
|
|
|
|
local i = 0
|
|
|
|
local n = table.getn(t)
|
|
|
|
return function ()
|
|
|
|
i = i + 1
|
|
|
|
if i <= n then
|
|
|
|
return t[i]
|
|
|
|
end
|
2013-11-06 21:33:52 +01:00
|
|
|
end
|
2019-04-07 21:32:54 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
local player_iter = nil
|
|
|
|
|
|
|
|
local function verify_wielditems()
|
2019-04-08 19:20:34 +02:00
|
|
|
if player_iter == nil then
|
|
|
|
local names = {}
|
|
|
|
local tmp = {}
|
|
|
|
for player in table_iter(minetest.get_connected_players()) do
|
|
|
|
local name = player:get_player_name()
|
|
|
|
if name then
|
|
|
|
tmp[name] = true;
|
|
|
|
table.insert(names, name)
|
|
|
|
end
|
|
|
|
end
|
2019-04-08 20:25:48 +02:00
|
|
|
player_iter = table_iter(names)
|
2019-04-08 19:20:34 +02:00
|
|
|
-- clean-up player_wielding table
|
2019-04-08 20:25:48 +02:00
|
|
|
for name, wield in pairs(player_wielding) do
|
|
|
|
player_wielding[name] = tmp[name] and wield
|
2019-04-08 19:20:34 +02:00
|
|
|
end
|
|
|
|
end
|
2019-04-07 21:32:54 +02:00
|
|
|
-- only deal with one player per server step
|
2019-04-08 19:20:34 +02:00
|
|
|
local name = player_iter()
|
|
|
|
if name then
|
|
|
|
local player = minetest.get_player_by_name(name)
|
|
|
|
if player and player:is_player() then
|
|
|
|
local pos = player:get_pos()
|
2019-04-07 21:32:54 +02:00
|
|
|
pos.y = pos.y + 0.5
|
|
|
|
local wielding = false
|
2019-04-08 19:20:34 +02:00
|
|
|
local objects = minetest.get_objects_inside_radius(pos, 1)
|
2019-04-07 21:32:54 +02:00
|
|
|
for _, object in pairs(objects) do
|
|
|
|
local entity = object:get_luaentity()
|
|
|
|
if entity and entity.wielder == name then
|
2019-04-08 20:25:48 +02:00
|
|
|
if wielding then
|
|
|
|
-- remove duplicates
|
|
|
|
object:remove()
|
|
|
|
end
|
2019-04-07 21:32:54 +02:00
|
|
|
wielding = true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
if not wielding then
|
2019-04-08 19:20:34 +02:00
|
|
|
player_wielding[name] = nil
|
2019-04-07 21:32:54 +02:00
|
|
|
add_wield_entity(player)
|
2016-11-26 20:50:11 +01:00
|
|
|
end
|
|
|
|
end
|
2019-04-07 21:32:54 +02:00
|
|
|
return minetest.after(0, verify_wielditems)
|
2016-11-26 20:50:11 +01:00
|
|
|
end
|
2019-04-07 21:32:54 +02:00
|
|
|
player_iter = nil
|
|
|
|
minetest.after(verify_time, verify_wielditems)
|
|
|
|
end
|
|
|
|
|
|
|
|
minetest.after(verify_time, verify_wielditems)
|
|
|
|
|
|
|
|
minetest.register_entity("wield3d:wield_entity", wield_entity)
|
|
|
|
|
|
|
|
minetest.register_item("wield3d:hand", {
|
|
|
|
type = "none",
|
|
|
|
wield_image = "blank.png",
|
|
|
|
})
|
|
|
|
|
|
|
|
minetest.register_on_joinplayer(function(player)
|
|
|
|
minetest.after(2, add_wield_entity, player)
|
2013-11-06 21:33:52 +01:00
|
|
|
end)
|