Compare commits
10 Commits
c2f3880317
...
885dc50638
Author | SHA1 | Date | |
---|---|---|---|
|
885dc50638 | ||
|
55445dc51c | ||
|
2eb918f7a2 | ||
|
9e06fa33d3 | ||
|
ad7a7139d6 | ||
|
4c9b9f394a | ||
|
e1d3dd9539 | ||
|
058ab87d2f | ||
|
ebb7410e0c | ||
|
0a962d003e |
16
.github/workflows/main.yml
vendored
Normal file
16
.github/workflows/main.yml
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
name: build
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
luacheck:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Install Luarocks
|
||||
run: |
|
||||
sudo apt-get update -qyy
|
||||
sudo apt-get install luarocks -qyy
|
||||
- name: Install Luacheck
|
||||
run: luarocks install --local luacheck
|
||||
- name: Run Luacheck
|
||||
run: $HOME/.luarocks/bin/luacheck .
|
42
.luacheckrc
Normal file
42
.luacheckrc
Normal file
@ -0,0 +1,42 @@
|
||||
globals = {
|
||||
"fire_plus",
|
||||
"armor",
|
||||
}
|
||||
|
||||
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
|
||||
|
48
README.md
48
README.md
@ -1,29 +1,29 @@
|
||||
# fire_plus
|
||||
# Fire Plus
|
||||
[](https://github.com/Dumpster-Studios/fire_plus/actions)
|
||||
[](https://content.minetest.net/packages/Lone_Wolf/fire_plus/)
|
||||

|
||||
|
||||
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.
|
||||
|
||||

|
||||
|
||||
## Credits
|
||||
* Thanks to **TenPlus1** for 3d_armor support and some other things
|
||||
|
||||
## 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>`
|
||||
|
125
api.lua
Normal file
125
api.lua
Normal file
@ -0,0 +1,125 @@
|
||||
local armor_mod = minetest.get_modpath("3d_armor")
|
||||
|
||||
-- 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()
|
||||
|
||||
-- 3d_armor fire protection puts out flames
|
||||
if armor_mod and armor.def[name].fire > 1 then
|
||||
fire_plus.extinguish_player(name)
|
||||
end
|
||||
|
||||
-- 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
|
@ -1,3 +1,4 @@
|
||||
default?
|
||||
fire
|
||||
tnt?
|
||||
3d_armor?
|
||||
|
238
init.lua
238
init.lua
@ -1,185 +1,91 @@
|
||||
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
|
||||
|
||||
minetest.register_on_player_hpchange(function(player, hp_change)
|
||||
local pos = player:get_pos()
|
||||
local node = minetest.get_node(pos)
|
||||
local name = player:get_player_name()
|
||||
|
||||
for id, 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
|
||||
|
||||
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
|
||||
|
||||
for _, extinguisher in pairs(fire_plus.extinguishers) do
|
||||
|
||||
if nodename:find(extinguisher) or nodename_head:find(extinguisher) then
|
||||
|
||||
minetest.sound_play("fire_extinguish_flame", {
|
||||
to_player = name,
|
||||
gain = 1.0,
|
||||
})
|
||||
|
||||
fire_plus.extinguish_player(name)
|
||||
|
||||
return
|
||||
end
|
||||
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 id, func in ipairs(callbacks) do
|
||||
local rval = callbacks[k](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 name = minetest.get_node(pos).name
|
||||
local remove_burn = false
|
||||
|
||||
for id, string in ipairs(fire_plus.put_outs) do
|
||||
if name: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 = tnt_radius, damage_radius = tnt_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
|
||||
|
||||
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
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
minetest.register_on_punchplayer(function(player, hitter, time_from_last_punch, tool_ca, dir, 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)
|
3
mod.conf
Normal file
3
mod.conf
Normal file
@ -0,0 +1,3 @@
|
||||
name = fire_plus
|
||||
depends = fire
|
||||
optional_depends = default, tnt, 3d_armor
|
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