Compare commits

...

37 Commits

Author SHA1 Message Date
cora e80ce4b758 Merge pull request 'Fix mirrored doors placement rotation' (#2736) from fix_doors_direction into master
Reviewed-on: MineClone2/MineClone2#2736
2022-10-11 09:47:31 +00:00
cora 51e43f7efc Fix mirrored doors rotation 2022-10-11 11:46:08 +02:00
cora dc0ca59534 Merge pull request 'Add new breaking animation by FossFanatic' (#2744) from fossfan_breaking_anim into master
Reviewed-on: MineClone2/MineClone2#2744
Reviewed-by: Nicu <kneekoo@noreply.git.minetest.land>
2022-10-11 09:40:51 +00:00
FossFanatic e35e949833 Add breaking animation by FossFanatic 2022-10-11 11:40:15 +02:00
cora 0b0a48fd10 Merge pull request 'Change torch model, add soul fire flame particle texture' (#2750) from talamh/MineClone2:torch_remodel into master
Reviewed-on: MineClone2/MineClone2#2750
Reviewed-by: cora <cora@noreply.git.minetest.land>
2022-10-11 09:36:49 +00:00
cora 1b6df20c0c Merge pull request 'Adds some mob jockey support' (#2752) from mob_jockey into master
Reviewed-on: MineClone2/MineClone2#2752
Reviewed-by: cora <cora@noreply.git.minetest.land>
2022-10-11 09:30:29 +00:00
epCode 8930f9da45 fix skeleton wielditem 2022-10-10 13:54:51 -07:00
epCode aa2693795d Add Spider Jockey 2022-10-10 13:42:01 -07:00
talamh 23ec60fff0 Change torch model, add soul fire flame particle texture 2022-10-10 20:50:11 +01:00
cora fec0dae4ca Merge pull request 'Make mobs have smooth turning' (#2743) from smooth_mob_turn into master
Reviewed-on: MineClone2/MineClone2#2743
Reviewed-by: cora <cora@noreply.git.minetest.land>
2022-10-10 02:10:53 +00:00
epCode 8cd093afa9 adjust values 2022-10-09 18:43:41 -07:00
epCode 9cf5b2a9f6 make mobs rotate when punched 2022-10-09 18:40:41 -07:00
epCode 8a63e90e4a remove debug message 2022-10-09 18:26:20 -07:00
epCode a16e8f0403 remove all glitchy shaking 2022-10-09 17:41:50 -07:00
epCode 090c5b086a fix mobs shaking a lot 2022-10-09 17:29:28 -07:00
epCode c500dc98f9 fix only hostile mobs using smooth turning 2022-10-09 17:23:14 -07:00
epCode 4a086db4c5 get rid of unecessary "if true" statement 2022-10-10 00:09:06 +00:00
epCode ef980f2ea0 Make mobs have smooth turning 2022-10-10 00:09:06 +00:00
cora 0c21abf28a Merge pull request 'Change Achievements to Advancements, Part 1' (#2681) from advancement_mod_fixes into master
Reviewed-on: MineClone2/MineClone2#2681
Reviewed-by: cora <cora@noreply.git.minetest.land>
2022-10-09 23:27:38 +00:00
PrairieWind 78f1a81d1f Add Advancement Groups (Overworld, Nether, End, Adventure, Husbandry) 2022-10-10 01:10:49 +02:00
PrairieWind 0a33c5b5df Added Types of Advancements (Advancements, Goals, and Challenges) 2022-10-10 01:10:49 +02:00
PrairieWind f9f74d2af7 Changed Achievements to Advancements in player visible text. 2022-10-10 01:10:49 +02:00
cora d43494e3b7 Merge pull request 'Fix dumb mistake in creative crash fix' (#2742) from fix_creative_crash_5.6 into master
Reviewed-on: MineClone2/MineClone2#2742
2022-10-09 23:09:58 +00:00
cora 2a9d704293 Fix dumb mistake in creative crash fix 2022-10-10 01:07:11 +02:00
cora e294466029 Merge pull request 'Fix crash in 5.6 gm-creative digging' (#2734) from fix_creative_crash_5.6 into master
Reviewed-on: MineClone2/MineClone2#2734
2022-10-09 22:53:59 +00:00
cora a1919b572a Fix crash in 5.6 gm-creative digging 2022-10-10 00:52:55 +02:00
cora 24c03c2d32 Merge pull request 'Fix baby zombies being 1/4 vis_size' (#2737) from fix_baby_z_visszie into master
Reviewed-on: MineClone2/MineClone2#2737
2022-10-09 22:50:23 +00:00
cora 2fa2f7cbf9 Fix baby zombies being 1/4 vis_size 2022-10-10 00:49:01 +02:00
cora aea899a569 Merge pull request 'Check enable damage instead of creative mode when appropriate' (#2726) from enable_damage into master
Reviewed-on: MineClone2/MineClone2#2726
Reviewed-by: cora <cora@noreply.git.minetest.land>
2022-10-09 19:51:00 +00:00
𝕵𝖔𝖍𝖆𝖓𝖓𝖊𝖘 𝕱𝖗𝖎𝖙𝖟 36427d5aef Check enable damage instead of creative mode in some cases 2022-10-09 21:45:05 +02:00
cora 3e9cb597e6 Merge pull request 'mcl_title API: enable styling' (#2730) from title-API-fixes into master
Reviewed-on: MineClone2/MineClone2#2730
Reviewed-by: cora <cora@noreply.git.minetest.land>
2022-10-09 19:35:48 +00:00
cora ba6dfc7368 Merge pull request 'Enable mcl_title debug code, debug priv to chatcmds' (#2735) from title-API-fixes_enable-debug into title-API-fixes
Reviewed-on: MineClone2/MineClone2#2735
2022-10-09 19:33:36 +00:00
cora 52ac8ffd43 clarify debug nature of chatcommands 2022-10-09 21:31:23 +02:00
cora 3686d9a79d Enable mcl_title debug code, debug priv to chatcmds 2022-10-08 22:56:40 +02:00
AFCMS d71d1c4b82 mcl_title API: enable styling 2022-10-08 22:46:32 +02:00
cora 0c4edbc4ac Merge pull request 'Flower pot fixes' (#2731) from flowerpot-fixes into master
Reviewed-on: MineClone2/MineClone2#2731
Reviewed-by: cora <cora@noreply.git.minetest.land>
2022-10-08 20:43:19 +00:00
AFCMS 5719637ee7
Flower pot fixes
- More accurate selection and collision box
-  Remove check for `minetest.features.use_texture_alpha_string_modes`
- Use new vectors
- Add some basic type annotations to API functions
2022-10-08 18:31:07 +02:00
32 changed files with 616 additions and 235 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 B

View File

@ -1,3 +1,5 @@
local enable_damage = minetest.settings:get_bool("enable_damage")
function mcl_burning.get_storage(obj)
return obj:is_player() and mcl_burning.storage[obj] or obj:get_luaentity()
end
@ -77,7 +79,7 @@ end
-- The effective burn duration is modified by obj's armor protection.
-- If obj was already burning, its burn duration is updated if the current
-- duration is less than burn_time.
-- If obj is dead, fireproof or a creative player, this function does nothing.
-- If obj is dead, fireproof or enable_damage is disabled, this function does nothing.
--
function mcl_burning.set_on_fire(obj, burn_time)
if obj:get_hp() < 0 then
@ -89,8 +91,9 @@ function mcl_burning.set_on_fire(obj, burn_time)
return
end
if obj:is_player() and minetest.is_creative_enabled(obj:get_player_name()) then
if obj:is_player() and not enable_damage then
burn_time = 0
return
else
local max_fire_prot_lvl = 0
local inv = mcl_util.get_inventory(obj)

View File

@ -16,6 +16,29 @@ local CRAMMING_DAMAGE = 3
-- Localize
local S = minetest.get_translator("mcl_mobs")
local function shortest_term_of_yaw_rotatoin(self, rot_origin, rot_target, nums)
if not rot_origin or not rot_target then
return
end
rot_origin = math.deg(rot_origin)
rot_target = math.deg(rot_target)
if math.abs(rot_target - rot_origin) < 180 then
return rot_target - rot_origin
else
if (rot_target - rot_origin) > 0 then
return 360-(rot_target - rot_origin)
else
return (rot_target - rot_origin)+360
end
end
end
-- Invisibility mod check
mcl_mobs.invis = {}
@ -309,25 +332,57 @@ local function update_roll(self)
end
-- set and return valid yaw
local set_yaw = function(self, yaw, delay, dtime)
if self.noyaw then return end
if true then
self.object:set_yaw(yaw)
return yaw
if self._kb_turn then
self._turn_to = yaw
end
--clamp our yaw to a 360 range
if math.deg(self.object:get_yaw()) > 360 then
self.object:set_yaw(math.rad(10))
elseif math.deg(self.object:get_yaw()) < 0 then
self.object:set_yaw(math.rad(350))
end
if not yaw or yaw ~= yaw then
yaw = 0
--calculate the shortest way to turn to find our target
local target_shortest_path = shortest_term_of_yaw_rotatoin(self, self.object:get_yaw(), yaw, true)
--turn in the shortest path possible toward our target. if we are attacking, don't dance.
if math.abs(target_shortest_path) > 100 and (self.attack and self.attack:get_pos() or self.following and self.following:get_pos()) then
if self.following then
target_shortest_path = shortest_term_of_yaw_rotatoin(self, self.object:get_yaw(), minetest.dir_to_yaw(vector.direction(self.object:get_pos(), self.following:get_pos())), true)
else
target_shortest_path = shortest_term_of_yaw_rotatoin(self, self.object:get_yaw(), minetest.dir_to_yaw(vector.direction(self.object:get_pos(), self.attack:get_pos())), true)
end
end
local ddtime = 0.05 --set_tick_rate
if dtime then
ddtime = dtime
end
if math.abs(target_shortest_path) > 280*ddtime then
if target_shortest_path > 0 then
self.object:set_yaw(self.object:get_yaw()+3.6*ddtime)
else
self.object:set_yaw(self.object:get_yaw()-3.6*ddtime)
end
end
delay = delay or 0
yaw = self.object:get_yaw()
if delay == 0 then
if self.shaking and dtime then
yaw = yaw + (random() * 2 - 1) * 5 * dtime
end
self.object:set_yaw(yaw)
update_roll(self)
return yaw
end
@ -412,6 +467,10 @@ local set_animation = function(self, anim, fixed_frame)
return
end
if self.jockey then
anim = "jockey"
end
if flight_check(self) and self.fly and anim == "walk" then anim = "fly" end
self._current_animation = self._current_animation or ""
@ -1910,7 +1969,6 @@ end
-- find someone to attack
local monster_attack = function(self)
if not damage_enabled
or minetest.is_creative_enabled("")
or self.passive ~= false
or self.state == "attack"
or day_docile(self) then
@ -3312,6 +3370,13 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
elseif luaentity and luaentity._knockback then
kb = kb + luaentity._knockback
end
--self._kb_turn = false
self._turn_to=self.object:get_yaw()+0.85
minetest.after(0.2, function()
if self and self.object then
self._kb_turn = true
end
end)
self.object:set_velocity({
x = dir.x * kb,
@ -3398,6 +3463,11 @@ end
local mob_detach_child = function(self, child)
if self.detach_child then
if self.detach_child(self, child) then
return
end
end
if self.driver == child then
self.driver = nil
end
@ -3670,6 +3740,9 @@ local mob_step = function(self, dtime)
end
-- smooth rotation by ThomasMonroe314
if self._turn_to then
set_yaw(self, self._turn_to, .1)
end
if self.delay and self.delay > 0 then
@ -3743,6 +3816,9 @@ local mob_step = function(self, dtime)
_locked_object_eye_height = self._locked_object:get_properties().eye_height
end
local self_rot = self.object:get_rotation()
if self.object:get_attach() then
self_rot = self.object:get_attach():get_rotation()
end
local player_pos = self._locked_object:get_pos()
local direction_player = vector.direction(vector.add(self.object:get_pos(), vector.new(0, self.head_eye_height*.7, 0)), vector.add(player_pos, vector.new(0, _locked_object_eye_height, 0)))
local mob_yaw = math.deg(-(-(self_rot.y)-(-minetest.dir_to_yaw(direction_player))))+self.head_yaw_offset
@ -4030,6 +4106,7 @@ minetest.register_entity(name, {
on_die = def.on_die,
spawn_small_alternative = def.spawn_small_alternative,
do_custom = def.do_custom,
detach_child = def.detach_child,
jump_height = def.jump_height or 4, -- was 6
rotate = math.rad(def.rotate or 0), -- 0=front, 90=side, 180=back, 270=side2
lifetimer = def.lifetimer or 57.73,

View File

@ -42,6 +42,7 @@ minetest.register_entity("mobs_mc:ender_eyes", {
})
local S = minetest.get_translator("mobs_mc")
local enable_damage = minetest.settings:get_bool("enable_damage")
local telesound = function(pos, is_source)
local snd
@ -412,7 +413,7 @@ mcl_mobs:register_mob("mobs_mc:enderman", {
-- self:teleport(nil)
-- self.state = ""
--else
if self.attack ~= nil and not minetest.settings:get_bool("creative_mode") then
if self.attack ~= nil and enable_damage then
self.state = 'attack'
end
--end

View File

@ -34,7 +34,6 @@ local skeleton = {
"mcl_bows_bow_0.png", -- bow
"mobs_mc_skeleton.png", -- skeleton
} },
visual_size = {x=1, y=1},
makes_footstep_sound = true,
textures = {
{
@ -81,11 +80,27 @@ local skeleton = {
run_speed = 30,
shoot_start = 70,
shoot_end = 90,
jockey_start = 172,
jockey_end = 172,
die_start = 160,
die_end = 170,
die_speed = 15,
die_loop = false,
},
jock = "mobs_mc:spider",
on_spawn = function(self)
self.jockey = false
if math.random(100) == 1 then -- 1% like from MCwiki
self.jockey = true
local jock = minetest.add_entity(self.object:get_pos(), "mobs_mc:spider")
jock:get_luaentity().docile_by_day = false
self.object:set_attach(jock, "", vector.new(0,0,0), vector.new(0,0,0))
end
return true
end,
on_detach=function(self, parent)
self.jockey = false
end,
ignited_by_sunlight = true,
view_range = 16,
fear_height = 4,
@ -93,6 +108,9 @@ local skeleton = {
arrow = "mcl_bows:arrow_entity",
shoot_arrow = function(self, pos, dir)
if mod_bows then
if self.attack then
self.object:set_yaw(minetest.dir_to_yaw(vector.direction(self.object:get_pos(), self.attack:get_pos())))
end
-- 2-4 damage per arrow
local dmg = math.max(4, math.random(2, 8))
mcl_bows.shoot_arrow("mcl_bows:arrow", pos, dir, self.object:get_yaw(), self.object, nil, dmg)

View File

@ -14,7 +14,7 @@ local S = minetest.get_translator("mobs_mc")
minetest.register_entity("mobs_mc:spider_eyes", {
visual = "mesh",
mesh = "mobs_mc_spider.b3d",
visual_size = {x=1.01, y=1.01},
visual_size = {x=1.01/3, y=1.01/3},
textures = {
"mobs_mc_spider_eyes.png",
},
@ -44,6 +44,7 @@ local spider = {
xp_max = 5,
armor = {fleshy = 100, arthropod = 100},
on_spawn = function(self)
self.object:set_properties({visual_size={x=1,y=1}})
local spider_eyes=false
for n = 1, #self.object:get_children() do
local obj = self.object:get_children()[n]
@ -55,6 +56,14 @@ local spider = {
minetest.add_entity(self.object:get_pos(), "mobs_mc:spider_eyes"):set_attach(self.object, "body.head", vector.new(0,-0.98,2), vector.new(90,180,180))
end
end,
on_die=function(self)
if self.object:get_children() and self.object:get_children()[1] then
self.object:get_children()[1]:set_detach()
end
end,
detach_child=function(self, child)
child:get_luaentity().jockey = false
end,
head_swivel = "Head_Control",
bone_eye_height = 1,
curiosity = 10,
@ -65,7 +74,7 @@ local spider = {
textures = {
{"mobs_mc_spider.png"},
},
visual_size = {x=3, y=3},
visual_size = {x=1, y=1},
makes_footstep_sound = false,
sounds = {
random = "mobs_mc_spider_random",

View File

@ -111,7 +111,6 @@ baby_zombie.description = S("Baby Zombie")
baby_zombie.collisionbox = {-0.25, -0.01, -0.25, 0.25, 1, 0.25}
baby_zombie.xp_min = 12
baby_zombie.xp_max = 12
baby_zombie.visual_size = {x = 1 / 2, y = 1 / 2}
baby_zombie.walk_velocity = 1.2
baby_zombie.run_velocity = 2.4
baby_zombie.child = 1

View File

@ -217,7 +217,7 @@ function awards.unlock(name, award)
-- Get award
minetest.log("action", name.." has gotten award "..award)
minetest.chat_send_all(S("@1 has made the achievement @2", name, minetest.colorize(mcl_colors.GREEN, "[" .. (awdef.title or award) .. "]")))
minetest.chat_send_all(S("@1 has made the advancement @2", name, minetest.colorize(mcl_colors.GREEN, "[" .. (awdef.title or award) .. "]")))
data.unlocked[award] = award
awards.save()
@ -257,9 +257,13 @@ function awards.unlock(name, award)
local custom_announce = awdef.custom_announce
if not custom_announce then
if awdef.secret then
custom_announce = S("Secret achievement gotten:")
custom_announce = S("Secret Advancement Made:")
elseif awdef.type == "Goal" then
custom_announce = S("Goal Completed:")
elseif awdef.type == "Challenge" then
custom_announce = S("Challenge Completed:")
else
custom_announce = S("Achievement gotten:")
custom_announce = S("Advancement Made:")
end
end
@ -283,9 +287,13 @@ function awards.unlock(name, award)
elseif awards.show_mode == "chat" then
local chat_announce
if awdef.secret == true then
chat_announce = S("Secret achievement gotten: @1")
chat_announce = S("Secret Advancement Made: @1")
elseif awdef.type == "Goal" then
chat_announce = S("Goal Completed: @1")
elseif awdef.type == "Challenge" then
chat_announce = S("Challenge Completed: @1")
else
chat_announce = S("Achievement gotten: @1")
chat_announce = S("Advancement Made: @1")
end
-- use the chat console to send it
minetest.chat_send_player(name, string.format(chat_announce, title))
@ -306,9 +314,13 @@ function awards.unlock(name, award)
})
local hud_announce
if awdef.secret == true then
hud_announce = S("Secret achievement gotten!")
hud_announce = S("Secret Advancement Made!")
elseif awdef.type == "Goal" then
hud_announce = S("Goal Completed!")
elseif awdef.type == "Challenge" then
hud_announce = S("Challenge Completed!")
else
hud_announce = S("Achievement gotten!")
hud_announce = S("Advancement Made!")
end
local two = player:hud_add({
hud_elem_type = "text",
@ -389,10 +401,10 @@ function awards.getFormspec(name, to, sid)
local def = awards.def[item.name]
if def and def.secret and not item.got then
formspec = formspec .. "label[1,2.75;"..minetest.formspec_escape(S("(Secret achievement)")).."]"..
formspec = formspec .. "label[1,2.75;"..minetest.formspec_escape(S("(Secret Advancement)")).."]"..
"image[1,0;3,3;awards_unknown.png]"
if def and def.description then
formspec = formspec .. "textarea[0.25,3.25;4.8,1.7;;"..minetest.formspec_escape(S("Get this achievement to find out what it is."))..";]"
formspec = formspec .. "textarea[0.25,3.25;4.8,1.7;;"..minetest.formspec_escape(S("Make this advancement to find out what it is."))..";]"
end
else
local title = item.name
@ -450,7 +462,7 @@ function awards.getFormspec(name, to, sid)
first = false
if def.secret and not award.got then
formspec = formspec .. "#707070" .. minetest.formspec_escape(S("(Secret Award)"))
formspec = formspec .. "#707070" .. minetest.formspec_escape(S("(Secret Advancement)"))
else
local title = award.name
if def and def.title then

View File

@ -18,7 +18,7 @@ local S = minetest.get_translator(minetest.get_current_modname())
minetest.register_chatcommand("awards", {
params = S("[c|clear|disable|enable]"),
description = S("Show, clear, disable or enable your achievements"),
description = S("Show, clear, disable or enable your advancements."),
func = function(name, param)
if param == "clear" then
if awards.player(name).disabled ~= nil then
@ -30,10 +30,10 @@ minetest.register_chatcommand("awards", {
end
elseif param == "disable" then
awards.disable(name)
minetest.chat_send_player(name, S("You have disabled your achievements."))
minetest.chat_send_player(name, S("You have disabled your advancements."))
elseif param == "enable" then
awards.enable(name)
minetest.chat_send_player(name, S("You have enabled your achievements."))
minetest.chat_send_player(name, S("You have enabled your advancements."))
elseif param == "c" then
if awards.player(name).disabled ~= nil then
minetest.chat_send_player(name, S("Awards are disabled, enable them first by using /awards enable!"))
@ -50,16 +50,16 @@ minetest.register_chatcommand("awards", {
end
})
minetest.register_privilege("achievements", {
description = S("Can give achievements to any player"),
minetest.register_privilege("advancements", {
description = S("Can give advancements to any player"),
give_to_singleplayer = false,
give_to_admin = false,
})
minetest.register_chatcommand("achievement", {
params = S("(grant <player> (<achievement> | all)) | list"),
privs = { achievements = true },
description = S("Give achievement to player or list all achievements"),
minetest.register_chatcommand("advancement", {
params = S("(grant <player> (<advancement> | all)) | list"),
privs = { advancements = true },
description = S("Give advancement to player or list all advancements"),
func = function(name, param)
if param == "list" then
local list = {}
@ -92,7 +92,7 @@ minetest.register_chatcommand("achievement", {
awards.unlock(playername, achievement)
return true, S("Done.")
else
return false, S("Achievement “@1” does not exist.", achievement)
return false, S("Advancement “@1” does not exist.", achievement)
end
end
})

View File

@ -11,9 +11,9 @@
(Secret Award)=
<achievement ID>=
<name>=
Achievement gotten!=
Achievement gotten:=
Achievement gotten: @1=
Advancement Made!=
Advancement Made:=
Advancement: @1=
Achievement not found.=
All your awards and statistics have been cleared. You can now start again.=
Awards=
@ -27,16 +27,16 @@ Join the game.=
List awards in chat (deprecated)=
Place a block: @1=
Place blocks: @1×@2=
Secret achievement gotten!=
Secret achievement gotten:=
Secret achievement gotten: @1=
Secret Advancement Made!=
Secret Advancement Made:=
Secret Advancement Made: @1=
Show details of an achievement=
Show, clear, disable or enable your achievements=
Get this achievement to find out what it is.=
Show, clear, disable or enable your advancements.=
Make this advancement to find out what it is.=
Write @1 chat messages.=
Write something in chat.=
You have disabled your achievements.=
You have enabled your achievements.=
You have disabled your advancements.=
You have enabled your advancements.=
You have not gotten any awards.=
You've disabled awards. Type /awards enable to reenable.=
[c|clear|disable|enable]=
@ -49,16 +49,22 @@ Place @1 block(s).=
Dig @1 block(s).=
Eat @1 item(s).=
Craft @1 item(s).=
Can give achievements to any player=
(grant <player> (<achievement> | all)) | list=
Give achievement to player or list all achievements=
Can give advancements to any player=
(grant <player> (<advancement> | all)) | list=
Give advancement to player or list all advancements=
@1 (@2)=
Invalid syntax.=
Invalid action.=
Player is not online.=
Done.=
Achievement “@1” does not exist.=
@1 has made the achievement @2=
Advancement “@1” does not exist.=
@1 has made the advancement @2=
Mine a block: @1=
Mine blocks: @1×@2=
Awards are disabled, enable them first by using /awards enable!=
Goal Completed:=
Goal Completed!=
Goal Completed: @1=
Challenge Completed:=
Challenge Completed!=
Challenge Completed: @1=

View File

@ -15,7 +15,9 @@ awards.register_achievement("mcl_buildWorkBench", {
type = "craft",
item = "mcl_crafting_table:crafting_table",
target = 1
}
},
type = "Advancement",
group = "Overworld",
})
awards.register_achievement("mcl:buildPickaxe", {
title = S("Time to Mine!"),
@ -25,7 +27,9 @@ awards.register_achievement("mcl:buildPickaxe", {
type = "craft",
item = "mcl_tools:pick_wood",
target = 1
}
},
type = "Advancement",
group = "Overworld",
})
awards.register_achievement("mcl:buildFurnace", {
title = S("Hot Topic"),
@ -35,7 +39,9 @@ awards.register_achievement("mcl:buildFurnace", {
type = "craft",
item = "mcl_furnaces:furnace",
target = 1
}
},
type = "Advancement",
group = "Overworld",
})
awards.register_achievement("mcl:buildHoe", {
title = S("Time to Farm!"),
@ -45,7 +51,9 @@ awards.register_achievement("mcl:buildHoe", {
type = "craft",
item = "mcl_farming:hoe_wood",
target = 1
}
},
type = "Advancement",
group = "Husbandry",
})
awards.register_achievement("mcl:makeBread", {
title = S("Bake Bread"),
@ -55,7 +63,9 @@ awards.register_achievement("mcl:makeBread", {
type = "craft",
item = "mcl_farming:bread",
target = 1
}
},
type = "Advancement",
group = "Husbandry",
})
awards.register_achievement("mcl:bakeCake", {
@ -66,7 +76,9 @@ awards.register_achievement("mcl:bakeCake", {
type = "craft",
item = "mcl_cake:cake",
target = 1
}
},
type = "Advancement",
group = "Husbandry",
})
awards.register_achievement("mcl:buildBetterPickaxe", {
title = S("Getting an Upgrade"),
@ -77,7 +89,9 @@ awards.register_achievement("mcl:buildBetterPickaxe", {
type = "craft",
item = "mcl_tools:pick_stone",
target = 1
}
},
type = "Advancement",
group = "Overworld",
})
awards.register_achievement("mcl:buildSword", {
title = S("Time to Strike!"),
@ -87,7 +101,9 @@ awards.register_achievement("mcl:buildSword", {
type = "craft",
item = "mcl_tools:sword_wood",
target = 1
}
},
type = "Advancement",
group = "Adventure",
})
awards.register_achievement("mcl:bookcase", {
@ -98,7 +114,9 @@ awards.register_achievement("mcl:bookcase", {
type = "craft",
item = "mcl_books:bookshelf",
target = 1
}
},
type = "Advancement",
group = "Overworld",
})
awards.register_achievement("mcl:buildIronPickaxe", {
@ -109,7 +127,9 @@ awards.register_achievement("mcl:buildIronPickaxe", {
type = "craft",
item = "mcl_tools:pick_iron",
target = 1
}
},
type = "Advancement",
group = "Overworld",
})
-- Item pickup achievements: These are awarded when picking up a certain item.
@ -118,46 +138,61 @@ awards.register_achievement("mcl:diamonds", {
title = S("DIAMONDS!"),
description = S("Pick up a diamond from the floor."),
icon = "mcl_core_diamond_ore.png",
type = "Advancement",
})
awards.register_achievement("mcl:blazeRod", {
title = S("Into Fire"),
description = S("Pick up a blaze rod from the floor."),
icon = "mcl_mobitems_blaze_rod.png",
type = "Advancement",
group = "Nether",
})
awards.register_achievement("mcl:killCow", {
title = S("Cow Tipper"),
description = S("Pick up leather from the floor.\nHint: Cows and some other animals have a chance to drop leather, when killed."),
icon = "mcl_mobitems_leather.png",
type = "Advancement",
group = "Adventure",
})
awards.register_achievement("mcl:mineWood", {
title = S("Getting Wood"),
description = S("Pick up a wood item from the ground.\nHint: Punch a tree trunk until it pops out as an item."),
icon = "default_tree.png",
type = "Advancement",
group = "Overworld",
})
awards.register_achievement("mcl:whosCuttingOnions", {
title = S("Who is Cutting Onions?"),
description = S("Pick up a crying obsidian from the floor."),
icon = "default_obsidian.png^mcl_core_crying_obsidian.png",
type = "Advancement",
group = "Nether",
})
awards.register_achievement("mcl:hiddenInTheDepths", {
title = S("Hidden in the Depths"),
description = S("Pick up an Ancient Debris from the floor."),
icon = "mcl_nether_ancient_debris_side.png",
type = "Advancement",
group = "Nether",
})
awards.register_achievement("mcl:PickUpDragonEgg", {
title = S("The Next Generation"),
description = S("Hold the Dragon Egg.\nHint: Pick up the egg from the ground and have it in your inventory."),
icon = "mcl_end_dragon_egg.png",
type = "Goal",
group = "End",
})
awards.register_achievement("mcl:skysTheLimit", {
title = S("Sky's the Limit"),
description = S("Find the elytra and prepare to fly above and beyond!"),
icon = "mcl_armor_inv_elytra.png",
type = "Goal",
group = "End",
}) -- TODO: Make also unlock when moved to inventory, not just picking up from ground
-- Smelting achivements: These are awarded when picking up an item from a furnace
@ -166,11 +201,15 @@ awards.register_achievement("mcl:acquireIron", {
title = S("Aquire Hardware"),
description = S("Take an iron ingot from a furnace's output slot.\nHint: To smelt an iron ingot, put a fuel (like coal) and iron ore into a furnace."),
icon = "default_steel_ingot.png",
type = "Advancement",
group = "Overworld",
})
awards.register_achievement("mcl:cookFish", {
title = S("Delicious Fish"),
description = S("Take a cooked fish from a furnace.\nHint: Use a fishing rod to catch a fish and cook it in a furnace."),
icon = "mcl_fishing_fish_cooked.png",
type = "Advancement",
group = "Husbandry",
})
-- Other achievements triggered outside of mcl_achievements
@ -180,6 +219,8 @@ awards.register_achievement("mcl:onARail", {
title = S("On A Rail"),
description = S("Travel by minecart for at least 1000 meters from your starting point in a single ride."),
icon = "default_rail.png",
type = "Challenge",
group = "Adventure",
})
-- Triggered in mcl_bows
@ -189,6 +230,8 @@ awards.register_achievement("mcl:snipeSkeleton", {
-- TODO: The range should be 50, not 20. Nerfed because of reduced bow range
description = S("Hit a skeleton, wither skeleton or stray by bow and arrow from a distance of at least 20 meters."),
icon = "mcl_bows_bow.png",
type = "Challenge",
group = "Adventure",
})
-- Triggered in mcl_portals
@ -196,18 +239,24 @@ awards.register_achievement("mcl:buildNetherPortal", {
title = S("We Need to Go Deeper"),
description = S("Use obsidian and a fire starter to construct a Nether portal."),
icon = "mcl_fire_flint_and_steel.png",
type = "Advancement",
group = "Overworld",
})
awards.register_achievement("mcl:enterEndPortal", {
title = S("The End?"),
description = S("Or the beginning?\nHint: Enter an end portal."),
icon = "mcl_end_end_stone.png",
type = "Advancement",
group = "Overworld",
})
awards.register_achievement("mcl:theNether", {
title = S("The Nether"),
description = S("Bring summer clothes.\nHint: Enter the Nether."),
icon = "mcl_nether_netherrack.png",
type = "Advancement",
group = "Nether",
})
-- Triggered in mcl_totems
@ -215,6 +264,8 @@ awards.register_achievement("mcl:postMortal", {
title = S("Postmortal"),
description = S("Use a Totem of Undying to cheat death."),
icon = "mcl_totems_totem.png",
type = "Goal",
group = "Adventure",
})
-- Triggered in mcl_beds
@ -222,12 +273,16 @@ awards.register_achievement("mcl:sweetDreams", {
title = S("Sweet Dreams"),
description = S("Sleep in a bed to change your respawn point."),
icon = "mcl_beds_bed_red_inv.png",
type = "Advancement",
group = "Adventure",
})
awards.register_achievement("mcl:notQuiteNineLives", {
title = S('Not Quite "Nine" Lives'),
description = S("Charge a Respawn Anchor to the maximum."),
icon = "respawn_anchor_side4.png",
type = "Advancement",
group = "Nether",
})
-- Triggered in mobs_mc
@ -235,24 +290,32 @@ awards.register_achievement("mcl:whatAdeal", {
title = S("What A Deal!"),
description = S("Successfully trade with a Villager."),
icon = "mcl_core_emerald.png",
type = "Advancement",
group = "Adventure",
})
awards.register_achievement("mcl:tacticalFishing", {
title = S("Tactical Fishing"),
description = S("Catch a fish... without a fishing rod!"),
icon = "pufferfish_bucket.png",
type = "Advancement",
group = "Husbandry",
})
awards.register_achievement("mcl:witheringHeights", {
title = S("Withering Heights"),
description = S("Summon the wither from the dead."),
icon = "mcl_mobitems_nether_star.png",
type = "Advancement",
group = "Nether",
})
awards.register_achievement("mcl:freeTheEnd", {
title = S("Free the End"),
description = S("Kill the ender dragon. Good Luck!"),
icon = "(spawn_egg.png^[multiply:#252525)^(spawn_egg_overlay.png^[multiply:#b313c9)", -- TODO: Dragon Head Icon
type = "Advancement",
group = "End",
})
-- Triggered in mcl_fishing
@ -260,6 +323,8 @@ awards.register_achievement("mcl:fishyBusiness", {
title = S("Fishy Business"),
description = S("Catch a fish.\nHint: Catch a fish, salmon, clownfish, or pufferfish."),
icon = "mcl_fishing_fishing_rod.png",
type = "Advancement",
group = "Husbandry",
})
-- Triggered in mcl_compass
@ -267,6 +332,8 @@ awards.register_achievement("mcl:countryLode", {
title = S("Country Lode,\nTake Me Home"),
description = S("Use a compass on a Lodestone."),
icon = "lodestone_side4.png",
type = "Advancement",
group = "Nether",
})
-- Triggered in mcl_smithing_table
@ -274,6 +341,8 @@ awards.register_achievement("mcl:seriousDedication", {
title = S("Serious Dedication"),
description = S("Use a Netherite Ingot to upgrade a hoe, and then completely reevaluate your life choices."),
icon = "farming_tool_netheritehoe.png",
type = "Challenge",
group = "Husbandry",
})
-- Triggered in mcl_brewing
@ -281,6 +350,8 @@ awards.register_achievement("mcl:localBrewery", {
title = S("Local Brewery"),
description = S("Brew a Potion.\nHint: Take a potion or glass bottle out of the brewing stand."),
icon = "mcl_potions_potion_overlay.png^[colorize:#F82423:"..tostring(127).."^mcl_potions_potion_bottle.png",
type = "Advancement",
group = "Nether",
})
-- Triggered in mcl_enchanting
@ -288,6 +359,8 @@ awards.register_achievement("mcl:enchanter", {
title = S("Enchanter"),
description = S("Enchant an item using an Enchantment Table."),
icon = "mcl_enchanting_book_enchanted.png",
type = "Advancement",
group = "Overworld",
})
--Triggered in mcl_beacons
@ -295,12 +368,16 @@ awards.register_achievement("mcl:beacon", {
title = S("Bring Home the Beacon"),
description = S("Use a beacon."),
icon = "beacon_achievement_icon.png",
type = "Advancement",
group = "Nether",
})
awards.register_achievement("mcl:maxed_beacon", {
title = S("Beaconator"),
description = S("Use a fully powered beacon."),
icon = "beacon_achievement_icon.png",
type = "Goal",
group = "Nether",
})
-- Triggered in mcl_end
@ -308,6 +385,8 @@ awards.register_achievement("mcl:theEndAgain", {
title = S("The End... Again..."),
description = S("Respawn the Ender Dragon."),
icon = "mcl_end_crystal_item.png",
type = "Goal",
group = "End",
})
-- NON-PC ACHIEVEMENTS (XBox, Pocket Edition, etc.)
@ -391,14 +470,20 @@ awards.register_achievement("mcl:stoneAge", {
title = S("Stone Age"),
description = S("Mine a stone with new pickaxe."),
icon = "default_cobble.png",
type = "Advancement",
group = "Overworld",
})
awards.register_achievement("mcl:hotStuff", {
title = S("Hot Stuff"),
description = S("Put lava in a bucket."),
icon = "bucket_lava.png",
type = "Advancement",
group = "Overworld",
})
awards.register_achievement("mcl:obsidian", {
title = S("Ice Bucket Challenge"),
description = S("Obtain an obsidian block."),
icon = "default_obsidian.png",
type = "Advancement",
group = "Overworld",
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -392,7 +392,7 @@ function mcl_inventory.set_creative_formspec(player, start_i, pagenum, inv_size,
-- Achievements button
"image_button[9,3;1,1;mcl_achievements_button.png;__mcl_achievements;]" ..
--"style_type[image_button;border=;bgimg=;bgimg_pressed=]" ..
"tooltip[__mcl_achievements;"..F(S("Achievements")) .. "]" ..
"tooltip[__mcl_achievements;"..F(S("Advancements")) .. "]" ..
-- Switch stack size button
"image_button[9,4;1,1;default_apple.png;__switch_stack;]" ..

View File

@ -119,7 +119,7 @@ local function set_inventory(player, armor_change_only)
form = form ..
-- Achievements button
"image_button[7,3;1,1;mcl_achievements_button.png;__mcl_achievements;]" ..
"tooltip[__mcl_achievements;" .. F(S("Achievements")) .. "]" ..
"tooltip[__mcl_achievements;" .. F(S("Advancements")) .. "]" ..
-- For shortcuts
"listring[current_player;main]" ..
@ -208,7 +208,6 @@ end
--Insta "digging" nodes in gamemode-creative
minetest.register_on_punchnode(function(pos, node, puncher, pointed_thing)
if not puncher or not puncher:is_player() then return end
if minetest.is_creative_enabled() then return end
local name = puncher:get_player_name()
if not minetest.is_creative_enabled(name) then return end
if pointed_thing.type ~= "node" then return end
@ -255,10 +254,13 @@ minetest.register_chatcommand("gamemode",{
privs = { server = true },
func = function(n,param)
-- Full input validation ( just for @erlehmann <3 )
local p = minetest.get_player_by_name(n)
local p
local args = param:split(" ")
if args[2] ~= nil then
p = minetest.get_player_by_name(args[2])
n = args[2]
else
p = minetest.get_player_by_name(n)
end
if not p then
return false, S("Player not online")
@ -268,6 +270,7 @@ minetest.register_chatcommand("gamemode",{
elseif args[1] ~= nil then
mcl_inventory.player_set_gamemode(p,args[1])
end
--Result message - show effective game mode
local gm = p:get_meta():get_string("gamemode")
if gm == "" then gm = gamemodes[1] end

View File

@ -2,7 +2,7 @@
Recipe book=
Help=
Select player skin=
Achievements=
Advancements=
Building Blocks=
Decoration Blocks=
Redstone=

View File

@ -11,8 +11,10 @@
--Note that the table storing timeouts use playername as index insteed of player objects (faster)
--This is intended in order to speedup the process of removing HUD elements the the timeout is up
---@type table<string, table<ObjectRef, any>>
local huds_idx = {}
---@type table<string, table<string, number>>
local hud_hide_timeouts = {}
hud_hide_timeouts.title = {}
@ -24,17 +26,19 @@ huds_idx.subtitle = {}
huds_idx.actionbar = {}
mcl_title = {}
mcl_title.defaults = {fadein = 10, stay = 70, fadeout = 20}
mcl_title.defaults = { fadein = 10, stay = 70, fadeout = 20 }
mcl_title.layout = {}
mcl_title.layout.title = {position = {x = 0.5, y = 0.5}, alignment = {x = 0, y = -1.3}, size = 7}
mcl_title.layout.subtitle = {position = {x = 0.5, y = 0.5}, alignment = {x = 0, y = 1.7}, size = 4}
mcl_title.layout.actionbar = {position = {x = 0.5, y = 1}, alignment = {x = 0, y = 0}, size = 1}
mcl_title.layout.title = { position = { x = 0.5, y = 0.5 }, alignment = { x = 0, y = -1.3 }, size = 7 }
mcl_title.layout.subtitle = { position = { x = 0.5, y = 0.5 }, alignment = { x = 0, y = 1.7 }, size = 4 }
mcl_title.layout.actionbar = { position = { x = 0.5, y = 1 }, alignment = { x = 0, y = 0 }, size = 1 }
local get_color = mcl_util.get_color
--local string = string
local pairs = pairs
---@param gametick integer
---@return number?
local function gametick_to_secondes(gametick)
if gametick then
return gametick / 20
@ -44,7 +48,10 @@ local function gametick_to_secondes(gametick)
end
--https://github.com/minetest/minetest/blob/b3b075ea02034306256b486dd45410aa765f035a/doc/lua_api.txt#L8477
--[[
---@param bold? boolean
---@param italic? boolean
---@return integer
local function style_to_bits(bold, italic)
if bold then
if italic then
@ -60,9 +67,11 @@ local function style_to_bits(bold, italic)
end
end
end
]]
--PARAMS SYSTEM
local no_style = style_to_bits(false, false)
---PARAMS SYSTEM
---@type table<ObjectRef, {stay: integer}>
local player_params = {}
minetest.register_on_joinplayer(function(player)
@ -75,34 +84,34 @@ minetest.register_on_joinplayer(function(player)
local _, hex_color = get_color("white")
huds_idx.title[player] = player:hud_add({
hud_elem_type = "text",
position = mcl_title.layout.title.position,
alignment = mcl_title.layout.title.alignment,
text = "",
--style = 0,
size = {x = mcl_title.layout.title.size},
number = hex_color,
z_index = 100,
position = mcl_title.layout.title.position,
alignment = mcl_title.layout.title.alignment,
text = "",
style = no_style,
size = { x = mcl_title.layout.title.size },
number = hex_color,
z_index = 100,
})
huds_idx.subtitle[player] = player:hud_add({
hud_elem_type = "text",
position = mcl_title.layout.subtitle.position,
alignment = mcl_title.layout.subtitle.alignment,
text = "",
--style = 0,
size = {x = mcl_title.layout.subtitle.size},
number = hex_color,
z_index = 100,
position = mcl_title.layout.subtitle.position,
alignment = mcl_title.layout.subtitle.alignment,
text = "",
style = no_style,
size = { x = mcl_title.layout.subtitle.size },
number = hex_color,
z_index = 100,
})
huds_idx.actionbar[player] = player:hud_add({
hud_elem_type = "text",
position = mcl_title.layout.actionbar.position,
offset = {x = 0, y = -210},
alignment = mcl_title.layout.actionbar.alignment,
--style = 0,
text = "",
size = {x = mcl_title.layout.actionbar.size},
number = hex_color,
z_index = 100,
position = mcl_title.layout.actionbar.position,
offset = { x = 0, y = -210 },
alignment = mcl_title.layout.actionbar.alignment,
style = no_style,
text = "",
size = { x = mcl_title.layout.actionbar.size },
number = hex_color,
z_index = 100,
})
end)
@ -123,6 +132,8 @@ minetest.register_on_leaveplayer(function(player)
hud_hide_timeouts.actionbar[playername] = nil
end)
---@param player ObjectRef
---@param data {stay: integer}
function mcl_title.params_set(player, data)
player_params[player] = {
stay = data.stay or mcl_title.defaults.stay,
@ -131,12 +142,18 @@ function mcl_title.params_set(player, data)
}
end
---@param player ObjectRef
---@return {stay: integer}
function mcl_title.params_get(player)
return player_params[player]
end
--API FUNCTIONS
---@param player ObjectRef
---@param type '"title"'|'"subtitle"'|'"actionbar"'
---@param data {text: string, color: string, stay: integer, bold: boolean, italic: boolean}
---@return boolean
function mcl_title.set(player, type, data)
if not data.color then
data.color = "white"
@ -149,20 +166,25 @@ function mcl_title.set(player, type, data)
player:hud_change(huds_idx[type][player], "text", data.text)
player:hud_change(huds_idx[type][player], "number", hex_color)
--apply bold and italic
--player:hud_change(huds_idx[type][player], "style", style_to_bits(data.bold, data.italic))
-- Apply bold and italic
player:hud_change(huds_idx[type][player], "style", style_to_bits(data.bold, data.italic))
hud_hide_timeouts[type][player:get_player_name()] = gametick_to_secondes(data.stay) or
gametick_to_secondes(mcl_title.params_get(player).stay)
hud_hide_timeouts[type][player:get_player_name()] = gametick_to_secondes(data.stay) or gametick_to_secondes(mcl_title.params_get(player).stay)
return true
end
---@param player ObjectRef?
---@param type '"title"'|'"subtitle"'|'"actionbar"'
function mcl_title.remove(player, type)
if player then
player:hud_change(huds_idx[type][player], "text", "")
--player:hud_change(huds_idx[type][player], "style", 0) --no styling
player:hud_change(huds_idx[type][player], "style", no_style)
end
end
---@param player ObjectRef
function mcl_title.clear(player)
mcl_title.remove(player, "title")
mcl_title.remove(player, "subtitle")
@ -179,6 +201,7 @@ minetest.register_globalstep(function(dtime)
subtitle = {},
actionbar = {},
}
for element, content in pairs(hud_hide_timeouts) do
for name, timeout in pairs(content) do
timeout = timeout - dtime
@ -190,47 +213,95 @@ minetest.register_globalstep(function(dtime)
end
end
end
hud_hide_timeouts = new_timeouts
end)
--DEBUG STUFF!!
--[[
--TODO:Proper /title command that can send the title to other players.
--These commands are just for debugging right now.
local dbg_msg = "Note that these are just debug commands right now. e.g. the title is only sent to he player issuing the command. Proper /title commands will be added in the future."
minetest.register_chatcommand("title", {
privs = { debug = true },
func = function(name, param)
local player = minetest.get_player_by_name(name)
mcl_title.set(player, "title", {text=param, color="gold", bold=true, italic=true})
if player then
mcl_title.set(player, "title", { text = param, color = "gold", bold = true, italic = true })
return true, dbg_msg
else
return false, dbg_msg
end
end,
})
minetest.register_chatcommand("subtitle", {
privs = { debug = true },
func = function(name, param)
local player = minetest.get_player_by_name(name)
mcl_title.set(player, "subtitle", {text=param, color="gold"})
if player then
mcl_title.set(player, "subtitle", { text = param, color = "gold" })
return true, dbg_msg
else
return false, dbg_msg
end
end,
})
minetest.register_chatcommand("actionbar", {
privs = { debug = true },
func = function(name, param)
local player = minetest.get_player_by_name(name)
mcl_title.set(player, "actionbar", {text=param, color="gold"})
if player then
mcl_title.set(player, "actionbar", { text = param, color = "gold", bold = true, italic = true })
return true, dbg_msg
else
return false, dbg_msg
end
end,
})
minetest.register_chatcommand("timeout", {
minetest.register_chatcommand("title_timeout", {
privs = { debug = true },
func = function(name, param)
local player = minetest.get_player_by_name(name)
mcl_title.params_set(player, {stay = 600})
if player then
mcl_title.params_set(player, { stay = 600 })
return true, dbg_msg
else
return false, dbg_msg
end
end,
})
minetest.register_chatcommand("all", {
minetest.register_chatcommand("title_all", {
privs = { debug = true },
func = function(name, param)
local player = minetest.get_player_by_name(name)
mcl_title.params_set(player, {stay = 600})
mcl_title.set(player, "title", {text=param, color="gold"})
mcl_title.set(player, "subtitle", {text=param, color="gold"})
mcl_title.set(player, "actionbar", {text=param, color="gold"})
if player then
mcl_title.params_set(player, { stay = 600 })
mcl_title.set(player, "title", { text = param, color = "gold" })
mcl_title.set(player, "subtitle", { text = param, color = "gold" })
mcl_title.set(player, "actionbar", { text = param, color = "gold" })
return true, dbg_msg
else
return false, dbg_msg
end
end,
})
minetest.register_chatcommand("title_all_styles", {
privs = { debug = true },
func = function(name, param)
local player = minetest.get_player_by_name(name)
if player then
mcl_title.params_set(player, { stay = 600 })
mcl_title.set(player, "title", { text = param, color = "gold" })
mcl_title.set(player, "subtitle", { text = param, color = "gold", bold = true })
mcl_title.set(player, "actionbar", { text = param, color = "gold", italic = true })
return true, dbg_msg
else
return false, dbg_msg
end
end,
})
]]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 B

After

Width:  |  Height:  |  Size: 306 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 B

After

Width:  |  Height:  |  Size: 5.6 KiB

View File

@ -342,6 +342,7 @@ mcl_torches.register_torch({
groups = {dig_immediate = 3, deco_block = 1},
sounds = mcl_sounds.node_sound_wood_defaults(),
particles = true,
flame_type = 2,
})
minetest.register_craft({

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 180 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 239 B

View File

@ -155,10 +155,17 @@ function mcl_doors:register_door(name, def)
end
local left_node = minetest.get_node(pt_left)
local mirrored = false
local door_dir = 1
if left_node.name:sub(1, #name) == name then
mirrored = true
door_dir = 2
p2 = left_node.param2
end
-- Set door nodes
minetest.set_node(pt, {name=name.."_b_1", param2=p2})
minetest.set_node(pt2, {name=name.."_t_1", param2=p2})
minetest.set_node(pt, {name=name.."_b_"..door_dir, param2=p2})
minetest.set_node(pt2, {name=name.."_t_"..door_dir, param2=p2})
if def.sounds and def.sounds.place then
minetest.sound_play(def.sounds.place, {pos=pt}, true)
@ -174,7 +181,7 @@ function mcl_doors:register_door(name, def)
local meta1 = minetest_get_meta(pt)
local meta2 = minetest_get_meta(pt2)
-- save mirror state for the correct door
if left_node.name:sub(1, #name) == name then
if mirrored then
meta1:set_int("is_mirrored", 1)
meta2:set_int("is_mirrored", 1)
end

View File

@ -2,8 +2,18 @@ local S = minetest.get_translator(minetest.get_current_modname())
local has_doc = minetest.get_modpath("doc")
mcl_flowerpots = {}
---@type table<string, string>
mcl_flowerpots.registered_pots = {}
---@type nodebox
local pot_box = {
type = "fixed",
fixed = {
{ -0.1875, -0.5, -0.1875, 0.1875, -0.125, 0.1875 },
},
}
minetest.register_node("mcl_flowerpots:flower_pot", {
description = S("Flower Pot"),
_tt_help = S("Can hold a small flower or plant"),
@ -14,23 +24,16 @@ minetest.register_node("mcl_flowerpots:flower_pot", {
tiles = {
"mcl_flowerpots_flowerpot.png",
},
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
use_texture_alpha = "clip",
visual_scale = 0.5,
wield_image = "mcl_flowerpots_flowerpot_inventory.png",
wield_scale = {x=1.0, y=1.0, z=1.0},
paramtype = "light",
sunlight_propagates = true,
selection_box = {
type = "fixed",
fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2}
},
collision_box = {
type = "fixed",
fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2}
},
selection_box = pot_box,
collision_box = pot_box,
is_ground_content = false,
inventory_image = "mcl_flowerpots_flowerpot_inventory.png",
groups = {dig_immediate=3, deco_block=1, attached_node=1, dig_by_piston=1, flower_pot=1},
groups = { dig_immediate = 3, deco_block = 1, attached_node = 1, dig_by_piston = 1, flower_pot = 1 },
sounds = mcl_sounds.node_sound_stone_defaults(),
on_rightclick = function(pos, node, clicker, itemstack)
local name = clicker:get_player_name()
@ -40,7 +43,7 @@ minetest.register_node("mcl_flowerpots:flower_pot", {
end
local item = clicker:get_wielded_item():get_name()
if mcl_flowerpots.registered_pots[item] then
minetest.swap_node(pos, {name="mcl_flowerpots:flower_pot_"..mcl_flowerpots.registered_pots[item]})
minetest.swap_node(pos, { name = "mcl_flowerpots:flower_pot_" .. mcl_flowerpots.registered_pots[item] })
if not minetest.is_creative_enabled(clicker:get_player_name()) then
itemstack:take_item()
end
@ -51,37 +54,32 @@ minetest.register_node("mcl_flowerpots:flower_pot", {
minetest.register_craft({
output = "mcl_flowerpots:flower_pot",
recipe = {
{"mcl_core:brick", "", "mcl_core:brick"},
{"", "mcl_core:brick", ""},
{"", "", ""},
}
{ "mcl_core:brick", "", "mcl_core:brick" },
{ "", "mcl_core:brick", "" },
{ "", "", "" },
},
})
---@param name string
---@param def {name: string, desc: string, image: string}
function mcl_flowerpots.register_potted_flower(name, def)
mcl_flowerpots.registered_pots[name] = def.name
minetest.register_node(":mcl_flowerpots:flower_pot_"..def.name, {
description = def.desc.." "..S("Flower Pot"),
minetest.register_node(":mcl_flowerpots:flower_pot_" .. def.name, {
description = def.desc .. " " .. S("Flower Pot"),
_doc_items_create_entry = false,
drawtype = "mesh",
mesh = "flowerpot.obj",
tiles = {
"[combine:32x32:0,0=mcl_flowerpots_flowerpot.png:0,0="..def.image,
"[combine:32x32:0,0=mcl_flowerpots_flowerpot.png:0,0=" .. def.image,
},
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
use_texture_alpha = "clip",
visual_scale = 0.5,
wield_scale = {x=1.0, y=1.0, z=1.0},
paramtype = "light",
sunlight_propagates = true,
selection_box = {
type = "fixed",
fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2}
},
collision_box = {
type = "fixed",
fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2}
},
selection_box = pot_box,
collision_box = pot_box,
is_ground_content = false,
groups = {dig_immediate=3, attached_node=1, dig_by_piston=1, not_in_creative_inventory=1, flower_pot=2},
groups = { dig_immediate = 3, attached_node = 1, dig_by_piston = 1, not_in_creative_inventory = 1, flower_pot = 2 },
sounds = mcl_sounds.node_sound_stone_defaults(),
on_rightclick = function(pos, item, clicker)
local player_name = clicker:get_player_name()
@ -89,46 +87,41 @@ function mcl_flowerpots.register_potted_flower(name, def)
minetest.record_protection_violation(pos, player_name)
return
end
minetest.add_item({x=pos.x, y=pos.y+0.5, z=pos.z}, name)
minetest.set_node(pos, {name="mcl_flowerpots:flower_pot"})
minetest.add_item(vector.offset(pos, 0, 0.5, 0), name)
minetest.set_node(pos, { name = "mcl_flowerpots:flower_pot" })
end,
drop = {
items = {
{ items = { "mcl_flowerpots:flower_pot", name } }
}
{ items = { "mcl_flowerpots:flower_pot", name } },
},
},
})
-- Add entry alias for the Help
if has_doc then
doc.add_entry_alias("nodes", "mcl_flowerpots:flower_pot", "nodes", "mcl_flowerpots:flower_pot_"..name)
doc.add_entry_alias("nodes", "mcl_flowerpots:flower_pot", "nodes", "mcl_flowerpots:flower_pot_" .. name)
end
end
---@param name string
---@param def {name: string, desc: string, image: string}
function mcl_flowerpots.register_potted_cube(name, def)
mcl_flowerpots.registered_pots[name] = def.name
minetest.register_node(":mcl_flowerpots:flower_pot_"..def.name, {
description = def.desc.." "..S("Flower Pot"),
minetest.register_node(":mcl_flowerpots:flower_pot_" .. def.name, {
description = def.desc .. " " .. S("Flower Pot"),
_doc_items_create_entry = false,
drawtype = "mesh",
mesh = "flowerpot_with_long_cube.obj",
tiles = {
def.image,
},
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "clip" or true,
use_texture_alpha = "clip",
visual_scale = 0.5,
wield_scale = {x=1.0, y=1.0, z=1.0},
paramtype = "light",
sunlight_propagates = true,
selection_box = {
type = "fixed",
fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2}
},
collision_box = {
type = "fixed",
fixed = {-0.2, -0.5, -0.2, 0.2, -0.1, 0.2}
},
selection_box = pot_box,
collision_box = pot_box,
is_ground_content = false,
groups = {dig_immediate=3, attached_node=1, dig_by_piston=1, not_in_creative_inventory=1, flower_pot=2},
groups = { dig_immediate = 3, attached_node = 1, dig_by_piston = 1, not_in_creative_inventory = 1, flower_pot = 2 },
sounds = mcl_sounds.node_sound_stone_defaults(),
on_rightclick = function(pos, item, clicker)
local player_name = ""
@ -139,18 +132,18 @@ function mcl_flowerpots.register_potted_cube(name, def)
minetest.record_protection_violation(pos, player_name)
return
end
minetest.add_item({x=pos.x, y=pos.y+0.5, z=pos.z}, name)
minetest.set_node(pos, {name="mcl_flowerpots:flower_pot"})
minetest.add_item(vector.offset(pos, 0, 0.5, 0), name)
minetest.set_node(pos, { name = "mcl_flowerpots:flower_pot" })
end,
drop = {
items = {
{ items = { "mcl_flowerpots:flower_pot", name } }
}
{ items = { "mcl_flowerpots:flower_pot", name } },
},
},
})
-- Add entry alias for the Help
if has_doc then
doc.add_entry_alias("nodes", "mcl_flowerpots:flower_pot", "nodes", "mcl_flowerpots:flower_pot_"..def.name)
doc.add_entry_alias("nodes", "mcl_flowerpots:flower_pot", "nodes", "mcl_flowerpots:flower_pot_" .. def.name)
end
end

View File

@ -1,3 +1,5 @@
local flame_texture = {"mcl_particles_flame.png", "mcl_particles_soul_fire_flame.png"}
local smoke_pdef = {
amount = 0.5,
maxexptime = 2.0,
@ -9,7 +11,8 @@ local smoke_pdef = {
maxrelpos = { x = 1/16, y = 0.06, z = 1/16 },
}
local function spawn_flames_floor(pos)
local function spawn_flames_floor(pos, flame_type)
-- Flames
mcl_particles.add_node_particlespawner(pos, {
amount = 8,
@ -22,32 +25,32 @@ local function spawn_flames_floor(pos)
maxexptime = 0.6,
minsize = 0.7,
maxsize = 2,
texture = "mcl_particles_flame.png",
texture = flame_texture[flame_type],
glow = minetest.registered_nodes[minetest.get_node(pos).name].light_source,
}, "low")
-- Smoke
mcl_particles.spawn_smoke(pos, "torch", smoke_pdef)
end
local function spawn_flames_wall(pos)
local function spawn_flames_wall(pos, flame_type)
--local minrelpos, maxrelpos
local node = minetest.get_node(pos)
local dir = minetest.wallmounted_to_dir(node.param2)
local smoke_pdef = table.copy(smoke_pdef)
if dir.x < 0 then
smoke_pdef.minrelpos = { x = -0.38, y = 0.04, z = -0.1 }
smoke_pdef.maxrelpos = { x = -0.2, y = 0.14, z = 0.1 }
smoke_pdef.minrelpos = { x = -0.38, y = 0.24, z = -0.1 }
smoke_pdef.maxrelpos = { x = -0.2, y = 0.34, z = 0.1 }
elseif dir.x > 0 then
smoke_pdef.minrelpos = { x = 0.2, y = 0.04, z = -0.1 }
smoke_pdef.maxrelpos = { x = 0.38, y = 0.14, z = 0.1 }
smoke_pdef.minrelpos = { x = 0.2, y = 0.24, z = -0.1 }
smoke_pdef.maxrelpos = { x = 0.38, y = 0.34, z = 0.1 }
elseif dir.z < 0 then
smoke_pdef.minrelpos = { x = -0.1, y = 0.04, z = -0.38 }
smoke_pdef.maxrelpos = { x = 0.1, y = 0.14, z = -0.2 }
smoke_pdef.minrelpos = { x = -0.1, y = 0.24, z = -0.38 }
smoke_pdef.maxrelpos = { x = 0.1, y = 0.34, z = -0.2 }
elseif dir.z > 0 then
smoke_pdef.minrelpos = { x = -0.1, y = 0.04, z = 0.2 }
smoke_pdef.maxrelpos = { x = 0.1, y = 0.14, z = 0.38 }
smoke_pdef.minrelpos = { x = -0.1, y = 0.24, z = 0.2 }
smoke_pdef.maxrelpos = { x = 0.1, y = 0.34, z = 0.38 }
else
return
end
@ -65,13 +68,25 @@ local function spawn_flames_wall(pos)
maxexptime = 0.6,
minsize = 0.7,
maxsize = 2,
texture = "mcl_particles_flame.png",
texture = flame_texture[flame_type],
glow = minetest.registered_nodes[node.name].light_source,
}, "low")
-- Smoke
mcl_particles.spawn_smoke(pos, "torch", smoke_pdef)
end
local function set_flames(pos, flame_type, attached_to)
if attached_to == "wall" then
return function(pos)
spawn_flames_wall(pos, flame_type)
end
end
return function(pos)
spawn_flames_floor(pos, flame_type)
end
end
local function remove_flames(pos)
mcl_particles.delete_node_particlespawners(pos)
end
@ -124,6 +139,7 @@ function mcl_torches.register_torch(def)
def.light = def.light or minetest.LIGHT_MAX
def.mesh_floor = def.mesh_floor or "mcl_torches_torch_floor.obj"
def.mesh_wall = def.mesh_wall or "mcl_torches_torch_wall.obj"
def.flame_type = def.flame_type or 1
local groups = def.groups or {}
@ -133,7 +149,8 @@ function mcl_torches.register_torch(def)
groups.dig_by_water = 1
groups.destroy_by_lava_flow = 1
groups.dig_by_piston = 1
groups.flame_type = def.flame_type or 1
local floordef = {
description = def.description,
_doc_items_longdesc = def.doc_items_longdesc,
@ -145,7 +162,6 @@ function mcl_torches.register_torch(def)
inventory_image = def.icon,
wield_image = def.icon,
tiles = def.tiles,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
paramtype = "light",
paramtype2 = "wallmounted",
sunlight_propagates = true,
@ -157,8 +173,7 @@ function mcl_torches.register_torch(def)
drop = def.drop or itemstring,
selection_box = {
type = "wallmounted",
wall_top = {-1/16, -1/16, -1/16, 1/16, 0.5, 1/16},
wall_bottom = {-1/16, -0.5, -1/16, 1/16, 1/16, 1/16},
wall_bottom = {-2/16, -0.5, -2/16, 2/16, 1/16, 2/16},
},
sounds = def.sounds,
node_placement_prediction = "",
@ -211,7 +226,7 @@ function mcl_torches.register_torch(def)
return itemstack
end,
on_rotate = false,
on_construct = def.particles and spawn_flames_floor,
on_construct = def.particles and set_flames(pos, def.flame_type, "floor"),
on_destruct = def.particles and remove_flames,
}
minetest.register_node(itemstring, floordef)
@ -223,7 +238,6 @@ function mcl_torches.register_torch(def)
drawtype = "mesh",
mesh = def.mesh_wall,
tiles = def.tiles,
use_texture_alpha = minetest.features.use_texture_alpha_string_modes and "opaque" or false,
paramtype = "light",
paramtype2 = "wallmounted",
sunlight_propagates = true,
@ -234,13 +248,11 @@ function mcl_torches.register_torch(def)
drop = def.drop or itemstring,
selection_box = {
type = "wallmounted",
wall_top = {-0.1, -0.1, -0.1, 0.1, 0.5, 0.1},
wall_bottom = {-0.1, -0.5, -0.1, 0.1, 0.1, 0.1},
wall_side = {-0.5, -0.5, -0.1, -0.2, 0.1, 0.1},
wall_side = {-0.5, -0.3, -0.1, -0.2, 0.325, 0.1},
},
sounds = def.sounds,
on_rotate = false,
on_construct = def.particles and spawn_flames_wall,
on_construct = def.particles and set_flames(pos, def.flame_type, "wall"),
on_destruct = def.particles and remove_flames,
}
minetest.register_node(itemstring_wall, walldef)
@ -259,9 +271,9 @@ minetest.register_lbm({
action = function(pos, node)
local torch_group = minetest.get_item_group(node.name, "torch")
if torch_group == 1 then
spawn_flames_floor(pos)
spawn_flames_floor(pos, minetest.get_item_group(node.name, "flame_type"))
elseif torch_group == 2 then
spawn_flames_wall(pos)
spawn_flames_wall(pos, minetest.get_item_group(node.name, "flame_type"))
end
end,
})

View File

@ -1,29 +1,72 @@
# Blender v2.76 (sub 0) OBJ File: 'torch_on_floor_node.blend'
# Blender 3.3.1
# www.blender.org
o torch_Cube_Cube.001_Cube_Cube.001_Material.001
mtllib mcl_torches_torch_floor.mtl
o cube.004
v -0.062500 0.437500 -0.500000
v -0.062500 -0.562500 -0.500000
v -0.062500 0.437500 0.500000
v -0.062500 -0.562500 0.500000
v 0.062500 0.062500 0.062500
v 0.062500 0.062500 -0.062500
v 0.062500 -0.562500 0.062500
v 0.062500 -0.562500 -0.062500
v -0.062500 0.062500 -0.062500
v -0.062500 0.062500 0.062500
v -0.062500 -0.500000 0.062500
v 0.062500 -0.500000 0.062500
v 0.062500 -0.500000 -0.062500
v -0.062500 -0.500000 -0.062500
v -0.062500 -0.562500 -0.062500
v -0.062500 -0.562500 0.062500
v 0.500000 0.437500 0.062500
v 0.500000 -0.562500 0.062500
v -0.500000 0.437500 0.062500
v -0.500000 -0.562500 0.062500
v 0.500000 0.437500 -0.062500
v 0.500000 -0.562500 -0.062500
v -0.500000 0.437500 -0.062500
v -0.500000 -0.562500 -0.062500
v 0.062500 0.437500 -0.500000
v 0.062500 -0.562500 -0.500000
v 0.062500 0.437500 0.500000
v 0.062500 -0.562500 0.500000
vn 1.0000 -0.0000 -0.0000
vn -0.0000 1.0000 -0.0000
vn -0.0000 -1.0000 -0.0000
vn -0.0000 -0.0000 -1.0000
vn -0.0000 -0.0000 1.0000
vn -1.0000 -0.0000 -0.0000
vt 1.000000 1.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 0.562500 0.500000
vt 0.562500 0.625000
vt 0.562500 0.125000
vt 0.562500 0.000063
vt 0.437500 0.625000
vt 0.437500 0.500000
vt 0.437500 0.000000
vt 0.562500 0.000000
vt 0.562500 0.125000
vt 0.437500 0.000063
vt 0.437500 0.125000
vn 0.000000 1.000000 0.000000
vn 0.000000 0.000000 -1.000000
vn 1.000000 0.000000 0.000000
s 1
f 1/1/1 2/2/1 3/3/1 4/4/1
f 5/5/1 6/6/1 7/7/1 8/8/1
f 1/2/2 6/6/2 5/5/2 4/3/2
f 2/3/3 1/2/3 6/6/3 7/5/3
f 3/2/2 2/3/2 7/5/2 8/6/2
f 4/3/3 5/5/3 8/6/3 3/2/3
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 1.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 1.000000
vt 1.000000 0.000000
s 0
usemtl m_0.002
f 3/3/1 4/4/1 1/1/1
f 4/4/1 2/2/1 1/1/1
f 9/9/2 10/10/2 6/6/2
f 10/10/2 5/5/2 6/6/2
f 12/12/3 11/11/3 7/7/3
f 11/11/3 8/8/3 7/7/3
f 13/13/4 14/14/4 15/15/4
f 14/14/4 16/16/4 15/15/4
f 19/19/5 20/20/5 17/17/5
f 20/20/5 18/18/5 17/17/5
f 21/21/6 22/22/6 23/23/6
f 22/22/6 24/24/6 23/23/6

View File

@ -1,29 +1,72 @@
# Blender v2.76 (sub 0) OBJ File: 'torch_on_wall_node.blend'
# Blender 3.3.1
# www.blender.org
o torch_wall_Cube_Cube.001_Cube_Cube.001_Material.001
v 0.062469 -0.303502 0.086070
v 0.062469 -0.195248 0.023570
v -0.062531 -0.195248 0.023570
v -0.062531 -0.303502 0.086070
v -0.062531 -0.584752 -0.401070
v 0.062469 -0.584752 -0.401070
v 0.062469 -0.476498 -0.463570
v -0.062531 -0.476498 -0.463570
mtllib mcl_torches_torch_wall.mtl
o cube
v -0.062500 -0.198340 0.273825
v -0.062500 -0.313825 0.321660
v -0.062500 -0.437517 -0.303600
v -0.062500 -0.553002 -0.255765
v 0.062500 -0.313825 0.321660
v 0.062500 -0.198340 0.273825
v 0.062500 -0.553002 -0.255765
v 0.062500 -0.437517 -0.303600
v -0.500000 -0.054833 0.620280
v -0.500000 -0.437517 -0.303600
v 0.500000 -0.054834 0.620280
v 0.500000 -0.437517 -0.303600
v -0.500000 -0.170318 0.668115
v -0.500000 -0.553002 -0.255765
v 0.500000 -0.170318 0.668115
v 0.500000 -0.553002 -0.255765
v -0.062500 -0.574516 0.835539
v -0.062500 -0.957199 -0.088340
v -0.062500 0.349364 0.452856
v -0.062500 -0.033320 -0.471024
v 0.062500 -0.574516 0.835539
v 0.062500 -0.957199 -0.088340
v 0.062500 0.349364 0.452856
v 0.062500 -0.033320 -0.471024
vn -0.0000 0.3827 0.9239
vn -0.0000 -0.3827 -0.9239
vn -0.0000 -0.9239 0.3827
vn -0.0000 0.9239 -0.3827
vn 1.0000 -0.0000 -0.0000
vn -1.0000 -0.0000 -0.0000
vt 0.562500 0.500000
vt 0.562500 0.625000
vt 0.562500 0.125000
vt 0.562500 0.000063
vt 0.437500 0.625000
vt 0.437500 0.500000
vt 0.437500 0.000000
vt 0.562500 0.000000
vt 0.562500 0.125000
vt 0.437500 0.000063
vt 0.437500 0.125000
vn 0.000000 0.500000 0.866000
vn 0.000000 0.866000 -0.500000
vn 1.000000 -0.000000 0.000000
s 1
f 1/1/1 2/2/1 3/3/1 4/4/1
f 5/5/1 6/6/1 7/7/1 8/8/1
f 1/2/2 6/6/2 5/5/2 4/3/2
f 2/3/3 1/2/3 6/6/3 7/5/3
f 3/2/2 2/3/2 7/5/2 8/6/2
f 4/3/3 5/5/3 8/6/3 3/2/3
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 1.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
vt 1.000000 1.000000
vt 1.000000 0.000000
vt 1.000000 1.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 0.000000 0.000000
s 0
usemtl m_0.001
f 5/5/1 6/6/1 2/2/1
f 6/6/1 1/1/1 2/2/1
f 8/8/2 7/7/2 3/3/2
f 7/7/2 4/4/2 3/3/2
f 9/9/3 10/10/3 11/11/3
f 10/10/3 12/12/3 11/11/3
f 15/15/4 16/16/4 13/13/4
f 16/16/4 14/14/4 13/13/4
f 17/17/5 18/18/5 19/19/5
f 18/18/5 20/20/5 19/19/5
f 23/23/6 24/24/6 21/21/6
f 24/24/6 22/22/6 21/21/6

View File

@ -15,6 +15,7 @@ mcl_torches.register_torch({
groups = {dig_immediate = 3, deco_block = 1},
sounds = mcl_sounds.node_sound_wood_defaults(),
particles = true,
flame_type = 1,
})
minetest.register_craft({

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

After

Width:  |  Height:  |  Size: 184 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 197 B

After

Width:  |  Height:  |  Size: 199 B

View File

@ -605,9 +605,6 @@ end)
-- Don't change HP if the player falls in the water or through End Portal:
mcl_damage.register_modifier(function(obj, damage, reason)
if reason.type == "fall" then
if minetest.is_creative_enabled(obj:get_player_name()) then
return 0
end
local pos = obj:get_pos()
local node = minetest.get_node(pos)
local velocity = obj:get_velocity() or obj:get_player_velocity() or {x=0,y=-10,z=0}