From dd2cd156bfdebac1ef0f3f18aed9b722033d70ac Mon Sep 17 00:00:00 2001 From: paramat Date: Sat, 24 Jan 2015 07:42:28 +0000 Subject: [PATCH] Initial commit --- README.txt | 4 + depends.txt | 1 + init.lua | 214 +++++++++++++++++++++++ license.txt | 14 ++ nodes.lua | 84 +++++++++ textures/riverexp_freshwater.png | Bin 0 -> 713 bytes textures/riverexp_freshwateranim.png | Bin 0 -> 4927 bytes textures/riverexp_freshwaterflowanim.png | Bin 0 -> 5819 bytes 8 files changed, 317 insertions(+) create mode 100644 README.txt create mode 100644 depends.txt create mode 100644 init.lua create mode 100644 license.txt create mode 100644 nodes.lua create mode 100644 textures/riverexp_freshwater.png create mode 100644 textures/riverexp_freshwateranim.png create mode 100644 textures/riverexp_freshwaterflowanim.png diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..ae1bc38 --- /dev/null +++ b/README.txt @@ -0,0 +1,4 @@ +riverexp 0.1.0 by paramat +For Minetest 0.4.11 stable or later +Depends default +Licenses: Code WTFPL. Textures CC-BY-SA diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..4ad96d5 --- /dev/null +++ b/depends.txt @@ -0,0 +1 @@ +default diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..6a3a74e --- /dev/null +++ b/init.lua @@ -0,0 +1,214 @@ +-- Parameters + +local YWATER = 1 +local YSAND = 4 +local YTERCEN = 0 +local TERSCA = 384 +local BASAMP = 0.2 + +local TSTONE = 0.02 +local TRIVER = 0.007 +local VALAMP = 0.33 +local VALEXP = 1 +local RIVAMP = 1.5 + +-- Noise parameters + +-- 2D noise + +local np_valleyhi = { + offset = 0, + scale = 1, + spread = {x=768, y=768, z=768}, + seed = -100, + octaves = 5, + persist = 0.6, + lacunarity = 2.0, + --flags = "" +} + +local np_valleyhi2 = { + offset = 0, + scale = 1, + spread = {x=768, y=768, z=768}, + seed = 95556, + octaves = 5, + persist = 0.6, + lacunarity = 2.0, + --flags = "" +} + +local np_valleylo = { + offset = 0, + scale = 1, + spread = {x=768, y=768, z=768}, + seed = -100, + octaves = 3, + persist = 0.5, + lacunarity = 2.0, + --flags = "" +} + +local np_valleylo2 = { + offset = 0, + scale = 1, + spread = {x=768, y=768, z=768}, + seed = 95556, + octaves = 3, + persist = 0.5, + lacunarity = 2.0, + --flags = "" +} + +local np_base = { + offset = 0, + scale = 1, + spread = {x=1536, y=1536, z=1536}, + seed = 188, + octaves = 3, + persist = 0.4, + lacunarity = 2.0, + --flags = "" +} + +--local np_ = { +-- offset = 0, +-- scale = 1, +-- spread = {x=, y=, z=}, +-- seed = , +-- octaves = , +-- persist = 0.5, +-- lacunarity = 2.0, +-- --flags = "" +--} + +-- Stuff + +dofile(minetest.get_modpath("riverexp").."/nodes.lua") + +-- Set mapgen parameters + +minetest.register_on_mapgen_init(function(mgparams) + minetest.set_mapgen_params({mgname="singlenode", flags="nolight"}) +end) + +-- Initialize noise objects to nil + +local nobj_valleyhi = nil +local nobj_valleyhi2 = nil +local nobj_valleylo = nil +local nobj_valleylo2 = nil +local nobj_base = nil + +-- On generated function + +minetest.register_on_generated(function(minp, maxp, seed) + local t0 = os.clock() + local x1 = maxp.x + local y1 = maxp.y + local z1 = maxp.z + local x0 = minp.x + local y0 = minp.y + local z0 = minp.z + print ("[riverexp] chunk minp ("..x0.." "..y0.." "..z0..")") + + local vm, emin, emax = minetest.get_mapgen_object("voxelmanip") + local area = VoxelArea:new{MinEdge=emin, MaxEdge=emax} + local data = vm:get_data() + + local c_stone = minetest.get_content_id("default:stone") + local c_water = minetest.get_content_id("default:water_source") + local c_sand = minetest.get_content_id("default:sand") + + local c_grass = minetest.get_content_id("riverexp:grass") + local c_freshwater = minetest.get_content_id("riverexp:freshwater") + + local sidelen = x1 - x0 + 1 + local ystride = sidelen + 32 + --local zstride = ystride ^ 2 + --local chulens3d = {x=sidelen, y=sidelen+17, z=sidelen} + local chulens2d = {x=sidelen, y=sidelen, z=1} + --local minpos3d = {x=x0, y=y0-16, z=z0} + local minpos2d = {x=x0, y=z0} + + nobj_valleyhi = nobj_valleyhi or minetest.get_perlin_map(np_valleyhi, chulens2d) + local nvals_valleyhi = nobj_valleyhi:get2dMap_flat(minpos2d) + + nobj_valleyhi2 = nobj_valleyhi2 or minetest.get_perlin_map(np_valleyhi2, chulens2d) + local nvals_valleyhi2 = nobj_valleyhi2:get2dMap_flat(minpos2d) + + nobj_valleylo = nobj_valleylo or minetest.get_perlin_map(np_valleylo, chulens2d) + local nvals_valleylo = nobj_valleylo:get2dMap_flat(minpos2d) + + nobj_valleylo2 = nobj_valleylo2 or minetest.get_perlin_map(np_valleylo2, chulens2d) + local nvals_valleylo2 = nobj_valleylo2:get2dMap_flat(minpos2d) + + nobj_base = nobj_base or minetest.get_perlin_map(np_base, chulens2d) + local nvals_base = nobj_base:get2dMap_flat(minpos2d) + + --nobj_ = nobj_ or minetest.get_perlin_map(np_, chulens2d) + --local nvals_ = nobj_:get2dMap_flat(minpos2d) + + --local ni3d = 1 + local ni2d = 1 + for z = z0, z1 do + for y = y0 - 16, y1 + 1 do + local vi = area:index(x0, y, z) + for x = x0, x1 do + + local n_base = nvals_base[ni2d] + local blend = math.min(math.max(n_base * 3 - 1, 0), 1) + local triver = TRIVER * (1 - blend * 0.5) + local valamp = VALAMP + local valexp = VALEXP + + local n_valleylo = nvals_valleylo[ni2d] + local n_valleyhi = nvals_valleyhi[ni2d] + local n_valleymix = n_valleylo * (1 - blend) + n_valleyhi * blend + + local n_valleylo2 = nvals_valleylo2[ni2d] + local n_valleyhi2 = nvals_valleyhi2[ni2d] + local n_valleymix2 = n_valleylo2 * (1 - blend) + n_valleyhi2 * blend + + local grad = (YTERCEN - y) / TERSCA + local densitybase = n_base * BASAMP + grad + local densityval = math.abs(n_valleymix * n_valleymix2) - triver + if densityval > 0 then -- valley shape + densityval = densityval ^ valexp * valamp + else -- river channel shape + densityval = densityval * RIVAMP + end + local density = densityval + densitybase + + if density >= TSTONE then + data[vi] = c_stone + elseif density > 0 and density < TSTONE then + if y <= YSAND or densitybase > 0.001 then + data[vi] = c_sand + else + data[vi] = c_grass + end + elseif y <= YWATER then + data[vi] = c_water + elseif densitybase > 0 then + data[vi] = c_freshwater + end + + --ni3d = ni3d + 1 + ni2d = ni2d + 1 + vi = vi + 1 + end + ni2d = ni2d - sidelen + end + ni2d = ni2d + sidelen + end + + vm:set_data(data) + vm:calc_lighting() + vm:write_to_map(data) + vm:update_liquids() + + local chugent = math.ceil((os.clock() - t0) * 1000) + print ("[riverexp] "..chugent.." ms") +end) + diff --git a/license.txt b/license.txt new file mode 100644 index 0000000..c73f8ae --- /dev/null +++ b/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/nodes.lua b/nodes.lua new file mode 100644 index 0000000..d324d9f --- /dev/null +++ b/nodes.lua @@ -0,0 +1,84 @@ +minetest.register_node("riverexp:grass", { + description = "Grass", + tiles = {"default_grass.png", "default_dirt.png", "default_grass.png"}, + groups = {crumbly=3}, + sounds = default.node_sound_dirt_defaults({ + footstep = {name="default_grass_footstep", gain=0.25}, + }), +}) + +minetest.register_node("riverexp:freshwater", { + description = "Fresh Water Source", + inventory_image = minetest.inventorycube("riverexp_freshwater.png"), + drawtype = "liquid", + tiles = { + { + name="riverexp_freshwateranim.png", + animation={type="vertical_frames", + aspect_w=16, aspect_h=16, length=2.0} + } + }, + special_tiles = { + { + name="riverexp_freshwateranim.png", + animation={type="vertical_frames", + aspect_w=16, aspect_h=16, length=2.0}, + backface_culling = false, + } + }, + alpha = WATER_ALPHA, + paramtype = "light", + is_ground_content = false, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + drop = "", + drowning = 1, + liquidtype = "source", + liquid_alternative_flowing = "riverexp:freshwaterflow", + liquid_alternative_source = "riverexp:freshwater", + liquid_viscosity = WATER_VISC, + liquid_renewable = false, + liquid_range = 2, + post_effect_color = {a=64, r=100, g=150, b=200}, + groups = {water=3, liquid=3, puts_out_fire=1}, +}) + +minetest.register_node("riverexp:freshwaterflow", { + description = "Fresh Flowing Water", + inventory_image = minetest.inventorycube("riverexp_freshwater.png"), + drawtype = "flowingliquid", + tiles = {"riverexp_freshwater.png"}, + special_tiles = { + { + image="riverexp_freshwaterflowanim.png", + backface_culling=false, + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.8} + }, + { + image="riverexp_freshwaterflowanim.png", + backface_culling=true, + animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=0.8} + }, + }, + alpha = WATER_ALPHA, + paramtype = "light", + paramtype2 = "flowingliquid", + is_ground_content = false, + walkable = false, + pointable = false, + diggable = false, + buildable_to = true, + drop = "", + drowning = 1, + liquidtype = "flowing", + liquid_alternative_flowing = "riverexp:freshwaterflow", + liquid_alternative_source = "riverexp:freshwater", + liquid_viscosity = WATER_VISC, + liquid_renewable = false, + liquid_range = 2, + post_effect_color = {a=64, r=100, g=130, b=200}, + groups = {water=3, liquid=3, puts_out_fire=1, not_in_creative_inventory=1}, +}) + diff --git a/textures/riverexp_freshwater.png b/textures/riverexp_freshwater.png new file mode 100644 index 0000000000000000000000000000000000000000..a4dfae047dc815f209a1addeeeff02b4a13c6d2f GIT binary patch literal 713 zcmV;)0yh1LP)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01FcU01FcV0GgZ_00007bV*G`2i^l8 z2NoAGKFo6f00K!#L_t(I%RQ6bcHA}$gg=0!DD6)+b<#R^k_Yc2k(o;bDF$A77J zC6OY~3pK&*0A~Qqj9h;C`X>OYNJ@Oj9e2&~rGgn=D=Z5#3|wzF92aA$g>BBfzP_Tm z-9d~lv9@h@LJKXBZ#1?d`f`_b5421 z%XsD=K)TFTPNWowdl61;0W)HkxsFP3M|00@GcHs)#Rz6FPb*O=+=jO#6=D?lkh@=N z{yh~W1l|YbheH$y?pO%W5BNMojBB$)yr~VFrsTK8|350JU&uk?X!g+<7VR{BXaju-Ot* z+K6KZxXhHPHD?8wQF+j%8WXs0z8~B1Qz~aWPt%G2qZ=p6fsaR!MLa vFf)9qhzMu^;L$;wbCHC{|3mj;2Ft>Kqp3wXzLE+_00000NkvXXu0mjfwsbHJ literal 0 HcmV?d00001 diff --git a/textures/riverexp_freshwateranim.png b/textures/riverexp_freshwateranim.png new file mode 100644 index 0000000000000000000000000000000000000000..ec359339e268dbd3785178e197ba83eb040760c8 GIT binary patch literal 4927 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 literal 0 HcmV?d00001 diff --git a/textures/riverexp_freshwaterflowanim.png b/textures/riverexp_freshwaterflowanim.png new file mode 100644 index 0000000000000000000000000000000000000000..bb1b2a3d389118a72fd3dba86160e3fbad4daaf2 GIT binary patch literal 5819 zcmY*d2RNJS`;JkgwrE9bQ_4}Js7=jC35xX8@7Q}4wMx(;YBi!%jo1{WiYlTNYSpey z?3JTxr1oC_k8}R(%9ZPTzjrc2=;n$ws_}!Y9y6Ic*X2xhqz8J{xy9hy2xav*YnUS zJ=Q@coP%ezu@BJ_W%XQ#Xxr<6p2D9*N=pReE%H!gFKNK*3VO=l;@Z)fMo?nA#Y<96 z#OfdJ^*Yl7QXY!Lex-YkXdMAYyiv3lH@!6R3$oC1Oh+>_zt?-pS*t3V(I9(MgUf)| zFUz{ENN6ziXsm%r3Tq zopiUaf->ZNx#A|!>ex!@1L$}KM(1kA`=zfj=5McUGsoa?`tg_!Eh92N#*oaaqF%d< zsA!5dgXq8}hiLbFsh9-tZg5ub81_@Cn~+OaKmDDIjhd?gE^1v1Thih>mdZgozc~q7 zHCSH$;BpC0Hj{U7OWE>R0}eI{SLp}RI%W@kbC#?8NY}6{pT((CX;_INOp&nWR&}A~QT`=@ zkF7<>vN~TIE@q2gPeitY;sGU3+`N5{^NXdBGKy@1TdB+07{z?~>K#ui1p&k(KI6By zoSOkpFeG#fRep4n>Er8TNl@G2g}pER*!v_}pL=JHi2U)DcFgg|!AA6y5^I8linAC$ z4Le^VIe2|T^~<_CD>?N_nxRt?f9VJ8L+stNL5db!JhW`dhZXIK!9ZfGRBlIxZcZtA zhgCo041%thPom<~PnRiR^z>U9Vm~Sh9Z7Ekqw&VnG=HFM=raQ2!Sia#H>XCtVLpLj za+-MPAo_h5LvwpP4~OFXJ)N>uDrq~9jTCsNU-T0ugEqVCEiAU9kq(m9ujabAYRr6& z&$#kCBj)WNNanM&&)G0Bj!0o5*=>G9Q#rVuHG;}M7H=Y8qOVEoZ)uLZXZv3XvGyDY zZQ}Kn|B^0&eBq=|5Sqg~y>aLPwRB{74QPo@1T|YUoN|n_2Xe)Id#<=dI!VrK3Q$}e z@okn{foaK`7D(y7d(v`*vogX)YMUkMwTWs?IX5@bE<~inENQ9STpz=3Hk2IJj@wS& zsrgTh`ewPM54Hf5QDV0woebx_0z`GSW)~>-Nu|LSQo&0?wqFrh)m>0whYJof^omHY z8-+cQah!R|KbU;fuY`ph2AWh3v0bxCEEME7H@8@jwMlw6Y*5S4wsyAxi&5ccfV@)_YrTjJKBPM@Dj(9}9yf3Dwnw6cO==h!{9ger@me}i_d4-;%+iX^FrypgAz7o{8wNi)R1jtHIK;KzTwu`EDD%gd7 zXN%Ow*>IReH5SpRrk07@ZVKoMP;~goMe!;ctke6MhKyxQHf(FUJU*xb6M56{H+5$n zx9N2=N+Q9cbLq$R$tRz7kF0{c7G5srSaXq!de5Q|(SrP`+s;|wL3*FFr%d7{k?&){ zk0~{=Tz_IWG!qj4(yHH@QYti%L{IYsd0|DB+$55R6>h8#gfNvd-fnJHx-0CiY5(&y zg_|?Lh5-3IIskD=Olsj* z$2%p8ewp2$(;VlWv0IRraMO=qH|zRrI>EhGV`|nb39pc`%SK747$J1X2Si5vHHDfh zI&}9`9&>X&Gz;Q%oJnYDpdQ`heQb|=ELqVZ);A!NOCNUr_3Qk`#%uPKr;QHL<|ARb z;4I;+CtUp#=r}SL9gE-53$_2j5rR&Fn-+I(Z7-vVZ%iC#9tx7kW;rrQ=XN0b7a?*W zI7J;7=uz^R-192Bk5`=p%dwRp{WO7&X$ zO+BLq*hEV4DsyLsm+TQM+n-eu@7AD=4)~kBJXGJUSp?QqgYPFs`1%L%BuPd3V8Wh> zVeiX~MK=DP_GAiAbXv1*g*yrI2OQqD9(L@}{Chn;@jEgOu}I9}ED{-*>j-K?Wjt}G z?yJiY)8u7oQi$riYintZRc7qMd)(HJp&|G&@NJpB<%vyVd5!FAF*n zn;OIG{(z7HFkn_0oAulOp_8BJNk6khrDOPfZc8##(k z9L^CmOXYA);5zvdyu~HictCvr60O@Zj)QLH8#3e=QyhW;6>mn*&B@8M&8qh6Z=sFF3_`TzU zse-W~4U0DLAeCQYS>OB~3f{ecbHrOM(>-71chj+u*V%l?B&vmY%-yqB-Vg)!(6k?i z;NY6O?c9{oQ@)YsnoQvw1ir2F(OVxzu6|fO<|962a-5NZFpOz?F(Dmi))yGWrt*_YR0RUB9z3X_EQy^k<}~Ru&gm zjS9q(W9XEK#HE_JYA~zstLPS-3P{PArywR#D@~yZiqOd1A&%>DcW-=F+sU~{4Dsqo z`Gba`(@Ph;kispNFSXr_6J4{l|9isDn}GVh=u}$v)P-spRGHzDSf%nf;=Y-jxlHqC z9gQGb)fYO#DxxO_gS?|H>5_-1-kRWUO&4NrwekB==|PQ_L!CTi66=15n6mCy zHQo38135$48rX|BLPFoW8Ly`z`%-J@R;el48WoJmiXZg8sj?s+a2{TjEm{FyGuKrd z&?k%A*V?0^@CHe(w7_Yjy~Jbo*I-h*^{*bKvXw-=^1qM2rv`$*V3<|2eV!^oXM)?G z6)%k`t(-0yWZH%2BGA!7c>TuEZwQ7YrRLphG7O_K=4X31aS~R*fnwSpWq)N7QX3oD z;E9%zQRexZQu_Kzafh{htL^P1WBPLIS)FEB?yySsnsOj*!2Hw;hwYBgdUIQ;D%9hlobp1jt8}SYOrdq#;=*+| z*O_Y+XENyvE`8^pP0hGCts!JKA>NUg%!*e!9X@56_SMs&-;Wm?W>@dKCJ@Y;yQ@wu z>_~U}6>nf;LVc1xg%rF(k?~1HA6FA|!Ql#LZq@U3>P@Xms-<#MH`vS~#Wi^QpZD&P z!h;nxLykv(7FbBT+S;c&xML&tKO~lv(7@rznK|FYlJ&PT_~Bke+PX1uWz1mGClnz@ zc!33Nh;TP_%1h$&@_CBkj%z<2s1EUAaCFa@k~oLX5frO%9~+PS$>5s)0a{$-N1kck zBb31Nyxg^+lU1m}Li;>^F*0A-?q=K(@pw-~5eCqD#WF66gj|RsVITsZwGO8!#r;Q4 zx6Xl=)3H((=?ogPEaIDpd}X4{!<}hli+fM`M#JyL8yU(BXtNdwLJ-Lai%=K_( zb>Yc*)_s0{*!`C{R(E~^K{u%;Cw#1DdGpnQ7%>eT-grJf5?@2XaKI@bCtBb)eut^GB zcJC}9Y~-g^&}$n!?4_qk{d!p1Q(poK;f{+1vkcnyVjZp?Vr z=u@F;sNXgrxJ20H^f4G%;1mk^t*#o=)?S&(v05p}NL6cfUC$QHDafs+WDVxe?%sO- z=E!g1P!(b6d|V>H|95Y0;8_9nO%RIU5^i03LI|>UoU*jgKuA5`%h>fA-UCi}WqdO- zVJWb>F`A7fYL&5&fGAnu_YX1delJ)qy-MZ4R4ziuE2ALTgFO4JA5}YDMLj~ofxjoP zeNW*ImcBiPG<4BEI0?fc2uBP56G-mI%j%uoo_=3 z@!$zA(bKoNqx!E7wRO>kJ`?l6x|~>2aaYD`1-@}Z$D3}RS*_IsO>q*<8YqL9y?q6_ zL^s0-J;5p4@NN{x^k~{|u1W+CM-WrW4^&MIhPN9$p0)Mjy<{PIvxO7Obo7cL;d_VS zbveq5;Hp0MsVj>j+5NpSTn%$JMh!pzrzjQCd)cU^K3@T|{o1+0WF`L(1m%^cKZ7q}asx1T0^|P;4nzd7 zA9E|ugLn27fzYbi{d+kr>{TiO6BiKWyFMFa=R9l3p(UwqPt6s<58qR}%USKx5_r_| zfQ%;mjwwmoSBg|r)lUatMHjmsxhkrsQwcYRAw97Ee9yV~>t<&wsTgO2Uwkv$-QV^J z#^$!L5SQ6P-nbS?ycS#Cp+$~F7+B3YMgdue8CZF(SO6rcS{cbN14H9Px|w$q%NI0e z#0vv6UUXCqvF{vSM1@)c)Sm@>1`_qF0${={fdsy`3;)6u`yYirx#%MB0WE;26t(l= zWx6suoS{+9x&r_2i(etlSeH^e@*J13Hz<7rF+C=1$<&CdDrSZZIyYNLYMYMb^d zuxs4~Z5QfZPE1j0n1h!9U;vR00|uADJ5l;dA?n!|u)PSVqTv67>XOc3fS+&h>LGUb zd_dBA#!r_R>Q9z=G8^Xbw3+{{r!m_lsP}3Lmny4U!G(bds<#afC@<-%W$FT}s+VH{ zuS~5~3<=)`8vpnQ2+W=Y1h(8e2$uuWzu;$y2rDuKmYDqOw_3U`6M#Ux8IX|TfBt*u z_a<$8_?E0yMcn8z_%~`R=|V*0;kF?VS<(ME!hgH4<%014&zSOB6CpUf0S4ssPt#I1 z_ur;QH=R;&lLb@O)`h*VUWg_U6x@_+neu(gn{Z6vFcy?UrNIY8CXgB0*nujt{PZv2t5ThpB{L6IjSfhGI~)%&H3d5 zAwSsHWB~u{TS1Xs?6vuC057b60NAn=Y8VoBE|*~br)mi?>pQexF_-HuDnVQ7*ADG} z0OwtSw%7nR-1h^_RRqIbC=0;daUUenc|5BFb_;3X-8-NpEL{|B+jsmBJ01osjc>?0 zkiD4s`&-t*C6n