Added protected_damage mod
This commit is contained in:
parent
3a7d3d8dce
commit
7b21742724
69
mods/protected_damage/init.lua
Normal file
69
mods/protected_damage/init.lua
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
protected_damage = {}
|
||||||
|
|
||||||
|
local function div(a, b)
|
||||||
|
if a == nil or b == nil then return 0 end
|
||||||
|
return a / b
|
||||||
|
end
|
||||||
|
|
||||||
|
local function mult(a, b)
|
||||||
|
if a == nil or b == nil then return 0 end
|
||||||
|
return a * b
|
||||||
|
end
|
||||||
|
|
||||||
|
function protected_damage.get_node_strength(groups)
|
||||||
|
local s = div(50, groups.cracky)
|
||||||
|
+ div(70, groups.stone)
|
||||||
|
+ mult(150, groups.level)
|
||||||
|
+ div(25, groups.crumbly)
|
||||||
|
- mult(10, groups.oddly_breakable_by_hand)
|
||||||
|
+ div(30, groups.snappy)
|
||||||
|
+ div(40, groups.choppy)
|
||||||
|
- mult(10, groups.dig_immediate)
|
||||||
|
s = math.floor(s + 0.5)
|
||||||
|
if s < 0 then s = 1 end
|
||||||
|
return s
|
||||||
|
end
|
||||||
|
|
||||||
|
protected_damage.blacklist = {
|
||||||
|
["kingdoms:marker"] = true,
|
||||||
|
["air"] = true
|
||||||
|
}
|
||||||
|
|
||||||
|
-- Core damage function (used by tnt mod)
|
||||||
|
function protected_damage.do_damage(pos, groups, amt)
|
||||||
|
-- Get node strength
|
||||||
|
local meta = minetest.get_meta(pos)
|
||||||
|
local s = meta:get_int("node_hp")
|
||||||
|
if s == 0 then
|
||||||
|
s = protected_damage.get_node_strength(groups)
|
||||||
|
end
|
||||||
|
-- Damage node
|
||||||
|
s = s - amt
|
||||||
|
s = math.floor(s + 0.5)
|
||||||
|
if s <= 0 then
|
||||||
|
minetest.set_node(pos, {name = "air"})
|
||||||
|
return
|
||||||
|
else
|
||||||
|
meta:set_int("node_hp", s)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Main damage function (involves checks)
|
||||||
|
function protected_damage.damage(pos, amt)
|
||||||
|
-- Check for unloaded node
|
||||||
|
local node = minetest.get_node_or_nil(pos)
|
||||||
|
if node == nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- Check for blacklisted node
|
||||||
|
if protected_damage.blacklist[node.name] ~= nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- Check for undefined / unbreakable node
|
||||||
|
local ndef = minetest.registered_nodes[node.name]
|
||||||
|
if ndef == nil or ndef.groups == nil or ndef.groups.unbreakable ~= nil then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
-- Do damage
|
||||||
|
protected_damage.do_damage(pos, ndef.groups, amt)
|
||||||
|
end
|
@ -1,2 +1,3 @@
|
|||||||
default
|
default
|
||||||
fire
|
fire
|
||||||
|
protected_damage
|
||||||
|
@ -1,13 +1,7 @@
|
|||||||
tnt = {}
|
tnt = {}
|
||||||
|
|
||||||
-- Default to enabled when in singleplayer
|
|
||||||
local enable_tnt = minetest.settings:get_bool("enable_tnt")
|
|
||||||
if enable_tnt == nil then
|
|
||||||
enable_tnt = minetest.is_singleplayer()
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Override by BillyS
|
-- Override by BillyS
|
||||||
enable_tnt = true
|
local enable_tnt = true
|
||||||
|
|
||||||
-- loss probabilities array (one in X will be lost)
|
-- loss probabilities array (one in X will be lost)
|
||||||
local loss_prob = {}
|
local loss_prob = {}
|
||||||
@ -22,35 +16,7 @@ local tnt_radius = tonumber(minetest.settings:get("tnt_radius") or 3)
|
|||||||
-- Special TNT effects for protected areas
|
-- Special TNT effects for protected areas
|
||||||
--
|
--
|
||||||
|
|
||||||
-- Helpers
|
|
||||||
local function div(a, b)
|
|
||||||
if a == nil or b == nil then return 0 end
|
|
||||||
return a / b
|
|
||||||
end
|
|
||||||
|
|
||||||
local function mult(a, b)
|
|
||||||
if a == nil or b == nil then return 0 end
|
|
||||||
return a * b
|
|
||||||
end
|
|
||||||
|
|
||||||
local function get_node_strength(groups)
|
|
||||||
local s = div(50, groups.cracky)
|
|
||||||
+ div(70, groups.stone)
|
|
||||||
+ mult(150, groups.level)
|
|
||||||
+ div(25, groups.crumbly)
|
|
||||||
- mult(10, groups.oddly_breakable_by_hand)
|
|
||||||
+ div(30, groups.snappy)
|
|
||||||
+ div(40, groups.choppy)
|
|
||||||
- mult(10, groups.dig_immediate)
|
|
||||||
s = math.floor(s + 0.5)
|
|
||||||
if s < 0 then s = 1 end
|
|
||||||
return s
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Run once all nodes are registered: modify on_blast to do node damage
|
-- Run once all nodes are registered: modify on_blast to do node damage
|
||||||
local blacklist = {
|
|
||||||
["kingdoms:marker"] = true
|
|
||||||
}
|
|
||||||
|
|
||||||
local cid_data = {}
|
local cid_data = {}
|
||||||
|
|
||||||
@ -63,25 +29,12 @@ minetest.after(0, function()
|
|||||||
drops = def.drops,
|
drops = def.drops,
|
||||||
flammable = def.groups.flammable,
|
flammable = def.groups.flammable,
|
||||||
}
|
}
|
||||||
if blacklist[n] == nil and def.groups and def.groups.unbreakable == nil and def.on_blast == nil then
|
if def.groups and def.groups.unbreakable == nil and def.on_blast == nil and
|
||||||
cid_data[id].on_blast = function(pos, intensity)
|
protected_damage.blacklist[n] == nil then
|
||||||
-- Check if node is protected
|
cid_data[id].on_blast = function(pos, intensity, is_protected)
|
||||||
if minetest.is_protected(pos) then
|
-- If protected, do protection damage; otherwise, destroy
|
||||||
-- Get node strength
|
if is_protected then
|
||||||
local meta = minetest.get_meta(pos)
|
protected_damage.do_damage(pos, def.groups, intensity * math.random(2, 20))
|
||||||
local s = meta:get_int("node_hp")
|
|
||||||
if s == 0 then
|
|
||||||
s = get_node_strength(def.groups)
|
|
||||||
end
|
|
||||||
-- Damage node
|
|
||||||
s = s - intensity * math.random(2, 20)
|
|
||||||
s = math.floor(s + 0.5)
|
|
||||||
if s <= 0 then
|
|
||||||
minetest.set_node(pos, {name = "air"})
|
|
||||||
return
|
|
||||||
else
|
|
||||||
meta:set_int("node_hp", s)
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
minetest.set_node(pos, {name = "air"})
|
minetest.set_node(pos, {name = "air"})
|
||||||
end
|
end
|
||||||
@ -156,7 +109,8 @@ local basic_flame_on_construct -- cached value
|
|||||||
local function destroy(drops, npos, cid, c_air, c_fire,
|
local function destroy(drops, npos, cid, c_air, c_fire,
|
||||||
on_blast_queue, on_construct_queue,
|
on_blast_queue, on_construct_queue,
|
||||||
ignore_protection, ignore_on_blast, owner)
|
ignore_protection, ignore_on_blast, owner)
|
||||||
if not ignore_protection and minetest.is_protected(npos, owner) then
|
local is_protected = minetest.is_protected(npos, owner)
|
||||||
|
if not ignore_protection and is_protected then
|
||||||
return cid
|
return cid
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -167,6 +121,7 @@ local function destroy(drops, npos, cid, c_air, c_fire,
|
|||||||
elseif not ignore_on_blast and def.on_blast then
|
elseif not ignore_on_blast and def.on_blast then
|
||||||
on_blast_queue[#on_blast_queue + 1] = {
|
on_blast_queue[#on_blast_queue + 1] = {
|
||||||
pos = vector.new(npos),
|
pos = vector.new(npos),
|
||||||
|
is_protected = is_protected,
|
||||||
on_blast = def.on_blast
|
on_blast = def.on_blast
|
||||||
}
|
}
|
||||||
return cid
|
return cid
|
||||||
@ -437,7 +392,7 @@ local function tnt_explode(pos, radius, ignore_protection, ignore_on_blast, owne
|
|||||||
for _, queued_data in pairs(on_blast_queue) do
|
for _, queued_data in pairs(on_blast_queue) do
|
||||||
local dist = math.max(1, vector.distance(queued_data.pos, pos))
|
local dist = math.max(1, vector.distance(queued_data.pos, pos))
|
||||||
local intensity = (radius * radius) / (dist * dist)
|
local intensity = (radius * radius) / (dist * dist)
|
||||||
local node_drops = queued_data.on_blast(queued_data.pos, intensity)
|
local node_drops = queued_data.on_blast(queued_data.pos, intensity, queued_data.is_protected)
|
||||||
if node_drops then
|
if node_drops then
|
||||||
for _, item in pairs(node_drops) do
|
for _, item in pairs(node_drops) do
|
||||||
add_drop(drops, item)
|
add_drop(drops, item)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user