Merge branch 'master' into crossbow

This commit is contained in:
Lizzy Fleckenstein 2021-03-18 13:29:16 +01:00
commit 54413d0954
349 changed files with 4299 additions and 3074 deletions

9
API.md
View File

@ -39,7 +39,7 @@ A lot of things are possible by using one of the APIs in the mods. Note that not
* Dispenser support: `ITEMS/REDSTONE/mcl_dispensers` * Dispenser support: `ITEMS/REDSTONE/mcl_dispensers`
## Mobs ## Mobs
* Mobs: `ENTITIES/mcl_mods` * Mobs: `ENTITIES/mcl_mobs`
MineClone 2 uses its own mobs framework, called “Mobs Redo: MineClone 2 Edition” or “MRM” for short. MineClone 2 uses its own mobs framework, called “Mobs Redo: MineClone 2 Edition” or “MRM” for short.
This is a fork of Mobs Redo [`mobs`] by TenPlus1. This is a fork of Mobs Redo [`mobs`] by TenPlus1.
@ -67,6 +67,9 @@ chances are good that it works out of the box.
* Get flowing direction of liquids: `CORE/flowlib` * Get flowing direction of liquids: `CORE/flowlib`
* `on_walk_over` callback for nodes: `CORE/walkover` * `on_walk_over` callback for nodes: `CORE/walkover`
* Get node names close to player (to reduce constant querying): `PLAYER/mcl_playerinfo` * Get node names close to player (to reduce constant querying): `PLAYER/mcl_playerinfo`
* Explosion API
* Music discs API
* Flowers and flower pots
### Unstable APIs ### Unstable APIs
The following APIs may be subject to change in future. You could already use these APIs but there will probably be breaking changes in the future, or the API is not as fleshed out as it should be. Use at your own risk! The following APIs may be subject to change in future. You could already use these APIs but there will probably be breaking changes in the future, or the API is not as fleshed out as it should be. Use at your own risk!
@ -79,12 +82,10 @@ The following APIs may be subject to change in future. You could already use the
### Planned APIs ### Planned APIs
* Flowers
* Saplings and trees * Saplings and trees
* Custom banner patterns * Custom banner patterns
* Custom dimensions * Custom dimensions
* Custom portals * Custom portals
* Music discs
* Dispenser and dropper support * Dispenser and dropper support
* Proper sky and weather APIs * Proper sky and weather APIs
* Explosion API

View File

@ -21,7 +21,7 @@ The basic digging time groups determine by which tools a node can be dug.
* `swordy=1`: Diggable by sword (any material), and this node is *not* a cobweb * `swordy=1`: Diggable by sword (any material), and this node is *not* a cobweb
* `swordy_cobweb=1`: Diggable by sword (any material), and this node is a cobweb * `swordy_cobweb=1`: Diggable by sword (any material), and this node is a cobweb
* `shearsy=1`: Diggable by shears, and this node is *not* wool * `shearsy=1`: Diggable by shears, and this node is *not* wool
* `shearsy=wool=1`: Diggable by shears, and this node is wool * `shearsy_wool=1`: Diggable by shears, and this node is wool
* `handy=1`: Breakable by hand and this node gives it useful drop when dug by hand. All nodes which are breakable by pickaxe, axe, shovel, sword or shears are also automatically breakable by hand, but not neccess * `handy=1`: Breakable by hand and this node gives it useful drop when dug by hand. All nodes which are breakable by pickaxe, axe, shovel, sword or shears are also automatically breakable by hand, but not neccess
* `creative_breakable=1`: Block is breakable by hand in creative mode. This group is implied if the node belongs to any other digging group * `creative_breakable=1`: Block is breakable by hand in creative mode. This group is implied if the node belongs to any other digging group

View File

@ -2,7 +2,7 @@
An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils. An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils.
Developed by many people. Not developed or endorsed by Mojang AB. Developed by many people. Not developed or endorsed by Mojang AB.
Version: 0.70.0 Version: 0.71.0
### Gameplay ### Gameplay
You start in a randomly-generated world made entirely of cubes. You can explore You start in a randomly-generated world made entirely of cubes. You can explore
@ -185,6 +185,11 @@ Please report all bugs and missing Minecraft features here:
<https://git.minetest.land/MineClone2/MineClone2/issues> <https://git.minetest.land/MineClone2/MineClone2/issues>
## Chating with the community
Join our discord server at:
<https://discord.gg/84GKcxczG3>
## Other readme files ## Other readme files
* `LICENSE.txt`: The GPLv3 license text * `LICENSE.txt`: The GPLv3 license text
@ -206,6 +211,7 @@ There are so many people to list (sorry). Check out the respective mod directori
* [bzoss](https://github.com/bzoss): Status effects, potions, brewing stand * [bzoss](https://github.com/bzoss): Status effects, potions, brewing stand
* kay27 <kay27@bk.ru>: Experience system, bugfixes, optimizations (Current maintainer) * kay27 <kay27@bk.ru>: Experience system, bugfixes, optimizations (Current maintainer)
* [EliasFleckenstein03](https://github.com/EliasFleckenstein03): End crystals, enchanting, burning mobs / players, animated chests, bugfixes (Current maintainer) * [EliasFleckenstein03](https://github.com/EliasFleckenstein03): End crystals, enchanting, burning mobs / players, animated chests, bugfixes (Current maintainer)
* epCode: Better player animations, new logo
* 2mac: Fix bug with powered rail * 2mac: Fix bug with powered rail
* Lots of other people: TO BE WRITTEN (see mod directories for details) * Lots of other people: TO BE WRITTEN (see mod directories for details)

View File

@ -1 +1 @@
A survival sandbox game. Survive, gather, hunt, mine, build, explore, and do much more. Faithful clone of Minecraft 1.11. This is a work in progress! Expect bugs! A survival sandbox game. Survive, gather, hunt, mine, build, explore, and do much more. Faithful clone of Minecraft 1.12. This is a work in progress! Expect bugs!

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 76 KiB

View File

@ -32,4 +32,13 @@ mgvalleys_spflags = noaltitude_chill,noaltitude_dry,nohumid_rivers,vary_river_de
# MCL2-specific stuff # MCL2-specific stuff
keepInventory = false keepInventory = false
# Performance settings
dedicated_server_step = 0.001 dedicated_server_step = 0.001
abm_interval = 0.25
max_objects_per_block = 4096
max_packets_per_iteration = 10096
# Clientmodding to support official client
enable_client_modding = true
csm_restriction_flags = 0
enable_mod_channels = true

View File

@ -1 +0,0 @@
MineClone 2 core mod which automatically adds groups to all items. Very important for digging times.

View File

@ -1 +1,3 @@
name = _mcl_autogroup name = _mcl_autogroup
author = Wuzzy
description = MineClone 2 core mod which automatically adds groups to all items. Very important for digging times.

View File

@ -1,2 +1,3 @@
name = biomeinfo name = biomeinfo
author = Wuzzy
description = Simple API to get data about biomes. description = Simple API to get data about biomes.

View File

@ -1,3 +1,6 @@
local get_connected_players = minetest.get_connected_players
local clock = os.clock
controls = {} controls = {}
controls.players = {} controls.players = {}
@ -42,7 +45,7 @@ minetest.register_on_leaveplayer(function(player)
end) end)
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
for _, player in pairs(minetest.get_connected_players()) do for _, player in pairs(get_connected_players()) do
local player_name = player:get_player_name() local player_name = player:get_player_name()
local player_controls = player:get_player_control() local player_controls = player:get_player_control()
if controls.players[player_name] then if controls.players[player_name] then
@ -53,15 +56,15 @@ minetest.register_globalstep(function(dtime)
for _, func in pairs(controls.registered_on_press) do for _, func in pairs(controls.registered_on_press) do
func(player, cname) func(player, cname)
end end
controls.players[player_name][cname] = {true, os.clock()} controls.players[player_name][cname] = {true, clock()}
elseif cbool==true and controls.players[player_name][cname][1]==true then elseif cbool==true and controls.players[player_name][cname][1]==true then
for _, func in pairs(controls.registered_on_hold) do for _, func in pairs(controls.registered_on_hold) do
func(player, cname, os.clock()-controls.players[player_name][cname][2]) func(player, cname, clock()-controls.players[player_name][cname][2])
end end
--Release a key --Release a key
elseif cbool==false and controls.players[player_name][cname][1]==true then elseif cbool==false and controls.players[player_name][cname][1]==true then
for _, func in pairs(controls.registered_on_release) do for _, func in pairs(controls.registered_on_release) do
func(player, cname, os.clock()-controls.players[player_name][cname][2]) func(player, cname, clock()-controls.players[player_name][cname][2])
end end
controls.players[player_name][cname] = {false} controls.players[player_name][cname] = {false}
end end

View File

@ -1 +1,4 @@
name=controls name = controls
author = Arcelmi
description = Controls framework by Arcelmi

View File

@ -1 +1,4 @@
name = flowlib name = flowlib
author = Qwertymine3
description = Simple flow functions for use in Minetest mods by Qwertymine3

View File

@ -1 +0,0 @@
Adds additional ways for nodes to be attached.

View File

@ -0,0 +1,3 @@
name = mcl_attached
author = Wuzzy
description = Adds additional ways for nodes to be attached.

View File

@ -0,0 +1,36 @@
mcl_colors = {
BLACK = "#000000",
DARK_BLUE = "#0000AA",
DARK_GREEN = "#00AA00",
DARK_AQUA = "#00AAAA",
DARK_RED = "#AA0000",
DARK_PURPLE = "#AA00AA",
GOLD = "#FFAA00",
GRAY = "#AAAAAA",
DARK_GRAY = "#555555",
BLUE = "#5555FF",
GREEN = "#55FF55",
AQUA = "#55FFFF",
RED = "#FF5555",
LIGHT_PURPLE = "#FF55FF",
YELLOW = "#FFFF55",
WHITE = "#FFFFFF",
background = {
BLACK = "#000000",
DARK_BLUE = "#00002A",
DARK_GREEN = "#002A00",
DARK_AQUA = "#002A2A",
DARK_RED = "#2A0000",
DARK_PURPLE = "#2A002A",
GOLD = "#2A2A00",
GRAY = "#2A2A2A",
DARK_GRAY = "#151515",
BLUE = "#15153F",
GREEN = "#153F15",
AQUA = "#153F3F",
RED = "#3F1515",
LIGHT_PURPLE = "#3F153F",
YELLOW = "#3F3F15",
WHITE = "#373501",
}
}

View File

@ -0,0 +1,3 @@
name = mcl_colors
author = Fleckenstein
description = The HTML sequences for the minecraft colors

View File

@ -18,6 +18,16 @@ local CONTENT_FIRE = minetest.get_content_id("mcl_fire:fire")
local S = minetest.get_translator("mcl_explosions") local S = minetest.get_translator("mcl_explosions")
local hash_node_position = minetest.hash_node_position
local get_objects_inside_radius = minetest.get_objects_inside_radius
local get_position_from_hash = minetest.get_position_from_hash
local get_node_drops = minetest.get_node_drops
local get_name_from_content_id = minetest.get_name_from_content_id
local get_voxel_manip = minetest.get_voxel_manip
local bulk_set_node = minetest.bulk_set_node
local check_for_falling = minetest.check_for_falling
local add_item = minetest.add_item
-- Saved sphere explosion shapes for various radiuses -- Saved sphere explosion shapes for various radiuses
local sphere_shapes = {} local sphere_shapes = {}
@ -64,7 +74,7 @@ local function compute_sphere_rays(radius)
local d = x * x + y * y + z * z local d = x * x + y * y + z * z
if d <= radius * radius then if d <= radius * radius then
local pos = { x = x, y = y, z = z } local pos = { x = x, y = y, z = z }
sphere[minetest.hash_node_position(pos)] = pos sphere[hash_node_position(pos)] = pos
break break
end end
end end
@ -79,7 +89,7 @@ local function compute_sphere_rays(radius)
local d = x * x + y * y + z * z local d = x * x + y * y + z * z
if d <= radius * radius then if d <= radius * radius then
local pos = { x = x, y = y, z = z } local pos = { x = x, y = y, z = z }
sphere[minetest.hash_node_position(pos)] = pos sphere[hash_node_position(pos)] = pos
break break
end end
end end
@ -94,7 +104,7 @@ local function compute_sphere_rays(radius)
local d = x * x + y * y + z * z local d = x * x + y * y + z * z
if d <= radius * radius then if d <= radius * radius then
local pos = { x = x, y = y, z = z } local pos = { x = x, y = y, z = z }
sphere[minetest.hash_node_position(pos)] = pos sphere[hash_node_position(pos)] = pos
break break
end end
end end
@ -149,12 +159,14 @@ end
-- max_blast_resistance - The explosion will treat all non-indestructible nodes -- max_blast_resistance - The explosion will treat all non-indestructible nodes
-- as having a blast resistance of no more than this -- as having a blast resistance of no more than this
-- value -- value
-- grief_protected - If true, the explosion will also destroy nodes which have
-- been protected
-- --
-- Note that this function has been optimized, it contains code which has been -- Note that this function has been optimized, it contains code which has been
-- inlined to avoid function calls and unnecessary table creation. This was -- inlined to avoid function calls and unnecessary table creation. This was
-- measured to give a significant performance increase. -- measured to give a significant performance increase.
local function trace_explode(pos, strength, raydirs, radius, info, puncher) local function trace_explode(pos, strength, raydirs, radius, info, puncher)
local vm = minetest.get_voxel_manip() local vm = get_voxel_manip()
local emin, emax = vm:read_from_map(vector.subtract(pos, radius), local emin, emax = vm:read_from_map(vector.subtract(pos, radius),
vector.add(pos, radius)) vector.add(pos, radius))
@ -178,6 +190,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
local drop_chance = info.drop_chance local drop_chance = info.drop_chance
local fire = info.fire local fire = info.fire
local max_blast_resistance = info.max_blast_resistance local max_blast_resistance = info.max_blast_resistance
local grief_protected = info.grief_protected
-- Trace rays for environment destruction -- Trace rays for environment destruction
if info.griefing then if info.griefing then
@ -194,6 +207,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
local npos_x = math.floor(rpos_x + 0.5) local npos_x = math.floor(rpos_x + 0.5)
local npos_y = math.floor(rpos_y + 0.5) local npos_y = math.floor(rpos_y + 0.5)
local npos_z = math.floor(rpos_z + 0.5) local npos_z = math.floor(rpos_z + 0.5)
local npos = { x = npos_x, y = npos_y, z = npos_z }
local idx = (npos_z - emin_z) * zstride + (npos_y - emin_y) * ystride + local idx = (npos_z - emin_z) * zstride + (npos_y - emin_y) * ystride +
npos_x - emin_x + 1 npos_x - emin_x + 1
@ -203,7 +217,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
br = max_blast_resistance br = max_blast_resistance
end end
local hash = minetest.hash_node_position({x=npos_x, y=npos_y, z=npos_z}) local hash = hash_node_position(npos)
rpos_x = rpos_x + STEP_LENGTH * rdir_x rpos_x = rpos_x + STEP_LENGTH * rdir_x
rpos_y = rpos_y + STEP_LENGTH * rdir_y rpos_y = rpos_y + STEP_LENGTH * rdir_y
@ -215,8 +229,10 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
break break
end end
if cid ~= minetest.CONTENT_AIR and not minetest.is_protected({x = npos_x, y = npos_y, z = npos_z}, "") then if cid ~= minetest.CONTENT_AIR then
destroy[hash] = idx if not minetest.is_protected(npos, "") or grief_protected then
destroy[hash] = idx
end
end end
end end
end end
@ -224,7 +240,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
-- Entities in radius of explosion -- Entities in radius of explosion
local punch_radius = 2 * strength local punch_radius = 2 * strength
local objs = minetest.get_objects_inside_radius(pos, punch_radius) local objs = get_objects_inside_radius(pos, punch_radius)
-- Trace rays for entity damage -- Trace rays for entity damage
for _, obj in pairs(objs) do for _, obj in pairs(objs) do
@ -329,13 +345,13 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
minetest.after(0.3, function(obj, damage, impact, punch_dir) -- 0.2 is minimum delay for closing old formspec and open died formspec -- TODO: REMOVE THIS IN THE FUTURE minetest.after(0.3, function(obj, damage, impact, punch_dir) -- 0.2 is minimum delay for closing old formspec and open died formspec -- TODO: REMOVE THIS IN THE FUTURE
if not obj then return end if not obj then return end
obj:punch(obj, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir) obj:punch(obj, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir)
obj:add_player_velocity(vector.multiply(punch_dir, impact * 20)) obj:add_velocity(vector.multiply(punch_dir, impact * 20))
end, obj, damage, impact, vector.new(punch_dir)) end, obj, damage, impact, vector.new(punch_dir))
else else
obj:punch(source, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir) obj:punch(source, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir)
if obj:is_player() then if obj:is_player() then
obj:add_player_velocity(vector.multiply(punch_dir, impact * 20)) obj:add_velocity(vector.multiply(punch_dir, impact * 20))
elseif ent.tnt_knockback then elseif ent.tnt_knockback then
obj:add_velocity(vector.multiply(punch_dir, impact * 20)) obj:add_velocity(vector.multiply(punch_dir, impact * 20))
end end
@ -353,46 +369,46 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
local remove = true local remove = true
if do_drop or on_blast ~= nil then if do_drop or on_blast ~= nil then
local npos = minetest.get_position_from_hash(hash) local npos = get_position_from_hash(hash)
if on_blast ~= nil then if on_blast ~= nil then
on_blast(npos, 1.0, do_drop) on_blast(npos, 1.0, do_drop)
remove = false remove = false
else else
local name = minetest.get_name_from_content_id(data[idx]) local name = get_name_from_content_id(data[idx])
local drop = minetest.get_node_drops(name, "") local drop = get_node_drops(name, "")
for _, item in ipairs(drop) do for _, item in ipairs(drop) do
if type(item) ~= "string" then if type(item) ~= "string" then
item = item:get_name() .. item:get_count() item = item:get_name() .. item:get_count()
end end
minetest.add_item(npos, item) add_item(npos, item)
end end
end end
end end
if remove then if remove then
if mod_fire and fire and math.random(1, 3) == 1 then if mod_fire and fire and math.random(1, 3) == 1 then
table.insert(fires, minetest.get_position_from_hash(hash)) table.insert(fires, get_position_from_hash(hash))
else else
table.insert(airs, minetest.get_position_from_hash(hash)) table.insert(airs, get_position_from_hash(hash))
end end
end end
end end
-- We use bulk_set_node instead of LVM because we want to have on_destruct and -- We use bulk_set_node instead of LVM because we want to have on_destruct and
-- on_construct being called -- on_construct being called
if #airs > 0 then if #airs > 0 then
minetest.bulk_set_node(airs, {name="air"}) bulk_set_node(airs, {name="air"})
end end
if #fires > 0 then if #fires > 0 then
minetest.bulk_set_node(fires, {name="mcl_fire:fire"}) bulk_set_node(fires, {name="mcl_fire:fire"})
end end
-- Update falling nodes -- Update falling nodes
for a=1, #airs do for a=1, #airs do
local p = airs[a] local p = airs[a]
minetest.check_for_falling({x=p.x, y=p.y+1, z=p.z}) check_for_falling({x=p.x, y=p.y+1, z=p.z})
end end
for f=1, #fires do for f=1, #fires do
local p = fires[f] local p = fires[f]
minetest.check_for_falling({x=p.x, y=p.y+1, z=p.z}) check_for_falling({x=p.x, y=p.y+1, z=p.z})
end end
-- Log explosion -- Log explosion
@ -418,6 +434,8 @@ end
-- particles - If true, the explosion will create particles (default: true) -- particles - If true, the explosion will create particles (default: true)
-- fire - If true, 1/3 nodes become fire (default: false) -- fire - If true, 1/3 nodes become fire (default: false)
-- griefing - If true, the explosion will destroy nodes (default: true) -- griefing - If true, the explosion will destroy nodes (default: true)
-- grief_protected - If true, the explosion will also destroy nodes which have
-- been protected (default: false)
function mcl_explosions.explode(pos, strength, info, puncher) function mcl_explosions.explode(pos, strength, info, puncher)
if info == nil then if info == nil then
info = {} info = {}
@ -437,6 +455,7 @@ function mcl_explosions.explode(pos, strength, info, puncher)
if info.sound == nil then info.sound = true end if info.sound == nil then info.sound = true end
if info.fire == nil then info.fire = false end if info.fire == nil then info.fire = false end
if info.griefing == nil then info.griefing = true end if info.griefing == nil then info.griefing = true end
if info.grief_protected == nil then info.grief_protected = false end
if info.max_blast_resistance == nil then if info.max_blast_resistance == nil then
info.max_blast_resistance = INDESTRUCT_BLASTRES info.max_blast_resistance = INDESTRUCT_BLASTRES
end end

View File

@ -1,4 +1,5 @@
name = mcl_explosions name = mcl_explosions
author = ryvnf
description = A common API to create explosions. description = A common API to create explosions.
depends = mcl_particles depends = mcl_particles
optional_depends = mcl_fire optional_depends = mcl_fire

View File

@ -1 +0,0 @@
Initialization mod of MineClone 2. Defines some common shared variables and sets up initial default settings which have to be set at the beginning.

View File

@ -46,6 +46,42 @@ local numcmax = math.max(math.floor((mapgen_limit_max - ccfmax) / chunk_size_in_
mcl_vars.mapgen_edge_min = central_chunk_min_pos - numcmin * chunk_size_in_nodes mcl_vars.mapgen_edge_min = central_chunk_min_pos - numcmin * chunk_size_in_nodes
mcl_vars.mapgen_edge_max = central_chunk_max_pos + numcmax * chunk_size_in_nodes mcl_vars.mapgen_edge_max = central_chunk_max_pos + numcmax * chunk_size_in_nodes
local function coordinate_to_block(x)
return math.floor(x / mcl_vars.MAP_BLOCKSIZE)
end
local function coordinate_to_chunk(x)
return math.floor((coordinate_to_block(x) + central_chunk_offset) / mcl_vars.chunksize)
end
function mcl_vars.pos_to_block(pos)
return {
x = coordinate_to_block(pos.x),
y = coordinate_to_block(pos.y),
z = coordinate_to_block(pos.z)
}
end
function mcl_vars.pos_to_chunk(pos)
return {
x = coordinate_to_chunk(pos.x),
y = coordinate_to_chunk(pos.y),
z = coordinate_to_chunk(pos.z)
}
end
local k_positive = math.ceil(mcl_vars.MAX_MAP_GENERATION_LIMIT / chunk_size_in_nodes)
local k_positive_z = k_positive * 2
local k_positive_y = k_positive_z * k_positive_z
function mcl_vars.get_chunk_number(pos) -- unsigned int
local c = mcl_vars.pos_to_chunk(pos)
return
(c.y + k_positive) * k_positive_y +
(c.z + k_positive) * k_positive_z +
c.x + k_positive
end
if not superflat and not singlenode then if not superflat and not singlenode then
-- Normal mode -- Normal mode
--[[ Realm stacking (h is for height) --[[ Realm stacking (h is for height)
@ -91,7 +127,7 @@ else
mcl_vars.mg_bedrock_is_rough = false mcl_vars.mg_bedrock_is_rough = false
end end
mcl_vars.mg_overworld_max = 31000 mcl_vars.mg_overworld_max = mcl_vars.mapgen_edge_max
-- The Nether (around Y = -29000) -- The Nether (around Y = -29000)
mcl_vars.mg_nether_min = -29067 -- Carefully chosen to be at a mapchunk border mcl_vars.mg_nether_min = -29067 -- Carefully chosen to be at a mapchunk border

View File

@ -1 +1,3 @@
name = mcl_init name = mcl_init
author = Wuzzy
description = Initialization mod of MineClone 2. Defines some common shared variables and sets up initial default settings which have to be set at the beginning.

View File

@ -1 +0,0 @@
API for filling a chest with random treasures.

View File

@ -111,14 +111,14 @@ end
Returns a table of length `max_slot` and all natural numbers between 1 and `max_slot` Returns a table of length `max_slot` and all natural numbers between 1 and `max_slot`
in a random order. in a random order.
]] ]]
local function get_random_slots(max_slot) local function get_random_slots(max_slot, pr)
local slots = {} local slots = {}
for s=1, max_slot do for s=1, max_slot do
slots[s] = s slots[s] = s
end end
local slots_out = {} local slots_out = {}
while #slots > 0 do while #slots > 0 do
local r = math.random(1, #slots) local r = pr and pr:next(1, #slots) or math.random(1, #slots)
table.insert(slots_out, slots[r]) table.insert(slots_out, slots[r])
table.remove(slots, r) table.remove(slots, r)
end end
@ -135,9 +135,9 @@ Items will be added from start of the table to end.
If the inventory already has occupied slots, or is If the inventory already has occupied slots, or is
too small, placement of some items might fail. too small, placement of some items might fail.
]] ]]
function mcl_loot.fill_inventory(inv, listname, items) function mcl_loot.fill_inventory(inv, listname, items, pr)
local size = inv:get_size(listname) local size = inv:get_size(listname)
local slots = get_random_slots(size) local slots = get_random_slots(size, pr)
local leftovers = {} local leftovers = {}
-- 1st pass: Add items into random slots -- 1st pass: Add items into random slots
for i=1, math.min(#items, size) do for i=1, math.min(#items, size) do

View File

@ -1 +1,3 @@
name = mcl_loot name = mcl_loot
author = Wuzzy
description = API for filling a chest with random treasures.

View File

@ -1 +0,0 @@
Contains particle images of MineClone 2. No code.

View File

@ -1 +1,3 @@
name = mcl_particles name = mcl_particles
author = Wuzzy
description = Contains particle images of MineClone 2. No code.

View File

@ -1 +0,0 @@
This mod contains the core sounds of MineClone 2 as well as helper function for mods to access them.

View File

@ -1 +1,3 @@
name = mcl_sounds name = mcl_sounds
author = Wuzzy
description = This mod contains the core sounds of MineClone 2 as well as helper function for mods to access them.

View File

@ -1 +0,0 @@
mcl_init

View File

@ -1 +0,0 @@
Helper functions for MineClone 2.

View File

@ -406,52 +406,15 @@ function mcl_util.get_object_center(obj)
return pos return pos
end end
local get_node_emerge_queue = {} function mcl_util.get_color(colorstr)
local function ecb_get_far_node(blockpos, action, calls_remaining, param) local mc_color = mcl_colors[colorstr:upper()]
if calls_remaining <= 0 and param then if mc_color then
minetest.log("verbose","[mcl_util] ecb done for param = "..param.." node.name="..minetest.get_node(minetest.string_to_pos(param)).name) colorstr = mc_color
get_node_emerge_queue[param] = nil elseif #colorstr ~= 7 or colorstr:sub(1, 1) ~= "#"then
return
end
local hex = tonumber(colorstr:sub(2, 7), 16)
if hex then
return colorstr, hex
end end
end end
function mcl_util.get_far_node(pos, force)
local node = minetest.get_node(pos)
if node.name ~= "ignore" then
return node
end
minetest.get_voxel_manip():read_from_map(pos, pos)
node = minetest.get_node(pos)
if node.name ~= "ignore" or not force then
return node
end
local blockpos = vector.multiply(vector.floor(vector.divide(pos, mcl_vars.MAP_BLOCKSIZE)), mcl_vars.MAP_BLOCKSIZE)
local key = minetest.pos_to_string(blockpos)
for i=1,2 do -- give engine 2 chances to emerge the data
if not get_node_emerge_queue[key] then
get_node_emerge_queue[key] = 1
minetest.log("verbose","[mcl_util] emerge during get_far_node("..minetest.pos_to_string(pos).."), key="..key..", blockpos="..minetest.pos_to_string(blockpos))
minetest.emerge_area(blockpos, vector.add(blockpos, mcl_vars.MAP_BLOCKSIZE-1), ecb_get_far_node, key)
end
while not get_node_emerge_queue[key] do end
minetest.log("verbose","[mcl_util] emerge finished for node "..minetest.pos_to_string(pos)..", key="..key..", blockpos="..minetest.pos_to_string(blockpos)..", node.name="..mcl_util.get_far_node(pos).name)
node = minetest.get_node(pos)
if node.name ~= "ignore" then
return node
end
minetest.get_voxel_manip():read_from_map(pos, pos)
node = minetest.get_node(pos)
if node.name ~= "ignore" or not force then
return node
end
end
node.name = "air" -- engine continuously returns "ignore" - probably it is a bug
minetest.swap_node(pos, node) -- engine continuously returns "ignore" - probably it is a bug
return node -- engine continuously returns "ignore" - probably it is a bug
end

View File

@ -1 +1,4 @@
name = mcl_util name = mcl_util
author = Wuzzy
description = Helper functions for MineClone 2.
depends = mcl_init

View File

@ -1 +0,0 @@
mcl_init

View File

@ -1 +0,0 @@
Utility functions for worlds and the “dimensions”.

View File

@ -0,0 +1,5 @@
name = mcl_worlds
author = Wuzzy
description = Utility functions for worlds and the “dimensions”.
depends = mcl_init

View File

@ -1,4 +1,10 @@
-- register extra flavours of a base nodedef -- register extra flavours of a base nodedef
local get_connected_players = minetest.get_connected_players
local get_node = minetest.get_node
local vector_add = vector.add
local ceil = math.ceil
walkover = {} walkover = {}
walkover.registered_globals = {} walkover.registered_globals = {}
@ -6,25 +12,38 @@ function walkover.register_global(func)
table.insert(walkover.registered_globals, func) table.insert(walkover.registered_globals, func)
end end
local on_walk = {}
local registered_globals = {}
minetest.register_on_mods_loaded(function()
for name,def in pairs(minetest.registered_nodes) do
if def.on_walk_over then
on_walk[name] = def.on_walk_over
end
end
for _,func in ipairs(walkover.registered_globals) do --cache registered globals
table.insert(registered_globals, func)
end
end)
local timer = 0 local timer = 0
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
timer = timer + dtime; timer = timer + dtime;
if timer >= 0.3 then if timer >= 0.3 then
for _,player in pairs(minetest.get_connected_players()) do for _,player in pairs(get_connected_players()) do
local pp = player:get_pos() local pp = player:get_pos()
pp.y = math.ceil(pp.y) pp.y = ceil(pp.y)
local loc = vector.add(pp, {x=0,y=-1,z=0}) local loc = vector_add(pp, {x=0,y=-1,z=0})
if loc ~= nil then if loc ~= nil then
local nodeiamon = minetest.get_node(loc) local nodeiamon = get_node(loc)
if nodeiamon ~= nil then if nodeiamon ~= nil then
local def = minetest.registered_nodes[nodeiamon.name] if on_walk[nodeiamon.name] then
if def ~= nil and def.on_walk_over ~= nil then on_walk[nodeiamon.name](loc, nodeiamon, player)
def.on_walk_over(loc, nodeiamon, player)
end end
for _, func in ipairs(walkover.registered_globals) do for i = 1, #registered_globals do
func(loc, nodeiamon, player) registered_globals[i](loc, nodeiamon, player)
end end
end end
end end

View File

@ -0,0 +1,4 @@
name = walkover
author = lordfingle
description = Some mode developers have shown an interest in having an `on_walk_over` event. This is useful for pressure-plates and the like.

View File

@ -1 +0,0 @@
mcl_core

View File

@ -0,0 +1,4 @@
name = drippingwater
author = kddekadenz
description = Drops are generated rarely under solid nodes
depends = mcl_core

View File

@ -20,4 +20,4 @@ Authors include:
* Various Minetest / Minetest Game developers and contributors (2012-2016) * Various Minetest / Minetest Game developers and contributors (2012-2016)
* maikerumine (2017) * maikerumine (2017)
* Wuzzy (2017) * Wuzzy (2017)
* Fleckenstein (2020-2021)

View File

@ -1,3 +0,0 @@
mcl_player
mcl_core?
doc_identifier?

View File

@ -1 +0,0 @@
Adds drivable boats.

View File

@ -1,13 +1,24 @@
local S = minetest.get_translator("mcl_boats") local S = minetest.get_translator("mcl_boats")
--
-- Helper functions
--
local function is_water(pos) local boat_visual_size = {x = 3, y = 3, z = 3}
local paddling_speed = 22
local boat_y_offset = 0.35
local boat_y_offset_ground = boat_y_offset + 0.6
local boat_side_offset = 1.001
local boat_max_hp = 4
local function is_group(pos, group)
local nn = minetest.get_node(pos).name local nn = minetest.get_node(pos).name
return minetest.get_item_group(nn, "water") ~= 0 return minetest.get_item_group(nn, group) ~= 0
end end
local function is_water(pos)
return is_group(pos, "water")
end
local function is_ice(pos)
return is_group(pos, "ice")
end
local function get_sign(i) local function get_sign(i)
if i == 0 then if i == 0 then
@ -17,26 +28,83 @@ local function get_sign(i)
end end
end end
local function get_velocity(v, yaw, y) local function get_velocity(v, yaw, y)
local x = -math.sin(yaw) * v local x = -math.sin(yaw) * v
local z = math.cos(yaw) * v local z = math.cos(yaw) * v
return {x = x, y = y, z = z} return {x = x, y = y, z = z}
end end
local function get_v(v) local function get_v(v)
return math.sqrt(v.x ^ 2 + v.z ^ 2) return math.sqrt(v.x ^ 2 + v.z ^ 2)
end end
local boat_visual_size = {x = 3, y = 3} local function check_object(obj)
-- Note: This mod assumes the default player visual_size is {x=1, y=1} return obj and (obj:is_player() or obj:get_luaentity()) and obj
local driver_visual_size = { x = 1/boat_visual_size.x, y = 1/boat_visual_size.y } end
local paddling_speed = 22
local boat_y_offset = 0.35 local function get_visual_size(obj)
local boat_y_offset_ground = boat_y_offset + 0.6 return obj:is_player() and {x = 1, y = 1, z = 1} or obj:get_luaentity()._old_visual_size or obj:get_properties().visual_size
local boat_side_offset = 1.001 end
local boat_max_hp = 4
local function set_attach(boat)
boat._driver:set_attach(boat.object, "",
{x = 0, y = 0.42, z = -1}, {x = 0, y = 0, z = 0})
end
local function set_double_attach(boat)
boat._driver:set_attach(boat.object, "",
{x = 0, y = 0.42, z = 0.8}, {x = 0, y = 0, z = 0})
boat._passenger:set_attach(boat.object, "",
{x = 0, y = 0.42, z = -2.2}, {x = 0, y = 0, z = 0})
end
local function attach_object(self, obj)
if self._driver then
if self._driver:is_player() then
self._passenger = obj
else
self._passenger = self._driver
self._driver = obj
end
set_double_attach(self)
else
self._driver = obj
set_attach(self)
end
local visual_size = get_visual_size(obj)
local yaw = self.object:get_yaw()
obj:set_properties({visual_size = vector.divide(visual_size, boat_visual_size)})
if obj:is_player() then
local name = obj:get_player_name()
mcl_player.player_attached[name] = true
minetest.after(0.2, function(name)
local player = minetest.get_player_by_name(name)
if player then
mcl_player.player_set_animation(player, "sit" , 30)
end
end, name)
obj:set_look_horizontal(yaw)
mcl_tmp_message.message(obj, S("Sneak to dismount"))
else
obj:get_luaentity()._old_visual_size = visual_size
end
end
local function detach_object(obj, change_pos)
obj:set_detach()
obj:set_properties({visual_size = get_visual_size(obj)})
if obj:is_player() then
mcl_player.player_attached[obj:get_player_name()] = false
mcl_player.player_set_animation(obj, "stand" , 30)
else
obj:get_luaentity()._old_visual_size = nil
end
if change_pos then
obj:set_pos(vector.add(obj:get_pos(), vector.new(0, 0.2, 0)))
end
end
-- --
-- Boat entity -- Boat entity
@ -52,6 +120,7 @@ local boat = {
textures = {"mcl_boats_texture_oak_boat.png"}, textures = {"mcl_boats_texture_oak_boat.png"},
visual_size = boat_visual_size, visual_size = boat_visual_size,
hp_max = boat_max_hp, hp_max = boat_max_hp,
damage_texture_modifier = "^[colorize:white:0",
_driver = nil, -- Attached driver (player) or nil if none _driver = nil, -- Attached driver (player) or nil if none
_passenger = nil, _passenger = nil,
@ -60,87 +129,31 @@ local boat = {
_removed = false, -- If true, boat entity is considered removed (e.g. after punch) and should be ignored _removed = false, -- If true, boat entity is considered removed (e.g. after punch) and should be ignored
_itemstring = "mcl_boats:boat", -- Itemstring of the boat item (implies boat type) _itemstring = "mcl_boats:boat", -- Itemstring of the boat item (implies boat type)
_animation = 0, -- 0: not animated; 1: paddling forwards; -1: paddling forwards _animation = 0, -- 0: not animated; 1: paddling forwards; -1: paddling forwards
_regen_timer = 0,
_damage_anim = 0,
} }
local function detach_player(player, change_pos) minetest.register_on_respawnplayer(detach_object)
player:set_detach()
player:set_properties({visual_size = {x=1, y=1}})
mcl_player.player_attached[player:get_player_name()] = false
mcl_player.player_set_animation(player, "stand" , 30)
if change_pos then
player:set_pos(vector.add(player:get_pos(), vector.new(0, 0.2, 0)))
end
end
local function check_object(obj)
return obj and (obj:is_player() or obj:get_luaentity()) and obj
end
local function set_attach(boat)
boat._driver:set_attach(boat.object, "",
{x = 0, y = 0.42, z = -1}, {x = 0, y = 0, z = 0})
end
local function set_double_attach(boat)
boat._driver:set_attach(boat.object, "",
{x = 0, y = 0.42, z = 0.8}, {x = 0, y = 0, z = 0})
boat._passenger:set_attach(boat.object, "",
{x = 0, y = 0.42, z = -2.2}, {x = 0, y = 0, z = 0})
end
minetest.register_on_respawnplayer(detach_player)
function boat.on_rightclick(self, clicker) function boat.on_rightclick(self, clicker)
if self._passenger or not clicker or clicker:get_attach() then if self._passenger or not clicker or clicker:get_attach() then
return return
end end
local name = clicker:get_player_name() attach_object(self, clicker)
--[[if attach and attach:get_luaentity() then
local luaentity = attach:get_luaentity()
if luaentity._driver then
luaentity._driver = nil
end
clicker:set_detach()
clicker:set_properties({visual_size = {x=1, y=1}})
end--]]
if self._driver then
if self._driver:is_player() then
self._passenger = clicker
else
-- for later use: transport mobs in boats
self._passenger = self._driver
self._driver = clicker
end
set_double_attach(self)
else
self._driver = clicker
set_attach(self)
end
clicker:set_properties({ visual_size = driver_visual_size })
mcl_player.player_attached[name] = true
minetest.after(0.2, function(name)
local player = minetest.get_player_by_name(name)
if player then
mcl_player.player_set_animation(player, "sit" , 30)
end
end, name)
clicker:set_look_horizontal(self.object:get_yaw())
mcl_tmp_message.message(clicker, S("Sneak to dismount"))
end end
function boat.on_activate(self, staticdata, dtime_s) function boat.on_activate(self, staticdata, dtime_s)
--self.object:set_armor_groups({immortal = 1}) self.object:set_armor_groups({fleshy = 100})
local data = minetest.deserialize(staticdata) local data = minetest.deserialize(staticdata)
if type(data) == "table" then if type(data) == "table" then
self._v = data.v self._v = data.v
self._last_v = self._v self._last_v = self._v
self._itemstring = data.itemstring self._itemstring = data.itemstring
self.object:set_properties({textures = data.textures, damage_texture_modifier = ""}) self.object:set_properties({textures = data.textures})
end end
end end
function boat.get_staticdata(self) function boat.get_staticdata(self)
return minetest.serialize({ return minetest.serialize({
v = self._v, v = self._v,
@ -149,8 +162,9 @@ function boat.get_staticdata(self)
}) })
end end
function boat.on_death(self, killer) function boat.on_death(self, killer)
mcl_burning.extinguish(self.object)
if killer and killer:is_player() and minetest.is_creative_enabled(killer:get_player_name()) then if killer and killer:is_player() and minetest.is_creative_enabled(killer:get_player_name()) then
local inv = killer:get_inventory() local inv = killer:get_inventory()
if not inv:contains_item("main", self._itemstring) then if not inv:contains_item("main", self._itemstring) then
@ -160,43 +174,62 @@ function boat.on_death(self, killer)
minetest.add_item(self.object:get_pos(), self._itemstring) minetest.add_item(self.object:get_pos(), self._itemstring)
end end
if self._driver then if self._driver then
detach_player(self._driver) detach_object(self._driver)
end end
if self._passenger then if self._passenger then
detach_player(self._passenger) detach_object(self._passenger)
end end
self._driver = nil self._driver = nil
self._passenger = nil self._passenger = nil
end end
function boat.on_punch(self, puncher, time_from_last_punch, tool_capabilities, dir, damage)
if damage > 0 then
self._regen_timer = 0
end
end
function boat.on_step(self, dtime, moveresult) function boat.on_step(self, dtime, moveresult)
mcl_burning.tick(self.object, dtime)
self._v = get_v(self.object:get_velocity()) * get_sign(self._v) self._v = get_v(self.object:get_velocity()) * get_sign(self._v)
local on_water = true
local in_water = false
local v_factor = 1 local v_factor = 1
local v_slowdown = 0.02 local v_slowdown = 0.02
local p = self.object:get_pos() local p = self.object:get_pos()
if (not is_water({x=p.x, y=p.y-boat_y_offset, z=p.z})) then local on_water = true
local on_ice = false
local in_water = is_water({x=p.x, y=p.y-boat_y_offset+1, z=p.z})
local waterp = {x=p.x, y=p.y-boat_y_offset - 0.1, z=p.z}
if not is_water(waterp) then
on_water = false on_water = false
v_factor = 0.5 if not in_water and is_ice(waterp) then
v_slowdown = 0.04 on_ice = true
elseif (is_water({x=p.x, y=p.y-boat_y_offset+1, z=p.z})) then else
v_slowdown = 0.04
v_factor = 0.5
end
elseif in_water then
on_water = false on_water = false
in_water = true in_water = true
v_factor = 0.75 v_factor = 0.75
v_slowdown = 0.05 v_slowdown = 0.05
end end
--local yaw = self.object:get_yaw() local hp = self.object:get_hp()
--local hp = math.min(self.object:get_hp() + 2 * dtime, boat_max_hp) local regen_timer = self._regen_timer + dtime
--self.object:set_rotation(vector.new((boat_max_hp - hp) / boat_max_hp, 0, 0)) if hp >= boat_max_hp then
self.object:set_hp(self.object:get_hp() + 2 * dtime) regen_timer = 0
--self.object:set_yaw(yaw) elseif regen_timer >= 0.5 then
hp = hp + 1
self.object:set_hp(hp)
regen_timer = 0
end
self._regen_timer = regen_timer
if moveresult and moveresult.collides then if moveresult and moveresult.collides then
for _, collision in ipairs(moveresult.collisions) do for _, collision in pairs(moveresult.collisions) do
local pos = collision.node_pos local pos = collision.node_pos
if collision.type == "node" and minetest.get_node_group(minetest.get_node(pos).name, "dig_by_boat") > 0 then if collision.type == "node" and minetest.get_item_group(minetest.get_node(pos).name, "dig_by_boat") > 0 then
minetest.dig_node(pos) minetest.dig_node(pos)
end end
end end
@ -226,7 +259,7 @@ function boat.on_step(self, dtime, moveresult)
end end
local ctrl = self._driver:get_player_control() local ctrl = self._driver:get_player_control()
if ctrl and ctrl.sneak then if ctrl and ctrl.sneak then
detach_player(self._driver, true) detach_object(self._driver, true)
self._driver = nil self._driver = nil
return return
end end
@ -275,11 +308,19 @@ function boat.on_step(self, dtime, moveresult)
self.object:set_animation({x=0, y=40}, 0, 0, true) self.object:set_animation({x=0, y=40}, 0, 0, true)
self._animation = 0 self._animation = 0
end end
for _, obj in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 1.3)) do
local entity = obj:get_luaentity()
if entity and entity._cmi_is_mob then
attach_object(self, obj)
break
end
end
end end
local s = get_sign(self._v) local s = get_sign(self._v)
if not on_water and not in_water and math.abs(self._v) > 1.0 then if not on_ice and not on_water and not in_water and math.abs(self._v) > 2.0 then
v_slowdown = math.min(math.abs(self._v) - 1.0, v_slowdown * 5) v_slowdown = math.min(math.abs(self._v) - 2.0, v_slowdown * 5)
elseif in_water and math.abs(self._v) > 1.5 then elseif not on_ice and in_water and math.abs(self._v) > 1.5 then
v_slowdown = math.min(math.abs(self._v) - 1.5, v_slowdown * 5) v_slowdown = math.min(math.abs(self._v) - 1.5, v_slowdown * 5)
end end
self._v = self._v - v_slowdown * s self._v = self._v - v_slowdown * s
@ -290,7 +331,7 @@ function boat.on_step(self, dtime, moveresult)
p.y = p.y - boat_y_offset p.y = p.y - boat_y_offset
local new_velo local new_velo
local new_acce = {x = 0, y = 0, z = 0} local new_acce = {x = 0, y = 0, z = 0}
if not is_water(p) then if not is_water(p) and not on_ice then
-- Not on water or inside water: Free fall -- Not on water or inside water: Free fall
local nodedef = minetest.registered_nodes[minetest.get_node(p).name] local nodedef = minetest.registered_nodes[minetest.get_node(p).name]
new_acce = {x = 0, y = -9.8, z = 0} new_acce = {x = 0, y = -9.8, z = 0}
@ -320,12 +361,17 @@ function boat.on_step(self, dtime, moveresult)
end end
-- Terminal velocity: 8 m/s per axis of travel -- Terminal velocity: 8 m/s per axis of travel
local terminal_velocity = on_ice and 57.1 or 8.0
for _,axis in pairs({"z","y","x"}) do for _,axis in pairs({"z","y","x"}) do
if math.abs(new_velo[axis]) > 8 then if math.abs(new_velo[axis]) > terminal_velocity then
new_velo[axis] = 8 * get_sign(new_velo[axis]) new_velo[axis] = terminal_velocity * get_sign(new_velo[axis])
end end
end end
local yaw = self.object:get_yaw()
local anim = (boat_max_hp - hp - regen_timer * 2) / boat_max_hp * math.pi / 4
self.object:set_rotation(vector.new(anim, yaw, anim))
self.object:set_velocity(new_velo) self.object:set_velocity(new_velo)
self.object:set_acceleration(new_acce) self.object:set_acceleration(new_acce)
end end

View File

@ -1 +1,7 @@
name = mcl_boats name = mcl_boats
author = PilzAdam
description = Adds drivable boats.
depends = mcl_player
optional_depends = mcl_core, doc_identifier

View File

@ -34,7 +34,7 @@ function mcl_burning.is_burning(obj)
end end
function mcl_burning.is_affected_by_rain(obj) function mcl_burning.is_affected_by_rain(obj)
return mcl_weather.get_weather() == "rain" and mcl_weather.is_outdoor(obj:get_pos()) return mcl_weather and mcl_weather.get_weather() == "rain" and mcl_weather.is_outdoor(obj:get_pos())
end end
function mcl_burning.get_collisionbox(obj, smaller) function mcl_burning.get_collisionbox(obj, smaller)
@ -107,11 +107,7 @@ function mcl_burning.damage(obj)
end end
if do_damage then if do_damage then
local damage = mcl_burning.get(obj, "float", "damage") local new_hp = hp - 1
if damage == 0 then
damage = 1
end
local new_hp = hp - damage
if health then if health then
luaentity.health = new_hp luaentity.health = new_hp
else else
@ -120,7 +116,7 @@ function mcl_burning.damage(obj)
end end
end end
function mcl_burning.set_on_fire(obj, burn_time, damage, interval, reason) function mcl_burning.set_on_fire(obj, burn_time, reason)
local luaentity = obj:get_luaentity() local luaentity = obj:get_luaentity()
if luaentity and luaentity.fire_resistant then if luaentity and luaentity.fire_resistant then
return return
@ -173,8 +169,6 @@ function mcl_burning.set_on_fire(obj, burn_time, damage, interval, reason)
end end
end end
mcl_burning.set(obj, "float", "burn_time", burn_time) mcl_burning.set(obj, "float", "burn_time", burn_time)
mcl_burning.set(obj, "float", "damage", damage)
mcl_burning.set(obj, "float", "interval", interval)
mcl_burning.set(obj, "string", "reason", reason) mcl_burning.set(obj, "string", "reason", reason)
mcl_burning.set(obj, "int", "hud_id", hud_id) mcl_burning.set(obj, "int", "hud_id", hud_id)
mcl_burning.set(obj, "int", "sound_id", sound_id) mcl_burning.set(obj, "int", "sound_id", sound_id)
@ -208,8 +202,6 @@ function mcl_burning.extinguish(obj)
obj:hud_remove(hud_id) obj:hud_remove(hud_id)
end end
mcl_burning.set(obj, "float", "damage")
mcl_burning.set(obj, "float", "interval")
mcl_burning.set(obj, "string", "reason") mcl_burning.set(obj, "string", "reason")
mcl_burning.set(obj, "float", "burn_time") mcl_burning.set(obj, "float", "burn_time")
mcl_burning.set(obj, "float", "damage_timer") mcl_burning.set(obj, "float", "damage_timer")
@ -240,12 +232,7 @@ function mcl_burning.tick(obj, dtime)
local damage_timer = mcl_burning.get(obj, "float", "damage_timer") + dtime local damage_timer = mcl_burning.get(obj, "float", "damage_timer") + dtime
local interval = mcl_burning.get(obj, "float", "interval") if damage_timer >= 1 then
if interval == 0 then
interval = 1
end
if damage_timer >= interval then
damage_timer = 0 damage_timer = 0
mcl_burning.damage(obj) mcl_burning.damage(obj)
end end
@ -280,7 +267,7 @@ function mcl_burning.fire_entity_step(self, dtime)
if not parent or not mcl_burning.is_burning(parent) then if not parent or not mcl_burning.is_burning(parent) then
do_remove = true do_remove = true
else else
for _, other in ipairs(minetest.get_objects_inside_radius(obj:get_pos(), 0)) do for _, other in pairs(minetest.get_objects_inside_radius(obj:get_pos(), 0)) do
local luaentity = obj:get_luaentity() local luaentity = obj:get_luaentity()
if luaentity and luaentity.name == "mcl_burning:fire" and not luaentity.doing_step and not luaentity.removed then if luaentity and luaentity.name == "mcl_burning:fire" and not luaentity.doing_step and not luaentity.removed then
do_remove = true do_remove = true

View File

@ -5,7 +5,7 @@ mcl_burning = {
animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8 animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8
} }
dofile(modpath .. "/engine.lua") dofile(modpath .. "/api.lua")
minetest.register_entity("mcl_burning:fire", { minetest.register_entity("mcl_burning:fire", {
initial_properties = { initial_properties = {
@ -22,7 +22,7 @@ minetest.register_entity("mcl_burning:fire", {
}) })
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
for _, player in ipairs(minetest.get_connected_players()) do for _, player in pairs(minetest.get_connected_players()) do
mcl_burning.tick(player, dtime) mcl_burning.tick(player, dtime)
end end
end) end)
@ -33,4 +33,4 @@ end)
minetest.register_on_leaveplayer(function(player) minetest.register_on_leaveplayer(function(player)
mcl_burning.set(player, "int", "hud_id") mcl_burning.set(player, "int", "hud_id")
end) end)

View File

@ -1 +0,0 @@
Falling node entities, Minecraft-style

View File

@ -1 +1,3 @@
name = mcl_falling_nodes name = mcl_falling_nodes
author = Wuzzy
description = Falling node entities, Minecraft-style

View File

@ -1,2 +0,0 @@
flowlib
mcl_enchanting

View File

@ -1 +0,0 @@
Dropped items will be attracted to the player like a magnet.

View File

@ -54,14 +54,14 @@ local disable_physics = function(object, luaentity, ignore_check, reset_movement
end end
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
for _,player in ipairs(minetest.get_connected_players()) do for _,player in pairs(minetest.get_connected_players()) do
if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then
local pos = player:get_pos() local pos = player:get_pos()
local inv = player:get_inventory() local inv = player:get_inventory()
local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z} local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z}
--magnet and collection --magnet and collection
for _,object in ipairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do for _,object in pairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do
if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then
object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime
local collected = false local collected = false
@ -785,7 +785,7 @@ minetest.register_entity(":__builtin:item", {
if self.physical_state then if self.physical_state then
local own_stack = ItemStack(self.object:get_luaentity().itemstring) local own_stack = ItemStack(self.object:get_luaentity().itemstring)
-- Merge with close entities of the same item -- Merge with close entities of the same item
for _, object in ipairs(minetest.get_objects_inside_radius(p, 0.8)) do for _, object in pairs(minetest.get_objects_inside_radius(p, 0.8)) do
local obj = object:get_luaentity() local obj = object:get_luaentity()
if obj and obj.name == "__builtin:item" if obj and obj.name == "__builtin:item"
and obj.physical_state == false then and obj.physical_state == false then

View File

@ -1 +1,4 @@
name = mcl_item_entity name = mcl_item_entity
author = PilzAdam
description = Dropped items will be attracted to the player like a magnet.
depends = flowlib, mcl_enchanting

View File

@ -1,12 +0,0 @@
mcl_explosions
mcl_core
mcl_sounds
mcl_player
mcl_achievements
mcl_chests
mcl_furnaces
mesecons_commandblock
mcl_hoppers
mcl_tnt
mesecons
doc_identifier?

View File

@ -1 +0,0 @@
Minecarts are vehicles to move players quickly on rails.

View File

@ -175,6 +175,19 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
cart.on_activate_by_rail = on_activate_by_rail cart.on_activate_by_rail = on_activate_by_rail
function cart:on_step(dtime) function cart:on_step(dtime)
local ctrl, player = nil, nil
if self._driver then
player = minetest.get_player_by_name(self._driver)
if player then
ctrl = player:get_player_control()
-- player detach
if ctrl.sneak then
detach_driver(self)
return
end
end
end
local vel = self.object:get_velocity() local vel = self.object:get_velocity()
local update = {} local update = {}
if self._last_float_check == nil then if self._last_float_check == nil then
@ -190,18 +203,14 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
node = minetest.get_node(rou_pos) node = minetest.get_node(rou_pos)
local g = minetest.get_item_group(node.name, "connect_to_raillike") local g = minetest.get_item_group(node.name, "connect_to_raillike")
if g ~= self._railtype and self._railtype ~= nil then if g ~= self._railtype and self._railtype ~= nil then
local player
-- Detach driver -- Detach driver
if self._driver then if player then
if self._old_pos then if self._old_pos then
self.object:set_pos(self._old_pos) self.object:set_pos(self._old_pos)
end end
mcl_player.player_attached[self._driver] = nil mcl_player.player_attached[self._driver] = nil
player = minetest.get_player_by_name(self._driver) player:set_detach()
if player then player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0})
player:set_detach()
player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0})
end
end end
-- Explode if already ignited -- Explode if already ignited
@ -337,14 +346,6 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
end end
end end
local ctrl, player = nil, nil
if self._driver then
player = minetest.get_player_by_name(self._driver)
if player then
ctrl = player:get_player_control()
end
end
-- Stop cart if velocity vector flips -- Stop cart if velocity vector flips
if self._old_vel and self._old_vel.y == 0 and if self._old_vel and self._old_vel.y == 0 and
(self._old_vel.x * vel.x < 0 or self._old_vel.z * vel.z < 0) then (self._old_vel.x * vel.x < 0 or self._old_vel.z * vel.z < 0) then
@ -643,6 +644,7 @@ register_minecart(
if player then if player then
mcl_player.player_set_animation(player, "sit" , 30) mcl_player.player_set_animation(player, "sit" , 30)
player:set_eye_offset({x=0, y=-5.5, z=0},{x=0, y=-4, z=0}) player:set_eye_offset({x=0, y=-5.5, z=0},{x=0, y=-4, z=0})
mcl_tmp_message.message(clicker, S("Sneak to dismount"))
end end
end, name) end, name)
end end
@ -660,6 +662,8 @@ register_minecart(
"mcl_minecarts_minecart_chest.png", "mcl_minecarts_minecart_chest.png",
{"mcl_minecarts:minecart", "mcl_chests:chest"}, {"mcl_minecarts:minecart", "mcl_chests:chest"},
nil, nil, false) nil, nil, false)
mcl_wip.register_wip_item("mcl_minecarts:chest_minecart")
-- Minecart with Furnace -- Minecart with Furnace
register_minecart( register_minecart(
@ -715,6 +719,8 @@ register_minecart(
end, nil, false end, nil, false
) )
mcl_wip.register_wip_item("mcl_minecarts:furnace_minecart")
-- Minecart with Command Block -- Minecart with Command Block
register_minecart( register_minecart(
"mcl_minecarts:command_block_minecart", "mcl_minecarts:command_block_minecart",
@ -736,6 +742,8 @@ register_minecart(
nil, nil, false nil, nil, false
) )
mcl_wip.register_wip_item("mcl_minecarts:command_block_minecart")
-- Minecart with Hopper -- Minecart with Hopper
register_minecart( register_minecart(
"mcl_minecarts:hopper_minecart", "mcl_minecarts:hopper_minecart",
@ -754,6 +762,8 @@ register_minecart(
nil, nil, false nil, nil, false
) )
mcl_wip.register_wip_item("mcl_minecarts:hopper_minecart")
-- Minecart with TNT -- Minecart with TNT
register_minecart( register_minecart(
"mcl_minecarts:tnt_minecart", "mcl_minecarts:tnt_minecart",

View File

@ -33,3 +33,4 @@ Activates minecarts when powered=Активирует особые вагоне
Emits redstone power when a minecart is detected=Испускает энергию редстоуна при обнаружении вагонетки Emits redstone power when a minecart is detected=Испускает энергию редстоуна при обнаружении вагонетки
Vehicle for fast travel on rails=Быстрый железнодорожный транспорт Vehicle for fast travel on rails=Быстрый железнодорожный транспорт
Can be ignited by tools or powered activator rail=Можно воспламенить с помощью инструмента или подключенного рельсового активатора Can be ignited by tools or powered activator rail=Можно воспламенить с помощью инструмента или подключенного рельсового активатора
Sneak to dismount=Нажмите [Красться] для высадки

View File

@ -33,3 +33,4 @@ Activates minecarts when powered=
Emits redstone power when a minecart is detected= Emits redstone power when a minecart is detected=
Vehicle for fast travel on rails= Vehicle for fast travel on rails=
Can be ignited by tools or powered activator rail= Can be ignited by tools or powered activator rail=
Sneak to dismount=

View File

@ -1 +1,6 @@
name = mcl_minecarts name = mcl_minecarts
author = Krock
description = Minecarts are vehicles to move players quickly on rails.
depends = mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons, mcl_wip
optional_depends = doc_identifier

View File

@ -226,7 +226,7 @@ local collision = function(self)
local z = 0 local z = 0
local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5 local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5
for _,object in ipairs(minetest.get_objects_inside_radius(pos, width)) do for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do
if object:is_player() if object:is_player()
or (object:get_luaentity()._cmi_is_mob == true and object ~= self.object) then or (object:get_luaentity()._cmi_is_mob == true and object ~= self.object) then
@ -396,7 +396,7 @@ local is_node_dangerous = function(self, nodename)
return true return true
end end
end end
if minetest.registered_nodes[nn].damage_per_second and minetest.registered_nodes[nn].damage_per_second > 0 then if minetest.registered_nodes[nn] and minetest.registered_nodes[nn].damage_per_second and minetest.registered_nodes[nn].damage_per_second > 0 then
return true return true
end end
return false return false
@ -751,10 +751,10 @@ local check_for_death = function(self, cause, cmi_cause)
-- play damage sound if health was reduced and make mob flash red. -- play damage sound if health was reduced and make mob flash red.
if damaged then if damaged then
add_texture_mod(self, "^[colorize:#FF000040") add_texture_mod(self, "^[colorize:red:130")
minetest.after(.2, function(self) minetest.after(.2, function(self)
if self and self.object then if self and self.object then
remove_texture_mod(self, "^[colorize:#FF000040") remove_texture_mod(self, "^[colorize:red:130")
end end
end, self) end, self)
mob_sound(self, "damage") mob_sound(self, "damage")
@ -1047,8 +1047,13 @@ local do_env_damage = function(self)
end end
end end
-- Use get_node_light for Minetest version 5.3 where get_natural_light
-- does not exist yet.
local get_light = minetest.get_natural_light or minetest.get_node_light
local sunlight = get_light(pos, self.time_of_day)
-- bright light harms mob -- bright light harms mob
if self.light_damage ~= 0 and (minetest.get_node_light(pos) or 0) > 12 then if self.light_damage ~= 0 and (sunlight or 0) > 12 then
if deal_light_damage(self, pos, self.light_damage) then if deal_light_damage(self, pos, self.light_damage) then
return true return true
end end
@ -1057,9 +1062,9 @@ local do_env_damage = function(self)
if mod_worlds then if mod_worlds then
_, dim = mcl_worlds.y_to_layer(pos.y) _, dim = mcl_worlds.y_to_layer(pos.y)
end end
if (self.sunlight_damage ~= 0 or self.ignited_by_sunlight) and (minetest.get_node_light(pos) or 0) >= minetest.LIGHT_MAX and dim == "overworld" then if (self.sunlight_damage ~= 0 or self.ignited_by_sunlight) and (sunlight or 0) >= minetest.LIGHT_MAX and dim == "overworld" then
if self.ignited_by_sunlight then if self.ignited_by_sunlight then
mcl_burning.set_on_fire(self.object, 10, self.sunlight_damage or 1) mcl_burning.set_on_fire(self.object, 10)
else else
deal_light_damage(self, pos, self.sunlight_damage) deal_light_damage(self, pos, self.sunlight_damage)
return true return true
@ -2975,8 +2980,7 @@ local mob_punch = function(self, hitter, tflp, tool_capabilities, dir)
if weapon then if weapon then
local fire_aspect_level = mcl_enchanting.get_enchantment(weapon, "fire_aspect") local fire_aspect_level = mcl_enchanting.get_enchantment(weapon, "fire_aspect")
if fire_aspect_level > 0 then if fire_aspect_level > 0 then
local damage = fire_aspect_level * 4 - 1 mcl_burning.set_on_fire(self.object, fire_aspect_level * 4)
mcl_burning.set_on_fire(self.object, 4, 1, 4 / damage)
end end
end end
@ -3712,6 +3716,7 @@ end
minetest.register_entity(name, { minetest.register_entity(name, {
use_texture_alpha = def.use_texture_alpha,
stepheight = def.stepheight or 0.6, stepheight = def.stepheight or 0.6,
name = name, name = name,
type = def.type, type = def.type,
@ -4576,9 +4581,9 @@ local timer = 0
minetest.register_globalstep(function(dtime) minetest.register_globalstep(function(dtime)
timer = timer + dtime timer = timer + dtime
if timer < 1 then return end if timer < 1 then return end
for _, player in ipairs(minetest.get_connected_players()) do for _, player in pairs(minetest.get_connected_players()) do
local pos = player:get_pos() local pos = player:get_pos()
for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 47)) do for _, obj in pairs(minetest.get_objects_inside_radius(pos, 47)) do
local lua = obj:get_luaentity() local lua = obj:get_luaentity()
if lua and lua._cmi_is_mob then if lua and lua._cmi_is_mob then
lua.lifetimer = math.max(20, lua.lifetimer) lua.lifetimer = math.max(20, lua.lifetimer)

View File

@ -1 +0,0 @@
Adds a mob API for mods to add animals or monsters, etc.

View File

@ -1,3 +1,5 @@
name = mcl_mobs name = mcl_mobs
author = PilzAdam
description = Adds a mob API for mods to add animals or monsters, etc.
depends = mcl_particles depends = mcl_particles
optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, lucky_block, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, lucky_block, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience

View File

@ -154,7 +154,7 @@ function mobs.attach(entity, player)
minetest.after(0.2, function(name) minetest.after(0.2, function(name)
local player = minetest.get_player_by_name(name) local player = minetest.get_player_by_name(name)
if player then if player then
mcl_player.player_set_animation(player, "sit" , 30) mcl_player.player_set_animation(player, "sit_mount" , 30)
end end
end, player:get_player_name()) end, player:get_player_name())

View File

@ -191,6 +191,14 @@ minetest.register_craftitem("mcl_paintings:painting", {
if pointed_thing.type ~= "node" then if pointed_thing.type ~= "node" then
return itemstack return itemstack
end end
local node = minetest.get_node(pointed_thing.under)
if placer and not placer:get_player_control().sneak then
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then
return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack
end
end
local dir = vector.subtract(pointed_thing.above, pointed_thing.under) local dir = vector.subtract(pointed_thing.above, pointed_thing.under)
dir = vector.normalize(dir) dir = vector.normalize(dir)
if dir.y ~= 0 then if dir.y ~= 0 then
@ -293,6 +301,8 @@ minetest.register_craftitem("mcl_paintings:painting", {
end, end,
}) })
mcl_wip.register_wip_item("mcl_paintings:painting")
minetest.register_craft({ minetest.register_craft({
output = "mcl_paintings:painting", output = "mcl_paintings:painting",
recipe = { recipe = {

View File

@ -1 +1,5 @@
name = mcl_paintings name = mcl_paintings
author = Wuzzy
description = The paintings mod for MCL2
depends = mcl_wip

View File

@ -122,7 +122,7 @@ local arrows = {
} }
local throwing_shoot_arrow = function(itemstack, player) local throwing_shoot_arrow = function(itemstack, player)
for _,arrow in ipairs(arrows) do for _,arrow in pairs(arrows) do
if player:get_inventory():get_stack("main", player:get_wield_index()+1):get_name() == arrow[1] then if player:get_inventory():get_stack("main", player:get_wield_index()+1):get_name() == arrow[1] then
if not minetest.is_creative_enabled(player:get_player_name()) then if not minetest.is_creative_enabled(player:get_player_name()) then
player:get_inventory():remove_item("main", arrow[1]) player:get_inventory():remove_item("main", arrow[1])

View File

@ -91,7 +91,7 @@ mobs:register_arrow("mobs_mc:blaze_fireball", {
if rawget(_G, "armor") and armor.last_damage_types then if rawget(_G, "armor") and armor.last_damage_types then
armor.last_damage_types[player:get_player_name()] = "fireball" armor.last_damage_types[player:get_player_name()] = "fireball"
end end
mcl_burning.set_on_fire(player, 5, 1, 5 / 4, "blaze") mcl_burning.set_on_fire(player, 5, "blaze")
player:punch(self.object, 1.0, { player:punch(self.object, 1.0, {
full_punch_interval = 1.0, full_punch_interval = 1.0,
damage_groups = {fleshy = 5}, damage_groups = {fleshy = 5},
@ -99,7 +99,7 @@ mobs:register_arrow("mobs_mc:blaze_fireball", {
end, end,
hit_mob = function(self, mob) hit_mob = function(self, mob)
mcl_burning.set_on_fire(mob, 5, 1, 5 / 4) mcl_burning.set_on_fire(mob, 5)
mob:punch(self.object, 1.0, { mob:punch(self.object, 1.0, {
full_punch_interval = 1.0, full_punch_interval = 1.0,
damage_groups = {fleshy = 5}, damage_groups = {fleshy = 5},

View File

@ -1,12 +0,0 @@
mcl_init
mcl_particles
default?
mcl_mobs
mcl_tnt?
mcl_bows?
mcl_throwing?
mcl_fishing?
bones?
mesecons_materials?
mobs_mc_gameconfig?
doc_items?

View File

@ -1 +0,0 @@
Adds Minecraft-like monsters and animals.

View File

@ -25,6 +25,7 @@ mobs:register_mob("mobs_mc:enderdragon", {
view_range = 35, view_range = 35,
walk_velocity = 6, walk_velocity = 6,
run_velocity = 6, run_velocity = 6,
can_despawn = false,
sounds = { sounds = {
-- TODO: more sounds -- TODO: more sounds
shoot_attack = "mobs_mc_ender_dragon_shoot", shoot_attack = "mobs_mc_ender_dragon_shoot",
@ -104,3 +105,5 @@ mobs:register_arrow("mobs_mc:dragon_fireball", {
}) })
mobs:register_egg("mobs_mc:enderdragon", S("Ender Dragon"), "mobs_mc_spawn_icon_dragon.png", 0, true) mobs:register_egg("mobs_mc:enderdragon", S("Ender Dragon"), "mobs_mc_spawn_icon_dragon.png", 0, true)
mcl_wip.register_wip_item("mobs_mc:enderdragon")

View File

@ -242,36 +242,39 @@ mobs:register_mob("mobs_mc:enderman", {
}) })
end end
-- RAIN DAMAGE / EVASIVE WARP BEHAVIOUR HERE. -- RAIN DAMAGE / EVASIVE WARP BEHAVIOUR HERE.
if mcl_weather.state == "rain" or mcl_weather.state == "lightning" then local dim = mcl_worlds.pos_to_dimension(enderpos)
local damage = true if dim == "overworld" then
local enderpos = self.object:get_pos() if mcl_weather.state == "rain" or mcl_weather.state == "lightning" then
enderpos.y = enderpos.y+2.89 local damage = true
local height = {x=enderpos.x, y=enderpos.y+512,z=enderpos.z} local enderpos = self.object:get_pos()
local ray = minetest.raycast(enderpos, height, true) enderpos.y = enderpos.y+2.89
-- Check for blocks above enderman. local height = {x=enderpos.x, y=enderpos.y+512,z=enderpos.z}
for pointed_thing in ray do local ray = minetest.raycast(enderpos, height, true)
if pointed_thing.type == "node" then -- Check for blocks above enderman.
local nn = minetest.get_node(minetest.get_pointed_thing_position(pointed_thing)).name for pointed_thing in ray do
local def = minetest.registered_nodes[nn] if pointed_thing.type == "node" then
if (not def) or def.walkable then local nn = minetest.get_node(minetest.get_pointed_thing_position(pointed_thing)).name
-- There's a node in the way. Delete arrow without damage local def = minetest.registered_nodes[nn]
damage = false if (not def) or def.walkable then
break -- There's a node in the way. Delete arrow without damage
damage = false
break
end
end end
end end
end
if damage == true then if damage == true then
self.state = "" self.state = ""
--rain hurts enderman --rain hurts enderman
self.object:punch(self.object, 1.0, { self.object:punch(self.object, 1.0, {
full_punch_interval=1.0, full_punch_interval=1.0,
damage_groups={fleshy=self._damage}, damage_groups={fleshy=self._damage},
}, nil) }, nil)
--randomly teleport hopefully under something. --randomly teleport hopefully under something.
self:teleport(nil) self:teleport(nil)
end
end end
end else return end
-- AGRESSIVELY WARP/CHASE PLAYER BEHAVIOUR HERE. -- AGRESSIVELY WARP/CHASE PLAYER BEHAVIOUR HERE.
if self.state == "attack" then if self.state == "attack" then
--if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then --if (minetest.get_timeofday() * 24000) > 5001 and (minetest.get_timeofday() * 24000) < 19000 then

View File

@ -450,7 +450,7 @@ mobs:spawn_specific("mobs_mc:donkey", mobs_mc.spawn.grassland_savanna, {"air"},
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0) mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0)
mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.png", 0) --mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.png", 0)
mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "mobs_mc_spawn_icon_horse_zombie.png", 0) --mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "mobs_mc_spawn_icon_horse_zombie.png", 0)
mobs:register_egg("mobs_mc:donkey", S("Donkey"), "mobs_mc_spawn_icon_donkey.png", 0) mobs:register_egg("mobs_mc:donkey", S("Donkey"), "mobs_mc_spawn_icon_donkey.png", 0)
mobs:register_egg("mobs_mc:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0) mobs:register_egg("mobs_mc:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0)

View File

@ -1 +1,6 @@
name = mobs_mc name = mobs_mc
author = maikerumine
description = Adds Minecraft-like monsters and animals.
depends = mcl_init, mcl_particles, mcl_mobs, mcl_wip
optional_depends = default, mcl_tnt, mcl_bows, mcl_throwing, mcl_fishing, bones, mesecons_materials, mobs_mc_gameconfig, doc_items

View File

@ -110,6 +110,7 @@ local slime_big = {
spawn_small_alternative = "mobs_mc:slime_small", spawn_small_alternative = "mobs_mc:slime_small",
on_die = spawn_children_on_die("mobs_mc:slime_small", 4, 1.0, 1.5), on_die = spawn_children_on_die("mobs_mc:slime_small", 4, 1.0, 1.5),
fire_resistant = true, fire_resistant = true,
use_texture_alpha = true,
} }
mobs:register_mob("mobs_mc:slime_big", slime_big) mobs:register_mob("mobs_mc:slime_big", slime_big)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 992 B

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@ -412,6 +412,7 @@ local init_trades = function(self, inv)
offered_stack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"}) offered_stack = mcl_enchanting.get_uniform_randomly_enchanted_book({"soul_speed"})
else else
mcl_enchanting.enchant_randomly(offered_stack, math.random(5, 19), false, false, true) mcl_enchanting.enchant_randomly(offered_stack, math.random(5, 19), false, false, true)
mcl_enchanting.unload_enchantments(offered_stack)
end end
end end
@ -457,7 +458,9 @@ local set_trade = function(trader, player, inv, concrete_tradenum)
player_tradenum[name] = concrete_tradenum player_tradenum[name] = concrete_tradenum
local trade = trades[concrete_tradenum] local trade = trades[concrete_tradenum]
inv:set_stack("wanted", 1, ItemStack(trade.wanted[1])) inv:set_stack("wanted", 1, ItemStack(trade.wanted[1]))
inv:set_stack("offered", 1, ItemStack(trade.offered)) local offered = ItemStack(trade.offered)
mcl_enchanting.load_enchantments(offered)
inv:set_stack("offered", 1, offered)
if trade.wanted[2] then if trade.wanted[2] then
local wanted2 = ItemStack(trade.wanted[2]) local wanted2 = ItemStack(trade.wanted[2])
inv:set_stack("wanted", 2, wanted2) inv:set_stack("wanted", 2, wanted2)

View File

@ -104,3 +104,5 @@ mobs:register_arrow("mobs_mc:potion_arrow", {
-- spawn eggs -- spawn eggs
mobs:register_egg("mobs_mc:witch", S("Witch"), "mobs_mc_spawn_icon_witch.png", 0, true) mobs:register_egg("mobs_mc:witch", S("Witch"), "mobs_mc_spawn_icon_witch.png", 0, true)
mcl_wip.register_wip_item("mobs_mc:witch")

View File

@ -43,6 +43,7 @@ mobs:register_mob("mobs_mc:wither", {
dogshoot_switch = 1, dogshoot_switch = 1,
dogshoot_count_max =1, dogshoot_count_max =1,
attack_animals = true, attack_animals = true,
can_despawn = false,
drops = { drops = {
{name = mobs_mc.items.nether_star, {name = mobs_mc.items.nether_star,
chance = 1, chance = 1,
@ -105,3 +106,5 @@ mobs:register_arrow("mobs_mc:wither_skull", {
--Spawn egg --Spawn egg
mobs:register_egg("mobs_mc:wither", S("Wither"), "mobs_mc_spawn_icon_wither.png", 0, true) mobs:register_egg("mobs_mc:wither", S("Wither"), "mobs_mc_spawn_icon_wither.png", 0, true)
mcl_wip.register_wip_item("mobs_mc:wither")

View File

@ -1,2 +0,0 @@
mcl_init
mcl_core

View File

@ -0,0 +1,4 @@
name = mobs_mc_gameconfig
author = Wuzzy
description = mobs_mc game configuration for MCL2
depends = mcl_init, mcl_core

View File

@ -1,2 +0,0 @@
mcl_fire
mcl_death_messages?

View File

@ -1 +0,0 @@
A mod that adds thunder and lightning effects.

View File

@ -11,6 +11,18 @@ of the license, or (at your option) any later version.
local S = minetest.get_translator("lightning") local S = minetest.get_translator("lightning")
local has_mcl_death_msg = minetest.get_modpath("mcl_death_messages")
local get_connected_players = minetest.get_connected_players
local line_of_sight = minetest.line_of_sight
local get_node = minetest.get_node
local set_node = minetest.set_node
local sound_play = minetest.sound_play
local add_particlespawner = minetest.add_particlespawner
local after = minetest.after
local add_entity = minetest.add_entity
local get_objects_inside_radius = minetest.get_objects_inside_radius
local get_item_group = minetest.get_item_group
lightning = {} lightning = {}
lightning.interval_low = 17 lightning.interval_low = 17
@ -45,7 +57,7 @@ minetest.register_globalstep(revertsky)
-- select a random strike point, midpoint -- select a random strike point, midpoint
local function choose_pos(pos) local function choose_pos(pos)
if not pos then if not pos then
local playerlist = minetest.get_connected_players() local playerlist = get_connected_players()
local playercount = table.getn(playerlist) local playercount = table.getn(playerlist)
-- nobody on -- nobody on
@ -67,14 +79,14 @@ local function choose_pos(pos)
pos.z = math.floor(pos.z - (lightning.range_h / 2) + rng:next(1, lightning.range_h)) pos.z = math.floor(pos.z - (lightning.range_h / 2) + rng:next(1, lightning.range_h))
end end
local b, pos2 = minetest.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 -- nothing but air found
if b then if b then
return nil, nil return nil, nil
end end
local n = minetest.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 if n.name == "air" or n.name == "ignore" then
return nil, nil return nil, nil
end end
@ -87,7 +99,7 @@ end
-- * returns: bool - success if a strike happened -- * returns: bool - success if a strike happened
lightning.strike = function(pos) lightning.strike = function(pos)
if lightning.auto then if lightning.auto then
minetest.after(rng:next(lightning.interval_low, lightning.interval_high), lightning.strike) after(rng:next(lightning.interval_low, lightning.interval_high), lightning.strike)
end end
local pos2 local pos2
@ -97,7 +109,7 @@ lightning.strike = function(pos)
return false return false
end end
minetest.add_particlespawner({ add_particlespawner({
amount = 1, amount = 1,
time = 0.2, time = 0.2,
-- make it hit the top of a block exactly with the bottom -- make it hit the top of a block exactly with the bottom
@ -120,16 +132,16 @@ lightning.strike = function(pos)
glow = minetest.LIGHT_MAX, glow = minetest.LIGHT_MAX,
}) })
minetest.sound_play({ name = "lightning_thunder", gain = 10 }, { pos = pos, max_hear_distance = 500 }, true) sound_play({ name = "lightning_thunder", gain = 10 }, { pos = pos, max_hear_distance = 500 }, true)
-- damage nearby objects, transform mobs -- damage nearby objects, transform mobs
local objs = minetest.get_objects_inside_radius(pos2, 3.5) local objs = get_objects_inside_radius(pos2, 3.5)
for o=1, #objs do for o=1, #objs do
local obj = objs[o] local obj = objs[o]
local lua = obj:get_luaentity() local lua = obj:get_luaentity()
if obj:is_player() then if obj:is_player() then
-- Player damage -- Player damage
if minetest.get_modpath("mcl_death_messages") then if has_mcl_death_msg then
mcl_death_messages.player_damage(obj, S("@1 was struck by lightning.", obj:get_player_name())) mcl_death_messages.player_damage(obj, S("@1 was struck by lightning.", obj:get_player_name()))
end end
obj:set_hp(obj:get_hp()-5, { type = "punch", from = "mod" }) obj:set_hp(obj:get_hp()-5, { type = "punch", from = "mod" })
@ -139,7 +151,7 @@ lightning.strike = function(pos)
if lua.name == "mobs_mc:pig" then if lua.name == "mobs_mc:pig" then
local rot = obj:get_yaw() local rot = obj:get_yaw()
obj:remove() obj:remove()
obj = minetest.add_entity(pos2, "mobs_mc:pigman") obj = add_entity(pos2, "mobs_mc:pigman")
obj:set_yaw(rot) obj:set_yaw(rot)
-- mooshroom: toggle color red/brown (no damage) -- mooshroom: toggle color red/brown (no damage)
elseif lua.name == "mobs_mc:mooshroom" then elseif lua.name == "mobs_mc:mooshroom" then
@ -163,7 +175,7 @@ lightning.strike = function(pos)
elseif lua.name == "mobs_mc:creeper" then elseif lua.name == "mobs_mc:creeper" then
local rot = obj:get_yaw() local rot = obj:get_yaw()
obj:remove() obj:remove()
obj = minetest.add_entity(pos2, "mobs_mc:creeper_charged") obj = add_entity(pos2, "mobs_mc:creeper_charged")
obj:set_yaw(rot) obj:set_yaw(rot)
-- Other mobs: Just damage -- Other mobs: Just damage
else else
@ -172,7 +184,7 @@ lightning.strike = function(pos)
end end
end end
local playerlist = minetest.get_connected_players() local playerlist = get_connected_players()
for i = 1, #playerlist do for i = 1, #playerlist do
local player = playerlist[i] local player = playerlist[i]
local sky = {} local sky = {}
@ -197,25 +209,25 @@ lightning.strike = function(pos)
if rng:next(1,100) <= 3 then if rng:next(1,100) <= 3 then
skeleton_lightning = true skeleton_lightning = true
end end
if minetest.get_item_group(minetest.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 minetest.get_node(pos2).name == "air" then if get_node(pos2).name == "air" then
-- Low chance for a lightning to spawn skeleton horse + skeletons -- Low chance for a lightning to spawn skeleton horse + skeletons
if skeleton_lightning then if skeleton_lightning then
minetest.add_entity(pos2, "mobs_mc:skeleton_horse") add_entity(pos2, "mobs_mc:skeleton_horse")
local angle, posadd local angle, posadd
angle = math.random(0, math.pi*2) angle = math.random(0, math.pi*2)
for i=1,3 do 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) posadd = vector.normalize(posadd)
local mob = minetest.add_entity(vector.add(pos2, posadd), "mobs_mc:skeleton") local mob = add_entity(vector.add(pos2, posadd), "mobs_mc:skeleton")
mob:set_yaw(angle-math.pi/2) mob:set_yaw(angle-math.pi/2)
angle = angle + (math.pi*2) / 3 angle = angle + (math.pi*2) / 3
end end
-- Cause a fire -- Cause a fire
else else
minetest.set_node(pos2, {name = "mcl_fire:fire"}) set_node(pos2, {name = "mcl_fire:fire"})
end end
end end
end end
@ -223,9 +235,9 @@ lightning.strike = function(pos)
end end
-- if other mods disable auto lightning during initialization, don't trigger the first lightning. -- if other mods disable auto lightning during initialization, don't trigger the first lightning.
minetest.after(5, function(dtime) after(5, function(dtime)
if lightning.auto then if lightning.auto then
minetest.after(rng:next(lightning.interval_low, after(rng:next(lightning.interval_low,
lightning.interval_high), lightning.strike) lightning.interval_high), lightning.strike)
end end
end) end)

View File

@ -1 +1,6 @@
name = lightning name = lightning
author = sofar
description = A mod that adds thunder and lightning effects.
depends = mcl_fire
optional_depends = mcl_death_messages

View File

@ -1,2 +1,3 @@
name = mcl_moon name = mcl_moon
author = Wuzzy
description = Adds moon phases to the game description = Adds moon phases to the game

View File

@ -1,2 +0,0 @@
mcl_worlds
mcl_death_messages

View File

@ -1 +0,0 @@
Deal damage to entities stuck in the deep void

View File

@ -1,6 +1,14 @@
local S = minetest.get_translator("mcl_void_damage") local S = minetest.get_translator("mcl_void_damage")
local enable_damage = minetest.settings:get_bool("enable_damage") local enable_damage = minetest.settings:get_bool("enable_damage")
local pos_to_dim = mcl_worlds.pos_to_dimension
local dim_change = mcl_worlds.dimension_change
local is_in_void = mcl_worlds.is_in_void
local get_spawn_pos = mcl_spawn.get_player_spawn_pos
local death_msg = mcl_death_messages.player_damage
local send_chat = minetest.chat_send_player
local get_connected = minetest.get_connected_players
local voidtimer = 0 local voidtimer = 0
local VOID_DAMAGE_FREQ = 0.5 local VOID_DAMAGE_FREQ = 0.5
local VOID_DAMAGE = 4 local VOID_DAMAGE = 4
@ -33,7 +41,7 @@ minetest.register_on_mods_loaded(function()
self._void_timer = 0 self._void_timer = 0
local pos = obj:get_pos() local pos = obj:get_pos()
local void, void_deadly = mcl_worlds.is_in_void(pos) local void, void_deadly = is_in_void(pos)
if void_deadly then if void_deadly then
local ent = obj:get_luaentity() local ent = obj:get_luaentity()
obj:remove() obj:remove()
@ -51,11 +59,11 @@ minetest.register_globalstep(function(dtime)
if voidtimer > VOID_DAMAGE_FREQ then if voidtimer > VOID_DAMAGE_FREQ then
voidtimer = 0 voidtimer = 0
local enable_damage = minetest.settings:get_bool("enable_damage") local enable_damage = minetest.settings:get_bool("enable_damage")
local players = minetest.get_connected_players() local players = get_connected()
for p=1, #players do for p=1, #players do
local player = players[p] local player = players[p]
local pos = player:get_pos() local pos = player:get_pos()
local void, void_deadly = mcl_worlds.is_in_void(pos) local void, void_deadly = is_in_void(pos)
if void_deadly then if void_deadly then
local immortal_val = player:get_armor_groups().immortal local immortal_val = player:get_armor_groups().immortal
local is_immortal = false local is_immortal = false
@ -65,14 +73,14 @@ minetest.register_globalstep(function(dtime)
if is_immortal or not enable_damage then if is_immortal or not enable_damage then
-- If damage is disabled, we can't kill players. -- If damage is disabled, we can't kill players.
-- So we just teleport the player back to spawn. -- So we just teleport the player back to spawn.
local spawn = mcl_spawn.get_player_spawn_pos(player) local spawn = get_spawn_pos(player)
player:set_pos(spawn) player:set_pos(spawn)
mcl_worlds.dimension_change(player, mcl_worlds.pos_to_dimension(spawn)) dim_change(player, pos_to_dim(spawn))
minetest.chat_send_player(player:get_player_name(), S("The void is off-limits to you!")) send_chat(player:get_player_name(), S("The void is off-limits to you!"))
elseif enable_damage and not is_immortal then elseif enable_damage and not is_immortal then
-- Damage enabled, not immortal: Deal void damage (4 HP / 0.5 seconds) -- Damage enabled, not immortal: Deal void damage (4 HP / 0.5 seconds)
if player:get_hp() > 0 then if player:get_hp() > 0 then
mcl_death_messages.player_damage(player, S("@1 fell into the endless void.", player:get_player_name())) death_msg(player, S("@1 fell into the endless void.", player:get_player_name()))
player:set_hp(player:get_hp() - VOID_DAMAGE) player:set_hp(player:get_hp() - VOID_DAMAGE)
end end
end end

View File

@ -1 +1,4 @@
name = mcl_void_damage name = mcl_void_damage
author = Wuzzy
description = Deal damage to entities stuck in the deep void
depends = mcl_worlds, mcl_death_messages

View File

@ -1,3 +0,0 @@
mcl_init
mcl_worlds
lightning?

View File

@ -1 +0,0 @@
Weather and sky handling: Rain, snow, thunderstorm, End and Nether ambience

View File

@ -1 +1,5 @@
name = mcl_weather name = mcl_weather
author = xeranas
description = Weather and sky handling: Rain, snow, thunderstorm, End and Nether ambience
depends = mcl_init, mcl_worlds
optional_depends = lightning

View File

@ -27,7 +27,7 @@ minetest.register_globalstep(function(dtime)
if timer < 0.7 then return end if timer < 0.7 then return end
timer = 0 timer = 0
for _, player in ipairs(minetest.get_connected_players()) do for _, player in pairs(minetest.get_connected_players()) do
if not mcl_worlds.has_dust(player:get_pos()) then if not mcl_worlds.has_dust(player:get_pos()) then
return false return false
end end

View File

@ -1,6 +1,8 @@
local PARTICLES_COUNT_RAIN = 30 local PARTICLES_COUNT_RAIN = 30
local PARTICLES_COUNT_THUNDER = 45 local PARTICLES_COUNT_THUNDER = 45
local get_connected_players = minetest.get_connected_players
mcl_weather.rain = { mcl_weather.rain = {
-- max rain particles created at time -- max rain particles created at time
particles_count = PARTICLES_COUNT_RAIN, particles_count = PARTICLES_COUNT_RAIN,
@ -36,7 +38,7 @@ mcl_weather.rain.set_sky_box = function()
{r=85, g=86, b=98}, {r=85, g=86, b=98},
{r=0, g=0, b=0}}) {r=0, g=0, b=0}})
mcl_weather.skycolor.active = true mcl_weather.skycolor.active = true
for _, player in ipairs(minetest.get_connected_players()) do for _, player in pairs(get_connected_players()) do
player:set_clouds({color="#5D5D5FE8"}) player:set_clouds({color="#5D5D5FE8"})
end end
end end
@ -154,7 +156,7 @@ mcl_weather.rain.clear = function()
mcl_weather.rain.init_done = false mcl_weather.rain.init_done = false
mcl_weather.rain.set_particles_mode("rain") mcl_weather.rain.set_particles_mode("rain")
mcl_weather.skycolor.remove_layer("weather-pack-rain-sky") mcl_weather.skycolor.remove_layer("weather-pack-rain-sky")
for _, player in ipairs(minetest.get_connected_players()) do for _, player in pairs(get_connected_players()) do
mcl_weather.rain.remove_sound(player) mcl_weather.rain.remove_sound(player)
mcl_weather.rain.remove_player(player) mcl_weather.rain.remove_player(player)
end end
@ -176,7 +178,7 @@ mcl_weather.rain.make_weather = function()
mcl_weather.rain.init_done = true mcl_weather.rain.init_done = true
end end
for _, player in ipairs(minetest.get_connected_players()) do for _, player in pairs(get_connected_players()) do
if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then
mcl_weather.rain.remove_sound(player) mcl_weather.rain.remove_sound(player)
return false return false

View File

@ -43,7 +43,7 @@ mcl_weather.skycolor = {
-- Remove layer from colors table -- Remove layer from colors table
remove_layer = function(layer_name) remove_layer = function(layer_name)
for k, name in ipairs(mcl_weather.skycolor.layer_names) do for k, name in pairs(mcl_weather.skycolor.layer_names) do
if name == layer_name then if name == layer_name then
table.remove(mcl_weather.skycolor.layer_names, k) table.remove(mcl_weather.skycolor.layer_names, k)
mcl_weather.skycolor.force_update = true mcl_weather.skycolor.force_update = true

View File

@ -1,3 +1,5 @@
local get_connected_players = minetest.get_connected_players
mcl_weather.snow = {} mcl_weather.snow = {}
mcl_weather.snow.particles_count = 15 mcl_weather.snow.particles_count = 15
@ -37,7 +39,7 @@ mcl_weather.snow.set_sky_box = function()
{r=85, g=86, b=86}, {r=85, g=86, b=86},
{r=0, g=0, b=0}}) {r=0, g=0, b=0}})
mcl_weather.skycolor.active = true mcl_weather.skycolor.active = true
for _, player in ipairs(minetest.get_connected_players()) do for _, player in pairs(get_connected_players()) do
player:set_clouds({color="#ADADADE8"}) player:set_clouds({color="#ADADADE8"})
end end
mcl_weather.skycolor.active = true mcl_weather.skycolor.active = true
@ -71,7 +73,7 @@ minetest.register_globalstep(function(dtime)
mcl_weather.snow.init_done = true mcl_weather.snow.init_done = true
end end
for _, player in ipairs(minetest.get_connected_players()) do for _, player in pairs(get_connected_players()) do
if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then
return false return false
end end

View File

@ -1,3 +1,5 @@
local get_connected_players = minetest.get_connected_players
-- turn off lightning mod 'auto mode' -- turn off lightning mod 'auto mode'
lightning.auto = false lightning.auto = false
@ -25,7 +27,7 @@ minetest.register_globalstep(function(dtime)
{r=40, g=40, b=40}, {r=40, g=40, b=40},
{r=0, g=0, b=0}}) {r=0, g=0, b=0}})
mcl_weather.skycolor.active = true mcl_weather.skycolor.active = true
for _, player in ipairs(minetest.get_connected_players()) do for _, player in pairs(get_connected_players()) do
player:set_clouds({color="#3D3D3FE8"}) player:set_clouds({color="#3D3D3FE8"})
end end
mcl_weather.thunder.init_done = true mcl_weather.thunder.init_done = true

View File

@ -1 +0,0 @@
Provides an extensible in-game help with texts about gameplay basics (such a crafting), items and advanced usage.

Some files were not shown because too many files have changed in this diff Show More