init.lua 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762
  1. potions = {
  2. geodes = {},
  3. utils = {},
  4. }
  5. local potions_players = {}
  6. local modpath = minetest.get_modpath("potions")
  7. -- Add everything:
  8. local modname = "potions"
  9. -- nodes and some mapgen
  10. dofile(modpath.."/glassware.lua")
  11. dofile(modpath.."/metals.lua")
  12. dofile(modpath.."/geodes.lua")
  13. dofile(modpath.."/hotsprings.lua")
  14. dofile(modpath.."/structures/ziggurat.lua")
  15. dofile(modpath.."/structures/coffer_dam.lua")
  16. dofile(modpath.."/structures/bridge.lua")
  17. dofile(modpath.."/structures/tunnel.lua")
  18. dofile(modpath.."/structures/island.lua")
  19. dofile(modpath.."/structures/hole.lua")
  20. dofile(modpath.."/util/spiral.lua")
  21. dofile(modpath.."/util/spawn.lua")
  22. -- core
  23. dofile(modpath.."/gates.lua")
  24. dofile(modpath.."/minetunnels.lua")
  25. dofile(modpath.."/beanstalk.lua")
  26. dofile(modpath.."/enchanting.lua")
  27. dofile(modpath.."/alchemy.lua")
  28. --spells
  29. dofile(modpath.."/spells/plant_growth.lua")
  30. -- pure mapgen
  31. dofile(modpath.."/rocks.lua")
  32. -- utility
  33. dofile(modpath.."/scanner.lua")
  34. --[[
  35. potions/magic
  36. destroy all nodes in area of certain type (stone), leaving others
  37. transform all nearby nodes into another node
  38. underwater breathing
  39. dig faster
  40. loaves and fishes when placing nodes
  41. summon a homunculus to provide knowledge
  42. conjure more magic books
  43. wards, ie area node protection
  44. spawn ice crust on nearby water
  45. scry for nearby things; particles lead the way
  46. summon a storm
  47. blight an area
  48. accelerate (certain) plant/fungus growth in an area
  49. conjure a volcano
  50. spawn magma node
  51. forge-style movement
  52. each move takes a time meta value along for cooling
  53. conjure a meteor
  54. freeze/thaw an area
  55. conjure a floatland
  56. conjure butterflies or fireflies
  57. a spell with two areas that sucks life-force from one area and vents it to another
  58. conjure a fully equipped wizard's tower
  59. conjure a (fully equipped) castle
  60. hollow a horizontal tunnel
  61. some potions are thrown, to break and activate where they land
  62. conjure a prison
  63. effectively change biome
  64. clone object
  65. nodes that explode when you dig them
  66. grow a big hollow bubble from the ground
  67. create a space of air
  68. emergent jungle tree with ladder inthe core up to a treehouse
  69. install stairs on a random slope
  70. ward areas
  71. climbable magic blocks, like antigrav
  72. [engine]
  73. stateless particle systems
  74. custom particle shaders
  75. above/below positional abms
  76. on_craft callback
  77. nodes that randomly emit particles on their own
  78. particles that break into or emit more particles
  79. mapgen "regions" or extra biome params ("magicness" or other such variations)
  80. ore-ish registration that guarantees a certain limited number of spawns
  81. mapgen distance-from-center params
  82. store a region in a gem, release later
  83. more particle functions
  84. raillike path prediction and pathing for entities
  85. fermentation, distillation, soaking/boiling pot, ball mill
  86. glass crafting furnace
  87. need books to do certain spells
  88. "Apocryphon" - secret book
  89. ink, black/gold/silver/red
  90. saltpeter, halite, iron(II) sulfate aka green vitriol (melanterite), soda nitre, pot ash
  91. pyrite
  92. iodine (from seaweed)
  93. fossils
  94. fireworks
  95. green alchemist's fire that ignites on and burns water
  96. extra metals:
  97. silver, lead, platinum, rhodium, arsenic, bismuth, mercury, iridium, osmium, zinc
  98. gems:
  99. lapis lazuli, opal, citrine, aquamarine
  100. cyclopian masonry
  101. ancient sunken cities
  102. fumaroles spawning, textures and features
  103. joshua trees (connected node)
  104. bogs
  105. cobwebs
  106. prickly pear - polishing, spawning and fruit
  107. barrel cactus
  108. bamboo forests
  109. clover fields
  110. basalt outcroppings with mesh nodes
  111. undersea sponges
  112. undersea volcanic vents
  113. deep-sea worms
  114. thornbushes
  115. blighted areas, purple miasma, dead plants, etc
  116. creosote bush
  117. pirate ships, treasure chests
  118. quicksand
  119. mayan temples on top of mountains
  120. poppies
  121. magic beanstalk
  122. arching bridge
  123. fancy tower
  124. summon a ziggurat (player is flung into the air while it spawns underneath)
  125. magic armor
  126. regeneration amulets
  127. force field
  128. fireball
  129. spell to unlock chests
  130. treasure maps of some sort
  131. minetunnels:
  132. torches in coves
  133. wood bracing
  134. ceiling bolts
  135. ladders to upper areas
  136. minecart chests
  137. wood walkways over caverns
  138. hail of arrows trap
  139. catapult that flings player back
  140. stone columns in large rooms
  141. chemistry glassware getting used or consumed
  142. brown version of glassware
  143. fancier glassware needed for fancier chemicals
  144. some chemicals are light-sensitive and are ruined or explode if in bright light
  145. some chemicals explode if heated
  146. can place potions bottles on the ground
  147. enchant tools
  148. can only dig certain nodes
  149. explode and damage player if used to dig certain nodes
  150. only works below ground/above ground
  151. ancient artifacts
  152. volcanic hotsprings
  153. geysers
  154. minetunnels a la mobehavior with geodes
  155. pentagram on enchanting table top
  156. higher level enchanting tables
  157. ]]
  158. minetest.register_node("potions:prickly_pear", {
  159. description = "Prickly Pear",
  160. drawtype = "plantlike",
  161. waving = 0,
  162. visual_scale = 2.828,
  163. tiles = {"potions_prickly_pear.png"},
  164. inventory_image = "potions_prickly_pear.png",
  165. wield_image = "default_junglegrass.png",
  166. paramtype = "light",
  167. sunlight_propagates = true,
  168. walkable = false,
  169. buildable_to = true,
  170. groups = {snappy = 3, flora = 1, flammable = 3},
  171. sounds = default.node_sound_leaves_defaults(),
  172. selection_box = {
  173. type = "fixed",
  174. fixed = {-8 / 16, -0.5, -8 / 16, 8 / 16, 0.5, 8 / 16},
  175. },
  176. })
  177. minetest.register_node("potions:prickly_pear_plus", {
  178. description = "Prickly Pear",
  179. drawtype = "plantlike",
  180. waving = 0,
  181. visual_scale = 2,
  182. tiles = {"potions_prickly_pear.png"},
  183. inventory_image = "potions_prickly_pear.png",
  184. wield_image = "default_junglegrass.png",
  185. paramtype = "light",
  186. paramtype2 = "meshoptions",
  187. place_param2 = 2,
  188. sunlight_propagates = true,
  189. walkable = false,
  190. buildable_to = true,
  191. drop = "potions:prickly_pear",
  192. groups = {snappy = 3, flora = 1, flammable = 3},
  193. sounds = default.node_sound_leaves_defaults(),
  194. selection_box = {
  195. type = "fixed",
  196. fixed = {-8 / 16, -0.5, -8 / 16, 8 / 16, 0.5, 8 / 16},
  197. },
  198. })
  199. minetest.register_abm({
  200. nodenames = "potions:prickly_pear",
  201. chance = 20,
  202. interval = 10,
  203. action = function(pos, node)
  204. local meta = minetest.get_meta(pos)
  205. local h = meta:get_int("height") + 1
  206. if 1 ~= math.random(h*h*h*h) then
  207. return
  208. end
  209. local offs = {
  210. {x=1, y=1, z=1},
  211. {x=1, y=1, z=-1},
  212. {x=-1, y=1, z=1},
  213. {x=-1, y=1, z=-1},
  214. }
  215. local p = vector.add(pos, offs[math.random(#offs)])
  216. local opts = {
  217. "potions:prickly_pear_plus",
  218. "potions:prickly_pear_plus",
  219. }
  220. local n = minetest.get_node(p)
  221. if n.name == "air" then
  222. minetest.set_node(p, {name=opts[math.random(#opts)], param2 = 1})
  223. local pmeta = minetest.get_meta(p)
  224. pmeta:set_int("height", h)
  225. end
  226. end
  227. })
  228. minetest.register_abm({
  229. nodenames = "potions:prickly_pear_plus",
  230. chance = 40,
  231. interval = 15,
  232. action = function(pos, node)
  233. local meta = minetest.get_meta(pos)
  234. local h = meta:get_int("height") + 1
  235. if 1 ~= math.random(h*h*h*h) then
  236. return
  237. end
  238. local offs = {
  239. {x=0, y=1, z=1},
  240. {x=0, y=1, z=-1},
  241. {x=1, y=1, z=0},
  242. {x=-1, y=1, z=0},
  243. }
  244. local p = vector.add(pos, offs[math.random(#offs)])
  245. local opts = {
  246. "potions:prickly_pear",
  247. "potions:prickly_pear",
  248. }
  249. local n = minetest.get_node(p)
  250. if n.name == "air" then
  251. minetest.set_node(p, {name=opts[math.random(#opts)]})
  252. local pmeta = minetest.get_meta(p)
  253. pmeta:set_int("height", h)
  254. end
  255. end
  256. })
  257. minetest.register_on_joinplayer(function(player)
  258. local name = player:get_player_name()
  259. local mid = player:hud_add({
  260. hud_elem_type = "image",
  261. position = {x = 0, y = 1},
  262. offset = {x = 10, y = -120},
  263. text = "potions_manna_bar.png",
  264. scale = { x = 1, y = .1},
  265. alignment = { x = 0, y = -1 },
  266. })
  267. player:hud_add({
  268. hud_elem_type = "image",
  269. position = {x = 0, y = 1},
  270. offset = {x = 10, y = -120},
  271. text = "potions_manna_border.png",
  272. scale = { x = 1, y = 1 },
  273. alignment = { x = 0, y = -1 },
  274. })
  275. if player:get_attribute("max_manna") == nil then
  276. player:set_attribute("manna", 10)
  277. player:set_attribute("max_manna", 100)
  278. end
  279. potions_players[name] = {
  280. player = player,
  281. ui = {
  282. manna_bar = mid,
  283. },
  284. }
  285. -- player:hud_change(idx, "text", "New Text")
  286. --
  287. -- local meta = player:get_meta()
  288. -- local digs_text = "Digs: " .. meta:get_int("score:digs")
  289. -- local places_text = "Places: " .. meta:get_int("score:places")
  290. -- local percent = tonumber(meta:get("score:score") or 0.2)
  291. --
  292. -- player:hud_change(ids["bar_foreground"],
  293. -- "scale", { x = percent, y = 1 })
  294. --
  295. print(dump(potions_players[name].default_sky))
  296. end)
  297. minetest.register_on_leaveplayer(function(player)
  298. local name = player:get_player_name()
  299. potions_players[name] = nil
  300. end)
  301. local function update_player_manna(player, increase)
  302. local p = player.player
  303. local manna = tonumber(p:get_attribute("manna")) or 0
  304. local max_manna = tonumber(p:get_attribute("max_manna")) or 100
  305. manna = math.min(manna + increase, max_manna)
  306. local mpct = manna / max_manna
  307. p:hud_change(player.ui.manna_bar, "scale", {x = 1, y = mpct})
  308. p:set_attribute("manna", manna)
  309. end
  310. local function update_all_manna()
  311. for _,p in pairs(potions_players) do
  312. update_player_manna(p, 20) -- HACK manna regenerates quickly for debugging
  313. end
  314. minetest.after(1, update_all_manna)
  315. end
  316. function trigger_negative_manna(player, m)
  317. return false
  318. end
  319. minetest.after(1, update_all_manna)
  320. potions.use_manna = function(player, amt)
  321. local om = tonumber(player:get_attribute("manna")) or 0
  322. local remm = om - amt
  323. local used = amt
  324. if remm < 0 then
  325. local res = trigger_negative_manna(player, m)
  326. if res ~= false then
  327. return res
  328. end
  329. used = om
  330. remm = 0
  331. end
  332. player:set_attribute("manna", remm)
  333. update_player_manna(potions_players[player:get_player_name()], 0)
  334. return used
  335. end
  336. potions.get_manna = function(player)
  337. return tonumber(player:get_attribute("manna")) or 0
  338. end
  339. potions.set_manna = function(player, amt)
  340. local max = tonumber(player:get_attribute("max_manna")) or 100
  341. player:set_attribute("manna", math.max(0, math.min(max, amt)))
  342. update_player_manna(potions_players[player:get_player_name()], 0)
  343. end
  344. potions.add_manna = function(player, amt)
  345. update_player_manna(potions_players[player:get_player_name()], amt)
  346. end
  347. potions.set_max_manna = function(player, amt)
  348. player:set_attribute("manna", math.max(0, amt))
  349. update_player_manna(potions_players[player:get_player_name()], 0)
  350. end
  351. minetest.register_craftitem("potions:holy_water", {
  352. description = "Holy Water",
  353. inventory_image = "potions_healing_broth.png",
  354. stack_max = 5,
  355. })
  356. minetest.register_craftitem("potions:solvent", {
  357. description = "Solvent",
  358. inventory_image = "potions_healing_broth.png",
  359. stack_max = 5,
  360. })
  361. --[[
  362. minetest.register_craft({
  363. output = "potions:solvent 3",
  364. recipe = {
  365. {"flowers:mushroom_red", "dye:red", "default:apple"},
  366. {"", "bucket:bucket_water", ""},
  367. {"vessels:glass_bottle", "vessels:glass_bottle", "vessels:glass_bottle"},
  368. },
  369. replacements = {{"bucket:bucket_water", "bucket:bucket_empty"}},
  370. })
  371. ]]
  372. minetest.register_craftitem("potions:healing_broth", {
  373. description = "Healing Potion Broth",
  374. inventory_image = "potions_healing_broth.png",
  375. stack_max = 5,
  376. })
  377. minetest.register_craftitem("potions:healing", {
  378. description = "Healing Potion",
  379. inventory_image = "potions_healing.png",
  380. stack_max = 5,
  381. on_use = function(itemstack, user, pointed_thing)
  382. user:set_hp(2*10)
  383. itemstack:take_item(1)
  384. local inv = user:get_inventory()
  385. inv:add_item("main", "vessels:glass_bottle 1")
  386. return itemstack
  387. end,
  388. })
  389. minetest.register_craft( {
  390. type = "cooking",
  391. cooktime = 90,
  392. output = "potions:healing",
  393. recipe = "potions:healing_broth",
  394. })
  395. minetest.register_craft({
  396. output = "potions:healing_broth 3",
  397. recipe = {
  398. {"flowers:mushroom_red", "dye:red", "default:apple"},
  399. {"", "bucket:bucket_water", ""},
  400. {"vessels:glass_bottle", "vessels:glass_bottle", "vessels:glass_bottle"},
  401. },
  402. replacements = {{"bucket:bucket_water", "bucket:bucket_empty"}},
  403. })
  404. -- -----------------------------------
  405. minetest.register_craftitem("potions:speed_broth", {
  406. description = "Speed Potion Broth",
  407. inventory_image = "potions_speed_broth.png",
  408. stack_max = 5,
  409. })
  410. minetest.register_craftitem("potions:speed", {
  411. description = "Speed Potion",
  412. inventory_image = "potions_speed.png",
  413. stack_max = 5,
  414. on_use = function(itemstack, user, pointed_thing)
  415. user:set_physics_override({
  416. speed = 3.0,
  417. })
  418. minetest.after(20, function()
  419. user:set_physics_override({
  420. speed = 1.0,
  421. })
  422. end)
  423. itemstack:take_item(1)
  424. local inv = user:get_inventory()
  425. inv:add_item("main", "vessels:glass_bottle 1")
  426. return itemstack
  427. end,
  428. })
  429. minetest.register_craft( {
  430. type = "cooking",
  431. cooktime = 30,
  432. output = "potions:speed",
  433. recipe = "potions:speed_broth",
  434. })
  435. minetest.register_craft({
  436. output = "potions:speed_broth 3",
  437. recipe = {
  438. {"default:mese_crystal_fragment", "dye:yellow", "default:mese_crystal_fragment"},
  439. {"", "bucket:bucket_water", ""},
  440. {"vessels:glass_bottle", "vessels:glass_bottle", "vessels:glass_bottle"},
  441. },
  442. replacements = {{"bucket:bucket_water", "bucket:bucket_empty"}},
  443. })
  444. ----------------------------------------------------
  445. minetest.register_craftitem("potions:lowgrav_broth", {
  446. description = "Low Gravity Potion Broth",
  447. inventory_image = "potions_lowgrav_broth.png",
  448. stack_max = 5,
  449. })
  450. minetest.register_craftitem("potions:lowgrav", {
  451. description = "Low Gravity Potion",
  452. inventory_image = "potions_lowgrav.png",
  453. stack_max = 5,
  454. on_use = function(itemstack, user, pointed_thing)
  455. user:set_physics_override({
  456. gravity = .1,
  457. })
  458. minetest.after(10, function()
  459. user:set_physics_override({
  460. gravity = .5,
  461. })
  462. end)
  463. minetest.after(18, function()
  464. user:set_physics_override({
  465. gravity = .75,
  466. })
  467. end)
  468. minetest.after(25, function()
  469. user:set_physics_override({
  470. gravity = 1.0,
  471. })
  472. end)
  473. itemstack:take_item(1)
  474. local inv = user:get_inventory()
  475. inv:add_item("main", "vessels:glass_bottle 1")
  476. return itemstack
  477. end,
  478. })
  479. minetest.register_craft( {
  480. type = "cooking",
  481. cooktime = 30,
  482. output = "potions:lowgrav",
  483. recipe = "potions:lowgrav_broth",
  484. })
  485. minetest.register_craft({
  486. output = "potions:lowgrav_broth 3",
  487. recipe = {
  488. {"flowers:dandelion_white", "dye:white", "flowers:dandelion_white"},
  489. {"", "bucket:bucket_water", ""},
  490. {"vessels:glass_bottle", "vessels:glass_bottle", "vessels:glass_bottle"},
  491. },
  492. replacements = {{"bucket:bucket_water", "bucket:bucket_empty"}},
  493. })
  494. ----------------------------------------------------
  495. minetest.register_craftitem("potions:teleport_broth", {
  496. description = "Teleportation Potion Broth",
  497. inventory_image = "potions_teleport_broth.png",
  498. stack_max = 4,
  499. })
  500. minetest.register_craftitem("potions:teleport", {
  501. description = "Teleportation Potion",
  502. inventory_image = "potions_teleport.png",
  503. stack_max = 1,
  504. on_use = function(itemstack, user, pointed_thing)
  505. return {name="potions:teleport_recall", count=1, wear=0, metadata=minetest.serialize(user:getpos())}
  506. end,
  507. })
  508. minetest.register_craftitem("potions:teleport_recall", {
  509. description = "Teleportation Recall Potion",
  510. inventory_image = "potions_teleport_recall.png",
  511. stack_max = 1,
  512. on_use = function(itemstack, user, pointed_thing)
  513. local item = itemstack:take_item(1)
  514. local pos = minetest.deserialize(item:get_metadata())
  515. if pos ~= nil then
  516. user:setpos(pos)
  517. end
  518. return "vessels:glass_bottle 1"
  519. end,
  520. })
  521. minetest.register_craft( {
  522. type = "cooking",
  523. cooktime = 30,
  524. output = "potions:teleport",
  525. recipe = "potions:teleport_broth",
  526. })
  527. minetest.register_craft({
  528. output = "potions:teleport_broth 3",
  529. recipe = {
  530. {"default:obsidian_shard", "dye:violet", "default:obsidian_shard"},
  531. {"", "bucket:bucket_water", ""},
  532. {"vessels:glass_bottle", "vessels:glass_bottle", "vessels:glass_bottle"},
  533. },
  534. replacements = {{"bucket:bucket_water", "bucket:bucket_empty"}},
  535. })
  536. -----------------------------------------------
  537. minetest.register_craftitem("potions:flight_broth", {
  538. description = "Flight Potion Broth",
  539. inventory_image = "potions_flight_broth.png",
  540. stack_max = 5,
  541. })
  542. minetest.register_craftitem("potions:flight", {
  543. description = "Flight Potion",
  544. inventory_image = "potions_flight.png",
  545. stack_max = 5,
  546. on_use = function(itemstack, user, pointed_thing)
  547. local name = user:get_player_name()
  548. local privs = minetest.get_player_privs(name)
  549. privs.fly = true
  550. minetest.set_player_privs(name, privs)
  551. minetest.after(14, function()
  552. local privs = minetest.get_player_privs(name)
  553. privs.fly = nil
  554. minetest.set_player_privs(name, privs)
  555. user:set_physics_override({
  556. gravity = .5,
  557. })
  558. end)
  559. minetest.after(18, function()
  560. user:set_physics_override({
  561. gravity = .75,
  562. })
  563. end)
  564. minetest.after(22, function()
  565. user:set_physics_override({
  566. gravity = 1.0,
  567. })
  568. end)
  569. itemstack:take_item(1)
  570. local inv = user:get_inventory()
  571. inv:add_item("main", "vessels:glass_bottle 1")
  572. return itemstack
  573. end,
  574. })
  575. minetest.register_craft( {
  576. type = "cooking",
  577. cooktime = 30,
  578. output = "potions:flight",
  579. recipe = "potions:flight_broth",
  580. })
  581. minetest.register_craft({
  582. output = "potions:flight_broth 3",
  583. recipe = {
  584. {"farming:cotton", "dye:cyan", "farming:cotton"},
  585. {"", "bucket:bucket_water", ""},
  586. {"vessels:glass_bottle", "vessels:glass_bottle", "vessels:glass_bottle"},
  587. },
  588. replacements = {{"bucket:bucket_water", "bucket:bucket_empty"}},
  589. })