Merge pull request 'master' (#9) from MineClone2/MineClone2:master into master

Reviewed-on: https://git.minetest.land/NO11/MineClone2/pulls/9
This commit is contained in:
NO11 2021-10-09 21:19:43 +00:00
commit 94e1d82b45
19 changed files with 172 additions and 142 deletions

View file

@ -538,3 +538,12 @@ function mcl_util.get_object_name(object)
return luaentity.nametag and luaentity.nametag ~= "" and luaentity.nametag or luaentity.description or luaentity.name
end
end
function mcl_util.replace_mob(obj, mob)
local rot = obj:get_yaw()
local pos = obj:get_pos()
obj:remove()
obj = minetest.add_entity(pos, mob)
obj:set_yaw(rot)
return obj
end

View file

@ -0,0 +1,31 @@
# lightning
Lightning mod for MineClone2 with the following API:
## lightning.register_on_strike(function(pos, pos2, objects))
Custom function called when a lightning strikes.
* `pos`: impact position
* `pos2`: rounded node position where fire is placed
* `objects`: table with ObjectRefs of all objects within a radius of 3.5 around pos2
## lightning.strike(pos)
Let a lightning strike.
* `pos`: optional, if not given a random pos will be chosen
* `returns`: bool - success if a strike happened
### Examples:
```
lightning.register_on_strike(function(pos, pos2, objects)
for _, obj in pairs(objects) do
obj:remove()
end
minetest.add_entity(pos, "mobs_mc:sheep")
end)
minetest.register_on_respawnplayer(function(player)
lightning.strike(player:get_pos())
end)
```

View file

@ -24,13 +24,14 @@ local get_objects_inside_radius = minetest.get_objects_inside_radius
local get_item_group = minetest.get_item_group
lightning = {
interval_low = 17,
interval_high = 503,
range_h = 100,
range_v = 50,
size = 100,
-- disable this to stop lightning mod from striking
auto = true,
interval_low = 17,
interval_high = 503,
range_h = 100,
range_v = 50,
size = 100,
-- disable this to stop lightning mod from striking
auto = true,
on_strike_functions = {},
}
local rng = PcgRandom(32321123312123)
@ -54,6 +55,18 @@ end
minetest.register_globalstep(revertsky)
-- lightning strike API
-- See API.md
--[[
lightning.register_on_strike(function(pos, pos2, objects)
-- code
end)
]]
function lightning.register_on_strike(func)
table.insert(lightning.on_strike_functions, func)
end
-- select a random strike point, midpoint
local function choose_pos(pos)
if not pos then
@ -79,14 +92,14 @@ local function choose_pos(pos)
pos.z = math.floor(pos.z - (lightning.range_h / 2) + rng:next(1, lightning.range_h))
end
local b, pos2 = line_of_sight(pos, {x = pos.x, y = pos.y - lightning.range_v, z = pos.z}, 1)
local b, pos2 = line_of_sight(pos, { x = pos.x, y = pos.y - lightning.range_v, z = pos.z }, 1)
-- nothing but air found
if b then
return nil, nil
end
local n = get_node({x = pos2.x, y = pos2.y - 1/2, z = pos2.z})
local n = get_node({ x = pos2.x, y = pos2.y - 1/2, z = pos2.z })
if n.name == "air" or n.name == "ignore" then
return nil, nil
end
@ -94,7 +107,6 @@ local function choose_pos(pos)
return pos, pos2
end
-- lightning strike API
-- * pos: optional, if not given a random pos will be chosen
-- * returns: bool - success if a strike happened
function lightning.strike(pos)
@ -108,21 +120,28 @@ function lightning.strike(pos)
if not pos then
return false
end
local objects = get_objects_inside_radius(pos2, 3.5)
if lightning.on_strike_functions then
for _, func in pairs(lightning.on_strike_functions) do
func(pos, pos2, objects)
end
end
end
lightning.register_on_strike(function(pos, pos2, objects)
local particle_pos = vector.offset(pos2, 0, (lightning.size / 2) + 0.5, 0)
local particle_size = lightning.size * 10
local time = 0.2
add_particlespawner({
amount = 1,
time = 0.2,
time = time,
-- make it hit the top of a block exactly with the bottom
minpos = {x = pos2.x, y = pos2.y + (lightning.size / 2) + 1/2, z = pos2.z },
maxpos = {x = pos2.x, y = pos2.y + (lightning.size / 2) + 1/2, z = pos2.z },
minvel = {x = 0, y = 0, z = 0},
maxvel = {x = 0, y = 0, z = 0},
minacc = {x = 0, y = 0, z = 0},
maxacc = {x = 0, y = 0, z = 0},
minexptime = 0.2,
maxexptime = 0.2,
minsize = lightning.size * 10,
maxsize = lightning.size * 10,
minpos = particle_pos,
maxpos = particle_pos,
minexptime = time,
maxexptime = time,
minsize = particle_size,
maxsize = particle_size,
collisiondetection = true,
vertical = true,
-- to make it appear hitting the node that will get set on fire, make sure
@ -135,44 +154,27 @@ function lightning.strike(pos)
sound_play({ name = "lightning_thunder", gain = 10 }, { pos = pos, max_hear_distance = 500 }, true)
-- damage nearby objects, transform mobs
-- TODO: use an API insteed of hardcoding this behaviour
local objs = get_objects_inside_radius(pos2, 3.5)
for o=1, #objs do
local obj = objs[o]
for _, obj in pairs(objects) do
local lua = obj:get_luaentity()
-- pig → zombie pigman (no damage)
if lua and lua._on_strike then
lua._on_strike(lua, pos, pos2, objects)
end
-- remove this when mob API is done
if lua and lua.name == "mobs_mc:pig" then
local rot = obj:get_yaw()
obj:remove()
obj = add_entity(pos2, "mobs_mc:pigman")
obj:set_yaw(rot)
-- mooshroom: toggle color red/brown (no damage)
mcl_util.replace_mob(obj, "mobs_mc:pigman")
elseif lua and lua.name == "mobs_mc:mooshroom" then
if lua.base_texture[1] == "mobs_mc_mooshroom.png" then
lua.base_texture = { "mobs_mc_mooshroom_brown.png", "mobs_mc_mushroom_brown.png" }
else
lua.base_texture = { "mobs_mc_mooshroom.png", "mobs_mc_mushroom_red.png" }
end
obj:set_properties({textures = lua.base_texture})
-- villager → witch (no damage)
--elseif lua and lua.name == "mobs_mc:villager" then
-- Witches are incomplete, this code is unused
-- TODO: Enable this code when witches are working.
--[[
local rot = obj:get_yaw()
obj:remove()
obj = minetest.add_entity(pos2, "mobs_mc:witch")
obj:set_yaw(rot)
]]
-- charged creeper
obj:set_properties({ textures = lua.base_texture })
elseif lua and lua.name == "mobs_mc:villager" then
mcl_util.replace_mob(obj, "mobs_mc:witch")
elseif lua and lua.name == "mobs_mc:creeper" then
local rot = obj:get_yaw()
obj:remove()
obj = add_entity(pos2, "mobs_mc:creeper_charged")
obj:set_yaw(rot)
-- Other objects: Just damage
mcl_util.replace_mob(obj, "mobs_mc:creeper_charged")
else
mcl_util.deal_damage(obj, 5, {type = "lightning_bolt"})
mcl_util.deal_damage(obj, 5, { type = "lightning_bolt" })
end
end
@ -186,7 +188,7 @@ function lightning.strike(pos)
local name = player:get_player_name()
if ps[name] == nil then
ps[name] = {p = player, sky = sky}
mcl_weather.skycolor.add_layer("lightning", {{r=255,g=255,b=255}}, true)
mcl_weather.skycolor.add_layer("lightning", { { r = 255, g = 255, b = 255 } }, true)
mcl_weather.skycolor.active = true
end
end
@ -201,7 +203,7 @@ function lightning.strike(pos)
if rng:next(1,100) <= 3 then
skeleton_lightning = true
end
if get_item_group(get_node({x = pos2.x, y = pos2.y - 1, z = pos2.z}).name, "liquid") < 1 then
if get_item_group(get_node({ x = pos2.x, y = pos2.y - 1, z = pos2.z }).name, "liquid") < 1 then
if get_node(pos2).name == "air" then
-- Low chance for a lightning to spawn skeleton horse + skeletons
if skeleton_lightning then
@ -210,7 +212,7 @@ function lightning.strike(pos)
local angle, posadd
angle = math.random(0, math.pi*2)
for i=1,3 do
posadd = {x=math.cos(angle),y=0,z=math.sin(angle)}
posadd = { x=math.cos(angle),y=0,z=math.sin(angle) }
posadd = vector.normalize(posadd)
local mob = add_entity(vector.add(pos2, posadd), "mobs_mc:skeleton")
mob:set_yaw(angle-math.pi/2)
@ -219,12 +221,11 @@ function lightning.strike(pos)
-- Cause a fire
else
set_node(pos2, {name = "mcl_fire:fire"})
set_node(pos2, { name = "mcl_fire:fire" })
end
end
end
end
end)
-- if other mods disable auto lightning during initialization, don't trigger the first lightning.
after(5, function(dtime)

View file

@ -203,12 +203,8 @@ local dispenserdef = {
else
minetest.add_item(droppos, mobs_mc.items.mushroom_red .. " 5")
end
local oldyaw = obj:get_yaw()
obj:remove()
local cow = minetest.add_entity(pos, "mobs_mc:cow")
cow:set_yaw(oldyaw)
obj = cow
entity = cow:get_luaentity()
obj = mcl_util.replace_mob(obj, "mobs_mc:cow")
entity = obj:get_luaentity()
used = true
end
if used then

View file

@ -12,15 +12,7 @@ Authors of media (textures)
BlockMen (CC BY-SA 3.0)
This mod adds a bed to Minetest which allows to skip the night.
To sleep, rightclick the bed. If playing in singleplayer mode the night gets skipped
immediately. If playing multiplayer you get shown how many other players are in bed too,
if all players are sleeping the night gets skipped. The night skip can be forced if more
than 50% of the players are lying in bed and use this option.
Another feature is a controlled respawning. If you have slept in bed (not just lying in
it) your respawn point is set to the beds location and you will respawn there after
To sleep, rightclick the bed.
Another feature is a controlled respawning. If you have slept in bed your respawn point is set to the beds location and you will respawn there after
death.
You can disable the respawn at beds by setting "enable_bed_respawn = false" in
minetest.conf.
You can disable the night skip feature by setting "enable_bed_night_skip = false" in
minetest.conf or by using the /set command in-game.
Use the mcl_playersSleepingPercentage setting to enable/disable night skipping or set a percentage of how many players need to sleep to skip the night.

View file

@ -14,39 +14,34 @@ local worlds_mod = minetest.get_modpath("mcl_worlds")
local function get_look_yaw(pos)
local n = minetest.get_node(pos)
if n.param2 == 1 then
return math.pi / 2, n.param2
elseif n.param2 == 3 then
return -math.pi / 2, n.param2
elseif n.param2 == 0 then
return math.pi, n.param2
local param = n.param2
if param == 1 then
return math.pi / 2, param
elseif param == 3 then
return -math.pi / 2, param
elseif param == 0 then
return math.pi, param
else
return 0, n.param2
return 0, param
end
end
local function players_in_bed_setting()
return tonumber(minetest.settings:get("mcl_playersSleepingPercentage")) or 100
end
local function is_night_skip_enabled()
local enable_night_skip = minetest.settings:get_bool("enable_bed_night_skip")
if enable_night_skip == nil then
enable_night_skip = true
end
return enable_night_skip
return players_in_bed_setting() <= 100
end
local function check_in_beds(players)
local in_bed = mcl_beds.player
if not players then
players = minetest.get_connected_players()
end
for n, player in pairs(players) do
local name = player:get_player_name()
if not in_bed[name] then
return false
end
if player_in_bed <= 0 then
return false
end
return #players > 0
return players_in_bed_setting() <= (player_in_bed * 100) / #players
end
-- These monsters do not prevent sleep
@ -198,7 +193,7 @@ end
local function update_formspecs(finished, ges)
local ges = ges or #minetest.get_connected_players()
local form_n = "size[12,5;true]"
local all_in_bed = ges == player_in_bed
local all_in_bed = players_in_bed_setting() <= (player_in_bed * 100) / ges
local night_skip = is_night_skip_enabled()
local button_leave = "button_exit[4,3;4,0.75;leave;"..F(S("Leave bed")).."]"
local button_abort = "button_exit[4,3;4,0.75;leave;"..F(S("Abort sleep")).."]"
@ -221,7 +216,13 @@ local function update_formspecs(finished, ges)
form_n = form_n .. bg_sleep
form_n = form_n .. button_abort
else
text = text .. "\n" .. S("You will fall asleep when all players are in bed.")
local comment = "You will fall asleep when "
if players_in_bed_setting() == 100 then
comment = S(comment .. "all players are in bed.")
else
comment = S(comment .. "@1% of all players are in bed.", players_in_bed_setting())
end
text = text .. "\n" .. comment
form_n = form_n .. bg_presleep
form_n = form_n .. button_leave
end
@ -349,7 +350,6 @@ function mcl_beds.on_rightclick(pos, player, is_top)
end
end
-- Callbacks
minetest.register_on_joinplayer(function(player)
local meta = player:get_meta()

View file

@ -37,5 +37,6 @@ Players in bed: @1/@2=Spieler im Bett: @1/@2
Note: Night skip is disabled.=Anmerkung: Überspringen der Nacht deaktiviert.
You're sleeping.=Sie schlafen.
You will fall asleep when all players are in bed.=Sie werden einschlafen, wenn alle Spieler im Bett sind.
You will fall asleep when @1% of all players are in bed.=Sie werden einschlafen, wenn @1% der Spieler im Bett sind.
You're in bed.=Sie sind im Bett.
Allows you to sleep=Zum Einschafen

View file

@ -37,5 +37,6 @@ Players in bed: @1/@2=
Note: Night skip is disabled.=
You're sleeping.=
You will fall asleep when all players are in bed.=
You will fall asleep when @1% of all players are in bed.=
You're in bed.=
Allows you to sleep=

View file

@ -93,7 +93,7 @@ minetest.register_craftitem("mcl_core:gold_ingot", {
minetest.register_craftitem("mcl_core:emerald", {
description = S("Emerald"),
_doc_items_longdesc = S("Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting."),
_doc_items_longdesc = S("Emeralds are used in villager trades as currency."),
inventory_image = "mcl_core_emerald.png",
stack_max = 64,
groups = { craftitem=1 },

View file

@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass
Emerald=Smaragd
Emerald Ore=Smaragderz
Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Smaragderz ist das Erz von Smaragden. Es ist sehr selten und kann nur einzeln gefunden werden, nicht in Ansammlungen.
Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Smaragde sind nicht besonders nützlich, aber man kann sie in der Fertigung durch Goldbarren eintauschen.
Emeralds are used in villager trades as currency.=
Flint=Feuerstein
Flint is a raw material.=Feuerstein ist ein Rohstoff.
Flowing Lava=Fließende Lava

View file

@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass
Emerald=Esmeralda
Emerald Ore=Mena de esmeralda
Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=El mineral esmeralda es el mineral de las esmeraldas. Es muy raro y se puede encontrar solo, no en grupos.
Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Las esmeraldas no son muy útiles por sí mismas, pero pueden cambiarse por lingotes de oro haciendo artesanías.
Emeralds are used in villager trades as currency.=
Flint=Pedernal
Flint is a raw material.=El pedernal es una materia prima.
Flowing Lava=Lava que fluye

View file

@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass
Emerald=Emeraude
Emerald Ore=Minerai d'Emeraude
Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Le minerai d'émeraude produit des émeraudes. Il est très rare et peut être trouvé seul, pas en filons.
Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Les émeraudes ne sont pas très utiles seules, mais elles peuvent être échangées contre des lingots d'or.
Emeralds are used in villager trades as currency.=Les émeraudes sont utilisées pour faire des échanges avec les villageois.
Flint=Silex
Flint is a raw material.=Le silex est une matière première.
Flowing Lava=Lave qui coule

View file

@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass
Emerald=Szmaragd
Emerald Ore=Ruda szmaragdu
Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Ruda szmaragdu jest bardzo rzadka i występuje samotnie, nie w grupach.
Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Szmaragdy nie są zbyt użyteczne same w sobie, ale można z nich wytworzyć sztabki złota.
Emeralds are used in villager trades as currency.=
Flint=Krzemień
Flint is a raw material.=Krzemień jest surowym materiałem.
Flowing Lava=Płynąca lawa

View file

@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass
Emerald=Изумруд
Emerald Ore=Изумрудная руда
Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=Изумрудная руда встречается очень редко и всегда по одному блоку.
Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=Изумруды не очень полезны сами по себе, но их можно обменять на золотые слитки.
Emeralds are used in villager trades as currency.=
Flint=Кремень
Flint is a raw material.=Кремень это необработанный материал.
Flowing Lava=Текущая лава

View file

@ -95,7 +95,7 @@ Dirt acts as a soil for a few plants. When in light, this block may grow a grass
Emerald=
Emerald Ore=
Emerald ore is the ore of emeralds. It is very rare and can be found alone, not in clusters.=
Emeralds are not very useful on their own, but they can exchanged for gold ingots by crafting.=
Emeralds are used in villager trades as currency.=
Flint=
Flint is a raw material.=
Flowing Lava=

View file

@ -270,8 +270,14 @@ function mcl_enchanting.initialize()
new_def.groups.not_in_creative_inventory = 1
new_def.groups.not_in_craft_guide = 1
new_def.groups.enchanted = 1
new_def._mcl_armor_texture = new_def._mcl_armor_texture and new_def._mcl_armor_texture .. mcl_enchanting.overlay
new_def._mcl_armor_preview = new_def._mcl_armor_preview and new_def._mcl_armor_preview .. mcl_enchanting.overlay
if new_def._mcl_armor_texture and not type(new_def._mcl_armor_texture) == "function" then
new_def._mcl_armor_texture = new_def._mcl_armor_texture .. mcl_enchanting.overlay
end
if new_def._mcl_armor_preview and not type(new_def._mcl_armor_preview) == "function" then
new_def._mcl_armor_preview = new_def._mcl_armor_preview .. mcl_enchanting.overlay
end
new_def._mcl_enchanting_enchanted_tool = new_name
new_def.after_use = get_after_use_callback(itemdef)
local register_list = register_item_list

View file

@ -3,3 +3,27 @@ local S = minetest.get_translator(minetest.get_current_modname())
minetest.register_privilege("maphack", {
description = S("Can place and use advanced blocks like mob spawners, command blocks and barriers."),
})
minetest.register_on_joinplayer(function(player)
local name = player:get_player_name()
local meta = player:get_meta()
if meta:get_int("fly_changed") == 1 then return end
local fly = nil
if minetest.is_creative_enabled(name) then
fly = true
end
local player_privs = minetest.get_player_privs(name)
player_privs.fly = fly
minetest.set_player_privs(name, player_privs)
end)
for _, action in pairs({"grant", "revoke"}) do
minetest["register_on_priv_" .. action](function(name, _, priv)
if priv == "fly" then
local player = minetest.get_player_by_name(name)
local meta = player:get_meta()
meta:set_int("fly_changed", 1)
end
end)
end

View file

@ -35,40 +35,6 @@ minetest.register_craft({
},
})
minetest.register_craft({
output = "mcl_armor:helmet_chain",
recipe = {
{ "xpanes:bar_flat", "mcl_core:iron_ingot", "xpanes:bar_flat" },
{ "xpanes:bar_flat", "", "xpanes:bar_flat" },
}
})
minetest.register_craft({
output = "mcl_armor:leggings_chain",
recipe = {
{ "xpanes:bar_flat", "mcl_core:iron_ingot", "xpanes:bar_flat" },
{ "xpanes:bar_flat", "", "xpanes:bar_flat" },
{ "xpanes:bar_flat", "", "xpanes:bar_flat" },
}
})
minetest.register_craft({
output = "mcl_armor:boots_chain",
recipe = {
{ "xpanes:bar_flat", "", "xpanes:bar_flat" },
{ "xpanes:bar_flat", "", "xpanes:bar_flat" },
}
})
minetest.register_craft({
output = "mcl_armor:chestplate_chain",
recipe = {
{ "xpanes:bar_flat", "", "xpanes:bar_flat" },
{ "xpanes:bar_flat", "mcl_core:iron_ingot", "xpanes:bar_flat" },
{ "xpanes:bar_flat", "xpanes:bar_flat", "xpanes:bar_flat" },
}
})
-- Make red sand, red sandstone and more craftable in v6
-- NOTE: When you change these, also update mcl_craftguide for the "v6" icon in
-- the craft guide!

View file

@ -33,9 +33,12 @@ mcl_tnt_griefing (TNT destroys blocks) bool true
# This setting is only read at startup.
enable_bed_respawn (Respawn at bed) bool true
# If enabled, the night can be skipped if all players are in bed.
# This setting is only read at startup.
enable_bed_night_skip (Skip night when sleeping) bool true
# How many players have to sleep to skip the night, in percent.
# Setting to 0 will mean 1 player is always enough to skip the night. Setting above 100 will prevent skipping the night.
# 100 by default.
# The setting can be changed ingame using `/set mcl_playersSleepingPercentage <number>`
mcl_playersSleepingPercentage (Players Sleeping Percentage) int 100
# Normally, players drop all their items when they die. Enable this
# setting, so players always keep their inventory on death.
mcl_keepInventory (Keep inventory on death) bool false