From 32d9ba2ff949d9aaea73f8b2932bf371768d0b73 Mon Sep 17 00:00:00 2001 From: Amaz1 Date: Tue, 13 May 2014 20:54:33 +0100 Subject: [PATCH] Added meseors --- mods/meseor/README.txt | 36 +++++ mods/meseor/depends.txt | 1 + mods/meseor/init.lua | 270 ++++++++++++++++++++++++++++++++++ mods/meseor/license.txt | 14 ++ mods/meseor/sounds/meseor.ogg | Bin 0 -> 6184 bytes 5 files changed, 321 insertions(+) create mode 100644 mods/meseor/README.txt create mode 100644 mods/meseor/depends.txt create mode 100644 mods/meseor/init.lua create mode 100644 mods/meseor/license.txt create mode 100644 mods/meseor/sounds/meseor.ogg diff --git a/mods/meseor/README.txt b/mods/meseor/README.txt new file mode 100644 index 00000000..ce3f3c4f --- /dev/null +++ b/mods/meseor/README.txt @@ -0,0 +1,36 @@ +Compatible with Minetest 0.4.3 and later +Depends default +License WTFPL + +* Warning, this mod can seriously damage maps, it is not 'on generated', instead impact is triggered by abm on dirt, grass, desert sand and sand. Unless testing in a new world you should edit the impact area and safe area in the init.lua. + +* This first version is the fastest and simplest, also being compatible back to 0.4.3. Perhaps i will develop a more complex version for 0.4.6 including the new stuff like mese crystals, obsidian etc. + +* Default parameters are for one impact every few minutes for your instant gratification, for normal use you might want to increase the abm interval and chance parameters. Personally i just add 1 or 2 zeros on the end of MSRCHA. + +* The primary excavated nodes (stone, desert stone, dirt, grass, desert sand, sand, trees) are counted, the proportions calculated, then randomly layered around the crater in the same proportions and with the same total number of nodes, thickest at the crater rim and thinning inwards and outwards. + +* Most stone is broken into gravel. Grass becomes dirt. Water, snow, plants are assumed to be vapourized and are not counted. As the ejected material is added it strips surrounding trees of their leaves. + +* Damage is inflicted to nearby players depending on distance from impact point, by default a rare direct hit is fatal. + +* There is a sound file for using your own choice of sound, the default sound is simply the pop of a dug node, it seems a good cute / abstract impact sound. + + +Version 0.2.0 + +* Impacts can now be created on generated chunk as well as by abm, both are optional. By default only on generated impacts are enabled. + +* By default on generated impacts are fairly common, you might want to increase parameter ONGCHA. + +* On generated craters are limited to 16m radius, craters by abm can be up to 31m radius. + +* On generated impacts are too distant to damage players. + +* Compatible with default jungles, jungletree trunks are now counted and scattered. + +* Meseor path is now excavated, single-node holes are punched in jungle canopies and in the ice above icecaves. + +* Compatible with snow biomes mod, bugs fixed (nodes floating above snow, floating moss). + +* Impact area and safe area apply to both on-gen and abm impacts. diff --git a/mods/meseor/depends.txt b/mods/meseor/depends.txt new file mode 100644 index 00000000..4ad96d51 --- /dev/null +++ b/mods/meseor/depends.txt @@ -0,0 +1 @@ +default diff --git a/mods/meseor/init.lua b/mods/meseor/init.lua new file mode 100644 index 00000000..f41fc550 --- /dev/null +++ b/mods/meseor/init.lua @@ -0,0 +1,270 @@ +-- meseor 0.2.0 by paramat. +-- License WTFPL, see license.txt. + +-- Parameters. + +local ONGEN = true -- (true / false) Enable / disable impacts on generated chunk. +local ONGCHA = 9 -- 9 -- Ongen 1/x chance of impact per generated chunk. + +local ABM = false -- Enable / disable impacts by abm on surface material. +local ABMINT = 181 -- 181 -- Abm interval. +local ABMCHA = 100000 -- 100000 -- Abm 1/x chance per node. +local DAMAGE = true -- Enable / disable player damage loop. +local DAMMAX = 20 -- 20 -- Maximum damage. 20 = direct hit is fatal. + +local RADMIN = 3 -- 3 -- Minimum crater radius. +local RADMAX = 31 -- 31 -- Maximum crater radius, on-gen craters are limited to 16. +local STOCHA = 5 -- 5 -- 1/x chance of stone boulders instead of gravel. + +local XMIN = -16000 -- Impact area dimensions. Impacts only inside this area. +local XMAX = 16000 +local ZMIN = -16000 +local ZMAX = 16000 + +local SAXMIN = 0 -- Safe area dimensions. No impacts inside this area. +local SAXMAX = 0 -- When overlapping impact area, the safe area overrides. +local SAZMIN = 0 +local SAZMAX = 0 + +local DEBUG = true + +-- Stuff. + +meseor = {} + +-- On generated. + +if ONGEN then + minetest.register_on_generated(function(minp, maxp, seed) + if math.random(ONGCHA) == 2 then + local env = minetest.env + local maxrad = RADMAX + if maxrad > 16 then maxrad = 16 end + local conrad = math.random(RADMIN, maxrad) + local rimrad = math.ceil(conrad * 2.4) + local x = math.random(minp.x + rimrad, maxp.x - rimrad) + local z = math.random(minp.z + rimrad, maxp.z - rimrad) + -- Find surface with air above, abort if water found, ignore trees and ice. + local surfy = false + local aa = false + for y = maxp.y, minp.y, -1 do + local nodename = env:get_node({x=x,y=y,z=z}).name + if nodename == "default:water_source" or nodename == "default:water_flowing" then + return + elseif nodename == "air" then + aa = true + elseif aa and nodename ~= "air" and nodename ~= "ignore" and nodename ~= "snow:ice" + and nodename ~= "default:leaves" and nodename ~= "default:jungleleaves" + and nodename ~= "default:tree" and nodename ~= "default:jungletree" then + surfy = y + break + end + end + if not surfy then + return + end + DAMAGE = false + crater({x=x,y=surfy,z=z},conrad) + end + end) +end + +-- Abm. + +if ABM then + minetest.register_abm({ + nodenames = { + "default:obsidian", + "moontest:dust", + }, + interval = ABMINT, + chance = ABMCHA, + action = function(pos, node, _, _) + local env = minetest.env + local x = pos.x + local y = pos.y + local z = pos.z + -- Find close surface above, abort if underwater or no close surface found. + local surfy = false + for j = 1, 4 do + local nodename = env:get_node({x=x,y=y+j,z=z}).name + if nodename == "default:water_source" or nodename == "default:water_flowing" then + return + elseif nodename == "air" then + surfy = y+j-1 + break + end + end + if not surfy then + return + end + local conrad = math.random(RADMIN, RADMAX) + crater({x=x,y=surfy,z=z},conrad) + end, + }) +end + +-- Functions. + +function crater(pos, conrad) + local env = minetest.env + local x = pos.x + local y = pos.y + local z = pos.z + local rimrad = math.ceil(conrad * 2.4) + -- If in safe zone or not in impact zone then abort. + if (x > SAXMIN - rimrad and x < SAXMAX + rimrad and z > SAZMIN - rimrad and z < SAZMAX + rimrad) + or not (x > XMIN and x < XMAX and z > ZMIN and z < ZMAX) then + return + end + -- Check enough depth. + for j = -conrad - 1, -1 do + local nodename = env:get_node({x=x,y=y+j,z=z}).name + if nodename == "air" or nodename == "ignore" then + return + end + end + -- Check pos open to sky. + for j = 1, 160 do + local nodename = env:get_node({x=x,y=y+j,z=z}).name + if nodename ~= "air" and nodename ~= "ignore" + and nodename ~= "default:leaves" and nodename ~= "default:jungleleaves" + and nodename ~= "snow:ice" and nodename ~= "snow:needles" then + return + end + end + -- Excavate path. + for j = 1, 160 do + local nodename = env:get_node({x=x,y=y+j,z=z}).name + if nodename ~= "air" and nodename ~= "ignore" then + env:remove_node({x=x,y=y+j,z=z}) + end + end + -- Add meseorite. + env:add_node({x=x,y=y-conrad-1,z=z},{name="default:mese"}) + -- Excavate cone and count excavated nodes. + local exsto = 0 + local exdsto = 0 + local exdirt = 0 + local exdsan = 0 + local exsan = 0 + local extree = 0 + local exjtree = 0 + for j = 0, conrad * 2 do + for i = -j, j do + for k = -j, j do + if i ^ 2 + k ^ 2 <= j ^ 2 then + local exsno = false + local nodename = env:get_node({x=x+i,y=y-conrad+j,z=z+k}).name + if nodename == "default:stone" then + exsto = exsto + 1 + elseif nodename == "default:desert_stone" then + exdsto = exdsto + 1 + elseif nodename == "default:dirt" or nodename == "default:dirt_with_grass" then + exdirt = exdirt + 1 + elseif nodename == "default:desert_sand" then + exdsan = exdsan + 1 + elseif nodename == "default:sand" then + exsan = exsan + 1 + elseif nodename == "default:tree" then + extree = extree + 1 + elseif nodename == "default:jungletree" then + exjtree = exjtree + 1 + elseif nodename == "snow:snow" then + exsno = true + end + if nodename ~= "air" then + env:remove_node({x=x+i,y=y-conrad+j,z=z+k}) + end + if exsno then + env:remove_node({x=x+i,y=y-conrad+j,z=z+k}) + end + end + end + end + end + -- Calculate proportions of ejecta. + local extot = exsto + exdsto + exdirt + exdsan + exsan + extree + exjtree + local pexsto = exsto / extot + local pexdsto = exdsto / extot + local pexdirt = exdirt / extot + local pexdsan = exdsan / extot + local pexsan = exsan / extot + local pextree = extree / extot + local pexjtree = exjtree / extot + -- Print to terminal. + if DEBUG then + print ("[meseor] Cone radius "..conrad.." node ("..x.." "..y.." "..z..")") + print ("[meseor] exsto "..exsto.." exdsto "..exdsto.." exdirt "..exdirt.." exdsan "..exdsan) + print ("[meseor] exsan "..exsan.." extree "..extree.." exjtree "..exjtree) + print ("[meseor] extot "..extot) + end + -- Add ejecta. + local addtot = 0 + for rep = 1, 128 do + for i = -rimrad, rimrad do + for k = -rimrad, rimrad do + local rad = (i ^ 2 + k ^ 2) ^ 0.5 + if rad <= rimrad and math.random() > math.abs(rad - conrad * 1.2) / (conrad * 1.2) + and addtot < extot and math.random(3) == 2 then + -- Find ground. + local groundy = false + for j = conrad - 1, -160, -1 do + local nodename = env:get_node({x=x+i,y=y+j,z=z+k}).name + if nodename == "default:leaves" or nodename == "default:jungleleaves" + or nodename == "default:papyrus" or nodename == "default:dry_shrub" + or nodename == "default:grass_1" or nodename == "default:grass_2" + or nodename == "default:grass_3" or nodename == "default:grass_4" + or nodename == "default:grass_5" or nodename == "default:apple" + or nodename == "default:junglegrass" or nodename == "snow:needles" then + env:remove_node({x=x+i,y=y+j,z=z+k}) + elseif nodename ~= "air" and nodename ~= "ignore" and nodename ~= "snow:snow" + and nodename ~= "default:water_source" and nodename ~= "default:water_flowing" then + groundy = y+j + break + end + end + if groundy then + local x = x + i + local y = groundy + 1 + local z = z + k + if math.random() < pexjtree then + env:add_node({x=x,y=y,z=z},{name="default:jungletree"}) + elseif math.random() < pextree then + env:add_node({x=x,y=y,z=z},{name="default:tree"}) + elseif math.random() < pexsan then + env:add_node({x=x,y=y,z=z},{name="default:sand"}) + elseif math.random() < pexdsan then + env:add_node({x=x,y=y,z=z},{name="default:desert_sand"}) + elseif math.random() < pexdirt then + env:add_node({x=x,y=y,z=z},{name="default:dirt"}) + elseif math.random() < pexdsto then + env:add_node({x=x,y=y,z=z},{name="default:desert_stone"}) + elseif math.random() < pexsto then + if math.random(STOCHA) == 2 then + env:add_node({x=x,y=y,z=z},{name="default:stone"}) + else + env:add_node({x=x,y=y,z=z},{name="default:gravel"}) + end + end + addtot = addtot + 1 + end + end + end + end + if addtot == extot then break end + end + -- Play sound. + minetest.sound_play("meseor", {gain = 1}) + -- Damage player if inside rimrad. + if DAMAGE then + for _,player in ipairs(minetest.get_connected_players()) do + local plapos = player:getpos() + local pladis = ((plapos.x - x) ^ 2 + (plapos.y - y) ^ 2 + (plapos.z - z) ^ 2) ^ 0.5 + local pladam = math.ceil((1 - pladis / rimrad) * DAMMAX) + if pladam > 0 then + player:set_hp(player:get_hp() - pladam) + end + end + end +end diff --git a/mods/meseor/license.txt b/mods/meseor/license.txt new file mode 100644 index 00000000..c73f8ae7 --- /dev/null +++ b/mods/meseor/license.txt @@ -0,0 +1,14 @@ + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + Version 2, December 2004 + + Copyright (C) 2004 Sam Hocevar + + Everyone is permitted to copy and distribute verbatim or modified + copies of this license document, and changing it is allowed as long + as the name is changed. + + DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. You just DO WHAT THE FUCK YOU WANT TO. + diff --git a/mods/meseor/sounds/meseor.ogg b/mods/meseor/sounds/meseor.ogg new file mode 100644 index 0000000000000000000000000000000000000000..9d56bb8c2782a3a6e40b4dc7c5f75174d3f1d101 GIT binary patch literal 6184 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 Sd&EW0M8Mrba9*=30Q?&kGPgVc literal 0 HcmV?d00001