From ce65c8ee753414f80fc7fd4474cc41c447cffcf7 Mon Sep 17 00:00:00 2001
From: teknomunk <teknomunk@protonmail.com>
Date: Sun, 5 May 2024 13:25:19 +0000
Subject: [PATCH] Add bubble columns, apply environmental physics to players

---
 mods/ITEMS/vl_bubble_column/init.lua | 95 ++++++++++++++++++++++++++++
 mods/ITEMS/vl_bubble_column/mod.conf |  4 ++
 mods/PLAYER/mcl_playerplus/init.lua  |  4 ++
 mods/PLAYER/mcl_playerplus/mod.conf  |  2 +-
 4 files changed, 104 insertions(+), 1 deletion(-)
 create mode 100644 mods/ITEMS/vl_bubble_column/init.lua
 create mode 100644 mods/ITEMS/vl_bubble_column/mod.conf

diff --git a/mods/ITEMS/vl_bubble_column/init.lua b/mods/ITEMS/vl_bubble_column/init.lua
new file mode 100644
index 000000000..12a0f60c9
--- /dev/null
+++ b/mods/ITEMS/vl_bubble_column/init.lua
@@ -0,0 +1,95 @@
+local S = minetest.get_translator(minetest.get_current_modname())
+
+local WATER_VISC = 1
+local USE_TEXTURE_ALPHA = true
+if minetest.features.use_texture_alpha_string_modes then
+	USE_TEXTURE_ALPHA = "blend"
+end
+
+local positions = {}
+local function check_bubble_column(pos, node)
+	local below_pos = vector.offset(pos,0,-1,0)
+	local below = minetest.get_node(below_pos)
+	if below.name == "mcl_nether:soul_sand" or below.name == "mcl_nether:magma" then
+		return true
+	end
+
+	if below.name == "mcl_core:water_source" and positions[minetest.hash_node_position(below_pos)] then
+		return true
+	end
+
+	print("Tearing down bubble column at "..vector.to_string(pos))
+
+	local pos_hash = minetest.hash_node_position(pos)
+
+	-- Don't continue upwards if this already wasn't a bubble column
+	if not positions[pos_hash] then return end
+
+	-- Remove this node from the columnpositions
+	positions[pos_hash] = nil
+
+	pos = vector.offset(pos,0,1,0)
+
+	node = minetest.get_node(pos)
+	return check_bubble_column(pos,node)
+end
+
+minetest.register_abm({
+	label = "Create Bubble Column",
+	interval = 1,
+	chance = 1,
+	nodenames = { "mcl_nether:soul_sand", "mcl_nether:magma" },
+	neighbors = { "mcl_core:water_source" },
+	action = function(pos, node)
+		local above_pos = vector.offset(pos,0,1,0)
+		local above = minetest.get_node(above_pos)
+		if above.name ~= "mcl_core:water_source" then return end
+
+		local direction = 1
+		if node.name == "mcl_nether:magma" then
+			direction = -1
+		end
+
+		-- Create the bubble column
+		while above.name == "mcl_core:water_source" do
+			local above_pos_hash = minetest.hash_node_position(above_pos)
+			if positions[above_pos_hash] == direction then return end
+			positions[above_pos_hash] = direction
+
+			above_pos = vector.offset(above_pos,0,1,0)
+			above = minetest.get_node(above_pos)
+		end
+	end
+})
+local BUBBLE_TIME = 0.5
+local BUBBLE_PARTICLE = {
+	texture = "mcl_particles_bubble.png",
+	collision_removal = false,
+	expirationtime = BUBBLE_TIME,
+	collisiondetection = false,
+	size = 2.5,
+}
+minetest.register_globalstep(function(dtime)
+	for hash,dir in pairs(positions) do
+		if math.random(1,17) == 1 then
+			local pos = minetest.get_position_from_hash(hash)
+			local node = minetest.get_node(pos)
+			if check_bubble_column(pos, node) then
+				local particle = table.copy(BUBBLE_PARTICLE)
+				particle.pos          =  vector.offset(pos, math.random(-28,28)/64, -0.51 * dir, math.random(-28,28)/64)
+				particle.velocity     = (vector.offset(pos, math.random(-28,28)/64,  0.51 * dir, math.random(-28,28)/64) - particle.pos) / BUBBLE_TIME
+				particle.acceleration = vector.zero()
+				minetest.add_particle(particle)
+			end
+		end
+	end
+end)
+vl_physics.register_environment_effect(function(pos, vel, staticdata, entity)
+	local pos_r = vector.round(pos)
+	local pos_r_hash = minetest.hash_node_position(pos_r)
+	local dir = positions[pos_r_hash]
+	if not dir then return nil,nil end
+
+	return vector.new(0,4*dir,0),vector.new(0,9*dir,0)
+end)
+
diff --git a/mods/ITEMS/vl_bubble_column/mod.conf b/mods/ITEMS/vl_bubble_column/mod.conf
new file mode 100644
index 000000000..971a6465d
--- /dev/null
+++ b/mods/ITEMS/vl_bubble_column/mod.conf
@@ -0,0 +1,4 @@
+name = vl_bubble_column
+author = teknomunk
+description = Bubble Column
+depends = mcl_sounds, vl_physics
diff --git a/mods/PLAYER/mcl_playerplus/init.lua b/mods/PLAYER/mcl_playerplus/init.lua
index 1707108f8..02ff8e775 100644
--- a/mods/PLAYER/mcl_playerplus/init.lua
+++ b/mods/PLAYER/mcl_playerplus/init.lua
@@ -179,6 +179,10 @@ minetest.register_globalstep(function(dtime)
 
 		local c_x, c_y = unpack(player_collision(player))
 
+		-- Apply enviornmental physics effects
+		local v,a = vl_physics.get_environment_effect(player:get_pos(), player_velocity, {}, 1, player)
+		if v then player:add_velocity(v) end
+
 		if player_velocity.x + player_velocity.y < .5 and c_x + c_y > 0 then
 			player:add_velocity({x = c_x, y = 0, z = c_y})
 			player_velocity = player:get_velocity() or player:get_player_velocity()
diff --git a/mods/PLAYER/mcl_playerplus/mod.conf b/mods/PLAYER/mcl_playerplus/mod.conf
index 953ea9403..db3ca2918 100644
--- a/mods/PLAYER/mcl_playerplus/mod.conf
+++ b/mods/PLAYER/mcl_playerplus/mod.conf
@@ -1,5 +1,5 @@
 name = mcl_playerplus
 author = TenPlus1
 description = Adds some simple player-related gameplay effects: Hurt by touching a cactus, suffocation and more.
-depends = mcl_init, mcl_core, mcl_particles, mcl_hunger, playerphysics, mcl_playerinfo, mcl_weather, mcl_spawn, mcl_enchanting, mcl_damage, mcl_sprint, mcl_util, mcl_shields
+depends = mcl_init, mcl_core, mcl_particles, mcl_hunger, playerphysics, mcl_playerinfo, mcl_weather, mcl_spawn, mcl_enchanting, mcl_damage, mcl_sprint, mcl_util, mcl_shields, vl_physics