The mod is reborn
This commit is contained in:
parent
ebb7410e0c
commit
058ab87d2f
41
.luacheckrc
Normal file
41
.luacheckrc
Normal file
@ -0,0 +1,41 @@
|
||||
globals = {
|
||||
"fire_plus",
|
||||
}
|
||||
|
||||
read_globals = {
|
||||
"DIR_DELIM",
|
||||
"minetest", "core",
|
||||
"dump", "dump2",
|
||||
"vector",
|
||||
"VoxelManip", "VoxelArea",
|
||||
"PseudoRandom", "PcgRandom",
|
||||
"ItemStack",
|
||||
"Settings",
|
||||
"unpack",
|
||||
|
||||
"tnt",
|
||||
|
||||
table = {
|
||||
fields = {
|
||||
"copy",
|
||||
"indexof",
|
||||
"insert_all",
|
||||
"key_value_swap",
|
||||
}
|
||||
},
|
||||
|
||||
string = {
|
||||
fields = {
|
||||
"split",
|
||||
"trim",
|
||||
}
|
||||
},
|
||||
|
||||
math = {
|
||||
fields = {
|
||||
"hypot",
|
||||
"sign",
|
||||
"factorial"
|
||||
}
|
||||
},
|
||||
}
|
2
LICENSE
2
LICENSE
@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Lone_Wolf
|
||||
Copyright (c) 2019-2021 LoneWolfHT
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
44
README.md
44
README.md
@ -1,29 +1,25 @@
|
||||
# fire_plus
|
||||
# Fire Plus
|
||||
[![ContentDB](https://content.minetest.net/packages/Lone_Wolf/fire_plus/shields/downloads/)](https://content.minetest.net/packages/Lone_Wolf/fire_plus/)
|
||||
![GitHub](https://img.shields.io/github/license/Dumpster-Studios/fire_plus?color=blue)
|
||||
|
||||
Allows players to be lit on fire by various fire-related things.
|
||||
|
||||
Visuals include HUD effect and fire particles around player.
|
||||
You can put yourself out by jumping into water/snow.
|
||||
|
||||
![Screenshot](screenshot.png)
|
||||
|
||||
## API
|
||||
|
||||
* `fire_plus.burnplayer(player)`
|
||||
Sets `player` on fire
|
||||
* player - player object
|
||||
|
||||
* `fire_plus.get_burn_dmg(player)`
|
||||
Returns how much damage `player` should take from fire
|
||||
default is 1
|
||||
* `player` - player object
|
||||
|
||||
* `fire_plus.burn_player(player, burns, damage)`
|
||||
* Sets `player` on fire and burns them `burns` times with `damage` damage every second
|
||||
* `fire_plus.tnt_explode_radius`
|
||||
How close to a TNT node a player has to be to detonate it
|
||||
|
||||
* How close to a TNT node a player has to be to detonate it
|
||||
* `fire_plus.ignition_nodes`
|
||||
Nodes that set player on fire. Example:
|
||||
* `table.insert(fire_plus.ignition_nodes, "fire")`
|
||||
All nodes with `fire` in their itemstring will set a player on fire
|
||||
|
||||
* `fire_plus.put_outs`
|
||||
Nodes that put out burning players. Example:
|
||||
* `table.insert(fire_plus.ignition_nodes, "water")`
|
||||
All nodes with `water` in their itemstring will put out a burning player
|
||||
|
||||
* `Fire tools`
|
||||
Allows modders to make tools set any players they hit on fire.
|
||||
Just set `tool_capabilities.damage_groups.burn = 1`
|
||||
* Nodes that set players on fire. See the init.lua for examples
|
||||
* `fire_plus.extinguishers`
|
||||
* Nodes that put out burning players. See the init.lua for examples
|
||||
* **Fire tools**
|
||||
* You can allow modders to make tools light punched players on fire
|
||||
* Just set `tool_capabilities.damage_groups.burns = <How much damage to do each burn>`
|
||||
* There's also `tool_capabilities.damage_groups.burn_time = <How many times to burn the player>`
|
||||
|
118
api.lua
Normal file
118
api.lua
Normal file
@ -0,0 +1,118 @@
|
||||
-- Replace min/max table with random value from min to max
|
||||
local function get_val(val)
|
||||
if type(val) == "table" then
|
||||
val = math.random(val.min or 1, val.max or 5)
|
||||
end
|
||||
|
||||
return val
|
||||
end
|
||||
|
||||
function fire_plus.burn_player(player, burns, damage, not_initial)
|
||||
if not player then
|
||||
minetest.log("warning", "[Fire Plus] (burn_player): player is nil")
|
||||
end
|
||||
|
||||
local name = player
|
||||
if type(player) == "string" then
|
||||
player = minetest.get_player_by_name(player)
|
||||
end
|
||||
|
||||
if not player or player:get_hp() <= 0 then
|
||||
fire_plus.extinguish_player(name)
|
||||
return
|
||||
end
|
||||
|
||||
name = player:get_player_name()
|
||||
|
||||
-- Fire was extinguished
|
||||
if not fire_plus.burning[name] and not_initial then
|
||||
return
|
||||
end
|
||||
|
||||
if not fire_plus.burning[name] then
|
||||
burns = get_val(burns)
|
||||
|
||||
fire_plus.burning[name] = {
|
||||
burns_left = burns,
|
||||
hud_id = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0.5, y = 0.95},
|
||||
offset = {x = 0, y = 0},
|
||||
text = "fire_basic_flame.png",
|
||||
alignment = -1,
|
||||
scale = {x = 100, y = 32},
|
||||
number = 0xFFFFFF,
|
||||
}),
|
||||
sound_id = minetest.sound_play("fire_fire", {
|
||||
to_player = name,
|
||||
gain = 1.0,
|
||||
loop = true,
|
||||
}),
|
||||
particlespawner_id = minetest.add_particlespawner({
|
||||
amount = 10,
|
||||
time = 0,
|
||||
minpos = vector.new(-0.3, 0.5, -0.3),
|
||||
maxpos = vector.new( 0.3, 2, 0.3),
|
||||
minvel = {x = -1, y = 0, z = -1},
|
||||
maxvel = {x = 1, y = 1, z = 1},
|
||||
minacc = {x = 0, y = 2, z = 0},
|
||||
maxacc = {x = 0, y = 3, z = 0},
|
||||
minexptime = 0.5,
|
||||
maxexptime = 1,
|
||||
minsize = 3,
|
||||
maxsize = 3,
|
||||
texture = "fire_basic_flame.png",
|
||||
collisiondetection = true,
|
||||
glow = minetest.LIGHT_MAX,
|
||||
attached = player,
|
||||
})
|
||||
}
|
||||
else
|
||||
player:set_hp(player:get_hp() - get_val(damage), {type = "set_hp", fire_plus = true})
|
||||
|
||||
if minetest.get_modpath("tnt") then
|
||||
local tntpos = minetest.find_node_near(player:get_pos(), fire_plus.tnt_explode_radius, {"tnt:tnt"}, true)
|
||||
|
||||
if tntpos then
|
||||
tnt.boom(tntpos, {radius = fire_plus.tnt_explode_radius, damage_radius = fire_plus.tnt_explode_radius})
|
||||
end
|
||||
end
|
||||
|
||||
if not_initial then
|
||||
fire_plus.burning[name].burns_left = fire_plus.burning[name].burns_left - 1
|
||||
else
|
||||
fire_plus.burning[name].burns_left = burns
|
||||
end
|
||||
end
|
||||
|
||||
if fire_plus.burning[name].burns_left > 0 then
|
||||
minetest.after(fire_plus.burn_interval, function()
|
||||
fire_plus.burn_player(name, burns, damage, true)
|
||||
end)
|
||||
else
|
||||
fire_plus.extinguish_player(name)
|
||||
end
|
||||
end
|
||||
|
||||
function fire_plus.extinguish_player(player)
|
||||
local name = player
|
||||
|
||||
if player then
|
||||
if type(name) ~= "string" then
|
||||
name = player:get_player_name()
|
||||
else
|
||||
player = minetest.get_player_by_name(name)
|
||||
end
|
||||
end
|
||||
|
||||
if not fire_plus.burning[name] then return end
|
||||
|
||||
if player then
|
||||
player:hud_remove(fire_plus.burning[name].hud_id)
|
||||
minetest.sound_fade(fire_plus.burning[name].sound_id, 1, 0)
|
||||
end
|
||||
|
||||
minetest.delete_particlespawner(fire_plus.burning[name].particlespawner_id)
|
||||
|
||||
fire_plus.burning[name] = nil
|
||||
end
|
231
init.lua
231
init.lua
@ -1,183 +1,86 @@
|
||||
fire_plus = {
|
||||
burn_interval = 1,
|
||||
tnt_explode_radius = 1.5,
|
||||
burning = {--[[
|
||||
["playername"] = {
|
||||
burns_left = <number>,
|
||||
hud_id = <hud id>,
|
||||
sound_id = <sound id>,
|
||||
particlespawner_id = <particlespawner id>
|
||||
}
|
||||
]]},
|
||||
ignition_nodes = {
|
||||
--["nodename"] = {burns = <table with min/max or number>, damage = <table with min/max or number>}
|
||||
["default:lava"] = {burns = 2, damage = 4},
|
||||
["fire:"] = {burns = 4, damage = 2},
|
||||
},
|
||||
extinguishers = {
|
||||
"default:water",
|
||||
"default:river_water",
|
||||
"default:snow"
|
||||
}
|
||||
}
|
||||
|
||||
fire_plus.ignition_nodes = {
|
||||
"default:lava",
|
||||
"fire:",
|
||||
}
|
||||
dofile(minetest.get_modpath(minetest.get_current_modname()) .. "/api.lua")
|
||||
|
||||
fire_plus.put_outs = { -- Couldn't thnk of a better name
|
||||
"default:water",
|
||||
"default:river_water",
|
||||
"default:snow"
|
||||
}
|
||||
local time = 0
|
||||
minetest.register_globalstep(function(dtime)
|
||||
time = time + dtime
|
||||
|
||||
local firehud = {}
|
||||
local firesound = {}
|
||||
local callbacks = {}
|
||||
|
||||
local function make_registration()
|
||||
local registerfunc = function(func)
|
||||
callbacks[#callbacks + 1] = func
|
||||
if time < 0.1 then
|
||||
return
|
||||
else
|
||||
time = 0
|
||||
end
|
||||
|
||||
return(registerfunc)
|
||||
end
|
||||
-- Put out players in extinguisher nodes
|
||||
for _, player in pairs(minetest.get_connected_players()) do
|
||||
local nodename = minetest.get_node(player:get_pos()).name
|
||||
local nodename_head = minetest.get_node(vector.add(player:get_pos(), vector.new(0, 1, 0))).name
|
||||
|
||||
minetest.register_on_player_hpchange(function(player)
|
||||
local pos = player:get_pos()
|
||||
local node = minetest.get_node(pos)
|
||||
for _, extinguisher in pairs(fire_plus.extinguishers) do
|
||||
if nodename:find(extinguisher) or nodename_head:find(extinguisher) then
|
||||
local name = player:get_player_name()
|
||||
|
||||
for _, string in ipairs(fire_plus.ignition_nodes) do
|
||||
if node.name:find(string) then
|
||||
fire_plus.burnplayer(player)
|
||||
break
|
||||
if fire_plus.burning[name] then
|
||||
minetest.sound_play("fire_extinguish_flame", {
|
||||
to_player = name,
|
||||
gain = 1.0,
|
||||
})
|
||||
|
||||
fire_plus.extinguish_player(name)
|
||||
end
|
||||
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
-- Ignite players in ignition nodes
|
||||
minetest.register_on_player_hpchange(function(player, _, reason)
|
||||
if reason.type == "node_damage" and reason.node then
|
||||
for igniter, def in pairs(fire_plus.ignition_nodes) do
|
||||
if reason.node:find(igniter) then
|
||||
fire_plus.burn_player(player, def.burns or 4, def.damage or 2)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
minetest.register_on_punchplayer(function(player, hitter, _, toolcaps, _, dmg)
|
||||
if hitter and hitter:is_player() and toolcaps.damage_groups.burns and player and player:get_hp() - dmg > 0 then
|
||||
fire_plus.burn_player(player, toolcaps.damage_groups.burn_time or 4, toolcaps.damage_groups.burns)
|
||||
end
|
||||
|
||||
return false
|
||||
end)
|
||||
|
||||
minetest.register_on_respawnplayer(function(player)
|
||||
local name = player:get_player_name()
|
||||
|
||||
if firehud[name] then
|
||||
player:hud_remove(firehud[name])
|
||||
firehud[name] = nil
|
||||
end
|
||||
|
||||
if firesound[name] then
|
||||
minetest.sound_stop(firesound[name])
|
||||
firesound[name] = nil
|
||||
if fire_plus.burning[name] then
|
||||
fire_plus.extinguish_player(name)
|
||||
end
|
||||
end)
|
||||
|
||||
fire_plus.on_burn = make_registration()
|
||||
|
||||
function fire_plus.get_burn_dmg(player)
|
||||
local dmg = 1
|
||||
|
||||
for _, func in ipairs(callbacks) do
|
||||
local rval = func(player)
|
||||
|
||||
if type(rval) == "number" then
|
||||
dmg = rval
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
return(dmg)
|
||||
end
|
||||
|
||||
function fire_plus.burnplayer(player)
|
||||
if not player then return end
|
||||
|
||||
local name = player:get_player_name()
|
||||
|
||||
if firehud[name] then
|
||||
return
|
||||
end
|
||||
|
||||
firehud[name] = player:hud_add({
|
||||
hud_elem_type = "image",
|
||||
position = {x = 0.5, y = 0.95},
|
||||
offset = {x = 0, y = 0},
|
||||
text = "fire_basic_flame.png",
|
||||
alignment = -1,
|
||||
scale = {x = 100, y = 32},
|
||||
number = 0xFFFFFF,
|
||||
})
|
||||
|
||||
firesound[name] = minetest.sound_play("fire_fire", {
|
||||
to_player = name,
|
||||
gain = 1.0,
|
||||
loop = true,
|
||||
})
|
||||
|
||||
for i=1, 4, 1 do
|
||||
minetest.after(i, function()
|
||||
if not player or firehud[player:get_player_name()] == nil then
|
||||
return
|
||||
end
|
||||
|
||||
local pos = player:get_pos()
|
||||
local pname = player:get_player_name()
|
||||
local nodename = minetest.get_node(pos).name
|
||||
local remove_burn = false
|
||||
|
||||
for _, string in ipairs(fire_plus.put_outs) do
|
||||
if nodename:find(string) then
|
||||
remove_burn = true
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if remove_burn == true then
|
||||
player:hud_remove(firehud[pname])
|
||||
minetest.sound_stop(firesound[pname])
|
||||
firehud[pname] = nil
|
||||
firesound[pname] = nil
|
||||
|
||||
minetest.sound_play("fire_extinguish_flame", {
|
||||
to_player = pname,
|
||||
gain = 1.0,
|
||||
})
|
||||
|
||||
return
|
||||
end
|
||||
|
||||
-- Detonate any nearby TNT if player is on fire
|
||||
|
||||
local tntpos = minetest.find_node_near(player:get_pos(), fire_plus.tnt_explode_radius, {"tnt:tnt"}, true)
|
||||
|
||||
if player:get_hp() > 0 then
|
||||
player:set_hp(player:get_hp()-fire_plus.get_burn_dmg(player))
|
||||
end
|
||||
|
||||
if tntpos then
|
||||
tnt.boom(tntpos, {radius = fire_plus.tnt_explode_radius, damage_radius = fire_plus.tnt_explode_radius})
|
||||
end
|
||||
|
||||
minetest.add_particlespawner({
|
||||
amount = 20,
|
||||
time = 0.1,
|
||||
minpos = vector.subtract(pos, 0.5),
|
||||
maxpos = vector.add(pos, 0.5),
|
||||
minvel = {x = -1, y = 0, z = -1},
|
||||
maxvel = {x = 1, y = 1, z = 1},
|
||||
minacc = {x = 0, y = 2, z = 0},
|
||||
maxacc = {x = 0, y = 3, z = 0},
|
||||
minexptime = 0.5,
|
||||
maxexptime = 1,
|
||||
minsize = 5 * 0.66,
|
||||
maxsize = 5 * 0.66,
|
||||
texture = "fire_basic_flame.png",
|
||||
collisiondetection = true,
|
||||
})
|
||||
end)
|
||||
end
|
||||
|
||||
minetest.after(4.5, function()
|
||||
if not player then
|
||||
return
|
||||
end
|
||||
|
||||
if firehud[name] then
|
||||
player:hud_remove(firehud[name])
|
||||
firehud[name] = nil
|
||||
end
|
||||
|
||||
if firesound[name] then
|
||||
minetest.sound_stop(firesound[name])
|
||||
firesound[name] = nil
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
minetest.register_on_punchplayer(function(player, hitter, _, tool_ca, _, dmg)
|
||||
if hitter:is_player() and tool_ca.damage_groups.burns == 1 and
|
||||
(player:get_hp()-dmg) > 0 then
|
||||
fire_plus.burnplayer(player)
|
||||
end
|
||||
|
||||
return(false)
|
||||
end)
|
||||
|
BIN
screenshot.png
Normal file
BIN
screenshot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 721 KiB |
BIN
screenshot2.png
Normal file
BIN
screenshot2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 997 KiB |
BIN
screenshot_1.png
BIN
screenshot_1.png
Binary file not shown.
Before Width: | Height: | Size: 896 KiB |
BIN
screenshot_2.png
BIN
screenshot_2.png
Binary file not shown.
Before Width: | Height: | Size: 613 KiB |
Loading…
x
Reference in New Issue
Block a user