Merge pull request 'Update from master' (#1) from MineClone2/MineClone2:master into master

Reviewed-on: FaceDeer/MineClone2#1
This commit is contained in:
FaceDeer 2022-08-29 07:16:32 +00:00
commit be36022249
40 changed files with 657 additions and 215 deletions

View File

@ -161,9 +161,9 @@ minetest.register_on_dieplayer(function(player, mt_reason)
if mt_reason.approved then if mt_reason.approved then
mcl_damage.run_death_callbacks(player, mcl_damage.from_mt(mt_reason)) mcl_damage.run_death_callbacks(player, mcl_damage.from_mt(mt_reason))
end end
minetest.log("action","Player "..player:get_player_name().." died at "..minetest.pos_to_string(vector.round(player:get_pos())))
end) end)
minetest.register_on_mods_loaded(function() minetest.register_on_mods_loaded(function()
table.sort(mcl_damage.modifiers, function(a, b) return a.priority < b.priority end) table.sort(mcl_damage.modifiers, function(a, b) return a.priority < b.priority end)
end) end)

View File

@ -847,15 +847,16 @@ minetest.register_entity(":__builtin:item", {
elseif self._flowing == true and not is_in_water and not is_floating then elseif self._flowing == true and not is_in_water and not is_floating then
-- Disable flowing physics if not on/in flowing liquid -- Disable flowing physics if not on/in flowing liquid
self._flowing = false self._flowing = false
disable_physics(self.object, self, true) enable_physics(self.object, self, true)
return return
end end
-- If node is not registered or node is walkably solid and resting on nodebox -- If node is not registered or node is walkably solid and resting on nodebox
local nn = minetest.get_node({x=p.x, y=p.y-0.5, z=p.z}).name local nn = minetest.get_node({x=p.x, y=p.y-0.5, z=p.z}).name
local def = minetest.registered_nodes[nn]
local v = self.object:get_velocity() local v = self.object:get_velocity()
local is_on_floor = (minetest.registered_nodes[nn].walkable local is_on_floor = def and (def.walkable
and not minetest.registered_nodes[nn].groups.slippery and v.y == 0) and not def.groups.slippery and v.y == 0)
if not minetest.registered_nodes[nn] if not minetest.registered_nodes[nn]
or is_floating or is_on_floor then or is_floating or is_on_floor then

View File

@ -213,11 +213,11 @@ end
local collision = function(self) local collision = function(self)
local pos = self.object:get_pos() local pos = self.object:get_pos()
if not pos then return {0,0} end
local vel = self.object:get_velocity() local vel = self.object:get_velocity()
local x = 0 local x = 0
local z = 0 local z = 0
local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5 local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5
for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do
local ent = object:get_luaentity() local ent = object:get_luaentity()
@ -254,12 +254,14 @@ local set_velocity = function(self, v)
end end
local yaw = (self.object:get_yaw() or 0) + self.rotate local yaw = (self.object:get_yaw() or 0) + self.rotate
local vv = self.object:get_velocity()
if vv then
self.object:set_velocity({ self.object:set_velocity({
x = (sin(yaw) * -v) + c_x, x = (sin(yaw) * -v) + c_x,
y = self.object:get_velocity().y, y = vv.y,
z = (cos(yaw) * v) + c_y, z = (cos(yaw) * v) + c_y,
}) })
end
end end
@ -407,15 +409,15 @@ local set_animation = function(self, anim, fixed_frame)
if flight_check(self) and self.fly and anim == "walk" then anim = "fly" end if flight_check(self) and self.fly and anim == "walk" then anim = "fly" end
self.animation.current = self.animation.current or "" self._current_animation = self._current_animation or ""
if (anim == self.animation.current if (anim == self._current_animation
or not self.animation[anim .. "_start"] or not self.animation[anim .. "_start"]
or not self.animation[anim .. "_end"]) and self.state ~= "die" then or not self.animation[anim .. "_end"]) and self.state ~= "die" then
return return
end end
self.animation.current = anim self._current_animation = anim
local a_start = self.animation[anim .. "_start"] local a_start = self.animation[anim .. "_start"]
local a_end local a_end
@ -3002,6 +3004,7 @@ end
local function check_entity_cramming(self) local function check_entity_cramming(self)
local p = self.object:get_pos() local p = self.object:get_pos()
if not p then return end
local oo = minetest.get_objects_inside_radius(p,1) local oo = minetest.get_objects_inside_radius(p,1)
local mobs = {} local mobs = {}
for _,o in pairs(oo) do for _,o in pairs(oo) do
@ -3467,7 +3470,10 @@ local mob_activate = function(self, staticdata, def, dtime)
def.textures = {def.textures} def.textures = {def.textures}
end end
self.base_texture = def.textures[random(1, #def.textures)] local c = 1
if #def.textures > c then c = #def.textures end
self.base_texture = def.textures[math.random(c)]
self.base_mesh = def.mesh self.base_mesh = def.mesh
self.base_size = self.visual_size self.base_size = self.visual_size
self.base_colbox = self.collisionbox self.base_colbox = self.collisionbox

View File

@ -513,6 +513,7 @@ if mobs_spawn then
local mob_def = mob_library_worker_table[mob_index] local mob_def = mob_library_worker_table[mob_index]
local mob_type = minetest.registered_entities[mob_def.name].type local mob_type = minetest.registered_entities[mob_def.name].type
local spawn_in_group = minetest.registered_entities[mob_def.name].spawn_in_group or 4 local spawn_in_group = minetest.registered_entities[mob_def.name].spawn_in_group or 4
local spawn_in_group_min = minetest.registered_entities[mob_def.name].spawn_in_group_min or 1
local mob_count_wide = count_mobs(pos,aoc_range,mob_type) local mob_count_wide = count_mobs(pos,aoc_range,mob_type)
local mob_count = count_mobs(spawning_position,32,mob_type) local mob_count = count_mobs(spawning_position,32,mob_type)
if mob_def if mob_def

View File

@ -219,6 +219,7 @@ local select_enderman_animation = function(animation_type)
end end
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
local spawners = {}
mcl_mobs:register_mob("mobs_mc:enderman", { mcl_mobs:register_mob("mobs_mc:enderman", {
description = S("Enderman"), description = S("Enderman"),
@ -263,20 +264,42 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
do_custom = function(self, dtime) do_custom = function(self, dtime)
-- PARTICLE BEHAVIOUR HERE. -- PARTICLE BEHAVIOUR HERE.
local enderpos = self.object:get_pos() local enderpos = self.object:get_pos()
local chanceOfParticle = math.random(0, 1) if self._particle_timer and self._particle_timer >= 1 then
if chanceOfParticle == 1 then for _,player in pairs(minetest.get_connected_players()) do
minetest.add_particle({ if not spawners[player] then spawners[player] = {} end
pos = {x=enderpos.x+math.random(-1,1)*math.random()/2,y=enderpos.y+math.random(0,3),z=enderpos.z+math.random(-1,1)*math.random()/2}, local dst = vector.distance(player:get_pos(),enderpos)
velocity = {x=math.random(-.25,.25), y=math.random(-.25,.25), z=math.random(-.25,.25)}, if dst < 128 and not spawners[player][self.object] then
acceleration = {x=math.random(-.5,.5), y=math.random(-.5,.5), z=math.random(-.5,.5)}, self._particle_timer = 0
expirationtime = math.random(), spawners[player][self.object] = minetest.add_particlespawner({
size = math.random(), amount = 5,
minpos = vector.new(-0.6,0,-0.6),
maxpos = vector.new(0.6,3,0.6),
minvel = vector.new(-0.25,-0.25,-0.25),
maxvel = vector.new(0.25,0.25,0.25),
minacc = vector.new(-0.5,-0.5,-0.5),
maxacc = vector.new(0.5,0.5,0.5),
minexptime = 0.2,
maxexptime = 3,
minsize = 0.2,
maxsize = 1.2,
collisiondetection = true, collisiondetection = true,
vertical = false, vertical = false,
time = 0,
texture = "mcl_portals_particle"..math.random(1, 5)..".png", texture = "mcl_portals_particle"..math.random(1, 5)..".png",
attached = self.object,
playername = player:get_player_name(),
}) })
elseif dst > 128 and spawners[player][self.object] then
minetest.delete_particlespawner(spawners[player][self.object])
spawners[player][self.object] = nil
end end
end
elseif not self._particle_timer then
self._particle_timer = 0
end
self._particle_timer = self._particle_timer + dtime
-- RAIN DAMAGE / EVASIVE WARP BEHAVIOUR HERE. -- RAIN DAMAGE / EVASIVE WARP BEHAVIOUR HERE.
enderpos = self.object:get_pos()
local dim = mcl_worlds.pos_to_dimension(enderpos) local dim = mcl_worlds.pos_to_dimension(enderpos)
if dim == "overworld" then if dim == "overworld" then
if mcl_weather.state == "rain" or mcl_weather.state == "lightning" then if mcl_weather.state == "rain" or mcl_weather.state == "lightning" then
@ -312,10 +335,6 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
else return end else return end
-- AGRESSIVELY WARP/CHASE PLAYER BEHAVIOUR HERE. -- AGRESSIVELY WARP/CHASE PLAYER BEHAVIOUR HERE.
if self.state == "attack" then if self.state == "attack" then
--if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then
--self:teleport(nil)
--self.state = ""
--else
if self.attack then if self.attack then
local target = self.attack local target = self.attack
local pos = target:get_pos() local pos = target:get_pos()
@ -325,11 +344,15 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
end end
end end
end end
--end else --if not attacking try to tp to the dark
if minetest.get_node_light(enderpos) > minetest.LIGHT_MAX then
self:teleport(nil)
end
end end
-- ARROW / DAYTIME PEOPLE AVOIDANCE BEHAVIOUR HERE. -- ARROW / DAYTIME PEOPLE AVOIDANCE BEHAVIOUR HERE.
-- Check for arrows and people nearby. -- Check for arrows and people nearby.
local enderpos = self.object:get_pos()
enderpos = self.object:get_pos()
enderpos.y = enderpos.y + 1.5 enderpos.y = enderpos.y + 1.5
local objs = minetest.get_objects_inside_radius(enderpos, 2) local objs = minetest.get_objects_inside_radius(enderpos, 2)
for n = 1, #objs do for n = 1, #objs do
@ -593,6 +616,13 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
attack_type = "dogfight", attack_type = "dogfight",
}) })
minetest.register_on_leaveplayer(function(player)
for _,s in pairs(spawners[player]) do
minetest.delete_particlespawner(s)
end
spawners[player] = nil
end)
-- End spawn -- End spawn
mcl_mobs:spawn_specific( mcl_mobs:spawn_specific(

View File

@ -114,6 +114,7 @@ dofile(path .. "/squid.lua") -- Animation, sound and egg texture by daufinsyd
dofile(path .. "/villager.lua") -- KrupnoPavel Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/villager.lua") -- KrupnoPavel Mesh and animation by toby109tt / https://github.com/22i
-- Illagers and witch -- Illagers and witch
dofile(path .. "/pillager.lua") -- Mesh by KrupnoPavel and MrRar, animation by MrRar
dofile(path .. "/villager_evoker.lua") -- Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/villager_evoker.lua") -- Mesh and animation by toby109tt / https://github.com/22i
dofile(path .. "/villager_vindicator.lua") -- Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/villager_vindicator.lua") -- Mesh and animation by toby109tt / https://github.com/22i
dofile(path .. "/villager_zombie.lua") -- Mesh and animation by toby109tt / https://github.com/22i dofile(path .. "/villager_zombie.lua") -- Mesh and animation by toby109tt / https://github.com/22i

View File

@ -65,3 +65,4 @@ Nitwit=
Cod= Cod=
Salmon= Salmon=
Dolphin= Dolphin=
Pillager=

Binary file not shown.

Binary file not shown.

View File

@ -13,12 +13,20 @@ local shoulders = {
right = vector.new(3.75,10.5,0) right = vector.new(3.75,10.5,0)
} }
local function table_get_rand(tbl)
local keys = {}
for k in pairs(tbl) do
table.insert(keys, k)
end
return tbl[keys[math.random(#keys)]]
end
local function get_random_mob_sound() local function get_random_mob_sound()
local t = table.copy(minetest.registered_entities) local t = table.copy(minetest.registered_entities)
table.shuffle(t) table.shuffle(t)
for _,e in pairs(t) do for _,e in pairs(t) do
if e.is_mob and e.sounds then if e.is_mob and e.sounds and #e.sounds > 0 then
return e.sounds[math.random(#e.sounds)] return table_get_rand(e.sounds)
end end
end end
return minetest.registered_entities["mobs_mc:parrot"].sounds.random return minetest.registered_entities["mobs_mc:parrot"].sounds.random

View File

@ -0,0 +1,122 @@
local S = minetest.get_translator("mobs_mc")
local function reload(self)
if not self.object:get_pos() then return end
minetest.sound_play("mcl_bows_crossbow_drawback_1", {object = self.object, max_hear_distance=16}, true)
local props = self.object:get_properties()
if not props then return end
props.textures[2] = "mcl_bows_crossbow_3.png^[resize:16x16"
self.object:set_properties(props)
end
local function reset_animation(self, animation)
if not self.object:get_pos() or self._current_animation ~= animation then return end
self._current_animation = "stand_reload" -- Mobs Redo won't set the animation unless we do this
mcl_mobs:set_animation(self, animation)
end
pillager = {
description = S("Pillager"),
type = "monster",
spawn_class = "hostile",
hp_min = 24,
hp_max = 24,
xp_min = 6,
xp_max = 6,
breath_max = -1,
eye_height = 1.5,
shoot_interval = 3,
shoot_offset = 1.5,
armor = {fleshy = 100},
collisionbox = {-0.3, -0.01, -0.3, 0.3, 1.98, 0.3},
pathfinding = 1,
group_attack = true,
visual = "mesh",
mesh = "mobs_mc_pillager.b3d",
visual_size = {x=2.75, y=2.75},
makes_footstep_sound = true,
walk_velocity = 1.2,
run_velocity = 4,
view_range = 16,
fear_height = 4,
arrow = "mcl_bows:arrow_entity",
attack_type = "dogshoot", -- Alternate punching/shooting
reach = 0, -- Punching max distance
damage = 0, -- Punching damage
dogshoot_switch = 1, -- Start of shooting
dogshoot_count_max = 5, -- Max time spent shooting (standing)
dogshoot_count2_max = 1, -- Max time spent punching (running)
sounds = {
random = "mobs_mc_pillager_grunt2",
war_cry = "mobs_mc_pillager_grunt1",
death = "mobs_mc_pillager_ow2",
damage = "mobs_mc_pillager_ow1",
distance = 16,
},
textures = {
{
"mobs_mc_pillager.png", -- Skin
"mcl_bows_crossbow_3.png^[resize:16x16", -- Wielded item
}
},
drops = {
{
name = "mcl_bows:arrow",
chance = 1,
min = 0,
max = 2,
looting = "common",
},
{
name = "mcl_bows:crossbow",
chance = 100 / 8.5,
min = 1,
max = 1,
looting = "rare",
},
},
animation = {
unloaded_walk_start = 1, unloaded_walk_end = 40,
unloaded_stand_start = 41, unloaded_stand_end = 60,
reload_stand_start = 61, reload_stand_end = 100, reload_stand_speed = 20,
stand_start = 101, stand_end = 109, stand_speed = 6,
walk_start = 111, walk_end = 150, walk_speed = 30,
run_start = 111, run_end = 150, run_speed = 50,
reload_run_start = 151, reload_run_end = 190, reload_run_speed = 20,
die_start = 191, die_end = 192, die_speed = 15,
stand_unloaded_start = 40, stand_unloaded_end = 59,
die_loop = false,
},
shoot_arrow = function(self, pos, dir)
minetest.sound_play("mcl_bows_crossbow_shoot", {object = self.object, max_hear_distance=16}, true)
local props = self.object:get_properties()
props.textures[2] = "mcl_bows_crossbow_0.png^[resize:16x16"
self.object:set_properties(props)
local old_anim = self._current_animation
if old_anim == "run" or old_anim == "walk" then
mcl_mobs:set_animation(self, "reload_run")
end
if old_anim == "stand" then
mcl_mobs:set_animation(self, "reload_stand")
end
self._current_animation = old_anim -- Mobs Redo will imediately reset the animation otherwise
minetest.after(1, reload, self)
minetest.after(2, reset_animation, self, old_anim)
-- 2-4 damage per arrow
local dmg = math.max(4, math.random(2, 8))
mcl_bows_s.shoot_arrow_crossbow("mcl_bows:arrow", pos, dir, self.object:get_yaw(), self.object, nil, dmg)
-- While we are at it, change the sounds since there is no way to do this in Mobs Redo
if self.sounds and self.sounds.random then
self.sounds = table.copy(self.sounds)
self.sounds.random = "mobs_mc_pillager_grunt" .. math.random(2)
end
-- Randomize reload time
self.shoot_interval = math.random(3, 4)
end,
}
mcl_mobs:register_mob("mobs_mc:pillager", pillager)
mcl_mobs:register_egg("mobs_mc:pillager", S("Pillager"), "mobs_mc_spawn_icon_pillager.png", 0)

Binary file not shown.

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

View File

@ -72,7 +72,7 @@ local tropical_fish = {
collisionbox = {-0.2, 0.0, -0.2, 0.2, 0.1, 0.2}, collisionbox = {-0.2, 0.0, -0.2, 0.2, 0.1, 0.2},
visual = "mesh", visual = "mesh",
mesh = "extra_mobs_tropical_fish_a.b3d", mesh = "extra_mobs_tropical_fish_a.b3d",
textures = {}, -- to be populated on_spawn textures = { "extra_mobs_tropical_fish_a.png" }, -- to be populated on_spawn
sounds = {}, sounds = {},
animation = { animation = {
stand_start = 0, stand_start = 0,

View File

@ -28,6 +28,11 @@ return {
"Code-Sploit", "Code-Sploit",
"NO11", "NO11",
"kabou", "kabou",
"rudzik8",
"chmodsayshello",
"PrarieWind",
"RandomLegoBrick",
"SumianVoice",
}}, }},
{S("Contributors"), 0x52FF00, { {S("Contributors"), 0x52FF00, {
"Laurent Rocher", "Laurent Rocher",
@ -72,6 +77,12 @@ return {
"Sven792", "Sven792",
"aldum", "aldum",
"Dieter44", "Dieter44",
"Pepebotella",
"MrRar",
"Lazerbeak12345",
"mrminer",
"Thunder1035",
"opfromthestart",
}}, }},
{S("MineClone5"), 0xA60014, { {S("MineClone5"), 0xA60014, {
"kay27", "kay27",
@ -79,10 +90,12 @@ return {
"epCode", "epCode",
"NO11", "NO11",
"j45", "j45",
"chmodsayshello",
"3raven", "3raven",
"PrarieWind", "PrarieWind",
"Gustavo1", "Gustavo1",
"CableGuy67", "CableGuy67",
"MrRar",
}}, }},
{S("Mineclonia"), 0xFFFFFF, { {S("Mineclonia"), 0xFFFFFF, {
"erlehmann", "erlehmann",
@ -135,6 +148,9 @@ return {
"yutyo", "yutyo",
"NO11", "NO11",
"kay27", "kay27",
"MysticTempest",
"RandomLegoBrick",
"cora",
}}, }},
{S("Translations"), 0x00FF60, { {S("Translations"), 0x00FF60, {
"Wuzzy", "Wuzzy",
@ -144,6 +160,8 @@ return {
"pitchum", "pitchum",
"todoporlalibertad", "todoporlalibertad",
"Marcin Serwin", "Marcin Serwin",
"Pepebotella",
"Emojigit",
}}, }},
{S("Funders"), 0xF7FF00, { {S("Funders"), 0xF7FF00, {
"40W", "40W",
@ -151,6 +169,7 @@ return {
{S("Special thanks"), 0x00E9FF, { {S("Special thanks"), 0x00E9FF, {
"celeron55 for creating Minetest", "celeron55 for creating Minetest",
"Jordach for the jukebox music compilation from Big Freaking Dig", "Jordach for the jukebox music compilation from Big Freaking Dig",
"wsor for working tirelessly in the shadows for the good of all of us, particularly helping with solving contentDB and copyright issues.",
"The workaholics who spent way too much time writing for the Minecraft Wiki. It's an invaluable resource for creating this game", "The workaholics who spent way too much time writing for the Minecraft Wiki. It's an invaluable resource for creating this game",
"Notch and Jeb for being the major forces behind Minecraft", "Notch and Jeb for being the major forces behind Minecraft",
}}, }},

View File

@ -390,7 +390,7 @@ minetest.register_tool("mcl_fishing:fishing_rod", {
_doc_items_usagehelp = S("Rightclick to launch the bobber. When it sinks right-click again to reel in an item. Who knows what you're going to catch?"), _doc_items_usagehelp = S("Rightclick to launch the bobber. When it sinks right-click again to reel in an item. Who knows what you're going to catch?"),
groups = { tool=1, fishing_rod=1, enchantability=1 }, groups = { tool=1, fishing_rod=1, enchantability=1 },
inventory_image = "mcl_fishing_fishing_rod.png", inventory_image = "mcl_fishing_fishing_rod.png",
wield_image = "mcl_fishing_fishing_rod.png^[transformR270", wield_image = "mcl_fishing_fishing_rod.png^[transformFY^[transformR90",
wield_scale = { x = 1.5, y = 1.5, z = 1 }, wield_scale = { x = 1.5, y = 1.5, z = 1 },
stack_max = 1, stack_max = 1,
on_place = fish, on_place = fish,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 359 B

View File

@ -1,9 +1,203 @@
-- Code based from mcl_anvils
local S = minetest.get_translator(minetest.get_current_modname()) local S = minetest.get_translator(minetest.get_current_modname())
local MAX_WEAR = 65535
-- formspecs
local function get_grindstone_formspec()
return "size[9,8.75]"..
"image[3,1.5;1.5,1;gui_crafting_arrow.png]"..
"label[0,4.0;"..minetest.formspec_escape(minetest.colorize("#313131", S("Inventory"))).."]"..
"label[1,0.1;"..minetest.formspec_escape(minetest.colorize("#313131", S("Repair & Disenchant"))).."]"..
"list[context;main;0,0;8,4;]"..
"list[current_player;main;0,4.5;9,3;9]"..
mcl_formspec.get_itemslot_bg(0,4.5,9,3)..
"list[current_player;main;0,7.74;9,1;]"..
mcl_formspec.get_itemslot_bg(0,7.74,9,1)..
"list[context;input;1,1;1,1;]"..
mcl_formspec.get_itemslot_bg(1,1,1,1)..
"list[context;input;1,2;1,1;1]"..
mcl_formspec.get_itemslot_bg(1,2,1,1)..
"list[context;output;6,1.5;1,1;]"..
mcl_formspec.get_itemslot_bg(6,1.5,1,1)..
"listring[context;output]"..
"listring[current_player;main]"..
"listring[context;input]"..
"listring[current_player;main]"
end
-- Creates a new item with the wear of the items and custom name
local function create_new_item(name_item, meta, wear)
local new_item = ItemStack(name_item)
if wear ~= nil then
new_item:set_wear(wear)
end
local new_meta = new_item:get_meta()
new_meta:set_string("name", meta:get_string("name"))
tt.reload_itemstack_description(new_item)
return new_item
end
-- If an item has an enchanment then remove "_enchanted" from the name
local function remove_enchant_name(stack)
if mcl_enchanting.is_enchanted(stack:get_name()) then
local name = stack:get_name()
return name.sub(name, 1, -11)
else
return stack:get_name()
end
end
-- If an input has a curse transfer it to the new item
local function transfer_curse(old_itemstack, new_itemstack)
local enchants = mcl_enchanting.get_enchantments(old_itemstack)
for enchant, level in pairs(enchants) do
if mcl_enchanting.enchantments[enchant].curse == true then
new_itemstack = mcl_enchanting.enchant(new_itemstack, enchant, level)
end
end
return new_itemstack
end
-- Depending on an enchantment level and isn't a curse multiply xp given
local function calculate_xp(stack)
local xp = 0
local enchants = mcl_enchanting.get_enchantments(stack)
for enchant, level in pairs(enchants) do
if level > 0 and mcl_enchanting.enchantments[enchant].curse == false then
-- Add a bit of uniform randomisation
xp = xp + math.random(7, 13) * level
end
end
return xp
end
-- Helper function to make sure update_grindstone_slots NEVER overstacks the output slot
local function fix_stack_size(stack)
if not stack or stack == "" then return "" end
local count = stack:get_count()
local max_count = stack:get_stack_max()
if count > max_count then
stack:set_count(max_count)
count = max_count
end
return count
end
-- Update the inventory slots of an grindstone node.
-- meta: Metadata of grindstone node
local function update_grindstone_slots(meta)
local inv = meta:get_inventory()
local input1 = inv:get_stack("input", 1)
local input2 = inv:get_stack("input", 2)
local meta = input1:get_meta()
local new_output
-- Both input slots are occupied
if (not input1:is_empty() and not input2:is_empty()) then
local def1 = input1:get_definition()
local def2 = input2:get_definition()
-- Remove enchant name if they have one
local name1 = remove_enchant_name(input1)
local name2 = remove_enchant_name(input2)
-- Calculate repair
local function calculate_repair(dur1, dur2)
-- Grindstone gives a 5% bonus to durability
local new_durability = (MAX_WEAR - dur1) + (MAX_WEAR - dur2) * 1.05
return math.max(0, math.min(MAX_WEAR, MAX_WEAR - new_durability))
end
-- Check if both are tools and have the same tool type
if def1.type == "tool" and def2.type == "tool" and name1 == name2 then
local new_wear = calculate_repair(input1:get_wear(), input2:get_wear())
local new_item = create_new_item(name1, meta, new_wear)
-- Transfer curses if both items have any
new_output = transfer_curse(input1, new_item)
new_output = transfer_curse(input2, new_output)
else
new_output = ""
end
-- Check if at least one input has an item
-- Check if the item is's an enchanted book or tool
elseif (not input1:is_empty() and input2:is_empty()) or (input1:is_empty() and not input2:is_empty()) then
if input2:is_empty() then
local def1 = input1:get_definition()
local meta = input1:get_meta()
if def1.type == "tool" and mcl_enchanting.is_enchanted(input1:get_name()) then
local name = remove_enchant_name(input1)
local wear = input1:get_wear()
local new_item = create_new_item(name, meta, wear)
new_output = transfer_curse(input1, new_item)
elseif input1:get_name() == "mcl_enchanting:book_enchanted" then
new_item = create_new_item("mcl_books:book", meta, nil)
new_output = transfer_curse(input1, new_item)
else
new_output = ""
end
else
local def2 = input2:get_definition()
local meta = input2:get_meta()
if def2.type == "tool" and mcl_enchanting.is_enchanted(input2:get_name()) then
local name = remove_enchant_name(input2)
local wear = input2:get_wear()
local new_item = create_new_item(name, meta, wear)
new_output = transfer_curse(input2, new_item)
elseif input2:get_name() == "mcl_enchanting:book_enchanted" then
new_item = create_new_item("mcl_books:book", meta, nil)
new_output = transfer_curse(input2, new_item)
else
new_output = ""
end
end
else
new_output = ""
end
-- Set the new output slot
if new_output then
fix_stack_size(new_output)
inv:set_stack("output", 1, new_output)
end
end
-- Drop any items inside the grindstone if destroyed
local function drop_grindstone_items(pos, meta)
local inv = meta:get_inventory()
for i=1, inv:get_size("input") do
local stack = inv:get_stack("input", i)
if not stack:is_empty() then
local p = {x=pos.x+math.random(0, 10)/10-0.5, y=pos.y, z=pos.z+math.random(0, 10)/10-0.5}
minetest.add_item(p, stack)
end
end
end
local node_box = {
type = "fixed",
-- created with nodebox editor
fixed = {
{-0.25, -0.25, -0.375, 0.25, 0.5, 0.375},
{-0.375, -0.0625, -0.1875, -0.25, 0.3125, 0.1875},
{0.25, -0.0625, -0.1875, 0.375, 0.3125, 0.1875},
{0.25, -0.5, -0.125, 0.375, -0.0625, 0.125},
{-0.375, -0.5, -0.125, -0.25, -0.0625, 0.125},
}
}
minetest.register_node("mcl_grindstone:grindstone", { minetest.register_node("mcl_grindstone:grindstone", {
description = S("Grindstone"), description = S("Grindstone"),
_tt_help = S("Used to disenchant/fix tools"), _tt_help = S("Used to disenchant/fix tools"),
_doc_items_longdesc = S("This is currently a decorative block which serves as the weapon smith's work station. In minecraft this is used to disenchant/fix tools howerver this has not yet been implemented"), _doc_items_longdesc = S("Grindstone disenchants tools and armour except for curses, and repairs two items of the same type it is also the weapon smith's work station."),
_doc_items_usagehelp = S("To use the grindstone, rightclick it, Two input slots (on the left) and a single output slot.").."\n"..
S("To disenchant an item place enchanted item in one of the input slots and take the disenchanted item from the output.").."\n"..
S("To repair a tool you need a tool of the same type and material, put both items in the input slot and the output slot will combine two items durabilities with 5% bonus.").."\n"..
S("If both items have enchantments the player will get xp from both items from the disenchant.").."\n"..
S("Curses cannot be removed and will be transfered to the new repaired item, if both items have a different curse the curses will be combined."),
tiles = { tiles = {
"grindstone_top.png", "grindstone_top.png",
"grindstone_top.png", "grindstone_top.png",
@ -14,18 +208,128 @@ minetest.register_node("mcl_grindstone:grindstone", {
}, },
drawtype = "nodebox", drawtype = "nodebox",
paramtype2 = "facedir", paramtype2 = "facedir",
node_box = { node_box = node_box,
type = "fixed", selection_box = node_box,
-- created with nodebox editor collision_box = node_box,
fixed = { sounds = mcl_sounds.node_sound_stone_defaults(),
{-0.25, -0.25, -0.375, 0.25, 0.5, 0.375},
{-0.375, -0.0625, -0.1875, -0.25, 0.3125, 0.1875},
{0.25, -0.0625, -0.1875, 0.375, 0.3125, 0.1875},
{0.25, -0.5, -0.125, 0.375, -0.0625, 0.125},
{-0.375, -0.5, -0.125, -0.25, -0.0625, 0.125},
}
},
groups = {pickaxey = 1, deco_block = 1}, groups = {pickaxey = 1, deco_block = 1},
after_dig_node = function(pos, oldnode, oldmetadata, digger)
local meta = minetest.get_meta(pos)
local meta2 = meta:to_table()
meta:from_table(oldmetadata)
drop_grindstone_items(pos, meta)
meta:from_table(meta2)
end,
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
local name = player:get_player_name()
if minetest.is_protected(pos, name) then
minetest.record_protection_violation(pos, name)
return 0
else
return stack:get_count()
end
end,
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
local name = player:get_player_name()
if minetest.is_protected(pos, name) then
minetest.record_protection_violation(pos, name)
return 0
elseif listname == "output" then
return 0
else
return stack:get_count()
end
end,
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
local name = player:get_player_name()
if minetest.is_protected(pos, name) then
minetest.record_protection_violation(pos, name)
return 0
elseif to_list == "output" then
return 0
elseif from_list == "output" and to_list == "input" then
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
if inv:get_stack(to_list, to_index):is_empty() then
return count
else
return 0
end
else
return count
end
end,
on_metadata_inventory_put = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
update_grindstone_slots(meta)
end,
on_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
local meta = minetest.get_meta(pos)
if from_list == "output" and to_list == "input" then
local inv = meta:get_inventory()
for i=1, inv:get_size("input") do
if i ~= to_index then
local istack = inv:get_stack("input", i)
istack:set_count(math.max(0, istack:get_count() - count))
inv:set_stack("input", i, istack)
end
end
end
update_grindstone_slots(meta)
end,
on_metadata_inventory_take = function(pos, listname, index, stack, player)
local meta = minetest.get_meta(pos)
if listname == "output" then
local xp_earnt = 0
local inv = meta:get_inventory()
local input1 = inv:get_stack("input", 1)
local input2 = inv:get_stack("input", 2)
-- Both slots occupied?
if not input1:is_empty() and not input2:is_empty() then
-- Get xp earnt from the enchanted items
xp_earnt = calculate_xp(input1) + calculate_xp(input1)
input1:take_item()
input2:take_item()
inv:set_stack("input", 1, input1)
inv:set_stack("input", 2, input2)
else
-- If only one input item
if not input1:is_empty() then
xp_earnt = calculate_xp(input1)
input1:set_count(math.max(0, input1:get_count() - stack:get_count()))
inv:set_stack("input", 1, input1)
end
if not input2:is_empty() then
xp_earnt = calculate_xp(input2)
input2:set_count(math.max(0, input2:get_count() - stack:get_count()))
inv:set_stack("input", 2, input2)
end
end
-- Give the player xp
if mcl_experience.throw_xp and xp_earnt > 0 then
mcl_experience.throw_xp(pos, xp_earnt)
end
elseif listname == "input" then
update_grindstone_slots(meta)
end
end,
on_construct = function(pos)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
inv:set_size("input", 2)
inv:set_size("output", 1)
local form = get_grindstone_formspec()
meta:set_string("formspec", form)
end,
on_rightclick = function(pos, node, player, itemstack)
if not player:get_player_control().sneak then
local meta = minetest.get_meta(pos)
update_grindstone_slots(meta)
meta:set_string("formspec", get_grindstone_formspec())
end
end,
_mcl_blast_resistance = 6, _mcl_blast_resistance = 6,
_mcl_hardness = 2 _mcl_hardness = 2
}) })

View File

@ -0,0 +1,10 @@
Inventory=
Repair & Disenchant=
Grindstone=
Used to disenchant/fix tools=
Grindstone disenchants tools and armour except for curses, and repairs two items of the same type it is also the weapon smith's work station.=
To use the grindstone, rightclick it, Two input slots (on the left) and a single output slot.=
To disenchant an item place enchanted item in one of the input slots and take the disenchanted item from the output.=
To repair a tool you need a tool of the same type and material, put both items in the input slot and the output slot will combine two items durabilities with 5% bonus.=
If both items have enchantments the player will get xp from both items from the disenchant.=
Curses cannot be removed and will be transfered to the new repaired item, if both items have a different curse the curses will be combined.=

View File

@ -1,3 +1,4 @@
name = mcl_grindstone name = mcl_grindstone
author = TheRandomLegoBrick author = TheRandomLegoBrick, ChrisPHP
description = Adds a cool looking block for the weaponsmiths jobsite depends = mcl_experience, mcl_sounds
description = Add block that disenchants tools and armour except for curses, and repairs two items of the same type it is also the weapon smith's work station.

Binary file not shown.

After

Width:  |  Height:  |  Size: 170 B

View File

@ -227,6 +227,7 @@ filled_wield_def.drawtype = "mesh"
filled_wield_def.node_placement_prediction = "" filled_wield_def.node_placement_prediction = ""
filled_wield_def.range = minetest.registered_items[""].range filled_wield_def.range = minetest.registered_items[""].range
filled_wield_def.on_place = mcl_util.call_on_rightclick filled_wield_def.on_place = mcl_util.call_on_rightclick
filled_wield_def._mcl_wieldview_item = "mcl_maps:filled_map"
for _, texture in pairs(mcl_skins.list) do for _, texture in pairs(mcl_skins.list) do
local def = table.copy(filled_wield_def) local def = table.copy(filled_wield_def)

View File

@ -321,7 +321,7 @@ minetest.register_tool("mcl_mobitems:carrot_on_a_stick", {
_tt_help = S("Lets you ride a saddled pig"), _tt_help = S("Lets you ride a saddled pig"),
_doc_items_longdesc = S("A carrot on a stick can be used on saddled pigs to ride them."), _doc_items_longdesc = S("A carrot on a stick can be used on saddled pigs to ride them."),
_doc_items_usagehelp = S("Place it on a saddled pig to mount it. You can now ride the pig like a horse. Pigs will also walk towards you when you just wield the carrot on a stick."), _doc_items_usagehelp = S("Place it on a saddled pig to mount it. You can now ride the pig like a horse. Pigs will also walk towards you when you just wield the carrot on a stick."),
wield_image = "mcl_mobitems_carrot_on_a_stick.png", wield_image = "mcl_mobitems_carrot_on_a_stick.png^[transformFY^[transformR90",
inventory_image = "mcl_mobitems_carrot_on_a_stick.png", inventory_image = "mcl_mobitems_carrot_on_a_stick.png",
groups = { transport = 1 }, groups = { transport = 1 },
_mcl_toollike_wield = true, _mcl_toollike_wield = true,

View File

@ -31,12 +31,12 @@ minetest.register_tool("mcl_shields:shield", {
shield = 1, shield = 1,
weapon = 1, weapon = 1,
enchantability = -1, enchantability = -1,
no_wieldview = 1,
offhand_item = 1, offhand_item = 1,
}, },
sound = {breaks = "default_tool_breaks"}, sound = {breaks = "default_tool_breaks"},
_repair_material = "group:wood", _repair_material = "group:wood",
wield_scale = vector.new(2, 2, 2), wield_scale = vector.new(2, 2, 2),
_mcl_wieldview_item = "",
}) })
local function wielded_item(obj, i) local function wielded_item(obj, i)
@ -438,7 +438,6 @@ for _, colortab in pairs(mcl_banners.colors) do
shield = 1, shield = 1,
weapon = 1, weapon = 1,
enchantability = -1, enchantability = -1,
no_wieldview = 1,
not_in_creative_inventory = 1, not_in_creative_inventory = 1,
offhand_item = 1, offhand_item = 1,
}, },
@ -446,6 +445,7 @@ for _, colortab in pairs(mcl_banners.colors) do
_repair_material = "group:wood", _repair_material = "group:wood",
wield_scale = vector.new(2, 2, 2), wield_scale = vector.new(2, 2, 2),
_shield_color = colortab[4], _shield_color = colortab[4],
_mcl_wieldview_item = "",
}) })
local banner = "mcl_banners:banner_item_" .. color local banner = "mcl_banners:banner_item_" .. color

View File

@ -7,19 +7,15 @@ mcl_smithing_table = {}
-- Function to upgrade diamond tool/armor to netherite tool/armor -- Function to upgrade diamond tool/armor to netherite tool/armor
function mcl_smithing_table.upgrade_item(itemstack) function mcl_smithing_table.upgrade_item(itemstack)
itemstack = ItemStack(itemstack) -- Copy the stack
local def = itemstack:get_definition() local def = itemstack:get_definition()
if not def or not def._mcl_upgradable then if not def or not def._mcl_upgradable then
return return
end end
local itemname = itemstack:get_name() local itemname = itemstack:get_name()
local upgrade_item = itemname:gsub("diamond", "netherite")
local upgrade_item = def._mcl_upgrade_item or itemname:gsub("diamond", "netherite") if def._mcl_upgrade_item and upgrade_item == itemname then
if upgrade_item == itemname then
return return
end end

View File

@ -57,11 +57,25 @@ mcl_structures.register_structure("pillager_outpost",{
after_place = function(p,def,pr) after_place = function(p,def,pr)
local p1 = vector.offset(p,-7,0,-7) local p1 = vector.offset(p,-7,0,-7)
local p2 = vector.offset(p,7,14,7) local p2 = vector.offset(p,7,14,7)
local spawnon = {"mcl_core:stripped_oak"}
local sp = minetest.find_nodes_in_area_under_air(p1,p2,spawnon)
for _,n in pairs(minetest.find_nodes_in_area(p1,p2,{"group:wall"})) do for _,n in pairs(minetest.find_nodes_in_area(p1,p2,{"group:wall"})) do
local def = minetest.registered_nodes[minetest.get_node(n).name:gsub("_%d+$","")] local def = minetest.registered_nodes[minetest.get_node(n).name:gsub("_%d+$","")]
if def and def.on_construct then if def and def.on_construct then
def.on_construct(n) def.on_construct(n)
end end
end end
if sp and #sp > 0 then
for i=1,5 do
local pos = sp[pr:next(1,#sp)]
if pos then
minetest.add_entity(pos,"mobs_mc:pillager")
end
end
local pos = sp[pr:next(1,#sp)]
if pos then
minetest.add_entity(pos,"mobs_mc:evoker")
end
end
end end
}) })

View File

@ -33,21 +33,20 @@ minetest.register_on_dieplayer(function(player)
end end
local listname = mcl_death_drop.registered_dropped_lists[l].listname local listname = mcl_death_drop.registered_dropped_lists[l].listname
local drop = mcl_death_drop.registered_dropped_lists[l].drop local drop = mcl_death_drop.registered_dropped_lists[l].drop
local dropspots = minetest.find_nodes_in_area(vector.offset(pos,-3,0,-3),vector.offset(pos,3,0,3),{"air"})
if #dropspots == 0 then
table.insert(dropspots,pos)
end
if inv then if inv then
for i, stack in ipairs(inv:get_list(listname)) do for i, stack in ipairs(inv:get_list(listname)) do
local x = random(0, 9)/3 local p = vector.offset(dropspots[math.random(#dropspots)],math.random()-0.5,math.random()-0.5,math.random()-0.5)
local z = random(0, 9)/3
pos.x = pos.x + x
pos.z = pos.z + z
if not void_deadly and drop and not mcl_enchanting.has_enchantment(stack, "curse_of_vanishing") then if not void_deadly and drop and not mcl_enchanting.has_enchantment(stack, "curse_of_vanishing") then
local def = minetest.registered_items[stack:get_name()] local def = minetest.registered_items[stack:get_name()]
if def and def.on_drop then if def and def.on_drop then
stack = def.on_drop(stack, player, pos) stack = def.on_drop(stack, player, p)
end end
minetest.add_item(pos, stack) minetest.add_item(p, stack)
end end
pos.x = pos.x - x
pos.z = pos.z - z
end end
inv:set_list(listname, {}) inv:set_list(listname, {})
end end

View File

@ -103,10 +103,6 @@ function mcl_player.player_set_armor(player, texture)
set_texture(player, 2, texture) set_texture(player, 2, texture)
end end
function mcl_player.player_set_wielditem(player, texture)
set_texture(player, 3, texture)
end
function mcl_player.get_player_formspec_model(player, x, y, w, h, fsname) function mcl_player.get_player_formspec_model(player, x, y, w, h, fsname)
local name = player:get_player_name() local name = player:get_player_name()
local model = player_model[name] local model = player_model[name]

View File

@ -359,15 +359,17 @@ minetest.register_globalstep(function(dtime)
end end
if wielded_def and wielded_def._mcl_toollike_wield then if wielded_def and wielded_def._mcl_toollike_wield then
set_bone_position_conditional(player,"Wield_Item", vector.new(0,3.9,1.3), vector.new(90,0,0)) set_bone_position_conditional(player,"Wield_Item", vector.new(0,4.7,3.1), vector.new(-90,225,90))
elseif string.find(wielded:get_name(), "mcl_bows:bow") then elseif string.find(wielded:get_name(), "mcl_bows:bow") then
set_bone_position_conditional(player,"Wield_Item", vector.new(.5,4.5,-1.6), vector.new(90,0,20)) set_bone_position_conditional(player,"Wield_Item", vector.new(1,4,0), vector.new(90,130,115))
elseif string.find(wielded:get_name(), "mcl_bows:crossbow_loaded") then elseif string.find(wielded:get_name(), "mcl_bows:crossbow_loaded") then
set_bone_position_conditional(player,"Wield_Item", vector.new(-1.5,5.7,1.8), vector.new(64,90,0)) set_bone_position_conditional(player,"Wield_Item", vector.new(0,5.2,1.2), vector.new(0,180,73))
elseif string.find(wielded:get_name(), "mcl_bows:crossbow") then elseif string.find(wielded:get_name(), "mcl_bows:crossbow") then
set_bone_position_conditional(player,"Wield_Item", vector.new(-1.5,5.7,1.8), vector.new(90,90,0)) set_bone_position_conditional(player,"Wield_Item", vector.new(0,5.2,1.2), vector.new(0,180,45))
elseif wielded_def.inventory_image == "" then
set_bone_position_conditional(player,"Wield_Item", vector.new(0,6,2), vector.new(180,-45,0))
else else
set_bone_position_conditional(player,"Wield_Item", vector.new(-1.5,4.9,1.8), vector.new(135,0,90)) set_bone_position_conditional(player,"Wield_Item", vector.new(0,5.3,2), vector.new(90,0,0))
end end
-- controls right and left arms pitch when shooting a bow or blocking -- controls right and left arms pitch when shooting a bow or blocking

View File

@ -1,21 +1,13 @@
[mod] visible wielded items [wieldview] [mod] visible wielded items [mcl_wieldview]
======================================= =======================================
Makes hand wielded items visible to other players. Makes hand wielded items visible to other players.
default settings: [minetest.conf]
# Set number of seconds between visible wielded item updates.
wieldview_update_time = 2
# Show nodes as tiles, disabled by default
wieldview_node_tiles = false
Info for modders Info for modders
################ ################
Wield image transformation: To apply a simple transformation to the item in Register an item with the property "_mcl_wieldview_item" to change the third person wield view appearance of the item.
hand, add the group “wieldview_transform” to the item definition. The group "_mcl_wieldview_item" should be set to an item name that will be shown by the wield view instead of the item.
rating equals one of the numbers used for the [transform texture modifier If you use an empty string, nothing will be shown.
of the Lua API.

View File

@ -1,126 +1,64 @@
local get_connected_players = minetest.get_connected_players minetest.register_entity("mcl_wieldview:wieldview", {
local get_item_group = minetest.get_item_group
mcl_wieldview = {
players = {}
}
function mcl_wieldview.get_item_texture(itemname)
if itemname == "" or minetest.get_item_group(itemname, "no_wieldview") ~= 0 then
return
end
local def = minetest.registered_items[itemname]
if not def then
return
end
local inv_image = def.inventory_image
if inv_image == "" then
return
end
local texture = inv_image
local transform = get_item_group(itemname, "wieldview_transform")
if transform then
-- This actually works with groups ratings because transform1, transform2, etc.
-- have meaning and transform0 is used for identidy, so it can be ignored
texture = texture .. "^[transform" .. transform
end
return texture
end
function mcl_wieldview.update_wielded_item(player)
if not player then
return
end
local itemstack = player:get_wielded_item()
local itemname = itemstack:get_name()
local def = mcl_wieldview.players[player]
if def.item == itemname then
return
end
def.item = itemname
def.texture = mcl_wieldview.get_item_texture(itemname) or "blank.png"
mcl_player.player_set_wielditem(player, def.texture)
end
minetest.register_on_joinplayer(function(player)
mcl_wieldview.players[player] = {item = "", texture = "blank.png"}
minetest.after(0, function()
if not player:is_player() then
return
end
mcl_wieldview.update_wielded_item(player)
local itementity = minetest.add_entity(player:get_pos(), "mcl_wieldview:wieldnode")
itementity:set_attach(player, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 0, 45))
itementity:get_luaentity().wielder = player
end)
end)
minetest.register_on_leaveplayer(function(player)
mcl_wieldview.players[player] = nil
end)
minetest.register_globalstep(function()
local players = get_connected_players()
for i = 1, #players do
mcl_wieldview.update_wielded_item(players[i])
end
end)
minetest.register_entity("mcl_wieldview:wieldnode", {
initial_properties = { initial_properties = {
hp_max = 1, hp_max = 1,
visual = "wielditem", visual = "wielditem",
physical = false, physical = false,
textures = {""}, is_visible = false,
automatic_rotate = 1.5,
is_visible = true,
pointable = false, pointable = false,
collide_with_objects = false, collide_with_objects = false,
static_save = false, static_save = false,
collisionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21}, collisionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21},
selectionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21}, selectionbox = {-0.21, -0.21, -0.21, 0.21, 0.21, 0.21},
visual_size = {x = 0.21, y = 0.21}, visual_size = {x = 0.21, y = 0.21},
}, }
itemstring = "",
on_step = function(self)
if self.wielder:is_player() then
local def = mcl_wieldview.players[self.wielder]
local itemstring = def.item
if self.itemstring ~= itemstring then
local itemdef = minetest.registered_items[itemstring]
self.object:set_properties({glow = itemdef and itemdef.light_source or 0})
-- wield item as cubic
if def.texture == "blank.png" then
self.object:set_properties({textures = {itemstring}})
-- wield item as flat
else
self.object:set_properties({textures = {""}})
end
if minetest.get_item_group(itemstring, "no_wieldview") ~= 0 then
self.object:set_properties({textures = {""}})
end
self.itemstring = itemstring
end
else
self.object:remove()
end
end,
}) })
local wieldview_luaentites = {}
local function update_wieldview_entity(player)
local luaentity = wieldview_luaentites[player]
if luaentity and luaentity.object:get_yaw() then
local item = player:get_wielded_item():get_name()
if item == luaentity._item then return end
luaentity._item = item
local def = player:get_wielded_item():get_definition()
if def and def._mcl_wieldview_item then
item = def._mcl_wieldview_item
end
local item_def = minetest.registered_items[item]
luaentity.object:set_properties({
glow = item_def and item_def.light_source or 0,
wield_item = item,
is_visible = item ~= ""
})
else
-- If the player is running through an unloaded area,
-- the wieldview entity will sometimes get unloaded.
-- This code path is also used to initalize the wieldview.
-- Creating entites from minetest.register_on_joinplayer
-- is unreliable as of Minetest 5.6
local obj_ref = minetest.add_entity(player:get_pos(), "mcl_wieldview:wieldview")
if not obj_ref then return end
obj_ref:set_attach(player, "Wield_Item")
--obj_ref:set_attach(player, "Hand_Right", vector.new(0, 1, 0), vector.new(90, 45, 90))
wieldview_luaentites[player] = obj_ref:get_luaentity()
end
end
minetest.register_on_leaveplayer(function(player)
if wieldview_luaentites[player] then
wieldview_luaentites[player].object:remove()
end
wieldview_luaentites[player] = nil
end)
minetest.register_globalstep(function(dtime)
local players = minetest.get_connected_players()
for i, player in pairs(players) do
update_wieldview_entity(player)
end
end)

View File

@ -1,4 +1,4 @@
name = mcl_wieldview name = mcl_wieldview
author = stujones11 author = stujones11
description = Makes hand wielded items visible to other players. description = Makes hand wielded items visible to other players.
depends = mcl_player depends = mcl_armor, mcl_playerplus