Merge branch 'master' of yunohost:nalc/unified_inventory
19
LICENSE.txt
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Unified Inventory for Minetest
|
||||||
|
Copyright (C) 2012-2014 Maciej Kasatkin (RealBadAngel)
|
||||||
|
|
||||||
|
This library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Library General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Library General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Library General Public
|
||||||
|
License along with this library; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
|
||||||
|
Contact information:
|
||||||
|
Examine a git patch to get the contributor's email address.
|
49
README.md
@ -1,22 +1,48 @@
|
|||||||
Unified inventory
|
# Unified Inventory
|
||||||
=================
|
|
||||||
|
|
||||||
Unified Inventory replaces the default survival and creative inventory.
|
Unified Inventory replaces the default survival and creative inventory.
|
||||||
It adds a nicer interface and a number of features, such as a crafting guide.
|
|
||||||
|
|
||||||
License
|
|
||||||
=======
|
## Features
|
||||||
|
|
||||||
|
* Node, item and tool browser
|
||||||
|
* Crafting guide
|
||||||
|
* Can copy the recipe to the crafting grid
|
||||||
|
* Recipe search function by ingredients
|
||||||
|
* Up to four bags with up to 24 slots each
|
||||||
|
* Home function to teleport
|
||||||
|
* Trash slot
|
||||||
|
* Lite mode: reduces the item browser width
|
||||||
|
* Mod API for modders: see [mod_api.txt](doc/mod_api.txt)
|
||||||
|
* Setting-determinated features: see [settingtypes.txt](settingtypes.txt)
|
||||||
|
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
* Minetest 5.0.0+ since commit 4403b69
|
||||||
|
* Minetest 0.4.16+ prior commit 4403b69
|
||||||
|
|
||||||
|
|
||||||
|
# Licenses
|
||||||
|
|
||||||
Copyright (C) 2012-2014 Maciej Kasatkin (RealBadAngel)
|
Copyright (C) 2012-2014 Maciej Kasatkin (RealBadAngel)
|
||||||
|
|
||||||
Unified inventory code is licensed under the GNU LGPLv2+.
|
Copyright (C) 2012-? Various minetest-mods contributors
|
||||||
|
|
||||||
Licenses for textures:
|
|
||||||
|
## Code
|
||||||
|
|
||||||
|
GNU LGPLv2+, see [license notice](LICENSE.txt)
|
||||||
|
|
||||||
|
|
||||||
|
## Textures
|
||||||
|
|
||||||
VanessaE: (CC-BY-4.0)
|
VanessaE: (CC-BY-4.0)
|
||||||
|
|
||||||
* `ui_group.png`
|
* `ui_group.png`
|
||||||
|
|
||||||
Tango Project: (Public Domain, CC-BY-4.0)
|
Tango Project: (Public Domain, CC-BY-4.0)
|
||||||
|
|
||||||
* [`ui_reset_icon.png`](https://commons.wikimedia.org/wiki/File:Edit-clear.svg)
|
* [`ui_reset_icon.png`](https://commons.wikimedia.org/wiki/File:Edit-clear.svg)
|
||||||
* [`ui_doubleleft_icon.png`](http://commons.wikimedia.org/wiki/File:Media-seek-backward.svg)
|
* [`ui_doubleleft_icon.png`](http://commons.wikimedia.org/wiki/File:Media-seek-backward.svg)
|
||||||
* [`ui_doubleright_icon.png`](http://commons.wikimedia.org/wiki/File:Media-seek-forward.svg)
|
* [`ui_doubleright_icon.png`](http://commons.wikimedia.org/wiki/File:Media-seek-forward.svg)
|
||||||
@ -25,6 +51,7 @@ Tango Project: (Public Domain, CC-BY-4.0)
|
|||||||
* [`ui_skip_forward_icon.png`](http://commons.wikimedia.org/wiki/File:Media-skip-forward.svg)
|
* [`ui_skip_forward_icon.png`](http://commons.wikimedia.org/wiki/File:Media-skip-forward.svg)
|
||||||
|
|
||||||
From http://www.clker.com (Public Domain, CC-BY-4.0):
|
From http://www.clker.com (Public Domain, CC-BY-4.0):
|
||||||
|
|
||||||
* [`bags_small.png`](http://www.clker.com/clipart-moneybag-empty.html)
|
* [`bags_small.png`](http://www.clker.com/clipart-moneybag-empty.html)
|
||||||
* [`bags_medium.png`](http://www.clker.com/clipart-backpack-1.html)
|
* [`bags_medium.png`](http://www.clker.com/clipart-backpack-1.html)
|
||||||
* [`bags_large.png` / `ui_bags_icon.png`](http://www.clker.com/clipart-backpack-green-brown.html)
|
* [`bags_large.png` / `ui_bags_icon.png`](http://www.clker.com/clipart-backpack-green-brown.html)
|
||||||
@ -37,25 +64,33 @@ From http://www.clker.com (Public Domain, CC-BY-4.0):
|
|||||||
* [`ui_waypoint_set_icon.png`](http://www.clker.com/clipart-larger-flag.html)
|
* [`ui_waypoint_set_icon.png`](http://www.clker.com/clipart-larger-flag.html)
|
||||||
|
|
||||||
Everaldo Coelho (YellowIcon) (LGPL v2.1+):
|
Everaldo Coelho (YellowIcon) (LGPL v2.1+):
|
||||||
|
|
||||||
* [`ui_craftguide_icon.png` / `ui_craft_icon.png`](http://commons.wikimedia.org/wiki/File:Advancedsettings.png)
|
* [`ui_craftguide_icon.png` / `ui_craft_icon.png`](http://commons.wikimedia.org/wiki/File:Advancedsettings.png)
|
||||||
|
|
||||||
Gregory H. Revera: (CC-BY-SA 3.0)
|
Gregory H. Revera: (CC-BY-SA 3.0)
|
||||||
|
|
||||||
* [`ui_moon_icon.png`](http://commons.wikimedia.org/wiki/File:FullMoon2010.jpg)
|
* [`ui_moon_icon.png`](http://commons.wikimedia.org/wiki/File:FullMoon2010.jpg)
|
||||||
|
|
||||||
Thomas Bresson: (CC-BY 3.0)
|
Thomas Bresson: (CC-BY 3.0)
|
||||||
|
|
||||||
* [`ui_sun_icon.png`](http://commons.wikimedia.org/wiki/File:2012-10-13_15-29-35-sun.jpg)
|
* [`ui_sun_icon.png`](http://commons.wikimedia.org/wiki/File:2012-10-13_15-29-35-sun.jpg)
|
||||||
|
|
||||||
Fibonacci: (Public domain, CC-BY 4.0)
|
Fibonacci: (Public domain, CC-BY 4.0)
|
||||||
|
|
||||||
* [`ui_xyz_off_icon.png`](http://commons.wikimedia.org/wiki/File:No_sign.svg)
|
* [`ui_xyz_off_icon.png`](http://commons.wikimedia.org/wiki/File:No_sign.svg)
|
||||||
|
|
||||||
Gregory Maxwell: (Public domain, CC-BY 4.0)
|
Gregory Maxwell: (Public domain, CC-BY 4.0)
|
||||||
|
|
||||||
* [`ui_ok_icon.png`](http://commons.wikimedia.org/wiki/File:Yes_check.svg)
|
* [`ui_ok_icon.png`](http://commons.wikimedia.org/wiki/File:Yes_check.svg)
|
||||||
|
|
||||||
Adrien Facélina: (LGPL v2.1+)
|
Adrien Facélina: (LGPL v2.1+)
|
||||||
|
|
||||||
* [`inventory_plus_worldedit_gui.png`](http://commons.wikimedia.org/wiki/File:Erioll_world_2.svg)
|
* [`inventory_plus_worldedit_gui.png`](http://commons.wikimedia.org/wiki/File:Erioll_world_2.svg)
|
||||||
|
|
||||||
Other files from Wikimedia Commons:
|
Other files from Wikimedia Commons:
|
||||||
|
|
||||||
* [`ui_gohome_icon.png` / `ui_home_icon.png` / `ui_sethome_icon.png`](http://commons.wikimedia.org/wiki/File:Home_256x256.png) (GPL v2+)
|
* [`ui_gohome_icon.png` / `ui_home_icon.png` / `ui_sethome_icon.png`](http://commons.wikimedia.org/wiki/File:Home_256x256.png) (GPL v2+)
|
||||||
|
|
||||||
RealBadAngel: (CC-BY-4.0)
|
RealBadAngel: (CC-BY-4.0)
|
||||||
|
|
||||||
* Everything else.
|
* Everything else.
|
2
api.lua
@ -187,7 +187,7 @@ end
|
|||||||
function unified_inventory.go_home(player)
|
function unified_inventory.go_home(player)
|
||||||
local pos = unified_inventory.home_pos[player:get_player_name()]
|
local pos = unified_inventory.home_pos[player:get_player_name()]
|
||||||
if pos then
|
if pos then
|
||||||
player:setpos(pos)
|
player:set_pos(pos)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
16
bags.lua
@ -1,7 +1,9 @@
|
|||||||
-- Bags for Minetest
|
--[[
|
||||||
|
Bags for Minetest
|
||||||
|
|
||||||
-- Copyright (c) 2012 cornernote, Brett O'Donnell <cornernote@gmail.com>
|
Copyright (c) 2012 cornernote, Brett O'Donnell <cornernote@gmail.com>
|
||||||
-- License: GPLv3
|
License: GPLv3
|
||||||
|
--]]
|
||||||
|
|
||||||
local S = unified_inventory.gettext
|
local S = unified_inventory.gettext
|
||||||
local F = minetest.formspec_escape
|
local F = minetest.formspec_escape
|
||||||
@ -118,17 +120,19 @@ local function save_bags_metadata(player, bags_inv)
|
|||||||
is_empty = false
|
is_empty = false
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
local meta = player:get_meta()
|
||||||
if is_empty then
|
if is_empty then
|
||||||
player:set_attribute("unified_inventory:bags", nil)
|
meta:set_string("unified_inventory:bags", nil)
|
||||||
else
|
else
|
||||||
player:set_attribute("unified_inventory:bags",
|
meta:set_string("unified_inventory:bags",
|
||||||
minetest.serialize(bags))
|
minetest.serialize(bags))
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
local function load_bags_metadata(player, bags_inv)
|
local function load_bags_metadata(player, bags_inv)
|
||||||
local player_inv = player:get_inventory()
|
local player_inv = player:get_inventory()
|
||||||
local bags_meta = player:get_attribute("unified_inventory:bags")
|
local meta = player:get_meta()
|
||||||
|
local bags_meta = meta:get_string("unified_inventory:bags")
|
||||||
local bags = bags_meta and minetest.deserialize(bags_meta) or {}
|
local bags = bags_meta and minetest.deserialize(bags_meta) or {}
|
||||||
local dirty_meta = false
|
local dirty_meta = false
|
||||||
if not bags_meta then
|
if not bags_meta then
|
||||||
|
@ -47,6 +47,15 @@ minetest.register_on_joinplayer(function(player)
|
|||||||
refill:set_size("main", 1)
|
refill:set_size("main", 1)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
local function apply_new_filter(player, search_text, new_dir)
|
||||||
|
local player_name = player:get_player_name()
|
||||||
|
minetest.sound_play("click", {to_player=player_name, gain = 0.1})
|
||||||
|
unified_inventory.apply_filter(player, search_text, new_dir)
|
||||||
|
unified_inventory.current_searchbox[player_name] = search_text
|
||||||
|
unified_inventory.set_inventory_formspec(player,
|
||||||
|
unified_inventory.current_page[player_name])
|
||||||
|
end
|
||||||
|
|
||||||
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
minetest.register_on_player_receive_fields(function(player, formname, fields)
|
||||||
local player_name = player:get_player_name()
|
local player_name = player:get_player_name()
|
||||||
|
|
||||||
@ -60,7 +69,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
if fields.searchbox
|
if fields.searchbox
|
||||||
and fields.searchbox ~= unified_inventory.current_searchbox[player_name] then
|
and fields.searchbox ~= unified_inventory.current_searchbox[player_name] then
|
||||||
unified_inventory.current_searchbox[player_name] = fields.searchbox
|
unified_inventory.current_searchbox[player_name] = fields.searchbox
|
||||||
unified_inventory.set_inventory_formspec(player, unified_inventory.current_page[player_name])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
for i, def in pairs(unified_inventory.buttons) do
|
for i, def in pairs(unified_inventory.buttons) do
|
||||||
@ -112,21 +120,18 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
unified_inventory.current_page[player_name])
|
unified_inventory.current_page[player_name])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Check clicked item image button
|
||||||
local clicked_item
|
local clicked_item
|
||||||
for name, value in pairs(fields) do
|
for name, value in pairs(fields) do
|
||||||
if string.sub(name, 1, 12) == "item_button_" then
|
local new_dir, mangled_item = string.match(name, "^item_button_([a-z]+)_(.*)$")
|
||||||
local new_dir, mangled_item = string.match(name, "^item_button_([a-z]+)_(.*)$")
|
if new_dir and mangled_item then
|
||||||
clicked_item = unified_inventory.demangle_for_formspec(mangled_item)
|
clicked_item = unified_inventory.demangle_for_formspec(mangled_item)
|
||||||
if string.sub(clicked_item, 1, 6) == "group:" then
|
if string.sub(clicked_item, 1, 6) == "group:" then
|
||||||
minetest.sound_play("click", {to_player=player_name, gain = 0.1})
|
-- Change search filter to this group
|
||||||
unified_inventory.apply_filter(player, clicked_item, new_dir)
|
apply_new_filter(player, clicked_item, new_dir)
|
||||||
unified_inventory.current_searchbox[player_name] = clicked_item
|
|
||||||
unified_inventory.set_inventory_formspec(player,
|
|
||||||
unified_inventory.current_page[player_name])
|
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
if new_dir == "recipe"
|
if new_dir == "recipe" or new_dir == "usage" then
|
||||||
or new_dir == "usage" then
|
|
||||||
unified_inventory.current_craft_direction[player_name] = new_dir
|
unified_inventory.current_craft_direction[player_name] = new_dir
|
||||||
end
|
end
|
||||||
break
|
break
|
||||||
@ -145,6 +150,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
unified_inventory.alternate[player_name] = 1
|
unified_inventory.alternate[player_name] = 1
|
||||||
unified_inventory.set_inventory_formspec(player, "craftguide")
|
unified_inventory.set_inventory_formspec(player, "craftguide")
|
||||||
elseif player_creative then
|
elseif player_creative then
|
||||||
|
-- Creative page: Add entire stack to inventory
|
||||||
local inv = player:get_inventory()
|
local inv = player:get_inventory()
|
||||||
local stack = ItemStack(clicked_item)
|
local stack = ItemStack(clicked_item)
|
||||||
stack:set_count(stack:get_stack_max())
|
stack:set_count(stack:get_stack_max())
|
||||||
@ -162,12 +168,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
minetest.sound_play("paperflip2",
|
minetest.sound_play("paperflip2",
|
||||||
{to_player=player_name, gain = 1.0})
|
{to_player=player_name, gain = 1.0})
|
||||||
elseif fields.searchresetbutton then
|
elseif fields.searchresetbutton then
|
||||||
unified_inventory.apply_filter(player, "", "nochange")
|
apply_new_filter(player, "", "nochange")
|
||||||
unified_inventory.current_searchbox[player_name] = ""
|
|
||||||
unified_inventory.set_inventory_formspec(player,
|
|
||||||
unified_inventory.current_page[player_name])
|
|
||||||
minetest.sound_play("click",
|
|
||||||
{to_player=player_name, gain = 0.1})
|
|
||||||
end
|
end
|
||||||
|
|
||||||
-- alternate buttons
|
-- alternate buttons
|
||||||
|
@ -302,15 +302,13 @@ function unified_inventory.apply_filter(player, filter, search_dir)
|
|||||||
return string.find(lname, lfilter, 1, true) or string.find(ldesc, lfilter, 1, true)
|
return string.find(lname, lfilter, 1, true) or string.find(ldesc, lfilter, 1, true)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
local is_creative = unified_inventory.is_creative(player_name)
|
|
||||||
unified_inventory.filtered_items_list[player_name]={}
|
unified_inventory.filtered_items_list[player_name]={}
|
||||||
for name, def in pairs(minetest.registered_items) do
|
for name, def in pairs(minetest.registered_items) do
|
||||||
if (not def.groups.not_in_creative_inventory
|
if (not def.groups.not_in_creative_inventory
|
||||||
or def.groups.not_in_creative_inventory == 0)
|
or def.groups.not_in_creative_inventory == 0)
|
||||||
and def.description
|
and def.description
|
||||||
and def.description ~= ""
|
and def.description ~= ""
|
||||||
and ffilter(name, def)
|
and ffilter(name, def) then
|
||||||
and (is_creative or unified_inventory.crafts_for.recipe[def.name]) then
|
|
||||||
table.insert(unified_inventory.filtered_items_list[player_name], name)
|
table.insert(unified_inventory.filtered_items_list[player_name], name)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
3
mod.conf
@ -1 +1,4 @@
|
|||||||
name = unified_inventory
|
name = unified_inventory
|
||||||
|
depends = default
|
||||||
|
optional_depends = creative, sfinv, intllib, datastorage, farming
|
||||||
|
description = Unified Inventory replaces the default survival and creative inventory. It adds a nicer interface and a number of features, such as a crafting guide.
|
||||||
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 546 B After Width: | Height: | Size: 456 B |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 961 B |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.1 KiB |
Before Width: | Height: | Size: 777 B After Width: | Height: | Size: 658 B |
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 928 B |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 7.9 KiB |
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 7.0 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 81 B After Width: | Height: | Size: 71 B |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 8.6 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 896 B After Width: | Height: | Size: 483 B |
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 962 B |
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.3 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.0 KiB |
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 9.1 KiB |
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 23 KiB After Width: | Height: | Size: 22 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 7.0 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.0 KiB |
Before Width: | Height: | Size: 8.7 KiB After Width: | Height: | Size: 5.2 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 5.9 KiB After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 5.9 KiB |
Before Width: | Height: | Size: 3.8 KiB After Width: | Height: | Size: 3.2 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 6.3 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 10 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 988 B After Width: | Height: | Size: 629 B |
Before Width: | Height: | Size: 9.3 KiB After Width: | Height: | Size: 8.1 KiB |
Before Width: | Height: | Size: 9.2 KiB After Width: | Height: | Size: 8.0 KiB |
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 18 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 3.7 KiB |
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 2.1 KiB |
@ -174,7 +174,7 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
|
|||||||
|
|
||||||
if fields["set_waypoint"..i] then
|
if fields["set_waypoint"..i] then
|
||||||
hit = true
|
hit = true
|
||||||
local pos = player:getpos()
|
local pos = player:get_pos()
|
||||||
pos.x = math.floor(pos.x)
|
pos.x = math.floor(pos.x)
|
||||||
pos.y = math.floor(pos.y)
|
pos.y = math.floor(pos.y)
|
||||||
pos.z = math.floor(pos.z)
|
pos.z = math.floor(pos.z)
|
||||||
|