1
0
Fork 0

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

Reviewed-on: https://git.minetest.land/FaceDeer/MineClone2/pulls/1
mobs-redo
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
mcl_damage.run_death_callbacks(player, mcl_damage.from_mt(mt_reason))
end
minetest.log("action","Player "..player:get_player_name().." died at "..minetest.pos_to_string(vector.round(player:get_pos())))
end)
minetest.register_on_mods_loaded(function()
table.sort(mcl_damage.modifiers, function(a, b) return a.priority < b.priority 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
-- Disable flowing physics if not on/in flowing liquid
self._flowing = false
disable_physics(self.object, self, true)
enable_physics(self.object, self, true)
return
end
-- 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 def = minetest.registered_nodes[nn]
local v = self.object:get_velocity()
local is_on_floor = (minetest.registered_nodes[nn].walkable
and not minetest.registered_nodes[nn].groups.slippery and v.y == 0)
local is_on_floor = def and (def.walkable
and not def.groups.slippery and v.y == 0)
if not minetest.registered_nodes[nn]
or is_floating or is_on_floor then

View File

@ -213,11 +213,11 @@ end
local collision = function(self)
local pos = self.object:get_pos()
if not pos then return {0,0} end
local vel = self.object:get_velocity()
local x = 0
local z = 0
local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5
for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do
local ent = object:get_luaentity()
@ -254,12 +254,14 @@ local set_velocity = function(self, v)
end
local yaw = (self.object:get_yaw() or 0) + self.rotate
self.object:set_velocity({
x = (sin(yaw) * -v) + c_x,
y = self.object:get_velocity().y,
z = (cos(yaw) * v) + c_y,
})
local vv = self.object:get_velocity()
if vv then
self.object:set_velocity({
x = (sin(yaw) * -v) + c_x,
y = vv.y,
z = (cos(yaw) * v) + c_y,
})
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
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 .. "_end"]) and self.state ~= "die" then
return
end
self.animation.current = anim
self._current_animation = anim
local a_start = self.animation[anim .. "_start"]
local a_end
@ -3002,6 +3004,7 @@ end
local function check_entity_cramming(self)
local p = self.object:get_pos()
if not p then return end
local oo = minetest.get_objects_inside_radius(p,1)
local mobs = {}
for _,o in pairs(oo) do
@ -3467,7 +3470,10 @@ local mob_activate = function(self, staticdata, def, dtime)
def.textures = {def.textures}
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_size = self.visual_size
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_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_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 = count_mobs(spawning_position,32,mob_type)
if mob_def

View File

@ -219,6 +219,7 @@ local select_enderman_animation = function(animation_type)
end
local mobs_griefing = minetest.settings:get_bool("mobs_griefing") ~= false
local spawners = {}
mcl_mobs:register_mob("mobs_mc:enderman", {
description = S("Enderman"),
@ -263,20 +264,42 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
do_custom = function(self, dtime)
-- PARTICLE BEHAVIOUR HERE.
local enderpos = self.object:get_pos()
local chanceOfParticle = math.random(0, 1)
if chanceOfParticle == 1 then
minetest.add_particle({
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},
velocity = {x=math.random(-.25,.25), y=math.random(-.25,.25), z=math.random(-.25,.25)},
acceleration = {x=math.random(-.5,.5), y=math.random(-.5,.5), z=math.random(-.5,.5)},
expirationtime = math.random(),
size = math.random(),
collisiondetection = true,
vertical = false,
texture = "mcl_portals_particle"..math.random(1, 5)..".png",
})
if self._particle_timer and self._particle_timer >= 1 then
for _,player in pairs(minetest.get_connected_players()) do
if not spawners[player] then spawners[player] = {} end
local dst = vector.distance(player:get_pos(),enderpos)
if dst < 128 and not spawners[player][self.object] then
self._particle_timer = 0
spawners[player][self.object] = minetest.add_particlespawner({
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,
vertical = false,
time = 0,
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
elseif not self._particle_timer then
self._particle_timer = 0
end
self._particle_timer = self._particle_timer + dtime
-- RAIN DAMAGE / EVASIVE WARP BEHAVIOUR HERE.
enderpos = self.object:get_pos()
local dim = mcl_worlds.pos_to_dimension(enderpos)
if dim == "overworld" then
if mcl_weather.state == "rain" or mcl_weather.state == "lightning" then
@ -312,24 +335,24 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
else return end
-- AGRESSIVELY WARP/CHASE PLAYER BEHAVIOUR HERE.
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
local target = self.attack
local pos = target:get_pos()
if pos ~= nil then
if vector.distance(self.object:get_pos(), target:get_pos()) > 10 then
self:teleport(target)
end
if self.attack then
local target = self.attack
local pos = target:get_pos()
if pos ~= nil then
if vector.distance(self.object:get_pos(), target:get_pos()) > 10 then
self:teleport(target)
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
-- ARROW / DAYTIME PEOPLE AVOIDANCE BEHAVIOUR HERE.
-- Check for arrows and people nearby.
local enderpos = self.object:get_pos()
enderpos = self.object:get_pos()
enderpos.y = enderpos.y + 1.5
local objs = minetest.get_objects_inside_radius(enderpos, 2)
for n = 1, #objs do
@ -593,6 +616,13 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
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
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
-- 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_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

View File

@ -65,3 +65,4 @@ Nitwit=
Cod=
Salmon=
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)
}
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 t = table.copy(minetest.registered_entities)
table.shuffle(t)
for _,e in pairs(t) do
if e.is_mob and e.sounds then
return e.sounds[math.random(#e.sounds)]
if e.is_mob and e.sounds and #e.sounds > 0 then
return table_get_rand(e.sounds)
end
end
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},
visual = "mesh",
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 = {},
animation = {
stand_start = 0,

View File

@ -28,6 +28,11 @@ return {
"Code-Sploit",
"NO11",
"kabou",
"rudzik8",
"chmodsayshello",
"PrarieWind",
"RandomLegoBrick",
"SumianVoice",
}},
{S("Contributors"), 0x52FF00, {
"Laurent Rocher",
@ -72,6 +77,12 @@ return {
"Sven792",
"aldum",
"Dieter44",
"Pepebotella",
"MrRar",
"Lazerbeak12345",
"mrminer",
"Thunder1035",
"opfromthestart",
}},
{S("MineClone5"), 0xA60014, {
"kay27",
@ -79,10 +90,12 @@ return {
"epCode",
"NO11",
"j45",
"chmodsayshello",
"3raven",
"PrarieWind",
"Gustavo1",
"CableGuy67",
"MrRar",
}},
{S("Mineclonia"), 0xFFFFFF, {
"erlehmann",
@ -135,6 +148,9 @@ return {
"yutyo",
"NO11",
"kay27",
"MysticTempest",
"RandomLegoBrick",
"cora",
}},
{S("Translations"), 0x00FF60, {
"Wuzzy",
@ -144,6 +160,8 @@ return {
"pitchum",
"todoporlalibertad",
"Marcin Serwin",
"Pepebotella",
"Emojigit",
}},
{S("Funders"), 0xF7FF00, {
"40W",
@ -151,7 +169,8 @@ return {
{S("Special thanks"), 0x00E9FF, {
"celeron55 for creating Minetest",
"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",
"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?"),
groups = { tool=1, fishing_rod=1, enchantability=1 },
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 },
stack_max = 1,
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 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", {
description = S("Grindstone"),
_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 = {
"grindstone_top.png",
"grindstone_top.png",
@ -14,18 +208,128 @@ minetest.register_node("mcl_grindstone:grindstone", {
},
drawtype = "nodebox",
paramtype2 = "facedir",
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},
}
},
node_box = node_box,
selection_box = node_box,
collision_box = node_box,
sounds = mcl_sounds.node_sound_stone_defaults(),
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_hardness = 2
})
@ -36,4 +340,4 @@ minetest.register_craft({
{ "mcl_core:stick", "mcl_stairs:slab_stone_rough", "mcl_core:stick"},
{ "group:wood", "", "group:wood"},
}
})
})

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
author = TheRandomLegoBrick
description = Adds a cool looking block for the weaponsmiths jobsite
author = TheRandomLegoBrick, ChrisPHP
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.range = minetest.registered_items[""].range
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
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"),
_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."),
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",
groups = { transport = 1 },
_mcl_toollike_wield = true,

View File

@ -31,12 +31,12 @@ minetest.register_tool("mcl_shields:shield", {
shield = 1,
weapon = 1,
enchantability = -1,
no_wieldview = 1,
offhand_item = 1,
},
sound = {breaks = "default_tool_breaks"},
_repair_material = "group:wood",
wield_scale = vector.new(2, 2, 2),
_mcl_wieldview_item = "",
})
local function wielded_item(obj, i)
@ -438,7 +438,6 @@ for _, colortab in pairs(mcl_banners.colors) do
shield = 1,
weapon = 1,
enchantability = -1,
no_wieldview = 1,
not_in_creative_inventory = 1,
offhand_item = 1,
},
@ -446,6 +445,7 @@ for _, colortab in pairs(mcl_banners.colors) do
_repair_material = "group:wood",
wield_scale = vector.new(2, 2, 2),
_shield_color = colortab[4],
_mcl_wieldview_item = "",
})
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 mcl_smithing_table.upgrade_item(itemstack)
itemstack = ItemStack(itemstack) -- Copy the stack
local def = itemstack:get_definition()
if not def or not def._mcl_upgradable then
return
end
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 upgrade_item == itemname then
if def._mcl_upgrade_item and upgrade_item == itemname then
return
end

View File

@ -57,11 +57,25 @@ mcl_structures.register_structure("pillager_outpost",{
after_place = function(p,def,pr)
local p1 = vector.offset(p,-7,0,-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
local def = minetest.registered_nodes[minetest.get_node(n).name:gsub("_%d+$","")]
if def and def.on_construct then
def.on_construct(n)
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
})

View File

@ -33,21 +33,20 @@ minetest.register_on_dieplayer(function(player)
end
local listname = mcl_death_drop.registered_dropped_lists[l].listname
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
for i, stack in ipairs(inv:get_list(listname)) do
local x = random(0, 9)/3
local z = random(0, 9)/3
pos.x = pos.x + x
pos.z = pos.z + z
local p = vector.offset(dropspots[math.random(#dropspots)],math.random()-0.5,math.random()-0.5,math.random()-0.5)
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()]
if def and def.on_drop then
stack = def.on_drop(stack, player, pos)
stack = def.on_drop(stack, player, p)
end
minetest.add_item(pos, stack)
minetest.add_item(p, stack)
end
pos.x = pos.x - x
pos.z = pos.z - z
end
inv:set_list(listname, {})
end

View File

@ -103,10 +103,6 @@ function mcl_player.player_set_armor(player, texture)
set_texture(player, 2, texture)
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)
local name = player:get_player_name()
local model = player_model[name]

View File

@ -359,15 +359,17 @@ minetest.register_globalstep(function(dtime)
end
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
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
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
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
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
-- 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.
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
################
Wield image transformation: To apply a simple transformation to the item in
hand, add the group “wieldview_transform” to the item definition. The group
rating equals one of the numbers used for the [transform texture modifier
of the Lua API.
Register an item with the property "_mcl_wieldview_item" to change the third person wield view appearance of the item.
"_mcl_wieldview_item" should be set to an item name that will be shown by the wield view instead of the item.
If you use an empty string, nothing will be shown.

View File

@ -1,126 +1,64 @@
local get_connected_players = minetest.get_connected_players
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", {
minetest.register_entity("mcl_wieldview:wieldview", {
initial_properties = {
hp_max = 1,
visual = "wielditem",
physical = false,
textures = {""},
automatic_rotate = 1.5,
is_visible = true,
is_visible = false,
pointable = false,
collide_with_objects = false,
static_save = false,
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},
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
author = stujones11
description = Makes hand wielded items visible to other players.
depends = mcl_player
depends = mcl_armor, mcl_playerplus