geodes.lua 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622
  1. local function probe_geode_neighbor(pos, v)
  2. local n = minetest.get_node(vector.add(pos, v))
  3. local def = minetest.registered_nodes[n.name]
  4. if not def or n.name == "air" then
  5. return 'i' -- interior
  6. end
  7. if def.groups and def.groups.geode_wall then
  8. return 'i' -- crystal wall
  9. end
  10. if def.groups and (def.groups.cracky or def.groups.crumbly) then
  11. return 'e' -- exterior
  12. end
  13. return 'i' -- interior
  14. end
  15. local orient_data = {
  16. eeeeee = {n = 6, o = 0 },
  17. eieeee = {n = 5, o = 3 }, --
  18. ieeeee = {n = 5, o = 5 }, --
  19. iieeee = {n = 42, o = 1 }, --
  20. eeieee = {n = 5, o = 8 }, --
  21. eiieee = {n = 4, o = 3 }, --
  22. ieieee = {n = 4, o = 1 }, --
  23. iiieee = {n = 32, o = 1 }, --
  24. eeeiee = {n = 5, o = 4 }, --
  25. eieiee = {n = 4, o = 19 }, --
  26. ieeiee = {n = 42, o = 13 }, --
  27. iieiee = {n = 32, o = 21 }, --
  28. eeiiee = {n = 42, o = 4 }, --
  29. eiiiee = {n = 32, o = 17 }, --
  30. ieiiee = {n = 32, o = 13 }, --
  31. iiiiee = {n = 22, o = 4 }, --
  32. eeeeie = {n = 5, o = 0 }, --
  33. eieeie = {n = 4, o = 16 }, --
  34. ieeeie = {n = 42, o = 5 }, --
  35. iieeie = {n = 32, o = 5 }, --
  36. eeieie = {n = 4, o = 0 }, --
  37. eiieie = {n = 3, o = 3 }, --
  38. ieieie = {n = 3, o = 0 }, --
  39. iiieie = {n = 2, o = 3 }, --
  40. eeeiie = {n = 4, o = 4 }, --
  41. eieiie = {n = 3, o = 20 }, --
  42. ieeiie = {n = 3, o = 4 }, --
  43. iieiie = {n = 2, o = 7 }, --
  44. eeiiie = {n = 32, o = 4 }, --
  45. eiiiie = {n = 2, o = 6 }, --
  46. ieiiie = {n = 2, o = 4 }, --
  47. iiiiie = {n = 1, o = 4 }, --
  48. eeeeei = {n = 5, o = 14 }, --
  49. eieeei = {n = 4, o = 18 }, --
  50. ieeeei = {n = 4, o = 9 }, --
  51. iieeei = {n = 32, o = 9 }, --
  52. eeieei = {n = 4, o = 2 }, --
  53. eiieei = {n = 3, o = 2 }, --
  54. ieieei = {n = 3, o = 1 }, --
  55. iiieei = {n = 2, o = 1 }, --
  56. eeeiei = {n = 4, o = 10 }, --
  57. eieiei = {n = 3, o = 10 }, --
  58. ieeiei = {n = 3, o = 9 }, --
  59. iieiei = {n = 2, o = 9 }, --
  60. eeiiei = {n = 32, o = 8 }, --
  61. eiiiei = {n = 2, o = 10 }, --
  62. ieiiei = {n = 2, o = 8 }, --
  63. iiiiei = {n = 1, o = 8 }, --
  64. eeeeii = {n = 42, o = 0 }, --
  65. eieeii = {n = 32, o = 16 }, --
  66. ieeeii = {n = 32, o = 12 }, --
  67. iieeii = {n = 22, o = 0 }, --
  68. eeieii = {n = 32, o = 0 }, --
  69. eiieii = {n = 2, o = 2 }, --
  70. ieieii = {n = 2, o = 0 }, --
  71. iiieii = {n = 1, o = 0 }, --
  72. eeeiii = {n = 32, o = 20 }, --
  73. eieiii = {n = 2, o = 18 }, --
  74. ieeiii = {n = 2, o = 12 }, --
  75. iieiii = {n = 1, o = 20 }, --
  76. eeiiii = {n = 22, o = 12 }, --
  77. eiiiii = {n = 1, o = 16 }, --
  78. ieiiii = {n = 1, o = 12 }, --
  79. iiiiii = {n = 0, o = 0 },
  80. }
  81. local function orient_geode_wall(pos, name)
  82. local xp = probe_geode_neighbor(pos, {x=1, y=0, z=0})
  83. local xm = probe_geode_neighbor(pos, {x=-1, y=0, z=0})
  84. local yp = probe_geode_neighbor(pos, {x=0, y=1, z=0})
  85. local ym = probe_geode_neighbor(pos, {x=0, y=-1, z=0})
  86. local zp = probe_geode_neighbor(pos, {x=0, y=0, z=1})
  87. local zm = probe_geode_neighbor(pos, {x=0, y=0, z=-1})
  88. local s = xp..xm..yp..ym..zp..zm
  89. local od = orient_data[s]
  90. -- print("["..pos.x..", "..pos.y..", "..pos.z.."] s: "..s)
  91. if od.n == 0 then
  92. minetest.set_node(pos, {name = "air"})
  93. else
  94. minetest.swap_node(pos, {name="potions:geode_"..name.."_"..od.n, param2 = od.o})
  95. end
  96. end
  97. function potions.register_geode(name, opts)
  98. local tiles = opts.tiles or "default_diamond.png"
  99. if type(tiles) == "string" then
  100. tiles = {tiles}
  101. end
  102. local desc = opts.desc or opts.description or (name.." Crystal")
  103. local drops = opts.drops
  104. potions.geodes[name] = {
  105. name = name,
  106. drops = drops,
  107. rarity = opts.rarity or 5,
  108. }
  109. minetest.register_node("potions:geode_"..name.."_1", {
  110. description = desc,
  111. paramtype = "light",
  112. paramtype2 = "facedir",
  113. drawtype = "nodebox",
  114. tiles = tiles,
  115. drop = drops,
  116. node_box = {
  117. type = "fixed",
  118. fixed = {
  119. {-.5, -.5, -.5, 0.5, -.4, 0.5}
  120. },
  121. },
  122. groups = {cracky=3, geode_wall = 1, },
  123. -- for testing orient functions
  124. -- on_construct = function(pos) potions.orient_geode_wall(pos) end,
  125. geode_name = name,
  126. })
  127. minetest.register_node("potions:geode_"..name.."_2", {
  128. description = desc,
  129. paramtype = "light",
  130. paramtype2 = "facedir",
  131. drawtype = "nodebox",
  132. tiles = tiles,
  133. drop = drops .. " 2",
  134. node_box = {
  135. type = "fixed",
  136. fixed = {
  137. {-.5, -.5, -.5, 0.5, -.4, 0.5},
  138. {-.5, -.5, -.5, -.4, 0.5, 0.5},
  139. },
  140. },
  141. groups = {cracky=3, geode_wall = 1, not_in_creative_inventory = 1 },
  142. geode_name = name,
  143. })
  144. minetest.register_node("potions:geode_"..name.."_22", {
  145. description = desc,
  146. paramtype = "light",
  147. paramtype2 = "facedir",
  148. drawtype = "nodebox",
  149. tiles = tiles,
  150. drop = drops .. " 2",
  151. node_box = {
  152. type = "fixed",
  153. fixed = {
  154. {-.5, -.5, -.5, 0.5, -.4, 0.5},
  155. {-.5, 0.4, -.5, 0.5, 0.5, 0.5},
  156. },
  157. },
  158. groups = {cracky=3, geode_wall = 1, not_in_creative_inventory = 1 },
  159. geode_name = name,
  160. })
  161. minetest.register_node("potions:geode_"..name.."_3", {
  162. description = desc,
  163. paramtype = "light",
  164. paramtype2 = "facedir",
  165. drawtype = "nodebox",
  166. tiles = tiles,
  167. drop = drops .. " 3",
  168. node_box = {
  169. type = "fixed",
  170. fixed = {
  171. {-.5, -.5, -.5, 0.5, -.4, 0.5},
  172. {-.5, -.5, -.5, -.4, 0.5, 0.5},
  173. {-.5, -.5, -.5, 0.5, 0.5, -.4},
  174. },
  175. },
  176. groups = {cracky=3, geode_wall = 1, not_in_creative_inventory = 1 },
  177. geode_name = name,
  178. })
  179. minetest.register_node("potions:geode_"..name.."_32", {
  180. description = desc,
  181. paramtype = "light",
  182. paramtype2 = "facedir",
  183. drawtype = "nodebox",
  184. tiles = tiles,
  185. drop = drops .. " 3",
  186. node_box = {
  187. type = "fixed",
  188. fixed = {
  189. {-.5, -.5, -.5, 0.5, -.4, 0.5},
  190. {-.5, -.5, -.5, -.4, 0.5, 0.5},
  191. { .4, -.5, -.5, 0.5, 0.5, 0.5},
  192. },
  193. },
  194. groups = {cracky=3, geode_wall = 1, not_in_creative_inventory = 1 },
  195. geode_name = name,
  196. })
  197. minetest.register_node("potions:geode_"..name.."_4", {
  198. description = desc,
  199. paramtype = "light",
  200. paramtype2 = "facedir",
  201. drawtype = "nodebox",
  202. tiles = tiles,
  203. drop = drops .. " 4",
  204. node_box = {
  205. type = "fixed",
  206. fixed = {
  207. {-.5, -.5, -.5, 0.5, -.4, 0.5},
  208. {-.5, -.5, -.5, -.4, 0.5, 0.5},
  209. {-.5, -.5, -.5, 0.5, 0.5, -.4},
  210. { .4, -.5, -.5, 0.5, 0.5, 0.5},
  211. },
  212. },
  213. groups = {cracky=3, geode_wall = 1, not_in_creative_inventory = 1 },
  214. geode_name = name,
  215. })
  216. minetest.register_node("potions:geode_"..name.."_42", {
  217. description = desc,
  218. paramtype = "light",
  219. paramtype2 = "facedir",
  220. drawtype = "nodebox",
  221. tiles = tiles,
  222. drop = drops .. " 4",
  223. node_box = {
  224. type = "fixed",
  225. fixed = {
  226. {-.5, -.5, -.5, 0.5, -.4, 0.5},
  227. {-.5, -.5, -.5, -.4, 0.5, 0.5},
  228. {-.5, .4, -.5, 0.5, 0.5, 0.5},
  229. { .4, -.5, -.5, 0.5, 0.5, 0.5},
  230. },
  231. },
  232. groups = {cracky=3, geode_wall = 1, not_in_creative_inventory = 1 },
  233. geode_name = name,
  234. })
  235. minetest.register_node("potions:geode_"..name.."_5", {
  236. description = desc,
  237. paramtype = "light",
  238. paramtype2 = "facedir",
  239. drawtype = "nodebox",
  240. tiles = tiles,
  241. drop = drops .. " 5",
  242. node_box = {
  243. type = "fixed",
  244. fixed = {
  245. {-.5, -.5, -.5, 0.5, -.4, 0.5},
  246. {-.5, -.5, -.5, -.4, 0.5, 0.5},
  247. {-.5, -.5, -.5, 0.5, 0.5, -.4},
  248. { .4, -.5, -.5, 0.5, 0.5, 0.5},
  249. {-.5, .4, -.5, 0.5, 0.5, 0.5},
  250. },
  251. },
  252. groups = {cracky=3, geode_wall = 1, not_in_creative_inventory = 1 },
  253. geode_name = name,
  254. })
  255. minetest.register_node("potions:geode_"..name.."_6", {
  256. description = desc,
  257. paramtype = "light",
  258. paramtype2 = "facedir",
  259. drawtype = "nodebox",
  260. tiles = tiles,
  261. drop = drops .. " 6",
  262. node_box = {
  263. type = "fixed",
  264. fixed = {
  265. {-.5, -.5, -.5, 0.5, 0.5, 0.5},
  266. },
  267. },
  268. groups = {cracky=3, geode_wall = 1, not_in_creative_inventory = 1},
  269. geode_name = name,
  270. })
  271. -- generation nodes
  272. minetest.register_node("potions:geode_seed_"..name, {
  273. description = "geode mapgen seed "..name,
  274. drawtype = "node",
  275. tiles = {"default_cobble.png"},
  276. drop = "default:cobble",
  277. groups = {cracky = 1, geode_seed = 1},
  278. geode_name = name,
  279. })
  280. minetest.register_node("potions:geode_wall_"..name, {
  281. description = "geode mapgen wall "..name,
  282. drawtype = "node",
  283. tiles = {"default_cobble.png"},
  284. drop = "default:cobble",
  285. groups = {cracky = 1, geode_wall = 1, not_in_creative_inventory = 1},
  286. on_timer = function(pos)
  287. orient_geode_wall(pos, name)
  288. -- minetest.set_node(pos, {name="d"})
  289. end,
  290. geode_name = name,
  291. })
  292. -- print("++++++++ ore registration "..name)
  293. minetest.register_ore({
  294. ore_type = "scatter",
  295. ore = "potions:geode_seed_"..name,
  296. wherein = "default:stone",
  297. clust_scarcity = 48 * 48 * 48,
  298. clust_num_ores = 1,
  299. clust_size = 1,
  300. y_max = 100,
  301. y_min = -31000,
  302. })
  303. end
  304. minetest.register_abm({
  305. name = "potions:geode_tester",
  306. nodenames = "group:geode_wall",
  307. chance = 1,
  308. interval = 1000,
  309. action = function(pos, node)
  310. -- orient_geode_wall(pos)
  311. end
  312. })
  313. local function dist3(a, b)
  314. local x = a.x - b.x
  315. local y = a.y - b.y
  316. local z = a.z - b.z
  317. return math.sqrt(x*x + y*y + z*z)
  318. end
  319. --[[
  320. minetest.register_lbm({
  321. name = "potions:geode_grow",
  322. nodenames = "potions:geode_seed",
  323. run_at_every_load = false,
  324. action =
  325. })
  326. ]]
  327. local function pow(base, p)
  328. return math.exp(p * math.log(base))
  329. end
  330. minetest.register_abm({
  331. name = "potions:geode_grow",
  332. nodenames = "group:geode_seed",
  333. chance = 1,
  334. interval = 5,
  335. action = function(pos, node)
  336. local def = minetest.registered_nodes[node.name]
  337. local name = def.geode_name
  338. local yoff = math.min(math.max(-pos.y, 0), 1000) / 1000
  339. local rarity = potions.geodes[name].rarity
  340. -- print("geode " .. rarity)
  341. if math.random(rarity + 10 - math.floor(yoff*10)) > 1 then
  342. minetest.set_node(pos, {name="default:stone"})
  343. return
  344. end
  345. -- print("growing")
  346. local w = math.random(4) == 1
  347. -- most geodes are small, rare exponential size increase
  348. local a = math.random(400 + yoff*100)
  349. local r = math.min(20, pow((a / 431), 63) / 1160) + .1
  350. -- local r = (math.random(50)) / math.log(50)) + 1
  351. -- local r = 1.5
  352. local r2 = math.ceil(r+1)
  353. for x = pos.x-r2,pos.x+r2,1 do
  354. for y = pos.y-r2,pos.y+r2,1 do
  355. for z = pos.z-r2,pos.z+r2,1 do
  356. local p = {x=x, y=y, z=z}
  357. local d = dist3(p, pos)
  358. d = d + math.random() * .5
  359. local dd = d - r
  360. if dd <= -.5 then
  361. if w then
  362. minetest.set_node(p, {name = "default:river_water_source"})
  363. else
  364. minetest.set_node(p, {name = "air"})
  365. end
  366. elseif dd < 1 then
  367. minetest.set_node(p, {name = "potions:geode_wall_"..name})
  368. minetest.get_node_timer(p):start(1)
  369. elseif dd <= 1.8 then
  370. minetest.set_node(p, {name = "default:stone"})
  371. else
  372. -- minetest.set_node(p, {name = "default:stone"})
  373. end
  374. end
  375. end
  376. end
  377. end,
  378. })
  379. minetest.register_craftitem("potions:quartz_crystal", {
  380. description = "Quartz Crystal",
  381. inventory_image = "potions_quartz_crystal.png",
  382. groups = {gem = 1},
  383. -- y_min, y_max, biome, wherein, rarity
  384. })
  385. potions.register_geode("quartz", {
  386. description = "Quartz",
  387. drops = "potions:quartz_crystal",
  388. tiles = "default_diamond_block.png^[colorize:white:120"
  389. })
  390. minetest.register_craftitem("potions:smoky_quartz_crystal", {
  391. description = "Smoky Quartz Crystal",
  392. inventory_image = "potions_smoky_quartz_crystal.png",
  393. groups = {gem = 1},
  394. })
  395. potions.register_geode("smoky_quartz", {
  396. description = "Smoky Quartz",
  397. drops = "potions:smoky_quartz_crystal",
  398. tiles = "default_diamond_block.png^[colorize:brown:50"
  399. })
  400. minetest.register_craftitem("potions:amethyst_crystal", {
  401. description = "Amethyst Crystal",
  402. inventory_image = "potions_amethyst_crystal.png",
  403. groups = {gem = 1},
  404. })
  405. potions.register_geode("amethyst", {
  406. description = "Amethyst",
  407. drops = "potions:amethyst_crystal",
  408. tiles = "default_diamond_block.png^[colorize:purple:60"
  409. })
  410. --[[
  411. minetest.register_craftitem("potions:epidote_crystal", {
  412. description = "Epidote Crystal",
  413. inventory_image = "potions_epidote_crystal.png",
  414. })
  415. potions.register_geode("epidote", {
  416. description = "Epidote",
  417. drops = "potions:epidote_crystal",
  418. tiles = "default_diamond_block.png^[colorize:green:220^[colorize:black:120"
  419. })
  420. ]]
  421. minetest.register_craftitem("potions:emerald_gem", {
  422. description = "Emerald Gem",
  423. inventory_image = "potions_emerald_gem.png",
  424. groups = {gem = 1},
  425. })
  426. minetest.register_craftitem("potions:emerald_crystal", {
  427. description = "Emerald Crystal",
  428. inventory_image = "potions_emerald_crystal.png",
  429. groups = {gem = 1},
  430. })
  431. potions.register_geode("emerald", {
  432. description = "Emerald",
  433. drops = "potions:emerald_crystal",
  434. tiles = "default_diamond_block.png^[colorize:green:120"
  435. })
  436. minetest.register_craftitem("potions:ruby_gem", {
  437. description = "Ruby Gem",
  438. inventory_image = "potions_ruby_gem.png",
  439. groups = {gem = 1},
  440. })
  441. minetest.register_craftitem("potions:ruby_crystal", {
  442. description = "Ruby Crystal",
  443. inventory_image = "potions_ruby_crystal.png",
  444. groups = {gem = 1},
  445. })
  446. potions.register_geode("ruby", {
  447. description = "Ruby",
  448. drops = "potions:ruby_crystal",
  449. tiles = "default_diamond_block.png^[colorize:red:120"
  450. })
  451. minetest.register_craftitem("potions:sapphire_gem", {
  452. description = "Sapphire Gem",
  453. inventory_image = "potions_sapphire_gem.png",
  454. groups = {gem = 1},
  455. })
  456. minetest.register_craftitem("potions:sapphire_crystal", {
  457. description = "Sapphire Crystal",
  458. inventory_image = "potions_sapphire_crystal.png",
  459. groups = {gem = 1},
  460. })
  461. potions.register_geode("sapphire", {
  462. description = "Sapphire",
  463. drops = "potions:sapphire_crystal",
  464. tiles = "default_diamond_block.png^[colorize:blue:120"
  465. })
  466. minetest.register_craftitem("potions:garnet_gem", {
  467. description = "Garnet Gem",
  468. inventory_image = "potions_garnet_gem.png",
  469. groups = {gem = 1},
  470. })
  471. minetest.register_craftitem("potions:garnet_crystal", {
  472. description = "Garnet Crystal",
  473. inventory_image = "potions_garnet_crystal.png",
  474. groups = {gem = 1},
  475. })
  476. potions.register_geode("garnet", {
  477. description = "Garnet",
  478. drops = "potions:garnet_crystal",
  479. tiles = "default_diamond_block.png^[colorize:red:120^[colorize:black:60"
  480. })
  481. minetest.register_craftitem("potions:zircon_gem", {
  482. description = "Zircon Gem",
  483. inventory_image = "potions_zircon_gem.png",
  484. groups = {gem = 1},
  485. })
  486. minetest.register_craftitem("potions:zircon_crystal", {
  487. description = "Zircon Crystal",
  488. inventory_image = "potions_zircon_crystal.png",
  489. groups = {gem = 1},
  490. })
  491. potions.register_geode("zircon", {
  492. description = "Zircon",
  493. drops = "potions:zircon_crystal",
  494. tiles = "default_diamond_block.png^[colorize:yellow:70"
  495. })
  496. --[[
  497. cinnabar
  498. lazurite
  499. pyrite
  500. gypsum
  501. flourite
  502. calcite
  503. halite
  504. cutting and polishing crystals into gems
  505. ]]