From c934cfa4811afaf35b79949dc845ce24f9a8edb3 Mon Sep 17 00:00:00 2001 From: Treer Date: Sat, 27 Jul 2019 19:50:59 +1000 Subject: [PATCH] Add animated particle support Also implements an ignition failure sound. --- README.md | 1 + init.lua | 52 +++++++++++++++------------ portal_api.lua | 44 +++++++++++++++-------- portal_api.txt | 56 ++++++++++++++++++----------- textures/nether_particle_anim1.png | Bin 0 -> 292 bytes textures/nether_particle_anim2.png | Bin 0 -> 275 bytes textures/nether_particle_anim3.png | Bin 0 -> 385 bytes 7 files changed, 96 insertions(+), 57 deletions(-) create mode 100644 textures/nether_particle_anim1.png create mode 100644 textures/nether_particle_anim2.png create mode 100644 textures/nether_particle_anim3.png diff --git a/README.md b/README.md index 82f201b..1d11224 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ SOFTWARE. ### [Attribution-ShareAlike 4.0 International (CC BY-SA 4.0)](https://creativecommons.org/licenses/by-sa/4.0/) * `nether_book_`* (files starting with "nether_book"): Treer, 2019 * `nether_portal_ignition_failure.ogg`: Treer, 2019 + * `nether_particle_anim`* (files starting with "nether_particle_anim"): Treer, 2019 ### [Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)](http://creativecommons.org/licenses/by-sa/3.0/) * `nether_rack.png`: Zeg9 diff --git a/init.lua b/init.lua index 7d8d5be..1f7b312 100644 --- a/init.lua +++ b/init.lua @@ -40,7 +40,10 @@ dofile(nether.path .. "/mapgen.lua") -- Portals are ignited by right-clicking with a mese crystal fragment -nether.register_portal_ignition_item("default:mese_crystal_fragment") +nether.register_portal_ignition_item( + "default:mese_crystal_fragment", + {name = "nether_portal_ignition_failure", gain = 0.3} +) -- Use the Portal API to add a portal type which goes to the Nether @@ -111,29 +114,34 @@ The expedition parties have found no diamonds or gold, and after an experienced end end, - on_ignite = function(portalDef, anochorPos, orientation) + on_ignite = function(portalDef, anchorPos, orientation) - local make_sparks_fly = function(pos) - minetest.add_particlespawner({ - amount = 14, - time = 0.1, - minpos = {x = pos.x - 0.25, y = pos.y - 0.25, z = pos.z - 0.25}, - maxpos = {x = pos.x + 0.25, y = pos.y + 0.25, z = pos.z + 0.25}, - minvel = {x = -5, y = -1, z = -5}, - maxvel = {x = 5, y = 1, z = 5}, - minacc = {x = 0, y = 0, z = 0}, - maxacc = {x = 0, y = 0, z = 0}, - minexptime = 0.1, - maxexptime = 0.5, - minsize = 0.2, - maxsize = 0.8, - collisiondetection = false, - texture = portalDef.particle_texture .. "^[colorize:#F4F:alpha", - glow = 8 - }) - end + -- make some sparks fly + local p1, p2 = portalDef.shape:get_p1_and_p2_from_anchorPos(anchorPos, orientation) + local pos = vector.divide(vector.add(p1, p2), 2) + + local textureName = portalDef.particle_texture + if type(textureName) == "table" then textureName = textureName.name end + + minetest.add_particlespawner({ + amount = 110, + time = 0.1, + minpos = {x = pos.x - 0.5, y = pos.y - 1.2, z = pos.z - 0.5}, + maxpos = {x = pos.x + 0.5, y = pos.y + 1.2, z = pos.z + 0.5}, + minvel = {x = -5, y = -1, z = -5}, + maxvel = {x = 5, y = 1, z = 5}, + minacc = {x = 0, y = 0, z = 0}, + maxacc = {x = 0, y = 0, z = 0}, + minexptime = 0.1, + maxexptime = 0.5, + minsize = 0.2 * portalDef.particle_texture_scale, + maxsize = 0.8 * portalDef.particle_texture_scale, + collisiondetection = false, + texture = textureName .. "^[colorize:#F4F:alpha", + animation = portalDef.particle_texture_animation, + glow = 8 + }) - portalDef.shape.apply_func_to_wormhole_nodes(anochorPos, orientation, make_sparks_fly) end }) \ No newline at end of file diff --git a/portal_api.lua b/portal_api.lua index 65509d7..30b2b69 100644 --- a/portal_api.lua +++ b/portal_api.lua @@ -1064,11 +1064,12 @@ function run_wormhole(timerPos, time_elapsed) minacc = {x = 0, y = 0, z = 0}, maxacc = {x = 0, y = 0, z = 0}, minexptime = 0.5, - maxexptime = 1.5, - minsize = 0.5, - maxsize = 1.5, + maxexptime = 1.7, + minsize = 0.5 * portal_definition.particle_texture_scale, + maxsize = 1.5 * portal_definition.particle_texture_scale, collisiondetection = false, - texture = portal_definition.particle_texture_colored, + texture = portal_definition.particle_texture_colored, + animation = portal_definition.particle_texture_animation, glow = 5 }) end @@ -1416,15 +1417,17 @@ end) -- The fallback defaults for registered portaldef tables local portaldef_default = { - shape = PortalShape_Traditional, - wormhole_node_name = "nether:portal", - wormhole_node_color = 0, - frame_node_name = "default:obsidian", - particle_texture = "nether_particle.png", + shape = PortalShape_Traditional, + wormhole_node_name = "nether:portal", + wormhole_node_color = 0, + frame_node_name = "default:obsidian", + particle_texture = "nether_particle.png", + particle_texture_animation = nil, + particle_texture_scale = 1, sounds = { ambient = {name = "nether_portal_ambient", gain = 0.6, length = 3}, - ignite = {name = "nether_portal_ignite", gain = 0.5}, - extinguish = {name = "nether_portal_extinguish", gain = 0.5}, + ignite = {name = "nether_portal_ignite", gain = 0.7}, + extinguish = {name = "nether_portal_extinguish", gain = 0.6}, teleport = {name = "nether_portal_teleport", gain = 0.3} } } @@ -1454,8 +1457,14 @@ function nether.register_portal(name, portaldef) portaldef.particle_color = minetest.rgba(rgb.r, rgb.g, rgb.b) end if portaldef.particle_texture_colored == nil then - -- Combine the particle texture with the particle color unless a colored particle texture was specified. - portaldef.particle_texture_colored = portaldef.particle_texture .. "^[colorize:" .. portaldef.particle_color .. ":alpha" + -- Combine the particle texture with the particle color unless a particle_texture_colored was specified. + if type(portaldef.particle_texture) == "table" and portaldef.particle_texture.animation ~= nil then + portaldef.particle_texture_colored = portaldef.particle_texture.name .. "^[colorize:" .. portaldef.particle_color .. ":alpha" + portaldef.particle_texture_animation = portaldef.particle_texture.animation + portaldef.particle_texture_scale = portaldef.particle_texture.scale or 1 + else + portaldef.particle_texture_colored = portaldef.particle_texture .. "^[colorize:" .. portaldef.particle_color .. ":alpha" + end end if portaldef.find_surface_anchorPos == nil then -- default to using find_surface_target_y() @@ -1499,16 +1508,21 @@ function nether.unregister_portal(name) return result end -function nether.register_portal_ignition_item(item_name) +function nether.register_portal_ignition_item(item_name, ignition_failure_sound) minetest.override_item(item_name, { on_place = function(stack, _, pt) + local done = false if pt.under and is_frame_node[minetest.get_node(pt.under).name] then - local done = ignite_portal(pt.under) + done = ignite_portal(pt.under) if done and not minetest.settings:get_bool("creative_mode") then stack:take_item() end end + if not done and ignition_failure_sound ~= nil then + minetest.sound_play(ignition_failure_sound, {pos = pt.under, max_hear_distance = 10}) + end + return stack end, diff --git a/portal_api.txt b/portal_api.txt index c7f2ba6..2806683 100644 --- a/portal_api.txt +++ b/portal_api.txt @@ -48,7 +48,9 @@ Call these functions only at load time: * Unregisters the portal from the engine, and deletes the entry with key `name` from `nether.registered_portals` and associated internal tables. * Returns true on success -* register_portal_ignition_item(name) +* register_portal_ignition_item(name, ignition_failure_sound) + * ignition_failure_sound is optional, it plays any time an attempt to use + the item occurs if a portal is not ignited. @@ -58,31 +60,45 @@ Portal definition Used by `nether.register_portal`. { - shape = PortalShape_Traditional, + shape = PortalShape_Traditional, -- optional. - wormhole_node_name = "nether:portal", + wormhole_node_name = "nether:portal", -- optional. Allows a custom wormhole node to be specified. -- Useful if you want the portals to have a different post_effect_color -- or texture. - wormhole_node_color = 0, + wormhole_node_color = 0, -- A value from 0 to 7 corresponding to the color of pixels in -- nether_portals_palette.png: - -- 0 traditional/magenta - -- 1 black - -- 2 blue - -- 3 green - -- 4 cyan - -- 5 red - -- 6 yellow - -- 7 white + -- 0 traditional/magenta + -- 1 black + -- 2 blue + -- 3 green + -- 4 cyan + -- 5 red + -- 6 yellow + -- 7 white - particle_color = "#808", + particle_color = "#808", -- Optional. Will default to a colour matching the wormhole_node_color -- if not specified. - frame_node_name = "default:obsidian", + particle_texture = "image.png", + -- Optional. Animation and particle scale may also be specified, e.g: + -- particle_texture = { + -- name = "nether_particle_anim1.png", + -- animation = { + -- type = "vertical_frames", + -- aspect_w = 7, + -- aspect_h = 7, + -- length = 1, + -- }, + -- scale = 1.5 + -- }, + -- See lua_api.txt for Tile Animation definition + + frame_node_name = "default:obsidian", -- Required. For best results, have your portal constructed of a -- material nobody else is using. @@ -100,7 +116,7 @@ Used by `nether.register_portal`. -- Required. Return true if a portal at pos is in the realm, rather than the surface world. - find_realm_anchorPos = function(surface_anchorPos), + find_realm_anchorPos = function(surface_anchorPos), -- Required. Return a position in the realm that a portal created at -- surface_anchorPos will link to. -- Return an anchorPos or anchorPos, orientation @@ -110,7 +126,7 @@ Used by `nether.register_portal`. -- orientation, otherwise the existing portal could be overwritten by -- a new one with the orientation of the surface portal. - find_surface_anchorPos = function(realm_anchorPos), + find_surface_anchorPos = function(realm_anchorPos), -- Optional. If you don't implement this then a position near the -- surface will be picked. -- Return an anchorPos or (anchorPos, orientation) @@ -120,16 +136,16 @@ Used by `nether.register_portal`. -- orientation, otherwise the existing portal could be overwritten by -- a new one with the orientation of the realm portal. - on_run_wormhole = function(portalDef, anochorPos, orientation), + on_run_wormhole = function(portalDef, anochorPos, orientation), -- invoked once per second per portal - on_extinguish = function(portalDef, anochorPos, orientation), + on_extinguish = function(portalDef, anochorPos, orientation), -- invoked when a portal is extinguished, including when the portal -- it connected to was extinguished. on_player_teleported = function(portalDef, player, oldPos, newPos), -- invoked immediately after a player is teleported on_ignite = function(portalDef, anochorPos, orientation) -- invoked when a player or mesecon ignites a portal - on_created = function(portalDef, anochorPos, orientation) + on_created = function(portalDef, anochorPos, orientation) -- invoked when a portal's remote twin is created, usually when a -- player travels through a portal for the first time. - } + } diff --git a/textures/nether_particle_anim1.png b/textures/nether_particle_anim1.png new file mode 100644 index 0000000000000000000000000000000000000000..7518037d4ecf710c7831607797ba30c4b378eb8c GIT binary patch literal 292 zcmeAS@N?(olHy`uVBq!ia0vp^>_Du=!2%?&W_E4>Qk(@Ik;M!QDlb8pF+k<{51?SH zr;B5V#`(PyPV*iz;Bknza!KU+evW5nX;+Hfrr@JO{m#NG_bRY3#lKPix%j!t@fkm4 z*^1YvCnY7THYB7v^UOY)#-Sv(wZq3@!pan;f^AZdlD{)yYb^i( literal 0 HcmV?d00001 diff --git a/textures/nether_particle_anim2.png b/textures/nether_particle_anim2.png new file mode 100644 index 0000000000000000000000000000000000000000..244cd83dca124fa7129179cb0dbcb648ca21b1ca GIT binary patch literal 275 zcmeAS@N?(olHy`uVBq!ia0vp^>_BYD!2%@rR8+qJQk(@Ik;M!QDlb8pF+k<{51?R) zr;B5V#`(3APV*j6;Bn49QZ{#c?0MT3hXspXvFGvi%@JVH&MV zxlQtX>yrL`xU)+||6h1`ZDX6OI_ literal 0 HcmV?d00001 diff --git a/textures/nether_particle_anim3.png b/textures/nether_particle_anim3.png new file mode 100644 index 0000000000000000000000000000000000000000..da33cd61f547f7e44dc484412e7af94b9dd1d2ee GIT binary patch literal 385 zcmeAS@N?(olHy`uVBq!ia0vp^>_F_x!2%=?%-9AJ;4JWnEM{O(c?rUd0V>ab00kd; zx;TbdoSr)Q_Qb;m9IpH`zf91(!M085*X3>H-<{PsEN5E$GTL^gwz2c;of}^HTLV0b z6j_{3sJ6z;cqY0!Y~stpYM)2UxXTGqzbKl6_7_>m%<6!ksm;>nW}7e89+u6rTe zZuNAxDd(@>t=Pc))R}v!uZ~1gNRx8p_nRN`&e>V&{=TYxDm_smnW>lS&y`h-wbSHl z6IZtGWscMSd6utg)1@W9uI>8vUVfgYi{~AYzsx5BeoIE(*?S7;Th$WRh!V%5lFZ@~ zhLEDv)FOq9l9GaAD}DX+%#w`KB)#PPTz#;_&6e&zKn)@w4bJ%ml|`B986^xx28Naj VV0phiO{anK44$rjF6*2UngA?gqGbR8 literal 0 HcmV?d00001