Compare commits
2 Commits
master
...
csm-enable
Author | SHA1 | Date |
---|---|---|
|
08e2daefb9 | |
|
3ec2d17641 |
|
@ -1,36 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
name: "Bug report"
|
|
||||||
about: "File a bug report"
|
|
||||||
labels:
|
|
||||||
|
|
||||||
- unconfirmed
|
|
||||||
- bug
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Thanks for taking the time to fill out this bug report!
|
|
||||||
|
|
||||||
Please follow our contributing guidelines first:
|
|
||||||
https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CONTRIBUTING.md#rules-about-both-bugs-and-feature-requests
|
|
||||||
|
|
||||||
By submitting this issue, you agree to follow our Code of Conduct:
|
|
||||||
https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CODE_OF_CONDUCT.md
|
|
||||||
-->
|
|
||||||
|
|
||||||
<!--
|
|
||||||
What version of MineClone2 are you using? We do not provide support for outdated versions of MineClone2.
|
|
||||||
Current latest version is listed here, at the top:
|
|
||||||
https://git.minetest.land/MineClone2/MineClone2/tags
|
|
||||||
-->
|
|
||||||
MineClone2 version:
|
|
||||||
|
|
||||||
### What happened?
|
|
||||||
Report about the bug! Please send large log snippets as an attachement file.
|
|
||||||
|
|
||||||
### What should happen:
|
|
||||||
Tell us what should happen!
|
|
||||||
|
|
||||||
### Steps to reproduce
|
|
||||||
Tell us how we can reproduce the bug!
|
|
|
@ -1,26 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
name: "Feature request"
|
|
||||||
about: "File a feature request not in Minecraft"
|
|
||||||
labels:
|
|
||||||
|
|
||||||
- "non-Minecraft feature"
|
|
||||||
- "needs discussion"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Got a new non-Minecraft feature request? Explain to us why we should consider your idea.
|
|
||||||
|
|
||||||
Please follow our contributing guidelines first:
|
|
||||||
https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CONTRIBUTING.md#rules-about-both-bugs-and-feature-requests
|
|
||||||
|
|
||||||
By submitting this issue, you agree to follow our Code of Conduct:
|
|
||||||
https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CODE_OF_CONDUCT.md
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Feature
|
|
||||||
Tell us about your requested feature not in Minecraft!
|
|
||||||
|
|
||||||
### Why
|
|
||||||
Tell us why should we implement it!
|
|
|
@ -1,25 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
name: "Missing Feature request"
|
|
||||||
about: "File a missing feature request in Minecraft but not in MineClone2"
|
|
||||||
labels:
|
|
||||||
|
|
||||||
- "missing feature"
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Thanks for taking the time to fill out this missing feature request!
|
|
||||||
|
|
||||||
Please follow our contributing guidelines first:
|
|
||||||
https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CONTRIBUTING.md#rules-about-both-bugs-and-feature-requests
|
|
||||||
|
|
||||||
By submitting this issue, you agree to follow our Code of Conduct:
|
|
||||||
https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CODE_OF_CONDUCT.md
|
|
||||||
-->
|
|
||||||
|
|
||||||
### Current feature in Minecraft
|
|
||||||
Tell us about the feature currently in Minecraft! What is it like on Minecraft?
|
|
||||||
|
|
||||||
### Current feature in MineClone2
|
|
||||||
Tell us about the feature currently in MineClone2! What is different?
|
|
|
@ -1,20 +0,0 @@
|
||||||
---
|
|
||||||
|
|
||||||
name: "Pull request"
|
|
||||||
about: "Submit a pull request"
|
|
||||||
labels:
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<!--
|
|
||||||
Please follow our contributing guidelines first:
|
|
||||||
https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CONTRIBUTING.md#how-you-can-help-as-a-programmer
|
|
||||||
|
|
||||||
By submitting this pull request, you agree to follow our Code of Conduct:
|
|
||||||
https://git.minetest.land/MineClone2/MineClone2/src/branch/master/CODE_OF_CONDUCT.md
|
|
||||||
-->
|
|
||||||
|
|
||||||
Tell us about your pull request! Reference related issues, if necessary
|
|
||||||
|
|
||||||
### Testing
|
|
||||||
Tell us how to test your changes!
|
|
|
@ -4,4 +4,3 @@
|
||||||
*.blend2
|
*.blend2
|
||||||
*.blend3
|
*.blend3
|
||||||
/.idea/
|
/.idea/
|
||||||
*.xcf
|
|
1
API.md
|
@ -41,7 +41,6 @@ A lot of things are possible by using one of the APIs in the mods. Note that not
|
||||||
* Beds: `ITEMS/mcl_beds`
|
* Beds: `ITEMS/mcl_beds`
|
||||||
* Buckets: `ITEMS/mcl_buckets`
|
* Buckets: `ITEMS/mcl_buckets`
|
||||||
* Dispenser support: `ITEMS/REDSTONE/mcl_dispensers`
|
* Dispenser support: `ITEMS/REDSTONE/mcl_dispensers`
|
||||||
* Campfires: `ITEMS/mcl_campfires`
|
|
||||||
|
|
||||||
### Mobs
|
### Mobs
|
||||||
* Mobs: `ENTITIES/mcl_mobs`
|
* Mobs: `ENTITIES/mcl_mobs`
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
So you want to contribute to MineClone2?
|
So you want to contribute to MineClone2?
|
||||||
Wow, thank you! :-)
|
Wow, thank you! :-)
|
||||||
|
|
||||||
MineClone2 is maintained by AncientMariner and Nicu. If you have any
|
MineClone2 is maintained by Nicu and Cora. If you have any
|
||||||
problems or questions, contact us on Discord/Matrix (See Links section below).
|
problems or questions, contact us (See Links section below).
|
||||||
|
|
||||||
You can help with MineClone2's development in many different ways,
|
You can help with MineClone2's development in many different ways,
|
||||||
whether you're a programmer or not.
|
whether you're a programmer or not.
|
||||||
|
@ -240,7 +240,7 @@ work causes problems, we ask you fix the issues as soon as possible.
|
||||||
|
|
||||||
### Changing Gameplay
|
### Changing Gameplay
|
||||||
Pull Requests that change gameplay have to be properly researched and
|
Pull Requests that change gameplay have to be properly researched and
|
||||||
need to state their sources. These PRs also need the maintainer's approval
|
need to state their sources. These PRs also need Fleckenstein's approval
|
||||||
before they are merged.
|
before they are merged.
|
||||||
You can use these sources:
|
You can use these sources:
|
||||||
|
|
||||||
|
@ -375,7 +375,7 @@ merged.
|
||||||
- Resolving conflicts and problems within the community
|
- Resolving conflicts and problems within the community
|
||||||
|
|
||||||
#### Current maintainers
|
#### Current maintainers
|
||||||
* AncientMariner - responsible for gameplay review, publishing releases,
|
* Cora - responsible for gameplay review, publishing releases,
|
||||||
technical guidelines
|
technical guidelines
|
||||||
* Nicu - responsible for community related issues
|
* Nicu - responsible for community related issues
|
||||||
|
|
||||||
|
|
15
CREDITS.md
|
@ -35,8 +35,7 @@
|
||||||
* SumianVoice
|
* SumianVoice
|
||||||
* MrRar
|
* MrRar
|
||||||
* talamh
|
* talamh
|
||||||
* Faerraven / Michieal
|
* Faerraven
|
||||||
* FossFanatic
|
|
||||||
|
|
||||||
## Contributors
|
## Contributors
|
||||||
* Laurent Rocher
|
* Laurent Rocher
|
||||||
|
@ -97,12 +96,6 @@
|
||||||
* TheOnlyJoeEnderman
|
* TheOnlyJoeEnderman
|
||||||
* Ranko Saotome
|
* Ranko Saotome
|
||||||
* Gregor Parzefall
|
* Gregor Parzefall
|
||||||
* Wbjitscool
|
|
||||||
* b3nderman
|
|
||||||
* CyberMango
|
|
||||||
* gldrk
|
|
||||||
* SmokeyDope
|
|
||||||
* atomdmac
|
|
||||||
|
|
||||||
## MineClone5
|
## MineClone5
|
||||||
* kay27
|
* kay27
|
||||||
|
@ -154,13 +147,11 @@
|
||||||
* jordan4ibanez
|
* jordan4ibanez
|
||||||
* paramat
|
* paramat
|
||||||
* cora
|
* cora
|
||||||
* Faerraven / Michieal
|
|
||||||
|
|
||||||
## 3D Models
|
## 3D Models
|
||||||
* 22i
|
* 22i
|
||||||
* tobyplowy
|
* tobyplowy
|
||||||
* epCode
|
* epCode
|
||||||
* Faerraven / Michieal
|
|
||||||
|
|
||||||
## Textures
|
## Textures
|
||||||
* XSSheep
|
* XSSheep
|
||||||
|
@ -175,7 +166,6 @@
|
||||||
* RandomLegoBrick
|
* RandomLegoBrick
|
||||||
* cora
|
* cora
|
||||||
* Faerraven / Michieal
|
* Faerraven / Michieal
|
||||||
* Nicu
|
|
||||||
|
|
||||||
## Translations
|
## Translations
|
||||||
* Wuzzy
|
* Wuzzy
|
||||||
|
@ -190,12 +180,9 @@
|
||||||
* snowyu
|
* snowyu
|
||||||
* 3raven
|
* 3raven
|
||||||
* SakuraRiu
|
* SakuraRiu
|
||||||
* anarquimico
|
|
||||||
|
|
||||||
## Funders
|
## Funders
|
||||||
* 40W
|
* 40W
|
||||||
* bauknecht
|
|
||||||
* Cora
|
|
||||||
|
|
||||||
## Special thanks
|
## Special thanks
|
||||||
* celeron55 for creating Minetest
|
* celeron55 for creating Minetest
|
||||||
|
|
|
@ -1,21 +0,0 @@
|
||||||
Survive, farm, build, explore, play with friends, and do much more. Inspired by a well known block game, pushing beyond.
|
|
||||||
|
|
||||||
How to play:
|
|
||||||
|
|
||||||
#### Download Minetest
|
|
||||||
- Navigate to https://www.minetest.net/ to download the client.
|
|
||||||
- Once installed, open and select the "Content" tab
|
|
||||||
|
|
||||||
#### Install MineClone2 from ContentDB
|
|
||||||
- Click "Browse Online Content" and filter by Games (select "Games" from the dropdown box)
|
|
||||||
- Find "MineClone2" (should be first on the list or on the first page)
|
|
||||||
- Click the [+] button next to MineClone2 and wait for download to finish
|
|
||||||
- Click "Back to Main Menu"
|
|
||||||
|
|
||||||
#### Create new world and play
|
|
||||||
- Click "Start Game" tab
|
|
||||||
- At the bottom click the MineClone2 icon (the 2 dirt with grass blocks)
|
|
||||||
- Click "New", give your world a name
|
|
||||||
- You can leave seed blank or put in a word of your choice
|
|
||||||
- Select your new world
|
|
||||||
- Click "Play Game" and enjoy!
|
|
|
@ -2,6 +2,8 @@
|
||||||
An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils.
|
An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils.
|
||||||
Developed by many people. Not developed or endorsed by Mojang AB.
|
Developed by many people. Not developed or endorsed by Mojang AB.
|
||||||
|
|
||||||
|
Version: 0.82 (in development)
|
||||||
|
|
||||||
### Gameplay
|
### Gameplay
|
||||||
You start in a randomly-generated world made entirely of cubes. You can explore
|
You start in a randomly-generated world made entirely of cubes. You can explore
|
||||||
the world and dig and build almost every block in the world to create new
|
the world and dig and build almost every block in the world to create new
|
||||||
|
@ -156,7 +158,7 @@ The following features are incomplete:
|
||||||
|
|
||||||
* Some monsters and animals
|
* Some monsters and animals
|
||||||
* Redstone-related things
|
* Redstone-related things
|
||||||
* Some special minecarts (hopper and chest minecarts work)
|
* Special minecarts
|
||||||
* A couple of non-trivial blocks and items
|
* A couple of non-trivial blocks and items
|
||||||
|
|
||||||
Bonus features (not found in Minecraft):
|
Bonus features (not found in Minecraft):
|
||||||
|
|
70
RELEASE.md
|
@ -1,75 +1,19 @@
|
||||||
### Standard Release
|
|
||||||
|
|
||||||
#File to document release steps with a view to evolving into a script
|
#File to document release steps with a view to evolving into a script
|
||||||
|
|
||||||
#Update CREDITS.md
|
#Update CREDITS.md
|
||||||
#Update version in game.conf
|
#Update version in README.md (soon to be game.conf from of 0.82.0)
|
||||||
|
|
||||||
lua tools/generate_ingame_credits.lua
|
lua tools/generate_ingame_credits.lua
|
||||||
|
|
||||||
git add CREDITS.md
|
git add CREDITS.md
|
||||||
git add mods/HUD/mcl_credits/people.lua
|
git add mods/HUD/mcl_credits/people.lua
|
||||||
git add game.conf
|
|
||||||
|
|
||||||
#git add RELEASE.md
|
git add README.md
|
||||||
|
# To uncomment when applicable
|
||||||
|
#git add game.conf
|
||||||
|
|
||||||
git commit -m "Pre-release update credits and set version 0.82.0"
|
git commit -m "Pre-release update credits and set version 0.81.1"
|
||||||
|
|
||||||
git tag 0.82.0
|
git tag 0.81.1
|
||||||
|
|
||||||
git push origin 0.82.0
|
git push origin 0.81.1
|
||||||
|
|
||||||
#Update version in game.conf to -SNAPSHOT
|
|
||||||
|
|
||||||
git commit -m "Post-release set version 0.82.0-SNAPSHOT"
|
|
||||||
|
|
||||||
### Hotfix Release
|
|
||||||
|
|
||||||
##### Prepare release branch
|
|
||||||
|
|
||||||
When hotfixing, you should never release new features. Any new code increases risk of new bugs which has additional testing/release concerns.
|
|
||||||
To mitigate this, you just release the last release, and the relevant bug fix. For this, we do the following:
|
|
||||||
|
|
||||||
* Create release branch from the last release tag, push it:
|
|
||||||
|
|
||||||
git checkout -b release/0.82.1 0.82.0
|
|
||||||
|
|
||||||
git push origin release/0.82.1
|
|
||||||
|
|
||||||
##### Prepare feature branch and fix
|
|
||||||
|
|
||||||
* Create feature branch from that release branch (can review it to check only fix is there, nothing else, and use to also merge into master separately)
|
|
||||||
|
|
||||||
git checkout -b hotfix_bug_1_branch
|
|
||||||
|
|
||||||
* Fix crash/serious bug and commit
|
|
||||||
* Push branch and create pr to the release and also the master branch (Do not rebase, to reduce merge conflict risk. Do not delete after first merge or it needs to be repushed)
|
|
||||||
|
|
||||||
##### Update version and tag the release
|
|
||||||
|
|
||||||
* After all fixes are in release branch, pull it locally (best to avoid a merge conflict as feature branch will need to be merged into master also, which already changed version):
|
|
||||||
|
|
||||||
* Update version in game.conf to hotfix version and commit it. Example: version=0.82.1
|
|
||||||
|
|
||||||
* Tag it, push tag and branch:
|
|
||||||
|
|
||||||
git tag 0.82.1
|
|
||||||
|
|
||||||
git push origin 0.82.1
|
|
||||||
|
|
||||||
git push origin release/0.82.1
|
|
||||||
|
|
||||||
Note: If you have to do more than 1 hotfix release, can do it on the same release branch.
|
|
||||||
|
|
||||||
### Release via ContentDB
|
|
||||||
|
|
||||||
* Go to MineClone2 page (https://content.minetest.net/packages/Wuzzy/mineclone2/)
|
|
||||||
* Click +Release
|
|
||||||
* Enter the release tag number in the title and Git reference box. For example (without quotes): "0.82.1"
|
|
||||||
* In the minimum minetest version, put the oldest supported version (as of 14/02/2023 it is 5.5), leave the Maximum minetest version blank
|
|
||||||
* Click save. Release is now live.
|
|
||||||
|
|
||||||
##### Inform people
|
|
||||||
|
|
||||||
* Add a comment to the forum post with the release number and what is involved, and maintainer will update main post.
|
|
||||||
* Add a comment in Discord announcement
|
|
|
@ -1,4 +1,4 @@
|
||||||
title = MineClone 2
|
title = 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.
|
||||||
disallowed_mapgens = v6
|
disallowed_mapgens = v6
|
||||||
version=0.82.0-SNAPSHOT
|
version=MCL2-0.82-indev
|
BIN
menu/footer.png
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.4 KiB |
|
@ -204,7 +204,7 @@ 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.
|
||||||
-- Returns true if it will yield its useful drop, false otherwise.
|
-- Returns true if it will yield its useful drop, false otherwise.
|
||||||
function mcl_autogroup.can_harvest(nodename, toolname, player)
|
function mcl_autogroup.can_harvest(nodename, toolname)
|
||||||
local ndef = minetest.registered_nodes[nodename]
|
local ndef = minetest.registered_nodes[nodename]
|
||||||
|
|
||||||
if not ndef then
|
if not ndef then
|
||||||
|
@ -228,9 +228,7 @@ function mcl_autogroup.can_harvest(nodename, toolname, player)
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Check if it can be dug by hand
|
-- Check if it can be dug by hand
|
||||||
if not player or not player:is_player() then return false end
|
local tdef = minetest.registered_tools[""]
|
||||||
local name = player:get_inventory():get_stack("hand", 1):get_name()
|
|
||||||
local tdef = minetest.registered_items[name]
|
|
||||||
if tdef then
|
if tdef then
|
||||||
for g, gdef in pairs(tdef._mcl_diggroups) do
|
for g, gdef in pairs(tdef._mcl_diggroups) do
|
||||||
if ndef.groups[g] then
|
if ndef.groups[g] then
|
||||||
|
@ -262,7 +260,7 @@ local function get_tool_capabilities(tdef)
|
||||||
|
|
||||||
-- If the damage group and punch interval from hand is not included,
|
-- If the damage group and punch interval from hand is not included,
|
||||||
-- then the user will not be able to attack with the tool.
|
-- then the user will not be able to attack with the tool.
|
||||||
local hand_toolcaps = mcl_meshhand.survival_hand_tool_caps
|
local hand_toolcaps = minetest.registered_tools[""].tool_capabilities
|
||||||
return {
|
return {
|
||||||
full_punch_interval = hand_toolcaps.full_punch_interval,
|
full_punch_interval = hand_toolcaps.full_punch_interval,
|
||||||
damage_groups = hand_toolcaps.damage_groups
|
damage_groups = hand_toolcaps.damage_groups
|
||||||
|
@ -282,7 +280,7 @@ end
|
||||||
-- would have to add _mcl_autogroup as a dependency which would break the mod
|
-- would have to add _mcl_autogroup as a dependency which would break the mod
|
||||||
-- loading order.
|
-- loading order.
|
||||||
function mcl_autogroup.get_groupcaps(toolname, efficiency)
|
function mcl_autogroup.get_groupcaps(toolname, efficiency)
|
||||||
local tdef = minetest.registered_items[toolname]
|
local tdef = minetest.registered_tools[toolname]
|
||||||
local groupcaps = table.copy(get_tool_capabilities(tdef).groupcaps or {})
|
local groupcaps = table.copy(get_tool_capabilities(tdef).groupcaps or {})
|
||||||
add_groupcaps(toolname, groupcaps, tdef._mcl_diggroups, efficiency)
|
add_groupcaps(toolname, groupcaps, tdef._mcl_diggroups, efficiency)
|
||||||
return groupcaps
|
return groupcaps
|
||||||
|
@ -352,7 +350,7 @@ local function overwrite()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
for tname, tdef in pairs(minetest.registered_items) do
|
for tname, tdef in pairs(minetest.registered_tools) do
|
||||||
-- Assign groupcaps for digging the registered digging groups
|
-- Assign groupcaps for digging the registered digging groups
|
||||||
-- depending on the _mcl_diggroups in the tool definition
|
-- depending on the _mcl_diggroups in the tool definition
|
||||||
if tdef._mcl_diggroups then
|
if tdef._mcl_diggroups then
|
||||||
|
@ -362,12 +360,6 @@ local function overwrite()
|
||||||
minetest.override_item(tname, {
|
minetest.override_item(tname, {
|
||||||
tool_capabilities = toolcaps
|
tool_capabilities = toolcaps
|
||||||
})
|
})
|
||||||
else
|
|
||||||
-- This is needed to deal damage when punching mobs
|
|
||||||
-- with random items in hand in survival mode
|
|
||||||
minetest.override_item(tname, {
|
|
||||||
tool_capabilities = mcl_meshhand.survival_hand_tool_caps
|
|
||||||
})
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
# mcl_autogroup
|
# mcl_autogroup
|
||||||
This mod emulate digging times from mc.
|
This mod emulate digging times from mc.
|
||||||
|
|
||||||
## mcl_autogroup.can_harvest(nodename, toolname, player)
|
## mcl_autogroup.can_harvest(nodename, toolname)
|
||||||
Return true if <nodename> can be dig with <toolname> by <player>.
|
Return true if <nodename> can be dig with <toolname>.
|
||||||
* nodename: string, valid nodename
|
* nodename: string, valid nodename
|
||||||
* toolname: (optional) string, valid toolname
|
* toolname: (optional) string, valid toolname
|
||||||
* player: (optinal) ObjectRef, valid player
|
|
||||||
|
|
||||||
## mcl_autogroup.get_groupcaps(toolname, efficiency)
|
## mcl_autogroup.get_groupcaps(toolname, efficiency)
|
||||||
This function is used to calculate diggroups for tools.
|
This function is used to calculate diggroups for tools.
|
||||||
|
|
|
@ -155,6 +155,7 @@ end, true)
|
||||||
minetest.register_on_player_hpchange(function(player, hp_change, mt_reason)
|
minetest.register_on_player_hpchange(function(player, hp_change, mt_reason)
|
||||||
if not damage_enabled then return 0 end
|
if not damage_enabled then return 0 end
|
||||||
if player:get_hp() > 0 then
|
if player:get_hp() > 0 then
|
||||||
|
mt_reason.approved = true
|
||||||
if hp_change < 0 then
|
if hp_change < 0 then
|
||||||
mcl_damage.run_damage_callbacks(player, -hp_change, mcl_damage.from_mt(mt_reason))
|
mcl_damage.run_damage_callbacks(player, -hp_change, mcl_damage.from_mt(mt_reason))
|
||||||
end
|
end
|
||||||
|
@ -162,7 +163,9 @@ minetest.register_on_player_hpchange(function(player, hp_change, mt_reason)
|
||||||
end, false)
|
end, false)
|
||||||
|
|
||||||
minetest.register_on_dieplayer(function(player, mt_reason)
|
minetest.register_on_dieplayer(function(player, mt_reason)
|
||||||
|
if mt_reason.approved then
|
||||||
mcl_damage.run_death_callbacks(player, mcl_damage.from_mt(mt_reason))
|
mcl_damage.run_death_callbacks(player, mcl_damage.from_mt(mt_reason))
|
||||||
|
end
|
||||||
minetest.log("action","Player "..player:get_player_name().." died at "..minetest.pos_to_string(vector.round(player:get_pos())))
|
minetest.log("action","Player "..player:get_player_name().." died at "..minetest.pos_to_string(vector.round(player:get_pos())))
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 126 B After Width: | Height: | Size: 126 B |
Before Width: | Height: | Size: 127 B After Width: | Height: | Size: 127 B |
Before Width: | Height: | Size: 91 B After Width: | Height: | Size: 91 B |
Before Width: | Height: | Size: 137 B After Width: | Height: | Size: 137 B |
Before Width: | Height: | Size: 145 B After Width: | Height: | Size: 145 B |
Before Width: | Height: | Size: 125 B After Width: | Height: | Size: 125 B |
Before Width: | Height: | Size: 183 B After Width: | Height: | Size: 183 B |
After Width: | Height: | Size: 262 B |
Before Width: | Height: | Size: 124 B After Width: | Height: | Size: 126 B |
Before Width: | Height: | Size: 126 B After Width: | Height: | Size: 126 B |
After Width: | Height: | Size: 216 B |
Before Width: | Height: | Size: 144 B After Width: | Height: | Size: 144 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 101 B After Width: | Height: | Size: 101 B |
Before Width: | Height: | Size: 148 B After Width: | Height: | Size: 148 B |
Before Width: | Height: | Size: 154 B After Width: | Height: | Size: 154 B |
Before Width: | Height: | Size: 155 B After Width: | Height: | Size: 155 B |
Before Width: | Height: | Size: 165 B After Width: | Height: | Size: 165 B |
|
@ -2,8 +2,8 @@ mcl_util = {}
|
||||||
|
|
||||||
-- Updates all values in t using values from to*.
|
-- Updates all values in t using values from to*.
|
||||||
function table.update(t, ...)
|
function table.update(t, ...)
|
||||||
for _, to in ipairs {...} do
|
for _, to in ipairs{...} do
|
||||||
for k, v in pairs(to) do
|
for k,v in pairs(to) do
|
||||||
t[k] = v
|
t[k] = v
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -12,8 +12,8 @@ end
|
||||||
|
|
||||||
-- Updates nil values in t using values from to*.
|
-- Updates nil values in t using values from to*.
|
||||||
function table.update_nil(t, ...)
|
function table.update_nil(t, ...)
|
||||||
for _, to in ipairs {...} do
|
for _, to in ipairs{...} do
|
||||||
for k, v in pairs(to) do
|
for k,v in pairs(to) do
|
||||||
if t[k] == nil then
|
if t[k] == nil then
|
||||||
t[k] = v
|
t[k] = v
|
||||||
end
|
end
|
||||||
|
@ -22,9 +22,9 @@ function table.update_nil(t, ...)
|
||||||
return t
|
return t
|
||||||
end
|
end
|
||||||
|
|
||||||
local LOGGING_ON = minetest.settings:get_bool("mcl_logging_default", false)
|
local LOGGING_ON = minetest.settings:get_bool("mcl_logging_default",false)
|
||||||
local LOG_MODULE = "[MCL2]"
|
local LOG_MODULE = "[MCL2]"
|
||||||
function mcl_util.mcl_log(message, module, bypass_default_logger)
|
function mcl_util.mcl_log (message, module, bypass_default_logger)
|
||||||
local selected_module = LOG_MODULE
|
local selected_module = LOG_MODULE
|
||||||
if module then
|
if module then
|
||||||
selected_module = module
|
selected_module = module
|
||||||
|
@ -34,6 +34,7 @@ function mcl_util.mcl_log(message, module, bypass_default_logger)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
function mcl_util.file_exists(name)
|
function mcl_util.file_exists(name)
|
||||||
if type(name) ~= "string" then return end
|
if type(name) ~= "string" then return end
|
||||||
local f = io.open(name)
|
local f = io.open(name)
|
||||||
|
@ -150,23 +151,23 @@ end
|
||||||
function mcl_util.get_double_container_neighbor_pos(pos, param2, side)
|
function mcl_util.get_double_container_neighbor_pos(pos, param2, side)
|
||||||
if side == "right" then
|
if side == "right" then
|
||||||
if param2 == 0 then
|
if param2 == 0 then
|
||||||
return {x = pos.x - 1, y = pos.y, z = pos.z}
|
return {x=pos.x-1, y=pos.y, z=pos.z}
|
||||||
elseif param2 == 1 then
|
elseif param2 == 1 then
|
||||||
return {x = pos.x, y = pos.y, z = pos.z + 1}
|
return {x=pos.x, y=pos.y, z=pos.z+1}
|
||||||
elseif param2 == 2 then
|
elseif param2 == 2 then
|
||||||
return {x = pos.x + 1, y = pos.y, z = pos.z}
|
return {x=pos.x+1, y=pos.y, z=pos.z}
|
||||||
elseif param2 == 3 then
|
elseif param2 == 3 then
|
||||||
return {x = pos.x, y = pos.y, z = pos.z - 1}
|
return {x=pos.x, y=pos.y, z=pos.z-1}
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if param2 == 0 then
|
if param2 == 0 then
|
||||||
return {x = pos.x + 1, y = pos.y, z = pos.z}
|
return {x=pos.x+1, y=pos.y, z=pos.z}
|
||||||
elseif param2 == 1 then
|
elseif param2 == 1 then
|
||||||
return {x = pos.x, y = pos.y, z = pos.z - 1}
|
return {x=pos.x, y=pos.y, z=pos.z-1}
|
||||||
elseif param2 == 2 then
|
elseif param2 == 2 then
|
||||||
return {x = pos.x - 1, y = pos.y, z = pos.z}
|
return {x=pos.x-1, y=pos.y, z=pos.z}
|
||||||
elseif param2 == 3 then
|
elseif param2 == 3 then
|
||||||
return {x = pos.x, y = pos.y, z = pos.z + 1}
|
return {x=pos.x, y=pos.y, z=pos.z+1}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -184,7 +185,7 @@ end
|
||||||
function mcl_util.get_eligible_transfer_item_slot(src_inventory, src_list, dst_inventory, dst_list, condition)
|
function mcl_util.get_eligible_transfer_item_slot(src_inventory, src_list, dst_inventory, dst_list, condition)
|
||||||
local size = src_inventory:get_size(src_list)
|
local size = src_inventory:get_size(src_list)
|
||||||
local stack
|
local stack
|
||||||
for i = 1, size do
|
for i=1, size do
|
||||||
stack = src_inventory:get_stack(src_list, i)
|
stack = src_inventory:get_stack(src_list, i)
|
||||||
if not stack:is_empty() and (condition == nil or condition(stack, src_inventory, src_list, dst_inventory, dst_list)) then
|
if not stack:is_empty() and (condition == nil or condition(stack, src_inventory, src_list, dst_inventory, dst_list)) then
|
||||||
return i
|
return i
|
||||||
|
@ -408,7 +409,7 @@ end
|
||||||
-- Returns true if item (itemstring or ItemStack) can be used as a furnace fuel.
|
-- Returns true if item (itemstring or ItemStack) can be used as a furnace fuel.
|
||||||
-- Returns false otherwise
|
-- Returns false otherwise
|
||||||
function mcl_util.is_fuel(item)
|
function mcl_util.is_fuel(item)
|
||||||
return minetest.get_craft_result({method = "fuel", width = 1, items = {item}}).time ~= 0
|
return minetest.get_craft_result({method="fuel", width=1, items={item}}).time ~= 0
|
||||||
end
|
end
|
||||||
|
|
||||||
-- Returns a on_place function for plants
|
-- Returns a on_place function for plants
|
||||||
|
@ -455,7 +456,7 @@ function mcl_util.generate_on_place_plant_function(condition)
|
||||||
|
|
||||||
if success then
|
if success then
|
||||||
if idef.sounds and idef.sounds.place then
|
if idef.sounds and idef.sounds.place then
|
||||||
minetest.sound_play(idef.sounds.place, {pos = pointed_thing.above, gain = 1}, true)
|
minetest.sound_play(idef.sounds.place, {pos=pointed_thing.above, gain=1}, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
itemstack = new_itemstack
|
itemstack = new_itemstack
|
||||||
|
@ -556,11 +557,6 @@ function mcl_util.deal_damage(target, damage, mcl_reason)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local is_immortal = target:get_armor_groups().immortal or 0
|
|
||||||
if is_immortal>0 then
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
local hp = target:get_hp()
|
local hp = target:get_hp()
|
||||||
|
|
||||||
if hp > 0 then
|
if hp > 0 then
|
||||||
|
@ -647,80 +643,78 @@ end
|
||||||
|
|
||||||
local function roundN(n, d)
|
local function roundN(n, d)
|
||||||
if type(n) ~= "number" then return n end
|
if type(n) ~= "number" then return n end
|
||||||
local m = 10 ^ d
|
local m = 10^d
|
||||||
return math.floor(n * m + 0.5) / m
|
return math.floor(n * m + 0.5) / m
|
||||||
end
|
end
|
||||||
|
|
||||||
local function close_enough(a, b)
|
local function close_enough(a,b)
|
||||||
local rt = true
|
local rt=true
|
||||||
if type(a) == "table" and type(b) == "table" then
|
if type(a) == "table" and type(b) == "table" then
|
||||||
for k, v in pairs(a) do
|
for k,v in pairs(a) do
|
||||||
if roundN(v, 2) ~= roundN(b[k], 2) then
|
if roundN(v,2) ~= roundN(b[k],2) then
|
||||||
rt = false
|
rt=false
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
rt = roundN(a, 2) == roundN(b, 2)
|
rt = roundN(a,2) == roundN(b,2)
|
||||||
end
|
end
|
||||||
return rt
|
return rt
|
||||||
end
|
end
|
||||||
|
|
||||||
local function props_changed(props, oldprops)
|
local function props_changed(props,oldprops)
|
||||||
local changed = false
|
local changed=false
|
||||||
local p = {}
|
local p={}
|
||||||
for k, v in pairs(props) do
|
for k,v in pairs(props) do
|
||||||
if not close_enough(v, oldprops[k]) then
|
if not close_enough(v,oldprops[k]) then
|
||||||
p[k] = v
|
p[k]=v
|
||||||
changed = true
|
changed=true
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
return changed, p
|
return changed,p
|
||||||
end
|
end
|
||||||
|
|
||||||
--tests for roundN
|
--tests for roundN
|
||||||
local test_round1 = 15
|
local test_round1=15
|
||||||
local test_round2 = 15.00199999999
|
local test_round2=15.00199999999
|
||||||
local test_round3 = 15.00111111
|
local test_round3=15.00111111
|
||||||
local test_round4 = 15.00999999
|
local test_round4=15.00999999
|
||||||
|
|
||||||
assert(roundN(test_round1, 2) == roundN(test_round1, 2))
|
assert(roundN(test_round1,2)==roundN(test_round1,2))
|
||||||
assert(roundN(test_round1, 2) == roundN(test_round2, 2))
|
assert(roundN(test_round1,2)==roundN(test_round2,2))
|
||||||
assert(roundN(test_round1, 2) == roundN(test_round3, 2))
|
assert(roundN(test_round1,2)==roundN(test_round3,2))
|
||||||
assert(roundN(test_round1, 2) ~= roundN(test_round4, 2))
|
assert(roundN(test_round1,2)~=roundN(test_round4,2))
|
||||||
|
|
||||||
-- tests for close_enough
|
-- tests for close_enough
|
||||||
local test_cb = {-0.35, 0, -0.35, 0.35, 0.8, 0.35} --collisionboxes
|
local test_cb = {-0.35,0,-0.35,0.35,0.8,0.35} --collisionboxes
|
||||||
local test_cb_close = {-0.351213, 0, -0.35, 0.35, 0.8, 0.351212}
|
local test_cb_close = {-0.351213,0,-0.35,0.35,0.8,0.351212}
|
||||||
local test_cb_diff = {-0.35, 0, -1.35, 0.35, 0.8, 0.35}
|
local test_cb_diff = {-0.35,0,-1.35,0.35,0.8,0.35}
|
||||||
|
|
||||||
local test_eh = 1.65 --eye height
|
local test_eh = 1.65 --eye height
|
||||||
local test_eh_close = 1.65123123
|
local test_eh_close = 1.65123123
|
||||||
local test_eh_diff = 1.35
|
local test_eh_diff = 1.35
|
||||||
|
|
||||||
local test_nt = {r = 225, b = 225, a = 225, g = 225} --nametag
|
local test_nt = { r = 225, b = 225, a = 225, g = 225 } --nametag
|
||||||
local test_nt_diff = {r = 225, b = 225, a = 0, g = 225}
|
local test_nt_diff = { r = 225, b = 225, a = 0, g = 225 }
|
||||||
|
|
||||||
assert(close_enough(test_cb, test_cb_close))
|
assert(close_enough(test_cb,test_cb_close))
|
||||||
assert(not close_enough(test_cb, test_cb_diff))
|
assert(not close_enough(test_cb,test_cb_diff))
|
||||||
assert(close_enough(test_eh, test_eh_close))
|
assert(close_enough(test_eh,test_eh_close))
|
||||||
assert(not close_enough(test_eh, test_eh_diff))
|
assert(not close_enough(test_eh,test_eh_diff))
|
||||||
assert(not close_enough(test_nt, test_nt_diff)) --no floats involved here
|
assert(not close_enough(test_nt,test_nt_diff)) --no floats involved here
|
||||||
|
|
||||||
--tests for properties_changed
|
--tests for properties_changed
|
||||||
local test_properties_set1 = {collisionbox = {-0.35, 0, -0.35, 0.35, 0.8, 0.35}, eye_height = 0.65,
|
local test_properties_set1={collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 0.65, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}
|
||||||
nametag_color = {r = 225, b = 225, a = 225, g = 225}}
|
local test_properties_set2={collisionbox = {-0.35,0,-0.35,0.35,0.8,0.35}, eye_height = 1.35, nametag_color = { r = 225, b = 225, a = 225, g = 225 }}
|
||||||
local test_properties_set2 = {collisionbox = {-0.35, 0, -0.35, 0.35, 0.8, 0.35}, eye_height = 1.35,
|
|
||||||
nametag_color = {r = 225, b = 225, a = 225, g = 225}}
|
|
||||||
|
|
||||||
local test_p1, _ = props_changed(test_properties_set1, test_properties_set1)
|
local test_p1,_=props_changed(test_properties_set1,test_properties_set1)
|
||||||
local test_p2, _ = props_changed(test_properties_set1, test_properties_set2)
|
local test_p2,_=props_changed(test_properties_set1,test_properties_set2)
|
||||||
|
|
||||||
assert(not test_p1)
|
assert(not test_p1)
|
||||||
assert(test_p2)
|
assert(test_p2)
|
||||||
|
|
||||||
function mcl_util.set_properties(obj, props)
|
function mcl_util.set_properties(obj,props)
|
||||||
local changed, p = props_changed(props, obj:get_properties())
|
local changed,p=props_changed(props,obj:get_properties())
|
||||||
if changed then
|
if changed then
|
||||||
obj:set_properties(p)
|
obj:set_properties(p)
|
||||||
end
|
end
|
||||||
|
@ -734,302 +728,3 @@ function mcl_util.set_bone_position(obj, bone, pos, rot)
|
||||||
obj:set_bone_position(bone, pos or current_pos, rot or current_rot)
|
obj:set_bone_position(bone, pos or current_pos, rot or current_rot)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
---Return a function to use in `on_place`.
|
|
||||||
---
|
|
||||||
---Allow to bypass the `buildable_to` node field in a `on_place` callback.
|
|
||||||
---
|
|
||||||
---You have to make sure that the nodes you return true for have `buildable_to = true`.
|
|
||||||
---@param func fun(node_name: string): boolean Return `true` if node must not replace the buildable_to node which have `node_name`
|
|
||||||
---@return fun(itemstack: ItemStack, placer: ObjectRef, pointed_thing: pointed_thing, param2: integer): ItemStack?
|
|
||||||
function mcl_util.bypass_buildable_to(func)
|
|
||||||
--------------------------
|
|
||||||
-- MINETEST CODE: UTILS --
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
local function copy_pointed_thing(pointed_thing)
|
|
||||||
return {
|
|
||||||
type = pointed_thing.type,
|
|
||||||
above = pointed_thing.above and vector.copy(pointed_thing.above),
|
|
||||||
under = pointed_thing.under and vector.copy(pointed_thing.under),
|
|
||||||
ref = pointed_thing.ref,
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
local function user_name(user)
|
|
||||||
return user and user:get_player_name() or ""
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Returns a logging function. For empty names, does not log.
|
|
||||||
local function make_log(name)
|
|
||||||
return name ~= "" and minetest.log or function() end
|
|
||||||
end
|
|
||||||
|
|
||||||
local function check_attached_node(p, n, group_rating)
|
|
||||||
local def = core.registered_nodes[n.name]
|
|
||||||
local d = vector.zero()
|
|
||||||
if group_rating == 3 then
|
|
||||||
-- always attach to floor
|
|
||||||
d.y = -1
|
|
||||||
elseif group_rating == 4 then
|
|
||||||
-- always attach to ceiling
|
|
||||||
d.y = 1
|
|
||||||
elseif group_rating == 2 then
|
|
||||||
-- attach to facedir or 4dir direction
|
|
||||||
if (def.paramtype2 == "facedir" or
|
|
||||||
def.paramtype2 == "colorfacedir") then
|
|
||||||
-- Attach to whatever facedir is "mounted to".
|
|
||||||
-- For facedir, this is where tile no. 5 point at.
|
|
||||||
|
|
||||||
-- The fallback vector here is in case 'facedir to dir' is nil due
|
|
||||||
-- to voxelmanip placing a wallmounted node without resetting a
|
|
||||||
-- pre-existing param2 value that is out-of-range for facedir.
|
|
||||||
-- The fallback vector corresponds to param2 = 0.
|
|
||||||
d = core.facedir_to_dir(n.param2) or vector.new(0, 0, 1)
|
|
||||||
elseif (def.paramtype2 == "4dir" or
|
|
||||||
def.paramtype2 == "color4dir") then
|
|
||||||
-- Similar to facedir handling
|
|
||||||
d = core.fourdir_to_dir(n.param2) or vector.new(0, 0, 1)
|
|
||||||
end
|
|
||||||
elseif def.paramtype2 == "wallmounted" or
|
|
||||||
def.paramtype2 == "colorwallmounted" then
|
|
||||||
-- Attach to whatever this node is "mounted to".
|
|
||||||
-- This where tile no. 2 points at.
|
|
||||||
|
|
||||||
-- The fallback vector here is used for the same reason as
|
|
||||||
-- for facedir nodes.
|
|
||||||
d = core.wallmounted_to_dir(n.param2) or vector.new(0, 1, 0)
|
|
||||||
else
|
|
||||||
d.y = -1
|
|
||||||
end
|
|
||||||
local p2 = vector.add(p, d)
|
|
||||||
local nn = core.get_node(p2).name
|
|
||||||
local def2 = core.registered_nodes[nn]
|
|
||||||
if def2 and not def2.walkable then
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
return function(itemstack, placer, pointed_thing, param2)
|
|
||||||
-------------------
|
|
||||||
-- MINETEST CODE --
|
|
||||||
-------------------
|
|
||||||
local def = itemstack:get_definition()
|
|
||||||
if def.type ~= "node" or pointed_thing.type ~= "node" then
|
|
||||||
return itemstack
|
|
||||||
end
|
|
||||||
|
|
||||||
local under = pointed_thing.under
|
|
||||||
local oldnode_under = minetest.get_node_or_nil(under)
|
|
||||||
local above = pointed_thing.above
|
|
||||||
local oldnode_above = minetest.get_node_or_nil(above)
|
|
||||||
local playername = user_name(placer)
|
|
||||||
local log = make_log(playername)
|
|
||||||
|
|
||||||
if not oldnode_under or not oldnode_above then
|
|
||||||
log("info", playername .. " tried to place"
|
|
||||||
.. " node in unloaded position " .. minetest.pos_to_string(above))
|
|
||||||
return itemstack
|
|
||||||
end
|
|
||||||
|
|
||||||
local olddef_under = minetest.registered_nodes[oldnode_under.name]
|
|
||||||
olddef_under = olddef_under or minetest.nodedef_default
|
|
||||||
local olddef_above = minetest.registered_nodes[oldnode_above.name]
|
|
||||||
olddef_above = olddef_above or minetest.nodedef_default
|
|
||||||
|
|
||||||
if not olddef_above.buildable_to and not olddef_under.buildable_to then
|
|
||||||
log("info", playername .. " tried to place"
|
|
||||||
.. " node in invalid position " .. minetest.pos_to_string(above)
|
|
||||||
.. ", replacing " .. oldnode_above.name)
|
|
||||||
return itemstack
|
|
||||||
end
|
|
||||||
|
|
||||||
---------------------
|
|
||||||
-- CUSTOMIZED CODE --
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
-- Place above pointed node
|
|
||||||
local place_to = vector.copy(above)
|
|
||||||
|
|
||||||
-- If node under is buildable_to, check for callback result and place into it instead
|
|
||||||
if olddef_under.buildable_to and not func(oldnode_under.name) then
|
|
||||||
log("info", "node under is buildable to")
|
|
||||||
place_to = vector.copy(under)
|
|
||||||
end
|
|
||||||
|
|
||||||
-------------------
|
|
||||||
-- MINETEST CODE --
|
|
||||||
-------------------
|
|
||||||
|
|
||||||
if minetest.is_protected(place_to, playername) then
|
|
||||||
log("action", playername
|
|
||||||
.. " tried to place " .. def.name
|
|
||||||
.. " at protected position "
|
|
||||||
.. minetest.pos_to_string(place_to))
|
|
||||||
minetest.record_protection_violation(place_to, playername)
|
|
||||||
return itemstack
|
|
||||||
end
|
|
||||||
|
|
||||||
local oldnode = minetest.get_node(place_to)
|
|
||||||
local newnode = {name = def.name, param1 = 0, param2 = param2 or 0}
|
|
||||||
|
|
||||||
-- Calculate direction for wall mounted stuff like torches and signs
|
|
||||||
if def.place_param2 ~= nil then
|
|
||||||
newnode.param2 = def.place_param2
|
|
||||||
elseif (def.paramtype2 == "wallmounted" or
|
|
||||||
def.paramtype2 == "colorwallmounted") and not param2 then
|
|
||||||
local dir = vector.subtract(under, above)
|
|
||||||
newnode.param2 = minetest.dir_to_wallmounted(dir)
|
|
||||||
-- Calculate the direction for furnaces and chests and stuff
|
|
||||||
elseif (def.paramtype2 == "facedir" or
|
|
||||||
def.paramtype2 == "colorfacedir" or
|
|
||||||
def.paramtype2 == "4dir" or
|
|
||||||
def.paramtype2 == "color4dir") and not param2 then
|
|
||||||
local placer_pos = placer and placer:get_pos()
|
|
||||||
if placer_pos then
|
|
||||||
local dir = vector.subtract(above, placer_pos)
|
|
||||||
newnode.param2 = minetest.dir_to_facedir(dir)
|
|
||||||
log("info", "facedir: " .. newnode.param2)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
local metatable = itemstack:get_meta():to_table().fields
|
|
||||||
|
|
||||||
-- Transfer color information
|
|
||||||
if metatable.palette_index and not def.place_param2 then
|
|
||||||
local color_divisor = nil
|
|
||||||
if def.paramtype2 == "color" then
|
|
||||||
color_divisor = 1
|
|
||||||
elseif def.paramtype2 == "colorwallmounted" then
|
|
||||||
color_divisor = 8
|
|
||||||
elseif def.paramtype2 == "colorfacedir" then
|
|
||||||
color_divisor = 32
|
|
||||||
elseif def.paramtype2 == "color4dir" then
|
|
||||||
color_divisor = 4
|
|
||||||
elseif def.paramtype2 == "colordegrotate" then
|
|
||||||
color_divisor = 32
|
|
||||||
end
|
|
||||||
if color_divisor then
|
|
||||||
local color = math.floor(metatable.palette_index / color_divisor)
|
|
||||||
local other = newnode.param2 % color_divisor
|
|
||||||
newnode.param2 = color * color_divisor + other
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Check if the node is attached and if it can be placed there
|
|
||||||
local an = minetest.get_item_group(def.name, "attached_node")
|
|
||||||
if an ~= 0 and
|
|
||||||
not check_attached_node(place_to, newnode, an) then
|
|
||||||
log("action", "attached node " .. def.name ..
|
|
||||||
" cannot be placed at " .. minetest.pos_to_string(place_to))
|
|
||||||
return itemstack
|
|
||||||
end
|
|
||||||
|
|
||||||
log("action", playername .. " places node "
|
|
||||||
.. def.name .. " at " .. minetest.pos_to_string(place_to))
|
|
||||||
|
|
||||||
-- Add node and update
|
|
||||||
minetest.add_node(place_to, newnode)
|
|
||||||
|
|
||||||
-- Play sound if it was done by a player
|
|
||||||
if playername ~= "" and def.sounds and def.sounds.place then
|
|
||||||
minetest.sound_play(def.sounds.place, {
|
|
||||||
pos = place_to,
|
|
||||||
exclude_player = playername,
|
|
||||||
}, true)
|
|
||||||
end
|
|
||||||
|
|
||||||
local take_item = true
|
|
||||||
|
|
||||||
-- Run callback
|
|
||||||
if def.after_place_node then
|
|
||||||
-- Deepcopy place_to and pointed_thing because callback can modify it
|
|
||||||
local place_to_copy = vector.copy(place_to)
|
|
||||||
local pointed_thing_copy = copy_pointed_thing(pointed_thing)
|
|
||||||
if def.after_place_node(place_to_copy, placer, itemstack,
|
|
||||||
pointed_thing_copy) then
|
|
||||||
take_item = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
-- Run script hook
|
|
||||||
for _, callback in ipairs(minetest.registered_on_placenodes) do
|
|
||||||
-- Deepcopy pos, node and pointed_thing because callback can modify them
|
|
||||||
local place_to_copy = vector.copy(place_to)
|
|
||||||
local newnode_copy = {name = newnode.name, param1 = newnode.param1, param2 = newnode.param2}
|
|
||||||
local oldnode_copy = {name = oldnode.name, param1 = oldnode.param1, param2 = oldnode.param2}
|
|
||||||
local pointed_thing_copy = copy_pointed_thing(pointed_thing)
|
|
||||||
if callback(place_to_copy, newnode_copy, placer, oldnode_copy, itemstack, pointed_thing_copy) then
|
|
||||||
take_item = false
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
if take_item then
|
|
||||||
itemstack:take_item()
|
|
||||||
end
|
|
||||||
return itemstack
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[Check for a protection violation in a given area.
|
|
||||||
--
|
|
||||||
-- Applies is_protected() to a 3D lattice of points in the defined volume. The points are spaced
|
|
||||||
-- evenly throughout the volume and have a spacing similar to, but no larger than, "interval".
|
|
||||||
--
|
|
||||||
-- @param pos1 A position table of the area volume's first edge.
|
|
||||||
-- @param pos2 A position table of the area volume's second edge.
|
|
||||||
-- @param player The player performing the action.
|
|
||||||
-- @param interval Optional. Max spacing between checked points at the volume.
|
|
||||||
-- Default: Same as minetest.is_area_protected.
|
|
||||||
--
|
|
||||||
-- @return true on protection violation detection. false otherwise.
|
|
||||||
--
|
|
||||||
-- @notes *All corners and edges of the defined volume are checked.
|
|
||||||
]]
|
|
||||||
function mcl_util.check_area_protection(pos1, pos2, player, interval)
|
|
||||||
local name = player and player:get_player_name() or ""
|
|
||||||
|
|
||||||
local protected_pos = minetest.is_area_protected(pos1, pos2, name, interval)
|
|
||||||
if protected_pos then
|
|
||||||
minetest.record_protection_violation(protected_pos, name)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
--[[Check for a protection violation on a single position.
|
|
||||||
--
|
|
||||||
-- @param position A position table to check for protection violation.
|
|
||||||
-- @param player The player performing the action.
|
|
||||||
--
|
|
||||||
-- @return true on protection violation detection. false otherwise.
|
|
||||||
]]
|
|
||||||
function mcl_util.check_position_protection(position, player)
|
|
||||||
local name = player and player:get_player_name() or ""
|
|
||||||
|
|
||||||
if minetest.is_protected(position, name) then
|
|
||||||
minetest.record_protection_violation(position, name)
|
|
||||||
return true
|
|
||||||
end
|
|
||||||
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
local palette_indexes = {grass_palette_index = 0, foliage_palette_index = 0, water_palette_index = 0}
|
|
||||||
function mcl_util.get_palette_indexes_from_pos(pos)
|
|
||||||
local biome_data = minetest.get_biome_data(pos)
|
|
||||||
local biome = biome_data.biome
|
|
||||||
local biome_name = minetest.get_biome_name(biome)
|
|
||||||
local reg_biome = minetest.registered_biomes[biome_name]
|
|
||||||
if reg_biome and reg_biome._mcl_grass_palette_index and reg_biome._mcl_foliage_palette_index and reg_biome._mcl_water_palette_index then
|
|
||||||
local gpi = reg_biome._mcl_grass_palette_index
|
|
||||||
local fpi = reg_biome._mcl_foliage_palette_index
|
|
||||||
local wpi = reg_biome._mcl_water_palette_index
|
|
||||||
local palette_indexes = {grass_palette_index = gpi, foliage_palette_index = fpi, water_palette_index = wpi}
|
|
||||||
return palette_indexes
|
|
||||||
else
|
|
||||||
return palette_indexes
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
After Width: | Height: | Size: 265 B |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 261 B After Width: | Height: | Size: 261 B |
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 271 B After Width: | Height: | Size: 271 B |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.4 KiB |
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 6.2 KiB |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 267 B |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 264 B After Width: | Height: | Size: 264 B |
Before Width: | Height: | Size: 267 B After Width: | Height: | Size: 267 B |
Before Width: | Height: | Size: 6.1 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 969 B After Width: | Height: | Size: 969 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 535 B After Width: | Height: | Size: 535 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
@ -252,17 +252,10 @@ function minetest.handle_node_drops(pos, drops, digger)
|
||||||
-- NOTE: This function override allows digger to be nil.
|
-- NOTE: This function override allows digger to be nil.
|
||||||
-- This means there is no digger. This is a special case which allows this function to be called
|
-- This means there is no digger. This is a special case which allows this function to be called
|
||||||
-- by hand. Creative Mode is intentionally ignored in this case.
|
-- by hand. Creative Mode is intentionally ignored in this case.
|
||||||
if digger and digger:is_player() and minetest.is_creative_enabled(digger:get_player_name()) then
|
|
||||||
local inv = digger:get_inventory()
|
if (digger and digger:is_player() and minetest.is_creative_enabled(digger:get_player_name())) or doTileDrops == false then
|
||||||
if inv then
|
|
||||||
for _, item in ipairs(drops) do
|
|
||||||
if not inv:contains_item("main", item, true) then
|
|
||||||
inv:add_item("main", item)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
return
|
return
|
||||||
elseif not doTileDrops then return end
|
end
|
||||||
|
|
||||||
-- Check if node will yield its useful drop by the digger's tool
|
-- Check if node will yield its useful drop by the digger's tool
|
||||||
local dug_node = minetest.get_node(pos)
|
local dug_node = minetest.get_node(pos)
|
||||||
|
@ -270,9 +263,9 @@ function minetest.handle_node_drops(pos, drops, digger)
|
||||||
local tool
|
local tool
|
||||||
if digger then
|
if digger then
|
||||||
tool = digger:get_wielded_item()
|
tool = digger:get_wielded_item()
|
||||||
tooldef = minetest.registered_items[tool:get_name()]
|
tooldef = minetest.registered_tools[tool:get_name()]
|
||||||
|
|
||||||
if not mcl_autogroup.can_harvest(dug_node.name, tool:get_name(), digger) then
|
if not mcl_autogroup.can_harvest(dug_node.name, tool:get_name()) then
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,7 +2,7 @@ local S = minetest.get_translator(minetest.get_current_modname())
|
||||||
|
|
||||||
-- Template rail function
|
-- Template rail function
|
||||||
local function register_rail(itemstring, tiles, def_extras, creative)
|
local function register_rail(itemstring, tiles, def_extras, creative)
|
||||||
local groups = {handy=1,pickaxey=1, attached_node=1,rail=1,connect_to_raillike=minetest.raillike_group("rail"),dig_by_water=0,destroy_by_lava_flow=0, transport=1}
|
local groups = {handy=1,pickaxey=1, attached_node=1,rail=1,connect_to_raillike=minetest.raillike_group("rail"),dig_by_water=1,destroy_by_lava_flow=1, transport=1}
|
||||||
if creative == false then
|
if creative == false then
|
||||||
groups.not_in_creative_inventory = 1
|
groups.not_in_creative_inventory = 1
|
||||||
end
|
end
|
||||||
|
|
Before Width: | Height: | Size: 250 B After Width: | Height: | Size: 250 B |
Before Width: | Height: | Size: 247 B After Width: | Height: | Size: 247 B |
Before Width: | Height: | Size: 231 B After Width: | Height: | Size: 231 B |
Before Width: | Height: | Size: 238 B After Width: | Height: | Size: 238 B |
Before Width: | Height: | Size: 624 B After Width: | Height: | Size: 624 B |
Before Width: | Height: | Size: 271 B After Width: | Height: | Size: 271 B |
Before Width: | Height: | Size: 243 B After Width: | Height: | Size: 243 B |
After Width: | Height: | Size: 271 B |
Before Width: | Height: | Size: 236 B After Width: | Height: | Size: 236 B |
Before Width: | Height: | Size: 222 B After Width: | Height: | Size: 222 B |
Before Width: | Height: | Size: 257 B After Width: | Height: | Size: 257 B |
After Width: | Height: | Size: 285 B |
Before Width: | Height: | Size: 254 B After Width: | Height: | Size: 254 B |
Before Width: | Height: | Size: 254 B After Width: | Height: | Size: 254 B |
Before Width: | Height: | Size: 260 B After Width: | Height: | Size: 260 B |
Before Width: | Height: | Size: 266 B After Width: | Height: | Size: 266 B |
Before Width: | Height: | Size: 281 B After Width: | Height: | Size: 281 B |
Before Width: | Height: | Size: 258 B After Width: | Height: | Size: 258 B |
Before Width: | Height: | Size: 258 B After Width: | Height: | Size: 258 B |
Before Width: | Height: | Size: 319 B After Width: | Height: | Size: 319 B |
After Width: | Height: | Size: 282 B |
After Width: | Height: | Size: 274 B |
After Width: | Height: | Size: 259 B |
After Width: | Height: | Size: 260 B |
Before Width: | Height: | Size: 321 B After Width: | Height: | Size: 321 B |
Before Width: | Height: | Size: 279 B After Width: | Height: | Size: 279 B |
Before Width: | Height: | Size: 278 B After Width: | Height: | Size: 278 B |
Before Width: | Height: | Size: 256 B After Width: | Height: | Size: 256 B |
Before Width: | Height: | Size: 263 B After Width: | Height: | Size: 263 B |
Before Width: | Height: | Size: 263 B After Width: | Height: | Size: 263 B |
Before Width: | Height: | Size: 223 B After Width: | Height: | Size: 223 B |
Before Width: | Height: | Size: 223 B After Width: | Height: | Size: 223 B |