The mod is reborn

This commit is contained in:
LoneWolfHT 2021-01-18 19:35:10 -08:00
parent ebb7410e0c
commit 058ab87d2f
10 changed files with 249 additions and 189 deletions

41
.luacheckrc Normal file
View 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"
}
},
}

View File

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

View File

@ -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
View 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
View File

@ -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)

View File

@ -1 +1,3 @@
name = fire_plus
depends = fire
optional_depends = default, tnt

BIN
screenshot.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 721 KiB

BIN
screenshot2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 997 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 896 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 613 KiB