Skip to content

Commit

Permalink
winterize improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
LoneWolfHT committed Dec 5, 2024
1 parent 7db622a commit 30f7e0a
Showing 1 changed file with 110 additions and 114 deletions.
224 changes: 110 additions & 114 deletions winterize/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,15 @@ local grasses = {"dry_grass", "grass", "coniferous_litter",}
local leaves = {"leaves", "aspen_leaves", "jungleleaves", "bush_leaves",}

minetest.register_node("winterize:ice", { -- breaks instantly, drops nothing
drawtype = "nodebox",
drawtype = "signlike",
description = "Ice",
tiles = {"winterize_ice_seethrough.png"},
buildable_to = true,
floodable = true,
paramtype = "light",
sunlight_propagates = true,
use_texture_alpha = "clip",
node_box = {
selection_box = {
type = "fixed",
fixed = {
{-0.5, -0.5, -0.5, 0.5, -0.4, 0.5},
Expand Down Expand Up @@ -58,139 +58,135 @@ end

-- Add snow and ice to map
ctf_api.register_on_new_match(function()
minetest.after(2, function()
local vm = VoxelManip(ctf_map.current_map.pos1, ctf_map.current_map.pos2)
local o_pos1, o_pos2 = vm:get_emerged_area()

minetest.log("action", "Starting to winterize...")
minetest.handle_async(function(data, pos1, pos2, present_count)
local outdata = {}
local present_positions = {}

local math_random = math.random
local math_min = math.min

local ID_AIR = minetest.CONTENT_AIR
local ID_IGNORE = minetest.get_content_id("ctf_map:ignore")
local ID_GLASS = minetest.get_content_id("ctf_map:ind_glass")
local ID_WATER = minetest.get_content_id("default:water_source")

local snow_place_blacklist = {
"ctf_map:", "default:snow", "doors:", "ctf_teams:", "default:fence",
"stairs:", "walls:", "default:mese_post", "xpanes:",
}
local SNOW_ID = minetest.get_content_id("default:snow")
local ICE_ID = minetest.get_content_id("winterize:ice")
local PRESENT_ID = minetest.get_content_id("winterize:present")

local Nx = pos2.x - pos1.x + 1
local Ny = pos2.y - pos1.y + 1
local count = 0

for y = pos1.y+1, pos2.y-1 do -- Make sure above/below checks don't go out of bounds
for z = pos1.z, pos2.z do
for x = pos1.x, pos2.x do
local pre = (((z - pos1.z) * Ny) * Nx)
local mid = (y - pos1.y) * Nx
local post = (x - pos1.x) + 1

local vi = pre + mid + post

local vi_below = pre + (mid - Nx) + post

if data[vi_below] ~= ID_AIR and data[vi] == ID_AIR then
if y <= pos2.y - 10 and data[vi_below] == ID_WATER then -- will ignore water near the ceiling
outdata[vi] = {i = ICE_ID, b = vi_below}
count = count + 1
elseif data[pre + (mid + Nx) + post] == ID_AIR then -- id_above == AIR
local name = minetest.get_name_from_content_id(data[vi_below])
local hit = false

if minetest.registered_nodes[name].walkable == false then
hit = true
else
for _, pattern in pairs(snow_place_blacklist) do
if name:find(pattern) then
hit = true
break
end
local vm = VoxelManip(ctf_map.current_map.pos1, ctf_map.current_map.pos2)
local o_pos1, o_pos2 = vm:get_emerged_area()

minetest.log("action", "Starting to winterize...")
minetest.handle_async(function(data, pos1, pos2, present_count)
local outdata = {}
local present_positions = {}

local math_random = math.random
local math_min = math.min

local ID_AIR = minetest.CONTENT_AIR
local ID_IGNORE = minetest.get_content_id("ctf_map:ignore")
local ID_GLASS = minetest.get_content_id("ctf_map:ind_glass")
local ID_WATER = minetest.get_content_id("default:water_source")

local snow_place_blacklist = {
"ctf_map:", "default:snow", "doors:", "ctf_teams:", "default:fence",
"stairs:", "walls:", "default:mese_post", "xpanes:",
}
local SNOW_ID = minetest.get_content_id("default:snow")
local ICE_ID = minetest.get_content_id("winterize:ice")
local PRESENT_ID = minetest.get_content_id("winterize:present")

local Nx = pos2.x - pos1.x + 1
local Ny = pos2.y - pos1.y + 1
local count = 0

for y = pos1.y+1, pos2.y-1 do -- Make sure above/below checks don't go out of bounds
for z = pos1.z, pos2.z do
for x = pos1.x, pos2.x do
local pre = (((z - pos1.z) * Ny) * Nx)
local mid = (y - pos1.y) * Nx
local post = (x - pos1.x) + 1

local vi = pre + mid + post

local vi_below = pre + (mid - Nx) + post

if data[vi_below] ~= ID_AIR and data[vi] == ID_AIR then
if y <= pos2.y - 10 and data[vi_below] == ID_WATER then -- will ignore water near the ceiling
outdata[vi] = {i = ICE_ID, b = vi_below}
count = count + 1
elseif data[pre + (mid + Nx) + post] == ID_AIR then -- id_above == AIR
local name = minetest.get_name_from_content_id(data[vi_below])
local hit = false

if minetest.registered_nodes[name].walkable == false then
hit = true
else
for _, pattern in pairs(snow_place_blacklist) do
if name:find(pattern) then
hit = true
break
end
end
end

if not hit then
for i = 1, math_min((pos2.y - y) - 4, 80) do
local id = data[pre + (mid + (i * Nx)) + post]

if id ~= ID_AIR then
-- Only count a hit if we aren't near the top of the map
local ignore_check = data[pre + (mid + ((i+4) * Nx)) + post]
if not hit then
for i = 1, math_min((pos2.y - y) - 4, 80) do
local id = data[pre + (mid + (i * Nx)) + post]

if ignore_check ~= ID_AIR and ignore_check ~= ID_IGNORE and ignore_check ~= ID_GLASS then
hit = true
end
if id ~= ID_AIR then
-- Only count a hit if we aren't near the top of the map
local ignore_check = data[pre + (mid + ((i+4) * Nx)) + post]

break
if ignore_check ~= ID_AIR and ignore_check ~= ID_IGNORE and ignore_check ~= ID_GLASS then
hit = true
end

break
end
end

if not hit then
if math_random(5) <= 4 then -- roughly 4/5 map coverage
outdata[vi] = {i = SNOW_ID, b = vi_below}
count = count + 1
elseif present_count > 0 then
table.insert(present_positions, {vi = vi, i = PRESENT_ID, b = vi_below})
end
if not hit then
if math_random(5) <= 4 then -- roughly 4/5 map coverage
outdata[vi] = {i = SNOW_ID, b = vi_below}
count = count + 1
elseif present_count > 0 then
table.insert(present_positions, {vi = vi, i = PRESENT_ID, b = vi_below})
end
end
end
end
end
end
end
end

if present_count > 0 and #present_positions > 0 then
table.shuffle(present_positions)
if present_count > 0 and #present_positions > 0 then
table.shuffle(present_positions)

for i=1, math_min(present_count, #present_positions) do
local vi = present_positions[i].vi
present_positions[i].vi = nil
outdata[vi] = present_positions[i]
end
for i=1, math_min(present_count, #present_positions) do
local vi = present_positions[i].vi
present_positions[i].vi = nil
outdata[vi] = present_positions[i]
end

return outdata, count
end,
function(outdata, change_count)
if change_count <= 1000 then
snow.SPAWN_SNOW = false
minetest.log("action", "Done winterizing, skipped changes: "..change_count)
return
end

return outdata, count
end,
function(outdata, change_count)
if change_count <= 1000 then
snow.SPAWN_SNOW = false
minetest.log("action", "Done winterizing, skipped changes: "..change_count)
return
else
snow.SPAWN_SNOW = true
minetest.log("action", "Done winterizing. Changes: "..change_count)
end

local newvm = VoxelManip(o_pos1, o_pos2)
local data = newvm:get_data()

local ID_AIR = minetest.CONTENT_AIR
local ID_IGNORE = minetest.CONTENT_IGNORE
for i in pairs(data) do
if outdata[i] then
if data[i] == ID_AIR and data[outdata[i].b] ~= ID_AIR then
data[i] = outdata[i].i
end
else
snow.SPAWN_SNOW = true
minetest.log("action", "Done winterizing. Changes: "..change_count)
data[i] = ID_IGNORE
end
end

minetest.after(2, function()
local newvm = VoxelManip(o_pos1, o_pos2)
local data = newvm:get_data()

local ID_AIR = minetest.CONTENT_AIR
local ID_IGNORE = minetest.CONTENT_IGNORE
for i in pairs(data) do
if outdata[i] then
if data[i] == ID_AIR and data[outdata[i].b] ~= ID_AIR then
data[i] = outdata[i].i
end
else
data[i] = ID_IGNORE
end
end

newvm:set_data(data)
newvm:write_to_map(false)
end)
end, vm:get_data(), o_pos1, o_pos2, winterize.get_present_count())
end)
newvm:set_data(data)
newvm:write_to_map(false)
end, vm:get_data(), o_pos1, o_pos2, winterize.get_present_count())
end)

local function get_drop(original, rarity)
Expand Down

0 comments on commit 30f7e0a

Please sign in to comment.