forked from Mineclonia/Mineclonia
Compare commits
210 Commits
mineclone2
...
master
Author | SHA1 | Date |
---|---|---|
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | 23f1c51912 | |
Nils Dagsson Moskopp | 4d02af8c94 | |
Li0n_2 | 7ede0ca79a | |
JosiahWI | e2e7e15b39 | |
cora | 93a0879b40 | |
Nils Dagsson Moskopp | 0b5fa14041 | |
cora | 4f33f626f5 | |
Nils Dagsson Moskopp | df7bd78af5 | |
Nils Dagsson Moskopp | fe3e837e1b | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | 6f811b3cee | |
Lizzy Fleckenstein | dfa56f229f | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | ee77f33ea8 | |
cora | 5deaabdb47 | |
cora | d77f31eab8 | |
cora | 10670d5c10 | |
Nils Dagsson Moskopp | 609105e091 | |
cora | f9e3c4fd6d | |
cora | d70c05e92c | |
Lizzy Fleckenstein | cacddd3fb4 | |
cora | dd347c50c5 | |
Nils Dagsson Moskopp | 54b36c42a9 | |
cora | 5252952555 | |
Li0n_2 | c08f9850f6 | |
Nils Dagsson Moskopp | f8b5066c61 | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | 4b9094ddc2 | |
cora | 5087e8194a | |
cora | 71befcff10 | |
Nils Dagsson Moskopp | 66dd87af25 | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | fc47f0a87e | |
Nils Dagsson Moskopp | 6bd4b0e62c | |
AFCMS | 3473f55136 | |
Lizzy Fleckenstein | af7f7c3574 | |
cora | 434e545745 | |
Nils Dagsson Moskopp | 76d2846c59 | |
Nils Dagsson Moskopp | 526c25aa57 | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | 249cfb8118 | |
cora | 84194b71e6 | |
cora | 0b7097cb28 | |
cora | bfbc953b92 | |
Nils Dagsson Moskopp | 253100380c | |
cora | df98db1d8c | |
Nils Dagsson Moskopp | f410de485a | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | 3a78211be4 | |
cora | eee94658e7 | |
cora | 07a59ef120 | |
Nils Dagsson Moskopp | e1462d9534 | |
cora | 42a076cc0b | |
NO11 | 3759d50344 | |
NO11 | 50e913b370 | |
NO11 | 508b08dfd3 | |
NO11 | 68646b62b3 | |
NO11 | d3348ef8b7 | |
NO11 | eadb96dd40 | |
NO11 | 616b009452 | |
NO11 | a92e1c05a3 | |
cora | b26fb44aeb | |
Li0n | 19112bfbec | |
cora | 6f046b199d | |
Nils Dagsson Moskopp | 7f4f5c5c89 | |
Nils Dagsson Moskopp | a2b8489c80 | |
Nils Dagsson Moskopp | c83278d3ff | |
Nils Dagsson Moskopp | cef3669ee2 | |
cora | 78634d4c90 | |
Nils Dagsson Moskopp | 10ce37d887 | |
cora | 3cd4ad5591 | |
Nils Dagsson Moskopp | ce6d6c26cc | |
Nils Dagsson Moskopp | a0c9f11af6 | |
sfan5 | 62d5b547a0 | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | 45cdad7283 | |
Nils Dagsson Moskopp | 71cff7051f | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | eddbfb4b5c | |
Wuzzy | 280aed484c | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | c1cf50ae15 | |
Nils Dagsson Moskopp | 01c8339f40 | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | 6219e8ae12 | |
Lizzy Fleckenstein | 920ca96764 | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | e2e08f28dd | |
Nils Dagsson Moskopp | 76e3a00e18 | |
Nils Dagsson Moskopp | 2033a9bf1d | |
Nils Dagsson Moskopp | 99ebf08873 | |
Nils Dagsson Moskopp | c45c0df118 | |
Nils Dagsson Moskopp | 39023f1adf | |
Nils Dagsson Moskopp | 689054f904 | |
cora | 8ed5fd4740 | |
epCode | 6951ecdfc9 | |
cora | 9f086a9242 | |
Nils Dagsson Moskopp | 275f0826ed | |
cora | 00ee2d5013 | |
Nils Dagsson Moskopp | f8c58262bc | |
cora | 926d5e2c37 | |
cora | f1ac39eaad | |
cora | 58fe08332f | |
Nils Dagsson Moskopp | 1e42c37895 | |
cora | 0816ee38b4 | |
Nils Dagsson Moskopp | 0b92dc1f26 | |
cora | 87761bf454 | |
Elias Åström | 725bf517ca | |
Elias Åström | fc61c71df5 | |
Elias Åström | 7bfd28cd75 | |
Nils Dagsson Moskopp | eb7b99d59e | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | b96dad7852 | |
E | 2feab24dd3 | |
cora | c9a8ef0ac2 | |
Nils Dagsson Moskopp | 2aafb2f2d0 | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | 86c1f37296 | |
Lizzy Fleckenstein | 764ff5512a | |
cora | 6c311d5528 | |
cora | 79766bff23 | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | 031ae5fcb5 | |
Nils Dagsson Moskopp | 7ccdbc5905 | |
Nils Dagsson Moskopp | 5f0710a486 | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | 811b6d7058 | |
AFCMS | e858ea6233 | |
AFCMS | 20b7b6ff99 | |
AFCMS | b6fc888559 | |
Elias Åström | ab389e9995 | |
E | e14265ff8e | |
E | b1fbbfdd35 | |
E | 02a8496b5f | |
E | 0c13293f43 | |
cora | 3ee2ef0618 | |
Nils Dagsson Moskopp | 27828b6317 | |
Elias Åström | 4b4d40f158 | |
Elias Åström | fac4a38657 | |
Elias Åström | c1bed0a826 | |
E | c17d450fda | |
E | 538e3b7e35 | |
E | 42205639f6 | |
E | dd8bcaec50 | |
E | 4dd1b00a0a | |
E | 32c7fe4741 | |
E | c9c568847c | |
E | 838bf0034f | |
E | 7f9ad443ac | |
E | 1738d57a2c | |
E | 438e91d212 | |
E | 9875183a6f | |
E | 95af8196a2 | |
Elias Åström | f3b0285347 | |
Elias Åström | 4c61fc80c6 | |
Elias Åström | 7ea25ab172 | |
Elias Åström | 5d3514880a | |
Elias Åström | d9bbf4879c | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | a9d4a85e9a | |
Nils Dagsson Moskopp | ee9f49b86e | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | 150868f03b | |
Elias Åström | 90f0a6ab2a | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | 659a158c66 | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | 4085d95d96 | |
Elias Åström | 74d4986d1d | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | 3009ebb2c6 | |
Benjamin Schötz | 9f61cfffaa | |
Benjamin Schötz | 7d44596c6d | |
E | 4ae17b0c8e | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | 0d92212e08 | |
Benjamin Schötz | 48091cecab | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | d6463fe29a | |
Nils Dagsson Moskopp | ac5f115f83 | |
Elias Åström | 31341ca57b | |
Elias Åström | e52cae28cd | |
Elias Åström | aa1af725f2 | |
Benjamin Schötz | adbb2f037a | |
E | 2381cb8e84 | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | fda2d41b4e | |
Benjamin Schötz | e5c324b0d7 | |
Benjamin Schötz | 82c838e067 | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | bbe07abb0d | |
AFCMS | 078586fa1a | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | 0761ad0964 | |
Nils Dagsson Moskopp | c0a76dd24f | |
Elias Åström | 1c6d3c2fea | |
Elias Åström | d6e1fe42d1 | |
My favourite Minetest cheat clients are Dragonfire and Waspsaliva. | b041666c18 | |
Elias Åström | 357024ad97 | |
Elias Åström | 42c7186674 | |
Elias Åström | b57c94df88 | |
Elias Åström | 34af6a2cc3 | |
Elias Åström | 029ebaa388 | |
Elias Åström | 2df6ee32be | |
Elias Åström | 9d38f0d01b | |
Elias Åström | eb1af8902d | |
Elias Åström | d4a3213343 | |
Elias Åström | 0681fc98d2 | |
Elias Åström | 9c961394ec | |
Elias Åström | 64e8b82ff7 | |
Elias Åström | 54563262f6 | |
Elias Åström | 6fb56b074f | |
Elias Åström | 7583223f68 | |
Elias Åström | 9bb39dfba6 | |
Elias Åström | dcd050a274 | |
Elias Åström | ccd53e7f10 | |
Elias Åström | 85ff4cee75 | |
Elias Åström | 3308ce812d | |
Elias Åström | e32f17b82a | |
Elias Åström | 576dde1dd5 | |
Elias Åström | b50addac55 | |
Elias Åström | fe883a40bc | |
Elias Åström | 4a9561e5dc | |
Elias Åström | c92f0e5ce3 | |
Elias Åström | ba0a09243b | |
Elias Åström | 64e353a9c2 | |
Elias Åström | ecccc2058a | |
Elias Åström | bb5094f657 | |
Elias Åström | a342652960 | |
Elias Åström | ffbbe91bc5 | |
Elias Åström | 012e150b59 | |
Elias Åström | 6741aded0b | |
Elias Åström | 15df697836 | |
Elias Åström | b6b0496a26 | |
Elias Åström | ac20baac12 |
|
@ -0,0 +1,38 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
name: "Bug Report"
|
||||||
|
about: "Use this for when something's broken."
|
||||||
|
labels:
|
||||||
|
- bug
|
||||||
|
- unconfirmed
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
##### What happened?
|
||||||
|
|
||||||
|
<!-- Describe what's wrong. -->
|
||||||
|
|
||||||
|
##### What did I expect?
|
||||||
|
|
||||||
|
<!-- Describe what should be happening instead -->
|
||||||
|
|
||||||
|
##### How to get it to happen
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Write down exactly what you did to get the bug to happen
|
||||||
|
If you need more steps, just keep adding numbers. If you
|
||||||
|
don't need them all, delete the empty numbers.
|
||||||
|
-->
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
|
||||||
|
##### Environment
|
||||||
|
|
||||||
|
Mineclonia Version: <!-- Paste the version of Mineclonia here, if you know it. -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Please refer to https://git.minetest.land/Mineclonia/Mineclonia/wiki/Reporting-Bugs
|
||||||
|
if you need help finding your Minetest version.
|
||||||
|
-->
|
||||||
|
Minetest Version:
|
|
@ -0,0 +1,22 @@
|
||||||
|
---
|
||||||
|
|
||||||
|
name: "Feature Request"
|
||||||
|
about: "Mineclonia doesn't do something you need it to"
|
||||||
|
labels:
|
||||||
|
- "feature request"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
##### Problem
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Describe what's wrong.
|
||||||
|
|
||||||
|
If you're reporting a missing feature from Minecraft,
|
||||||
|
please include a link to the Minetest wiki or Mojang bug
|
||||||
|
tracker entry describing that feature.
|
||||||
|
-->
|
||||||
|
|
||||||
|
##### Solution
|
||||||
|
|
||||||
|
<!-- Write down an example of what you'd like to happen. -->
|
|
@ -0,0 +1,51 @@
|
||||||
|
<!--
|
||||||
|
Please include the main mod this PR affects in the title, including
|
||||||
|
the leading directory. For example, if you have added a new
|
||||||
|
type of banner to mcl_banners, the title should look like:
|
||||||
|
|
||||||
|
items/mcl_banners: add new banner type
|
||||||
|
|
||||||
|
-->
|
||||||
|
##### Problem
|
||||||
|
TRACKING ISSUE: #<!-- Tracking issue number -->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Describe WHAT problem this pull request solves.
|
||||||
|
If the tracking issue includes all the needed
|
||||||
|
information, you can leave this section empty.
|
||||||
|
-->
|
||||||
|
|
||||||
|
##### Solution
|
||||||
|
|
||||||
|
<!-- Describe HOW this pull request solves its problem. -->
|
||||||
|
|
||||||
|
##### Details
|
||||||
|
|
||||||
|
<!-- Include any additional information here. -->
|
||||||
|
|
||||||
|
##### Testing Steps
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Write how we can verify this patch addresses its problem.
|
||||||
|
If you need more steps, just keep adding numbers. If you
|
||||||
|
don't need them all, delete the empty numbers.
|
||||||
|
-->
|
||||||
|
1.
|
||||||
|
2.
|
||||||
|
3.
|
||||||
|
|
||||||
|
<!--
|
||||||
|
If your pull request still needs work, uncomment the
|
||||||
|
following section and include a list of things that
|
||||||
|
need to be done before it's ready for us to look at.
|
||||||
|
|
||||||
|
Please remember to put WIP: in front of the title as well.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
##### To do
|
||||||
|
|
||||||
|
- [ ] Item 1
|
||||||
|
- [ ] Item 2
|
||||||
|
- [ ] Item 3
|
||||||
|
-->
|
|
@ -0,0 +1,102 @@
|
||||||
|
std = "min"
|
||||||
|
|
||||||
|
read_globals = {
|
||||||
|
"ItemStack",
|
||||||
|
"dump", "dump2",
|
||||||
|
"vector",
|
||||||
|
"VoxelArea",
|
||||||
|
"minetest",
|
||||||
|
"PseudoRandom",
|
||||||
|
"PerlinNoise",
|
||||||
|
"PcgRandom",
|
||||||
|
|
||||||
|
string = {fields = {"split", "trim"}},
|
||||||
|
table = {fields = {"copy", "getn", "indexof", "insert_all"}},
|
||||||
|
math = {fields = {"hypot", "round"}},
|
||||||
|
}
|
||||||
|
|
||||||
|
-- A config option to allow r/w access to mods which contain
|
||||||
|
-- this one. It only avoids a couple warnings, and may not be
|
||||||
|
-- the behavior we want, so it's disabled by default.
|
||||||
|
local allow_parents=false
|
||||||
|
|
||||||
|
local lfs = require "lfs"
|
||||||
|
|
||||||
|
-- Seed the queue with the mods/ directory
|
||||||
|
local queue={ {"mods"} }
|
||||||
|
|
||||||
|
local function check(dir)
|
||||||
|
-- Get the string of the directory path
|
||||||
|
local sdir=table.concat(dir, "/")
|
||||||
|
-- Save the top-level directory name as a
|
||||||
|
-- fallback in case there's no mod.conf,
|
||||||
|
-- or no name= directive.
|
||||||
|
local name=dir[#dir]
|
||||||
|
|
||||||
|
-- Is there a mod.conf?
|
||||||
|
if lfs.attributes(sdir.."/mod.conf", "mode") == "file" then
|
||||||
|
local deps={}
|
||||||
|
for line in io.lines(sdir.."/mod.conf") do
|
||||||
|
-- Use name= if it's there
|
||||||
|
name=string.match(line, "name *= *([a-zA-Z0-9_]+)") or name
|
||||||
|
-- Get the dependency entries (if they're there)
|
||||||
|
local ents=string.match(line, "depends *=(.*)$")
|
||||||
|
if ents then
|
||||||
|
-- Split them in to the comma-separated names
|
||||||
|
for m in string.gmatch(ents, "([a-zA-Z0-9_]+),?") do
|
||||||
|
table.insert(deps, m)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local glb={ name }
|
||||||
|
if allow_parents then
|
||||||
|
for _, v in pairs(dir) do
|
||||||
|
-- Skip ALL-CAPS names since those tend
|
||||||
|
-- to be collections of mods instead of
|
||||||
|
-- mods themselves.
|
||||||
|
if not string.match(v, "^[A-Z]+$") then
|
||||||
|
table.insert(glb, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Tell Luacheck what the directory is allowed to do
|
||||||
|
files[sdir]={
|
||||||
|
globals = glb,
|
||||||
|
read_globals = deps,
|
||||||
|
}
|
||||||
|
elseif lfs.attributes(sdir.."/init.lua", "mode") == "file" then
|
||||||
|
-- No mod.conf, but there's an init.lua here.
|
||||||
|
local glb={ name }
|
||||||
|
if allow_parents then
|
||||||
|
for _, v in pairs(dir) do
|
||||||
|
-- Again, skip ALL-CAPS.
|
||||||
|
if not string.match(v, "^[A-Z]+$") then
|
||||||
|
table.insert(glb, v)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
files[sdir]={ globals=glb }
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Queue any child directories
|
||||||
|
for d in lfs.dir(sdir) do
|
||||||
|
-- Skip hidden directories and parent/current directories.
|
||||||
|
if lfs.attributes(sdir.."/"..d, "mode") == "directory" and not string.match(d, "^%.") then
|
||||||
|
-- Copy dir in to nd (New Dir)
|
||||||
|
local nd={}
|
||||||
|
for k, v in pairs(dir) do
|
||||||
|
nd[k]=v
|
||||||
|
end
|
||||||
|
nd[#nd+1]=d
|
||||||
|
table.insert(queue, nd)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
while #queue > 0 do
|
||||||
|
-- Pop an entry and process it.
|
||||||
|
check(table.remove(queue, 1))
|
||||||
|
end
|
4
API.md
4
API.md
|
@ -17,6 +17,10 @@ Items can have these fields:
|
||||||
anvil.
|
anvil.
|
||||||
See `mcl_banners` for an example.
|
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:
|
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
|
* `_mcl_hardness`: Hardness of the block, ranges from 0 to infinity (represented by -1). Determines digging times. Default: 0
|
||||||
|
|
|
@ -21,7 +21,7 @@ The basic digging time groups determine by which tools a node can be dug.
|
||||||
* `swordy=1`: Diggable by sword (any material), and this node is *not* a cobweb
|
* `swordy=1`: Diggable by sword (any material), and this node is *not* a cobweb
|
||||||
* `swordy_cobweb=1`: Diggable by sword (any material), and this node is a cobweb
|
* `swordy_cobweb=1`: Diggable by sword (any material), and this node is a cobweb
|
||||||
* `shearsy=1`: Diggable by shears, and this node is *not* wool
|
* `shearsy=1`: Diggable by shears, and this node is *not* wool
|
||||||
* `shearsy=wool=1`: Diggable by shears, and this node is wool
|
* `shearsy_wool=1`: Diggable by shears, and this node is wool
|
||||||
* `handy=1`: Breakable by hand and this node gives it useful drop when dug by hand. All nodes which are breakable by pickaxe, axe, shovel, sword or shears are also automatically breakable by hand, but not neccess
|
* `handy=1`: Breakable by hand and this node gives it useful drop when dug by hand. All nodes which are breakable by pickaxe, axe, shovel, sword or shears are also automatically breakable by hand, but not neccess
|
||||||
* `creative_breakable=1`: Block is breakable by hand in creative mode. This group is implied if the node belongs to any other digging group
|
* `creative_breakable=1`: Block is breakable by hand in creative mode. This group is implied if the node belongs to any other digging group
|
||||||
|
|
||||||
|
@ -149,7 +149,7 @@ These groups are used mostly for informational purposes
|
||||||
* `trapdoor=2`: Open trapdoor
|
* `trapdoor=2`: Open trapdoor
|
||||||
* `glass=1`: Glass (full cubes only)
|
* `glass=1`: Glass (full cubes only)
|
||||||
* `rail=1`: Rail
|
* `rail=1`: Rail
|
||||||
* `music_record`: Music Disc (rating is track ID)
|
* `music_record=1`: Music Disc
|
||||||
* `tnt=1`: Block is TNT
|
* `tnt=1`: Block is TNT
|
||||||
* `boat=1`: Boat
|
* `boat=1`: Boat
|
||||||
* `minecart=1`: Minecart
|
* `minecart=1`: Minecart
|
||||||
|
@ -182,6 +182,10 @@ These groups are used mostly for informational purposes
|
||||||
* `redstone_torch=1`: Redstone Torch (lit)
|
* `redstone_torch=1`: Redstone Torch (lit)
|
||||||
* `redstone_torch=2`: Redstone Torch (unlit)
|
* `redstone_torch=2`: Redstone Torch (unlit)
|
||||||
|
|
||||||
|
* `dirt=1`: Uncovered dirt
|
||||||
|
* `dirt=2`: Covered dirt (grass or mycelium or podzol on top)
|
||||||
|
* `dirt=3`: Coarse dirt
|
||||||
|
|
||||||
* `plant=1`: Plant or part of a plant
|
* `plant=1`: Plant or part of a plant
|
||||||
* `double_plant`: Part of a double-sized plant. 1 = lower part, 2 = upper part
|
* `double_plant`: Part of a double-sized plant. 1 = lower part, 2 = upper part
|
||||||
|
|
||||||
|
|
43
README.md
43
README.md
|
@ -1,5 +1,5 @@
|
||||||
# MineClone 2
|
# Mineclonia
|
||||||
An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils.
|
An unofficial Minecraft-like game for Minetest. Forked from MineClone2.
|
||||||
Developed by many people. Not developed or endorsed by Mojang AB.
|
Developed by many people. Not developed or endorsed by Mojang AB.
|
||||||
|
|
||||||
Version: 0.71.0
|
Version: 0.71.0
|
||||||
|
@ -74,24 +74,24 @@ These items do not work yet, but you can get them with `/giveme` for testing:
|
||||||
* Minecart with Command Block: `mcl_minecarts:command_block_minecart`
|
* Minecart with Command Block: `mcl_minecarts:command_block_minecart`
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
This game requires [Minetest](http://minetest.net) to run (version 5.0.0 or
|
This game requires [Minetest](http://minetest.net) to run (version 5.4.0 or
|
||||||
later). So you need to install Minetest first. Only stable versions of Minetest
|
later). So you need to install Minetest first. Only stable versions of Minetest
|
||||||
are officially supported.
|
are officially supported.
|
||||||
There is no support for running MineClone 2 in development versions of Minetest.
|
There is no support for running Mineclonia in development versions of Minetest.
|
||||||
|
|
||||||
To install MineClone 2 (if you haven't already), move this directory into the
|
To install Mineclonia (if you haven't already), move this directory into the
|
||||||
“games” directory of your Minetest data directory. Consult the help of
|
“games” directory of your Minetest data directory. Consult the help of
|
||||||
Minetest to learn more.
|
Minetest to learn more.
|
||||||
|
|
||||||
## Project description
|
## Project description
|
||||||
The main goal of **MineClone 2** is to be a clone of Minecraft and to be released as free software.
|
The main goal of **Mineclonia** is to be a clone of Minecraft and to be released as free software.
|
||||||
|
|
||||||
* **Target of development: Minecraft, PC Edition, version 1.12** (later known as “Java Edition”)
|
* **Target of development: Minecraft, PC Edition, version 1.12** (later known as “Java Edition”)
|
||||||
* MineClone2 also includes Optifine features supported by the Minetest
|
* Mineclonia also includes Optifine features supported by the Minetest
|
||||||
* Features of later Minecraft versions might sneak in, but they have a low priority
|
* Features of later Minecraft versions might sneak in, but they have a low priority
|
||||||
* In general, Minecraft is aimed to be cloned as good as Minetest currently permits (no hacks)
|
* In general, Minecraft is aimed to be cloned as good as Minetest currently permits (no hacks)
|
||||||
* Cloning the gameplay has highest priority
|
* Cloning the gameplay has highest priority
|
||||||
* MineClone 2 will use different graphics and sounds, but with a similar style
|
* Mineclonia will use different graphics and sounds, but with a similar style
|
||||||
* Cloning the interface has no priority. It will only be roughly imitated
|
* Cloning the interface has no priority. It will only be roughly imitated
|
||||||
* Limitations found in Minetest will be written down and reported in the course of development
|
* Limitations found in Minetest will be written down and reported in the course of development
|
||||||
|
|
||||||
|
@ -178,18 +178,18 @@ Technical differences from Minecraft:
|
||||||
* Different sounds (various sources)
|
* Different sounds (various sources)
|
||||||
* Different engine (Minetest)
|
* Different engine (Minetest)
|
||||||
|
|
||||||
… and finally, MineClone 2 is free software (“free” as in “freedom”)!
|
… and finally, Mineclonia is free software (“free” as in “freedom”)!
|
||||||
|
|
||||||
## Reporting bugs
|
## Reporting bugs
|
||||||
Please report all bugs and missing Minecraft features here:
|
Please report all bugs and missing Minecraft features here:
|
||||||
|
|
||||||
<https://git.minetest.land/MineClone2/MineClone2/issues>
|
<https://git.minetest.land/Mineclonia/Mineclonia/issues>
|
||||||
|
|
||||||
## Other readme files
|
## Other readme files
|
||||||
|
|
||||||
* `LICENSE.txt`: The GPLv3 license text
|
* `LICENSE.txt`: The GPLv3 license text
|
||||||
* `CONTRIBUTING.md`: Information for those who want to contribute
|
* `CONTRIBUTING.md`: Information for those who want to contribute
|
||||||
* `MISSING_ENGINE_FEATURES.md`: List of missing features in Minetest which MineClone 2 would need for improvement
|
* `MISSING_ENGINE_FEATURES.md`: List of missing features in Minetest which Mineclonia would need for improvement
|
||||||
* `API.md`: For Minetest modders who want to mod this game
|
* `API.md`: For Minetest modders who want to mod this game
|
||||||
|
|
||||||
## Credits
|
## Credits
|
||||||
|
@ -197,15 +197,15 @@ There are so many people to list (sorry). Check out the respective mod directori
|
||||||
|
|
||||||
### Coding
|
### Coding
|
||||||
* [Wuzzy](https://forum.minetest.net/memberlist.php?mode=viewprofile&u=3082): Main programmer of most mods (retired)
|
* [Wuzzy](https://forum.minetest.net/memberlist.php?mode=viewprofile&u=3082): Main programmer of most mods (retired)
|
||||||
* davedevils: Creator of MineClone on which MineClone 2 is based on
|
* davedevils: Creator of MineClone on which Mineclonia is based on
|
||||||
* [ex-bart](https://github.com/ex-bart): Redstone comparators
|
* [ex-bart](https://github.com/ex-bart): Redstone comparators
|
||||||
* [Rootyjr](https://github.com/Rootyjr): Fishing rod and bugfixes
|
* [Rootyjr](https://github.com/Rootyjr): Fishing rod and bugfixes
|
||||||
* [aligator](https://github.com/aligator): Improvement of doors
|
* [aligator](https://github.com/aligator): Improvement of doors
|
||||||
* [ryvnf](https://github.com/ryvnf): Explosion mechanics
|
* [ryvnf](https://github.com/ryvnf): Explosion mechanics
|
||||||
* MysticTempest: Bugfixes
|
* MysticTempest: Bugfixes
|
||||||
* [bzoss](https://github.com/bzoss): Status effects, potions, brewing stand
|
* [bzoss](https://github.com/bzoss): Status effects, potions, brewing stand
|
||||||
* kay27 <kay27@bk.ru>: Experience system, bugfixes, optimizations (Current maintainer)
|
* kay27 <kay27@bk.ru>: Experience system, bugfixes, optimizations
|
||||||
* [EliasFleckenstein03](https://github.com/EliasFleckenstein03): End crystals, enchanting, burning mobs / players, animated chests, bugfixes (Current maintainer)
|
* [EliasFleckenstein03](https://github.com/EliasFleckenstein03): End crystals, enchanting, burning mobs / players, animated chests, bugfixes
|
||||||
* epCode: Better player animations, new logo
|
* epCode: Better player animations, new logo
|
||||||
* 2mac: Fix bug with powered rail
|
* 2mac: Fix bug with powered rail
|
||||||
* Lots of other people: TO BE WRITTEN (see mod directories for details)
|
* Lots of other people: TO BE WRITTEN (see mod directories for details)
|
||||||
|
@ -255,7 +255,7 @@ Various sources. See the respective mod directories for details.
|
||||||
* davedevils for starting MineClone, the original version of this game
|
* davedevils for starting MineClone, the original version of this game
|
||||||
* Wuzzy for starting and maintaining MineClone2 for several years
|
* Wuzzy for starting and maintaining MineClone2 for several years
|
||||||
* celeron55 for creating Minetest
|
* celeron55 for creating Minetest
|
||||||
* Minetest's modding community for providing a huge selection of mods, some of which ended up in MineClone 2
|
* Minetest's modding community for providing a huge selection of mods, some of which ended up in Mineclonia
|
||||||
* Jordach for the jukebox music compilation from Big Freaking Dig
|
* Jordach for the jukebox music compilation from Big Freaking Dig
|
||||||
* The workaholics who spent way too much time writing for the Minecraft Wiki. It's an invaluable resource for creating this game
|
* The workaholics who spent way too much time writing for the Minecraft Wiki. It's an invaluable resource for creating this game
|
||||||
* Notch and Jeb for being the major forces behind Minecraft
|
* Notch and Jeb for being the major forces behind Minecraft
|
||||||
|
@ -273,10 +273,9 @@ Copying is an act of love. Please copy and share! <3
|
||||||
Here's the detailed legalese for those who need it:
|
Here's the detailed legalese for those who need it:
|
||||||
|
|
||||||
### License of source code
|
### License of source code
|
||||||
MineClone 2 (by kay27, EliasFleckenstein, Wuzzy, davedevils and countless others)
|
Mineclonia is an imitation of Minecraft.
|
||||||
is an imitation of Minecraft.
|
|
||||||
|
|
||||||
MineClone 2 is free software: you can redistribute it and/or modify
|
Mineclonia is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
(at your option) any later version.
|
(at your option) any later version.
|
||||||
|
@ -290,15 +289,15 @@ details.
|
||||||
In the mods you might find in the read-me or license
|
In the mods you might find in the read-me or license
|
||||||
text files a different license. This counts as dual-licensing.
|
text files a different license. This counts as dual-licensing.
|
||||||
You can choose which license applies to you: Either the
|
You can choose which license applies to you: Either the
|
||||||
license of MineClone 2 (GNU GPLv3) or the mod's license.
|
license of Mineclonia (GNU GPLv3) or the mod's license.
|
||||||
|
|
||||||
MineClone 2 is a direct continuation of the discontinued MineClone
|
Mineclonia is a continuation of the discontinued MineClone project by davedevils
|
||||||
project by davedevils.
|
and the MineClone2 project by Wuzzy.
|
||||||
|
|
||||||
Mod credits:
|
Mod credits:
|
||||||
See `README.txt` or `README.md` in each mod directory for information about other authors.
|
See `README.txt` or `README.md` in each mod directory for information about other authors.
|
||||||
For mods that do not have such a file, the license is the source code license
|
For mods that do not have such a file, the license is the source code license
|
||||||
of MineClone 2 and the author is Wuzzy.
|
of Mineclonia and the author is Wuzzy.
|
||||||
|
|
||||||
### License of media (textures and sounds)
|
### License of media (textures and sounds)
|
||||||
No non-free licenses are used anywhere.
|
No non-free licenses are used anywhere.
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
name = MineClone 2
|
name = Mineclonia
|
||||||
description = A survival sandbox game. Survive, gather, hunt, build, explore, and do much more.
|
description = A survival sandbox game. Survive, gather, hunt, build, explore, and do much more.
|
||||||
|
|
BIN
menu/header.png
BIN
menu/header.png
Binary file not shown.
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 20 KiB |
BIN
menu/icon.png
BIN
menu/icon.png
Binary file not shown.
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 4.9 KiB |
|
@ -0,0 +1,29 @@
|
||||||
|
#!/bin/sh
|
||||||
|
set -eu
|
||||||
|
|
||||||
|
SVG_FILE=${2%.png}.svg
|
||||||
|
|
||||||
|
# How crisp a Minetest menu icon appears is influenced by image height
|
||||||
|
# and width. Low resolutions lead to blurry edges, as Minetest scales
|
||||||
|
# menu icons up. High resolutions lead to jagged edges, as Minetest
|
||||||
|
# scales menu icons down. Height & width of 72 pixes seem to work.
|
||||||
|
#
|
||||||
|
# Though usually one would export directly to "${3}", Inkscape 1.0 had
|
||||||
|
# its command line options changed by people who apparently think that
|
||||||
|
# backwards compatibility is some kind of swear word: Whereas earlier
|
||||||
|
# Inkscape versions would export to a file called foo.png.tmp, newer
|
||||||
|
# behaviour is to ignore the user's wishes & write to foo.png.png –
|
||||||
|
# unless one asks it to write to a filename with a .png extension,
|
||||||
|
# Inkscape 1.0 changes the filename extension to .png each time.
|
||||||
|
#
|
||||||
|
# As we do not know the extension of "${3}", we have to use the
|
||||||
|
# extension, then rename the resulting file to the proper name;
|
||||||
|
# only that way the export works with Inkscape 1.0 & earlier …
|
||||||
|
>&2 inkscape \
|
||||||
|
--file="${SVG_FILE}" \
|
||||||
|
--export-png="${3}".png \
|
||||||
|
--export-area-page \
|
||||||
|
--export-height 72 \
|
||||||
|
--export-width 72 \
|
||||||
|
|
||||||
|
mv "${3}".png "${3}"
|
File diff suppressed because it is too large
Load Diff
After Width: | Height: | Size: 509 KiB |
|
@ -4,6 +4,11 @@ Specifically, this mod has 2 purposes:
|
||||||
1) Automatically adding the group “solid” for blocks considered “solid” in Minecraft.
|
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)
|
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.
|
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.
|
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,169 +1,365 @@
|
||||||
--[[ 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
|
1) The block's hardness
|
||||||
2) The tool being used
|
2) The tool being used (the tool speed and its efficiency level)
|
||||||
3) Whether the tool is considered as “eligible” for the block
|
3) Whether the tool is considered as "eligible" for the block
|
||||||
(e.g. only diamond pick eligible for obsidian)
|
(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).
|
See Minecraft Wiki <http://minecraft.gamepedia.com/Minecraft_Wiki> for more
|
||||||
The nodes are also required to specify the “eligible” tools in groups like “pickaxey”, “shovely”, etc.
|
information.
|
||||||
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.
|
|
||||||
|
|
||||||
Example:
|
How the mod is used
|
||||||
mcl_autogroup.digtimes.pickaxey_dig_diamond[1] = 0.2
|
===================
|
||||||
|
|
||||||
→ This means that when a node has been assigned the group “pickaxey_dig_diamond=1”, it can be dug by the
|
In MineClone 2, all diggable nodes have the hardness set in the custom field
|
||||||
diamond pickaxe in 0.2 seconds.
|
"_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
|
Nodes indicate that they belong to a particular digging group by being member of
|
||||||
a single tool needs to use. If this is not being done, the loading time will increase considerably
|
the digging group in their node definition. "mcl_core:dirt" for example has
|
||||||
(>10s).
|
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" }
|
_mcl_diggroups = {
|
||||||
local basegroups = { "pickaxey", "axey", "shovely" }
|
handy = { speed = 1, level = 1, uses = 0 },
|
||||||
local minigroups = { "handy", "shearsy", "swordy", "shearsy_wool", "swordy_cobweb" }
|
pickaxey = { speed = 1, level = 0, uses = 0 },
|
||||||
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_autogroup = {}
|
The "uses" field indicate how many uses (0 for infinite) a tool has when used on
|
||||||
mcl_autogroup.digtimes = {}
|
the specified digging group. The "speed" field is a multiplier to the dig speed
|
||||||
mcl_autogroup.creativetimes = {} -- Copy of digtimes, except that all values are 0. Used for creative mode
|
on that digging group.
|
||||||
|
|
||||||
for m=1, #materials do
|
The "level" field indicates which levels of the group the tool can harvest. A
|
||||||
for g=1, #basegroups do
|
level of 0 means that the tool cannot harvest blocks of that node. A level of 1
|
||||||
mcl_autogroup.digtimes[basegroups[g].."_dig_"..materials[m]] = {}
|
or above means that the tool can harvest nodes with that level or below. See
|
||||||
mcl_autogroup.creativetimes[basegroups[g].."_dig_"..materials[m]] = {}
|
"mcl_tools/init.lua" for examples on how "_mcl_diggroups" is used in practice.
|
||||||
for e=1, max_efficiency_level do
|
|
||||||
mcl_autogroup.digtimes[basegroups[g].."_dig_"..materials[m].."_efficiency_"..e] = {}
|
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
|
||||||
|
|
||||||
|
-- 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)
|
||||||
|
if not groupcaps_def then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
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
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
for g=1, #minigroups do
|
|
||||||
mcl_autogroup.digtimes[minigroups[g].."_dig"] = {}
|
-- Checks if the given node would drop its useful drop if dug by a given tool.
|
||||||
mcl_autogroup.creativetimes[minigroups[g].."_dig"] = {}
|
-- Returns true if it will yield its useful drop, false otherwise.
|
||||||
for e=1, max_efficiency_level do
|
function mcl_autogroup.can_harvest(nodename, toolname)
|
||||||
mcl_autogroup.digtimes[minigroups[g].."_dig_efficiency_"..e] = {}
|
local ndef = minetest.registered_nodes[nodename]
|
||||||
mcl_autogroup.creativetimes[minigroups[g].."_dig_efficiency_"..e] = {}
|
|
||||||
|
if not ndef then
|
||||||
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
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
|
end
|
||||||
|
|
||||||
local overwrite = function()
|
local overwrite = function()
|
||||||
for nname, ndef in pairs(minetest.registered_nodes) do
|
for nname, ndef in pairs(minetest.registered_nodes) do
|
||||||
local groups_changed = false
|
|
||||||
local newgroups = table.copy(ndef.groups)
|
local newgroups = table.copy(ndef.groups)
|
||||||
if (nname ~= "ignore" and ndef.diggable) then
|
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)
|
if (ndef.walkable == nil or ndef.walkable == true)
|
||||||
and (ndef.collision_box == nil or ndef.collision_box.type == "regular")
|
and (ndef.collision_box == nil or ndef.collision_box.type == "regular")
|
||||||
and (ndef.node_box == nil or ndef.node_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
|
and (ndef.groups.not_solid == 0 or ndef.groups.not_solid == nil) then
|
||||||
newgroups.solid = 1
|
newgroups.solid = 1
|
||||||
groups_changed = true
|
|
||||||
end
|
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
|
if (not (ndef.paramtype == "light" or ndef.sunlight_propagates)) and
|
||||||
(ndef.groups.not_opaque == 0 or ndef.groups.not_opaque == nil) then
|
(ndef.groups.not_opaque == 0 or ndef.groups.not_opaque == nil) then
|
||||||
newgroups.opaque = 1
|
newgroups.opaque = 1
|
||||||
groups_changed = true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function calculate_group(hardness, material, diggroup, newgroups, actual_rating, expected_rating, efficiency)
|
local creative_breakable = false
|
||||||
local time, validity_factor
|
|
||||||
if actual_rating >= expected_rating then
|
|
||||||
-- Valid tool
|
|
||||||
validity_factor = 1.5
|
|
||||||
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
|
-- Assign groups used for digging this node depending on
|
||||||
local hardness = ndef._mcl_hardness
|
-- the registered digging groups
|
||||||
if not hardness then
|
for g, gdef in pairs(mcl_autogroup.registered_diggroups) do
|
||||||
hardness = 0
|
creative_breakable = true
|
||||||
end
|
local index = hardness_lookup[g][ndef._mcl_hardness or 0]
|
||||||
|
if ndef.groups[g] then
|
||||||
|
if gdef.levels then
|
||||||
|
newgroups[g .. "_dig_default"] = index
|
||||||
|
|
||||||
-- Handle pickaxey, axey and shovely
|
for i = ndef.groups[g], #gdef.levels do
|
||||||
for _, basegroup in pairs(basegroups) do
|
newgroups[g .. "_dig_" .. gdef.levels[i]] = index
|
||||||
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
|
end
|
||||||
groups_changed = true
|
else
|
||||||
end
|
newgroups[g .. "_dig"] = index
|
||||||
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
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if groups_changed then
|
-- Automatically assign the node to the
|
||||||
minetest.override_item(nname, {
|
-- creative_breakable group if it belongs to any digging
|
||||||
groups = newgroups
|
-- group.
|
||||||
})
|
newgroups["creative_breakable"] = 1
|
||||||
end
|
|
||||||
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
name = _mcl_autogroup
|
name = _mcl_autogroup
|
||||||
|
author = ryvnf
|
||||||
|
description = MineClone 2 core mod which automatically adds groups to all items. Very important for digging times.
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Adds additional ways for nodes to be attached.
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
name = mcl_attached
|
||||||
|
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,8 @@
|
||||||
|
# mcl_colors
|
||||||
|
Mod providing global table containing legacy minecraft colors to be used in mods.
|
||||||
|
|
||||||
|
## mcl_colors.*
|
||||||
|
Colors by upper name, in hex value.
|
||||||
|
|
||||||
|
## mcl_colors.background.*
|
||||||
|
Background colors by upper name, in hex value.
|
|
@ -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
|
|
@ -57,46 +57,44 @@ local function compute_sphere_rays(radius)
|
||||||
local rays = {}
|
local rays = {}
|
||||||
local sphere = {}
|
local sphere = {}
|
||||||
|
|
||||||
for i=1, 2 do
|
local function add_ray(pos)
|
||||||
|
sphere[minetest.hash_node_position(pos)] = pos
|
||||||
|
end
|
||||||
|
|
||||||
|
for y = -radius, radius do
|
||||||
|
for z = -radius, radius do
|
||||||
|
for x = -radius, 0 do
|
||||||
|
local d = x * x + y * y + z * z
|
||||||
|
if d <= radius * radius then
|
||||||
|
add_ray(vector.new(x, y, z))
|
||||||
|
add_ray(vector.new(-x, y, z))
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for x = -radius, radius do
|
||||||
|
for z = -radius, radius do
|
||||||
|
for y = -radius, 0 do
|
||||||
|
local d = x * x + y * y + z * z
|
||||||
|
if d <= radius * radius then
|
||||||
|
add_ray(vector.new(x, y, z))
|
||||||
|
add_ray(vector.new(x, -y, z))
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for x = -radius, radius do
|
||||||
for y = -radius, radius do
|
for y = -radius, radius do
|
||||||
for z = -radius, radius do
|
for z = -radius, 0 do
|
||||||
for x = -radius, 0, 1 do
|
local d = x * x + y * y + z * z
|
||||||
local d = x * x + y * y + z * z
|
if d <= radius * radius then
|
||||||
if d <= radius * radius then
|
add_ray(vector.new(x, y, z))
|
||||||
local pos = { x = x, y = y, z = z }
|
add_ray(vector.new(x, y, -z))
|
||||||
sphere[minetest.hash_node_position(pos)] = pos
|
break
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for i=1,2 do
|
|
||||||
for x = -radius, radius do
|
|
||||||
for z = -radius, radius do
|
|
||||||
for y = -radius, 0, 1 do
|
|
||||||
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
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
for i=1,2 do
|
|
||||||
for x = -radius, radius do
|
|
||||||
for y = -radius, radius do
|
|
||||||
for z = -radius, 0, 1 do
|
|
||||||
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
|
|
||||||
break
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -202,7 +200,10 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
|
||||||
npos_x - emin_x + 1
|
npos_x - emin_x + 1
|
||||||
|
|
||||||
local cid = data[idx]
|
local cid = data[idx]
|
||||||
local br = node_blastres[cid]
|
|
||||||
|
-- Set blast resistance to 0 for unknown nodes
|
||||||
|
local br = node_blastres[cid] or 0
|
||||||
|
|
||||||
if br < INDESTRUCT_BLASTRES and br > max_blast_resistance then
|
if br < INDESTRUCT_BLASTRES and br > max_blast_resistance then
|
||||||
br = max_blast_resistance
|
br = max_blast_resistance
|
||||||
end
|
end
|
||||||
|
@ -250,12 +251,12 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
|
||||||
|
|
||||||
if collisionbox then
|
if collisionbox then
|
||||||
-- Create rays from random points in the collision box
|
-- Create rays from random points in the collision box
|
||||||
local x1 = collisionbox[1] * 2
|
local x1 = collisionbox[1]
|
||||||
local y1 = collisionbox[2] * 2
|
local y1 = collisionbox[2]
|
||||||
local z1 = collisionbox[3] * 2
|
local z1 = collisionbox[3]
|
||||||
local x2 = collisionbox[4] * 2
|
local x2 = collisionbox[4]
|
||||||
local y2 = collisionbox[5] * 2
|
local y2 = collisionbox[5]
|
||||||
local z2 = collisionbox[6] * 2
|
local z2 = collisionbox[6]
|
||||||
local x_len = math.abs(x2 - x1)
|
local x_len = math.abs(x2 - x1)
|
||||||
local y_len = math.abs(y2 - y1)
|
local y_len = math.abs(y2 - y1)
|
||||||
local z_len = math.abs(z2 - z1)
|
local z_len = math.abs(z2 - z1)
|
||||||
|
|
|
@ -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.
|
|
|
@ -1 +1,2 @@
|
||||||
name = mcl_init
|
name = mcl_init
|
||||||
|
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,2 @@
|
||||||
name = mcl_loot
|
name = mcl_loot
|
||||||
|
description = API for filling a chest with random treasures.
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Contains particle images of MineClone 2. No code.
|
|
|
@ -1 +1,2 @@
|
||||||
name = mcl_particles
|
name = mcl_particles
|
||||||
|
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,2 @@
|
||||||
name = mcl_sounds
|
name = mcl_sounds
|
||||||
|
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.
|
|
|
@ -1 +1,3 @@
|
||||||
name = mcl_util
|
name = mcl_util
|
||||||
|
description = Helper functions for MineClone 2.
|
||||||
|
depends = mcl_init
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
mcl_init
|
|
|
@ -1 +0,0 @@
|
||||||
Utility functions for worlds and the “dimensions”.
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
name = mcl_worlds
|
||||||
|
description = Utility functions for worlds and the “dimensions”.
|
||||||
|
depends = mcl_init
|
|
@ -1 +0,0 @@
|
||||||
mcl_core
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
name = drippingwater
|
||||||
|
depends = mcl_core
|
|
@ -1,3 +0,0 @@
|
||||||
mcl_player
|
|
||||||
mcl_core?
|
|
||||||
doc_identifier?
|
|
|
@ -1 +0,0 @@
|
||||||
Adds drivable boats.
|
|
|
@ -243,7 +243,7 @@ function boat.on_step(self, dtime, moveresult)
|
||||||
else
|
else
|
||||||
local ctrl = self._passenger:get_player_control()
|
local ctrl = self._passenger:get_player_control()
|
||||||
if ctrl and ctrl.sneak then
|
if ctrl and ctrl.sneak then
|
||||||
detach_player(self._passenger, true)
|
detach_object(self._passenger, true)
|
||||||
self._passenger = nil
|
self._passenger = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = mcl_boats
|
name = mcl_boats
|
||||||
|
description = Adds drivable boats.
|
||||||
|
depends = mcl_player
|
||||||
|
optional_depends = mcl_core, doc_identifier
|
||||||
|
|
|
@ -155,6 +155,16 @@ function mcl_burning.set_on_fire(obj, burn_time, reason)
|
||||||
}) + 1
|
}) + 1
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local already_burning = mcl_burning.is_burning(obj)
|
||||||
|
|
||||||
|
|
||||||
|
mcl_burning.set(obj, "float", "burn_time", burn_time)
|
||||||
|
mcl_burning.set(obj, "string", "reason", reason)
|
||||||
|
|
||||||
|
if already_burning then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local hud_id
|
local hud_id
|
||||||
if obj:is_player() then
|
if obj:is_player() then
|
||||||
hud_id = mcl_burning.get(obj, "int", "hud_id")
|
hud_id = mcl_burning.get(obj, "int", "hud_id")
|
||||||
|
@ -168,8 +178,7 @@ function mcl_burning.set_on_fire(obj, burn_time, reason)
|
||||||
}) + 1
|
}) + 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
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", "hud_id", hud_id)
|
||||||
mcl_burning.set(obj, "int", "sound_id", sound_id)
|
mcl_burning.set(obj, "int", "sound_id", sound_id)
|
||||||
|
|
||||||
|
@ -285,7 +294,7 @@ function mcl_burning.fire_entity_step(self, dtime)
|
||||||
end
|
end
|
||||||
|
|
||||||
local animation_timer = self.animation_timer + dtime
|
local animation_timer = self.animation_timer + dtime
|
||||||
if animation_timer >= 0.015 then
|
if animation_timer >= ( 1 / mcl_burning.animation_fps ) then
|
||||||
animation_timer = 0
|
animation_timer = 0
|
||||||
local animation_frame = self.animation_frame + 1
|
local animation_frame = self.animation_frame + 1
|
||||||
if animation_frame > mcl_burning.animation_frames - 1 then
|
if animation_frame > mcl_burning.animation_frames - 1 then
|
||||||
|
@ -296,3 +305,48 @@ function mcl_burning.fire_entity_step(self, dtime)
|
||||||
end
|
end
|
||||||
self.animation_timer = animation_timer
|
self.animation_timer = animation_timer
|
||||||
end
|
end
|
||||||
|
|
||||||
|
minetest.register_chatcommand("burn", {
|
||||||
|
params = S("<playername> <duration> <reason>"),
|
||||||
|
description = S("Sets a player on fire for the given amount of seconds with the given reason."),
|
||||||
|
privs = { debug = true },
|
||||||
|
func = function(name, params)
|
||||||
|
local playername, duration, reason = params:match("^(.+) (.+) (.+)$")
|
||||||
|
if not (playername and duration and reason) then
|
||||||
|
return false, S("Error: Parameter missing.")
|
||||||
|
end
|
||||||
|
local player = minetest.get_player_by_name(playername)
|
||||||
|
if not player then
|
||||||
|
return false, S(
|
||||||
|
"Error: Player “@1” not found.",
|
||||||
|
playername
|
||||||
|
)
|
||||||
|
end
|
||||||
|
local duration_number = tonumber(duration)
|
||||||
|
-- Lua numbers are truthy
|
||||||
|
-- NaN is not equal to NaN
|
||||||
|
if not duration_number or (duration_number ~= duration_number) then
|
||||||
|
return false, S(
|
||||||
|
"Error: Duration “@1” is not a number.",
|
||||||
|
duration
|
||||||
|
)
|
||||||
|
end
|
||||||
|
if duration_number < 0 then
|
||||||
|
return false, S(
|
||||||
|
"Error: Duration “@1” is negative.",
|
||||||
|
duration
|
||||||
|
)
|
||||||
|
end
|
||||||
|
mcl_burning.set_on_fire(
|
||||||
|
player,
|
||||||
|
duration_number,
|
||||||
|
reason
|
||||||
|
)
|
||||||
|
return true, S(
|
||||||
|
"Set @1 on fire for @2s for the following reason: @3",
|
||||||
|
playername,
|
||||||
|
duration,
|
||||||
|
reason
|
||||||
|
)
|
||||||
|
end,
|
||||||
|
})
|
||||||
|
|
|
@ -2,7 +2,8 @@ local S = minetest.get_translator("mcl_burning")
|
||||||
local modpath = minetest.get_modpath("mcl_burning")
|
local modpath = minetest.get_modpath("mcl_burning")
|
||||||
|
|
||||||
mcl_burning = {
|
mcl_burning = {
|
||||||
animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8
|
animation_frames = tonumber(minetest.settings:get("fire_animation_frames")) or 8,
|
||||||
|
animation_fps = tonumber(minetest.settings:get("fire_animation_fps")) or 30
|
||||||
}
|
}
|
||||||
|
|
||||||
dofile(modpath .. "/api.lua")
|
dofile(modpath .. "/api.lua")
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Falling node entities, Minecraft-style
|
|
|
@ -1 +1,2 @@
|
||||||
name = mcl_falling_nodes
|
name = mcl_falling_nodes
|
||||||
|
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.
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
local S = minetest.get_translator("mcl_item_entity")
|
||||||
--basic settings
|
--basic settings
|
||||||
local item_drop_settings = {} --settings table
|
local item_drop_settings = {} --settings table
|
||||||
item_drop_settings.age = 1.0 --how old a dropped item (_insta_collect==false) has to be before collecting
|
item_drop_settings.age = 1.0 --how old a dropped item (_insta_collect==false) has to be before collecting
|
||||||
|
@ -165,66 +166,6 @@ minetest.register_globalstep(function(dtime)
|
||||||
end
|
end
|
||||||
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:
|
-- Stupid workaround to get drops from a drop table:
|
||||||
-- Create a temporary table in minetest.registered_nodes that contains the proper drops,
|
-- 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
|
-- because unfortunately minetest.get_node_drops needs the drop table to be inside a registered node definition
|
||||||
|
@ -281,17 +222,20 @@ function minetest.handle_node_drops(pos, drops, digger)
|
||||||
|
|
||||||
-- Check if node will yield its useful drop by the digger's tool
|
-- Check if node will yield its useful drop by the digger's tool
|
||||||
local dug_node = minetest.get_node(pos)
|
local dug_node = minetest.get_node(pos)
|
||||||
local toolcaps
|
local tooldef
|
||||||
local tool
|
local tool
|
||||||
if digger ~= nil then
|
if digger ~= nil then
|
||||||
tool = digger:get_wielded_item()
|
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
|
return
|
||||||
end
|
end
|
||||||
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
|
--[[ 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.
|
from the node definition.
|
||||||
Definition of _mcl_shears_drop / _mcl_silk_touch_drop:
|
Definition of _mcl_shears_drop / _mcl_silk_touch_drop:
|
||||||
|
@ -303,7 +247,7 @@ function minetest.handle_node_drops(pos, drops, digger)
|
||||||
|
|
||||||
local silk_touch_drop = false
|
local silk_touch_drop = false
|
||||||
local nodedef = minetest.registered_nodes[dug_node.name]
|
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
|
if nodedef._mcl_shears_drop == true then
|
||||||
drops = { dug_node.name }
|
drops = { dug_node.name }
|
||||||
else
|
else
|
||||||
|
@ -505,7 +449,7 @@ minetest.register_entity(":__builtin:item", {
|
||||||
end,
|
end,
|
||||||
|
|
||||||
get_staticdata = function(self)
|
get_staticdata = function(self)
|
||||||
return minetest.serialize({
|
local data = minetest.serialize({
|
||||||
itemstring = self.itemstring,
|
itemstring = self.itemstring,
|
||||||
always_collect = self.always_collect,
|
always_collect = self.always_collect,
|
||||||
age = self.age,
|
age = self.age,
|
||||||
|
@ -513,6 +457,39 @@ minetest.register_entity(":__builtin:item", {
|
||||||
_flowing = self._flowing,
|
_flowing = self._flowing,
|
||||||
_removed = self._removed,
|
_removed = self._removed,
|
||||||
})
|
})
|
||||||
|
-- sfan5 guessed that the biggest serializable item
|
||||||
|
-- entity would have a size of 65530 bytes. This has
|
||||||
|
-- been experimentally verified to be still too large.
|
||||||
|
--
|
||||||
|
-- anon5 has calculated that the biggest serializable
|
||||||
|
-- item entity has a size of exactly 65487 bytes:
|
||||||
|
--
|
||||||
|
-- 1. serializeString16 can handle max. 65535 bytes.
|
||||||
|
-- 2. The following engine metadata is always saved:
|
||||||
|
-- • 1 byte (version)
|
||||||
|
-- • 2 byte (length prefix)
|
||||||
|
-- • 14 byte “__builtin:item”
|
||||||
|
-- • 4 byte (length prefix)
|
||||||
|
-- • 2 byte (health)
|
||||||
|
-- • 3 × 4 byte = 12 byte (position)
|
||||||
|
-- • 4 byte (yaw)
|
||||||
|
-- • 1 byte (version 2)
|
||||||
|
-- • 2 × 4 byte = 8 byte (pitch and roll)
|
||||||
|
-- 3. This leaves 65487 bytes for the serialization.
|
||||||
|
if #data > 65487 then -- would crash the engine
|
||||||
|
local stack = ItemStack(self.itemstring)
|
||||||
|
stack:get_meta():from_table(nil)
|
||||||
|
self.itemstring = stack:to_string()
|
||||||
|
minetest.log(
|
||||||
|
"warning",
|
||||||
|
"Overlong item entity metadata removed: “" ..
|
||||||
|
self.itemstring ..
|
||||||
|
"” had serialized length of " ..
|
||||||
|
#data
|
||||||
|
)
|
||||||
|
return self:get_staticdata()
|
||||||
|
end
|
||||||
|
return data
|
||||||
end,
|
end,
|
||||||
|
|
||||||
on_activate = function(self, staticdata, dtime_s)
|
on_activate = function(self, staticdata, dtime_s)
|
||||||
|
@ -805,3 +782,29 @@ minetest.register_entity(":__builtin:item", {
|
||||||
|
|
||||||
-- Note: on_punch intentionally left out. The player should *not* be able to collect items by punching
|
-- Note: on_punch intentionally left out. The player should *not* be able to collect items by punching
|
||||||
})
|
})
|
||||||
|
|
||||||
|
-- The “getwrittenbook” command was added as a debug aid. It can help
|
||||||
|
-- reproducing situations in which items with lots of metadata trigger
|
||||||
|
-- issues like heavy lag or server crashes. Do not remove this command
|
||||||
|
-- unless another easy way of getting items with overlong meta exists!
|
||||||
|
--
|
||||||
|
-- “/getwrittenbook 65323” creates an item that creates the largest
|
||||||
|
-- possible serializable written book item entity when dropped.
|
||||||
|
--
|
||||||
|
-- “/getwrittenbook 65324” creates an item that creates the smallest
|
||||||
|
-- possible non-serializable written book item entity when dropped.
|
||||||
|
minetest.register_chatcommand("getwrittenbook", {
|
||||||
|
params = S("<Count>"),
|
||||||
|
description = S("Get a written book with a configurable amount of characters."),
|
||||||
|
privs = {debug=true},
|
||||||
|
func = function(name, param)
|
||||||
|
local count = tonumber(param)
|
||||||
|
local itemstack = ItemStack("mcl_books:written_book")
|
||||||
|
local meta = itemstack:get_meta()
|
||||||
|
meta:set_string("description", "")
|
||||||
|
meta:set_string("text", string.rep("x", count))
|
||||||
|
local player = minetest.get_player_by_name(name)
|
||||||
|
local inv = player:get_inventory()
|
||||||
|
inv:add_item("main", itemstack)
|
||||||
|
end
|
||||||
|
})
|
||||||
|
|
|
@ -1 +1,3 @@
|
||||||
name = mcl_item_entity
|
name = mcl_item_entity
|
||||||
|
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
|
if not self._driver then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if self._driver:is_player() then
|
mcl_player.player_attached[self._driver] = nil
|
||||||
mcl_player.player_attached[self._driver:get_player_name()] = nil
|
local player = minetest.get_player_by_name(self._driver)
|
||||||
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
|
|
||||||
self._driver = nil
|
self._driver = nil
|
||||||
self._start_pos = 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
|
end
|
||||||
|
|
||||||
local function activate_tnt_minecart(self, timer)
|
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,
|
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
|
_punched = false, -- used to re-send _velocity and position
|
||||||
_velocity = {x=0, y=0, z=0}, -- only used on punch
|
_velocity = {x=0, y=0, z=0}, -- only used on punch
|
||||||
_start_pos = nil, -- Used to calculate distance for “On A Rail” achievement
|
_start_pos = nil, -- Used to calculate distance for “On A Rail” achievement
|
||||||
|
@ -96,101 +97,111 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
end
|
end
|
||||||
|
|
||||||
function cart:on_punch(puncher, time_from_last_punch, tool_capabilities, direction)
|
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
|
|
||||||
if self._driver then
|
|
||||||
detach_driver(self)
|
|
||||||
end
|
|
||||||
local pos = self.object:get_pos()
|
local pos = self.object:get_pos()
|
||||||
|
if not self._railtype then
|
||||||
-- Disable detector rail
|
local node = minetest.get_node(vector.floor(pos)).name
|
||||||
local rou_pos = vector.round(pos)
|
self._railtype = minetest.get_item_group(node, "connect_to_raillike")
|
||||||
local node = minetest.get_node(rou_pos)
|
|
||||||
if node.name == "mcl_minecarts:detector_rail_on" then
|
|
||||||
local newnode = {name="mcl_minecarts:detector_rail", param2 = node.param2}
|
|
||||||
minetest.swap_node(rou_pos, newnode)
|
|
||||||
mesecon.receptor_off(rou_pos)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Drop items and remove cart entity
|
if not puncher or not puncher:is_player() then
|
||||||
if not minetest.is_creative_enabled(puncher:get_player_name()) then
|
local cart_dir = mcl_minecarts:get_rail_direction(pos, {x=1, y=0, z=0}, nil, nil, self._railtype)
|
||||||
for d=1, #drop do
|
if vector.equals(cart_dir, {x=0, y=0, z=0}) then
|
||||||
minetest.add_item(self.object:get_pos(), drop[d])
|
return
|
||||||
end
|
end
|
||||||
elseif puncher and puncher:is_player() then
|
self._velocity = vector.multiply(cart_dir, 3)
|
||||||
local inv = puncher:get_inventory()
|
self._old_pos = nil
|
||||||
for d=1, #drop do
|
self._punched = true
|
||||||
if not inv:contains_item("main", drop[d]) then
|
return
|
||||||
inv:add_item("main", drop[d])
|
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
|
||||||
|
|
||||||
|
-- Disable detector rail
|
||||||
|
local rou_pos = vector.round(pos)
|
||||||
|
local node = minetest.get_node(rou_pos)
|
||||||
|
if node.name == "mcl_minecarts:detector_rail_on" then
|
||||||
|
local newnode = {name="mcl_minecarts:detector_rail", param2 = node.param2}
|
||||||
|
minetest.swap_node(rou_pos, newnode)
|
||||||
|
mesecon.receptor_off(rou_pos)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- Drop items and remove cart entity
|
||||||
|
if not minetest.is_creative_enabled(puncher:get_player_name()) then
|
||||||
|
for d=1, #drop do
|
||||||
|
minetest.add_item(self.object:get_pos(), drop[d])
|
||||||
|
end
|
||||||
|
elseif puncher and puncher:is_player() then
|
||||||
|
local inv = puncher:get_inventory()
|
||||||
|
for d=1, #drop do
|
||||||
|
if not inv:contains_item("main", drop[d]) then
|
||||||
|
inv:add_item("main", drop[d])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
self.object:remove()
|
||||||
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
self.object:remove()
|
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
|
end
|
||||||
|
|
||||||
cart.on_activate_by_rail = on_activate_by_rail
|
cart.on_activate_by_rail = on_activate_by_rail
|
||||||
|
|
||||||
function cart:on_step(dtime)
|
function cart:on_step(dtime)
|
||||||
local ctrl, player = nil, nil
|
local ctrl, player = nil, nil
|
||||||
local update = {}
|
if self._driver then
|
||||||
local vel = self.object:get_velocity()
|
player = minetest.get_player_by_name(self._driver)
|
||||||
local pos, rou_pos, node
|
if player then
|
||||||
pos = self.object:get_pos()
|
ctrl = player:get_player_control()
|
||||||
rou_pos = vector.round(pos)
|
-- player detach
|
||||||
node = minetest.get_node(rou_pos)
|
if ctrl.sneak then
|
||||||
local g = minetest.get_item_group(node.name, "connect_to_raillike")
|
detach_driver(self)
|
||||||
if self._driver and self._driver:is_player() then
|
return
|
||||||
player = self._driver
|
|
||||||
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
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local vel = self.object:get_velocity()
|
||||||
|
local update = {}
|
||||||
if self._last_float_check == nil then
|
if self._last_float_check == nil then
|
||||||
self._last_float_check = 0
|
self._last_float_check = 0
|
||||||
else
|
else
|
||||||
self._last_float_check = self._last_float_check + dtime
|
self._last_float_check = self._last_float_check + dtime
|
||||||
end
|
end
|
||||||
|
local pos, rou_pos, node
|
||||||
-- Drop minecart if it isn't on a rail anymore
|
-- Drop minecart if it isn't on a rail anymore
|
||||||
if self._last_float_check >= mcl_minecarts.check_float_time then
|
if self._last_float_check >= mcl_minecarts.check_float_time then
|
||||||
|
pos = self.object:get_pos()
|
||||||
|
rou_pos = vector.round(pos)
|
||||||
for _,object in pairs(minetest.get_objects_inside_radius(pos, 1.3)) do
|
node = minetest.get_node(rou_pos)
|
||||||
if object ~= self.object then
|
local g = minetest.get_item_group(node.name, "connect_to_raillike")
|
||||||
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
|
|
||||||
|
|
||||||
|
|
||||||
if g ~= self._railtype and self._railtype ~= nil then
|
if g ~= self._railtype and self._railtype ~= nil then
|
||||||
-- Detach driver
|
-- Detach driver
|
||||||
if player then
|
if player then
|
||||||
|
@ -289,12 +300,8 @@ local function register_entity(entity_id, mesh, textures, drop, on_rightclick, o
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if update.vel then
|
if self._punched then
|
||||||
vel = vector.add(vel, self._velocity)
|
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.object:set_velocity(vel)
|
||||||
self._old_dir.y = 0
|
self._old_dir.y = 0
|
||||||
elseif vector.equals(vel, {x=0, y=0, z=0}) and (not has_fuel) then
|
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_normal.png",
|
||||||
{"mcl_minecarts:minecart"},
|
{"mcl_minecarts:minecart"},
|
||||||
function(self, clicker)
|
function(self, clicker)
|
||||||
if not clicker or not clicker:is_player() then return end
|
local name = clicker:get_player_name()
|
||||||
if clicker == self._driver then
|
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)
|
detach_driver(self)
|
||||||
else
|
elseif not self._driver then
|
||||||
local name = clicker:get_player_name()
|
self._driver = player_name
|
||||||
self._driver = clicker
|
|
||||||
self._start_pos = self.object:get_pos()
|
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})
|
clicker:set_attach(self.object, "", {x=0, y=-1.75, z=-2}, {x=0, y=0, z=0})
|
||||||
mcl_player.player_attached[name] = true
|
mcl_player.player_attached[name] = true
|
||||||
minetest.after(0.2, function(name)
|
minetest.after(0.2, function(name)
|
||||||
|
@ -637,7 +647,6 @@ register_minecart(
|
||||||
mcl_tmp_message.message(clicker, S("Sneak to dismount"))
|
mcl_tmp_message.message(clicker, S("Sneak to dismount"))
|
||||||
end
|
end
|
||||||
end, name)
|
end, name)
|
||||||
clicker:set_look_horizontal(self.object:get_yaw())
|
|
||||||
end
|
end
|
||||||
end, activate_normal_minecart
|
end, activate_normal_minecart
|
||||||
)
|
)
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = mcl_minecarts
|
name = mcl_minecarts
|
||||||
|
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
|
||||||
|
optional_depends = doc_identifier
|
||||||
|
|
|
@ -14,6 +14,8 @@ local DEFAULT_FALL_SPEED = -10
|
||||||
local FLOP_HEIGHT = 5.0
|
local FLOP_HEIGHT = 5.0
|
||||||
local FLOP_HOR_SPEED = 1.5
|
local FLOP_HOR_SPEED = 1.5
|
||||||
|
|
||||||
|
local LIGHT_SUN = minetest.LIGHT_MAX + 1
|
||||||
|
|
||||||
local MOB_CAP = {}
|
local MOB_CAP = {}
|
||||||
MOB_CAP.hostile = 70
|
MOB_CAP.hostile = 70
|
||||||
MOB_CAP.passive = 10
|
MOB_CAP.passive = 10
|
||||||
|
@ -1057,7 +1059,7 @@ local do_env_damage = function(self)
|
||||||
if mod_worlds then
|
if mod_worlds then
|
||||||
_, dim = mcl_worlds.y_to_layer(pos.y)
|
_, dim = mcl_worlds.y_to_layer(pos.y)
|
||||||
end
|
end
|
||||||
if (self.sunlight_damage ~= 0 or self.ignited_by_sunlight) and (minetest.get_node_light(pos) or 0) >= minetest.LIGHT_MAX and dim == "overworld" then
|
if (self.sunlight_damage ~= 0 or self.ignited_by_sunlight) and (minetest.get_node_light(pos) or 0) == LIGHT_SUN and dim == "overworld" then
|
||||||
if self.ignited_by_sunlight then
|
if self.ignited_by_sunlight then
|
||||||
mcl_burning.set_on_fire(self.object, 10)
|
mcl_burning.set_on_fire(self.object, 10)
|
||||||
else
|
else
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Adds a mob API for mods to add animals or monsters, etc.
|
|
|
@ -1,3 +1,4 @@
|
||||||
name = mcl_mobs
|
name = mcl_mobs
|
||||||
depends = mcl_particles
|
depends = mcl_particles
|
||||||
optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, lucky_block, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience
|
optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, lucky_block, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience
|
||||||
|
description = Adds a mob API for mods to add animals or monsters, etc.
|
||||||
|
|
|
@ -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.
|
|
|
@ -28,6 +28,7 @@ Pig=Schwein
|
||||||
Polar Bear=Eisbär
|
Polar Bear=Eisbär
|
||||||
Rabbit=Kaninchen
|
Rabbit=Kaninchen
|
||||||
Killer Bunny=Killerkaninchen
|
Killer Bunny=Killerkaninchen
|
||||||
|
The Killer Bunny=Das Killerkaninchen
|
||||||
Sheep=Schaf
|
Sheep=Schaf
|
||||||
Shulker=Shulker
|
Shulker=Shulker
|
||||||
Silverfish=Silberfischchen
|
Silverfish=Silberfischchen
|
||||||
|
|
|
@ -28,6 +28,7 @@ Pig=Cerdo
|
||||||
Polar Bear=Oso polar
|
Polar Bear=Oso polar
|
||||||
Rabbit=Conejo
|
Rabbit=Conejo
|
||||||
Killer Bunny=Conejo asesino
|
Killer Bunny=Conejo asesino
|
||||||
|
The Killer Bunny=El Conejo asesino
|
||||||
Sheep=Oveja
|
Sheep=Oveja
|
||||||
Shulker=Shulker
|
Shulker=Shulker
|
||||||
Silverfish=Lepisma
|
Silverfish=Lepisma
|
||||||
|
|
|
@ -28,6 +28,7 @@ Pig=Cochon
|
||||||
Polar Bear=Ours blanc
|
Polar Bear=Ours blanc
|
||||||
Rabbit=Lapin
|
Rabbit=Lapin
|
||||||
Killer Bunny=Lapin tueur
|
Killer Bunny=Lapin tueur
|
||||||
|
The Killer Bunny=Le Lapin tueur
|
||||||
Sheep=Mouton
|
Sheep=Mouton
|
||||||
Shulker=Shulker
|
Shulker=Shulker
|
||||||
Silverfish=Poisson d'argent
|
Silverfish=Poisson d'argent
|
||||||
|
|
|
@ -28,6 +28,7 @@ Pig=Свинья
|
||||||
Polar Bear=Полярный медведь
|
Polar Bear=Полярный медведь
|
||||||
Rabbit=Кролик
|
Rabbit=Кролик
|
||||||
Killer Bunny=Кролик-убийца
|
Killer Bunny=Кролик-убийца
|
||||||
|
The Killer Bunny=Кролик-убийца
|
||||||
Sheep=Овца
|
Sheep=Овца
|
||||||
Shulker=Шалкер
|
Shulker=Шалкер
|
||||||
Silverfish=Чешуйница
|
Silverfish=Чешуйница
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = mobs_mc
|
name = mobs_mc
|
||||||
|
description = Adds Minecraft-like monsters and animals.
|
||||||
|
depends = mcl_init, mcl_particles, mcl_mobs
|
||||||
|
optional_depends = default, mcl_tnt, mcl_bows, mcl_throwing, mcl_fishing, bones, mesecons_materials, mobs_mc_gameconfig, doc_items
|
||||||
|
|
|
@ -99,7 +99,7 @@ killer_bunny.on_rightclick = nil
|
||||||
killer_bunny.run_velocity = 6
|
killer_bunny.run_velocity = 6
|
||||||
killer_bunny.do_custom = function(self)
|
killer_bunny.do_custom = function(self)
|
||||||
if not self._killer_bunny_nametag_set then
|
if not self._killer_bunny_nametag_set then
|
||||||
self.nametag = "The Killer Bunny"
|
self.nametag = S("The Killer Bunny")
|
||||||
self._killer_bunny_nametag_set = true
|
self._killer_bunny_nametag_set = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
mcl_init
|
|
||||||
mcl_core
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
name = mobs_mc_gameconfig
|
||||||
|
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.
|
|
|
@ -1 +1,4 @@
|
||||||
name = lightning
|
name = lightning
|
||||||
|
description = A mod that adds thunder and lightning effects.
|
||||||
|
depends = mcl_fire
|
||||||
|
optional_depends = mcl_death_messages
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
mcl_worlds
|
|
||||||
mcl_death_messages
|
|
|
@ -1 +0,0 @@
|
||||||
Deal damage to entities stuck in the deep void
|
|
|
@ -1 +1,3 @@
|
||||||
name = mcl_void_damage
|
name = mcl_void_damage
|
||||||
|
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,4 @@
|
||||||
name = mcl_weather
|
name = mcl_weather
|
||||||
|
description = Weather and sky handling: Rain, snow, thunderstorm, End and Nether ambience
|
||||||
|
depends = mcl_init, mcl_worlds
|
||||||
|
optional_depends = lightning
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Provides an extensible in-game help with texts about gameplay basics (such a crafting), items and advanced usage.
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
name = doc
|
||||||
|
description = Provides an extensible in-game help with texts about gameplay basics (such a crafting), items and advanced usage.
|
|
@ -1,6 +0,0 @@
|
||||||
mcl_core
|
|
||||||
mcl_compass
|
|
||||||
mcl_clock
|
|
||||||
doc
|
|
||||||
sfinv?
|
|
||||||
sfinv_buttons?
|
|
|
@ -1,2 +0,0 @@
|
||||||
The most comprehensive Crafting Guide
|
|
||||||
on Minetest.
|
|
|
@ -1 +1,5 @@
|
||||||
name = mcl_craftguide
|
name = mcl_craftguide
|
||||||
|
description = The most comprehensive Crafting Guide
|
||||||
|
on Minetest.
|
||||||
|
depends = mcl_core, mcl_compass, mcl_clock, doc
|
||||||
|
optional_depends = sfinv, sfinv_buttons
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
doc
|
|
||||||
doc_items
|
|
|
@ -1 +0,0 @@
|
||||||
This MineClone 2 mod sets up and configures the Help modpack mods to tailor the help towards MineClone 2.
|
|
|
@ -1 +1,3 @@
|
||||||
name = mcl_doc
|
name = mcl_doc
|
||||||
|
description = This MineClone 2 mod sets up and configures the Help modpack mods to tailor the help towards MineClone 2.
|
||||||
|
depends = doc, doc_items
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
tt
|
|
||||||
mcl_enchanting
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
name = mcl_tt
|
||||||
|
depends = tt, mcl_enchanting
|
|
@ -1,2 +0,0 @@
|
||||||
sfinv?
|
|
||||||
unified_inventory?
|
|
|
@ -1 +0,0 @@
|
||||||
Adds achievements to Minetest, and an API to register new ones.
|
|
|
@ -5,3 +5,4 @@ description = Adds achievements to Minetest, and an API to register new ones.
|
||||||
license = LGPL 2.1 or later
|
license = LGPL 2.1 or later
|
||||||
forum = https://forum.minetest.net/viewtopic.php?t=4870
|
forum = https://forum.minetest.net/viewtopic.php?t=4870
|
||||||
version = 2.3.0
|
version = 2.3.0
|
||||||
|
optional_depends = sfinv, unified_inventory
|
||||||
|
|
|
@ -413,6 +413,7 @@ function hb.hide_hudbar(player, identifier)
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
local hudtable = hb.get_hudtable(identifier)
|
local hudtable = hb.get_hudtable(identifier)
|
||||||
if hudtable == nil then return false end
|
if hudtable == nil then return false end
|
||||||
|
if hudtable.hudstate[name].hidden == true then return true end
|
||||||
if hb.settings.bar_type == "progress_bar" then
|
if hb.settings.bar_type == "progress_bar" then
|
||||||
if hudtable.hudids[name].icon ~= nil then
|
if hudtable.hudids[name].icon ~= nil then
|
||||||
player:hud_change(hudtable.hudids[name].icon, "scale", {x=0,y=0})
|
player:hud_change(hudtable.hudids[name].icon, "scale", {x=0,y=0})
|
||||||
|
@ -431,6 +432,7 @@ function hb.unhide_hudbar(player, identifier)
|
||||||
local name = player:get_player_name()
|
local name = player:get_player_name()
|
||||||
local hudtable = hb.get_hudtable(identifier)
|
local hudtable = hb.get_hudtable(identifier)
|
||||||
if hudtable == nil then return false end
|
if hudtable == nil then return false end
|
||||||
|
if hudtable.hudstate[name].hidden == false then return true end
|
||||||
local value = hudtable.hudstate[name].value
|
local value = hudtable.hudstate[name].value
|
||||||
local max = hudtable.hudstate[name].max
|
local max = hudtable.hudstate[name].max
|
||||||
if hb.settings.bar_type == "progress_bar" then
|
if hb.settings.bar_type == "progress_bar" then
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
awards
|
|
|
@ -1 +1,2 @@
|
||||||
name = mcl_achievements
|
name = mcl_achievements
|
||||||
|
depends = awards
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Provides core textures needed by Minetest.
|
|
|
@ -1 +1,2 @@
|
||||||
name = mcl_base_textures
|
name = mcl_base_textures
|
||||||
|
description = Provides core textures needed by Minetest.
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
Shows messages in chat when a player dies.
|
|
|
@ -3,13 +3,106 @@ local N = function(s) return s end
|
||||||
|
|
||||||
local function get_tool_name(item)
|
local function get_tool_name(item)
|
||||||
local name = item:get_meta():get_string("name")
|
local name = item:get_meta():get_string("name")
|
||||||
if name ~= "" then
|
if name == "" then
|
||||||
return name
|
local def = item:get_definition()
|
||||||
|
name=def._tt_original_description or def.description
|
||||||
end
|
end
|
||||||
local def = item:get_definition()
|
local sanitized_name, substitution_count = name:gsub("[\r\n]"," ")
|
||||||
return def._tt_original_description or def.description
|
return sanitized_name
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local test_tool_1a = {
|
||||||
|
get_meta = function()
|
||||||
|
return {
|
||||||
|
get_string = function()
|
||||||
|
return "foo 1a"
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( get_tool_name(test_tool_1a) == "foo 1a" )
|
||||||
|
|
||||||
|
local test_tool_1b = {
|
||||||
|
get_meta = function()
|
||||||
|
return {
|
||||||
|
get_string = function()
|
||||||
|
return "bar\rbaz\n1b"
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( get_tool_name(test_tool_1b) == "bar baz 1b" )
|
||||||
|
|
||||||
|
local test_tool_2a = {
|
||||||
|
get_definition = function()
|
||||||
|
return {
|
||||||
|
_tt_original_description = "foo 2a"
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
get_meta = function()
|
||||||
|
return {
|
||||||
|
get_string = function()
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( get_tool_name(test_tool_2a) == "foo 2a" )
|
||||||
|
|
||||||
|
local test_tool_2b = {
|
||||||
|
get_definition = function()
|
||||||
|
return {
|
||||||
|
_tt_original_description = "bar\rbaz\n2b"
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
get_meta = function()
|
||||||
|
return {
|
||||||
|
get_string = function()
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( get_tool_name(test_tool_2b) == "bar baz 2b" )
|
||||||
|
|
||||||
|
local test_tool_3a = {
|
||||||
|
get_definition = function()
|
||||||
|
return {
|
||||||
|
description = "foo 3a"
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
get_meta = function()
|
||||||
|
return {
|
||||||
|
get_string = function()
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( get_tool_name(test_tool_3a) == "foo 3a" )
|
||||||
|
|
||||||
|
local test_tool_3b = {
|
||||||
|
get_definition = function()
|
||||||
|
return {
|
||||||
|
description = "bar\rbaz\n3b"
|
||||||
|
}
|
||||||
|
end,
|
||||||
|
get_meta = function()
|
||||||
|
return {
|
||||||
|
get_string = function()
|
||||||
|
return ""
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
}
|
||||||
|
|
||||||
|
assert( get_tool_name(test_tool_3b) == "bar baz 3b" )
|
||||||
|
|
||||||
mcl_death_messages = {}
|
mcl_death_messages = {}
|
||||||
|
|
||||||
-- Death messages
|
-- Death messages
|
||||||
|
@ -41,6 +134,9 @@ local msgs = {
|
||||||
["murder"] = {
|
["murder"] = {
|
||||||
N("@1 was slain by @2 using [@3]"),
|
N("@1 was slain by @2 using [@3]"),
|
||||||
},
|
},
|
||||||
|
["murder_by_named_mob"] = {
|
||||||
|
N("@1 was slain by @2."),
|
||||||
|
},
|
||||||
["murder_any"] = {
|
["murder_any"] = {
|
||||||
N("@1 was killed."),
|
N("@1 was killed."),
|
||||||
},
|
},
|
||||||
|
@ -212,7 +308,7 @@ minetest.register_on_dieplayer(function(player, reason)
|
||||||
end
|
end
|
||||||
hittersubtype = hitter:get_luaentity().name
|
hittersubtype = hitter:get_luaentity().name
|
||||||
if hittername then
|
if hittername then
|
||||||
msg = dmsg("murder", name, hittername)
|
msg = dmsg("murder_by_named_mob", name, hittername)
|
||||||
elseif hittersubtype ~= nil and hittersubtype ~= "" then
|
elseif hittersubtype ~= nil and hittersubtype ~= "" then
|
||||||
msg = mmsg(hittersubtype, name)
|
msg = mmsg(hittersubtype, name)
|
||||||
else
|
else
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
@1 drowned.=@1 ertrank.
|
@1 drowned.=@1 ertrank.
|
||||||
@1 ran out of oxygen.=@1 ging die Luft aus.
|
@1 ran out of oxygen.=@1 ging die Luft aus.
|
||||||
@1 was killed by @2.=@1 wurde von @2 getötet.
|
@1 was killed by @2.=@1 wurde von @2 getötet.
|
||||||
|
@1 was slain by @2.=@1 wurde von @2 getötet.
|
||||||
@1 was killed.=@1 wurde getötet.
|
@1 was killed.=@1 wurde getötet.
|
||||||
@1 was killed by a mob.=@1 wurde von einem Mob getötet.
|
@1 was killed by a mob.=@1 wurde von einem Mob getötet.
|
||||||
@1 was burned to death by a blaze's fireball.=@1 wurde von einem Feuerball einer Lohe zu Tode verbrannt.
|
@1 was burned to death by a blaze's fireball.=@1 wurde von einem Feuerball einer Lohe zu Tode verbrannt.
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue