forked from VoxeLibre/VoxeLibre
Compare commits
2 Commits
4df6f82c64
...
8ef4cddc38
Author | SHA1 | Date |
---|---|---|
mirqf | 8ef4cddc38 | |
Eliy21 | 7cbba73d50 |
|
@ -532,11 +532,28 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local time_now = minetest.get_us_time()
|
||||||
|
|
||||||
local is_player = hitter:is_player()
|
local is_player = hitter:is_player()
|
||||||
|
|
||||||
if is_player then
|
if is_player then
|
||||||
|
local time_diff = time_now - self.invul_timestamp
|
||||||
|
|
||||||
|
-- check for invulnerability time in microseconds (0.5 second)
|
||||||
|
if time_diff <= 500000 and time_diff >= 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local mob_pos = self.object:get_pos()
|
||||||
|
local player_pos = hitter:get_pos()
|
||||||
|
|
||||||
|
-- is mob out of reach?
|
||||||
|
if vector.distance(mob_pos, player_pos) > 3 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
-- is mob protected?
|
-- is mob protected?
|
||||||
if self.protected and minetest.is_protected(self.object:get_pos(), hitter:get_player_name()) then
|
if self.protected and minetest.is_protected(mob_pos, hitter:get_player_name()) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -545,7 +562,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- set/update 'drop xp' timestamp if hitted by player
|
-- set/update 'drop xp' timestamp if hitted by player
|
||||||
self.xp_timestamp = minetest.get_us_time()
|
self.xp_timestamp = time_now
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -657,6 +674,9 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
|
||||||
-- do damage
|
-- do damage
|
||||||
self.health = self.health - damage
|
self.health = self.health - damage
|
||||||
|
|
||||||
|
-- give invulnerability
|
||||||
|
self.invul_timestamp = time_now
|
||||||
|
|
||||||
-- skip future functions if dead, except alerting others
|
-- skip future functions if dead, except alerting others
|
||||||
if self:check_for_death( "hit", {type = "punch", puncher = hitter}) then
|
if self:check_for_death( "hit", {type = "punch", puncher = hitter}) then
|
||||||
die = true
|
die = true
|
||||||
|
@ -672,10 +692,10 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
|
||||||
if not v then return end
|
if not v then return end
|
||||||
local r = 1.4 - math.min(punch_interval, 1.4)
|
local r = 1.4 - math.min(punch_interval, 1.4)
|
||||||
local kb = r * (math.abs(v.x)+math.abs(v.z))
|
local kb = r * (math.abs(v.x)+math.abs(v.z))
|
||||||
local up = 2
|
local up = 2.625
|
||||||
|
|
||||||
if die==true then
|
if die==true then
|
||||||
kb=kb*2
|
kb=kb*1.25
|
||||||
end
|
end
|
||||||
|
|
||||||
-- if already in air then dont go up anymore when hit
|
-- if already in air then dont go up anymore when hit
|
||||||
|
@ -689,7 +709,7 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
|
||||||
if tool_capabilities.damage_groups["knockback"] then
|
if tool_capabilities.damage_groups["knockback"] then
|
||||||
kb = tool_capabilities.damage_groups["knockback"]
|
kb = tool_capabilities.damage_groups["knockback"]
|
||||||
else
|
else
|
||||||
kb = kb * 1.5
|
kb = kb * 1.25
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
|
@ -699,9 +719,19 @@ function mob_class:on_punch(hitter, tflp, tool_capabilities, dir)
|
||||||
end
|
end
|
||||||
if hitter and is_player then
|
if hitter and is_player then
|
||||||
local wielditem = hitter:get_wielded_item()
|
local wielditem = hitter:get_wielded_item()
|
||||||
kb = kb + 3 * mcl_enchanting.get_enchantment(wielditem, "knockback")
|
local hv = hitter:get_velocity()
|
||||||
elseif luaentity and luaentity._knockback then
|
local dir_dot = (hv.x * dir.x) + (hv.z * dir.z)
|
||||||
|
local player_mag = math.sqrt((hv.x * hv.x) + (hv.z * hv.z))
|
||||||
|
local mob_mag = math.sqrt((v.x * v.x) + (v.z * v.z))
|
||||||
|
kb = kb + 9 * mcl_enchanting.get_enchantment(wielditem, "knockback")
|
||||||
|
-- add player velocity to mob knockback
|
||||||
|
if dir_dot > 0 and mob_mag <= player_mag * 0.625 then
|
||||||
|
kb = kb + ((math.abs(hv.x) + math.abs(hv.z)) * r)
|
||||||
|
end
|
||||||
|
elseif luaentity and luaentity._knockback and die == false then
|
||||||
kb = kb + luaentity._knockback
|
kb = kb + luaentity._knockback
|
||||||
|
elseif luaentity and luaentity._knockback and die == true then
|
||||||
|
kb = kb + luaentity._knockback * 0.25
|
||||||
end
|
end
|
||||||
self._kb_turn = true
|
self._kb_turn = true
|
||||||
self._turn_to=self.object:get_yaw()-1.57
|
self._turn_to=self.object:get_yaw()-1.57
|
||||||
|
|
|
@ -171,6 +171,7 @@ function mcl_mobs.register_mob(name, def)
|
||||||
xp_min = def.xp_min or 0,
|
xp_min = def.xp_min or 0,
|
||||||
xp_max = def.xp_max or 0,
|
xp_max = def.xp_max or 0,
|
||||||
xp_timestamp = 0,
|
xp_timestamp = 0,
|
||||||
|
invul_timestamp = 0,
|
||||||
breath_max = def.breath_max or 15,
|
breath_max = def.breath_max or 15,
|
||||||
breathes_in_water = def.breathes_in_water or false,
|
breathes_in_water = def.breathes_in_water or false,
|
||||||
physical = true,
|
physical = true,
|
||||||
|
|
|
@ -48,7 +48,7 @@ function mcl_bows.shoot_arrow(arrow_item, pos, dir, yaw, shooter, power, damage,
|
||||||
damage = damage + (enchantments.power + 1) / 4
|
damage = damage + (enchantments.power + 1) / 4
|
||||||
end
|
end
|
||||||
if enchantments.punch then
|
if enchantments.punch then
|
||||||
knockback = enchantments.punch * 3
|
knockback = enchantments.punch * 21
|
||||||
end
|
end
|
||||||
if enchantments.flame then
|
if enchantments.flame then
|
||||||
mcl_burning.set_on_fire(obj, math.huge)
|
mcl_burning.set_on_fire(obj, math.huge)
|
||||||
|
|
|
@ -1,13 +1,70 @@
|
||||||
--|||||||||||||||||||||||
|
|
||||||
--||||| STONECUTTER |||||
|
|
||||||
--|||||||||||||||||||||||
|
|
||||||
|
|
||||||
-- TO-DO:
|
|
||||||
-- * Add GUI
|
|
||||||
|
|
||||||
local S = minetest.get_translator(minetest.get_current_modname())
|
local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
local C = minetest.colorize
|
||||||
|
local F = minetest.formspec_escape
|
||||||
|
|
||||||
minetest.register_node("mcl_stonecutter:stonecutter", {
|
-- Some nodes have special recepies, all of them logged here
|
||||||
|
local special = {
|
||||||
|
["mcl_core:stone"] = {"mcl_core:stonebrickcarved", "mcl_stairs:slab_stonebrick 2", "mcl_stairs:stair_stonebrick", "mcl_walls:stonebrick", "mcl_core:stonebrick", "mcl_stairs:slab_stone_rough 2", "mcl_stairs:stair_stone_rough"},
|
||||||
|
}
|
||||||
|
|
||||||
|
local function show_stonecutter_formspec(pos, player)
|
||||||
|
local inv = minetest.get_meta(pos):get_inventory()
|
||||||
|
local input = inv:get_stack("input", 1):get_name()
|
||||||
|
local container_content = ""
|
||||||
|
local otp = {}
|
||||||
|
if special[input] then
|
||||||
|
table.insert_all(otp, special[input])
|
||||||
|
else
|
||||||
|
if minetest.get_item_group(input, "material_stone") > 0 and minetest.registered_nodes["mcl_stairs:slab_" .. input:split(":")[2]] then
|
||||||
|
local material = input:split(":")[2]
|
||||||
|
for i, grindment in ipairs({"mcl_stairs:slab_%s 2", "mcl_stairs:stair_%s", "mcl_walls:%s"}) do
|
||||||
|
local output = string.format(grindment, material)
|
||||||
|
if ItemStack(output):is_known() then table.insert(otp, output) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for i, new in ipairs(otp) do
|
||||||
|
container_content = container_content .. string.format("item_image_button[%f,%f;1.1,1.1;%s;%s;]", ((i%4>0 and i%4 or 4)-1)*1.1, (math.ceil(i/4)-1)*1.1, new, new)
|
||||||
|
end
|
||||||
|
local formspec = table.concat({
|
||||||
|
"formspec_version[4]",
|
||||||
|
"size[11.75,10.425]",
|
||||||
|
"label[0.375,0.375;" .. F(C(mcl_formspec.label_color, S("Stonecutter"))) .. "]",
|
||||||
|
|
||||||
|
-- Input slot
|
||||||
|
mcl_formspec.get_itemslot_bg_v4(1, 2, 1, 1),
|
||||||
|
"list[nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ";input;1,2;1,1;]",
|
||||||
|
|
||||||
|
-- Container background
|
||||||
|
"image[3.23,0.85;4.4,3.3;mcl_inventory_background9.png;2]",
|
||||||
|
|
||||||
|
-- It should be a scroll container, but no default recepies exist to overflow the limit of 12 buttons.
|
||||||
|
"container[3.23,0.85]",
|
||||||
|
container_content,
|
||||||
|
"container_end[]",
|
||||||
|
|
||||||
|
-- Scrollbar
|
||||||
|
-- TODO: style the scrollbar correctly when possible
|
||||||
|
"scrollbaroptions[min=0;max=1;smallstep=0;largesteps=0]",
|
||||||
|
"scrollbar[7.6,0.85;0.75,3.3;vertical;scroll;0]",
|
||||||
|
|
||||||
|
-- Output slot
|
||||||
|
mcl_formspec.get_itemslot_bg_v4(9.75, 2, 1, 1, 0.2),
|
||||||
|
"list[nodemeta:" .. pos.x .. "," .. pos.y .. "," .. pos.z .. ";output;9.75,2;1,1;]",
|
||||||
|
|
||||||
|
-- Player inventory
|
||||||
|
"label[0.375,4.7;" .. F(C(mcl_formspec.label_color, S("Inventory"))) .. "]",
|
||||||
|
mcl_formspec.get_itemslot_bg_v4(0.375, 5.1, 9, 3),
|
||||||
|
"list[current_player;main;0.375,5.1;9,3;9]",
|
||||||
|
|
||||||
|
mcl_formspec.get_itemslot_bg_v4(0.375, 9.05, 9, 1),
|
||||||
|
"list[current_player;main;0.375,9.05;9,1;]",
|
||||||
|
})
|
||||||
|
|
||||||
|
minetest.show_formspec(player:get_player_name(), ("mcl_stonecutter:%f_%f_%f"):format(pos.x, pos.y, pos.z), formspec)
|
||||||
|
end
|
||||||
|
|
||||||
|
minetest.register_node("mcl_functional:stonecutter", {
|
||||||
description = S("Stone Cutter"),
|
description = S("Stone Cutter"),
|
||||||
_tt_help = S("Used to cut stone like materials."),
|
_tt_help = S("Used to cut stone like materials."),
|
||||||
_doc_items_longdesc = S("Stonecutters are used to create stairs and slabs from stone like materials. It is also the jobsite for the Stone Mason Villager."),
|
_doc_items_longdesc = S("Stonecutters are used to create stairs and slabs from stone like materials. It is also the jobsite for the Stone Mason Villager."),
|
||||||
|
@ -45,14 +102,66 @@ minetest.register_node("mcl_stonecutter:stonecutter", {
|
||||||
},
|
},
|
||||||
_mcl_blast_resistance = 3.5,
|
_mcl_blast_resistance = 3.5,
|
||||||
_mcl_hardness = 3.5,
|
_mcl_hardness = 3.5,
|
||||||
|
allow_metadata_inventory_put = function(pos, listname, index, stack, player)
|
||||||
|
return (minetest.is_protected(pos, player:get_player_name()) or listname == "output") and 0 or stack:get_count()
|
||||||
|
end,
|
||||||
|
allow_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||||
|
return minetest.is_protected(pos, player:get_player_name()) and 0 or stack:get_count()
|
||||||
|
end,
|
||||||
|
allow_metadata_inventory_move = function(pos, from_list, from_index, to_list, to_index, count, player)
|
||||||
|
return (minetest.is_protected(pos, player:get_player_name()) or to_list == "output") and 0 or count
|
||||||
|
end,
|
||||||
|
on_metadata_inventory_put = function(pos, _, _, _, player)
|
||||||
|
show_stonecutter_formspec(pos, player)
|
||||||
|
end,
|
||||||
|
on_metadata_inventory_take = function(pos, listname, index, stack, player)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
if listname == "input" then
|
||||||
|
show_stonecutter_formspec(pos, player)
|
||||||
|
meta:get_inventory():set_stack("output", 1, "")
|
||||||
|
else
|
||||||
|
local input = meta:get_inventory():get_stack("input", 1)
|
||||||
|
input:take_item(stack:get_count())
|
||||||
|
meta:get_inventory():set_stack("input", 1, input)
|
||||||
|
if input:is_empty() then show_stonecutter_formspec(pos, player) end
|
||||||
|
end
|
||||||
|
end,
|
||||||
sounds = mcl_sounds.node_sound_stone_defaults(),
|
sounds = mcl_sounds.node_sound_stone_defaults(),
|
||||||
|
on_construct = function(pos)
|
||||||
|
local inv = minetest.get_meta(pos):get_inventory()
|
||||||
|
inv:set_size("input", 1)
|
||||||
|
inv:set_size("output", 1)
|
||||||
|
end,
|
||||||
|
on_rightclick = function(pos, node, player, itemstack)
|
||||||
|
if not player:get_player_control().sneak then
|
||||||
|
show_stonecutter_formspec(pos, player)
|
||||||
|
end
|
||||||
|
end,
|
||||||
|
after_dig_node = function(pos, _, oldmetadata, _)
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local meta2 = meta:to_table()
|
||||||
|
meta:from_table(oldmetadata)
|
||||||
|
local input = meta:get_inventory():get_stack("input", 1)
|
||||||
|
if not input:is_empty() then minetest.add_item(vector.offset(pos, math.random(0,10)/10-0.5, 0, math.random(0,10)/10-0.5), input) end
|
||||||
|
meta:from_table(meta2)
|
||||||
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
|
if formname:find("mcl_stonecutter") then
|
||||||
|
if fields.quit then return end
|
||||||
|
local p = formname:split(":")[2]:split("_")
|
||||||
|
local pos = vector.new(tonumber(p[1]), tonumber(p[2]), tonumber(p[3]))
|
||||||
|
local item; for k, v in pairs(fields) do if k ~= "scroll" then item = k break end end; if not item then return end
|
||||||
|
minetest.get_meta(pos):get_inventory():set_stack("output", 1, item)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = "mcl_stonecutter:stonecutter",
|
output = "mcl_functional:stonecutter",
|
||||||
recipe = {
|
recipe = {
|
||||||
{ "", "", "" },
|
{"", "", ""},
|
||||||
{ "", "mcl_core:iron_ingot", "" },
|
{"", "mcl_core:iron_ingot", ""},
|
||||||
{ "mcl_core:stone", "mcl_core:stone", "mcl_core:stone" },
|
{"mcl_core:stone", "mcl_core:stone", "mcl_core:stone"},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
name = mcl_stonecutter
|
name = mcl_stonecutter
|
||||||
author = PrairieWind
|
author = PrairieWind, mirqf
|
||||||
description = This mod adds a stonecutter, which is used to cut stone like materials, and used as the jobsite for the Stone Mason Villager.
|
description = This mod adds a stonecutter, which is used to cut stone like materials, and used as the jobsite for the Stone Mason Villager.
|
||||||
depends = mcl_sounds
|
depends = mcl_sounds, mcl_formspec
|
||||||
|
|
|
@ -146,8 +146,9 @@ minetest.register_globalstep(function(dtime)
|
||||||
local food_level = mcl_hunger.get_hunger(player)
|
local food_level = mcl_hunger.get_hunger(player)
|
||||||
local food_saturation_level = mcl_hunger.get_saturation(player)
|
local food_saturation_level = mcl_hunger.get_saturation(player)
|
||||||
local player_health = player:get_hp()
|
local player_health = player:get_hp()
|
||||||
|
local max_tick_timer = tonumber(minetest.settings:get("mcl_health_regen_delay")) or 4
|
||||||
|
|
||||||
if food_tick_timer > 4.0 then
|
if food_tick_timer > max_tick_timer then
|
||||||
food_tick_timer = 0
|
food_tick_timer = 0
|
||||||
|
|
||||||
-- let hunger work always
|
-- let hunger work always
|
||||||
|
@ -173,7 +174,7 @@ minetest.register_globalstep(function(dtime)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
elseif food_tick_timer > 0.5 and food_level == 20 and food_saturation_level > 0 then -- fast regeneration
|
elseif food_tick_timer > max_tick_timer and food_level == 20 and food_saturation_level > 0 then -- fast regeneration
|
||||||
if player_health > 0 and player_health < 20 then
|
if player_health > 0 and player_health < 20 then
|
||||||
food_tick_timer = 0
|
food_tick_timer = 0
|
||||||
player:set_hp(player_health+1)
|
player:set_hp(player_health+1)
|
||||||
|
|
|
@ -95,6 +95,10 @@ mcl_creative_dig_speed (Creative mode dig speed) float 0.2
|
||||||
# If enabled the hunger mechanic will be active
|
# If enabled the hunger mechanic will be active
|
||||||
mcl_enable_hunger (Hunger mechanic) bool true
|
mcl_enable_hunger (Hunger mechanic) bool true
|
||||||
|
|
||||||
|
# Health regeneration delay when hunger bar is full
|
||||||
|
# Default:4
|
||||||
|
mcl_health_regen_delay (Health regen delay) float 4 0
|
||||||
|
|
||||||
[Mobs]
|
[Mobs]
|
||||||
# If enabled, mobs will spawn naturally. This does not affect
|
# If enabled, mobs will spawn naturally. This does not affect
|
||||||
# affect mob spawners.
|
# affect mob spawners.
|
||||||
|
|
Loading…
Reference in New Issue