From 436d2fd2d12485fab2a8ea8eb33c415525c513de Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Fri, 22 Mar 2024 13:02:43 +0100 Subject: [PATCH 1/9] Make bed head pointable --- mods/rp_bed/init.lua | 206 +++++++++++++++++++++++++------------------ 1 file changed, 122 insertions(+), 84 deletions(-) diff --git a/mods/rp_bed/init.lua b/mods/rp_bed/init.lua index d1006825..f5463381 100644 --- a/mods/rp_bed/init.lua +++ b/mods/rp_bed/init.lua @@ -459,6 +459,79 @@ local sounds = rp_sounds.node_sound_planks_defaults({ place = {name="rp_sounds_place_planks", gain=1.0, pitch=0.8}, }) +local on_rightclick_bed_foot = function(pos, node, clicker, itemstack) + if not clicker:is_player() then + return itemstack + end + + local clicker_name = clicker:get_player_name() + + local sleeper_name = get_player_in_bed(pos) + + if clicker_name == sleeper_name then + take_player_from_bed(clicker) + elseif sleeper_name == nil and not rp_player.player_attached[clicker_name] + and bed.userdata.temp[clicker_name].in_bed == false then + if not minetest.settings:get_bool("bed_enable", true) then + minetest.chat_send_player(clicker_name, minetest.colorize("#FFFF00", S("Sleeping is disabled."))) + return itemstack + end + + local dir = minetest.fourdir_to_dir(node.param2) + local above_posses = { + {x=pos.x, y=pos.y+1, z=pos.z}, + vector.add({x=pos.x, y=pos.y+1, z=pos.z}, dir), + {x=pos.x, y=pos.y+2, z=pos.z}, + vector.add({x=pos.x, y=pos.y+2, z=pos.z}, dir), + } + for a=1,#above_posses do + local apos = above_posses[a] + local anode = minetest.get_node(apos) + local is_spawnable, fail_reason = node_is_spawnable_in(anode, true) + if not is_spawnable then + local msg + if fail_reason == "damage" then + msg = S("It’s too painful to sleep here!") + elseif fail_reason == "drowning" then + msg = S("You can’t sleep while holding your breath!") + elseif fail_reason == "blocked" then + msg = S("Not enough space to sleep!") + else + msg = S("You can’t sleep here!") + end + minetest.chat_send_player(clicker_name, minetest.colorize("#FFFF00", msg)) + return itemstack + end + end + + -- No sleeping while moving + if vector.length(clicker:get_velocity()) > 0.001 then + minetest.chat_send_player(clicker_name, minetest.colorize("#FFFF00", S("You have to stop moving before going to bed!"))) + return itemstack + end + + local put_pos = table.copy(pos) + + local yaw = (-(node.param2 / 2.0) * math.pi) + math.pi + + bed.userdata.temp[clicker_name].in_bed = true + + local changed = bed.set_spawn(clicker, put_pos) + if changed then + minetest.chat_send_player(clicker_name, minetest.colorize("#00FFFF", S("Respawn position set!"))) + end + + bed.userdata.temp[clicker_name].node_pos = pos + local sleep_pos = vector.add(pos, vector.divide(minetest.fourdir_to_dir(node.param2), 2)) + bed.userdata.temp[clicker_name].sleep_pos = sleep_pos + + set_bed_occupier(pos, clicker_name) + + put_player_in_bed(clicker) + end + return itemstack +end + minetest.register_node( "rp_bed:bed_foot", { @@ -495,12 +568,9 @@ minetest.register_node( type = "fixed", fixed = {-0.5, -0.5, -0.5, 0.5, 2/16, 0.5} }, - selection_box = { - type = "fixed", - fixed = {-0.5, -0.5, -0.5, 0.5, 2/16, 1.5} - }, node_placement_prediction = "", + on_rightclick = on_rightclick_bed_foot, on_place = function(itemstack, placer, pointed_thing) local under = pointed_thing.under @@ -571,8 +641,9 @@ minetest.register_node( end set_bed_occupier(pos, nil) - local node = minetest.get_node(pos) - local dir = minetest.fourdir_to_dir(node.param2) + end, + after_destruct = function(pos, oldnode) + local dir = minetest.fourdir_to_dir(oldnode.param2) local head_pos = vector.add(pos, dir) if minetest.get_node(head_pos).name == "rp_bed:bed_head" then minetest.remove_node(head_pos) @@ -580,84 +651,11 @@ minetest.register_node( end end, on_blast = function(pos) - -- Needed to force on_destruct to be called + -- Needed to force on_destruct/after_destruct to be called minetest.remove_node(pos) minetest.check_for_falling({x=pos.x, y=pos.y+1, z=pos.z}) end, - on_rightclick = function(pos, node, clicker, itemstack) - if not clicker:is_player() then - return itemstack - end - - local clicker_name = clicker:get_player_name() - - local sleeper_name = get_player_in_bed(pos) - - if clicker_name == sleeper_name then - take_player_from_bed(clicker) - elseif sleeper_name == nil and not rp_player.player_attached[clicker_name] - and bed.userdata.temp[clicker_name].in_bed == false then - if not minetest.settings:get_bool("bed_enable", true) then - minetest.chat_send_player(clicker_name, minetest.colorize("#FFFF00", S("Sleeping is disabled."))) - return itemstack - end - - local dir = minetest.fourdir_to_dir(node.param2) - local above_posses = { - {x=pos.x, y=pos.y+1, z=pos.z}, - vector.add({x=pos.x, y=pos.y+1, z=pos.z}, dir), - {x=pos.x, y=pos.y+2, z=pos.z}, - vector.add({x=pos.x, y=pos.y+2, z=pos.z}, dir), - } - for a=1,#above_posses do - local apos = above_posses[a] - local anode = minetest.get_node(apos) - local is_spawnable, fail_reason = node_is_spawnable_in(anode, true) - if not is_spawnable then - local msg - if fail_reason == "damage" then - msg = S("It’s too painful to sleep here!") - elseif fail_reason == "drowning" then - msg = S("You can’t sleep while holding your breath!") - elseif fail_reason == "blocked" then - msg = S("Not enough space to sleep!") - else - msg = S("You can’t sleep here!") - end - minetest.chat_send_player(clicker_name, minetest.colorize("#FFFF00", msg)) - return itemstack - end - end - - -- No sleeping while moving - if vector.length(clicker:get_velocity()) > 0.001 then - minetest.chat_send_player(clicker_name, minetest.colorize("#FFFF00", S("You have to stop moving before going to bed!"))) - return itemstack - end - - local put_pos = table.copy(pos) - - local yaw = (-(node.param2 / 2.0) * math.pi) + math.pi - - bed.userdata.temp[clicker_name].in_bed = true - - local changed = bed.set_spawn(clicker, put_pos) - if changed then - minetest.chat_send_player(clicker_name, minetest.colorize("#00FFFF", S("Respawn position set!"))) - end - - bed.userdata.temp[clicker_name].node_pos = pos - local sleep_pos = vector.add(pos, vector.divide(minetest.fourdir_to_dir(node.param2), 2)) - bed.userdata.temp[clicker_name].sleep_pos = sleep_pos - - set_bed_occupier(pos, clicker_name) - - put_player_in_bed(clicker) - end - return itemstack - end, - can_dig = function(pos) local sleeper = get_player_in_bed(pos) return sleeper == nil @@ -686,8 +684,6 @@ minetest.register_node( paramtype2 = "color4dir", palette = "bed_palette.png", is_ground_content = false, - pointable = false, - diggable = false, tiles = { "bed_head.png", @@ -706,13 +702,55 @@ minetest.register_node( {name="bed_inside_overlay.png",color="white"}, }, use_texture_alpha = "clip", - groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 1, fall_damage_add_percent = -15, not_in_creative_inventory = 1 }, + groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3, bed = 1, fall_damage_add_percent = -15, not_in_creative_inventory = 1, paintable = 1 }, sounds = sounds, node_box = { type = "fixed", fixed = {-0.5, -0.5, -0.5, 0.5, 2/16, 0.5} }, - on_blast = function() end, + + on_rightclick = function(pos, node, clicker, itemstack) + local dir = minetest.fourdir_to_dir(node.param2) + local foot_pos = vector.subtract(pos, dir) + local foot_node = minetest.get_node(foot_pos) + if foot_node.name == "rp_bed:bed_foot" then + return on_rightclick_bed_foot(foot_pos, foot_node, clicker, itemstack) + end + return itemstack + end, + + after_destruct = function(pos, oldnode) + local dir = minetest.fourdir_to_dir(oldnode.param2) + local foot_pos = vector.subtract(pos, dir) + if minetest.get_node(foot_pos).name == "rp_bed:bed_foot" then + minetest.remove_node(foot_pos) + end + end, + + on_blast = function(pos) + -- Needed to force after_destruct to be called + minetest.remove_node(pos) + minetest.check_for_falling({x=pos.x, y=pos.y+1, z=pos.z}) + end, + + can_dig = function(pos) + local node = minetest.get_node(pos) + local dir = minetest.fourdir_to_dir(node.param2) + local foot_pos = vector.subtract(pos, dir) + local sleeper = get_player_in_bed(foot_pos) + return sleeper == nil + end, + + -- Paint support for rp_paint mod + _on_paint = function(pos, new_param2) + local node = minetest.get_node(pos) + local dir = minetest.fourdir_to_dir(node.param2) + local foot_pos = vector.subtract(pos, dir) + if minetest.get_node(foot_pos).name == "rp_bed:bed_foot" then + minetest.swap_node(foot_pos, {name = "rp_bed:bed_foot", param2=new_param2}) + end + return true + end, drop = "", }) From 70b1e1f543c3437d13001a94a0cf88d0a391f75a Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 17 Apr 2024 12:42:43 +0200 Subject: [PATCH 2/9] Apply slight offset when laying in bed To fix pointing issues --- mods/rp_bed/init.lua | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/mods/rp_bed/init.lua b/mods/rp_bed/init.lua index f5463381..45291126 100644 --- a/mods/rp_bed/init.lua +++ b/mods/rp_bed/init.lua @@ -8,6 +8,7 @@ local S = minetest.get_translator("rp_bed") local bed = {} local DEFAULT_BED_COLOR = rp_paint.COLOR_AZURE_BLUE +local BED_EYE_OFFSET_Y = -13 -- Per-user data table @@ -104,7 +105,7 @@ local function put_player_in_bed(player) player_effects.apply_effect(player, "inbed") - player:set_eye_offset(vector.new(0, -13, 0), vector.new(0, -13, 0)) + player:set_eye_offset(vector.new(0, BED_EYE_OFFSET_Y, 0), vector.new(0, BED_EYE_OFFSET_Y, 0)) player:set_local_animation( {x=162, y=166}, {x=162, y=166}, @@ -522,7 +523,7 @@ local on_rightclick_bed_foot = function(pos, node, clicker, itemstack) end bed.userdata.temp[clicker_name].node_pos = pos - local sleep_pos = vector.add(pos, vector.divide(minetest.fourdir_to_dir(node.param2), 2)) + local sleep_pos = vector.add(pos, vector.multiply(minetest.fourdir_to_dir(node.param2), 0.49)) bed.userdata.temp[clicker_name].sleep_pos = sleep_pos set_bed_occupier(pos, clicker_name) From b0fff0e595718cdc2e932c8963844a59646a647d Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 17 Apr 2024 12:54:37 +0200 Subject: [PATCH 3/9] Allow sleeper to dig their own bed --- mods/rp_bed/init.lua | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/mods/rp_bed/init.lua b/mods/rp_bed/init.lua index 45291126..937f6999 100644 --- a/mods/rp_bed/init.lua +++ b/mods/rp_bed/init.lua @@ -657,9 +657,17 @@ minetest.register_node( minetest.check_for_falling({x=pos.x, y=pos.y+1, z=pos.z}) end, - can_dig = function(pos) - local sleeper = get_player_in_bed(pos) - return sleeper == nil + -- Can be dug if no sleeper or digger equaals sleeper + can_dig = function(pos, digger) + local sleeper_name = get_player_in_bed(pos) + if not sleeper_name then + return true + end + local sleeper = minetest.get_player_by_name(sleeper_name) + if (not digger) or (not sleeper) or (digger and digger:is_player() and sleeper == digger) then + return true + end + return false end, -- Paint support for rp_paint mod @@ -734,12 +742,23 @@ minetest.register_node( minetest.check_for_falling({x=pos.x, y=pos.y+1, z=pos.z}) end, - can_dig = function(pos) + -- Can be dug if no sleeper or digger equaals sleeper + can_dig = function(pos, digger) local node = minetest.get_node(pos) local dir = minetest.fourdir_to_dir(node.param2) local foot_pos = vector.subtract(pos, dir) - local sleeper = get_player_in_bed(foot_pos) - return sleeper == nil + local sleeper_name = get_player_in_bed(foot_pos) + if not sleeper_name then + return true + end + local sleeper = minetest.get_player_by_name(sleeper_name) + if (not digger) or (not sleeper) or (digger and digger:is_player() and sleeper == digger) then + return true + end + if sleeper and sleeper:is_player() and digger and digger:is_player() and sleeper == digger then + return true + end + return false end, -- Paint support for rp_paint mod From 946f1b3d2d441af12299e275ca40f8737b028d1b Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 17 Apr 2024 13:04:36 +0200 Subject: [PATCH 4/9] Can get up from bed with Sneak key --- mods/rp_bed/init.lua | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/mods/rp_bed/init.lua b/mods/rp_bed/init.lua index 937f6999..007cc32e 100644 --- a/mods/rp_bed/init.lua +++ b/mods/rp_bed/init.lua @@ -58,7 +58,7 @@ local saving = false -- Timer -local timer_interval = 1 +local TIMER_INTERVAL = 1 local timer = 0 local delay_daytime = false @@ -362,25 +362,34 @@ end local function on_globalstep(dtime) timer = timer + dtime - if timer < timer_interval then - return - end - - timer = 0 - local sleeping_players = 0 + -- Count number of sleeping players; + -- also check for Sneak key local in_bed = {} for name, data in pairs(bed.userdata.temp) do if data.in_bed then local player = minetest.get_player_by_name(name) if player then - table.insert(in_bed, name) - sleeping_players = sleeping_players + 1 + local ctrl = player:get_player_control() + -- Get up from bed if holding down Sneak + if ctrl and ctrl.sneak then + take_player_from_bed(player) + -- Count player + else + table.insert(in_bed, name) + sleeping_players = sleeping_players + 1 + end end end end + -- Reduce load of the following section + if timer < TIMER_INTERVAL then + return + end + timer = 0 + local players = minetest.get_connected_players() local player_count = #players From 9ffcd9524168663c31d2313823164750615f1ff5 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 17 Apr 2024 13:05:26 +0200 Subject: [PATCH 5/9] Update manual for bed sneak --- manual_generator/content/home.md | 46 ++++++++++++++++++++++++++++++ manual_generator/content/manual.md | 2 +- 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 manual_generator/content/home.md diff --git a/manual_generator/content/home.md b/manual_generator/content/home.md new file mode 100644 index 00000000..74d39ff8 --- /dev/null +++ b/manual_generator/content/home.md @@ -0,0 +1,46 @@ ++++ +title = "Repixture" ++++ + +![](/assets/images/repixture.png) + +Welcome to Repixture! + +### Survive + +![](/assets/screenshots/survive.png) + +### Explore + +![](/assets/screenshots/explore.png) + +### Build + +![](/assets/screenshots/build.png) + +### Decorate + +![](/assets/screenshots/decorate.png) + +### Achieve + +![](/assets/screenshots/achieve.png) + +### And more! + +![](/assets/screenshots/and_more.png) + + +## Features + +Blabla. + +## Player Manual + +Read the [Player Manual](/manual) to learn how to play. + +## Links + +* Download page (ContentDB) +* Forum discussion +* Code repository diff --git a/manual_generator/content/manual.md b/manual_generator/content/manual.md index feffbbe9..5ba396cf 100644 --- a/manual_generator/content/manual.md +++ b/manual_generator/content/manual.md @@ -83,7 +83,7 @@ Repixture recognizes the following game-related controls offered by Minetest: * Look around * Left / Right / Forwards / Backwards * Jump -* Sneak (also unmounts you on boats) +* Sneak (also unmounts you on boats and gets you up from a bed) * Drop item * Punch (see below) * Place (see below) From 4b2af985f0d2e52a72fa265e043faff91695b72a Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 17 Apr 2024 13:17:30 +0200 Subject: [PATCH 6/9] Remove bed placement hack at invalid bed node --- mods/rp_bed/init.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mods/rp_bed/init.lua b/mods/rp_bed/init.lua index 007cc32e..52c1c4dc 100644 --- a/mods/rp_bed/init.lua +++ b/mods/rp_bed/init.lua @@ -623,8 +623,8 @@ minetest.register_node( local bot = minetest.get_node(botpos) local botdef = minetest.registered_nodes[bot.name] - -- Check if the 2nd node for the bed is free or already a bed head. - if not (bot.name == "rp_bed:bed_head" and bot.param2 == dir) and (not botdef or not botdef.buildable_to) then + -- Check if the 2nd node for the bed is free to build to + if not botdef or not botdef.buildable_to then rp_sounds.play_place_failed_sound(placer) return itemstack end From 73ae4ec8edeaa16870678f41880a7c76c452b42e Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 17 Apr 2024 13:55:35 +0200 Subject: [PATCH 7/9] Add on_dig event for digging bed head --- mods/rp_bed/init.lua | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/mods/rp_bed/init.lua b/mods/rp_bed/init.lua index 52c1c4dc..9ce661a1 100644 --- a/mods/rp_bed/init.lua +++ b/mods/rp_bed/init.lua @@ -745,6 +745,24 @@ minetest.register_node( end end, + on_dig = function(pos, node, digger) + -- Drop bed if neccessary + local dir = minetest.fourdir_to_dir(node.param2) + local foot_pos = vector.subtract(pos, dir) + if minetest.get_node(foot_pos).name == "rp_bed:bed_foot" then + local item = ItemStack("rp_bed:bed_foot") + if digger and digger:is_player() and minetest.is_creative_enabled(digger:get_player_name()) then + local inv = digger:get_inventory() + if not inv:contains_item("main", item) then + inv:add_item("main", item) + end + else + minetest.add_item(foot_pos, item) + end + end + return minetest.node_dig(pos, node, digger) + end, + on_blast = function(pos) -- Needed to force after_destruct to be called minetest.remove_node(pos) From 4ade1c4bbc35fa1ae5c3bd7a67934827cc434789 Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 17 Apr 2024 14:09:18 +0200 Subject: [PATCH 8/9] Bed: Drop bed by function call only --- mods/rp_bed/init.lua | 59 +++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 22 deletions(-) diff --git a/mods/rp_bed/init.lua b/mods/rp_bed/init.lua index 9ce661a1..29cf80c8 100644 --- a/mods/rp_bed/init.lua +++ b/mods/rp_bed/init.lua @@ -38,7 +38,7 @@ bed.set_spawn = function(player, spawn_pos) local name = player:get_player_name() local old_spawn_pos = bed.userdata.saved[name].spawn_pos if old_spawn_pos and vector.equals(spawn_pos, old_spawn_pos) then - return false + return false end bed.userdata.saved[name].spawn_pos = table.copy(spawn_pos) minetest.log("action", "[rp_bed] Respawn position of "..name.." set to "..minetest.pos_to_string(spawn_pos, 1)) @@ -542,6 +542,18 @@ local on_rightclick_bed_foot = function(pos, node, clicker, itemstack) return itemstack end +local function drop_bed(pos, player) + local item = ItemStack("rp_bed:bed_foot") + if player and player:is_player() and minetest.is_creative_enabled(player:get_player_name()) then + local inv = player:get_inventory() + if not inv:contains_item("main", item) then + inv:add_item("main", item) + end + else + minetest.add_item(pos, item) + end +end + minetest.register_node( "rp_bed:bed_foot", { @@ -679,6 +691,18 @@ minetest.register_node( return false end, + on_dig = function(pos, node, digger) + -- Drop bed if neccessary + local dir = minetest.fourdir_to_dir(node.param2) + local head_pos = vector.add(pos, dir) + if minetest.get_node(head_pos).name == "rp_bed:bed_head" then + drop_bed(pos, digger) + end + return minetest.node_dig(pos, node, digger) + end, + + + -- Paint support for rp_paint mod _on_paint = function(pos, new_param2) local node = minetest.get_node(pos) @@ -690,8 +714,8 @@ minetest.register_node( return true end, - -- Drop itself, but without metadata - drop = "rp_bed:bed_foot", + -- Drop is handled in on_dig + drop = "", }) minetest.register_node( @@ -745,25 +769,7 @@ minetest.register_node( end end, - on_dig = function(pos, node, digger) - -- Drop bed if neccessary - local dir = minetest.fourdir_to_dir(node.param2) - local foot_pos = vector.subtract(pos, dir) - if minetest.get_node(foot_pos).name == "rp_bed:bed_foot" then - local item = ItemStack("rp_bed:bed_foot") - if digger and digger:is_player() and minetest.is_creative_enabled(digger:get_player_name()) then - local inv = digger:get_inventory() - if not inv:contains_item("main", item) then - inv:add_item("main", item) - end - else - minetest.add_item(foot_pos, item) - end - end - return minetest.node_dig(pos, node, digger) - end, - - on_blast = function(pos) + on_blast = function(pos) -- Needed to force after_destruct to be called minetest.remove_node(pos) minetest.check_for_falling({x=pos.x, y=pos.y+1, z=pos.z}) @@ -787,6 +793,15 @@ minetest.register_node( end return false end, + on_dig = function(pos, node, digger) + -- Drop bed if neccessary + local dir = minetest.fourdir_to_dir(node.param2) + local foot_pos = vector.subtract(pos, dir) + if minetest.get_node(foot_pos).name == "rp_bed:bed_foot" then + drop_bed(foot_pos, digger) + end + return minetest.node_dig(pos, node, digger) + end, -- Paint support for rp_paint mod _on_paint = function(pos, new_param2) From cc8357f9b06051b2150869525812981681947f8e Mon Sep 17 00:00:00 2001 From: Wuzzy Date: Wed, 17 Apr 2024 14:13:40 +0200 Subject: [PATCH 9/9] Can't sleep in bed foot only --- mods/rp_bed/init.lua | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/mods/rp_bed/init.lua b/mods/rp_bed/init.lua index 29cf80c8..46a03f32 100644 --- a/mods/rp_bed/init.lua +++ b/mods/rp_bed/init.lua @@ -592,7 +592,17 @@ minetest.register_node( }, node_placement_prediction = "", - on_rightclick = on_rightclick_bed_foot, + on_rightclick = function(pos, node, clicker, itemstack) + local dir = minetest.fourdir_to_dir(node.param2) + local head_pos = vector.add(pos, dir) + local head_node = minetest.get_node(head_pos) + -- Make sure the bed is complete + if head_node.name == "rp_bed:bed_head" then + return on_rightclick_bed_foot(pos, node, clicker, itemstack) + end + return itemstack + end, + on_place = function(itemstack, placer, pointed_thing) local under = pointed_thing.under