forked from Mineclonia/Mineclonia
Compare commits
237 Commits
master
...
mineclone2
Author | SHA1 | Date |
---|---|---|
kay27 | 273aeaffd2 | |
kay27 | e5ccf63d7e | |
kay27 | 77e249af79 | |
kay27 | ae28007f36 | |
Lizzy Fleckenstein | 9a4d26c2ae | |
Lizzy Fleckenstein | 2d1ac1c7fa | |
Lizzy Fleckenstein | f0c2a0a1e9 | |
Elias Åström | 7f56e5efa4 | |
Elias Åström | c1e295de5f | |
Elias Åström | dac3c21628 | |
Elias Åström | b0c7941b3a | |
kay27 | 6bc8219c63 | |
kay27 | 8e43f042b4 | |
Elias Åström | 0996a83ba0 | |
Elias Åström | 1621c23308 | |
kay27 | 04a88fd244 | |
Elias Åström | 1873080046 | |
kay27 | f031120fe5 | |
Elias Åström | 46541a4adc | |
Elias Åström | 10154d5778 | |
kay27 | f7b290267d | |
iliekprogrammar | a18a87e247 | |
iliekprogrammar | dc462e2433 | |
iliekprogrammar | fd9ed93ea4 | |
iliekprogrammar | 69c855be1f | |
iliekprogrammar | 92941534f8 | |
epCode | c877d6e922 | |
iliekprogrammar | 12745bd450 | |
iliekprogrammar | 03be45b983 | |
iliekprogrammar | 34dbddb40a | |
kay27 | 53dcee99cb | |
kay27 | 3a585488b4 | |
kay27 | b871433c47 | |
Nicu | a40e1c4737 | |
Nicu | df8fdda2c5 | |
kay27 | 45f2a26f1c | |
iliekprogrammar | 249b5cfd1e | |
iliekprogrammar | f5f85a2148 | |
Lizzy Fleckenstein | d168bfa791 | |
Lizzy Fleckenstein | c20bd768ec | |
Lizzy Fleckenstein | 67cedf1308 | |
Lizzy Fleckenstein | 9391628813 | |
Lizzy Fleckenstein | 327bb68927 | |
Lizzy Fleckenstein | 906aa3b434 | |
Lizzy Fleckenstein | ecd27a4cdb | |
Lizzy Fleckenstein | 55df2a57f4 | |
Lizzy Fleckenstein | 4ff987ccc5 | |
Lizzy Fleckenstein | f3c37f49b9 | |
Lizzy Fleckenstein | f3580efced | |
Lizzy Fleckenstein | 4a53ba67ab | |
kay27 | ef395af838 | |
kay27 | 60fc57d878 | |
epCode | d02fc0c83d | |
epCode | e474ce6397 | |
ZeDique la Ruleta | b71566aad6 | |
epCode | 4fbb95bed3 | |
ZeDique la Ruleta | 2571c6124b | |
kay27 | 653a633adf | |
Nicu | e61f1e38f2 | |
kay27 | f191be41db | |
kay27 | aa3e4c2846 | |
AFCMS | a482a18a67 | |
Elias Åström | ed30fa0868 | |
kay27 | b3cdb44410 | |
Elias Åström | 8d473a42ca | |
Elias Åström | 0f2c487dca | |
Elias Åström | dc41c594aa | |
Elias Åström | bfe51316ee | |
Elias Åström | 13268965ee | |
Elias Åström | 521f96b4ab | |
Lizzy Fleckenstein | df59cc12a8 | |
Lizzy Fleckenstein | 3df3e957e2 | |
Lizzy Fleckenstein | 0e206e9974 | |
Lizzy Fleckenstein | 6ac0d628ef | |
Lizzy Fleckenstein | 413fbc9c60 | |
Elias Åström | c8b543991f | |
Elias Åström | 8f9650abe4 | |
Elias Åström | 4c46eb2b4b | |
Elias Åström | fe770c19a5 | |
Elias Åström | 0112825a9f | |
Elias Åström | cff0130506 | |
Elias Åström | 7b93f68ed8 | |
Elias Åström | ece4c892f4 | |
Elias Åström | bec1f786a6 | |
Elias Åström | 6458565bf9 | |
Elias Åström | 2e9b3c2259 | |
Elias Åström | 5193730652 | |
Elias Åström | e77473e800 | |
Elias Åström | 922bdbc601 | |
Elias Åström | 3241dbbec5 | |
Elias Åström | b47733507d | |
Elias Åström | f0528b11d7 | |
Elias Åström | 503b3a8149 | |
Elias Åström | 5b5a254b1a | |
Elias Åström | 0c90dda04c | |
Elias Åström | fa86d4e5eb | |
Elias Åström | f8461d5e90 | |
Elias Åström | fb6f5eae7a | |
AFCMS | 558fa57cc6 | |
kay27 | 809b88f57d | |
kay27 | 4c9643fde9 | |
kay27 | e4840e4170 | |
epCode | 61ef6ebc03 | |
epCode | e52d58d15a | |
epCode | 6b1ce182d3 | |
AFCMS | 5df668f6af | |
kay27 | c4f4ede29a | |
kay27 | 7bd1bc23b1 | |
kay27 | 574c38c768 | |
ZeDique la Ruleta | 47312f86ed | |
epCode | 12192d1a8d | |
AFCMS | ae18ca7602 | |
Elias Åström | 5c3bb22036 | |
Elias Åström | 7441f0269b | |
Elias Fleckenstein | a06d0f7474 | |
ZeDique la Ruleta | 6c49c46697 | |
epCode | b82da05590 | |
kay27 | 3a8900f905 | |
kay27 | 0d725252dc | |
epCode | 86f2d639f9 | |
Elias Åström | 0805431231 | |
epCode | 33c589369f | |
AFCMS | 6645c4cb30 | |
AFCMS | 8f30e223e2 | |
AFCMS | 5d17a6b699 | |
AFCMS | f35f80d79a | |
Code-Sploit | 834dfcf9af | |
Code-Sploit | f06a56d7c4 | |
AFCMS | 77167e901d | |
AFCMS | 2da8be9f78 | |
AFCMS | 71bb18cd76 | |
kay27 | cad23bd851 | |
AFCMS | c1da231f9d | |
Lizzy Fleckenstein | cb0d49a5a5 | |
Lizzy Fleckenstein | 19e5670e85 | |
AFCMS | 731d42196a | |
Elias Fleckenstein | 502666932f | |
iliekprogrammar | c30e9e511d | |
iliekprogrammar | 8519730ee4 | |
AFCMS | bd9713ab50 | |
AFCMS | 4b2c963222 | |
iliekprogrammar | 440dd5700d | |
epCode | 39c357672c | |
AFCMS | fe6b7cb89b | |
AFCMS | c8a7ca729e | |
AFCMS | 5098932b98 | |
AFCMS | 671de95357 | |
AFCMS | 2dcaf8fdcb | |
AFCMS | 9eda34b0ff | |
AFCMS | 9d19c3db4b | |
AFCMS | bb9df764c4 | |
AFCMS | e069962c48 | |
iliekprogrammar | 09f97584bc | |
kay27 | d5c82cb2cf | |
iliekprogrammar | 8c0c1380b1 | |
iliekprogrammar | 10c46e91ff | |
iliekprogrammar | b23495b9c1 | |
AFCMS | 53510ea32a | |
AFCMS | 6e561be37c | |
iliekprogrammar | 1b00346790 | |
iliekprogrammar | 7ce6485717 | |
kay27 | 53bfda827a | |
Code-Sploit | 08f522ffff | |
iliekprogrammar | 7a5aa54035 | |
epCode | dd7facfc03 | |
epCode | 1bdf141198 | |
epCode | 975efb2288 | |
Elias Åström | 69e38debe5 | |
AFCMS | 68df2c447a | |
AFCMS | 3ef10cfb30 | |
epCode | 8115575f20 | |
epCode | 46be7c0388 | |
epCode | 90a0858495 | |
epCode | 1d65daa2c9 | |
epCode | 9419db6d35 | |
epCode | 40471399cb | |
AFCMS | a84b70bde6 | |
AFCMS | 36cc040c41 | |
AFCMS | 752f74e554 | |
Lizzy Fleckenstein | 75c2787583 | |
Lizzy Fleckenstein | 88372778c9 | |
AFCMS | 6c3d4524a0 | |
Lizzy Fleckenstein | 0a5b1e75d0 | |
Lizzy Fleckenstein | 87e4bed630 | |
Lizzy Fleckenstein | 8e28690303 | |
AFCMS | ad87169120 | |
AFCMS | 81167b4431 | |
epCode | cb10a5508b | |
epCode | eeb1f88e08 | |
epCode | 360070bb6a | |
AFCMS | 06e8e972cc | |
AFCMS | 8c87014a01 | |
AFCMS | fb8b0e877e | |
AFCMS | bed3dd87ad | |
AFCMS | 1a60d08a37 | |
epCode | 19337489f6 | |
AFCMS | 6fd6717302 | |
AFCMS | 787d997e51 | |
AFCMS | 3b7b055e2c | |
AFCMS | d37d6fe07f | |
AFCMS | 7b5d67cdbe | |
AFCMS | 134005180c | |
AFCMS | 20e0aed58a | |
AFCMS | 21ddae3dc1 | |
AFCMS | 5124a97add | |
AFCMS | 31eff23ce8 | |
AFCMS | 9a910e033b | |
epCode | d12009538e | |
AFCMS | d3a2faefe2 | |
kay27 | 6e6809f360 | |
kay27 | 15fa1e5b7a | |
AFCMS | d274f6f444 | |
AFCMS | bddc4a3ac7 | |
AFCMS | a6bceb08ee | |
kay27 | 8ed28adf7c | |
kay27 | 66febf158a | |
kay27 | 45c0c576f7 | |
AFCMS | 3635b848d5 | |
kay27 | f3fb80200d | |
Elias Fleckenstein | 95111e1d8d | |
AFCMS | b0c57beacd | |
Elias Fleckenstein | 2fba745724 | |
AFCMS | e3eb8c7ac8 | |
AFCMS | 1f1f9f54a2 | |
AFCMS | b1ab79b857 | |
Lizzy Fleckenstein | 2125c51c9c | |
AFCMS | d71e296602 | |
AFCMS | 71353ac934 | |
AFCMS | 0e8b5c403a | |
Lizzy Fleckenstein | 09671b7ac9 | |
Lizzy Fleckenstein | 31441a02e5 | |
AFCMS | 68d8eb4c9c | |
Lizzy Fleckenstein | d57db0444f | |
Lizzy Fleckenstein | 713f933a99 | |
Lizzy Fleckenstein | ee084f33a7 | |
epCode | 5f544bd5b3 | |
epCode | 65734d0fa4 |
13
API.md
13
API.md
|
@ -17,6 +17,10 @@ Items can have these fields:
|
|||
anvil.
|
||||
See `mcl_banners` for an example.
|
||||
|
||||
Tools can have these fields:
|
||||
* `_mcl_diggroups`: Specifies the digging groups that a tool can dig and how
|
||||
efficiently. See `_mcl_autogroup` for more information.
|
||||
|
||||
All nodes can have these fields:
|
||||
|
||||
* `_mcl_hardness`: Hardness of the block, ranges from 0 to infinity (represented by -1). Determines digging times. Default: 0
|
||||
|
@ -39,7 +43,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`
|
||||
|
||||
## 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.
|
||||
This is a fork of Mobs Redo [`mobs`] by TenPlus1.
|
||||
|
@ -67,6 +71,9 @@ chances are good that it works out of the box.
|
|||
* Get flowing direction of liquids: `CORE/flowlib`
|
||||
* `on_walk_over` callback for nodes: `CORE/walkover`
|
||||
* Get node names close to player (to reduce constant querying): `PLAYER/mcl_playerinfo`
|
||||
* Explosion API
|
||||
* Music discs API
|
||||
* Flowers and flower pots
|
||||
|
||||
### 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!
|
||||
|
@ -79,12 +86,10 @@ The following APIs may be subject to change in future. You could already use the
|
|||
|
||||
### Planned APIs
|
||||
|
||||
* Flowers
|
||||
* Saplings and trees
|
||||
* Custom banner patterns
|
||||
* Custom dimensions
|
||||
* Custom portals
|
||||
* Music discs
|
||||
* Dispenser and dropper support
|
||||
* Proper sky and weather APIs
|
||||
* Explosion API
|
||||
|
||||
|
|
|
@ -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_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=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
|
||||
* `creative_breakable=1`: Block is breakable by hand in creative mode. This group is implied if the node belongs to any other digging group
|
||||
|
||||
|
|
|
@ -185,6 +185,11 @@ Please report all bugs and missing Minecraft features here:
|
|||
|
||||
<https://git.minetest.land/MineClone2/MineClone2/issues>
|
||||
|
||||
## Chating with the community
|
||||
Join our discord server at:
|
||||
|
||||
<https://discord.gg/84GKcxczG3>
|
||||
|
||||
## Other readme files
|
||||
|
||||
* `LICENSE.txt`: The GPLv3 license text
|
||||
|
|
|
@ -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!
|
||||
|
|
|
@ -32,4 +32,13 @@ mgvalleys_spflags = noaltitude_chill,noaltitude_dry,nohumid_rivers,vary_river_de
|
|||
# MCL2-specific stuff
|
||||
keepInventory = false
|
||||
|
||||
dedicated_server_step = 0.001
|
||||
# Performance settings
|
||||
# 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
|
||||
|
|
|
@ -4,6 +4,11 @@ Specifically, this mod has 2 purposes:
|
|||
1) Automatically adding the group “solid” for blocks considered “solid” in Minecraft.
|
||||
2) Generating digging time group for all nodes based on node metadata (it's complicated)
|
||||
|
||||
This mod also requires another mod called “mcl_autogroup” to function properly.
|
||||
“mcl_autogroup” exposes the API used to register digging groups, while this mod
|
||||
uses those digging groups to set the digging time groups for all the nodes and
|
||||
tools.
|
||||
|
||||
See init.lua for more infos.
|
||||
|
||||
The leading underscore in the name “_mcl_autogroup” was added to force Minetest to load this mod as late as possible.
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
MineClone 2 core mod which automatically adds groups to all items. Very important for digging times.
|
|
@ -1,170 +1,359 @@
|
|||
--[[ Mining times. Yeah, mining times … Alright, this is going to be FUN!
|
||||
--[[
|
||||
This mod implements a HACK to make 100% sure the digging times of all tools
|
||||
match Minecraft's perfectly. The digging times system of Minetest is very
|
||||
different, so this weird group trickery has to be used. In Minecraft, each
|
||||
block has a hardness and the actual Minecraft digging time is determined by
|
||||
this:
|
||||
|
||||
This mod does include a HACK to make 100% sure the digging times of all tools match Minecraft's perfectly.
|
||||
The digging times system of Minetest is very different, so this weird group trickery has to be used.
|
||||
In Minecraft, each block has a hardness and the actual Minecraft digging time is determined by this:
|
||||
1) The block's hardness
|
||||
2) The tool being used
|
||||
3) Whether the tool is considered as “eligible” for the block
|
||||
2) The tool being used (the tool speed and its efficiency level)
|
||||
3) Whether the tool is considered as "eligible" for the block
|
||||
(e.g. only diamond pick eligible for obsidian)
|
||||
See Minecraft Wiki <http://minecraft.gamepedia.com/Minecraft_Wiki> for more information.
|
||||
|
||||
In MineClone 2, all diggable node have the hardness set in the custom field “_mcl_hardness” (0 by default).
|
||||
The nodes are also required to specify the “eligible” tools in groups like “pickaxey”, “shovely”, etc.
|
||||
This mod then calculates the real digging time based on the node meta data. The real digging times
|
||||
are then added into mcl_autogroup.digtimes where the table indices are group rating and the values are the
|
||||
digging times in seconds. These digging times can be then added verbatim into the tool definitions.
|
||||
See Minecraft Wiki <http://minecraft.gamepedia.com/Minecraft_Wiki> for more
|
||||
information.
|
||||
|
||||
Example:
|
||||
mcl_autogroup.digtimes.pickaxey_dig_diamond[1] = 0.2
|
||||
How the mod is used
|
||||
===================
|
||||
|
||||
→ This means that when a node has been assigned the group “pickaxey_dig_diamond=1”, it can be dug by the
|
||||
diamond pickaxe in 0.2 seconds.
|
||||
In MineClone 2, all diggable nodes have the hardness set in the custom field
|
||||
"_mcl_hardness" (0 by default). These values are used together with digging
|
||||
groups by this mod to create the correct digging times for nodes. Digging
|
||||
groups are registered using the following code:
|
||||
|
||||
mcl_autogroup.register_diggroup("shovely")
|
||||
mcl_autogroup.register_diggroup("pickaxey", {
|
||||
levels = { "wood", "gold", "stone", "iron", "diamond" }
|
||||
})
|
||||
|
||||
The first line registers a simple digging group. The second line registers a
|
||||
digging group with 5 different levels (in this case one for each material of a
|
||||
pickaxes).
|
||||
|
||||
This strange setup with mcl_autogroup has been done to minimize the amount of required digging times
|
||||
a single tool needs to use. If this is not being done, the loading time will increase considerably
|
||||
(>10s).
|
||||
Nodes indicate that they belong to a particular digging group by being member of
|
||||
the digging group in their node definition. "mcl_core:dirt" for example has
|
||||
shovely=1 in its groups. If the digging group has multiple levels the value of
|
||||
the group indicates which digging level the node requires.
|
||||
"mcl_core:stone_with_gold" for example has pickaxey=4 because it requires a
|
||||
pickaxe of level 4 be mined.
|
||||
|
||||
]]
|
||||
For tools to be able to dig nodes of digging groups they need to use the have
|
||||
the custom field "_mcl_diggroups" function to get the groupcaps. The value of
|
||||
this field is a table which defines which groups the tool can dig and how
|
||||
efficiently.
|
||||
|
||||
local materials = { "wood", "gold", "stone", "iron", "diamond" }
|
||||
local basegroups = { "pickaxey", "axey", "shovely" }
|
||||
local minigroups = { "handy", "shearsy", "swordy", "shearsy_wool", "swordy_cobweb" }
|
||||
local divisors = {
|
||||
["wood"] = 2,
|
||||
["gold"] = 12,
|
||||
["stone"] = 4,
|
||||
["iron"] = 6,
|
||||
["diamond"] = 8,
|
||||
["handy"] = 1,
|
||||
["shearsy"] = 15,
|
||||
["swordy"] = 1.5,
|
||||
["shearsy_wool"] = 5,
|
||||
["swordy_cobweb"] = 15,
|
||||
}
|
||||
local max_efficiency_level = 5
|
||||
_mcl_diggroups = {
|
||||
handy = { speed = 1, level = 1, uses = 0 },
|
||||
pickaxey = { speed = 1, level = 0, uses = 0 },
|
||||
}
|
||||
|
||||
mcl_autogroup = {}
|
||||
mcl_autogroup.digtimes = {}
|
||||
mcl_autogroup.creativetimes = {} -- Copy of digtimes, except that all values are 0. Used for creative mode
|
||||
The "uses" field indicate how many uses (0 for infinite) a tool has when used on
|
||||
the specified digging group. The "speed" field is a multiplier to the dig speed
|
||||
on that digging group.
|
||||
|
||||
for m=1, #materials do
|
||||
for g=1, #basegroups do
|
||||
mcl_autogroup.digtimes[basegroups[g].."_dig_"..materials[m]] = {}
|
||||
mcl_autogroup.creativetimes[basegroups[g].."_dig_"..materials[m]] = {}
|
||||
for e=1, max_efficiency_level do
|
||||
mcl_autogroup.digtimes[basegroups[g].."_dig_"..materials[m].."_efficiency_"..e] = {}
|
||||
The "level" field indicates which levels of the group the tool can harvest. A
|
||||
level of 0 means that the tool cannot harvest blocks of that node. A level of 1
|
||||
or above means that the tool can harvest nodes with that level or below. See
|
||||
"mcl_tools/init.lua" for examples on how "_mcl_diggroups" is used in practice.
|
||||
|
||||
Information about the mod
|
||||
=========================
|
||||
|
||||
The mod is split up into two parts, mcl_autogroup and _mcl_autogroup.
|
||||
mcl_autogroup contains the API functions used to register custom digging groups.
|
||||
_mcl_autogroup contains most of the code. The leading underscore in the name
|
||||
"_mcl_autogroup" is used to force Minetest to load that part of the mod as late
|
||||
as possible. Minetest loads mods in reverse alphabetical order.
|
||||
|
||||
This also means that it is very important that no mod adds _mcl_autogroup as a
|
||||
dependency.
|
||||
--]]
|
||||
|
||||
assert(minetest.get_modpath("mcl_autogroup"), "This mod requires the mod mcl_autogroup to function")
|
||||
|
||||
-- Returns a table containing the unique "_mcl_hardness" for nodes belonging to
|
||||
-- each diggroup.
|
||||
local function get_hardness_values_for_groups()
|
||||
local maps = {}
|
||||
local values = {}
|
||||
for g, _ in pairs(mcl_autogroup.registered_diggroups) do
|
||||
maps[g] = {}
|
||||
values[g] = {}
|
||||
end
|
||||
|
||||
for _, ndef in pairs(minetest.registered_nodes) do
|
||||
for g, _ in pairs(mcl_autogroup.registered_diggroups) do
|
||||
if ndef.groups[g] ~= nil then
|
||||
maps[g][ndef._mcl_hardness or 0] = true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for g, map in pairs(maps) do
|
||||
for k, _ in pairs(map) do
|
||||
table.insert(values[g], k)
|
||||
end
|
||||
end
|
||||
|
||||
for g, _ in pairs(mcl_autogroup.registered_diggroups) do
|
||||
table.sort(values[g])
|
||||
end
|
||||
return values
|
||||
end
|
||||
for g=1, #minigroups do
|
||||
mcl_autogroup.digtimes[minigroups[g].."_dig"] = {}
|
||||
mcl_autogroup.creativetimes[minigroups[g].."_dig"] = {}
|
||||
for e=1, max_efficiency_level do
|
||||
mcl_autogroup.digtimes[minigroups[g].."_dig_efficiency_"..e] = {}
|
||||
mcl_autogroup.creativetimes[minigroups[g].."_dig_efficiency_"..e] = {}
|
||||
|
||||
-- Returns a table containing a table indexed by "_mcl_hardness_value" to get
|
||||
-- its index in the list of unique hardnesses for each diggroup.
|
||||
local function get_hardness_lookup_for_groups(hardness_values)
|
||||
local map = {}
|
||||
for g, values in pairs(hardness_values) do
|
||||
map[g] = {}
|
||||
for k, v in pairs(values) do
|
||||
map[g][v] = k
|
||||
end
|
||||
end
|
||||
return map
|
||||
end
|
||||
|
||||
-- Array of unique hardness values for each group which affects dig time.
|
||||
local hardness_values = get_hardness_values_for_groups()
|
||||
|
||||
-- Map indexed by hardness values which return the index of that value in
|
||||
-- hardness_value. Used for quick lookup.
|
||||
local hardness_lookup = get_hardness_lookup_for_groups(hardness_values)
|
||||
|
||||
local function compute_creativetimes(group)
|
||||
local creativetimes = {}
|
||||
|
||||
for index, hardness in pairs(hardness_values[group]) do
|
||||
table.insert(creativetimes, 0)
|
||||
end
|
||||
|
||||
return creativetimes
|
||||
end
|
||||
|
||||
-- Get the list of digging times for using a specific tool on a specific
|
||||
-- diggroup.
|
||||
--
|
||||
-- Parameters:
|
||||
-- group - the group which it is digging
|
||||
-- can_harvest - if the tool can harvest the block
|
||||
-- speed - dig speed multiplier for tool (default 1)
|
||||
-- efficiency - efficiency level for the tool if applicable
|
||||
local function get_digtimes(group, can_harvest, speed, efficiency)
|
||||
local speed = speed or 1
|
||||
if efficiency then
|
||||
speed = speed + efficiency * efficiency + 1
|
||||
end
|
||||
|
||||
local digtimes = {}
|
||||
|
||||
for index, hardness in pairs(hardness_values[group]) do
|
||||
local digtime = (hardness or 0) / speed
|
||||
if can_harvest then
|
||||
digtime = digtime * 1.5
|
||||
else
|
||||
digtime = digtime * 5
|
||||
end
|
||||
|
||||
if digtime <= 0.05 then
|
||||
digtime = 0
|
||||
else
|
||||
digtime = math.ceil(digtime * 20) / 20
|
||||
end
|
||||
table.insert(digtimes, digtime)
|
||||
end
|
||||
|
||||
return digtimes
|
||||
end
|
||||
|
||||
-- Get one groupcap field for using a specific tool on a specific group.
|
||||
local function get_groupcap(group, can_harvest, multiplier, efficiency, uses)
|
||||
return {
|
||||
times = get_digtimes(group, can_harvest, multiplier, efficiency),
|
||||
uses = uses,
|
||||
maxlevel = 0,
|
||||
}
|
||||
end
|
||||
|
||||
-- Add the groupcaps from a field in "_mcl_diggroups" to the groupcaps of a
|
||||
-- tool.
|
||||
local function add_groupcaps(toolname, groupcaps, groupcaps_def, efficiency)
|
||||
for g, capsdef in pairs(groupcaps_def) do
|
||||
local mult = capsdef.speed or 1
|
||||
local uses = capsdef.uses
|
||||
local def = mcl_autogroup.registered_diggroups[g]
|
||||
local max_level = def.levels and #def.levels or 1
|
||||
|
||||
assert(capsdef.level, toolname .. ' is missing level for ' .. g)
|
||||
local level = math.min(capsdef.level, max_level)
|
||||
|
||||
if def.levels then
|
||||
groupcaps[g .. "_dig_default"] = get_groupcap(g, false, mult, efficiency, uses)
|
||||
if level > 0 then
|
||||
groupcaps[g .. "_dig_" .. def.levels[level]] = get_groupcap(g, true, mult, efficiency, uses)
|
||||
end
|
||||
else
|
||||
groupcaps[g .. "_dig"] = get_groupcap(g, level > 0, mult, efficiency, uses)
|
||||
end
|
||||
end
|
||||
return groupcaps
|
||||
end
|
||||
|
||||
-- Checks if the given node would drop its useful drop if dug by a given tool.
|
||||
-- Returns true if it will yield its useful drop, false otherwise.
|
||||
function mcl_autogroup.can_harvest(nodename, toolname)
|
||||
local ndef = minetest.registered_nodes[nodename]
|
||||
|
||||
if minetest.get_item_group(nodename, "dig_immediate") >= 2 then
|
||||
return true
|
||||
end
|
||||
|
||||
-- Check if it can be dug by tool
|
||||
local tdef = minetest.registered_tools[toolname]
|
||||
if tdef and tdef._mcl_diggroups then
|
||||
for g, gdef in pairs(tdef._mcl_diggroups) do
|
||||
if ndef.groups[g] then
|
||||
if ndef.groups[g] <= gdef.level then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if it can be dug by hand
|
||||
local tdef = minetest.registered_tools[""]
|
||||
if tdef then
|
||||
for g, gdef in pairs(tdef._mcl_diggroups) do
|
||||
if ndef.groups[g] then
|
||||
if ndef.groups[g] <= gdef.level then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- Get one groupcap field for using a specific tool on a specific group.
|
||||
local function get_groupcap(group, can_harvest, multiplier, efficiency, uses)
|
||||
return {
|
||||
times = get_digtimes(group, can_harvest, multiplier, efficiency),
|
||||
uses = uses,
|
||||
maxlevel = 0,
|
||||
}
|
||||
end
|
||||
|
||||
-- Returns the tool_capabilities from a tool definition or a default set of
|
||||
-- tool_capabilities
|
||||
local function get_tool_capabilities(tdef)
|
||||
if tdef.tool_capabilities then
|
||||
return tdef.tool_capabilities
|
||||
end
|
||||
|
||||
-- If the damage group and punch interval from hand is not included,
|
||||
-- then the user will not be able to attack with the tool.
|
||||
local hand_toolcaps = minetest.registered_tools[""].tool_capabilities
|
||||
return {
|
||||
full_punch_interval = hand_toolcaps.full_punch_interval,
|
||||
damage_groups = hand_toolcaps.damage_groups
|
||||
}
|
||||
end
|
||||
|
||||
-- Get the groupcaps for a tool. This function returns "groupcaps" table of
|
||||
-- digging which should be put in the "tool_capabilities" of the tool definition
|
||||
-- or in the metadata of an enchanted tool.
|
||||
--
|
||||
-- Parameters:
|
||||
-- toolname - Name of the tool being enchanted (like "mcl_tools:diamond_pickaxe")
|
||||
-- efficiency - The efficiency level the tool is enchanted with (default 0)
|
||||
--
|
||||
-- NOTE:
|
||||
-- This function can only be called after mod initialization. Otherwise a mod
|
||||
-- would have to add _mcl_autogroup as a dependency which would break the mod
|
||||
-- loading order.
|
||||
function mcl_autogroup.get_groupcaps(toolname, efficiency)
|
||||
local tdef = minetest.registered_tools[toolname]
|
||||
local groupcaps = table.copy(get_tool_capabilities(tdef).groupcaps or {})
|
||||
add_groupcaps(toolname, groupcaps, tdef._mcl_diggroups, efficiency)
|
||||
return groupcaps
|
||||
end
|
||||
|
||||
-- Get the wear from using a tool on a digging group.
|
||||
--
|
||||
-- Parameters
|
||||
-- toolname - Name of the tool used
|
||||
-- diggroup - The name of the diggroup the tool is used on
|
||||
--
|
||||
-- NOTE:
|
||||
-- This function can only be called after mod initialization. Otherwise a mod
|
||||
-- would have to add _mcl_autogroup as a dependency which would break the mod
|
||||
-- loading order.
|
||||
function mcl_autogroup.get_wear(toolname, diggroup)
|
||||
local tdef = minetest.registered_tools[toolname]
|
||||
local uses = tdef._mcl_diggroups[diggroup].uses
|
||||
return math.ceil(65535 / uses)
|
||||
end
|
||||
|
||||
local overwrite = function()
|
||||
for nname, ndef in pairs(minetest.registered_nodes) do
|
||||
local groups_changed = false
|
||||
local newgroups = table.copy(ndef.groups)
|
||||
if (nname ~= "ignore" and ndef.diggable) then
|
||||
-- Automatically assign the “solid” group for solid nodes
|
||||
-- Automatically assign the "solid" group for solid nodes
|
||||
if (ndef.walkable == nil or ndef.walkable == true)
|
||||
and (ndef.collision_box == nil or ndef.collision_box.type == "regular")
|
||||
and (ndef.node_box == nil or ndef.node_box.type == "regular")
|
||||
and (ndef.groups.not_solid == 0 or ndef.groups.not_solid == nil) then
|
||||
newgroups.solid = 1
|
||||
groups_changed = true
|
||||
end
|
||||
-- Automatically assign the “opaque” group for opaque nodes
|
||||
-- Automatically assign the "opaque" group for opaque nodes
|
||||
if (not (ndef.paramtype == "light" or ndef.sunlight_propagates)) and
|
||||
(ndef.groups.not_opaque == 0 or ndef.groups.not_opaque == nil) then
|
||||
newgroups.opaque = 1
|
||||
groups_changed = true
|
||||
end
|
||||
|
||||
local function calculate_group(hardness, material, diggroup, newgroups, actual_rating, expected_rating, efficiency)
|
||||
local time, validity_factor
|
||||
if actual_rating >= expected_rating then
|
||||
-- Valid tool
|
||||
validity_factor = 1.5
|
||||
local creative_breakable = false
|
||||
|
||||
-- Assign groups used for digging this node depending on
|
||||
-- the registered digging groups
|
||||
for g, gdef in pairs(mcl_autogroup.registered_diggroups) do
|
||||
creative_breakable = true
|
||||
local index = hardness_lookup[g][ndef._mcl_hardness or 0]
|
||||
if ndef.groups[g] then
|
||||
if gdef.levels then
|
||||
newgroups[g .. "_dig_default"] = index
|
||||
|
||||
for i = ndef.groups[g], #gdef.levels do
|
||||
newgroups[g .. "_dig_" .. gdef.levels[i]] = index
|
||||
end
|
||||
else
|
||||
-- Wrong tool (higher digging time)
|
||||
validity_factor = 5
|
||||
end
|
||||
local speed_multiplier = divisors[material]
|
||||
if efficiency then
|
||||
speed_multiplier = speed_multiplier + efficiency * efficiency + 1
|
||||
end
|
||||
time = (hardness * validity_factor) / speed_multiplier
|
||||
if time <= 0.05 then
|
||||
time = 0
|
||||
else
|
||||
time = math.ceil(time * 20) / 20
|
||||
end
|
||||
table.insert(mcl_autogroup.digtimes[diggroup], time)
|
||||
if not efficiency then
|
||||
table.insert(mcl_autogroup.creativetimes[diggroup], 0)
|
||||
end
|
||||
newgroups[diggroup] = #mcl_autogroup.digtimes[diggroup]
|
||||
return newgroups
|
||||
end
|
||||
|
||||
-- Hack in digging times
|
||||
local hardness = ndef._mcl_hardness
|
||||
if not hardness then
|
||||
hardness = 0
|
||||
end
|
||||
|
||||
-- Handle pickaxey, axey and shovely
|
||||
for _, basegroup in pairs(basegroups) do
|
||||
if (hardness ~= -1 and ndef.groups[basegroup]) then
|
||||
for g=1,#materials do
|
||||
local diggroup = basegroup.."_dig_"..materials[g]
|
||||
newgroups = calculate_group(hardness, materials[g], diggroup, newgroups, g, ndef.groups[basegroup])
|
||||
for e=1,max_efficiency_level do
|
||||
newgroups = calculate_group(hardness, materials[g], diggroup .. "_efficiency_" .. e, newgroups, g, ndef.groups[basegroup], e)
|
||||
end
|
||||
groups_changed = true
|
||||
end
|
||||
end
|
||||
end
|
||||
for m=1, #minigroups do
|
||||
local minigroup = minigroups[m]
|
||||
if hardness ~= -1 then
|
||||
local diggroup = minigroup.."_dig"
|
||||
-- actual rating
|
||||
local ar = ndef.groups[minigroup]
|
||||
if ar == nil then
|
||||
ar = 0
|
||||
end
|
||||
if (minigroup == "handy")
|
||||
or
|
||||
(ndef.groups.shearsy_wool and minigroup == "shearsy_wool" and ndef.groups.wool)
|
||||
or
|
||||
(ndef.groups.swordy_cobweb and minigroup == "swordy_cobweb" and nname == "mcl_core:cobweb")
|
||||
or
|
||||
(ndef.groups[minigroup] and minigroup ~= "swordy_cobweb" and minigroup ~= "shearsy_wool") then
|
||||
newgroups = calculate_group(hardness, minigroup, diggroup, newgroups, ar, 1)
|
||||
for e=1,max_efficiency_level do
|
||||
newgroups = calculate_group(hardness, minigroup, diggroup .. "_efficiency_" .. e, newgroups, ar, 1, e)
|
||||
end
|
||||
groups_changed = true
|
||||
newgroups[g .. "_dig"] = index
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if groups_changed then
|
||||
-- Automatically assign the node to the
|
||||
-- creative_breakable group if it belongs to any digging
|
||||
-- group.
|
||||
newgroups["creative_breakable"] = 1
|
||||
|
||||
minetest.override_item(nname, {
|
||||
groups = newgroups
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
for tname, tdef in pairs(minetest.registered_tools) do
|
||||
-- Assign groupcaps for digging the registered digging groups
|
||||
-- depending on the _mcl_diggroups in the tool definition
|
||||
if tdef._mcl_diggroups then
|
||||
local toolcaps = table.copy(get_tool_capabilities(tdef))
|
||||
toolcaps.groupcaps = mcl_autogroup.get_groupcaps(tname)
|
||||
|
||||
minetest.override_item(tname, {
|
||||
tool_capabilities = toolcaps
|
||||
})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
name = _mcl_autogroup
|
||||
author = ryvnf
|
||||
description = MineClone 2 core mod which automatically adds groups to all items. Very important for digging times.
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
name = biomeinfo
|
||||
author = Wuzzy
|
||||
description = Simple API to get data about biomes.
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
local get_connected_players = minetest.get_connected_players
|
||||
local clock = os.clock
|
||||
|
||||
controls = {}
|
||||
controls.players = {}
|
||||
|
||||
|
@ -42,7 +45,7 @@ minetest.register_on_leaveplayer(function(player)
|
|||
end)
|
||||
|
||||
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_controls = player:get_player_control()
|
||||
if controls.players[player_name] then
|
||||
|
@ -53,15 +56,15 @@ minetest.register_globalstep(function(dtime)
|
|||
for _, func in pairs(controls.registered_on_press) do
|
||||
func(player, cname)
|
||||
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
|
||||
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
|
||||
--Release a key
|
||||
elseif cbool==false and controls.players[player_name][cname][1]==true then
|
||||
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
|
||||
controls.players[player_name][cname] = {false}
|
||||
end
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
name=controls
|
||||
name = controls
|
||||
author = Arcelmi
|
||||
description = Controls framework by Arcelmi
|
||||
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
name = flowlib
|
||||
author = Qwertymine3
|
||||
description = Simple flow functions for use in Minetest mods by Qwertymine3
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Adds additional ways for nodes to be attached.
|
|
@ -0,0 +1,3 @@
|
|||
name = mcl_attached
|
||||
author = Wuzzy
|
||||
description = Adds additional ways for nodes to be attached.
|
|
@ -0,0 +1,28 @@
|
|||
--[[
|
||||
This is one part of a mod to replicate the digging times from Minecraft. This
|
||||
part only exposes a function to register digging groups. The rest of the mod is
|
||||
implemented and documented in the _mcl_autogroup.
|
||||
|
||||
The mod is split up into two parts, mcl_autogroup and _mcl_autogroup.
|
||||
mcl_autogroup contains the API functions used to register custom digging groups.
|
||||
_mcl_autogroup contains most of the code. The leading underscore in the name
|
||||
"_mcl_autogroup" is used to force Minetest to load that part of the mod as late
|
||||
as possible. Minetest loads mods in reverse alphabetical order.
|
||||
--]]
|
||||
mcl_autogroup = {}
|
||||
mcl_autogroup.registered_diggroups = {}
|
||||
|
||||
assert(minetest.get_modpath("_mcl_autogroup"), "This mod requires the mod _mcl_autogroup to function")
|
||||
|
||||
-- Register a group as a digging group.
|
||||
--
|
||||
-- Parameters:
|
||||
-- group - Name of the group to register as a digging group
|
||||
-- def - Table with information about the diggroup (defaults to {} if unspecified)
|
||||
--
|
||||
-- Values in def:
|
||||
-- level - If specified it is an array containing the names of the different
|
||||
-- digging levels the digging group supports.
|
||||
function mcl_autogroup.register_diggroup(group, def)
|
||||
mcl_autogroup.registered_diggroups[group] = def or {}
|
||||
end
|
|
@ -0,0 +1,3 @@
|
|||
name = mcl_autogroup
|
||||
author = ryvnf
|
||||
description = MineClone 2 core mod which automatically adds groups to all items. Very important for digging times.
|
|
@ -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",
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
name = mcl_colors
|
||||
author = Fleckenstein
|
||||
description = The HTML sequences for the minecraft colors
|
|
@ -18,6 +18,16 @@ local CONTENT_FIRE = minetest.get_content_id("mcl_fire:fire")
|
|||
|
||||
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
|
||||
local sphere_shapes = {}
|
||||
|
||||
|
@ -64,7 +74,7 @@ local function compute_sphere_rays(radius)
|
|||
local d = x * x + y * y + z * z
|
||||
if d <= radius * radius then
|
||||
local pos = { x = x, y = y, z = z }
|
||||
sphere[minetest.hash_node_position(pos)] = pos
|
||||
sphere[hash_node_position(pos)] = pos
|
||||
break
|
||||
end
|
||||
end
|
||||
|
@ -79,7 +89,7 @@ local function compute_sphere_rays(radius)
|
|||
local d = x * x + y * y + z * z
|
||||
if d <= radius * radius then
|
||||
local pos = { x = x, y = y, z = z }
|
||||
sphere[minetest.hash_node_position(pos)] = pos
|
||||
sphere[hash_node_position(pos)] = pos
|
||||
break
|
||||
end
|
||||
end
|
||||
|
@ -94,7 +104,7 @@ local function compute_sphere_rays(radius)
|
|||
local d = x * x + y * y + z * z
|
||||
if d <= radius * radius then
|
||||
local pos = { x = x, y = y, z = z }
|
||||
sphere[minetest.hash_node_position(pos)] = pos
|
||||
sphere[hash_node_position(pos)] = pos
|
||||
break
|
||||
end
|
||||
end
|
||||
|
@ -156,7 +166,7 @@ end
|
|||
-- inlined to avoid function calls and unnecessary table creation. This was
|
||||
-- measured to give a significant performance increase.
|
||||
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),
|
||||
vector.add(pos, radius))
|
||||
|
@ -207,7 +217,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
|
|||
br = max_blast_resistance
|
||||
end
|
||||
|
||||
local hash = minetest.hash_node_position(npos)
|
||||
local hash = hash_node_position(npos)
|
||||
|
||||
rpos_x = rpos_x + STEP_LENGTH * rdir_x
|
||||
rpos_y = rpos_y + STEP_LENGTH * rdir_y
|
||||
|
@ -230,7 +240,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
|
|||
|
||||
-- Entities in radius of explosion
|
||||
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
|
||||
for _, obj in pairs(objs) do
|
||||
|
@ -335,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
|
||||
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: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))
|
||||
else
|
||||
obj:punch(source, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir)
|
||||
|
||||
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
|
||||
obj:add_velocity(vector.multiply(punch_dir, impact * 20))
|
||||
end
|
||||
|
@ -359,46 +369,46 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
|
|||
local remove = true
|
||||
|
||||
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
|
||||
on_blast(npos, 1.0, do_drop)
|
||||
remove = false
|
||||
else
|
||||
local name = minetest.get_name_from_content_id(data[idx])
|
||||
local drop = minetest.get_node_drops(name, "")
|
||||
local name = get_name_from_content_id(data[idx])
|
||||
local drop = get_node_drops(name, "")
|
||||
|
||||
for _, item in ipairs(drop) do
|
||||
if type(item) ~= "string" then
|
||||
item = item:get_name() .. item:get_count()
|
||||
end
|
||||
minetest.add_item(npos, item)
|
||||
add_item(npos, item)
|
||||
end
|
||||
end
|
||||
end
|
||||
if remove 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
|
||||
table.insert(airs, minetest.get_position_from_hash(hash))
|
||||
table.insert(airs, get_position_from_hash(hash))
|
||||
end
|
||||
end
|
||||
end
|
||||
-- We use bulk_set_node instead of LVM because we want to have on_destruct and
|
||||
-- on_construct being called
|
||||
if #airs > 0 then
|
||||
minetest.bulk_set_node(airs, {name="air"})
|
||||
bulk_set_node(airs, {name="air"})
|
||||
end
|
||||
if #fires > 0 then
|
||||
minetest.bulk_set_node(fires, {name="mcl_fire:fire"})
|
||||
bulk_set_node(fires, {name="mcl_fire:fire"})
|
||||
end
|
||||
-- Update falling nodes
|
||||
for a=1, #airs do
|
||||
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
|
||||
for f=1, #fires do
|
||||
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
|
||||
|
||||
-- Log explosion
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
name = mcl_explosions
|
||||
author = ryvnf
|
||||
description = A common API to create explosions.
|
||||
depends = mcl_particles
|
||||
optional_depends = mcl_fire
|
||||
|
|
|
@ -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.
|
|
@ -33,25 +33,26 @@ mcl_vars.MAP_BLOCKSIZE = math.max(1, core.MAP_BLOCKSIZE or 16)
|
|||
mcl_vars.mapgen_limit = math.max(1, tonumber(minetest.get_mapgen_setting("mapgen_limit")) or 31000)
|
||||
mcl_vars.MAX_MAP_GENERATION_LIMIT = math.max(1, core.MAX_MAP_GENERATION_LIMIT or 31000)
|
||||
local central_chunk_offset = -math.floor(mcl_vars.chunksize / 2)
|
||||
local chunk_size_in_nodes = mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE
|
||||
mcl_vars.central_chunk_offset_in_nodes = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE
|
||||
mcl_vars.chunk_size_in_nodes = mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE
|
||||
local central_chunk_min_pos = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE
|
||||
local central_chunk_max_pos = central_chunk_min_pos + chunk_size_in_nodes - 1
|
||||
local central_chunk_max_pos = central_chunk_min_pos + mcl_vars.chunk_size_in_nodes - 1
|
||||
local ccfmin = central_chunk_min_pos - mcl_vars.MAP_BLOCKSIZE -- Fullminp/fullmaxp of central chunk, in nodes
|
||||
local ccfmax = central_chunk_max_pos + mcl_vars.MAP_BLOCKSIZE
|
||||
local mapgen_limit_b = math.floor(math.min(mcl_vars.mapgen_limit, mcl_vars.MAX_MAP_GENERATION_LIMIT) / mcl_vars.MAP_BLOCKSIZE)
|
||||
local mapgen_limit_min = -mapgen_limit_b * mcl_vars.MAP_BLOCKSIZE
|
||||
local mapgen_limit_max = (mapgen_limit_b + 1) * mcl_vars.MAP_BLOCKSIZE - 1
|
||||
local numcmin = math.max(math.floor((ccfmin - mapgen_limit_min) / chunk_size_in_nodes), 0) -- Number of complete chunks from central chunk
|
||||
local numcmax = math.max(math.floor((mapgen_limit_max - ccfmax) / chunk_size_in_nodes), 0) -- fullminp/fullmaxp to effective mapgen limits.
|
||||
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
|
||||
local numcmin = math.max(math.floor((ccfmin - mapgen_limit_min) / mcl_vars.chunk_size_in_nodes), 0) -- Number of complete chunks from central chunk
|
||||
local numcmax = math.max(math.floor((mapgen_limit_max - ccfmax) / mcl_vars.chunk_size_in_nodes), 0) -- fullminp/fullmaxp to effective mapgen limits.
|
||||
mcl_vars.mapgen_edge_min = central_chunk_min_pos - numcmin * mcl_vars.chunk_size_in_nodes
|
||||
mcl_vars.mapgen_edge_max = central_chunk_max_pos + numcmax * mcl_vars.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)
|
||||
return math.floor((coordinate_to_block(x) - central_chunk_offset) / mcl_vars.chunksize)
|
||||
end
|
||||
|
||||
function mcl_vars.pos_to_block(pos)
|
||||
|
@ -70,7 +71,7 @@ function mcl_vars.pos_to_chunk(pos)
|
|||
}
|
||||
end
|
||||
|
||||
local k_positive = math.ceil(mcl_vars.MAX_MAP_GENERATION_LIMIT / chunk_size_in_nodes)
|
||||
local k_positive = math.ceil(mcl_vars.MAX_MAP_GENERATION_LIMIT / mcl_vars.chunk_size_in_nodes)
|
||||
local k_positive_z = k_positive * 2
|
||||
local k_positive_y = k_positive_z * k_positive_z
|
||||
|
||||
|
|
|
@ -1 +1,3 @@
|
|||
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.
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
API for filling a chest with random treasures.
|
|
@ -1 +1,3 @@
|
|||
name = mcl_loot
|
||||
author = Wuzzy
|
||||
description = API for filling a chest with random treasures.
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Contains particle images of MineClone 2. No code.
|
|
@ -1 +1,3 @@
|
|||
name = mcl_particles
|
||||
author = Wuzzy
|
||||
description = Contains particle images of MineClone 2. No code.
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
This mod contains the core sounds of MineClone 2 as well as helper function for mods to access them.
|
|
@ -1 +1,3 @@
|
|||
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.
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
mcl_init
|
|
@ -1 +0,0 @@
|
|||
Helper functions for MineClone 2.
|
|
@ -405,3 +405,16 @@ function mcl_util.get_object_center(obj)
|
|||
pos.y = pos.y + (ymax - ymin) / 2.0
|
||||
return pos
|
||||
end
|
||||
|
||||
function mcl_util.get_color(colorstr)
|
||||
local mc_color = mcl_colors[colorstr:upper()]
|
||||
if mc_color then
|
||||
colorstr = mc_color
|
||||
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
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
name = mcl_util
|
||||
author = Wuzzy
|
||||
description = Helper functions for MineClone 2.
|
||||
depends = mcl_init
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
mcl_init
|
|
@ -1 +0,0 @@
|
|||
Utility functions for worlds and the “dimensions”.
|
|
@ -6,7 +6,7 @@ mcl_worlds = {}
|
|||
function mcl_worlds.is_in_void(pos)
|
||||
local void =
|
||||
not ((pos.y < mcl_vars.mg_overworld_max and pos.y > mcl_vars.mg_overworld_min) or
|
||||
(pos.y < mcl_vars.mg_nether_max and pos.y > mcl_vars.mg_nether_min) or
|
||||
(pos.y < mcl_vars.mg_nether_max+128 and pos.y > mcl_vars.mg_nether_min) or
|
||||
(pos.y < mcl_vars.mg_end_max and pos.y > mcl_vars.mg_end_min))
|
||||
|
||||
local void_deadly = false
|
||||
|
@ -15,11 +15,11 @@ function mcl_worlds.is_in_void(pos)
|
|||
-- Overworld → Void → End → Void → Nether → Void
|
||||
if pos.y < mcl_vars.mg_overworld_min and pos.y > mcl_vars.mg_end_max then
|
||||
void_deadly = pos.y < mcl_vars.mg_overworld_min - deadly_tolerance
|
||||
elseif pos.y < mcl_vars.mg_end_min and pos.y > mcl_vars.mg_nether_max then
|
||||
elseif pos.y < mcl_vars.mg_end_min and pos.y > mcl_vars.mg_nether_max+128 then
|
||||
-- The void between End and Nether. Like usual, but here, the void
|
||||
-- *above* the Nether also has a small tolerance area, so player
|
||||
-- can fly above the Nether without getting hurt instantly.
|
||||
void_deadly = (pos.y < mcl_vars.mg_end_min - deadly_tolerance) and (pos.y > mcl_vars.mg_nether_max + deadly_tolerance)
|
||||
void_deadly = (pos.y < mcl_vars.mg_end_min - deadly_tolerance) and (pos.y > mcl_vars.mg_nether_max+128 + deadly_tolerance)
|
||||
elseif pos.y < mcl_vars.mg_nether_min then
|
||||
void_deadly = pos.y < mcl_vars.mg_nether_min - deadly_tolerance
|
||||
end
|
||||
|
@ -35,7 +35,7 @@ end
|
|||
function mcl_worlds.y_to_layer(y)
|
||||
if y >= mcl_vars.mg_overworld_min then
|
||||
return y - mcl_vars.mg_overworld_min, "overworld"
|
||||
elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max then
|
||||
elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max+128 then
|
||||
return y - mcl_vars.mg_nether_min, "nether"
|
||||
elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then
|
||||
return y - mcl_vars.mg_end_min, "end"
|
||||
|
@ -73,7 +73,7 @@ end
|
|||
-- Takes a position and returns true if this position can have Nether dust
|
||||
function mcl_worlds.has_dust(pos)
|
||||
-- Weather in the Overworld and the high part of the void below
|
||||
return pos.y <= mcl_vars.mg_nether_max + 64 and pos.y >= mcl_vars.mg_nether_min - 64
|
||||
return pos.y <= mcl_vars.mg_nether_max + 138 and pos.y >= mcl_vars.mg_nether_min - 10
|
||||
end
|
||||
|
||||
-- Takes a position (pos) and returns true if compasses are working here
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
name = mcl_worlds
|
||||
author = Wuzzy
|
||||
description = Utility functions for worlds and the “dimensions”.
|
||||
depends = mcl_init
|
||||
|
|
@ -1,4 +1,10 @@
|
|||
-- 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.registered_globals = {}
|
||||
|
||||
|
@ -6,25 +12,38 @@ function walkover.register_global(func)
|
|||
table.insert(walkover.registered_globals, func)
|
||||
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
|
||||
minetest.register_globalstep(function(dtime)
|
||||
timer = timer + dtime;
|
||||
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()
|
||||
pp.y = math.ceil(pp.y)
|
||||
local loc = vector.add(pp, {x=0,y=-1,z=0})
|
||||
pp.y = ceil(pp.y)
|
||||
local loc = vector_add(pp, {x=0,y=-1,z=0})
|
||||
if loc ~= nil then
|
||||
|
||||
local nodeiamon = minetest.get_node(loc)
|
||||
local nodeiamon = get_node(loc)
|
||||
|
||||
if nodeiamon ~= nil then
|
||||
local def = minetest.registered_nodes[nodeiamon.name]
|
||||
if def ~= nil and def.on_walk_over ~= nil then
|
||||
def.on_walk_over(loc, nodeiamon, player)
|
||||
if on_walk[nodeiamon.name] then
|
||||
on_walk[nodeiamon.name](loc, nodeiamon, player)
|
||||
end
|
||||
for _, func in ipairs(walkover.registered_globals) do
|
||||
func(loc, nodeiamon, player)
|
||||
for i = 1, #registered_globals do
|
||||
registered_globals[i](loc, nodeiamon, player)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -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.
|
||||
|
|
@ -1 +0,0 @@
|
|||
mcl_core
|
|
@ -0,0 +1,4 @@
|
|||
name = drippingwater
|
||||
author = kddekadenz
|
||||
description = Drops are generated rarely under solid nodes
|
||||
depends = mcl_core
|
|
@ -20,4 +20,4 @@ Authors include:
|
|||
* Various Minetest / Minetest Game developers and contributors (2012-2016)
|
||||
* maikerumine (2017)
|
||||
* Wuzzy (2017)
|
||||
|
||||
* Fleckenstein (2020-2021)
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
mcl_player
|
||||
mcl_core?
|
||||
doc_identifier?
|
|
@ -1 +0,0 @@
|
|||
Adds drivable boats.
|
|
@ -163,6 +163,8 @@ function boat.get_staticdata(self)
|
|||
end
|
||||
|
||||
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
|
||||
local inv = killer:get_inventory()
|
||||
if not inv:contains_item("main", self._itemstring) then
|
||||
|
@ -188,6 +190,8 @@ function boat.on_punch(self, puncher, time_from_last_punch, tool_capabilities, d
|
|||
end
|
||||
|
||||
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)
|
||||
local v_factor = 1
|
||||
local v_slowdown = 0.02
|
||||
|
@ -223,7 +227,7 @@ function boat.on_step(self, dtime, moveresult)
|
|||
self._regen_timer = regen_timer
|
||||
|
||||
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
|
||||
if collision.type == "node" and minetest.get_item_group(minetest.get_node(pos).name, "dig_by_boat") > 0 then
|
||||
minetest.dig_node(pos)
|
||||
|
@ -305,7 +309,7 @@ function boat.on_step(self, dtime, moveresult)
|
|||
self._animation = 0
|
||||
end
|
||||
|
||||
for _, obj in ipairs(minetest.get_objects_inside_radius(self.object:get_pos(), 1.3)) do
|
||||
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)
|
||||
|
|
|
@ -1 +1,7 @@
|
|||
name = mcl_boats
|
||||
author = PilzAdam
|
||||
description = Adds drivable boats.
|
||||
depends = mcl_player
|
||||
optional_depends = mcl_core, doc_identifier
|
||||
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ function mcl_burning.is_burning(obj)
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
function mcl_burning.get_collisionbox(obj, smaller)
|
||||
|
@ -117,6 +117,10 @@ function mcl_burning.damage(obj)
|
|||
end
|
||||
|
||||
function mcl_burning.set_on_fire(obj, burn_time, reason)
|
||||
if obj:get_hp() < 0 then
|
||||
return
|
||||
end
|
||||
|
||||
local luaentity = obj:get_luaentity()
|
||||
if luaentity and luaentity.fire_resistant then
|
||||
return
|
||||
|
@ -145,7 +149,7 @@ function mcl_burning.set_on_fire(obj, burn_time, reason)
|
|||
end
|
||||
|
||||
if old_burn_time <= burn_time then
|
||||
local sound_id = mcl_burning.get(obj, "int", "sound_id")
|
||||
--[[local sound_id = mcl_burning.get(obj, "int", "sound_id")
|
||||
if sound_id == 0 then
|
||||
sound_id = minetest.sound_play("fire_fire", {
|
||||
object = obj,
|
||||
|
@ -153,7 +157,7 @@ function mcl_burning.set_on_fire(obj, burn_time, reason)
|
|||
max_hear_distance = 16,
|
||||
loop = true,
|
||||
}) + 1
|
||||
end
|
||||
end]]--
|
||||
|
||||
local hud_id
|
||||
if obj:is_player() then
|
||||
|
@ -163,7 +167,7 @@ function mcl_burning.set_on_fire(obj, burn_time, reason)
|
|||
hud_elem_type = "image",
|
||||
position = {x = 0.5, y = 0.5},
|
||||
scale = {x = -100, y = -100},
|
||||
text = "fire_basic_flame.png",
|
||||
text = "mcl_burning_hud_flame_animated.png",
|
||||
z_index = 1000,
|
||||
}) + 1
|
||||
end
|
||||
|
@ -171,7 +175,7 @@ function mcl_burning.set_on_fire(obj, burn_time, reason)
|
|||
mcl_burning.set(obj, "float", "burn_time", burn_time)
|
||||
mcl_burning.set(obj, "string", "reason", reason)
|
||||
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)
|
||||
|
||||
local fire_entity = minetest.add_entity(obj:get_pos(), "mcl_burning:fire")
|
||||
local minp, maxp = mcl_burning.get_collisionbox(obj)
|
||||
|
@ -194,8 +198,8 @@ end
|
|||
|
||||
function mcl_burning.extinguish(obj)
|
||||
if mcl_burning.is_burning(obj) then
|
||||
local sound_id = mcl_burning.get(obj, "int", "sound_id") - 1
|
||||
minetest.sound_stop(sound_id)
|
||||
--local sound_id = mcl_burning.get(obj, "int", "sound_id") - 1
|
||||
--minetest.sound_stop(sound_id)
|
||||
|
||||
if obj:is_player() then
|
||||
local hud_id = mcl_burning.get(obj, "int", "hud_id") - 1
|
||||
|
@ -206,7 +210,7 @@ function mcl_burning.extinguish(obj)
|
|||
mcl_burning.set(obj, "float", "burn_time")
|
||||
mcl_burning.set(obj, "float", "damage_timer")
|
||||
mcl_burning.set(obj, "int", "hud_id")
|
||||
mcl_burning.set(obj, "int", "sound_id")
|
||||
--mcl_burning.set(obj, "int", "sound_id")
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -267,7 +271,7 @@ function mcl_burning.fire_entity_step(self, dtime)
|
|||
if not parent or not mcl_burning.is_burning(parent) then
|
||||
do_remove = true
|
||||
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()
|
||||
if luaentity and luaentity.name == "mcl_burning:fire" and not luaentity.doing_step and not luaentity.removed then
|
||||
do_remove = true
|
||||
|
|
|
@ -22,7 +22,7 @@ minetest.register_entity("mcl_burning:fire", {
|
|||
})
|
||||
|
||||
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)
|
||||
end
|
||||
end)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Falling node entities, Minecraft-style
|
|
@ -1 +1,3 @@
|
|||
name = mcl_falling_nodes
|
||||
author = Wuzzy
|
||||
description = Falling node entities, Minecraft-style
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
flowlib
|
||||
mcl_enchanting
|
|
@ -1 +0,0 @@
|
|||
Dropped items will be attracted to the player like a magnet.
|
|
@ -54,14 +54,14 @@ local disable_physics = function(object, luaentity, ignore_check, reset_movement
|
|||
end
|
||||
|
||||
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
|
||||
local pos = player:get_pos()
|
||||
local inv = player:get_inventory()
|
||||
local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z}
|
||||
|
||||
--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
|
||||
object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime
|
||||
local collected = false
|
||||
|
@ -165,66 +165,6 @@ minetest.register_globalstep(function(dtime)
|
|||
end
|
||||
end)
|
||||
|
||||
local minigroups = { "shearsy", "swordy", "shearsy_wool", "swordy_cobweb" }
|
||||
local basegroups = { "pickaxey", "axey", "shovely" }
|
||||
local materials = { "wood", "gold", "stone", "iron", "diamond" }
|
||||
|
||||
-- Checks if the given node would drop its useful drop if dug by a tool
|
||||
-- with the given tool capabilities. Returns true if it will yield its useful
|
||||
-- drop, false otherwise.
|
||||
local check_can_drop = function(node_name, tool_capabilities)
|
||||
local handy = minetest.get_item_group(node_name, "handy")
|
||||
local dig_immediate = minetest.get_item_group(node_name, "dig_immediate")
|
||||
if handy == 1 or dig_immediate == 2 or dig_immediate == 3 then
|
||||
return true
|
||||
else
|
||||
local toolgroupcaps
|
||||
if tool_capabilities then
|
||||
toolgroupcaps = tool_capabilities.groupcaps
|
||||
else
|
||||
return false
|
||||
end
|
||||
|
||||
-- Compare node groups with tool capabilities
|
||||
for m=1, #minigroups do
|
||||
local minigroup = minigroups[m]
|
||||
local g = minetest.get_item_group(node_name, minigroup)
|
||||
if g ~= 0 then
|
||||
local plus = minigroup .. "_dig"
|
||||
if toolgroupcaps[plus] then
|
||||
return true
|
||||
end
|
||||
for e=1,5 do
|
||||
local effplus = plus .. "_efficiency_" .. e
|
||||
if toolgroupcaps[effplus] then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
for b=1, #basegroups do
|
||||
local basegroup = basegroups[b]
|
||||
local g = minetest.get_item_group(node_name, basegroup)
|
||||
if g ~= 0 then
|
||||
for m=g, #materials do
|
||||
local plus = basegroup .. "_dig_"..materials[m]
|
||||
if toolgroupcaps[plus] then
|
||||
return true
|
||||
end
|
||||
for e=1,5 do
|
||||
local effplus = plus .. "_efficiency_" .. e
|
||||
if toolgroupcaps[effplus] then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
-- Stupid workaround to get drops from a drop table:
|
||||
-- Create a temporary table in minetest.registered_nodes that contains the proper drops,
|
||||
-- because unfortunately minetest.get_node_drops needs the drop table to be inside a registered node definition
|
||||
|
@ -281,17 +221,20 @@ function minetest.handle_node_drops(pos, drops, digger)
|
|||
|
||||
-- Check if node will yield its useful drop by the digger's tool
|
||||
local dug_node = minetest.get_node(pos)
|
||||
local toolcaps
|
||||
local tooldef
|
||||
local tool
|
||||
if digger ~= nil then
|
||||
tool = digger:get_wielded_item()
|
||||
toolcaps = tool:get_tool_capabilities()
|
||||
tooldef = minetest.registered_tools[tool:get_name()]
|
||||
|
||||
if not check_can_drop(dug_node.name, toolcaps) then
|
||||
if not mcl_autogroup.can_harvest(dug_node.name, tool:get_name()) then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local diggroups = tooldef and tooldef._mcl_diggroups
|
||||
local shearsy_level = diggroups and diggroups.shearsy and diggroups.shearsy.level
|
||||
|
||||
--[[ Special node drops when dug by shears by reading _mcl_shears_drop or with a silk touch tool reading _mcl_silk_touch_drop
|
||||
from the node definition.
|
||||
Definition of _mcl_shears_drop / _mcl_silk_touch_drop:
|
||||
|
@ -303,7 +246,7 @@ function minetest.handle_node_drops(pos, drops, digger)
|
|||
|
||||
local silk_touch_drop = false
|
||||
local nodedef = minetest.registered_nodes[dug_node.name]
|
||||
if toolcaps ~= nil and toolcaps.groupcaps and toolcaps.groupcaps.shearsy_dig and nodedef._mcl_shears_drop then
|
||||
if shearsy_level and shearsy_level > 0 and nodedef._mcl_shears_drop then
|
||||
if nodedef._mcl_shears_drop == true then
|
||||
drops = { dug_node.name }
|
||||
else
|
||||
|
@ -785,7 +728,7 @@ minetest.register_entity(":__builtin:item", {
|
|||
if self.physical_state then
|
||||
local own_stack = ItemStack(self.object:get_luaentity().itemstring)
|
||||
-- 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()
|
||||
if obj and obj.name == "__builtin:item"
|
||||
and obj.physical_state == false then
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
name = mcl_item_entity
|
||||
author = PilzAdam
|
||||
description = Dropped items will be attracted to the player like a magnet.
|
||||
depends = flowlib, mcl_enchanting
|
||||
|
|
|
@ -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?
|
|
@ -1 +0,0 @@
|
|||
Minecarts are vehicles to move players quickly on rails.
|
|
@ -12,14 +12,15 @@ local function detach_driver(self)
|
|||
if not self._driver then
|
||||
return
|
||||
end
|
||||
if self._driver:is_player() then
|
||||
mcl_player.player_attached[self._driver:get_player_name()] = nil
|
||||
self._driver:set_detach()
|
||||
self._driver:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0})
|
||||
mcl_player.player_set_animation(self._driver, "stand" , 30)
|
||||
end
|
||||
mcl_player.player_attached[self._driver] = nil
|
||||
local player = minetest.get_player_by_name(self._driver)
|
||||
self._driver = nil
|
||||
self._start_pos = nil
|
||||
if player then
|
||||
player:set_detach()
|
||||
player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0})
|
||||
mcl_player.player_set_animation(player, "stand" , 30)
|
||||
end
|
||||
end
|
||||
|
||||
local function activate_tnt_minecart(self, timer)
|
||||
|
@ -61,7 +62,7 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
|||
|
||||
on_rightclick = on_rightclick,
|
||||
|
||||
_driver = nil, -- player (or mob) who sits in and controls the minecart (only for minecart!)
|
||||
_driver = nil, -- player who sits in and controls the minecart (only for minecart!)
|
||||
_punched = false, -- used to re-send _velocity and position
|
||||
_velocity = {x=0, y=0, z=0}, -- only used on punch
|
||||
_start_pos = nil, -- Used to calculate distance for “On A Rail” achievement
|
||||
|
@ -96,12 +97,31 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
|||
end
|
||||
|
||||
function cart:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
|
||||
-- Punch: Pick up minecart (unless TNT was ignited)
|
||||
if self._boomtimer then return end
|
||||
local pos = self.object:get_pos()
|
||||
if not self._railtype then
|
||||
local node = minetest.get_node(vector.floor(pos)).name
|
||||
self._railtype = minetest.get_item_group(node, "connect_to_raillike")
|
||||
end
|
||||
|
||||
if not puncher or not puncher:is_player() then
|
||||
local cart_dir = mcl_minecarts:get_rail_direction(pos, {x=1, y=0, z=0}, nil, nil, self._railtype)
|
||||
if vector.equals(cart_dir, {x=0, y=0, z=0}) then
|
||||
return
|
||||
end
|
||||
self._velocity = vector.multiply(cart_dir, 3)
|
||||
self._old_pos = nil
|
||||
self._punched = true
|
||||
return
|
||||
end
|
||||
|
||||
-- Punch+sneak: Pick up minecart (unless TNT was ignited)
|
||||
if puncher:get_player_control().sneak and not self._boomtimer then
|
||||
if self._driver then
|
||||
if self._old_pos then
|
||||
self.object:set_pos(self._old_pos)
|
||||
end
|
||||
detach_driver(self)
|
||||
end
|
||||
local pos = self.object:get_pos()
|
||||
|
||||
-- Disable detector rail
|
||||
local rou_pos = vector.round(pos)
|
||||
|
@ -127,70 +147,61 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
|||
end
|
||||
|
||||
self.object:remove()
|
||||
return
|
||||
end
|
||||
|
||||
local vel = self.object:get_velocity()
|
||||
if puncher:get_player_name() == self._driver then
|
||||
if math.abs(vel.x + vel.z) > 7 then
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local punch_dir = mcl_minecarts:velocity_to_dir(puncher:get_look_dir())
|
||||
punch_dir.y = 0
|
||||
local cart_dir = mcl_minecarts:get_rail_direction(pos, punch_dir, nil, nil, self._railtype)
|
||||
if vector.equals(cart_dir, {x=0, y=0, z=0}) then
|
||||
return
|
||||
end
|
||||
|
||||
time_from_last_punch = math.min(time_from_last_punch, tool_capabilities.full_punch_interval)
|
||||
local f = 3 * (time_from_last_punch / tool_capabilities.full_punch_interval)
|
||||
|
||||
self._velocity = vector.multiply(cart_dir, f)
|
||||
self._old_pos = nil
|
||||
self._punched = true
|
||||
end
|
||||
|
||||
cart.on_activate_by_rail = on_activate_by_rail
|
||||
|
||||
function cart:on_step(dtime)
|
||||
local ctrl, player = nil, nil
|
||||
local update = {}
|
||||
local vel = self.object:get_velocity()
|
||||
local pos, rou_pos, node
|
||||
pos = self.object:get_pos()
|
||||
rou_pos = vector.round(pos)
|
||||
node = minetest.get_node(rou_pos)
|
||||
local g = minetest.get_item_group(node.name, "connect_to_raillike")
|
||||
if self._driver and self._driver:is_player() then
|
||||
player = self._driver
|
||||
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
|
||||
if g == self._railtype then
|
||||
if ctrl.right then
|
||||
local c = vector.multiply(minetest.yaw_to_dir(self._driver:get_look_horizontal()-1.57), 0.2)
|
||||
self.object:set_velocity(vector.add(vel, {x=c.x, y=0, z=c.z}))
|
||||
end
|
||||
if ctrl.left then
|
||||
local c = vector.multiply(minetest.yaw_to_dir(self._driver:get_look_horizontal()+1.57), 0.2)
|
||||
self.object:set_velocity(vector.add(vel, {x=c.x, y=0, z=c.z}))
|
||||
end
|
||||
if ctrl.up then
|
||||
local c = vector.multiply(self._driver:get_look_dir(), 0.2)
|
||||
self.object:set_velocity(vector.add(vel, {x=c.x, y=0, z=c.z}))
|
||||
end
|
||||
if ctrl.down then
|
||||
local c = vector.multiply(self._driver:get_look_dir(), 0.2)
|
||||
self.object:set_velocity(vector.subtract(vel, {x=c.x, y=0, z=c.z}))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local vel = self.object:get_velocity()
|
||||
local update = {}
|
||||
if self._last_float_check == nil then
|
||||
self._last_float_check = 0
|
||||
else
|
||||
self._last_float_check = self._last_float_check + dtime
|
||||
end
|
||||
local pos, rou_pos, node
|
||||
-- Drop minecart if it isn't on a rail anymore
|
||||
if self._last_float_check >= mcl_minecarts.check_float_time then
|
||||
|
||||
|
||||
for _,object in pairs(minetest.get_objects_inside_radius(pos, 1.3)) do
|
||||
if object ~= self.object then
|
||||
local mob = object:get_luaentity()
|
||||
if mob then mob = mob._cmi_is_mob == true end
|
||||
if mob and (not self._driver) and not object:get_attach() then
|
||||
self._driver = object
|
||||
object:set_attach(self.object, "", {x=0, y=-1.75, z=-2}, {x=0, y=0, z=0})
|
||||
mobs:set_animation(self.object, "stand")
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
pos = self.object:get_pos()
|
||||
rou_pos = vector.round(pos)
|
||||
node = minetest.get_node(rou_pos)
|
||||
local g = minetest.get_item_group(node.name, "connect_to_raillike")
|
||||
if g ~= self._railtype and self._railtype ~= nil then
|
||||
-- Detach driver
|
||||
if player then
|
||||
|
@ -289,12 +300,8 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
|||
end
|
||||
end
|
||||
|
||||
if update.vel then
|
||||
if self._punched then
|
||||
vel = vector.add(vel, self._velocity)
|
||||
if vel.x>8 then vel.x = 8 end
|
||||
if vel.x<-8 then vel.x = -8 end
|
||||
if vel.z>8 then vel.z = 8 end
|
||||
if vel.z<-8 then vel.z = -8 end
|
||||
self.object:set_velocity(vel)
|
||||
self._old_dir.y = 0
|
||||
elseif vector.equals(vel, {x=0, y=0, z=0}) and (not has_fuel) then
|
||||
|
@ -619,14 +626,17 @@ register_minecart(
|
|||
"mcl_minecarts_minecart_normal.png",
|
||||
{"mcl_minecarts:minecart"},
|
||||
function(self, clicker)
|
||||
if not clicker or not clicker:is_player() then return end
|
||||
if clicker == self._driver then
|
||||
detach_driver(self)
|
||||
else
|
||||
local name = clicker:get_player_name()
|
||||
self._driver = clicker
|
||||
if not clicker or not clicker:is_player() then
|
||||
return
|
||||
end
|
||||
local player_name = clicker:get_player_name()
|
||||
if self._driver and player_name == self._driver then
|
||||
detach_driver(self)
|
||||
elseif not self._driver then
|
||||
self._driver = player_name
|
||||
self._start_pos = self.object:get_pos()
|
||||
mcl_player.player_attached[name] = true
|
||||
mcl_player.player_attached[player_name] = true
|
||||
clicker:set_attach(self.object, "", {x=0, y=-1.75, z=-2}, {x=0, y=0, z=0})
|
||||
mcl_player.player_attached[name] = true
|
||||
minetest.after(0.2, function(name)
|
||||
|
@ -637,7 +647,6 @@ register_minecart(
|
|||
mcl_tmp_message.message(clicker, S("Sneak to dismount"))
|
||||
end
|
||||
end, name)
|
||||
clicker:set_look_horizontal(self.object:get_yaw())
|
||||
end
|
||||
end, activate_normal_minecart
|
||||
)
|
||||
|
@ -654,6 +663,8 @@ register_minecart(
|
|||
{"mcl_minecarts:minecart", "mcl_chests:chest"},
|
||||
nil, nil, false)
|
||||
|
||||
mcl_wip.register_wip_item("mcl_minecarts:chest_minecart")
|
||||
|
||||
-- Minecart with Furnace
|
||||
register_minecart(
|
||||
"mcl_minecarts:furnace_minecart",
|
||||
|
@ -708,6 +719,8 @@ register_minecart(
|
|||
end, nil, false
|
||||
)
|
||||
|
||||
mcl_wip.register_wip_item("mcl_minecarts:furnace_minecart")
|
||||
|
||||
-- Minecart with Command Block
|
||||
register_minecart(
|
||||
"mcl_minecarts:command_block_minecart",
|
||||
|
@ -729,6 +742,8 @@ register_minecart(
|
|||
nil, nil, false
|
||||
)
|
||||
|
||||
mcl_wip.register_wip_item("mcl_minecarts:command_block_minecart")
|
||||
|
||||
-- Minecart with Hopper
|
||||
register_minecart(
|
||||
"mcl_minecarts:hopper_minecart",
|
||||
|
@ -747,6 +762,8 @@ register_minecart(
|
|||
nil, nil, false
|
||||
)
|
||||
|
||||
mcl_wip.register_wip_item("mcl_minecarts:hopper_minecart")
|
||||
|
||||
-- Minecart with TNT
|
||||
register_minecart(
|
||||
"mcl_minecarts:tnt_minecart",
|
||||
|
|
|
@ -1 +1,6 @@
|
|||
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
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ local collision = function(self)
|
|||
local z = 0
|
||||
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()
|
||||
or (object:get_luaentity()._cmi_is_mob == true and object ~= self.object) then
|
||||
|
@ -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.
|
||||
if damaged then
|
||||
add_texture_mod(self, "^[colorize:#FF000040")
|
||||
add_texture_mod(self, "^[colorize:red:130")
|
||||
minetest.after(.2, function(self)
|
||||
if self and self.object then
|
||||
remove_texture_mod(self, "^[colorize:#FF000040")
|
||||
remove_texture_mod(self, "^[colorize:red:130")
|
||||
end
|
||||
end, self)
|
||||
mob_sound(self, "damage")
|
||||
|
@ -1047,8 +1047,13 @@ local do_env_damage = function(self)
|
|||
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
|
||||
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
|
||||
return true
|
||||
end
|
||||
|
@ -1057,7 +1062,7 @@ local do_env_damage = function(self)
|
|||
if mod_worlds then
|
||||
_, dim = mcl_worlds.y_to_layer(pos.y)
|
||||
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
|
||||
mcl_burning.set_on_fire(self.object, 10)
|
||||
else
|
||||
|
@ -2821,7 +2826,7 @@ local falling = function(self, pos)
|
|||
end
|
||||
|
||||
if mcl_portals ~= nil then
|
||||
if mcl_portals.nether_portal_cooloff[self.object] then
|
||||
if mcl_portals.nether_portal_cooloff(self.object) then
|
||||
return false -- mob has teleported through Nether portal - it's 99% not falling
|
||||
end
|
||||
end
|
||||
|
@ -4576,9 +4581,9 @@ local timer = 0
|
|||
minetest.register_globalstep(function(dtime)
|
||||
timer = timer + dtime
|
||||
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()
|
||||
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()
|
||||
if lua and lua._cmi_is_mob then
|
||||
lua.lifetimer = math.max(20, lua.lifetimer)
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
Adds a mob API for mods to add animals or monsters, etc.
|
|
@ -1,3 +1,5 @@
|
|||
name = mcl_mobs
|
||||
author = PilzAdam
|
||||
description = Adds a mob API for mods to add animals or monsters, etc.
|
||||
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
|
||||
|
|
|
@ -154,7 +154,7 @@ function mobs.attach(entity, player)
|
|||
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)
|
||||
mcl_player.player_set_animation(player, "sit_mount" , 30)
|
||||
end
|
||||
end, player:get_player_name())
|
||||
|
||||
|
|
|
@ -191,6 +191,14 @@ minetest.register_craftitem("mcl_paintings:painting", {
|
|||
if pointed_thing.type ~= "node" then
|
||||
return itemstack
|
||||
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)
|
||||
dir = vector.normalize(dir)
|
||||
if dir.y ~= 0 then
|
||||
|
@ -293,6 +301,8 @@ minetest.register_craftitem("mcl_paintings:painting", {
|
|||
end,
|
||||
})
|
||||
|
||||
mcl_wip.register_wip_item("mcl_paintings:painting")
|
||||
|
||||
minetest.register_craft({
|
||||
output = "mcl_paintings:painting",
|
||||
recipe = {
|
||||
|
|
|
@ -1 +1,5 @@
|
|||
name = mcl_paintings
|
||||
author = Wuzzy
|
||||
description = The paintings mod for MCL2
|
||||
depends = mcl_wip
|
||||
|
||||
|
|
|
@ -122,7 +122,7 @@ local arrows = {
|
|||
}
|
||||
|
||||
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 not minetest.is_creative_enabled(player:get_player_name()) then
|
||||
player:get_inventory():remove_item("main", arrow[1])
|
||||
|
|
|
@ -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?
|
|
@ -1 +0,0 @@
|
|||
Adds Minecraft-like monsters and animals.
|
|
@ -105,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)
|
||||
|
||||
mcl_wip.register_wip_item("mobs_mc:enderdragon")
|
||||
|
|
|
@ -451,6 +451,6 @@ mobs:spawn_specific("mobs_mc:donkey", mobs_mc.spawn.grassland_savanna, {"air"},
|
|||
-- spawn eggs
|
||||
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: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:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0)
|
||||
|
|
|
@ -1 +1,6 @@
|
|||
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
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 4.0 KiB |
Binary file not shown.
Before Width: | Height: | Size: 11 KiB |
|
@ -960,7 +960,7 @@ mobs:register_mob("mobs_mc:villager", {
|
|||
"mobs_mc_villager_smith.png", --hat
|
||||
},
|
||||
},
|
||||
visual_size = {x=3, y=3},
|
||||
visual_size = {x=2.75, y=2.75},
|
||||
makes_footstep_sound = true,
|
||||
walk_velocity = 1.2,
|
||||
run_velocity = 2.4,
|
||||
|
|
|
@ -28,7 +28,7 @@ mobs:register_mob("mobs_mc:evoker", {
|
|||
"blank.png", --no hat
|
||||
-- TODO: Attack glow
|
||||
} },
|
||||
visual_size = {x=3, y=3},
|
||||
visual_size = {x=2.75, y=2.75},
|
||||
makes_footstep_sound = true,
|
||||
damage = 6,
|
||||
walk_velocity = 0.2,
|
||||
|
|
|
@ -36,7 +36,7 @@ mobs:register_mob("mobs_mc:illusioner", {
|
|||
-- TODO: more sounds
|
||||
distance = 16,
|
||||
},
|
||||
visual_size = {x=3, y=3},
|
||||
visual_size = {x=2.75, y=2.75},
|
||||
walk_velocity = 0.6,
|
||||
run_velocity = 2,
|
||||
jump = true,
|
||||
|
|
|
@ -30,7 +30,7 @@ mobs:register_mob("mobs_mc:vindicator", {
|
|||
-- TODO: Glow when attacking (mobs_mc_vindicator.png)
|
||||
},
|
||||
},
|
||||
visual_size = {x=3, y=3},
|
||||
visual_size = {x=2.75, y=2.75},
|
||||
makes_footstep_sound = true,
|
||||
damage = 13,
|
||||
reach = 2,
|
||||
|
|
|
@ -45,7 +45,7 @@ mobs:register_mob("mobs_mc:villager_zombie", {
|
|||
{"mobs_mc_zombie_smith.png"},
|
||||
{"mobs_mc_zombie_villager.png"}
|
||||
},
|
||||
visual_size = {x=3, y=3},
|
||||
visual_size = {x=2.75, y=2.75},
|
||||
makes_footstep_sound = true,
|
||||
damage = 3,
|
||||
reach = 2,
|
||||
|
|
|
@ -25,7 +25,7 @@ mobs:register_mob("mobs_mc:witch", {
|
|||
textures = {
|
||||
{"mobs_mc_witch.png"},
|
||||
},
|
||||
visual_size = {x=3, y=3},
|
||||
visual_size = {x=2.75, y=2.75},
|
||||
makes_footstep_sound = true,
|
||||
damage = 2,
|
||||
reach = 2,
|
||||
|
@ -104,3 +104,5 @@ mobs:register_arrow("mobs_mc:potion_arrow", {
|
|||
|
||||
-- spawn eggs
|
||||
mobs:register_egg("mobs_mc:witch", S("Witch"), "mobs_mc_spawn_icon_witch.png", 0, true)
|
||||
|
||||
mcl_wip.register_wip_item("mobs_mc:witch")
|
||||
|
|
|
@ -106,3 +106,5 @@ mobs:register_arrow("mobs_mc:wither_skull", {
|
|||
|
||||
--Spawn egg
|
||||
mobs:register_egg("mobs_mc:wither", S("Wither"), "mobs_mc_spawn_icon_wither.png", 0, true)
|
||||
|
||||
mcl_wip.register_wip_item("mobs_mc:wither")
|
|
@ -1,2 +0,0 @@
|
|||
mcl_init
|
||||
mcl_core
|
|
@ -0,0 +1,4 @@
|
|||
name = mobs_mc_gameconfig
|
||||
author = Wuzzy
|
||||
description = mobs_mc game configuration for MCL2
|
||||
depends = mcl_init, mcl_core
|
|
@ -1,2 +0,0 @@
|
|||
mcl_fire
|
||||
mcl_death_messages?
|
|
@ -1 +0,0 @@
|
|||
A mod that adds thunder and lightning effects.
|
|
@ -11,6 +11,18 @@ of the license, or (at your option) any later version.
|
|||
|
||||
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.interval_low = 17
|
||||
|
@ -45,7 +57,7 @@ minetest.register_globalstep(revertsky)
|
|||
-- select a random strike point, midpoint
|
||||
local function choose_pos(pos)
|
||||
if not pos then
|
||||
local playerlist = minetest.get_connected_players()
|
||||
local playerlist = get_connected_players()
|
||||
local playercount = table.getn(playerlist)
|
||||
|
||||
-- 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))
|
||||
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
|
||||
if b then
|
||||
return nil, nil
|
||||
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
|
||||
return nil, nil
|
||||
end
|
||||
|
@ -87,7 +99,7 @@ end
|
|||
-- * returns: bool - success if a strike happened
|
||||
lightning.strike = function(pos)
|
||||
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
|
||||
|
||||
local pos2
|
||||
|
@ -97,7 +109,7 @@ lightning.strike = function(pos)
|
|||
return false
|
||||
end
|
||||
|
||||
minetest.add_particlespawner({
|
||||
add_particlespawner({
|
||||
amount = 1,
|
||||
time = 0.2,
|
||||
-- make it hit the top of a block exactly with the bottom
|
||||
|
@ -120,16 +132,16 @@ lightning.strike = function(pos)
|
|||
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
|
||||
local objs = minetest.get_objects_inside_radius(pos2, 3.5)
|
||||
local objs = get_objects_inside_radius(pos2, 3.5)
|
||||
for o=1, #objs do
|
||||
local obj = objs[o]
|
||||
local lua = obj:get_luaentity()
|
||||
if obj:is_player() then
|
||||
-- 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()))
|
||||
end
|
||||
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
|
||||
local rot = obj:get_yaw()
|
||||
obj:remove()
|
||||
obj = minetest.add_entity(pos2, "mobs_mc:pigman")
|
||||
obj = add_entity(pos2, "mobs_mc:pigman")
|
||||
obj:set_yaw(rot)
|
||||
-- mooshroom: toggle color red/brown (no damage)
|
||||
elseif lua.name == "mobs_mc:mooshroom" then
|
||||
|
@ -163,7 +175,7 @@ lightning.strike = function(pos)
|
|||
elseif lua.name == "mobs_mc:creeper" then
|
||||
local rot = obj:get_yaw()
|
||||
obj:remove()
|
||||
obj = minetest.add_entity(pos2, "mobs_mc:creeper_charged")
|
||||
obj = add_entity(pos2, "mobs_mc:creeper_charged")
|
||||
obj:set_yaw(rot)
|
||||
-- Other mobs: Just damage
|
||||
else
|
||||
|
@ -172,7 +184,7 @@ lightning.strike = function(pos)
|
|||
end
|
||||
end
|
||||
|
||||
local playerlist = minetest.get_connected_players()
|
||||
local playerlist = get_connected_players()
|
||||
for i = 1, #playerlist do
|
||||
local player = playerlist[i]
|
||||
local sky = {}
|
||||
|
@ -197,25 +209,25 @@ lightning.strike = function(pos)
|
|||
if rng:next(1,100) <= 3 then
|
||||
skeleton_lightning = true
|
||||
end
|
||||
if minetest.get_item_group(minetest.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_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
|
||||
minetest.add_entity(pos2, "mobs_mc:skeleton_horse")
|
||||
add_entity(pos2, "mobs_mc:skeleton_horse")
|
||||
|
||||
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 = 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)
|
||||
angle = angle + (math.pi*2) / 3
|
||||
end
|
||||
|
||||
-- Cause a fire
|
||||
else
|
||||
minetest.set_node(pos2, {name = "mcl_fire:fire"})
|
||||
set_node(pos2, {name = "mcl_fire:fire"})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -223,9 +235,9 @@ lightning.strike = function(pos)
|
|||
end
|
||||
|
||||
-- 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
|
||||
minetest.after(rng:next(lightning.interval_low,
|
||||
after(rng:next(lightning.interval_low,
|
||||
lightning.interval_high), lightning.strike)
|
||||
end
|
||||
end)
|
||||
|
|
|
@ -1 +1,6 @@
|
|||
name = lightning
|
||||
author = sofar
|
||||
description = A mod that adds thunder and lightning effects.
|
||||
depends = mcl_fire
|
||||
optional_depends = mcl_death_messages
|
||||
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
name = mcl_moon
|
||||
author = Wuzzy
|
||||
description = Adds moon phases to the game
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
mcl_worlds
|
||||
mcl_death_messages
|
|
@ -1 +0,0 @@
|
|||
Deal damage to entities stuck in the deep void
|
|
@ -1,6 +1,14 @@
|
|||
local S = minetest.get_translator("mcl_void_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 VOID_DAMAGE_FREQ = 0.5
|
||||
local VOID_DAMAGE = 4
|
||||
|
@ -33,7 +41,7 @@ minetest.register_on_mods_loaded(function()
|
|||
self._void_timer = 0
|
||||
|
||||
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
|
||||
local ent = obj:get_luaentity()
|
||||
obj:remove()
|
||||
|
@ -51,11 +59,11 @@ minetest.register_globalstep(function(dtime)
|
|||
if voidtimer > VOID_DAMAGE_FREQ then
|
||||
voidtimer = 0
|
||||
local enable_damage = minetest.settings:get_bool("enable_damage")
|
||||
local players = minetest.get_connected_players()
|
||||
local players = get_connected()
|
||||
for p=1, #players do
|
||||
local player = players[p]
|
||||
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
|
||||
local immortal_val = player:get_armor_groups().immortal
|
||||
local is_immortal = false
|
||||
|
@ -65,14 +73,14 @@ minetest.register_globalstep(function(dtime)
|
|||
if is_immortal or not enable_damage then
|
||||
-- If damage is disabled, we can't kill players.
|
||||
-- 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)
|
||||
mcl_worlds.dimension_change(player, mcl_worlds.pos_to_dimension(spawn))
|
||||
minetest.chat_send_player(player:get_player_name(), S("The void is off-limits to you!"))
|
||||
dim_change(player, pos_to_dim(spawn))
|
||||
send_chat(player:get_player_name(), S("The void is off-limits to you!"))
|
||||
elseif enable_damage and not is_immortal then
|
||||
-- Damage enabled, not immortal: Deal void damage (4 HP / 0.5 seconds)
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1 +1,4 @@
|
|||
name = mcl_void_damage
|
||||
author = Wuzzy
|
||||
description = Deal damage to entities stuck in the deep void
|
||||
depends = mcl_worlds, mcl_death_messages
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
mcl_init
|
||||
mcl_worlds
|
||||
lightning?
|
|
@ -1 +0,0 @@
|
|||
Weather and sky handling: Rain, snow, thunderstorm, End and Nether ambience
|
|
@ -1 +1,5 @@
|
|||
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
|
||||
|
|
|
@ -27,7 +27,7 @@ minetest.register_globalstep(function(dtime)
|
|||
if timer < 0.7 then return end
|
||||
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
|
||||
return false
|
||||
end
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
local PARTICLES_COUNT_RAIN = 30
|
||||
local PARTICLES_COUNT_THUNDER = 45
|
||||
|
||||
local get_connected_players = minetest.get_connected_players
|
||||
|
||||
mcl_weather.rain = {
|
||||
-- max rain particles created at time
|
||||
particles_count = PARTICLES_COUNT_RAIN,
|
||||
|
@ -36,7 +38,7 @@ mcl_weather.rain.set_sky_box = function()
|
|||
{r=85, g=86, b=98},
|
||||
{r=0, g=0, b=0}})
|
||||
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"})
|
||||
end
|
||||
end
|
||||
|
@ -154,7 +156,7 @@ mcl_weather.rain.clear = function()
|
|||
mcl_weather.rain.init_done = false
|
||||
mcl_weather.rain.set_particles_mode("rain")
|
||||
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_player(player)
|
||||
end
|
||||
|
@ -176,7 +178,7 @@ mcl_weather.rain.make_weather = function()
|
|||
mcl_weather.rain.init_done = true
|
||||
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
|
||||
mcl_weather.rain.remove_sound(player)
|
||||
return false
|
||||
|
|
|
@ -43,7 +43,7 @@ mcl_weather.skycolor = {
|
|||
|
||||
-- Remove layer from colors table
|
||||
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
|
||||
table.remove(mcl_weather.skycolor.layer_names, k)
|
||||
mcl_weather.skycolor.force_update = true
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
local get_connected_players = minetest.get_connected_players
|
||||
|
||||
mcl_weather.snow = {}
|
||||
|
||||
mcl_weather.snow.particles_count = 15
|
||||
|
@ -37,7 +39,7 @@ mcl_weather.snow.set_sky_box = function()
|
|||
{r=85, g=86, b=86},
|
||||
{r=0, g=0, b=0}})
|
||||
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"})
|
||||
end
|
||||
mcl_weather.skycolor.active = true
|
||||
|
@ -71,7 +73,7 @@ minetest.register_globalstep(function(dtime)
|
|||
mcl_weather.snow.init_done = true
|
||||
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
|
||||
return false
|
||||
end
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
local get_connected_players = minetest.get_connected_players
|
||||
|
||||
-- turn off lightning mod 'auto mode'
|
||||
lightning.auto = false
|
||||
|
||||
|
@ -25,7 +27,7 @@ minetest.register_globalstep(function(dtime)
|
|||
{r=40, g=40, b=40},
|
||||
{r=0, g=0, b=0}})
|
||||
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"})
|
||||
end
|
||||
mcl_weather.thunder.init_done = true
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue