Compare commits
237 Commits
master
...
mineclone2
Author | SHA1 | Date |
---|---|---|
|
273aeaffd2 | |
|
e5ccf63d7e | |
|
77e249af79 | |
|
ae28007f36 | |
|
9a4d26c2ae | |
|
2d1ac1c7fa | |
|
f0c2a0a1e9 | |
|
7f56e5efa4 | |
|
c1e295de5f | |
|
dac3c21628 | |
|
b0c7941b3a | |
|
6bc8219c63 | |
|
8e43f042b4 | |
|
0996a83ba0 | |
|
1621c23308 | |
|
04a88fd244 | |
|
1873080046 | |
|
f031120fe5 | |
|
46541a4adc | |
|
10154d5778 | |
|
f7b290267d | |
|
a18a87e247 | |
|
dc462e2433 | |
|
fd9ed93ea4 | |
|
69c855be1f | |
|
92941534f8 | |
|
c877d6e922 | |
|
12745bd450 | |
|
03be45b983 | |
|
34dbddb40a | |
|
53dcee99cb | |
|
3a585488b4 | |
|
b871433c47 | |
|
a40e1c4737 | |
|
df8fdda2c5 | |
|
45f2a26f1c | |
|
249b5cfd1e | |
|
f5f85a2148 | |
|
d168bfa791 | |
|
c20bd768ec | |
|
67cedf1308 | |
|
9391628813 | |
|
327bb68927 | |
|
906aa3b434 | |
|
ecd27a4cdb | |
|
55df2a57f4 | |
|
4ff987ccc5 | |
|
f3c37f49b9 | |
|
f3580efced | |
|
4a53ba67ab | |
|
ef395af838 | |
|
60fc57d878 | |
|
d02fc0c83d | |
|
e474ce6397 | |
|
b71566aad6 | |
|
4fbb95bed3 | |
|
2571c6124b | |
|
653a633adf | |
|
e61f1e38f2 | |
|
f191be41db | |
|
aa3e4c2846 | |
|
a482a18a67 | |
|
ed30fa0868 | |
|
b3cdb44410 | |
|
8d473a42ca | |
|
0f2c487dca | |
|
dc41c594aa | |
|
bfe51316ee | |
|
13268965ee | |
|
521f96b4ab | |
|
df59cc12a8 | |
|
3df3e957e2 | |
|
0e206e9974 | |
|
6ac0d628ef | |
|
413fbc9c60 | |
|
c8b543991f | |
|
8f9650abe4 | |
|
4c46eb2b4b | |
|
fe770c19a5 | |
|
0112825a9f | |
|
cff0130506 | |
|
7b93f68ed8 | |
|
ece4c892f4 | |
|
bec1f786a6 | |
|
6458565bf9 | |
|
2e9b3c2259 | |
|
5193730652 | |
|
e77473e800 | |
|
922bdbc601 | |
|
3241dbbec5 | |
|
b47733507d | |
|
f0528b11d7 | |
|
503b3a8149 | |
|
5b5a254b1a | |
|
0c90dda04c | |
|
fa86d4e5eb | |
|
f8461d5e90 | |
|
fb6f5eae7a | |
|
558fa57cc6 | |
|
809b88f57d | |
|
4c9643fde9 | |
|
e4840e4170 | |
|
61ef6ebc03 | |
|
e52d58d15a | |
|
6b1ce182d3 | |
|
5df668f6af | |
|
c4f4ede29a | |
|
7bd1bc23b1 | |
|
574c38c768 | |
|
47312f86ed | |
|
12192d1a8d | |
|
ae18ca7602 | |
|
5c3bb22036 | |
|
7441f0269b | |
|
a06d0f7474 | |
|
6c49c46697 | |
|
b82da05590 | |
|
3a8900f905 | |
|
0d725252dc | |
|
86f2d639f9 | |
|
0805431231 | |
|
33c589369f | |
|
6645c4cb30 | |
|
8f30e223e2 | |
|
5d17a6b699 | |
|
f35f80d79a | |
|
834dfcf9af | |
|
f06a56d7c4 | |
|
77167e901d | |
|
2da8be9f78 | |
|
71bb18cd76 | |
|
cad23bd851 | |
|
c1da231f9d | |
|
cb0d49a5a5 | |
|
19e5670e85 | |
|
731d42196a | |
|
502666932f | |
|
c30e9e511d | |
|
8519730ee4 | |
|
bd9713ab50 | |
|
4b2c963222 | |
|
440dd5700d | |
|
39c357672c | |
|
fe6b7cb89b | |
|
c8a7ca729e | |
|
5098932b98 | |
|
671de95357 | |
|
2dcaf8fdcb | |
|
9eda34b0ff | |
|
9d19c3db4b | |
|
bb9df764c4 | |
|
e069962c48 | |
|
09f97584bc | |
|
d5c82cb2cf | |
|
8c0c1380b1 | |
|
10c46e91ff | |
|
b23495b9c1 | |
|
53510ea32a | |
|
6e561be37c | |
|
1b00346790 | |
|
7ce6485717 | |
|
53bfda827a | |
|
08f522ffff | |
|
7a5aa54035 | |
|
dd7facfc03 | |
|
1bdf141198 | |
|
975efb2288 | |
|
69e38debe5 | |
|
68df2c447a | |
|
3ef10cfb30 | |
|
8115575f20 | |
|
46be7c0388 | |
|
90a0858495 | |
|
1d65daa2c9 | |
|
9419db6d35 | |
|
40471399cb | |
|
a84b70bde6 | |
|
36cc040c41 | |
|
752f74e554 | |
|
75c2787583 | |
|
88372778c9 | |
|
6c3d4524a0 | |
|
0a5b1e75d0 | |
|
87e4bed630 | |
|
8e28690303 | |
|
ad87169120 | |
|
81167b4431 | |
|
cb10a5508b | |
|
eeb1f88e08 | |
|
360070bb6a | |
|
06e8e972cc | |
|
8c87014a01 | |
|
fb8b0e877e | |
|
bed3dd87ad | |
|
1a60d08a37 | |
|
19337489f6 | |
|
6fd6717302 | |
|
787d997e51 | |
|
3b7b055e2c | |
|
d37d6fe07f | |
|
7b5d67cdbe | |
|
134005180c | |
|
20e0aed58a | |
|
21ddae3dc1 | |
|
5124a97add | |
|
31eff23ce8 | |
|
9a910e033b | |
|
d12009538e | |
|
d3a2faefe2 | |
|
6e6809f360 | |
|
15fa1e5b7a | |
|
d274f6f444 | |
|
bddc4a3ac7 | |
|
a6bceb08ee | |
|
8ed28adf7c | |
|
66febf158a | |
|
45c0c576f7 | |
|
3635b848d5 | |
|
f3fb80200d | |
|
95111e1d8d | |
|
b0c57beacd | |
|
2fba745724 | |
|
e3eb8c7ac8 | |
|
1f1f9f54a2 | |
|
b1ab79b857 | |
|
2125c51c9c | |
|
d71e296602 | |
|
71353ac934 | |
|
0e8b5c403a | |
|
09671b7ac9 | |
|
31441a02e5 | |
|
68d8eb4c9c | |
|
d57db0444f | |
|
713f933a99 | |
|
ee084f33a7 | |
|
5f544bd5b3 | |
|
65734d0fa4 |
|
@ -1,38 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
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:
|
|
|
@ -1,22 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
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. -->
|
|
|
@ -1,51 +0,0 @@
|
||||||
<!--
|
|
||||||
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
|
|
||||||
-->
|
|
102
.luacheckrc
|
@ -1,102 +0,0 @@
|
||||||
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
|
|
9
API.md
|
@ -43,7 +43,7 @@ A lot of things are possible by using one of the APIs in the mods. Note that not
|
||||||
* Dispenser support: `ITEMS/REDSTONE/mcl_dispensers`
|
* Dispenser support: `ITEMS/REDSTONE/mcl_dispensers`
|
||||||
|
|
||||||
## Mobs
|
## Mobs
|
||||||
* Mobs: `ENTITIES/mcl_mods`
|
* Mobs: `ENTITIES/mcl_mobs`
|
||||||
|
|
||||||
MineClone 2 uses its own mobs framework, called “Mobs Redo: MineClone 2 Edition” or “MRM” for short.
|
MineClone 2 uses its own mobs framework, called “Mobs Redo: MineClone 2 Edition” or “MRM” for short.
|
||||||
This is a fork of Mobs Redo [`mobs`] by TenPlus1.
|
This is a fork of Mobs Redo [`mobs`] by TenPlus1.
|
||||||
|
@ -71,6 +71,9 @@ chances are good that it works out of the box.
|
||||||
* Get flowing direction of liquids: `CORE/flowlib`
|
* Get flowing direction of liquids: `CORE/flowlib`
|
||||||
* `on_walk_over` callback for nodes: `CORE/walkover`
|
* `on_walk_over` callback for nodes: `CORE/walkover`
|
||||||
* Get node names close to player (to reduce constant querying): `PLAYER/mcl_playerinfo`
|
* Get node names close to player (to reduce constant querying): `PLAYER/mcl_playerinfo`
|
||||||
|
* Explosion API
|
||||||
|
* Music discs API
|
||||||
|
* Flowers and flower pots
|
||||||
|
|
||||||
### Unstable APIs
|
### Unstable APIs
|
||||||
The following APIs may be subject to change in future. You could already use these APIs but there will probably be breaking changes in the future, or the API is not as fleshed out as it should be. Use at your own risk!
|
The following APIs may be subject to change in future. You could already use these APIs but there will probably be breaking changes in the future, or the API is not as fleshed out as it should be. Use at your own risk!
|
||||||
|
@ -83,12 +86,10 @@ The following APIs may be subject to change in future. You could already use the
|
||||||
|
|
||||||
### Planned APIs
|
### Planned APIs
|
||||||
|
|
||||||
* Flowers
|
|
||||||
* Saplings and trees
|
* Saplings and trees
|
||||||
* Custom banner patterns
|
* Custom banner patterns
|
||||||
* Custom dimensions
|
* Custom dimensions
|
||||||
* Custom portals
|
* Custom portals
|
||||||
* Music discs
|
|
||||||
* Dispenser and dropper support
|
* Dispenser and dropper support
|
||||||
* Proper sky and weather APIs
|
* Proper sky and weather APIs
|
||||||
* Explosion API
|
|
||||||
|
|
|
@ -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=1`: Music Disc
|
* `music_record`: Music Disc (rating is track ID)
|
||||||
* `tnt=1`: Block is TNT
|
* `tnt=1`: Block is TNT
|
||||||
* `boat=1`: Boat
|
* `boat=1`: Boat
|
||||||
* `minecart=1`: Minecart
|
* `minecart=1`: Minecart
|
||||||
|
@ -182,10 +182,6 @@ 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
|
||||||
|
|
||||||
|
|
48
README.md
|
@ -1,5 +1,5 @@
|
||||||
# Mineclonia
|
# MineClone 2
|
||||||
An unofficial Minecraft-like game for Minetest. Forked from MineClone2.
|
An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils.
|
||||||
Developed by many people. Not developed or endorsed by Mojang AB.
|
Developed by many people. Not developed or endorsed by Mojang AB.
|
||||||
|
|
||||||
Version: 0.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.4.0 or
|
This game requires [Minetest](http://minetest.net) to run (version 5.0.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 Mineclonia in development versions of Minetest.
|
There is no support for running MineClone 2 in development versions of Minetest.
|
||||||
|
|
||||||
To install Mineclonia (if you haven't already), move this directory into the
|
To install MineClone 2 (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 **Mineclonia** is to be a clone of Minecraft and to be released as free software.
|
The main goal of **MineClone 2** 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”)
|
||||||
* Mineclonia also includes Optifine features supported by the Minetest
|
* MineClone2 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
|
||||||
* Mineclonia will use different graphics and sounds, but with a similar style
|
* MineClone 2 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,23 @@ Technical differences from Minecraft:
|
||||||
* Different sounds (various sources)
|
* Different sounds (various sources)
|
||||||
* Different engine (Minetest)
|
* Different engine (Minetest)
|
||||||
|
|
||||||
… and finally, Mineclonia is free software (“free” as in “freedom”)!
|
… and finally, MineClone 2 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/Mineclonia/Mineclonia/issues>
|
<https://git.minetest.land/MineClone2/MineClone2/issues>
|
||||||
|
|
||||||
|
## Chating with the community
|
||||||
|
Join our discord server at:
|
||||||
|
|
||||||
|
<https://discord.gg/84GKcxczG3>
|
||||||
|
|
||||||
## Other readme files
|
## Other readme files
|
||||||
|
|
||||||
* `LICENSE.txt`: The GPLv3 license text
|
* `LICENSE.txt`: The GPLv3 license text
|
||||||
* `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 Mineclonia would need for improvement
|
* `MISSING_ENGINE_FEATURES.md`: List of missing features in Minetest which MineClone 2 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 +202,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 Mineclonia is based on
|
* davedevils: Creator of MineClone on which MineClone 2 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
|
* kay27 <kay27@bk.ru>: Experience system, bugfixes, optimizations (Current maintainer)
|
||||||
* [EliasFleckenstein03](https://github.com/EliasFleckenstein03): End crystals, enchanting, burning mobs / players, animated chests, bugfixes
|
* [EliasFleckenstein03](https://github.com/EliasFleckenstein03): End crystals, enchanting, burning mobs / players, animated chests, bugfixes (Current maintainer)
|
||||||
* 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 +260,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 Mineclonia
|
* Minetest's modding community for providing a huge selection of mods, some of which ended up in MineClone 2
|
||||||
* 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,9 +278,10 @@ 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
|
||||||
Mineclonia is an imitation of Minecraft.
|
MineClone 2 (by kay27, EliasFleckenstein, Wuzzy, davedevils and countless others)
|
||||||
|
is an imitation of Minecraft.
|
||||||
|
|
||||||
Mineclonia is free software: you can redistribute it and/or modify
|
MineClone 2 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.
|
||||||
|
@ -289,15 +295,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 Mineclonia (GNU GPLv3) or the mod's license.
|
license of MineClone 2 (GNU GPLv3) or the mod's license.
|
||||||
|
|
||||||
Mineclonia is a continuation of the discontinued MineClone project by davedevils
|
MineClone 2 is a direct continuation of the discontinued MineClone
|
||||||
and the MineClone2 project by Wuzzy.
|
project by davedevils.
|
||||||
|
|
||||||
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 Mineclonia and the author is Wuzzy.
|
of MineClone 2 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 +1 @@
|
||||||
A survival sandbox game. Survive, gather, hunt, mine, build, explore, and do much more. Faithful clone of Minecraft 1.11. This is a work in progress! Expect bugs!
|
A survival sandbox game. Survive, gather, hunt, mine, build, explore, and do much more. Faithful clone of Minecraft 1.12. This is a work in progress! Expect bugs!
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
name = Mineclonia
|
name = MineClone 2
|
||||||
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
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 76 KiB |
BIN
menu/icon.png
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 3.9 KiB |
|
@ -1,29 +0,0 @@
|
||||||
#!/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}"
|
|
8838
menu/icon.svg
Before Width: | Height: | Size: 509 KiB |
|
@ -32,4 +32,13 @@ mgvalleys_spflags = noaltitude_chill,noaltitude_dry,nohumid_rivers,vary_river_de
|
||||||
# MCL2-specific stuff
|
# MCL2-specific stuff
|
||||||
keepInventory = false
|
keepInventory = false
|
||||||
|
|
||||||
dedicated_server_step = 0.001
|
# Performance settings
|
||||||
|
# dedicated_server_step = 0.001
|
||||||
|
# abm_interval = 0.25
|
||||||
|
# max_objects_per_block = 4096
|
||||||
|
# max_packets_per_iteration = 10096
|
||||||
|
|
||||||
|
# Clientmodding to support official client
|
||||||
|
enable_client_modding = true
|
||||||
|
csm_restriction_flags = 0
|
||||||
|
enable_mod_channels = true
|
||||||
|
|
|
@ -178,10 +178,6 @@ end
|
||||||
-- Add the groupcaps from a field in "_mcl_diggroups" to the groupcaps of a
|
-- Add the groupcaps from a field in "_mcl_diggroups" to the groupcaps of a
|
||||||
-- tool.
|
-- tool.
|
||||||
local function add_groupcaps(toolname, groupcaps, groupcaps_def, efficiency)
|
local function add_groupcaps(toolname, groupcaps, groupcaps_def, efficiency)
|
||||||
if not groupcaps_def then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
for g, capsdef in pairs(groupcaps_def) do
|
for g, capsdef in pairs(groupcaps_def) do
|
||||||
local mult = capsdef.speed or 1
|
local mult = capsdef.speed or 1
|
||||||
local uses = capsdef.uses
|
local uses = capsdef.uses
|
||||||
|
@ -200,6 +196,7 @@ local function add_groupcaps(toolname, groupcaps, groupcaps_def, efficiency)
|
||||||
groupcaps[g .. "_dig"] = get_groupcap(g, level > 0, mult, efficiency, uses)
|
groupcaps[g .. "_dig"] = get_groupcap(g, level > 0, mult, efficiency, uses)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
return groupcaps
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Checks if the given node would drop its useful drop if dug by a given tool.
|
-- Checks if the given node would drop its useful drop if dug by a given tool.
|
||||||
|
@ -207,10 +204,6 @@ end
|
||||||
function mcl_autogroup.can_harvest(nodename, toolname)
|
function mcl_autogroup.can_harvest(nodename, toolname)
|
||||||
local ndef = minetest.registered_nodes[nodename]
|
local ndef = minetest.registered_nodes[nodename]
|
||||||
|
|
||||||
if not ndef then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
if minetest.get_item_group(nodename, "dig_immediate") >= 2 then
|
if minetest.get_item_group(nodename, "dig_immediate") >= 2 then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
name = biomeinfo
|
name = biomeinfo
|
||||||
|
author = Wuzzy
|
||||||
description = Simple API to get data about biomes.
|
description = Simple API to get data about biomes.
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
local get_connected_players = minetest.get_connected_players
|
||||||
|
local clock = os.clock
|
||||||
|
|
||||||
controls = {}
|
controls = {}
|
||||||
controls.players = {}
|
controls.players = {}
|
||||||
|
|
||||||
|
@ -42,7 +45,7 @@ minetest.register_on_leaveplayer(function(player)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
minetest.register_globalstep(function(dtime)
|
minetest.register_globalstep(function(dtime)
|
||||||
for _, player in pairs(minetest.get_connected_players()) do
|
for _, player in pairs(get_connected_players()) do
|
||||||
local player_name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
local player_controls = player:get_player_control()
|
local player_controls = player:get_player_control()
|
||||||
if controls.players[player_name] then
|
if controls.players[player_name] then
|
||||||
|
@ -53,15 +56,15 @@ minetest.register_globalstep(function(dtime)
|
||||||
for _, func in pairs(controls.registered_on_press) do
|
for _, func in pairs(controls.registered_on_press) do
|
||||||
func(player, cname)
|
func(player, cname)
|
||||||
end
|
end
|
||||||
controls.players[player_name][cname] = {true, os.clock()}
|
controls.players[player_name][cname] = {true, clock()}
|
||||||
elseif cbool==true and controls.players[player_name][cname][1]==true then
|
elseif cbool==true and controls.players[player_name][cname][1]==true then
|
||||||
for _, func in pairs(controls.registered_on_hold) do
|
for _, func in pairs(controls.registered_on_hold) do
|
||||||
func(player, cname, os.clock()-controls.players[player_name][cname][2])
|
func(player, cname, clock()-controls.players[player_name][cname][2])
|
||||||
end
|
end
|
||||||
--Release a key
|
--Release a key
|
||||||
elseif cbool==false and controls.players[player_name][cname][1]==true then
|
elseif cbool==false and controls.players[player_name][cname][1]==true then
|
||||||
for _, func in pairs(controls.registered_on_release) do
|
for _, func in pairs(controls.registered_on_release) do
|
||||||
func(player, cname, os.clock()-controls.players[player_name][cname][2])
|
func(player, cname, clock()-controls.players[player_name][cname][2])
|
||||||
end
|
end
|
||||||
controls.players[player_name][cname] = {false}
|
controls.players[player_name][cname] = {false}
|
||||||
end
|
end
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = controls
|
name = controls
|
||||||
|
author = Arcelmi
|
||||||
|
description = Controls framework by Arcelmi
|
||||||
|
|
||||||
|
|
|
@ -1 +1,4 @@
|
||||||
name = flowlib
|
name = flowlib
|
||||||
|
author = Qwertymine3
|
||||||
|
description = Simple flow functions for use in Minetest mods by Qwertymine3
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
name = mcl_attached
|
name = mcl_attached
|
||||||
|
author = Wuzzy
|
||||||
description = Adds additional ways for nodes to be attached.
|
description = Adds additional ways for nodes to be attached.
|
||||||
|
|
|
@ -1,8 +0,0 @@
|
||||||
# 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.
|
|
|
@ -18,6 +18,16 @@ local CONTENT_FIRE = minetest.get_content_id("mcl_fire:fire")
|
||||||
|
|
||||||
local S = minetest.get_translator("mcl_explosions")
|
local S = minetest.get_translator("mcl_explosions")
|
||||||
|
|
||||||
|
local hash_node_position = minetest.hash_node_position
|
||||||
|
local get_objects_inside_radius = minetest.get_objects_inside_radius
|
||||||
|
local get_position_from_hash = minetest.get_position_from_hash
|
||||||
|
local get_node_drops = minetest.get_node_drops
|
||||||
|
local get_name_from_content_id = minetest.get_name_from_content_id
|
||||||
|
local get_voxel_manip = minetest.get_voxel_manip
|
||||||
|
local bulk_set_node = minetest.bulk_set_node
|
||||||
|
local check_for_falling = minetest.check_for_falling
|
||||||
|
local add_item = minetest.add_item
|
||||||
|
|
||||||
-- Saved sphere explosion shapes for various radiuses
|
-- Saved sphere explosion shapes for various radiuses
|
||||||
local sphere_shapes = {}
|
local sphere_shapes = {}
|
||||||
|
|
||||||
|
@ -57,48 +67,50 @@ local function compute_sphere_rays(radius)
|
||||||
local rays = {}
|
local rays = {}
|
||||||
local sphere = {}
|
local sphere = {}
|
||||||
|
|
||||||
local function add_ray(pos)
|
for i=1, 2 do
|
||||||
sphere[minetest.hash_node_position(pos)] = pos
|
|
||||||
end
|
|
||||||
|
|
||||||
for y = -radius, radius do
|
for y = -radius, radius do
|
||||||
for z = -radius, radius do
|
for z = -radius, radius do
|
||||||
for x = -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[hash_node_position(pos)] = pos
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i=1,2 do
|
||||||
for x = -radius, radius do
|
for x = -radius, radius do
|
||||||
for z = -radius, radius do
|
for z = -radius, radius do
|
||||||
for y = -radius, 0 do
|
for y = -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[hash_node_position(pos)] = pos
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for i=1,2 do
|
||||||
for x = -radius, radius do
|
for x = -radius, radius do
|
||||||
for y = -radius, radius do
|
for y = -radius, radius do
|
||||||
for z = -radius, 0 do
|
for z = -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[hash_node_position(pos)] = pos
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
for _, pos in pairs(sphere) do
|
for _, pos in pairs(sphere) do
|
||||||
rays[#rays + 1] = vector.normalize(pos)
|
rays[#rays + 1] = vector.normalize(pos)
|
||||||
|
@ -154,7 +166,7 @@ end
|
||||||
-- inlined to avoid function calls and unnecessary table creation. This was
|
-- inlined to avoid function calls and unnecessary table creation. This was
|
||||||
-- measured to give a significant performance increase.
|
-- measured to give a significant performance increase.
|
||||||
local function trace_explode(pos, strength, raydirs, radius, info, puncher)
|
local function trace_explode(pos, strength, raydirs, radius, info, puncher)
|
||||||
local vm = minetest.get_voxel_manip()
|
local vm = get_voxel_manip()
|
||||||
|
|
||||||
local emin, emax = vm:read_from_map(vector.subtract(pos, radius),
|
local emin, emax = vm:read_from_map(vector.subtract(pos, radius),
|
||||||
vector.add(pos, radius))
|
vector.add(pos, radius))
|
||||||
|
@ -200,15 +212,12 @@ 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
|
||||||
|
|
||||||
local hash = minetest.hash_node_position(npos)
|
local hash = hash_node_position(npos)
|
||||||
|
|
||||||
rpos_x = rpos_x + STEP_LENGTH * rdir_x
|
rpos_x = rpos_x + STEP_LENGTH * rdir_x
|
||||||
rpos_y = rpos_y + STEP_LENGTH * rdir_y
|
rpos_y = rpos_y + STEP_LENGTH * rdir_y
|
||||||
|
@ -231,7 +240,7 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
|
||||||
|
|
||||||
-- Entities in radius of explosion
|
-- Entities in radius of explosion
|
||||||
local punch_radius = 2 * strength
|
local punch_radius = 2 * strength
|
||||||
local objs = minetest.get_objects_inside_radius(pos, punch_radius)
|
local objs = get_objects_inside_radius(pos, punch_radius)
|
||||||
|
|
||||||
-- Trace rays for entity damage
|
-- Trace rays for entity damage
|
||||||
for _, obj in pairs(objs) do
|
for _, obj in pairs(objs) do
|
||||||
|
@ -251,12 +260,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]
|
local x1 = collisionbox[1] * 2
|
||||||
local y1 = collisionbox[2]
|
local y1 = collisionbox[2] * 2
|
||||||
local z1 = collisionbox[3]
|
local z1 = collisionbox[3] * 2
|
||||||
local x2 = collisionbox[4]
|
local x2 = collisionbox[4] * 2
|
||||||
local y2 = collisionbox[5]
|
local y2 = collisionbox[5] * 2
|
||||||
local z2 = collisionbox[6]
|
local z2 = collisionbox[6] * 2
|
||||||
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)
|
||||||
|
@ -336,13 +345,13 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
|
||||||
minetest.after(0.3, function(obj, damage, impact, punch_dir) -- 0.2 is minimum delay for closing old formspec and open died formspec -- TODO: REMOVE THIS IN THE FUTURE
|
minetest.after(0.3, function(obj, damage, impact, punch_dir) -- 0.2 is minimum delay for closing old formspec and open died formspec -- TODO: REMOVE THIS IN THE FUTURE
|
||||||
if not obj then return end
|
if not obj then return end
|
||||||
obj:punch(obj, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir)
|
obj:punch(obj, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir)
|
||||||
obj:add_player_velocity(vector.multiply(punch_dir, impact * 20))
|
obj:add_velocity(vector.multiply(punch_dir, impact * 20))
|
||||||
end, obj, damage, impact, vector.new(punch_dir))
|
end, obj, damage, impact, vector.new(punch_dir))
|
||||||
else
|
else
|
||||||
obj:punch(source, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir)
|
obj:punch(source, 10, { damage_groups = { full_punch_interval = 1, fleshy = damage, knockback = impact * 20.0 } }, punch_dir)
|
||||||
|
|
||||||
if obj:is_player() then
|
if obj:is_player() then
|
||||||
obj:add_player_velocity(vector.multiply(punch_dir, impact * 20))
|
obj:add_velocity(vector.multiply(punch_dir, impact * 20))
|
||||||
elseif ent.tnt_knockback then
|
elseif ent.tnt_knockback then
|
||||||
obj:add_velocity(vector.multiply(punch_dir, impact * 20))
|
obj:add_velocity(vector.multiply(punch_dir, impact * 20))
|
||||||
end
|
end
|
||||||
|
@ -360,46 +369,46 @@ local function trace_explode(pos, strength, raydirs, radius, info, puncher)
|
||||||
local remove = true
|
local remove = true
|
||||||
|
|
||||||
if do_drop or on_blast ~= nil then
|
if do_drop or on_blast ~= nil then
|
||||||
local npos = minetest.get_position_from_hash(hash)
|
local npos = get_position_from_hash(hash)
|
||||||
if on_blast ~= nil then
|
if on_blast ~= nil then
|
||||||
on_blast(npos, 1.0, do_drop)
|
on_blast(npos, 1.0, do_drop)
|
||||||
remove = false
|
remove = false
|
||||||
else
|
else
|
||||||
local name = minetest.get_name_from_content_id(data[idx])
|
local name = get_name_from_content_id(data[idx])
|
||||||
local drop = minetest.get_node_drops(name, "")
|
local drop = get_node_drops(name, "")
|
||||||
|
|
||||||
for _, item in ipairs(drop) do
|
for _, item in ipairs(drop) do
|
||||||
if type(item) ~= "string" then
|
if type(item) ~= "string" then
|
||||||
item = item:get_name() .. item:get_count()
|
item = item:get_name() .. item:get_count()
|
||||||
end
|
end
|
||||||
minetest.add_item(npos, item)
|
add_item(npos, item)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
if remove then
|
if remove then
|
||||||
if mod_fire and fire and math.random(1, 3) == 1 then
|
if mod_fire and fire and math.random(1, 3) == 1 then
|
||||||
table.insert(fires, minetest.get_position_from_hash(hash))
|
table.insert(fires, get_position_from_hash(hash))
|
||||||
else
|
else
|
||||||
table.insert(airs, minetest.get_position_from_hash(hash))
|
table.insert(airs, get_position_from_hash(hash))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
-- We use bulk_set_node instead of LVM because we want to have on_destruct and
|
-- We use bulk_set_node instead of LVM because we want to have on_destruct and
|
||||||
-- on_construct being called
|
-- on_construct being called
|
||||||
if #airs > 0 then
|
if #airs > 0 then
|
||||||
minetest.bulk_set_node(airs, {name="air"})
|
bulk_set_node(airs, {name="air"})
|
||||||
end
|
end
|
||||||
if #fires > 0 then
|
if #fires > 0 then
|
||||||
minetest.bulk_set_node(fires, {name="mcl_fire:fire"})
|
bulk_set_node(fires, {name="mcl_fire:fire"})
|
||||||
end
|
end
|
||||||
-- Update falling nodes
|
-- Update falling nodes
|
||||||
for a=1, #airs do
|
for a=1, #airs do
|
||||||
local p = airs[a]
|
local p = airs[a]
|
||||||
minetest.check_for_falling({x=p.x, y=p.y+1, z=p.z})
|
check_for_falling({x=p.x, y=p.y+1, z=p.z})
|
||||||
end
|
end
|
||||||
for f=1, #fires do
|
for f=1, #fires do
|
||||||
local p = fires[f]
|
local p = fires[f]
|
||||||
minetest.check_for_falling({x=p.x, y=p.y+1, z=p.z})
|
check_for_falling({x=p.x, y=p.y+1, z=p.z})
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Log explosion
|
-- Log explosion
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
name = mcl_explosions
|
name = mcl_explosions
|
||||||
|
author = ryvnf
|
||||||
description = A common API to create explosions.
|
description = A common API to create explosions.
|
||||||
depends = mcl_particles
|
depends = mcl_particles
|
||||||
optional_depends = mcl_fire
|
optional_depends = mcl_fire
|
||||||
|
|
|
@ -33,25 +33,26 @@ mcl_vars.MAP_BLOCKSIZE = math.max(1, core.MAP_BLOCKSIZE or 16)
|
||||||
mcl_vars.mapgen_limit = math.max(1, tonumber(minetest.get_mapgen_setting("mapgen_limit")) or 31000)
|
mcl_vars.mapgen_limit = math.max(1, tonumber(minetest.get_mapgen_setting("mapgen_limit")) or 31000)
|
||||||
mcl_vars.MAX_MAP_GENERATION_LIMIT = math.max(1, core.MAX_MAP_GENERATION_LIMIT or 31000)
|
mcl_vars.MAX_MAP_GENERATION_LIMIT = math.max(1, core.MAX_MAP_GENERATION_LIMIT or 31000)
|
||||||
local central_chunk_offset = -math.floor(mcl_vars.chunksize / 2)
|
local central_chunk_offset = -math.floor(mcl_vars.chunksize / 2)
|
||||||
local chunk_size_in_nodes = mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE
|
mcl_vars.central_chunk_offset_in_nodes = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE
|
||||||
|
mcl_vars.chunk_size_in_nodes = mcl_vars.chunksize * mcl_vars.MAP_BLOCKSIZE
|
||||||
local central_chunk_min_pos = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE
|
local central_chunk_min_pos = central_chunk_offset * mcl_vars.MAP_BLOCKSIZE
|
||||||
local central_chunk_max_pos = central_chunk_min_pos + chunk_size_in_nodes - 1
|
local central_chunk_max_pos = central_chunk_min_pos + mcl_vars.chunk_size_in_nodes - 1
|
||||||
local ccfmin = central_chunk_min_pos - mcl_vars.MAP_BLOCKSIZE -- Fullminp/fullmaxp of central chunk, in nodes
|
local ccfmin = central_chunk_min_pos - mcl_vars.MAP_BLOCKSIZE -- Fullminp/fullmaxp of central chunk, in nodes
|
||||||
local ccfmax = central_chunk_max_pos + mcl_vars.MAP_BLOCKSIZE
|
local ccfmax = central_chunk_max_pos + mcl_vars.MAP_BLOCKSIZE
|
||||||
local mapgen_limit_b = math.floor(math.min(mcl_vars.mapgen_limit, mcl_vars.MAX_MAP_GENERATION_LIMIT) / mcl_vars.MAP_BLOCKSIZE)
|
local mapgen_limit_b = math.floor(math.min(mcl_vars.mapgen_limit, mcl_vars.MAX_MAP_GENERATION_LIMIT) / mcl_vars.MAP_BLOCKSIZE)
|
||||||
local mapgen_limit_min = -mapgen_limit_b * mcl_vars.MAP_BLOCKSIZE
|
local mapgen_limit_min = -mapgen_limit_b * mcl_vars.MAP_BLOCKSIZE
|
||||||
local mapgen_limit_max = (mapgen_limit_b + 1) * mcl_vars.MAP_BLOCKSIZE - 1
|
local mapgen_limit_max = (mapgen_limit_b + 1) * mcl_vars.MAP_BLOCKSIZE - 1
|
||||||
local numcmin = math.max(math.floor((ccfmin - mapgen_limit_min) / chunk_size_in_nodes), 0) -- Number of complete chunks from central chunk
|
local numcmin = math.max(math.floor((ccfmin - mapgen_limit_min) / mcl_vars.chunk_size_in_nodes), 0) -- Number of complete chunks from central chunk
|
||||||
local numcmax = math.max(math.floor((mapgen_limit_max - ccfmax) / chunk_size_in_nodes), 0) -- fullminp/fullmaxp to effective mapgen limits.
|
local numcmax = math.max(math.floor((mapgen_limit_max - ccfmax) / mcl_vars.chunk_size_in_nodes), 0) -- fullminp/fullmaxp to effective mapgen limits.
|
||||||
mcl_vars.mapgen_edge_min = central_chunk_min_pos - numcmin * chunk_size_in_nodes
|
mcl_vars.mapgen_edge_min = central_chunk_min_pos - numcmin * mcl_vars.chunk_size_in_nodes
|
||||||
mcl_vars.mapgen_edge_max = central_chunk_max_pos + numcmax * chunk_size_in_nodes
|
mcl_vars.mapgen_edge_max = central_chunk_max_pos + numcmax * mcl_vars.chunk_size_in_nodes
|
||||||
|
|
||||||
local function coordinate_to_block(x)
|
local function coordinate_to_block(x)
|
||||||
return math.floor(x / mcl_vars.MAP_BLOCKSIZE)
|
return math.floor(x / mcl_vars.MAP_BLOCKSIZE)
|
||||||
end
|
end
|
||||||
|
|
||||||
local function coordinate_to_chunk(x)
|
local function coordinate_to_chunk(x)
|
||||||
return math.floor((coordinate_to_block(x) + central_chunk_offset) / mcl_vars.chunksize)
|
return math.floor((coordinate_to_block(x) - central_chunk_offset) / mcl_vars.chunksize)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_vars.pos_to_block(pos)
|
function mcl_vars.pos_to_block(pos)
|
||||||
|
@ -70,7 +71,7 @@ function mcl_vars.pos_to_chunk(pos)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
local k_positive = math.ceil(mcl_vars.MAX_MAP_GENERATION_LIMIT / chunk_size_in_nodes)
|
local k_positive = math.ceil(mcl_vars.MAX_MAP_GENERATION_LIMIT / mcl_vars.chunk_size_in_nodes)
|
||||||
local k_positive_z = k_positive * 2
|
local k_positive_z = k_positive * 2
|
||||||
local k_positive_y = k_positive_z * k_positive_z
|
local k_positive_y = k_positive_z * k_positive_z
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
name = mcl_init
|
name = mcl_init
|
||||||
|
author = Wuzzy
|
||||||
description = Initialization mod of MineClone 2. Defines some common shared variables and sets up initial default settings which have to be set at the beginning.
|
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,2 +1,3 @@
|
||||||
name = mcl_loot
|
name = mcl_loot
|
||||||
|
author = Wuzzy
|
||||||
description = API for filling a chest with random treasures.
|
description = API for filling a chest with random treasures.
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
name = mcl_particles
|
name = mcl_particles
|
||||||
|
author = Wuzzy
|
||||||
description = Contains particle images of MineClone 2. No code.
|
description = Contains particle images of MineClone 2. No code.
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
name = mcl_sounds
|
name = mcl_sounds
|
||||||
|
author = Wuzzy
|
||||||
description = This mod contains the core sounds of MineClone 2 as well as helper function for mods to access them.
|
description = This mod contains the core sounds of MineClone 2 as well as helper function for mods to access them.
|
||||||
|
|
|
@ -405,3 +405,16 @@ function mcl_util.get_object_center(obj)
|
||||||
pos.y = pos.y + (ymax - ymin) / 2.0
|
pos.y = pos.y + (ymax - ymin) / 2.0
|
||||||
return pos
|
return pos
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function mcl_util.get_color(colorstr)
|
||||||
|
local mc_color = mcl_colors[colorstr:upper()]
|
||||||
|
if mc_color then
|
||||||
|
colorstr = mc_color
|
||||||
|
elseif #colorstr ~= 7 or colorstr:sub(1, 1) ~= "#"then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local hex = tonumber(colorstr:sub(2, 7), 16)
|
||||||
|
if hex then
|
||||||
|
return colorstr, hex
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
name = mcl_util
|
name = mcl_util
|
||||||
|
author = Wuzzy
|
||||||
description = Helper functions for MineClone 2.
|
description = Helper functions for MineClone 2.
|
||||||
depends = mcl_init
|
depends = mcl_init
|
||||||
|
|
|
@ -6,7 +6,7 @@ mcl_worlds = {}
|
||||||
function mcl_worlds.is_in_void(pos)
|
function mcl_worlds.is_in_void(pos)
|
||||||
local void =
|
local void =
|
||||||
not ((pos.y < mcl_vars.mg_overworld_max and pos.y > mcl_vars.mg_overworld_min) or
|
not ((pos.y < mcl_vars.mg_overworld_max and pos.y > mcl_vars.mg_overworld_min) or
|
||||||
(pos.y < mcl_vars.mg_nether_max and pos.y > mcl_vars.mg_nether_min) or
|
(pos.y < mcl_vars.mg_nether_max+128 and pos.y > mcl_vars.mg_nether_min) or
|
||||||
(pos.y < mcl_vars.mg_end_max and pos.y > mcl_vars.mg_end_min))
|
(pos.y < mcl_vars.mg_end_max and pos.y > mcl_vars.mg_end_min))
|
||||||
|
|
||||||
local void_deadly = false
|
local void_deadly = false
|
||||||
|
@ -15,11 +15,11 @@ function mcl_worlds.is_in_void(pos)
|
||||||
-- Overworld → Void → End → Void → Nether → Void
|
-- Overworld → Void → End → Void → Nether → Void
|
||||||
if pos.y < mcl_vars.mg_overworld_min and pos.y > mcl_vars.mg_end_max then
|
if pos.y < mcl_vars.mg_overworld_min and pos.y > mcl_vars.mg_end_max then
|
||||||
void_deadly = pos.y < mcl_vars.mg_overworld_min - deadly_tolerance
|
void_deadly = pos.y < mcl_vars.mg_overworld_min - deadly_tolerance
|
||||||
elseif pos.y < mcl_vars.mg_end_min and pos.y > mcl_vars.mg_nether_max then
|
elseif pos.y < mcl_vars.mg_end_min and pos.y > mcl_vars.mg_nether_max+128 then
|
||||||
-- The void between End and Nether. Like usual, but here, the void
|
-- The void between End and Nether. Like usual, but here, the void
|
||||||
-- *above* the Nether also has a small tolerance area, so player
|
-- *above* the Nether also has a small tolerance area, so player
|
||||||
-- can fly above the Nether without getting hurt instantly.
|
-- can fly above the Nether without getting hurt instantly.
|
||||||
void_deadly = (pos.y < mcl_vars.mg_end_min - deadly_tolerance) and (pos.y > mcl_vars.mg_nether_max + deadly_tolerance)
|
void_deadly = (pos.y < mcl_vars.mg_end_min - deadly_tolerance) and (pos.y > mcl_vars.mg_nether_max+128 + deadly_tolerance)
|
||||||
elseif pos.y < mcl_vars.mg_nether_min then
|
elseif pos.y < mcl_vars.mg_nether_min then
|
||||||
void_deadly = pos.y < mcl_vars.mg_nether_min - deadly_tolerance
|
void_deadly = pos.y < mcl_vars.mg_nether_min - deadly_tolerance
|
||||||
end
|
end
|
||||||
|
@ -35,7 +35,7 @@ end
|
||||||
function mcl_worlds.y_to_layer(y)
|
function mcl_worlds.y_to_layer(y)
|
||||||
if y >= mcl_vars.mg_overworld_min then
|
if y >= mcl_vars.mg_overworld_min then
|
||||||
return y - mcl_vars.mg_overworld_min, "overworld"
|
return y - mcl_vars.mg_overworld_min, "overworld"
|
||||||
elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max then
|
elseif y >= mcl_vars.mg_nether_min and y <= mcl_vars.mg_nether_max+128 then
|
||||||
return y - mcl_vars.mg_nether_min, "nether"
|
return y - mcl_vars.mg_nether_min, "nether"
|
||||||
elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then
|
elseif y >= mcl_vars.mg_end_min and y <= mcl_vars.mg_end_max then
|
||||||
return y - mcl_vars.mg_end_min, "end"
|
return y - mcl_vars.mg_end_min, "end"
|
||||||
|
@ -73,7 +73,7 @@ end
|
||||||
-- Takes a position and returns true if this position can have Nether dust
|
-- Takes a position and returns true if this position can have Nether dust
|
||||||
function mcl_worlds.has_dust(pos)
|
function mcl_worlds.has_dust(pos)
|
||||||
-- Weather in the Overworld and the high part of the void below
|
-- Weather in the Overworld and the high part of the void below
|
||||||
return pos.y <= mcl_vars.mg_nether_max + 64 and pos.y >= mcl_vars.mg_nether_min - 64
|
return pos.y <= mcl_vars.mg_nether_max + 138 and pos.y >= mcl_vars.mg_nether_min - 10
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Takes a position (pos) and returns true if compasses are working here
|
-- Takes a position (pos) and returns true if compasses are working here
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
name = mcl_worlds
|
name = mcl_worlds
|
||||||
|
author = Wuzzy
|
||||||
description = Utility functions for worlds and the “dimensions”.
|
description = Utility functions for worlds and the “dimensions”.
|
||||||
depends = mcl_init
|
depends = mcl_init
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,10 @@
|
||||||
-- register extra flavours of a base nodedef
|
-- register extra flavours of a base nodedef
|
||||||
|
|
||||||
|
local get_connected_players = minetest.get_connected_players
|
||||||
|
local get_node = minetest.get_node
|
||||||
|
local vector_add = vector.add
|
||||||
|
local ceil = math.ceil
|
||||||
|
|
||||||
walkover = {}
|
walkover = {}
|
||||||
walkover.registered_globals = {}
|
walkover.registered_globals = {}
|
||||||
|
|
||||||
|
@ -6,25 +12,38 @@ function walkover.register_global(func)
|
||||||
table.insert(walkover.registered_globals, func)
|
table.insert(walkover.registered_globals, func)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local on_walk = {}
|
||||||
|
local registered_globals = {}
|
||||||
|
|
||||||
|
minetest.register_on_mods_loaded(function()
|
||||||
|
for name,def in pairs(minetest.registered_nodes) do
|
||||||
|
if def.on_walk_over then
|
||||||
|
on_walk[name] = def.on_walk_over
|
||||||
|
end
|
||||||
|
end
|
||||||
|
for _,func in ipairs(walkover.registered_globals) do --cache registered globals
|
||||||
|
table.insert(registered_globals, func)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
local timer = 0
|
local timer = 0
|
||||||
minetest.register_globalstep(function(dtime)
|
minetest.register_globalstep(function(dtime)
|
||||||
timer = timer + dtime;
|
timer = timer + dtime;
|
||||||
if timer >= 0.3 then
|
if timer >= 0.3 then
|
||||||
for _,player in pairs(minetest.get_connected_players()) do
|
for _,player in pairs(get_connected_players()) do
|
||||||
local pp = player:get_pos()
|
local pp = player:get_pos()
|
||||||
pp.y = math.ceil(pp.y)
|
pp.y = ceil(pp.y)
|
||||||
local loc = vector.add(pp, {x=0,y=-1,z=0})
|
local loc = vector_add(pp, {x=0,y=-1,z=0})
|
||||||
if loc ~= nil then
|
if loc ~= nil then
|
||||||
|
|
||||||
local nodeiamon = minetest.get_node(loc)
|
local nodeiamon = get_node(loc)
|
||||||
|
|
||||||
if nodeiamon ~= nil then
|
if nodeiamon ~= nil then
|
||||||
local def = minetest.registered_nodes[nodeiamon.name]
|
if on_walk[nodeiamon.name] then
|
||||||
if def ~= nil and def.on_walk_over ~= nil then
|
on_walk[nodeiamon.name](loc, nodeiamon, player)
|
||||||
def.on_walk_over(loc, nodeiamon, player)
|
|
||||||
end
|
end
|
||||||
for _, func in ipairs(walkover.registered_globals) do
|
for i = 1, #registered_globals do
|
||||||
func(loc, nodeiamon, player)
|
registered_globals[i](loc, nodeiamon, player)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
name = walkover
|
||||||
|
author = lordfingle
|
||||||
|
description = Some mode developers have shown an interest in having an `on_walk_over` event. This is useful for pressure-plates and the like.
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
name = drippingwater
|
name = drippingwater
|
||||||
|
author = kddekadenz
|
||||||
|
description = Drops are generated rarely under solid nodes
|
||||||
depends = mcl_core
|
depends = mcl_core
|
||||||
|
|
|
@ -20,4 +20,4 @@ Authors include:
|
||||||
* Various Minetest / Minetest Game developers and contributors (2012-2016)
|
* Various Minetest / Minetest Game developers and contributors (2012-2016)
|
||||||
* maikerumine (2017)
|
* maikerumine (2017)
|
||||||
* Wuzzy (2017)
|
* Wuzzy (2017)
|
||||||
|
* Fleckenstein (2020-2021)
|
||||||
|
|
|
@ -163,6 +163,8 @@ function boat.get_staticdata(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
function boat.on_death(self, killer)
|
function boat.on_death(self, killer)
|
||||||
|
mcl_burning.extinguish(self.object)
|
||||||
|
|
||||||
if killer and killer:is_player() and minetest.is_creative_enabled(killer:get_player_name()) then
|
if killer and killer:is_player() and minetest.is_creative_enabled(killer:get_player_name()) then
|
||||||
local inv = killer:get_inventory()
|
local inv = killer:get_inventory()
|
||||||
if not inv:contains_item("main", self._itemstring) then
|
if not inv:contains_item("main", self._itemstring) then
|
||||||
|
@ -188,6 +190,8 @@ function boat.on_punch(self, puncher, time_from_last_punch, tool_capabilities, d
|
||||||
end
|
end
|
||||||
|
|
||||||
function boat.on_step(self, dtime, moveresult)
|
function boat.on_step(self, dtime, moveresult)
|
||||||
|
mcl_burning.tick(self.object, dtime)
|
||||||
|
|
||||||
self._v = get_v(self.object:get_velocity()) * get_sign(self._v)
|
self._v = get_v(self.object:get_velocity()) * get_sign(self._v)
|
||||||
local v_factor = 1
|
local v_factor = 1
|
||||||
local v_slowdown = 0.02
|
local v_slowdown = 0.02
|
||||||
|
@ -223,7 +227,7 @@ function boat.on_step(self, dtime, moveresult)
|
||||||
self._regen_timer = regen_timer
|
self._regen_timer = regen_timer
|
||||||
|
|
||||||
if moveresult and moveresult.collides then
|
if moveresult and moveresult.collides then
|
||||||
for _, collision in ipairs(moveresult.collisions) do
|
for _, collision in pairs(moveresult.collisions) do
|
||||||
local pos = collision.node_pos
|
local pos = collision.node_pos
|
||||||
if collision.type == "node" and minetest.get_item_group(minetest.get_node(pos).name, "dig_by_boat") > 0 then
|
if collision.type == "node" and minetest.get_item_group(minetest.get_node(pos).name, "dig_by_boat") > 0 then
|
||||||
minetest.dig_node(pos)
|
minetest.dig_node(pos)
|
||||||
|
@ -243,7 +247,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_object(self._passenger, true)
|
detach_player(self._passenger, true)
|
||||||
self._passenger = nil
|
self._passenger = nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -305,7 +309,7 @@ function boat.on_step(self, dtime, moveresult)
|
||||||
self._animation = 0
|
self._animation = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, obj in ipairs(minetest.get_objects_inside_radius(self.object:get_pos(), 1.3)) do
|
for _, obj in pairs(minetest.get_objects_inside_radius(self.object:get_pos(), 1.3)) do
|
||||||
local entity = obj:get_luaentity()
|
local entity = obj:get_luaentity()
|
||||||
if entity and entity._cmi_is_mob then
|
if entity and entity._cmi_is_mob then
|
||||||
attach_object(self, obj)
|
attach_object(self, obj)
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
name = mcl_boats
|
name = mcl_boats
|
||||||
|
author = PilzAdam
|
||||||
description = Adds drivable boats.
|
description = Adds drivable boats.
|
||||||
depends = mcl_player
|
depends = mcl_player
|
||||||
optional_depends = mcl_core, doc_identifier
|
optional_depends = mcl_core, doc_identifier
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ function mcl_burning.is_burning(obj)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_burning.is_affected_by_rain(obj)
|
function mcl_burning.is_affected_by_rain(obj)
|
||||||
return mcl_weather.get_weather() == "rain" and mcl_weather.is_outdoor(obj:get_pos())
|
return mcl_weather and mcl_weather.get_weather() == "rain" and mcl_weather.is_outdoor(obj:get_pos())
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_burning.get_collisionbox(obj, smaller)
|
function mcl_burning.get_collisionbox(obj, smaller)
|
||||||
|
@ -117,6 +117,10 @@ function mcl_burning.damage(obj)
|
||||||
end
|
end
|
||||||
|
|
||||||
function mcl_burning.set_on_fire(obj, burn_time, reason)
|
function mcl_burning.set_on_fire(obj, burn_time, reason)
|
||||||
|
if obj:get_hp() < 0 then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
local luaentity = obj:get_luaentity()
|
local luaentity = obj:get_luaentity()
|
||||||
if luaentity and luaentity.fire_resistant then
|
if luaentity and luaentity.fire_resistant then
|
||||||
return
|
return
|
||||||
|
@ -145,7 +149,7 @@ function mcl_burning.set_on_fire(obj, burn_time, reason)
|
||||||
end
|
end
|
||||||
|
|
||||||
if old_burn_time <= burn_time then
|
if old_burn_time <= burn_time then
|
||||||
local sound_id = mcl_burning.get(obj, "int", "sound_id")
|
--[[local sound_id = mcl_burning.get(obj, "int", "sound_id")
|
||||||
if sound_id == 0 then
|
if sound_id == 0 then
|
||||||
sound_id = minetest.sound_play("fire_fire", {
|
sound_id = minetest.sound_play("fire_fire", {
|
||||||
object = obj,
|
object = obj,
|
||||||
|
@ -153,17 +157,7 @@ function mcl_burning.set_on_fire(obj, burn_time, reason)
|
||||||
max_hear_distance = 16,
|
max_hear_distance = 16,
|
||||||
loop = true,
|
loop = true,
|
||||||
}) + 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
|
||||||
|
@ -173,14 +167,15 @@ function mcl_burning.set_on_fire(obj, burn_time, reason)
|
||||||
hud_elem_type = "image",
|
hud_elem_type = "image",
|
||||||
position = {x = 0.5, y = 0.5},
|
position = {x = 0.5, y = 0.5},
|
||||||
scale = {x = -100, y = -100},
|
scale = {x = -100, y = -100},
|
||||||
text = "fire_basic_flame.png",
|
text = "mcl_burning_hud_flame_animated.png",
|
||||||
z_index = 1000,
|
z_index = 1000,
|
||||||
}) + 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)
|
||||||
|
|
||||||
local fire_entity = minetest.add_entity(obj:get_pos(), "mcl_burning:fire")
|
local fire_entity = minetest.add_entity(obj:get_pos(), "mcl_burning:fire")
|
||||||
local minp, maxp = mcl_burning.get_collisionbox(obj)
|
local minp, maxp = mcl_burning.get_collisionbox(obj)
|
||||||
|
@ -203,8 +198,8 @@ end
|
||||||
|
|
||||||
function mcl_burning.extinguish(obj)
|
function mcl_burning.extinguish(obj)
|
||||||
if mcl_burning.is_burning(obj) then
|
if mcl_burning.is_burning(obj) then
|
||||||
local sound_id = mcl_burning.get(obj, "int", "sound_id") - 1
|
--local sound_id = mcl_burning.get(obj, "int", "sound_id") - 1
|
||||||
minetest.sound_stop(sound_id)
|
--minetest.sound_stop(sound_id)
|
||||||
|
|
||||||
if obj:is_player() then
|
if obj:is_player() then
|
||||||
local hud_id = mcl_burning.get(obj, "int", "hud_id") - 1
|
local hud_id = mcl_burning.get(obj, "int", "hud_id") - 1
|
||||||
|
@ -215,7 +210,7 @@ function mcl_burning.extinguish(obj)
|
||||||
mcl_burning.set(obj, "float", "burn_time")
|
mcl_burning.set(obj, "float", "burn_time")
|
||||||
mcl_burning.set(obj, "float", "damage_timer")
|
mcl_burning.set(obj, "float", "damage_timer")
|
||||||
mcl_burning.set(obj, "int", "hud_id")
|
mcl_burning.set(obj, "int", "hud_id")
|
||||||
mcl_burning.set(obj, "int", "sound_id")
|
--mcl_burning.set(obj, "int", "sound_id")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -276,7 +271,7 @@ function mcl_burning.fire_entity_step(self, dtime)
|
||||||
if not parent or not mcl_burning.is_burning(parent) then
|
if not parent or not mcl_burning.is_burning(parent) then
|
||||||
do_remove = true
|
do_remove = true
|
||||||
else
|
else
|
||||||
for _, other in ipairs(minetest.get_objects_inside_radius(obj:get_pos(), 0)) do
|
for _, other in pairs(minetest.get_objects_inside_radius(obj:get_pos(), 0)) do
|
||||||
local luaentity = obj:get_luaentity()
|
local luaentity = obj:get_luaentity()
|
||||||
if luaentity and luaentity.name == "mcl_burning:fire" and not luaentity.doing_step and not luaentity.removed then
|
if luaentity and luaentity.name == "mcl_burning:fire" and not luaentity.doing_step and not luaentity.removed then
|
||||||
do_remove = true
|
do_remove = true
|
||||||
|
@ -294,7 +289,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 >= ( 1 / mcl_burning.animation_fps ) then
|
if animation_timer >= 0.015 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
|
||||||
|
@ -305,48 +300,3 @@ 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,8 +2,7 @@ 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")
|
||||||
|
@ -23,7 +22,7 @@ minetest.register_entity("mcl_burning:fire", {
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.register_globalstep(function(dtime)
|
minetest.register_globalstep(function(dtime)
|
||||||
for _, player in ipairs(minetest.get_connected_players()) do
|
for _, player in pairs(minetest.get_connected_players()) do
|
||||||
mcl_burning.tick(player, dtime)
|
mcl_burning.tick(player, dtime)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
name = mcl_falling_nodes
|
name = mcl_falling_nodes
|
||||||
|
author = Wuzzy
|
||||||
description = Falling node entities, Minecraft-style
|
description = Falling node entities, Minecraft-style
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
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
|
||||||
|
@ -55,14 +54,14 @@ local disable_physics = function(object, luaentity, ignore_check, reset_movement
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.register_globalstep(function(dtime)
|
minetest.register_globalstep(function(dtime)
|
||||||
for _,player in ipairs(minetest.get_connected_players()) do
|
for _,player in pairs(minetest.get_connected_players()) do
|
||||||
if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then
|
if player:get_hp() > 0 or not minetest.settings:get_bool("enable_damage") then
|
||||||
local pos = player:get_pos()
|
local pos = player:get_pos()
|
||||||
local inv = player:get_inventory()
|
local inv = player:get_inventory()
|
||||||
local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z}
|
local checkpos = {x=pos.x,y=pos.y + item_drop_settings.player_collect_height,z=pos.z}
|
||||||
|
|
||||||
--magnet and collection
|
--magnet and collection
|
||||||
for _,object in ipairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do
|
for _,object in pairs(minetest.get_objects_inside_radius(checkpos, item_drop_settings.xp_radius_magnet)) do
|
||||||
if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then
|
if not object:is_player() and vector.distance(checkpos, object:get_pos()) < item_drop_settings.radius_magnet and object:get_luaentity() and object:get_luaentity().name == "__builtin:item" and object:get_luaentity()._magnet_timer and (object:get_luaentity()._insta_collect or (object:get_luaentity().age > item_drop_settings.age)) then
|
||||||
object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime
|
object:get_luaentity()._magnet_timer = object:get_luaentity()._magnet_timer + dtime
|
||||||
local collected = false
|
local collected = false
|
||||||
|
@ -449,7 +448,7 @@ minetest.register_entity(":__builtin:item", {
|
||||||
end,
|
end,
|
||||||
|
|
||||||
get_staticdata = function(self)
|
get_staticdata = function(self)
|
||||||
local data = minetest.serialize({
|
return minetest.serialize({
|
||||||
itemstring = self.itemstring,
|
itemstring = self.itemstring,
|
||||||
always_collect = self.always_collect,
|
always_collect = self.always_collect,
|
||||||
age = self.age,
|
age = self.age,
|
||||||
|
@ -457,39 +456,6 @@ 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)
|
||||||
|
@ -762,7 +728,7 @@ minetest.register_entity(":__builtin:item", {
|
||||||
if self.physical_state then
|
if self.physical_state then
|
||||||
local own_stack = ItemStack(self.object:get_luaentity().itemstring)
|
local own_stack = ItemStack(self.object:get_luaentity().itemstring)
|
||||||
-- Merge with close entities of the same item
|
-- Merge with close entities of the same item
|
||||||
for _, object in ipairs(minetest.get_objects_inside_radius(p, 0.8)) do
|
for _, object in pairs(minetest.get_objects_inside_radius(p, 0.8)) do
|
||||||
local obj = object:get_luaentity()
|
local obj = object:get_luaentity()
|
||||||
if obj and obj.name == "__builtin:item"
|
if obj and obj.name == "__builtin:item"
|
||||||
and obj.physical_state == false then
|
and obj.physical_state == false then
|
||||||
|
@ -782,29 +748,3 @@ 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,3 +1,4 @@
|
||||||
name = mcl_item_entity
|
name = mcl_item_entity
|
||||||
|
author = PilzAdam
|
||||||
description = Dropped items will be attracted to the player like a magnet.
|
description = Dropped items will be attracted to the player like a magnet.
|
||||||
depends = flowlib, mcl_enchanting
|
depends = flowlib, mcl_enchanting
|
||||||
|
|
|
@ -663,6 +663,8 @@ register_minecart(
|
||||||
{"mcl_minecarts:minecart", "mcl_chests:chest"},
|
{"mcl_minecarts:minecart", "mcl_chests:chest"},
|
||||||
nil, nil, false)
|
nil, nil, false)
|
||||||
|
|
||||||
|
mcl_wip.register_wip_item("mcl_minecarts:chest_minecart")
|
||||||
|
|
||||||
-- Minecart with Furnace
|
-- Minecart with Furnace
|
||||||
register_minecart(
|
register_minecart(
|
||||||
"mcl_minecarts:furnace_minecart",
|
"mcl_minecarts:furnace_minecart",
|
||||||
|
@ -717,6 +719,8 @@ register_minecart(
|
||||||
end, nil, false
|
end, nil, false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
mcl_wip.register_wip_item("mcl_minecarts:furnace_minecart")
|
||||||
|
|
||||||
-- Minecart with Command Block
|
-- Minecart with Command Block
|
||||||
register_minecart(
|
register_minecart(
|
||||||
"mcl_minecarts:command_block_minecart",
|
"mcl_minecarts:command_block_minecart",
|
||||||
|
@ -738,6 +742,8 @@ register_minecart(
|
||||||
nil, nil, false
|
nil, nil, false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
mcl_wip.register_wip_item("mcl_minecarts:command_block_minecart")
|
||||||
|
|
||||||
-- Minecart with Hopper
|
-- Minecart with Hopper
|
||||||
register_minecart(
|
register_minecart(
|
||||||
"mcl_minecarts:hopper_minecart",
|
"mcl_minecarts:hopper_minecart",
|
||||||
|
@ -756,6 +762,8 @@ register_minecart(
|
||||||
nil, nil, false
|
nil, nil, false
|
||||||
)
|
)
|
||||||
|
|
||||||
|
mcl_wip.register_wip_item("mcl_minecarts:hopper_minecart")
|
||||||
|
|
||||||
-- Minecart with TNT
|
-- Minecart with TNT
|
||||||
register_minecart(
|
register_minecart(
|
||||||
"mcl_minecarts:tnt_minecart",
|
"mcl_minecarts:tnt_minecart",
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
name = mcl_minecarts
|
name = mcl_minecarts
|
||||||
|
author = Krock
|
||||||
description = Minecarts are vehicles to move players quickly on rails.
|
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
|
depends = mcl_explosions, mcl_core, mcl_sounds, mcl_player, mcl_achievements, mcl_chests, mcl_furnaces, mesecons_commandblock, mcl_hoppers, mcl_tnt, mesecons, mcl_wip
|
||||||
optional_depends = doc_identifier
|
optional_depends = doc_identifier
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,6 @@ 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
|
||||||
|
@ -228,7 +226,7 @@ local collision = function(self)
|
||||||
local z = 0
|
local z = 0
|
||||||
local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5
|
local width = -self.collisionbox[1] + self.collisionbox[4] + 0.5
|
||||||
|
|
||||||
for _,object in ipairs(minetest.get_objects_inside_radius(pos, width)) do
|
for _,object in pairs(minetest.get_objects_inside_radius(pos, width)) do
|
||||||
|
|
||||||
if object:is_player()
|
if object:is_player()
|
||||||
or (object:get_luaentity()._cmi_is_mob == true and object ~= self.object) then
|
or (object:get_luaentity()._cmi_is_mob == true and object ~= self.object) then
|
||||||
|
@ -753,10 +751,10 @@ local check_for_death = function(self, cause, cmi_cause)
|
||||||
|
|
||||||
-- play damage sound if health was reduced and make mob flash red.
|
-- play damage sound if health was reduced and make mob flash red.
|
||||||
if damaged then
|
if damaged then
|
||||||
add_texture_mod(self, "^[colorize:#FF000040")
|
add_texture_mod(self, "^[colorize:red:130")
|
||||||
minetest.after(.2, function(self)
|
minetest.after(.2, function(self)
|
||||||
if self and self.object then
|
if self and self.object then
|
||||||
remove_texture_mod(self, "^[colorize:#FF000040")
|
remove_texture_mod(self, "^[colorize:red:130")
|
||||||
end
|
end
|
||||||
end, self)
|
end, self)
|
||||||
mob_sound(self, "damage")
|
mob_sound(self, "damage")
|
||||||
|
@ -1049,8 +1047,13 @@ local do_env_damage = function(self)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Use get_node_light for Minetest version 5.3 where get_natural_light
|
||||||
|
-- does not exist yet.
|
||||||
|
local get_light = minetest.get_natural_light or minetest.get_node_light
|
||||||
|
local sunlight = get_light(pos, self.time_of_day)
|
||||||
|
|
||||||
-- bright light harms mob
|
-- bright light harms mob
|
||||||
if self.light_damage ~= 0 and (minetest.get_node_light(pos) or 0) > 12 then
|
if self.light_damage ~= 0 and (sunlight or 0) > 12 then
|
||||||
if deal_light_damage(self, pos, self.light_damage) then
|
if deal_light_damage(self, pos, self.light_damage) then
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
@ -1059,7 +1062,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) == LIGHT_SUN and dim == "overworld" then
|
if (self.sunlight_damage ~= 0 or self.ignited_by_sunlight) and (sunlight or 0) >= minetest.LIGHT_MAX and dim == "overworld" then
|
||||||
if self.ignited_by_sunlight then
|
if self.ignited_by_sunlight then
|
||||||
mcl_burning.set_on_fire(self.object, 10)
|
mcl_burning.set_on_fire(self.object, 10)
|
||||||
else
|
else
|
||||||
|
@ -2823,7 +2826,7 @@ local falling = function(self, pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
if mcl_portals ~= nil then
|
if mcl_portals ~= nil then
|
||||||
if mcl_portals.nether_portal_cooloff[self.object] then
|
if mcl_portals.nether_portal_cooloff(self.object) then
|
||||||
return false -- mob has teleported through Nether portal - it's 99% not falling
|
return false -- mob has teleported through Nether portal - it's 99% not falling
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -4578,9 +4581,9 @@ local timer = 0
|
||||||
minetest.register_globalstep(function(dtime)
|
minetest.register_globalstep(function(dtime)
|
||||||
timer = timer + dtime
|
timer = timer + dtime
|
||||||
if timer < 1 then return end
|
if timer < 1 then return end
|
||||||
for _, player in ipairs(minetest.get_connected_players()) do
|
for _, player in pairs(minetest.get_connected_players()) do
|
||||||
local pos = player:get_pos()
|
local pos = player:get_pos()
|
||||||
for _, obj in ipairs(minetest.get_objects_inside_radius(pos, 47)) do
|
for _, obj in pairs(minetest.get_objects_inside_radius(pos, 47)) do
|
||||||
local lua = obj:get_luaentity()
|
local lua = obj:get_luaentity()
|
||||||
if lua and lua._cmi_is_mob then
|
if lua and lua._cmi_is_mob then
|
||||||
lua.lifetimer = math.max(20, lua.lifetimer)
|
lua.lifetimer = math.max(20, lua.lifetimer)
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
name = mcl_mobs
|
name = mcl_mobs
|
||||||
|
author = PilzAdam
|
||||||
|
description = Adds a mob API for mods to add animals or monsters, etc.
|
||||||
depends = mcl_particles
|
depends = mcl_particles
|
||||||
optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, lucky_block, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience
|
optional_depends = mcl_weather, mcl_explosions, mcl_hunger, mcl_worlds, invisibility, lucky_block, cmi, doc_identifier, mcl_armor, mcl_portals, mcl_experience
|
||||||
description = Adds a mob API for mods to add animals or monsters, etc.
|
|
||||||
|
|
|
@ -154,7 +154,7 @@ function mobs.attach(entity, player)
|
||||||
minetest.after(0.2, function(name)
|
minetest.after(0.2, function(name)
|
||||||
local player = minetest.get_player_by_name(name)
|
local player = minetest.get_player_by_name(name)
|
||||||
if player then
|
if player then
|
||||||
mcl_player.player_set_animation(player, "sit" , 30)
|
mcl_player.player_set_animation(player, "sit_mount" , 30)
|
||||||
end
|
end
|
||||||
end, player:get_player_name())
|
end, player:get_player_name())
|
||||||
|
|
||||||
|
|
|
@ -191,6 +191,14 @@ minetest.register_craftitem("mcl_paintings:painting", {
|
||||||
if pointed_thing.type ~= "node" then
|
if pointed_thing.type ~= "node" then
|
||||||
return itemstack
|
return itemstack
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local node = minetest.get_node(pointed_thing.under)
|
||||||
|
if placer and not placer:get_player_control().sneak then
|
||||||
|
if minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].on_rightclick then
|
||||||
|
return minetest.registered_nodes[node.name].on_rightclick(pointed_thing.under, node, placer, itemstack) or itemstack
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local dir = vector.subtract(pointed_thing.above, pointed_thing.under)
|
local dir = vector.subtract(pointed_thing.above, pointed_thing.under)
|
||||||
dir = vector.normalize(dir)
|
dir = vector.normalize(dir)
|
||||||
if dir.y ~= 0 then
|
if dir.y ~= 0 then
|
||||||
|
@ -293,6 +301,8 @@ minetest.register_craftitem("mcl_paintings:painting", {
|
||||||
end,
|
end,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
mcl_wip.register_wip_item("mcl_paintings:painting")
|
||||||
|
|
||||||
minetest.register_craft({
|
minetest.register_craft({
|
||||||
output = "mcl_paintings:painting",
|
output = "mcl_paintings:painting",
|
||||||
recipe = {
|
recipe = {
|
||||||
|
|
|
@ -1 +1,5 @@
|
||||||
name = mcl_paintings
|
name = mcl_paintings
|
||||||
|
author = Wuzzy
|
||||||
|
description = The paintings mod for MCL2
|
||||||
|
depends = mcl_wip
|
||||||
|
|
||||||
|
|
|
@ -122,7 +122,7 @@ local arrows = {
|
||||||
}
|
}
|
||||||
|
|
||||||
local throwing_shoot_arrow = function(itemstack, player)
|
local throwing_shoot_arrow = function(itemstack, player)
|
||||||
for _,arrow in ipairs(arrows) do
|
for _,arrow in pairs(arrows) do
|
||||||
if player:get_inventory():get_stack("main", player:get_wield_index()+1):get_name() == arrow[1] then
|
if player:get_inventory():get_stack("main", player:get_wield_index()+1):get_name() == arrow[1] then
|
||||||
if not minetest.is_creative_enabled(player:get_player_name()) then
|
if not minetest.is_creative_enabled(player:get_player_name()) then
|
||||||
player:get_inventory():remove_item("main", arrow[1])
|
player:get_inventory():remove_item("main", arrow[1])
|
||||||
|
|
|
@ -105,3 +105,5 @@ mobs:register_arrow("mobs_mc:dragon_fireball", {
|
||||||
})
|
})
|
||||||
|
|
||||||
mobs:register_egg("mobs_mc:enderdragon", S("Ender Dragon"), "mobs_mc_spawn_icon_dragon.png", 0, true)
|
mobs:register_egg("mobs_mc:enderdragon", S("Ender Dragon"), "mobs_mc_spawn_icon_dragon.png", 0, true)
|
||||||
|
|
||||||
|
mcl_wip.register_wip_item("mobs_mc:enderdragon")
|
||||||
|
|
|
@ -451,6 +451,6 @@ mobs:spawn_specific("mobs_mc:donkey", mobs_mc.spawn.grassland_savanna, {"air"},
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0)
|
mobs:register_egg("mobs_mc:horse", S("Horse"), "mobs_mc_spawn_icon_horse.png", 0)
|
||||||
mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.png", 0)
|
mobs:register_egg("mobs_mc:skeleton_horse", S("Skeleton Horse"), "mobs_mc_spawn_icon_horse_skeleton.png", 0)
|
||||||
mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "mobs_mc_spawn_icon_horse_zombie.png", 0)
|
--mobs:register_egg("mobs_mc:zombie_horse", S("Zombie Horse"), "mobs_mc_spawn_icon_horse_zombie.png", 0)
|
||||||
mobs:register_egg("mobs_mc:donkey", S("Donkey"), "mobs_mc_spawn_icon_donkey.png", 0)
|
mobs:register_egg("mobs_mc:donkey", S("Donkey"), "mobs_mc_spawn_icon_donkey.png", 0)
|
||||||
mobs:register_egg("mobs_mc:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0)
|
mobs:register_egg("mobs_mc:mule", S("Mule"), "mobs_mc_spawn_icon_mule.png", 0)
|
||||||
|
|
|
@ -28,7 +28,6 @@ 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,7 +28,6 @@ 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,7 +28,6 @@ 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,7 +28,6 @@ Pig=Свинья
|
||||||
Polar Bear=Полярный медведь
|
Polar Bear=Полярный медведь
|
||||||
Rabbit=Кролик
|
Rabbit=Кролик
|
||||||
Killer Bunny=Кролик-убийца
|
Killer Bunny=Кролик-убийца
|
||||||
The Killer Bunny=Кролик-убийца
|
|
||||||
Sheep=Овца
|
Sheep=Овца
|
||||||
Shulker=Шалкер
|
Shulker=Шалкер
|
||||||
Silverfish=Чешуйница
|
Silverfish=Чешуйница
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
name = mobs_mc
|
name = mobs_mc
|
||||||
|
author = maikerumine
|
||||||
description = Adds Minecraft-like monsters and animals.
|
description = Adds Minecraft-like monsters and animals.
|
||||||
depends = mcl_init, mcl_particles, mcl_mobs
|
depends = mcl_init, mcl_particles, mcl_mobs, mcl_wip
|
||||||
optional_depends = default, mcl_tnt, mcl_bows, mcl_throwing, mcl_fishing, bones, mesecons_materials, mobs_mc_gameconfig, doc_items
|
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 = S("The Killer Bunny")
|
self.nametag = "The Killer Bunny"
|
||||||
self._killer_bunny_nametag_set = true
|
self._killer_bunny_nametag_set = true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 11 KiB |
|
@ -960,7 +960,7 @@ mobs:register_mob("mobs_mc:villager", {
|
||||||
"mobs_mc_villager_smith.png", --hat
|
"mobs_mc_villager_smith.png", --hat
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=2.75, y=2.75},
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
walk_velocity = 1.2,
|
walk_velocity = 1.2,
|
||||||
run_velocity = 2.4,
|
run_velocity = 2.4,
|
||||||
|
|
|
@ -28,7 +28,7 @@ mobs:register_mob("mobs_mc:evoker", {
|
||||||
"blank.png", --no hat
|
"blank.png", --no hat
|
||||||
-- TODO: Attack glow
|
-- TODO: Attack glow
|
||||||
} },
|
} },
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=2.75, y=2.75},
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
damage = 6,
|
damage = 6,
|
||||||
walk_velocity = 0.2,
|
walk_velocity = 0.2,
|
||||||
|
|
|
@ -36,7 +36,7 @@ mobs:register_mob("mobs_mc:illusioner", {
|
||||||
-- TODO: more sounds
|
-- TODO: more sounds
|
||||||
distance = 16,
|
distance = 16,
|
||||||
},
|
},
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=2.75, y=2.75},
|
||||||
walk_velocity = 0.6,
|
walk_velocity = 0.6,
|
||||||
run_velocity = 2,
|
run_velocity = 2,
|
||||||
jump = true,
|
jump = true,
|
||||||
|
|
|
@ -30,7 +30,7 @@ mobs:register_mob("mobs_mc:vindicator", {
|
||||||
-- TODO: Glow when attacking (mobs_mc_vindicator.png)
|
-- TODO: Glow when attacking (mobs_mc_vindicator.png)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=2.75, y=2.75},
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
damage = 13,
|
damage = 13,
|
||||||
reach = 2,
|
reach = 2,
|
||||||
|
|
|
@ -45,7 +45,7 @@ mobs:register_mob("mobs_mc:villager_zombie", {
|
||||||
{"mobs_mc_zombie_smith.png"},
|
{"mobs_mc_zombie_smith.png"},
|
||||||
{"mobs_mc_zombie_villager.png"}
|
{"mobs_mc_zombie_villager.png"}
|
||||||
},
|
},
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=2.75, y=2.75},
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
damage = 3,
|
damage = 3,
|
||||||
reach = 2,
|
reach = 2,
|
||||||
|
|
|
@ -25,7 +25,7 @@ mobs:register_mob("mobs_mc:witch", {
|
||||||
textures = {
|
textures = {
|
||||||
{"mobs_mc_witch.png"},
|
{"mobs_mc_witch.png"},
|
||||||
},
|
},
|
||||||
visual_size = {x=3, y=3},
|
visual_size = {x=2.75, y=2.75},
|
||||||
makes_footstep_sound = true,
|
makes_footstep_sound = true,
|
||||||
damage = 2,
|
damage = 2,
|
||||||
reach = 2,
|
reach = 2,
|
||||||
|
@ -104,3 +104,5 @@ mobs:register_arrow("mobs_mc:potion_arrow", {
|
||||||
|
|
||||||
-- spawn eggs
|
-- spawn eggs
|
||||||
mobs:register_egg("mobs_mc:witch", S("Witch"), "mobs_mc_spawn_icon_witch.png", 0, true)
|
mobs:register_egg("mobs_mc:witch", S("Witch"), "mobs_mc_spawn_icon_witch.png", 0, true)
|
||||||
|
|
||||||
|
mcl_wip.register_wip_item("mobs_mc:witch")
|
||||||
|
|
|
@ -106,3 +106,5 @@ mobs:register_arrow("mobs_mc:wither_skull", {
|
||||||
|
|
||||||
--Spawn egg
|
--Spawn egg
|
||||||
mobs:register_egg("mobs_mc:wither", S("Wither"), "mobs_mc_spawn_icon_wither.png", 0, true)
|
mobs:register_egg("mobs_mc:wither", S("Wither"), "mobs_mc_spawn_icon_wither.png", 0, true)
|
||||||
|
|
||||||
|
mcl_wip.register_wip_item("mobs_mc:wither")
|
|
@ -1,2 +1,4 @@
|
||||||
name = mobs_mc_gameconfig
|
name = mobs_mc_gameconfig
|
||||||
|
author = Wuzzy
|
||||||
|
description = mobs_mc game configuration for MCL2
|
||||||
depends = mcl_init, mcl_core
|
depends = mcl_init, mcl_core
|
||||||
|
|
|
@ -11,6 +11,18 @@ of the license, or (at your option) any later version.
|
||||||
|
|
||||||
local S = minetest.get_translator("lightning")
|
local S = minetest.get_translator("lightning")
|
||||||
|
|
||||||
|
local has_mcl_death_msg = minetest.get_modpath("mcl_death_messages")
|
||||||
|
local get_connected_players = minetest.get_connected_players
|
||||||
|
local line_of_sight = minetest.line_of_sight
|
||||||
|
local get_node = minetest.get_node
|
||||||
|
local set_node = minetest.set_node
|
||||||
|
local sound_play = minetest.sound_play
|
||||||
|
local add_particlespawner = minetest.add_particlespawner
|
||||||
|
local after = minetest.after
|
||||||
|
local add_entity = minetest.add_entity
|
||||||
|
local get_objects_inside_radius = minetest.get_objects_inside_radius
|
||||||
|
local get_item_group = minetest.get_item_group
|
||||||
|
|
||||||
lightning = {}
|
lightning = {}
|
||||||
|
|
||||||
lightning.interval_low = 17
|
lightning.interval_low = 17
|
||||||
|
@ -45,7 +57,7 @@ minetest.register_globalstep(revertsky)
|
||||||
-- select a random strike point, midpoint
|
-- select a random strike point, midpoint
|
||||||
local function choose_pos(pos)
|
local function choose_pos(pos)
|
||||||
if not pos then
|
if not pos then
|
||||||
local playerlist = minetest.get_connected_players()
|
local playerlist = get_connected_players()
|
||||||
local playercount = table.getn(playerlist)
|
local playercount = table.getn(playerlist)
|
||||||
|
|
||||||
-- nobody on
|
-- nobody on
|
||||||
|
@ -67,14 +79,14 @@ local function choose_pos(pos)
|
||||||
pos.z = math.floor(pos.z - (lightning.range_h / 2) + rng:next(1, lightning.range_h))
|
pos.z = math.floor(pos.z - (lightning.range_h / 2) + rng:next(1, lightning.range_h))
|
||||||
end
|
end
|
||||||
|
|
||||||
local b, pos2 = minetest.line_of_sight(pos, {x = pos.x, y = pos.y - lightning.range_v, z = pos.z}, 1)
|
local b, pos2 = line_of_sight(pos, {x = pos.x, y = pos.y - lightning.range_v, z = pos.z}, 1)
|
||||||
|
|
||||||
-- nothing but air found
|
-- nothing but air found
|
||||||
if b then
|
if b then
|
||||||
return nil, nil
|
return nil, nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local n = minetest.get_node({x = pos2.x, y = pos2.y - 1/2, z = pos2.z})
|
local n = get_node({x = pos2.x, y = pos2.y - 1/2, z = pos2.z})
|
||||||
if n.name == "air" or n.name == "ignore" then
|
if n.name == "air" or n.name == "ignore" then
|
||||||
return nil, nil
|
return nil, nil
|
||||||
end
|
end
|
||||||
|
@ -87,7 +99,7 @@ end
|
||||||
-- * returns: bool - success if a strike happened
|
-- * returns: bool - success if a strike happened
|
||||||
lightning.strike = function(pos)
|
lightning.strike = function(pos)
|
||||||
if lightning.auto then
|
if lightning.auto then
|
||||||
minetest.after(rng:next(lightning.interval_low, lightning.interval_high), lightning.strike)
|
after(rng:next(lightning.interval_low, lightning.interval_high), lightning.strike)
|
||||||
end
|
end
|
||||||
|
|
||||||
local pos2
|
local pos2
|
||||||
|
@ -97,7 +109,7 @@ lightning.strike = function(pos)
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
minetest.add_particlespawner({
|
add_particlespawner({
|
||||||
amount = 1,
|
amount = 1,
|
||||||
time = 0.2,
|
time = 0.2,
|
||||||
-- make it hit the top of a block exactly with the bottom
|
-- make it hit the top of a block exactly with the bottom
|
||||||
|
@ -120,16 +132,16 @@ lightning.strike = function(pos)
|
||||||
glow = minetest.LIGHT_MAX,
|
glow = minetest.LIGHT_MAX,
|
||||||
})
|
})
|
||||||
|
|
||||||
minetest.sound_play({ name = "lightning_thunder", gain = 10 }, { pos = pos, max_hear_distance = 500 }, true)
|
sound_play({ name = "lightning_thunder", gain = 10 }, { pos = pos, max_hear_distance = 500 }, true)
|
||||||
|
|
||||||
-- damage nearby objects, transform mobs
|
-- damage nearby objects, transform mobs
|
||||||
local objs = minetest.get_objects_inside_radius(pos2, 3.5)
|
local objs = get_objects_inside_radius(pos2, 3.5)
|
||||||
for o=1, #objs do
|
for o=1, #objs do
|
||||||
local obj = objs[o]
|
local obj = objs[o]
|
||||||
local lua = obj:get_luaentity()
|
local lua = obj:get_luaentity()
|
||||||
if obj:is_player() then
|
if obj:is_player() then
|
||||||
-- Player damage
|
-- Player damage
|
||||||
if minetest.get_modpath("mcl_death_messages") then
|
if has_mcl_death_msg then
|
||||||
mcl_death_messages.player_damage(obj, S("@1 was struck by lightning.", obj:get_player_name()))
|
mcl_death_messages.player_damage(obj, S("@1 was struck by lightning.", obj:get_player_name()))
|
||||||
end
|
end
|
||||||
obj:set_hp(obj:get_hp()-5, { type = "punch", from = "mod" })
|
obj:set_hp(obj:get_hp()-5, { type = "punch", from = "mod" })
|
||||||
|
@ -139,7 +151,7 @@ lightning.strike = function(pos)
|
||||||
if lua.name == "mobs_mc:pig" then
|
if lua.name == "mobs_mc:pig" then
|
||||||
local rot = obj:get_yaw()
|
local rot = obj:get_yaw()
|
||||||
obj:remove()
|
obj:remove()
|
||||||
obj = minetest.add_entity(pos2, "mobs_mc:pigman")
|
obj = add_entity(pos2, "mobs_mc:pigman")
|
||||||
obj:set_yaw(rot)
|
obj:set_yaw(rot)
|
||||||
-- mooshroom: toggle color red/brown (no damage)
|
-- mooshroom: toggle color red/brown (no damage)
|
||||||
elseif lua.name == "mobs_mc:mooshroom" then
|
elseif lua.name == "mobs_mc:mooshroom" then
|
||||||
|
@ -163,7 +175,7 @@ lightning.strike = function(pos)
|
||||||
elseif lua.name == "mobs_mc:creeper" then
|
elseif lua.name == "mobs_mc:creeper" then
|
||||||
local rot = obj:get_yaw()
|
local rot = obj:get_yaw()
|
||||||
obj:remove()
|
obj:remove()
|
||||||
obj = minetest.add_entity(pos2, "mobs_mc:creeper_charged")
|
obj = add_entity(pos2, "mobs_mc:creeper_charged")
|
||||||
obj:set_yaw(rot)
|
obj:set_yaw(rot)
|
||||||
-- Other mobs: Just damage
|
-- Other mobs: Just damage
|
||||||
else
|
else
|
||||||
|
@ -172,7 +184,7 @@ lightning.strike = function(pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local playerlist = minetest.get_connected_players()
|
local playerlist = get_connected_players()
|
||||||
for i = 1, #playerlist do
|
for i = 1, #playerlist do
|
||||||
local player = playerlist[i]
|
local player = playerlist[i]
|
||||||
local sky = {}
|
local sky = {}
|
||||||
|
@ -197,25 +209,25 @@ lightning.strike = function(pos)
|
||||||
if rng:next(1,100) <= 3 then
|
if rng:next(1,100) <= 3 then
|
||||||
skeleton_lightning = true
|
skeleton_lightning = true
|
||||||
end
|
end
|
||||||
if minetest.get_item_group(minetest.get_node({x = pos2.x, y = pos2.y - 1, z = pos2.z}).name, "liquid") < 1 then
|
if get_item_group(get_node({x = pos2.x, y = pos2.y - 1, z = pos2.z}).name, "liquid") < 1 then
|
||||||
if minetest.get_node(pos2).name == "air" then
|
if get_node(pos2).name == "air" then
|
||||||
-- Low chance for a lightning to spawn skeleton horse + skeletons
|
-- Low chance for a lightning to spawn skeleton horse + skeletons
|
||||||
if skeleton_lightning then
|
if skeleton_lightning then
|
||||||
minetest.add_entity(pos2, "mobs_mc:skeleton_horse")
|
add_entity(pos2, "mobs_mc:skeleton_horse")
|
||||||
|
|
||||||
local angle, posadd
|
local angle, posadd
|
||||||
angle = math.random(0, math.pi*2)
|
angle = math.random(0, math.pi*2)
|
||||||
for i=1,3 do
|
for i=1,3 do
|
||||||
posadd = {x=math.cos(angle),y=0,z=math.sin(angle)}
|
posadd = {x=math.cos(angle),y=0,z=math.sin(angle)}
|
||||||
posadd = vector.normalize(posadd)
|
posadd = vector.normalize(posadd)
|
||||||
local mob = minetest.add_entity(vector.add(pos2, posadd), "mobs_mc:skeleton")
|
local mob = add_entity(vector.add(pos2, posadd), "mobs_mc:skeleton")
|
||||||
mob:set_yaw(angle-math.pi/2)
|
mob:set_yaw(angle-math.pi/2)
|
||||||
angle = angle + (math.pi*2) / 3
|
angle = angle + (math.pi*2) / 3
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Cause a fire
|
-- Cause a fire
|
||||||
else
|
else
|
||||||
minetest.set_node(pos2, {name = "mcl_fire:fire"})
|
set_node(pos2, {name = "mcl_fire:fire"})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -223,9 +235,9 @@ lightning.strike = function(pos)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- if other mods disable auto lightning during initialization, don't trigger the first lightning.
|
-- if other mods disable auto lightning during initialization, don't trigger the first lightning.
|
||||||
minetest.after(5, function(dtime)
|
after(5, function(dtime)
|
||||||
if lightning.auto then
|
if lightning.auto then
|
||||||
minetest.after(rng:next(lightning.interval_low,
|
after(rng:next(lightning.interval_low,
|
||||||
lightning.interval_high), lightning.strike)
|
lightning.interval_high), lightning.strike)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
name = lightning
|
name = lightning
|
||||||
|
author = sofar
|
||||||
description = A mod that adds thunder and lightning effects.
|
description = A mod that adds thunder and lightning effects.
|
||||||
depends = mcl_fire
|
depends = mcl_fire
|
||||||
optional_depends = mcl_death_messages
|
optional_depends = mcl_death_messages
|
||||||
|
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
name = mcl_moon
|
name = mcl_moon
|
||||||
|
author = Wuzzy
|
||||||
description = Adds moon phases to the game
|
description = Adds moon phases to the game
|
||||||
|
|
|
@ -1,6 +1,14 @@
|
||||||
local S = minetest.get_translator("mcl_void_damage")
|
local S = minetest.get_translator("mcl_void_damage")
|
||||||
local enable_damage = minetest.settings:get_bool("enable_damage")
|
local enable_damage = minetest.settings:get_bool("enable_damage")
|
||||||
|
|
||||||
|
local pos_to_dim = mcl_worlds.pos_to_dimension
|
||||||
|
local dim_change = mcl_worlds.dimension_change
|
||||||
|
local is_in_void = mcl_worlds.is_in_void
|
||||||
|
local get_spawn_pos = mcl_spawn.get_player_spawn_pos
|
||||||
|
local death_msg = mcl_death_messages.player_damage
|
||||||
|
local send_chat = minetest.chat_send_player
|
||||||
|
local get_connected = minetest.get_connected_players
|
||||||
|
|
||||||
local voidtimer = 0
|
local voidtimer = 0
|
||||||
local VOID_DAMAGE_FREQ = 0.5
|
local VOID_DAMAGE_FREQ = 0.5
|
||||||
local VOID_DAMAGE = 4
|
local VOID_DAMAGE = 4
|
||||||
|
@ -33,7 +41,7 @@ minetest.register_on_mods_loaded(function()
|
||||||
self._void_timer = 0
|
self._void_timer = 0
|
||||||
|
|
||||||
local pos = obj:get_pos()
|
local pos = obj:get_pos()
|
||||||
local void, void_deadly = mcl_worlds.is_in_void(pos)
|
local void, void_deadly = is_in_void(pos)
|
||||||
if void_deadly then
|
if void_deadly then
|
||||||
local ent = obj:get_luaentity()
|
local ent = obj:get_luaentity()
|
||||||
obj:remove()
|
obj:remove()
|
||||||
|
@ -51,11 +59,11 @@ minetest.register_globalstep(function(dtime)
|
||||||
if voidtimer > VOID_DAMAGE_FREQ then
|
if voidtimer > VOID_DAMAGE_FREQ then
|
||||||
voidtimer = 0
|
voidtimer = 0
|
||||||
local enable_damage = minetest.settings:get_bool("enable_damage")
|
local enable_damage = minetest.settings:get_bool("enable_damage")
|
||||||
local players = minetest.get_connected_players()
|
local players = get_connected()
|
||||||
for p=1, #players do
|
for p=1, #players do
|
||||||
local player = players[p]
|
local player = players[p]
|
||||||
local pos = player:get_pos()
|
local pos = player:get_pos()
|
||||||
local void, void_deadly = mcl_worlds.is_in_void(pos)
|
local void, void_deadly = is_in_void(pos)
|
||||||
if void_deadly then
|
if void_deadly then
|
||||||
local immortal_val = player:get_armor_groups().immortal
|
local immortal_val = player:get_armor_groups().immortal
|
||||||
local is_immortal = false
|
local is_immortal = false
|
||||||
|
@ -65,14 +73,14 @@ minetest.register_globalstep(function(dtime)
|
||||||
if is_immortal or not enable_damage then
|
if is_immortal or not enable_damage then
|
||||||
-- If damage is disabled, we can't kill players.
|
-- If damage is disabled, we can't kill players.
|
||||||
-- So we just teleport the player back to spawn.
|
-- So we just teleport the player back to spawn.
|
||||||
local spawn = mcl_spawn.get_player_spawn_pos(player)
|
local spawn = get_spawn_pos(player)
|
||||||
player:set_pos(spawn)
|
player:set_pos(spawn)
|
||||||
mcl_worlds.dimension_change(player, mcl_worlds.pos_to_dimension(spawn))
|
dim_change(player, pos_to_dim(spawn))
|
||||||
minetest.chat_send_player(player:get_player_name(), S("The void is off-limits to you!"))
|
send_chat(player:get_player_name(), S("The void is off-limits to you!"))
|
||||||
elseif enable_damage and not is_immortal then
|
elseif enable_damage and not is_immortal then
|
||||||
-- Damage enabled, not immortal: Deal void damage (4 HP / 0.5 seconds)
|
-- Damage enabled, not immortal: Deal void damage (4 HP / 0.5 seconds)
|
||||||
if player:get_hp() > 0 then
|
if player:get_hp() > 0 then
|
||||||
mcl_death_messages.player_damage(player, S("@1 fell into the endless void.", player:get_player_name()))
|
death_msg(player, S("@1 fell into the endless void.", player:get_player_name()))
|
||||||
player:set_hp(player:get_hp() - VOID_DAMAGE)
|
player:set_hp(player:get_hp() - VOID_DAMAGE)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
name = mcl_void_damage
|
name = mcl_void_damage
|
||||||
|
author = Wuzzy
|
||||||
description = Deal damage to entities stuck in the deep void
|
description = Deal damage to entities stuck in the deep void
|
||||||
depends = mcl_worlds, mcl_death_messages
|
depends = mcl_worlds, mcl_death_messages
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
name = mcl_weather
|
name = mcl_weather
|
||||||
|
author = xeranas
|
||||||
description = Weather and sky handling: Rain, snow, thunderstorm, End and Nether ambience
|
description = Weather and sky handling: Rain, snow, thunderstorm, End and Nether ambience
|
||||||
depends = mcl_init, mcl_worlds
|
depends = mcl_init, mcl_worlds
|
||||||
optional_depends = lightning
|
optional_depends = lightning
|
||||||
|
|
|
@ -27,7 +27,7 @@ minetest.register_globalstep(function(dtime)
|
||||||
if timer < 0.7 then return end
|
if timer < 0.7 then return end
|
||||||
timer = 0
|
timer = 0
|
||||||
|
|
||||||
for _, player in ipairs(minetest.get_connected_players()) do
|
for _, player in pairs(minetest.get_connected_players()) do
|
||||||
if not mcl_worlds.has_dust(player:get_pos()) then
|
if not mcl_worlds.has_dust(player:get_pos()) then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
local PARTICLES_COUNT_RAIN = 30
|
local PARTICLES_COUNT_RAIN = 30
|
||||||
local PARTICLES_COUNT_THUNDER = 45
|
local PARTICLES_COUNT_THUNDER = 45
|
||||||
|
|
||||||
|
local get_connected_players = minetest.get_connected_players
|
||||||
|
|
||||||
mcl_weather.rain = {
|
mcl_weather.rain = {
|
||||||
-- max rain particles created at time
|
-- max rain particles created at time
|
||||||
particles_count = PARTICLES_COUNT_RAIN,
|
particles_count = PARTICLES_COUNT_RAIN,
|
||||||
|
@ -36,7 +38,7 @@ mcl_weather.rain.set_sky_box = function()
|
||||||
{r=85, g=86, b=98},
|
{r=85, g=86, b=98},
|
||||||
{r=0, g=0, b=0}})
|
{r=0, g=0, b=0}})
|
||||||
mcl_weather.skycolor.active = true
|
mcl_weather.skycolor.active = true
|
||||||
for _, player in ipairs(minetest.get_connected_players()) do
|
for _, player in pairs(get_connected_players()) do
|
||||||
player:set_clouds({color="#5D5D5FE8"})
|
player:set_clouds({color="#5D5D5FE8"})
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -154,7 +156,7 @@ mcl_weather.rain.clear = function()
|
||||||
mcl_weather.rain.init_done = false
|
mcl_weather.rain.init_done = false
|
||||||
mcl_weather.rain.set_particles_mode("rain")
|
mcl_weather.rain.set_particles_mode("rain")
|
||||||
mcl_weather.skycolor.remove_layer("weather-pack-rain-sky")
|
mcl_weather.skycolor.remove_layer("weather-pack-rain-sky")
|
||||||
for _, player in ipairs(minetest.get_connected_players()) do
|
for _, player in pairs(get_connected_players()) do
|
||||||
mcl_weather.rain.remove_sound(player)
|
mcl_weather.rain.remove_sound(player)
|
||||||
mcl_weather.rain.remove_player(player)
|
mcl_weather.rain.remove_player(player)
|
||||||
end
|
end
|
||||||
|
@ -176,7 +178,7 @@ mcl_weather.rain.make_weather = function()
|
||||||
mcl_weather.rain.init_done = true
|
mcl_weather.rain.init_done = true
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, player in ipairs(minetest.get_connected_players()) do
|
for _, player in pairs(get_connected_players()) do
|
||||||
if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then
|
if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then
|
||||||
mcl_weather.rain.remove_sound(player)
|
mcl_weather.rain.remove_sound(player)
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -43,7 +43,7 @@ mcl_weather.skycolor = {
|
||||||
|
|
||||||
-- Remove layer from colors table
|
-- Remove layer from colors table
|
||||||
remove_layer = function(layer_name)
|
remove_layer = function(layer_name)
|
||||||
for k, name in ipairs(mcl_weather.skycolor.layer_names) do
|
for k, name in pairs(mcl_weather.skycolor.layer_names) do
|
||||||
if name == layer_name then
|
if name == layer_name then
|
||||||
table.remove(mcl_weather.skycolor.layer_names, k)
|
table.remove(mcl_weather.skycolor.layer_names, k)
|
||||||
mcl_weather.skycolor.force_update = true
|
mcl_weather.skycolor.force_update = true
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
local get_connected_players = minetest.get_connected_players
|
||||||
|
|
||||||
mcl_weather.snow = {}
|
mcl_weather.snow = {}
|
||||||
|
|
||||||
mcl_weather.snow.particles_count = 15
|
mcl_weather.snow.particles_count = 15
|
||||||
|
@ -37,7 +39,7 @@ mcl_weather.snow.set_sky_box = function()
|
||||||
{r=85, g=86, b=86},
|
{r=85, g=86, b=86},
|
||||||
{r=0, g=0, b=0}})
|
{r=0, g=0, b=0}})
|
||||||
mcl_weather.skycolor.active = true
|
mcl_weather.skycolor.active = true
|
||||||
for _, player in ipairs(minetest.get_connected_players()) do
|
for _, player in pairs(get_connected_players()) do
|
||||||
player:set_clouds({color="#ADADADE8"})
|
player:set_clouds({color="#ADADADE8"})
|
||||||
end
|
end
|
||||||
mcl_weather.skycolor.active = true
|
mcl_weather.skycolor.active = true
|
||||||
|
@ -71,7 +73,7 @@ minetest.register_globalstep(function(dtime)
|
||||||
mcl_weather.snow.init_done = true
|
mcl_weather.snow.init_done = true
|
||||||
end
|
end
|
||||||
|
|
||||||
for _, player in ipairs(minetest.get_connected_players()) do
|
for _, player in pairs(get_connected_players()) do
|
||||||
if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then
|
if (mcl_weather.is_underwater(player) or not mcl_worlds.has_weather(player:get_pos())) then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
local get_connected_players = minetest.get_connected_players
|
||||||
|
|
||||||
-- turn off lightning mod 'auto mode'
|
-- turn off lightning mod 'auto mode'
|
||||||
lightning.auto = false
|
lightning.auto = false
|
||||||
|
|
||||||
|
@ -25,7 +27,7 @@ minetest.register_globalstep(function(dtime)
|
||||||
{r=40, g=40, b=40},
|
{r=40, g=40, b=40},
|
||||||
{r=0, g=0, b=0}})
|
{r=0, g=0, b=0}})
|
||||||
mcl_weather.skycolor.active = true
|
mcl_weather.skycolor.active = true
|
||||||
for _, player in ipairs(minetest.get_connected_players()) do
|
for _, player in pairs(get_connected_players()) do
|
||||||
player:set_clouds({color="#3D3D3FE8"})
|
player:set_clouds({color="#3D3D3FE8"})
|
||||||
end
|
end
|
||||||
mcl_weather.thunder.init_done = true
|
mcl_weather.thunder.init_done = true
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
name = doc
|
name = doc
|
||||||
optional_depends = unified_inventory, sfinv_buttons, central_message, inventory_plus
|
author = Wuzzy
|
||||||
description = A simple in-game documentation system which enables mods to add help entries based on templates.
|
description = A simple in-game documentation system which enables mods to add help entries based on templates.
|
||||||
|
optional_depends = unified_inventory, sfinv_buttons, central_message, inventory_plus
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
name = doc_identifier
|
name = doc_identifier
|
||||||
|
author = Wuzzy
|
||||||
|
description = Adds a tool which shows help entries about almost anything which it punches.
|
||||||
depends = doc, doc_items
|
depends = doc, doc_items
|
||||||
optional_depends = doc_basics, mcl_core
|
optional_depends = doc_basics, mcl_core
|
||||||
description = Adds a tool which shows help entries about almost anything which it punches.
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
name = doc_items
|
name = doc_items
|
||||||
depends = doc
|
author = Wuzzy
|
||||||
description = Adds automatically generated help texts for items.
|
description = Adds automatically generated help texts for items.
|
||||||
|
depends = doc
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
name = doc
|
|
||||||
description = Provides an extensible in-game help with texts about gameplay basics (such a crafting), items and advanced usage.
|
|
|
@ -1 +1,2 @@
|
||||||
name = doc
|
name = doc
|
||||||
|
description = Provides an extensible in-game help with texts about gameplay basics (such a crafting), items and advanced usage.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
name = mcl_craftguide
|
name = mcl_craftguide
|
||||||
description = The most comprehensive Crafting Guide
|
author = kilbith
|
||||||
on Minetest.
|
description = The most comprehensive Crafting Guide on Minetest.
|
||||||
depends = mcl_core, mcl_compass, mcl_clock, doc
|
depends = mcl_core, mcl_compass, mcl_clock, doc
|
||||||
optional_depends = sfinv, sfinv_buttons
|
optional_depends = sfinv, sfinv_buttons
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
name = mcl_doc
|
name = mcl_doc
|
||||||
|
author = Wuzzy
|
||||||
description = This MineClone 2 mod sets up and configures the Help modpack mods to tailor the help towards MineClone 2.
|
description = This MineClone 2 mod sets up and configures the Help modpack mods to tailor the help towards MineClone 2.
|
||||||
depends = doc, doc_items
|
depends = doc, doc_items
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
name = mcl_doc_basics
|
name = mcl_doc_basics
|
||||||
depends = doc
|
author = Wuzzy
|
||||||
description = Adds some help texts explaining how to use MineClone 2.
|
description = Adds some help texts explaining how to use MineClone 2.
|
||||||
|
depends = doc
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
name = mcl_tt
|
name = mcl_tt
|
||||||
|
author = Wuzzy
|
||||||
|
description = Add MCL2 tooltips
|
||||||
depends = tt, mcl_enchanting
|
depends = tt, mcl_enchanting
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
name = tt
|
name = tt
|
||||||
|
author = Wuzzy
|
||||||
description = Support for custom tooltip extensions for items
|
description = Support for custom tooltip extensions for items
|
||||||
|
|
|
@ -413,7 +413,6 @@ 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})
|
||||||
|
@ -432,7 +431,6 @@ 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
|
||||||
|
@ -513,9 +511,9 @@ local function update_health(player)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- update built-in HUD bars
|
-- update built-in HUD bars
|
||||||
local function update_hud(player)
|
local function update_hud(player, has_damage)
|
||||||
if not player_exists(player) then return end
|
if not player_exists(player) then return end
|
||||||
if minetest.settings:get_bool("enable_damage") then
|
if has_damage then
|
||||||
if hb.settings.forceload_default_hudbars then
|
if hb.settings.forceload_default_hudbars then
|
||||||
hb.unhide_hudbar(player, "health")
|
hb.unhide_hudbar(player, "health")
|
||||||
end
|
end
|
||||||
|
@ -566,10 +564,11 @@ minetest.register_globalstep(function(dtime)
|
||||||
if main_timer > hb.settings.tick or timer > 4 then
|
if main_timer > hb.settings.tick or timer > 4 then
|
||||||
if main_timer > hb.settings.tick then main_timer = 0 end
|
if main_timer > hb.settings.tick then main_timer = 0 end
|
||||||
-- only proceed if damage is enabled
|
-- only proceed if damage is enabled
|
||||||
if minetest.settings:get_bool("enable_damage") or hb.settings.forceload_default_hudbars then
|
local has_dmg = minetest.settings:get_bool("enable_damage")
|
||||||
|
if has_dmg or hb.settings.forceload_default_hudbars then
|
||||||
for _, player in pairs(hb.players) do
|
for _, player in pairs(hb.players) do
|
||||||
-- update all hud elements
|
-- update all hud elements
|
||||||
update_hud(player)
|
update_hud(player, has_dmg)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
name = hudbars
|
name = hudbars
|
||||||
|
author = Wuzzy
|
||||||
description = Replaces the health and breath symbols in the HUD by “progress bars” and shows exact values. Other mods can add more progress bars for custom player stats.
|
description = Replaces the health and breath symbols in the HUD by “progress bars” and shows exact values. Other mods can add more progress bars for custom player stats.
|
||||||
|
|
|
@ -1,2 +1,4 @@
|
||||||
name = mcl_achievements
|
name = mcl_achievements
|
||||||
|
author = Wuzzy
|
||||||
|
description = Adds MCL2 Archivements
|
||||||
depends = awards
|
depends = awards
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
name = mcl_base_textures
|
name = mcl_base_textures
|
||||||
|
author = Wuzzy
|
||||||
description = Provides core textures needed by Minetest.
|
description = Provides core textures needed by Minetest.
|
||||||
|
|
|
@ -3,105 +3,12 @@ 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
|
||||||
|
end
|
||||||
local def = item:get_definition()
|
local def = item:get_definition()
|
||||||
name=def._tt_original_description or def.description
|
return def._tt_original_description or def.description
|
||||||
end
|
end
|
||||||
local sanitized_name, substitution_count = name:gsub("[\r\n]"," ")
|
|
||||||
return sanitized_name
|
|
||||||
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 = {}
|
||||||
|
|
||||||
|
@ -134,9 +41,6 @@ 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."),
|
||||||
},
|
},
|
||||||
|
@ -308,7 +212,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_by_named_mob", name, hittername)
|
msg = dmsg("murder", 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,7 +10,6 @@
|
||||||
@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.
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
@1 drowned.=
|
@1 drowned.=
|
||||||
@1 ran out of oxygen.=
|
@1 ran out of oxygen.=
|
||||||
@1 was killed by @2.=
|
@1 was killed by @2.=
|
||||||
@1 was slain by @2.=
|
|
||||||
@1 was killed.=
|
@1 was killed.=
|
||||||
@1 was killed by a mob.=
|
@1 was killed by a mob.=
|
||||||
@1 was burned to death by a blaze's fireball.=
|
@1 was burned to death by a blaze's fireball.=
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
name = mcl_death_messages
|
name = mcl_death_messages
|
||||||
|
author = 4Evergreen4
|
||||||
description = Shows messages in chat when a player dies.
|
description = Shows messages in chat when a player dies.
|
||||||
|
|
|
@ -312,7 +312,7 @@ function mcl_experience.add_experience(player, experience)
|
||||||
temp_pool.xp = math.min(math.max(temp_pool.xp + experience, 0), max_xp)
|
temp_pool.xp = math.min(math.max(temp_pool.xp + experience, 0), max_xp)
|
||||||
|
|
||||||
if (temp_pool.xp < temp_pool.xp_next_level) and (temp_pool.xp >= old_xp) then
|
if (temp_pool.xp < temp_pool.xp_next_level) and (temp_pool.xp >= old_xp) then
|
||||||
temp_pool.bar = mcl_experience.xp_to_bar(temp_pool.xp, temp_pool.level)
|
temp_pool.bar = temp_pool.bar + temp_pool.bar_step * experience
|
||||||
else
|
else
|
||||||
temp_pool.level = mcl_experience.xp_to_level(temp_pool.xp)
|
temp_pool.level = mcl_experience.xp_to_level(temp_pool.xp)
|
||||||
temp_pool.bar, temp_pool.bar_step, temp_pool.xp_next_level = mcl_experience.xp_to_bar(temp_pool.xp, temp_pool.level)
|
temp_pool.bar, temp_pool.bar_step, temp_pool.xp_next_level = mcl_experience.xp_to_bar(temp_pool.xp, temp_pool.level)
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
name = mcl_experience
|
||||||
|
author = oilboi
|
||||||
|
description = eXPerience mod
|