added smokebombs and molotov cocktails from Napiophelios.
|
@ -8,10 +8,12 @@ Lighter image created by me with Blender.
|
|||
|
||||
Code:
|
||||
3d torch code and nodebox's from Carbone, by Calinou CC0 1.0 Will be replaced with mesh torches once I figure that bit out.
|
||||
Smokebomb and molotov cocktail coded by Napiophelios
|
||||
|
||||
Inspiration:
|
||||
Napiophelios, from the forum, who gave me some really good ideas from the old campfire mod, which I didn't even know about.
|
||||
|
||||
|
||||
Sound Effects:
|
||||
Sparker sound from BroAsis on Freesound. https://www.freesound.org/people/BroAsis/sounds/106853/
|
||||
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
default
|
||||
farming
|
||||
fire
|
||||
vessels
|
||||
|
|
3
init.lua
|
@ -60,4 +60,5 @@ dofile(minetest.get_modpath('more_fire')..'/nodes.lua')
|
|||
dofile(minetest.get_modpath('more_fire')..'/craftitems.lua')
|
||||
dofile(minetest.get_modpath('more_fire')..'/crafts.lua')
|
||||
dofile(minetest.get_modpath('more_fire')..'/tools.lua')
|
||||
|
||||
dofile(minetest.get_modpath('more_fire')..'/molotov.lua')
|
||||
dofile(minetest.get_modpath('more_fire')..'/smokebomb.lua')
|
||||
|
|
|
@ -0,0 +1,398 @@
|
|||
local THIS_VERSION = "1.0"
|
||||
|
||||
--- 3D vector class/operations.
|
||||
--
|
||||
-- Note that methods can be called in either an object-oriented way:
|
||||
-- v1 = Vec3(1, 2, 3)
|
||||
-- v2 = v1:add({ x = 2, y = 2, z = 0 })
|
||||
-- or as simple functions:
|
||||
-- Vec3.add({ x = 1, y = 2, z = 3 }, { x = 2, y = 2, z = 0 })
|
||||
--
|
||||
-- All methods that can be called on a Vec3 using ":" may be called on a table
|
||||
-- using the second functional syntax, but the first parameter MUST have the
|
||||
-- expected components "x", "y", and "z". If a vector is used as the second
|
||||
-- paramter, it may instead be a list/array with numeric indices, like
|
||||
-- { 1.0, 2.0, 3.0 } in place of { x = 1.0, y = 2.0, z = 3.0 }.
|
||||
--
|
||||
-- @author prestidigitator (as registered at forum.minetest.net)
|
||||
-- @copyright 2013, licensed under WTFPL
|
||||
--
|
||||
local Vec3 = {}
|
||||
local Vec3_meta = {}
|
||||
local Vec3_inst_meta = {}
|
||||
|
||||
Vec3.VERSION = THIS_VERSION
|
||||
|
||||
setmetatable(Vec3, Vec3_meta)
|
||||
Vec3_inst_meta.__index = Vec3
|
||||
|
||||
--- Constructs a Vec3 from three numbers.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- Vec3.new(x, y, z)
|
||||
-- Vec3(x, y, z)
|
||||
--
|
||||
-- @return a new Vec3 object
|
||||
local function Vec3_new(x, y, z)
|
||||
local obj = { x = x or 0.0, y = y or 0.0, z = z or 0.0 }
|
||||
setmetatable(obj, Vec3_inst_meta)
|
||||
return obj
|
||||
end
|
||||
Vec3.new = Vec3_new
|
||||
|
||||
--- Constructs a new copy of a Vec3.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec:new_copy()
|
||||
-- Vec3.new_copy(vec)
|
||||
-- Vec3(vec)
|
||||
--
|
||||
-- @return a new Vec3 object that is a copy of the parameter
|
||||
local function Vec3_new_copy(v)
|
||||
local obj = { x = v.x or v[1] or 0.0,
|
||||
y = v.y or v[2] or 0.0,
|
||||
z = v.z or v[3] or 0.0 }
|
||||
setmetatable(obj, Vec3_inst_meta)
|
||||
return obj
|
||||
end
|
||||
Vec3.new_copy = Vec3_new_copy
|
||||
|
||||
Vec3_meta.__call = function(class, a, b, c)
|
||||
if type(a) == "table" then
|
||||
return Vec3.new_copy(a)
|
||||
else
|
||||
return Vec3.new(a, b, c)
|
||||
end
|
||||
end
|
||||
|
||||
--- Computes the square of the length of a Vec3.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec:len_sq()
|
||||
-- Vec3.len_sq(vec)
|
||||
--
|
||||
-- @return a number
|
||||
local function Vec3_len_sq(v)
|
||||
return v.x^2 + v.y^2 + v.z^2
|
||||
end
|
||||
Vec3.len_sq = Vec3_len_sq
|
||||
|
||||
--- Computes the length of a Vec3.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec:len()
|
||||
-- Vec3.len(vec)
|
||||
--
|
||||
-- @return a number
|
||||
local function Vec3_len(v)
|
||||
return math.sqrt(v.x^2 + v.y^2 + v.z^2)
|
||||
end
|
||||
Vec3.len = Vec3_len
|
||||
|
||||
--- Computes a unit vector pointing in the same direction as a Vec3.
|
||||
-- Undefined for a zero-vector and may throw an error.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec:unit()
|
||||
-- Vec3.unit(vec)
|
||||
--
|
||||
-- @return a new Vec3 with length 1.0
|
||||
local function Vec3_unit(v)
|
||||
local len = math.sqrt(v.x^2 + v.y^2 + v.z^2)
|
||||
return Vec3.new(v.x/len, v.y/len, v.z/len)
|
||||
end
|
||||
Vec3.unit = Vec3_unit
|
||||
|
||||
--- Multiplies a Vec3 by a number.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec:mul(m)
|
||||
-- Vec3.mul(vec, m)
|
||||
-- vec*m
|
||||
-- m*vec
|
||||
--
|
||||
-- @return a new Vec3 object with the result of the operation
|
||||
local function Vec3_mul(v, m)
|
||||
local mn = tonumber(m)
|
||||
if not mn then error("Can't multiply vector by non-scalar") end
|
||||
return Vec3.new(v.x*mn, v.y*mn, v.z*mn)
|
||||
end
|
||||
Vec3.mul = Vec3_mul
|
||||
Vec3_inst_meta.__mul = function(a, b)
|
||||
if type(a) == "table" then
|
||||
return Vec3_mul(a, b)
|
||||
else
|
||||
return Vec3_mul(b, a)
|
||||
end
|
||||
end
|
||||
|
||||
--- Divides a Vec3 by a number.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec:div(m)
|
||||
-- Vec3.div(vec, m)
|
||||
-- vec/m
|
||||
--
|
||||
-- @return a new Vec3 object with the result of the operation
|
||||
local function Vec3_div(v, m)
|
||||
return Vec3.new(v.x/m, v.y/m, v.z/m)
|
||||
end
|
||||
Vec3.div = Vec3_div
|
||||
Vec3_inst_meta.__div = Vec3_div
|
||||
|
||||
--- Negates a Vec3 (signs of all components are inverted).
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec:unm()
|
||||
-- Vec3.unm(vec)
|
||||
-- -vec
|
||||
--
|
||||
-- @return a new Vec3 object with the result of the operation
|
||||
local function Vec3_unm(v)
|
||||
return Vec3.new(-v.x, -v.y, -v.z)
|
||||
end
|
||||
Vec3.unm = Vec3_unm
|
||||
Vec3_inst_meta.__unm = Vec3_unm
|
||||
|
||||
--- Adds two Vec3s or a Vec3 composed of three given components.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec1:add(vec2)
|
||||
-- vec1:add(x, y, z)
|
||||
-- Vec3.add(vec1, vec2)
|
||||
-- Vec3.add(vec1, x, y, z)
|
||||
-- vec1 + vec2
|
||||
--
|
||||
-- @return a new Vec3 object with the result of the operation
|
||||
local function Vec3_add(v, a, b, c)
|
||||
if type(a) == "table" then
|
||||
return Vec3.new(v.x + (a.x or a[1] or 0.0),
|
||||
v.y + (a.y or a[2] or 0.0),
|
||||
v.z + (a.z or a[3] or 0.0))
|
||||
else
|
||||
return Vec3.new(v.x + a, v.y + b, v.z + c)
|
||||
end
|
||||
end
|
||||
Vec3.add = Vec3_add
|
||||
|
||||
--- Subtracts two Vec3s or a Vec3 composed of three given components.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec1:sub(vec2)
|
||||
-- vec1:sub(x, y, z)
|
||||
-- Vec3.sub(vec1, vec2)
|
||||
-- Vec3.sub(vec1, x, y, z)
|
||||
-- vec1 - vec2
|
||||
--
|
||||
-- @return a new Vec3 object with the result of the operation
|
||||
local function Vec3_sub(v, a, b, c)
|
||||
if type(a) == "table" then
|
||||
return Vec3.new(v.x - (a.x or a[1] or 0.0),
|
||||
v.y - (a.y or a[2] or 0.0),
|
||||
v.z - (a.z or a[3] or 0.0))
|
||||
else
|
||||
return Vec3.new(v.x - a, v.y - b, v.z - c)
|
||||
end
|
||||
end
|
||||
Vec3.sub = Vec3_sub
|
||||
|
||||
--- Tests two Vec3s or a Vec3 composed of three given components for
|
||||
-- exact component-wise equality.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec1:eq(vec2)
|
||||
-- vec1:eq(x, y, z)
|
||||
-- Vec3.eq(vec1, vec2)
|
||||
-- Vec3.eq(vec1, x, y, z)
|
||||
-- vec1 == vec2
|
||||
-- vec1 ~= vec2
|
||||
-- Note that because of built-in Lua logic "==" and "~=" work ONLY if
|
||||
-- vec1 and vec2 are actually Vec3s (not tables).
|
||||
--
|
||||
-- @return a new Vec3 object with the result of the operation
|
||||
local function Vec3_eq(v, a, b, c)
|
||||
if type(a) == "table" then
|
||||
return v.x == (a.x or a[1] or 0.0) and
|
||||
v.y == (a.y or a[2] or 0.0) and
|
||||
v.z == (a.z or a[3] or 0.0)
|
||||
else
|
||||
return v.x == a and v.y == b and v.z == c
|
||||
end
|
||||
end
|
||||
Vec3.eq = Vec3_eq
|
||||
|
||||
--- Takes the dot product of a Vec3 and a Vec3s or a Vec3 composed of
|
||||
-- three given components.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec1:dot(vec2)
|
||||
-- vec1:dot(x, y, z)
|
||||
-- Vec3.dot(vec1, vec2)
|
||||
-- Vec3.dot(vec1, x, y, z)
|
||||
--
|
||||
-- @return a number
|
||||
local function Vec3_dot(v, a, b, c)
|
||||
if type(a) == "table" then
|
||||
return v.x * (a.x or a[1] or 0.0) +
|
||||
v.y * (a.y or a[2] or 0.0) +
|
||||
v.z * (a.z or a[3] or 0.0)
|
||||
else
|
||||
return v.x * a + v.y * b + v.z * c
|
||||
end
|
||||
end
|
||||
Vec3.dot = Vec3_dot
|
||||
|
||||
--- Takes the cross product of a Vec3 and a Vec3s or a Vec3 composed of
|
||||
-- three given components.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec1:cross(vec2)
|
||||
-- vec1:cross(x, y, z)
|
||||
-- Vec3.cross(vec1, vec2)
|
||||
-- Vec3.cross(vec1, x, y, z)
|
||||
--
|
||||
-- @return a new Vec3 with the result of the operation
|
||||
local function Vec3_cross(v, a, b, c)
|
||||
local ux, uy, uz
|
||||
if type(a) == "table" then
|
||||
ux = a.x or a[1] or 0.0
|
||||
uy = a.y or a[2] or 0.0
|
||||
uz = a.z or a[3] or 0.0
|
||||
else
|
||||
ux = a or 0.0
|
||||
uy = b or 0.0
|
||||
uz = c or 0.0
|
||||
end
|
||||
|
||||
return Vec3.new(v.y*uz - v.z*uy, v.z*ux - v.x*uz, v.x*uy - v.y*ux)
|
||||
end
|
||||
Vec3.cross = Vec3_cross
|
||||
|
||||
--- Rotates this (the first) vector around the second vector by the
|
||||
-- given angle.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec:rot_around(axis, angle)
|
||||
-- Vec3.rot_around(vec, axis, angle)
|
||||
--
|
||||
-- @param axis
|
||||
-- The axis about which to rotate.
|
||||
-- @param angle
|
||||
-- The angle by which to rotate this vector, in radians.
|
||||
-- @return
|
||||
-- a new Vec3 with the result of the operation.
|
||||
local function Vec3_rot_around(v, axis, angle)
|
||||
local uaxis = Vec3.new_copy(axis):unit()
|
||||
|
||||
local alen = uaxis:dotvec(v)
|
||||
local avec = uaxis:mul(alen)
|
||||
|
||||
local pvec = Vec3.subvec(v, avec)
|
||||
local rvec = uaxis:crossvec(v)
|
||||
|
||||
local v1 = pvec:mul(math.cos(angle))
|
||||
local v2 = rvec:mul(math.sin(angle))
|
||||
|
||||
return avec:addvec(v1):addvec(v2)
|
||||
end
|
||||
Vec3.rot_around = Vec3_rot_around
|
||||
|
||||
--- Adds two Vec3s. Optimized for pure Vec3/table operations by removing
|
||||
-- type checking and conditionals. If called with Vec3-likes table(s),
|
||||
-- ensure all expected components "x", "y", and "z" exist.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec1:addvec(vec2)
|
||||
-- Vec3.addvec(vec1, vec2)
|
||||
--
|
||||
-- @return a new Vec3 object with the result of the operation
|
||||
local function Vec3_addvec(v1, v2)
|
||||
return Vec3.new(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z)
|
||||
end
|
||||
Vec3.addvec = Vec3_addvec
|
||||
Vec3_inst_meta.__add = Vec3_addvec
|
||||
|
||||
--- Subtracts two Vec3s. Optimized for pure Vec3/table operations by
|
||||
-- removing type checking and conditionals. If called with Vec3-likes
|
||||
-- table(s), ensure all expected components "x", "y", and "z" exist.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec1:subvec(vec2)
|
||||
-- Vec3.subvec(vec1, vec2)
|
||||
--
|
||||
-- @return a new Vec3 object with the result of the operation
|
||||
local function Vec3_subvec(v1, v2)
|
||||
return Vec3.new(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z)
|
||||
end
|
||||
Vec3.subvec = Vec3_subvec
|
||||
Vec3_inst_meta.__sub = Vec3_subvec
|
||||
|
||||
--- Tests two Vec3s for exact component-wise equality. Optimized for pure
|
||||
-- Vec3/table operations by removing type checking and conditionals.
|
||||
-- If called with Vec3-likes table(s), ensure all expected components
|
||||
-- "x", "y", and "z" exist.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec1:eqvec(vec2)
|
||||
-- Vec3.eqvec(vec1, vec2)
|
||||
--
|
||||
-- @return a new Vec3 object with the result of the operation
|
||||
local function Vec3_eqvec(v1, v2)
|
||||
return v1.x == v2.x and v1.y == v2.y and v1.z == v2.z
|
||||
end
|
||||
Vec3.eqvec = Vec3_eqvec
|
||||
Vec3_inst_meta.__eq = Vec3_eqvec
|
||||
|
||||
--- Takes the dot product of two Vec3s. Optimized for pure Vec3/table
|
||||
-- operations by removing type checking and conditionals. If called
|
||||
-- with Vec3-likes table(s), ensure all expected components "x", "y",
|
||||
-- and "z" exist.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec1:dotvec(vec2)
|
||||
-- Vec3.dotvec(vec1, vec2)
|
||||
--
|
||||
-- @return a number
|
||||
local function Vec3_dotvec(v1, v2)
|
||||
return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z
|
||||
end
|
||||
Vec3.dotvec = Vec3_dotvec
|
||||
|
||||
--- Takes the cross product of two Vec3s. Optimized for pure Vec3/table
|
||||
-- operations by removing type checking and conditionals. If called
|
||||
-- with Vec3-likes table(s), ensure all expected components "x", "y",
|
||||
-- and "z" exist.
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec1:crossvec(vec2)
|
||||
-- Vec3.crossvec(vec1, vec2)
|
||||
--
|
||||
-- @return a new Vec3 with the result of the operation
|
||||
local function Vec3_crossvec(v1, v2)
|
||||
return Vec3.new(v1.y*v2.z - v1.z*v2.y,
|
||||
v1.z*v2.x - v1.x*v2.z,
|
||||
v1.x*v2.y - v1.y*v2.x)
|
||||
end
|
||||
Vec3.crossvec = Vec3_crossvec
|
||||
|
||||
--- Converts Vec3 to a string with format "(x,y,z)".
|
||||
--
|
||||
-- Call with one of:
|
||||
-- vec:tostring()
|
||||
-- Vec3.tostring(vec)
|
||||
-- tostring(vec)
|
||||
--
|
||||
-- @return a string
|
||||
local function Vec3_tostring(v)
|
||||
return "("..
|
||||
(v.x or v[1] or "0")
|
||||
..","..
|
||||
(v.y or v[2] or "0")
|
||||
..","..
|
||||
(v.z or v[3] or "0")
|
||||
..")"
|
||||
end
|
||||
Vec3.tostring = Vec3_tostring
|
||||
Vec3_inst_meta.__tostring = Vec3_tostring
|
||||
|
||||
return Vec3
|
|
@ -0,0 +1,328 @@
|
|||
--Molotov Cocktail_[rev002]
|
||||
--base code is from throwing enhanced and potions mods
|
||||
|
||||
local MOD_NAME = minetest.get_current_modname()
|
||||
local MOD_PATH = minetest.get_modpath(MOD_NAME)
|
||||
local Vec3 = dofile(MOD_PATH.."/lib/Vec3_1-0.lua")
|
||||
|
||||
more_fire = {}
|
||||
|
||||
minetest.register_craftitem("more_fire:molotov_cocktail", {
|
||||
description = "Molotov Cocktail",
|
||||
inventory_image = "more_fire_molotov_cocktail.png",
|
||||
on_place = function(itemstack, user, pointed_thing)
|
||||
itemstack:take_item()
|
||||
minetest.sound_play("more_fire_shatter", {gain = 1.0})
|
||||
n = minetest.env:get_node(pointed_thing)
|
||||
if pointed_thing.type == "node" then
|
||||
minetest.env:add_node(pointed_thing.above, {name="more_fire:napalm"})
|
||||
minetest.sound_play("more_fire_ignite", {pos,pos})
|
||||
end
|
||||
--Shattered glass Particles
|
||||
minetest.add_particlespawner(40, 0.1,
|
||||
pointed_thing.above, pointed_thing.above,
|
||||
{x=2, y=0.2, z=2}, {x=-2, y=0.5, z=-2},
|
||||
{x=0, y=-6, z=0}, {x=0, y=-10, z=0},
|
||||
0.5, 2,
|
||||
0.2, 5,
|
||||
true, "more_fire_shatter.png")
|
||||
--fire ember particles
|
||||
minetest.add_particlespawner(100, 0.1,
|
||||
pointed_thing.above, pointed_thing.above,
|
||||
{x=-2, y=0.5, z=-2}, {x=2, y=0.5, z=2},
|
||||
{x=0, y=-10, z=0}, {x=0, y=-6, z=0},
|
||||
2, 3,
|
||||
0.25, 0.5,
|
||||
true, "more_fire_spark.png")
|
||||
local dir = Vec3(user:get_look_dir()) *20
|
||||
minetest.add_particle(
|
||||
{x=user:getpos().x, y=user:getpos().y+1.5, z=user:getpos().z}, {x=dir.x, y=dir.y, z=dir.z}, {x=0, y=-10, z=0}, 0.2,
|
||||
6, false, "more_fire_molotov_cocktail.png")
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
local function throw_cocktail(item, player)
|
||||
local playerpos = player:getpos()
|
||||
local obj = minetest.add_entity({x=playerpos.x,y=playerpos.y+1.625,z=playerpos.z}, "more_fire:molotov_entity")
|
||||
local dir = player:get_look_dir()
|
||||
obj:setvelocity({x=dir.x*30, y=dir.y*30, z=dir.z*30})
|
||||
obj:setacceleration({x=dir.x*-3, y=-dir.y^8*80-10, z=dir.z*-3})
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
item:take_item()
|
||||
end
|
||||
return item
|
||||
end
|
||||
|
||||
local radius = 5.0
|
||||
|
||||
local function add_effects(pos, radius)
|
||||
minetest.add_particlespawner({
|
||||
amount = 10,
|
||||
time = 0.2,
|
||||
minpos = vector.subtract(pos, radius / 2),
|
||||
maxpos = vector.add(pos, radius / 2),
|
||||
minvel = {x=-2, y=-2, z=-2},
|
||||
maxvel = {x=2, y=-4, z=2},
|
||||
minacc = {x=0, y=-4, z=0},
|
||||
--~ maxacc = {x=-20, y=-50, z=-50},
|
||||
minexptime = 1,
|
||||
maxexptime = 1.5,
|
||||
minsize = 1,
|
||||
maxsize = 2,
|
||||
texture = "more_fire_spark.png",
|
||||
})
|
||||
minetest.add_particlespawner({
|
||||
amount = 10,
|
||||
time = 0.2,
|
||||
minpos = vector.subtract(pos, radius / 2),
|
||||
maxpos = vector.add(pos, radius / 2),
|
||||
minvel = {x=-1.25, y=-1.25, z=-1.25},
|
||||
maxvel = {x=0.5, y=-4, z=0.5},
|
||||
minacc = {x=1.25, y=-1.25, z=1.25},
|
||||
--~ maxacc = {x=-20, y=-50, z=-50},
|
||||
minexptime =1,
|
||||
maxexptime = 1.5,
|
||||
minsize = 1,
|
||||
maxsize = 2,
|
||||
texture = "more_fire_spark.png",
|
||||
})
|
||||
end
|
||||
|
||||
local function napalm(pos)
|
||||
minetest.sound_play("more_fire_ignite", {pos=pos, gain=1})
|
||||
minetest.set_node(pos, {name="more_fire:napalm"})
|
||||
minetest.get_node_timer(pos):start(5.0)
|
||||
add_effects(pos, radius)
|
||||
end
|
||||
|
||||
local MORE_FIRE_MOLOTOV_ENTITY = {
|
||||
timer=0,
|
||||
collisionbox = {0,0,0,0,0,0},
|
||||
physical = false,
|
||||
textures = {"more_fire_molotov_cocktail.png"},
|
||||
lastpos={},
|
||||
}
|
||||
|
||||
MORE_FIRE_MOLOTOV_ENTITY.on_step = function(self, dtime)
|
||||
self.timer = self.timer + dtime
|
||||
local pos = self.object:getpos()
|
||||
local node = minetest.get_node(pos)
|
||||
minetest.add_particlespawner({
|
||||
amount = 10,
|
||||
time = 0.5,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = {x=-0, y=0, z=-0.5},
|
||||
maxvel = {x=0, y=0, z=-0.75},
|
||||
minacc = vector.new(),
|
||||
maxacc = vector.new(),
|
||||
minexptime = 0.5,
|
||||
maxexptime = 1,
|
||||
minsize = 0.25,
|
||||
maxsize = 0.5,
|
||||
texture = "more_fire_smoke.png",
|
||||
})
|
||||
minetest.add_particlespawner({
|
||||
amount = 100,
|
||||
time = 0.25,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = {x=-0, y=0, z=-0.5},
|
||||
maxvel = {x=0, y=0, z=-0.75},
|
||||
minacc = {x=0, y=0, z=-0.75},
|
||||
maxacc = {x=-0, y=0, z=-0.5},
|
||||
minexptime = 0.25,
|
||||
maxexptime = 0.5,
|
||||
minsize = 0.5,
|
||||
maxsize = 0.75,
|
||||
texture = "more_fire_spark.png",
|
||||
})
|
||||
if self.timer>0.2 then
|
||||
local objs = minetest.env:get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 1)
|
||||
for k, obj in pairs(objs) do
|
||||
if obj:get_luaentity() ~= nil then
|
||||
if obj:get_luaentity().name ~= "more_fire:molotov_entity" and obj:get_luaentity().name ~= "__builtin:item" then
|
||||
if self.node ~= "" then
|
||||
minetest.sound_play("more_fire_shatter", {gain = 1.0})
|
||||
for dx=-3,3 do
|
||||
for dy=-3,3 do
|
||||
for dz=-3,3 do
|
||||
local p = {x=pos.x+dx, y=pos.y+dy, z=pos.z+dz}
|
||||
local n = minetest.env:get_node(pos).name
|
||||
if minetest.registered_nodes[n].groups.flammable or math.random(1, 100) <= 20 then
|
||||
minetest.sound_play("more_fire_ignite", {pos = self.lastpos})
|
||||
minetest.env:set_node(p, {name="more_fire:napalm"})
|
||||
else
|
||||
--minetest.env:remove_node(p)
|
||||
minetest.sound_play("more_fire_ignite", {pos = self.lastpos})
|
||||
minetest.env:set_node(p, {name="fire:basic_flame"})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
self.object:remove()
|
||||
end
|
||||
else
|
||||
if self.node ~= "" then
|
||||
minetest.sound_play("more_fire_shatter", {gain = 1.0})
|
||||
for dx=-2,2 do
|
||||
for dy=-2,2 do
|
||||
for dz=-2,2 do
|
||||
local p = {x=pos.x+dx, y=pos.y+dy, z=pos.z+dz}
|
||||
local n = minetest.env:get_node(pos).name
|
||||
if minetest.registered_nodes[n].groups.flammable or math.random(1, 100) <= 20 then
|
||||
minetest.sound_play("more_fire_ignite", {pos = self.lastpos})
|
||||
minetest.env:set_node(p, {name="more_fire:napalm"})
|
||||
else
|
||||
--minetest.env:remove_node(p)
|
||||
minetest.sound_play("more_fire_ignite", {pos = self.lastpos})
|
||||
minetest.env:set_node(p, {name="fire:basic_flame"})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
self.object:remove()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if self.lastpos.x~=nil then
|
||||
if node.name ~= "air" then
|
||||
if self.node ~= "" then
|
||||
minetest.sound_play("more_fire_shatter", {gain = 1.0})
|
||||
for dx=-1,1 do
|
||||
for dy=-1,1 do
|
||||
for dz=-1,1 do
|
||||
local p = {x=pos.x+dx, y=pos.y+dy, z=pos.z+dz}
|
||||
local n = minetest.env:get_node(pos).name
|
||||
if minetest.registered_nodes[n].groups.flammable or math.random(1, 100) <= 20 then
|
||||
minetest.sound_play("more_fire_ignite", {pos = self.lastpos})
|
||||
minetest.env:set_node(p, {name="more_fire:napalm"})
|
||||
else
|
||||
--minetest.env:remove_node(p)
|
||||
minetest.sound_play("more_fire_ignite", {pos = self.lastpos})
|
||||
minetest.env:set_node(p, {name="fire:basic_flame"})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
self.object:remove()
|
||||
napalm(self.lastpos)
|
||||
end
|
||||
end
|
||||
self.lastpos={x=pos.x, y=pos.y, z=pos.z}
|
||||
end
|
||||
|
||||
minetest.register_entity("more_fire:molotov_entity", MORE_FIRE_MOLOTOV_ENTITY)
|
||||
|
||||
minetest.override_item("more_fire:molotov_cocktail", {on_use = throw_cocktail})
|
||||
|
||||
minetest.register_node("more_fire:napalm", {
|
||||
drawtype = "firelike",
|
||||
tiles = {{
|
||||
name="fire_basic_flame_animated.png",
|
||||
animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=1},
|
||||
}},
|
||||
inventory_image = "fire_basic_flame.png",
|
||||
light_source = 14,
|
||||
groups = {igniter=1,dig_immediate=3, not_in_creative_inventory =1, not_in_craft_guide=1},
|
||||
drop = '',
|
||||
walkable = false,
|
||||
buildable_to = true,
|
||||
damage_per_second = 4,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames={"more_fire:napalm"},
|
||||
neighbors={"air"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos,node,active_object_count,active_object_count_wider)
|
||||
minetest.add_particlespawner(200, 3,
|
||||
pos, pos,
|
||||
{x=2, y=-0.2, z=2}, {x=-2, y=-0.5, z=-2},
|
||||
{x=0, y=-6, z=0}, {x=0, y=-10, z=0},
|
||||
2, 6,
|
||||
0.05, 0.5,
|
||||
false, "more_fire_spark.png")
|
||||
minetest.add_particlespawner(20, 2,
|
||||
pos, pos,
|
||||
{x=-2, y=2, z=-2}, {x=1, y=3, z=1},
|
||||
{x=0, y=6, z=0}, {x=0, y=2, z=0},
|
||||
1, 3,
|
||||
3, 5,
|
||||
false, "more_fire_smoke.png")
|
||||
minetest.add_particlespawner(10, 4,
|
||||
pos, pos,
|
||||
{x=0, y= 3, z=0}, {x=0, y=5, z=0},
|
||||
{x=0.1, y=0.5, z=-0.1}, {x=-0.2, y=2, z=0.2},
|
||||
1, 3,
|
||||
1, 3,
|
||||
false, "more_fire_smoke.png")
|
||||
local r = 0-- Radius for destroying
|
||||
for x = pos.x-r, pos.x+r, 1 do
|
||||
for y = pos.y-r, pos.y+r, 1 do
|
||||
for z = pos.z-r, pos.z+r, 1 do
|
||||
local cpos = {x=x,y=y,z=z}
|
||||
if minetest.env:get_node(cpos).name == "more_fire:napalm" then
|
||||
minetest.env:set_node(cpos,{name="fire:basic_flame"})
|
||||
end
|
||||
if math.random(0,1) == 1
|
||||
or minetest.env:get_node(cpos).name == "more_fire:napalm"
|
||||
then
|
||||
minetest.env:remove_node(cpos)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames={"fire:basic_flame"},
|
||||
neighbors={"air"},
|
||||
interval = 1,
|
||||
chance = 2,
|
||||
action = function(pos, node)
|
||||
if
|
||||
minetest.get_node({x=pos.x, y=pos.y+1.0, z=pos.z}).name == "air" and
|
||||
minetest.get_node({x=pos.x, y=pos.y+2.0, z=pos.z}).name == "air"
|
||||
then
|
||||
minetest.add_particlespawner(30, 2,
|
||||
pos, pos,
|
||||
{x=-2, y=2, z=-2}, {x=1, y=3, z=1},
|
||||
{x=0, y=6, z=0}, {x=0, y=2, z=0},
|
||||
1, 3,
|
||||
10, 20,
|
||||
false, "more_fire_smoke.png")
|
||||
minetest.add_particlespawner(15, 4,
|
||||
pos, pos,
|
||||
{x=0, y= 3, z=0}, {x=0, y=5, z=0},
|
||||
{x=0.1, y=0.5, z=-0.1}, {x=-0.2, y=2, z=0.2},
|
||||
1, 3,
|
||||
5, 10,
|
||||
false, "more_fire_smoke.png")
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
--crafting recipes
|
||||
minetest.register_craft( {
|
||||
output = 'more_fire:molotov_cocktail',
|
||||
recipe = {
|
||||
{'farming:cotton'},
|
||||
{'more_fire:oil'},
|
||||
{'vessels:glass_bottle'},
|
||||
}
|
||||
})
|
||||
|
||||
-- fuel recipes
|
||||
minetest.register_craft({
|
||||
type = 'fuel',
|
||||
recipe = 'more_fire:molotov_cocktail',
|
||||
burntime = 5,
|
||||
})
|
|
@ -0,0 +1,252 @@
|
|||
--Smoke Bomb_[rev001]
|
||||
--base code is from throwing enhanced and potions mods
|
||||
|
||||
local MOD_NAME = minetest.get_current_modname()
|
||||
local MOD_PATH = minetest.get_modpath(MOD_NAME)
|
||||
local Vec3 = dofile(MOD_PATH.."/lib/Vec3_1-0.lua")
|
||||
|
||||
more_fire = {}
|
||||
|
||||
minetest.register_craftitem("more_fire:smokebomb", {
|
||||
description = "Smoke Bomb",
|
||||
inventory_image = "more_fire_smokebomb.png",
|
||||
on_place = function(itemstack, user, pointed_thing)
|
||||
itemstack:take_item()
|
||||
minetest.sound_play("more_fire_shatter", {gain = 1.0})
|
||||
--Shattered glass Particles
|
||||
minetest.add_particlespawner(40, 0.1,
|
||||
pointed_thing.above, pointed_thing.above,
|
||||
{x=2, y=0.2, z=2}, {x=-2, y=0.5, z=-2},
|
||||
{x=0, y=-6, z=0}, {x=0, y=-10, z=0},
|
||||
0.5, 2,
|
||||
0.2, 5,
|
||||
true, "more_fire_shatter.png")
|
||||
--smoke particles
|
||||
minetest.add_particlespawner(400, 0.1,
|
||||
pointed_thing.above, pointed_thing.above,
|
||||
{x=2, y=0.2, z=2}, {x=-2, y=0.5, z=-2},
|
||||
{x=0, y=-6, z=0}, {x=0, y=-10, z=0},
|
||||
5, 2,
|
||||
20, 5,
|
||||
true, "more_fire_smoke.png")
|
||||
--more smoke particles
|
||||
minetest.add_particlespawner(600, 1,
|
||||
pointed_thing.above, pointed_thing.above,
|
||||
{x=10, y= 3, z=10}, {x=-10, y= 3, z=-10},
|
||||
{x=2, y=2, z=2}, {x=-2, y=1, z=-2},
|
||||
2, 3,
|
||||
20, 2,
|
||||
true, "more_fire_smoke.png")
|
||||
--even more smoke particles
|
||||
minetest.add_particlespawner(400, 1,
|
||||
pointed_thing.above, pointed_thing.above,
|
||||
{x=0.2, y=0.2, z=0.2}, {x=-0.2, y=0.5, z=-0.2},
|
||||
{x=10, y= 2, z=10}, {x=-10, y= 1, z=-10},
|
||||
2, 3,
|
||||
20, 2,
|
||||
true, "more_fire_smoke.png")
|
||||
local dir = Vec3(user:get_look_dir()) *20
|
||||
minetest.add_particle(
|
||||
{x=user:getpos().x, y=user:getpos().y+1.5, z=user:getpos().z}, {x=dir.x, y=dir.y, z=dir.z}, {x=0, y=-10, z=0}, 0.2,
|
||||
6, false, "more_fire_smokebomb.png")
|
||||
return itemstack
|
||||
end,
|
||||
})
|
||||
|
||||
local function throw_smokebomb(item, player)
|
||||
local playerpos = player:getpos()
|
||||
local obj = minetest.add_entity({x=playerpos.x,y=playerpos.y+1.625,z=playerpos.z}, "more_fire:smokebomb_entity")
|
||||
local dir = player:get_look_dir()
|
||||
obj:setvelocity({x=dir.x*30, y=dir.y*30, z=dir.z*30})
|
||||
obj:setacceleration({x=dir.x*-3, y=-dir.y^8*80-10, z=dir.z*-3})
|
||||
if not minetest.setting_getbool("creative_mode") then
|
||||
item:take_item()
|
||||
end
|
||||
return item
|
||||
end
|
||||
|
||||
local radius = 5
|
||||
|
||||
local function add_effects(pos, radius)
|
||||
minetest.add_particlespawner({
|
||||
amount = 200,
|
||||
time = 0.1,
|
||||
minpos = vector.subtract(pos, radius / 3),
|
||||
maxpos = vector.add(pos, radius / 3),
|
||||
minvel = {x=2, y=0.2, z=2},
|
||||
maxvel = {x=-2, y=-0.5, z=-2},
|
||||
minacc = {x=1, y=-6, z=1},
|
||||
maxacc = {x=1, y=-10, z=1},
|
||||
minexptime = 1,
|
||||
maxexptime = 5,
|
||||
minsize = 10,
|
||||
maxsize = 20,
|
||||
texture = "more_fire_smoke.png",
|
||||
})
|
||||
minetest.add_particlespawner({
|
||||
amount = 100,
|
||||
time = 2,
|
||||
minpos = vector.subtract(pos, radius / 2),
|
||||
maxpos = vector.add(pos, radius / 2),
|
||||
minvel = {x=0.2, y=0.2, z=0.2},
|
||||
maxvel = {x=-0.2, y=0.5, z=-0.2},
|
||||
minacc = {x=10, y= 2, z=10},
|
||||
maxacc = {x=-10, y= 1, z=-10},
|
||||
minexptime =1,
|
||||
maxexptime = 3,
|
||||
minsize = 5,
|
||||
maxsize = 15,
|
||||
texture = "more_fire_smoke.png",
|
||||
})
|
||||
end
|
||||
|
||||
local function plume(pos)
|
||||
minetest.set_node(pos, {name="more_fire:plume"})
|
||||
minetest.get_node_timer(pos):start(3.0)
|
||||
add_effects(pos, radius)
|
||||
end
|
||||
|
||||
local MORE_FIRE_SMOKEBOMB_ENTITY = {
|
||||
timer=0,
|
||||
collisionbox = {0,0,0,0,0,0},
|
||||
physical = false,
|
||||
textures = {"more_fire_smokebomb.png"},
|
||||
lastpos={},
|
||||
}
|
||||
|
||||
MORE_FIRE_SMOKEBOMB_ENTITY.on_step = function(self, dtime)
|
||||
self.timer = self.timer + dtime
|
||||
local pos = self.object:getpos()
|
||||
local node = minetest.get_node(pos)
|
||||
minetest.add_particlespawner({
|
||||
amount = 10,
|
||||
time = 0.5,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = {x=-0, y=0, z=-0.5},
|
||||
maxvel = {x=0, y=0, z=-0.75},
|
||||
minacc = vector.new(),
|
||||
maxacc = vector.new(),
|
||||
minexptime = 0.5,
|
||||
maxexptime = 1,
|
||||
minsize = 0.25,
|
||||
maxsize = 0.5,
|
||||
texture = "more_fire_smoke.png",
|
||||
})
|
||||
minetest.add_particlespawner({
|
||||
amount = 10,
|
||||
time = 0.25,
|
||||
minpos = pos,
|
||||
maxpos = pos,
|
||||
minvel = {x=-0, y=0, z=-0.5},
|
||||
maxvel = {x=0, y=0, z=-0.75},
|
||||
minacc = {x=0, y=0, z=-0.75},
|
||||
maxacc = {x=-0, y=0, z=-0.5},
|
||||
minexptime = 0.25,
|
||||
maxexptime = 0.5,
|
||||
minsize = 0.5,
|
||||
maxsize = 0.75,
|
||||
texture = "more_fire_smoke.png",
|
||||
})
|
||||
if self.timer>0.2 then
|
||||
local objs = minetest.env:get_objects_inside_radius({x=pos.x,y=pos.y,z=pos.z}, 1)
|
||||
for k, obj in pairs(objs) do
|
||||
if obj:get_luaentity() ~= nil then
|
||||
if obj:get_luaentity().name ~= "more_fire:smokebomb_entity" and obj:get_luaentity().name ~= "__builtin:item" then
|
||||
if self.node ~= "" then
|
||||
minetest.sound_play("more_fire_shatter", {gain = 1.0})
|
||||
local damage = 1
|
||||
obj:punch(self.object, 1.0, {
|
||||
full_punch_interval=1.0,
|
||||
damage_groups={fleshy=damage},
|
||||
}, nil)
|
||||
self.object:remove()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if self.lastpos.x~=nil then
|
||||
if node.name ~= "air" then
|
||||
self.object:remove()
|
||||
plume(self.lastpos)
|
||||
end
|
||||
end
|
||||
self.lastpos={x=pos.x, y=pos.y, z=pos.z}
|
||||
end
|
||||
end
|
||||
|
||||
minetest.register_entity("more_fire:smokebomb_entity", MORE_FIRE_SMOKEBOMB_ENTITY)
|
||||
|
||||
minetest.override_item("more_fire:smokebomb", {on_use = throw_smokebomb})
|
||||
|
||||
minetest.register_node("more_fire:plume", {
|
||||
drawtype = "plantlike",
|
||||
description = "Smoke Plume",
|
||||
tiles = {{
|
||||
name="more_fire_smoke_animated.png",
|
||||
animation={type="vertical_frames", aspect_w=16, aspect_h=16, length=1},
|
||||
}},
|
||||
inventory_image = "more_fire_smoke.png",
|
||||
light_source = 8,
|
||||
groups = {dig_immediate=3, not_in_creative_inventory =1, not_in_craft_guide=1},
|
||||
drop = '',
|
||||
walkable = false,
|
||||
buildable_to = true,
|
||||
on_timer = function(pos, elapsed)
|
||||
minetest.remove_node(pos)
|
||||
end,
|
||||
damage_per_second = 1,
|
||||
})
|
||||
|
||||
minetest.register_abm({
|
||||
nodenames={"more_fire:plume"},
|
||||
neighbors={"air"},
|
||||
interval = 1,
|
||||
chance = 1,
|
||||
action = function(pos, node)
|
||||
if
|
||||
minetest.get_node({x=pos.x, y=pos.y+1.0, z=pos.z}).name == "air" and
|
||||
minetest.get_node({x=pos.x, y=pos.y+2.0, z=pos.z}).name == "air"
|
||||
then
|
||||
minetest.add_particlespawner(400, 3,
|
||||
pos, pos,
|
||||
{x=2, y=-0.2, z=2}, {x=-2, y=-0.5, z=-2},
|
||||
{x=0, y=-6, z=0}, {x=0, y=-10, z=0},
|
||||
2, 6,
|
||||
0.05, 0.5,
|
||||
false, "more_fire_smoke.png")
|
||||
minetest.add_particlespawner(50, 2,
|
||||
pos, pos,
|
||||
{x=-2, y=0.5, z=-2}, {x=2, y=0.5, z=2},
|
||||
{x=0, y=0.04, z=0}, {x=0, y=0.01, z=0},
|
||||
1, 3,
|
||||
3, 5,
|
||||
false, "more_fire_smoke.png")
|
||||
minetest.add_particlespawner({
|
||||
amount = 400,
|
||||
time = 2,
|
||||
minpos = vector.subtract(pos, radius / 2),
|
||||
maxpos = vector.add(pos, radius / 2),
|
||||
minvel = {x=0.2, y=2, z=0.2},
|
||||
maxvel = {x=-0.2, y=2, z=-0.2},
|
||||
minacc = {x=10, y= 2, z=10},
|
||||
maxacc = {x=-10, y= 1, z=-10},
|
||||
minexptime =1,
|
||||
maxexptime = 3,
|
||||
minsize = 5,
|
||||
maxsize = 15,
|
||||
texture = "more_fire_smoke.png",
|
||||
})
|
||||
end
|
||||
end
|
||||
})
|
||||
|
||||
--crafting recipes
|
||||
minetest.register_craft( {
|
||||
output = 'more_fire:smoke_bomb',
|
||||
recipe = {
|
||||
{'more_fire:flintstone'},
|
||||
{'more_fire:charcoal'},
|
||||
{'vessels:glass_bottle'},
|
||||
}
|
||||
})
|
After Width: | Height: | Size: 117 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 101 B |
Before Width: | Height: | Size: 419 B After Width: | Height: | Size: 8.5 KiB |
After Width: | Height: | Size: 80 KiB |
After Width: | Height: | Size: 419 B |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 268 B |