Compare commits

..

2 Commits

Author SHA1 Message Date
iliekprogrammar 08e2daefb9 Merge branch 'master' into csm-enabled 2022-12-31 05:52:22 +00:00
AFCMS 3ec2d17641
Add `mcl_player_csm` mod to check if a player have the official CSM enabled 2022-12-09 23:22:50 +01:00
3337 changed files with 4179 additions and 19078 deletions

View File

@ -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!

View File

@ -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!

View File

@ -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?

View File

@ -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!

1
.gitignore vendored
View File

@ -4,4 +4,3 @@
*.blend2
*.blend3
/.idea/
*.xcf

1
API.md
View File

@ -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`
* Buckets: `ITEMS/mcl_buckets`
* Dispenser support: `ITEMS/REDSTONE/mcl_dispensers`
* Campfires: `ITEMS/mcl_campfires`
### Mobs
* Mobs: `ENTITIES/mcl_mobs`

View File

@ -2,8 +2,8 @@
So you want to contribute to MineClone2?
Wow, thank you! :-)
MineClone2 is maintained by AncientMariner and Nicu. If you have any
problems or questions, contact us on Discord/Matrix (See Links section below).
MineClone2 is maintained by Nicu and Cora. If you have any
problems or questions, contact us (See Links section below).
You can help with MineClone2's development in many different ways,
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
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.
You can use these sources:
@ -375,7 +375,7 @@ merged.
- Resolving conflicts and problems within the community
#### Current maintainers
* AncientMariner - responsible for gameplay review, publishing releases,
* Cora - responsible for gameplay review, publishing releases,
technical guidelines
* Nicu - responsible for community related issues

View File

@ -35,8 +35,7 @@
* SumianVoice
* MrRar
* talamh
* Faerraven / Michieal
* FossFanatic
* Faerraven
## Contributors
* Laurent Rocher
@ -97,12 +96,6 @@
* TheOnlyJoeEnderman
* Ranko Saotome
* Gregor Parzefall
* Wbjitscool
* b3nderman
* CyberMango
* gldrk
* SmokeyDope
* atomdmac
## MineClone5
* kay27
@ -154,13 +147,11 @@
* jordan4ibanez
* paramat
* cora
* Faerraven / Michieal
## 3D Models
* 22i
* tobyplowy
* epCode
* Faerraven / Michieal
## Textures
* XSSheep
@ -175,7 +166,6 @@
* RandomLegoBrick
* cora
* Faerraven / Michieal
* Nicu
## Translations
* Wuzzy
@ -190,12 +180,9 @@
* snowyu
* 3raven
* SakuraRiu
* anarquimico
## Funders
* 40W
* bauknecht
* Cora
## Special thanks
* celeron55 for creating Minetest

View File

@ -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!

View File

@ -2,6 +2,8 @@
An unofficial Minecraft-like game for Minetest. Forked from MineClone by davedevils.
Developed by many people. Not developed or endorsed by Mojang AB.
Version: 0.82 (in development)
### Gameplay
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
@ -156,7 +158,7 @@ The following features are incomplete:
* Some monsters and animals
* Redstone-related things
* Some special minecarts (hopper and chest minecarts work)
* Special minecarts
* A couple of non-trivial blocks and items
Bonus features (not found in Minecraft):

View File

@ -1,75 +1,19 @@
### Standard Release
#File to document release steps with a view to evolving into a script
#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
git add CREDITS.md
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
#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
git push origin 0.81.1

View File

@ -1,4 +1,4 @@
title = MineClone 2
description = A survival sandbox game. Survive, gather, hunt, build, explore, and do much more.
disallowed_mapgens = v6
version=0.82.0-SNAPSHOT
version=MCL2-0.82-indev

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@ -204,7 +204,7 @@ end
-- Checks if the given node would drop its useful drop if dug by a given tool.
-- Returns true if it will yield its useful drop, false otherwise.
function mcl_autogroup.can_harvest(nodename, toolname, player)
function mcl_autogroup.can_harvest(nodename, toolname)
local ndef = minetest.registered_nodes[nodename]
if not ndef then
@ -228,9 +228,7 @@ function mcl_autogroup.can_harvest(nodename, toolname, player)
end
-- Check if it can be dug by hand
if not player or not player:is_player() then return false end
local name = player:get_inventory():get_stack("hand", 1):get_name()
local tdef = minetest.registered_items[name]
local tdef = minetest.registered_tools[""]
if tdef then
for g, gdef in pairs(tdef._mcl_diggroups) do
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,
-- 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 {
full_punch_interval = hand_toolcaps.full_punch_interval,
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
-- loading order.
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 {})
add_groupcaps(toolname, groupcaps, tdef._mcl_diggroups, efficiency)
return groupcaps
@ -352,7 +350,7 @@ local function overwrite()
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
-- depending on the _mcl_diggroups in the tool definition
if tdef._mcl_diggroups then
@ -362,12 +360,6 @@ local function overwrite()
minetest.override_item(tname, {
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

View File

@ -1,11 +1,10 @@
# mcl_autogroup
This mod emulate digging times from mc.
## mcl_autogroup.can_harvest(nodename, toolname, player)
Return true if <nodename> can be dig with <toolname> by <player>.
## mcl_autogroup.can_harvest(nodename, toolname)
Return true if <nodename> can be dig with <toolname>.
* nodename: string, valid nodename
* toolname: (optional) string, valid toolname
* player: (optinal) ObjectRef, valid player
## mcl_autogroup.get_groupcaps(toolname, efficiency)
This function is used to calculate diggroups for tools.

View File

@ -155,6 +155,7 @@ end, true)
minetest.register_on_player_hpchange(function(player, hp_change, mt_reason)
if not damage_enabled then return 0 end
if player:get_hp() > 0 then
mt_reason.approved = true
if hp_change < 0 then
mcl_damage.run_damage_callbacks(player, -hp_change, mcl_damage.from_mt(mt_reason))
end
@ -162,7 +163,9 @@ minetest.register_on_player_hpchange(function(player, hp_change, mt_reason)
end, false)
minetest.register_on_dieplayer(function(player, mt_reason)
mcl_damage.run_death_callbacks(player, mcl_damage.from_mt(mt_reason))
if mt_reason.approved then
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())))
end)

View File

Before

Width:  |  Height:  |  Size: 3.3 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

View File

Before

Width:  |  Height:  |  Size: 126 B

After

Width:  |  Height:  |  Size: 126 B

View File

Before

Width:  |  Height:  |  Size: 127 B

After

Width:  |  Height:  |  Size: 127 B

View File

Before

Width:  |  Height:  |  Size: 91 B

After

Width:  |  Height:  |  Size: 91 B

View File

Before

Width:  |  Height:  |  Size: 137 B

After

Width:  |  Height:  |  Size: 137 B

View File

Before

Width:  |  Height:  |  Size: 145 B

After

Width:  |  Height:  |  Size: 145 B

View File

Before

Width:  |  Height:  |  Size: 125 B

After

Width:  |  Height:  |  Size: 125 B

View File

Before

Width:  |  Height:  |  Size: 183 B

After

Width:  |  Height:  |  Size: 183 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 B

After

Width:  |  Height:  |  Size: 126 B

View File

Before

Width:  |  Height:  |  Size: 126 B

After

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 B

View File

Before

Width:  |  Height:  |  Size: 144 B

After

Width:  |  Height:  |  Size: 144 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 101 B

After

Width:  |  Height:  |  Size: 101 B

View File

Before

Width:  |  Height:  |  Size: 148 B

After

Width:  |  Height:  |  Size: 148 B

View File

Before

Width:  |  Height:  |  Size: 154 B

After

Width:  |  Height:  |  Size: 154 B

View File

Before

Width:  |  Height:  |  Size: 155 B

After

Width:  |  Height:  |  Size: 155 B

View File

Before

Width:  |  Height:  |  Size: 165 B

After

Width:  |  Height:  |  Size: 165 B

View File

@ -2,8 +2,8 @@ mcl_util = {}
-- Updates all values in t using values from to*.
function table.update(t, ...)
for _, to in ipairs {...} do
for k, v in pairs(to) do
for _, to in ipairs{...} do
for k,v in pairs(to) do
t[k] = v
end
end
@ -12,8 +12,8 @@ end
-- Updates nil values in t using values from to*.
function table.update_nil(t, ...)
for _, to in ipairs {...} do
for k, v in pairs(to) do
for _, to in ipairs{...} do
for k,v in pairs(to) do
if t[k] == nil then
t[k] = v
end
@ -22,9 +22,9 @@ function table.update_nil(t, ...)
return t
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]"
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
if module then
selected_module = module
@ -34,6 +34,7 @@ function mcl_util.mcl_log(message, module, bypass_default_logger)
end
end
function mcl_util.file_exists(name)
if type(name) ~= "string" then return end
local f = io.open(name)
@ -68,7 +69,7 @@ function mcl_util.rotate_axis_and_place(itemstack, placer, pointed_thing, infini
local undef = minetest.registered_nodes[unode.name]
if undef and undef.on_rightclick then
undef.on_rightclick(pointed_thing.under, unode, placer,
itemstack, pointed_thing)
itemstack, pointed_thing)
return
end
local fdir = minetest.dir_to_facedir(placer:get_look_dir())
@ -150,23 +151,23 @@ end
function mcl_util.get_double_container_neighbor_pos(pos, param2, side)
if side == "right" 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
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
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
return {x = pos.x, y = pos.y, z = pos.z - 1}
return {x=pos.x, y=pos.y, z=pos.z-1}
end
else
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
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
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
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
@ -184,7 +185,7 @@ end
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 stack
for i = 1, size do
for i=1, size do
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
return i
@ -287,10 +288,10 @@ function mcl_util.move_item_container(source_pos, destination_pos, source_list,
-- Main inventory for most container types
if sctype == 2 or sctype == 3 or sctype == 5 or sctype == 6 or sctype == 7 then
source_list = "main"
-- Furnace: output
-- Furnace: output
elseif sctype == 4 then
source_list = "dst"
-- Unknown source container type. Bail out
-- Unknown source container type. Bail out
else
return false
end
@ -343,7 +344,7 @@ function mcl_util.move_item_container(source_pos, destination_pos, source_list,
-- Main inventory for most container types
if dctype == 2 or dctype == 3 or dctype == 5 or dctype == 6 or dctype == 7 then
destination_list = "main"
-- Furnace source slot
-- Furnace source slot
elseif dctype == 4 then
destination_list = "src"
end
@ -408,7 +409,7 @@ end
-- Returns true if item (itemstring or ItemStack) can be used as a furnace fuel.
-- Returns false otherwise
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
-- Returns a on_place function for plants
@ -455,7 +456,7 @@ function mcl_util.generate_on_place_plant_function(condition)
if success 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
itemstack = new_itemstack
@ -556,11 +557,6 @@ function mcl_util.deal_damage(target, damage, mcl_reason)
end
end
local is_immortal = target:get_armor_groups().immortal or 0
if is_immortal>0 then
return
end
local hp = target:get_hp()
if hp > 0 then
@ -647,80 +643,78 @@ end
local function roundN(n, d)
if type(n) ~= "number" then return n end
local m = 10 ^ d
return math.floor(n * m + 0.5) / m
local m = 10^d
return math.floor(n * m + 0.5) / m
end
local function close_enough(a, b)
local rt = true
local function close_enough(a,b)
local rt=true
if type(a) == "table" and type(b) == "table" then
for k, v in pairs(a) do
if roundN(v, 2) ~= roundN(b[k], 2) then
rt = false
for k,v in pairs(a) do
if roundN(v,2) ~= roundN(b[k],2) then
rt=false
break
end
end
else
rt = roundN(a, 2) == roundN(b, 2)
rt = roundN(a,2) == roundN(b,2)
end
return rt
end
local function props_changed(props, oldprops)
local changed = false
local p = {}
for k, v in pairs(props) do
if not close_enough(v, oldprops[k]) then
p[k] = v
changed = true
local function props_changed(props,oldprops)
local changed=false
local p={}
for k,v in pairs(props) do
if not close_enough(v,oldprops[k]) then
p[k]=v
changed=true
end
end
return changed, p
return changed,p
end
--tests for roundN
local test_round1 = 15
local test_round2 = 15.00199999999
local test_round3 = 15.00111111
local test_round4 = 15.00999999
local test_round1=15
local test_round2=15.00199999999
local test_round3=15.00111111
local test_round4=15.00999999
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_round3, 2))
assert(roundN(test_round1, 2) ~= roundN(test_round4, 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_round3,2))
assert(roundN(test_round1,2)~=roundN(test_round4,2))
-- tests for close_enough
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_diff = {-0.35, 0, -1.35, 0.35, 0.8, 0.35}
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_diff = {-0.35,0,-1.35,0.35,0.8,0.35}
local test_eh = 1.65 --eye height
local test_eh_close = 1.65123123
local test_eh_diff = 1.35
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 = { r = 225, b = 225, a = 225, g = 225 } --nametag
local test_nt_diff = { r = 225, b = 225, a = 0, g = 225 }
assert(close_enough(test_cb, test_cb_close))
assert(not close_enough(test_cb, test_cb_diff))
assert(close_enough(test_eh, test_eh_close))
assert(not close_enough(test_eh, test_eh_diff))
assert(not close_enough(test_nt, test_nt_diff)) --no floats involved here
assert(close_enough(test_cb,test_cb_close))
assert(not close_enough(test_cb,test_cb_diff))
assert(close_enough(test_eh,test_eh_close))
assert(not close_enough(test_eh,test_eh_diff))
assert(not close_enough(test_nt,test_nt_diff)) --no floats involved here
--tests for properties_changed
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}}
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_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 }}
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_p2, _ = props_changed(test_properties_set1, test_properties_set2)
local test_p1,_=props_changed(test_properties_set1,test_properties_set1)
local test_p2,_=props_changed(test_properties_set1,test_properties_set2)
assert(not test_p1)
assert(test_p2)
function mcl_util.set_properties(obj, props)
local changed, p = props_changed(props, obj:get_properties())
function mcl_util.set_properties(obj,props)
local changed,p=props_changed(props,obj:get_properties())
if changed then
obj:set_properties(p)
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)
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

Binary file not shown.

After

Width:  |  Height:  |  Size: 265 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 264 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 261 B

After

Width:  |  Height:  |  Size: 261 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 271 B

After

Width:  |  Height:  |  Size: 271 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.0 KiB

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 264 B

After

Width:  |  Height:  |  Size: 264 B

View File

Before

Width:  |  Height:  |  Size: 267 B

After

Width:  |  Height:  |  Size: 267 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

Before

Width:  |  Height:  |  Size: 969 B

After

Width:  |  Height:  |  Size: 969 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 12 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 535 B

After

Width:  |  Height:  |  Size: 535 B

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -252,17 +252,10 @@ function minetest.handle_node_drops(pos, drops, digger)
-- 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
-- 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 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
if (digger and digger:is_player() and minetest.is_creative_enabled(digger:get_player_name())) or doTileDrops == false then
return
elseif not doTileDrops then return end
end
-- Check if node will yield its useful drop by the digger's tool
local dug_node = minetest.get_node(pos)
@ -270,9 +263,9 @@ function minetest.handle_node_drops(pos, drops, digger)
local tool
if digger then
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
end
end

View File

@ -2,7 +2,7 @@ local S = minetest.get_translator(minetest.get_current_modname())
-- Template rail function
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
groups.not_in_creative_inventory = 1
end

View File

Before

Width:  |  Height:  |  Size: 250 B

After

Width:  |  Height:  |  Size: 250 B

View File

Before

Width:  |  Height:  |  Size: 247 B

After

Width:  |  Height:  |  Size: 247 B

View File

Before

Width:  |  Height:  |  Size: 231 B

After

Width:  |  Height:  |  Size: 231 B

View File

Before

Width:  |  Height:  |  Size: 238 B

After

Width:  |  Height:  |  Size: 238 B

View File

Before

Width:  |  Height:  |  Size: 624 B

After

Width:  |  Height:  |  Size: 624 B

View File

Before

Width:  |  Height:  |  Size: 271 B

After

Width:  |  Height:  |  Size: 271 B

View File

Before

Width:  |  Height:  |  Size: 243 B

After

Width:  |  Height:  |  Size: 243 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 271 B

View File

Before

Width:  |  Height:  |  Size: 236 B

After

Width:  |  Height:  |  Size: 236 B

View File

Before

Width:  |  Height:  |  Size: 222 B

After

Width:  |  Height:  |  Size: 222 B

View File

Before

Width:  |  Height:  |  Size: 257 B

After

Width:  |  Height:  |  Size: 257 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 285 B

View File

Before

Width:  |  Height:  |  Size: 254 B

After

Width:  |  Height:  |  Size: 254 B

View File

Before

Width:  |  Height:  |  Size: 260 B

After

Width:  |  Height:  |  Size: 260 B

View File

Before

Width:  |  Height:  |  Size: 281 B

After

Width:  |  Height:  |  Size: 281 B

View File

Before

Width:  |  Height:  |  Size: 258 B

After

Width:  |  Height:  |  Size: 258 B

View File

Before

Width:  |  Height:  |  Size: 319 B

After

Width:  |  Height:  |  Size: 319 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 259 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 260 B

View File

Before

Width:  |  Height:  |  Size: 321 B

After

Width:  |  Height:  |  Size: 321 B

View File

Before

Width:  |  Height:  |  Size: 279 B

After

Width:  |  Height:  |  Size: 279 B

View File

Before

Width:  |  Height:  |  Size: 256 B

After

Width:  |  Height:  |  Size: 256 B

View File

Before

Width:  |  Height:  |  Size: 263 B

After

Width:  |  Height:  |  Size: 263 B

View File

Before

Width:  |  Height:  |  Size: 223 B

After

Width:  |  Height:  |  Size: 223 B

View File

Before

Width:  |  Height:  |  Size: 223 B

After

Width:  |  Height:  |  Size: 223 B

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