Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
M
minetest_game
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Model registry
Operate
Environments
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Zadrog Pzvotrügen
minetest_game
Commits
77648aac
Commit
77648aac
authored
8 years ago
by
Milan
Browse files
Options
Downloads
Patches
Plain Diff
hopefully readd submodule boats and farming
parent
23544869
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
.gitmodules
+1
-1
1 addition, 1 deletion
.gitmodules
mods/boats
+1
-0
1 addition, 0 deletions
mods/boats
mods/boats/init.lua
+0
-249
0 additions, 249 deletions
mods/boats/init.lua
mods/farming
+1
-0
1 addition, 0 deletions
mods/farming
mods/farming/api.lua
+0
-364
0 additions, 364 deletions
mods/farming/api.lua
with
3 additions
and
614 deletions
.gitmodules
+
1
−
1
View file @
77648aac
[submodule "mods/boats"]
path = mods/boats
url = https://git
hub.com/tenplus1
/boats.git
url = https://git
.tchncs.de/Illuna-Minetest
/boats.git
[submodule "mods/illuna"]
path = mods/illuna
url = https://git.tchncs.de/Illuna-Minetest/illuna.git
...
...
This diff is collapsed.
Click to expand it.
boats
@
a7534e93
Subproject commit a7534e938834c1a0322e49df796f613ca1f55880
This diff is collapsed.
Click to expand it.
mods/boats/init.lua
deleted
100644 → 0
+
0
−
249
View file @
23544869
--
-- Helper functions
--
local
function
is_water
(
pos
)
local
nn
=
minetest
.
get_node
(
pos
).
name
return
minetest
.
get_item_group
(
nn
,
"water"
)
~=
0
end
local
function
get_sign
(
i
)
if
i
==
0
then
return
0
else
return
i
/
math.abs
(
i
)
end
end
local
function
get_velocity
(
v
,
yaw
,
y
)
local
x
=
-
math.sin
(
yaw
)
*
v
local
z
=
math.cos
(
yaw
)
*
v
return
{
x
=
x
,
y
=
y
,
z
=
z
}
end
local
function
get_v
(
v
)
return
math.sqrt
(
v
.
x
^
2
+
v
.
z
^
2
)
end
--
-- Boat entity
--
local
boat
=
{
physical
=
true
,
-- Warning: Do not change the position of the collisionbox top surface,
-- lowering it causes the boat to fall through the world if underwater
collisionbox
=
{
-
0
.
5
,
-
0
.
35
,
-
0
.
5
,
0
.
5
,
0
.
3
,
0
.
5
},
visual
=
"mesh"
,
mesh
=
"boats_boat.obj"
,
textures
=
{
"default_wood.png"
},
driver
=
nil
,
v
=
0
,
last_v
=
0
,
removed
=
false
}
function
boat
.
on_rightclick
(
self
,
clicker
)
if
not
clicker
or
not
clicker
:
is_player
()
then
return
end
local
name
=
clicker
:
get_player_name
()
if
self
.
driver
and
clicker
==
self
.
driver
then
self
.
driver
=
nil
clicker
:
set_detach
()
default
.
player_attached
[
name
]
=
false
default
.
player_set_animation
(
clicker
,
"stand"
,
30
)
local
pos
=
clicker
:
getpos
()
pos
=
{
x
=
pos
.
x
,
y
=
pos
.
y
+
0
.
2
,
z
=
pos
.
z
}
minetest
.
after
(
0
.
1
,
function
()
clicker
:
setpos
(
pos
)
end
)
elseif
not
self
.
driver
then
local
attach
=
clicker
:
get_attach
()
if
attach
and
attach
:
get_luaentity
()
then
local
luaentity
=
attach
:
get_luaentity
()
if
luaentity
.
driver
then
luaentity
.
driver
=
nil
end
clicker
:
set_detach
()
end
self
.
driver
=
clicker
clicker
:
set_attach
(
self
.
object
,
""
,
{
x
=
0
,
y
=
11
,
z
=
-
3
},
{
x
=
0
,
y
=
0
,
z
=
0
})
default
.
player_attached
[
name
]
=
true
minetest
.
after
(
0
.
2
,
function
()
default
.
player_set_animation
(
clicker
,
"sit"
,
30
)
end
)
self
.
object
:
setyaw
(
clicker
:
get_look_yaw
()
-
math.pi
/
2
)
end
end
function
boat
.
on_activate
(
self
,
staticdata
,
dtime_s
)
self
.
object
:
set_armor_groups
({
immortal
=
1
})
if
staticdata
then
self
.
v
=
tonumber
(
staticdata
)
end
self
.
last_v
=
self
.
v
end
function
boat
.
get_staticdata
(
self
)
return
tostring
(
self
.
v
)
end
function
boat
.
on_punch
(
self
,
puncher
)
if
not
puncher
or
not
puncher
:
is_player
()
or
self
.
removed
then
return
end
if
self
.
driver
and
puncher
==
self
.
driver
then
self
.
driver
=
nil
puncher
:
set_detach
()
default
.
player_attached
[
puncher
:
get_player_name
()]
=
false
end
if
not
self
.
driver
then
self
.
removed
=
true
-- delay remove to ensure player is detached
minetest
.
after
(
0
.
1
,
function
()
self
.
object
:
remove
()
end
)
if
not
minetest
.
setting_getbool
(
"creative_mode"
)
then
local
inv
=
puncher
:
get_inventory
()
if
inv
:
room_for_item
(
"main"
,
"boats:boat"
)
then
inv
:
add_item
(
"main"
,
"boats:boat"
)
else
minetest
.
add_item
(
self
.
object
:
getpos
(),
"boats:boat"
)
end
end
end
end
function
boat
.
on_step
(
self
,
dtime
)
self
.
v
=
get_v
(
self
.
object
:
getvelocity
())
*
get_sign
(
self
.
v
)
if
self
.
driver
then
local
ctrl
=
self
.
driver
:
get_player_control
()
local
yaw
=
self
.
object
:
getyaw
()
if
ctrl
.
up
then
self
.
v
=
self
.
v
+
0
.
1
elseif
ctrl
.
down
then
self
.
v
=
self
.
v
-
0
.
1
end
if
ctrl
.
left
then
if
self
.
v
<
0
then
self
.
object
:
setyaw
(
yaw
-
(
1
+
dtime
)
*
0
.
03
)
else
self
.
object
:
setyaw
(
yaw
+
(
1
+
dtime
)
*
0
.
03
)
end
elseif
ctrl
.
right
then
if
self
.
v
<
0
then
self
.
object
:
setyaw
(
yaw
+
(
1
+
dtime
)
*
0
.
03
)
else
self
.
object
:
setyaw
(
yaw
-
(
1
+
dtime
)
*
0
.
03
)
end
end
end
local
velo
=
self
.
object
:
getvelocity
()
if
self
.
v
==
0
and
velo
.
x
==
0
and
velo
.
y
==
0
and
velo
.
z
==
0
then
self
.
object
:
setpos
(
self
.
object
:
getpos
())
return
end
local
s
=
get_sign
(
self
.
v
)
self
.
v
=
self
.
v
-
0
.
02
*
s
if
s
~=
get_sign
(
self
.
v
)
then
self
.
object
:
setvelocity
({
x
=
0
,
y
=
0
,
z
=
0
})
self
.
v
=
0
return
end
if
math.abs
(
self
.
v
)
>
5
then
self
.
v
=
5
*
get_sign
(
self
.
v
)
end
local
p
=
self
.
object
:
getpos
()
p
.
y
=
p
.
y
-
0
.
5
local
new_velo
local
new_acce
=
{
x
=
0
,
y
=
0
,
z
=
0
}
if
not
is_water
(
p
)
then
local
nodedef
=
minetest
.
registered_nodes
[
minetest
.
get_node
(
p
).
name
]
if
(
not
nodedef
)
or
nodedef
.
walkable
then
self
.
v
=
0
new_acce
=
{
x
=
0
,
y
=
1
,
z
=
0
}
else
new_acce
=
{
x
=
0
,
y
=
-
9
.
8
,
z
=
0
}
end
new_velo
=
get_velocity
(
self
.
v
,
self
.
object
:
getyaw
(),
self
.
object
:
getvelocity
().
y
)
self
.
object
:
setpos
(
self
.
object
:
getpos
())
else
p
.
y
=
p
.
y
+
1
if
is_water
(
p
)
then
local
y
=
self
.
object
:
getvelocity
().
y
if
y
>=
5
then
y
=
5
elseif
y
<
0
then
new_acce
=
{
x
=
0
,
y
=
20
,
z
=
0
}
else
new_acce
=
{
x
=
0
,
y
=
5
,
z
=
0
}
end
new_velo
=
get_velocity
(
self
.
v
,
self
.
object
:
getyaw
(),
y
)
self
.
object
:
setpos
(
self
.
object
:
getpos
())
else
new_acce
=
{
x
=
0
,
y
=
0
,
z
=
0
}
if
math.abs
(
self
.
object
:
getvelocity
().
y
)
<
1
then
local
pos
=
self
.
object
:
getpos
()
pos
.
y
=
math.floor
(
pos
.
y
)
+
0
.
5
self
.
object
:
setpos
(
pos
)
new_velo
=
get_velocity
(
self
.
v
,
self
.
object
:
getyaw
(),
0
)
else
new_velo
=
get_velocity
(
self
.
v
,
self
.
object
:
getyaw
(),
self
.
object
:
getvelocity
().
y
)
self
.
object
:
setpos
(
self
.
object
:
getpos
())
end
end
end
self
.
object
:
setvelocity
(
new_velo
)
self
.
object
:
setacceleration
(
new_acce
)
end
minetest
.
register_entity
(
"boats:boat"
,
boat
)
minetest
.
register_craftitem
(
"boats:boat"
,
{
description
=
"Boat"
,
inventory_image
=
"boats_inventory.png"
,
wield_image
=
"boats_wield.png"
,
wield_scale
=
{
x
=
2
,
y
=
2
,
z
=
1
},
liquids_pointable
=
true
,
on_place
=
function
(
itemstack
,
placer
,
pointed_thing
)
if
pointed_thing
.
type
~=
"node"
then
return
itemstack
end
if
not
is_water
(
pointed_thing
.
under
)
then
return
itemstack
end
pointed_thing
.
under
.
y
=
pointed_thing
.
under
.
y
+
0
.
5
minetest
.
add_entity
(
pointed_thing
.
under
,
"boats:boat"
)
if
not
minetest
.
setting_getbool
(
"creative_mode"
)
then
itemstack
:
take_item
()
end
return
itemstack
end
,
})
minetest
.
register_craft
({
output
=
"boats:boat"
,
recipe
=
{
{
""
,
""
,
""
},
{
"group:wood"
,
""
,
"group:wood"
},
{
"group:wood"
,
"group:wood"
,
"group:wood"
},
},
})
This diff is collapsed.
Click to expand it.
farming
@
f93811a8
Subproject commit f93811a8ab8345e453b962620d997c736b02a8ff
This diff is collapsed.
Click to expand it.
mods/farming/api.lua
deleted
100644 → 0
+
0
−
364
View file @
23544869
-- Wear out hoes, place soil
-- TODO Ignore group:flower
farming
.
hoe_on_use
=
function
(
itemstack
,
user
,
pointed_thing
,
uses
)
local
pt
=
pointed_thing
-- check if pointing at a node
if
not
pt
then
return
end
if
pt
.
type
~=
"node"
then
return
end
local
under
=
minetest
.
get_node
(
pt
.
under
)
local
p
=
{
x
=
pt
.
under
.
x
,
y
=
pt
.
under
.
y
+
1
,
z
=
pt
.
under
.
z
}
local
above
=
minetest
.
get_node
(
p
)
-- return if any of the nodes is not registered
if
not
minetest
.
registered_nodes
[
under
.
name
]
then
return
end
if
not
minetest
.
registered_nodes
[
above
.
name
]
then
return
end
-- check if the node above the pointed thing is air
if
above
.
name
~=
"air"
then
return
end
-- check if pointing at soil
if
minetest
.
get_item_group
(
under
.
name
,
"soil"
)
~=
1
then
return
end
-- check if (wet) soil defined
local
regN
=
minetest
.
registered_nodes
if
regN
[
under
.
name
].
soil
==
nil
or
regN
[
under
.
name
].
soil
.
wet
==
nil
or
regN
[
under
.
name
].
soil
.
dry
==
nil
then
return
end
if
minetest
.
is_protected
(
pt
.
under
,
user
:
get_player_name
())
then
minetest
.
record_protection_violation
(
pt
.
under
,
user
:
get_player_name
())
return
end
if
minetest
.
is_protected
(
pt
.
above
,
user
:
get_player_name
())
then
minetest
.
record_protection_violation
(
pt
.
above
,
user
:
get_player_name
())
return
end
-- turn the node into soil, wear out item and play sound
minetest
.
set_node
(
pt
.
under
,
{
name
=
regN
[
under
.
name
].
soil
.
dry
})
minetest
.
sound_play
(
"default_dig_crumbly"
,
{
pos
=
pt
.
under
,
gain
=
0
.
5
,
})
if
not
minetest
.
setting_getbool
(
"creative_mode"
)
then
itemstack
:
add_wear
(
65535
/
(
uses
-
1
))
end
return
itemstack
end
-- Register new hoes
farming
.
register_hoe
=
function
(
name
,
def
)
-- Check for : prefix (register new hoes in your mod's namespace)
if
name
:
sub
(
1
,
1
)
~=
":"
then
name
=
":"
..
name
end
-- Check def table
if
def
.
description
==
nil
then
def
.
description
=
"Hoe"
end
if
def
.
inventory_image
==
nil
then
def
.
inventory_image
=
"unknown_item.png"
end
if
def
.
recipe
==
nil
then
def
.
recipe
=
{
{
"air"
,
"air"
,
""
},
{
""
,
"group:stick"
,
""
},
{
""
,
"group:stick"
,
""
}
}
end
if
def
.
max_uses
==
nil
then
def
.
max_uses
=
30
end
-- Register the tool
minetest
.
register_tool
(
name
,
{
description
=
def
.
description
,
inventory_image
=
def
.
inventory_image
,
on_use
=
function
(
itemstack
,
user
,
pointed_thing
)
return
farming
.
hoe_on_use
(
itemstack
,
user
,
pointed_thing
,
def
.
max_uses
)
end
})
-- Register its recipe
if
def
.
material
==
nil
then
minetest
.
register_craft
({
output
=
name
:
sub
(
2
),
recipe
=
def
.
recipe
})
else
minetest
.
register_craft
({
output
=
name
:
sub
(
2
),
recipe
=
{
{
def
.
material
,
def
.
material
,
""
},
{
""
,
"group:stick"
,
""
},
{
""
,
"group:stick"
,
""
}
}
})
-- Reverse Recipe
minetest
.
register_craft
({
output
=
name
:
sub
(
2
),
recipe
=
{
{
""
,
def
.
material
,
def
.
material
},
{
""
,
"group:stick"
,
""
},
{
""
,
"group:stick"
,
""
}
}
})
end
end
-- how often node timers for plants will tick, +/- some random value
local
function
tick
(
pos
)
minetest
.
get_node_timer
(
pos
):
start
(
math.random
(
166
,
286
))
end
-- how often a growth failure tick is retried (e.g. too dark)
local
function
tick_again
(
pos
)
minetest
.
get_node_timer
(
pos
):
start
(
math.random
(
40
,
80
))
end
-- Seed placement
farming
.
place_seed
=
function
(
itemstack
,
placer
,
pointed_thing
,
plantname
)
local
pt
=
pointed_thing
-- check if pointing at a node
if
not
pt
then
return
itemstack
end
if
pt
.
type
~=
"node"
then
return
itemstack
end
local
under
=
minetest
.
get_node
(
pt
.
under
)
local
above
=
minetest
.
get_node
(
pt
.
above
)
if
minetest
.
is_protected
(
pt
.
under
,
placer
:
get_player_name
())
then
minetest
.
record_protection_violation
(
pt
.
under
,
placer
:
get_player_name
())
return
end
if
minetest
.
is_protected
(
pt
.
above
,
placer
:
get_player_name
())
then
minetest
.
record_protection_violation
(
pt
.
above
,
placer
:
get_player_name
())
return
end
-- return if any of the nodes is not registered
if
not
minetest
.
registered_nodes
[
under
.
name
]
then
return
itemstack
end
if
not
minetest
.
registered_nodes
[
above
.
name
]
then
return
itemstack
end
-- check if pointing at the top of the node
if
pt
.
above
.
y
~=
pt
.
under
.
y
+
1
then
return
itemstack
end
-- check if you can replace the node above the pointed node
if
not
minetest
.
registered_nodes
[
above
.
name
].
buildable_to
then
return
itemstack
end
-- check if pointing at soil
if
minetest
.
get_item_group
(
under
.
name
,
"soil"
)
<
2
then
return
itemstack
end
-- add the node and remove 1 item from the itemstack
minetest
.
add_node
(
pt
.
above
,
{
name
=
plantname
,
param2
=
1
})
tick
(
pt
.
above
)
if
not
minetest
.
setting_getbool
(
"creative_mode"
)
then
itemstack
:
take_item
()
end
return
itemstack
end
farming
.
grow_plant
=
function
(
pos
,
elapsed
)
local
node
=
minetest
.
get_node
(
pos
)
local
name
=
node
.
name
local
def
=
minetest
.
registered_nodes
[
name
]
if
not
def
.
next_plant
then
-- disable timer for fully grown plant
return
end
-- grow seed
if
minetest
.
get_item_group
(
node
.
name
,
"seed"
)
and
def
.
fertility
then
local
soil_node
=
minetest
.
get_node_or_nil
({
x
=
pos
.
x
,
y
=
pos
.
y
-
1
,
z
=
pos
.
z
})
if
not
soil_node
then
tick_again
(
pos
)
return
end
-- omitted is a check for light, we assume seeds can germinate in the dark.
for
_
,
v
in
pairs
(
def
.
fertility
)
do
if
minetest
.
get_item_group
(
soil_node
.
name
,
v
)
~=
0
then
minetest
.
swap_node
(
pos
,
{
name
=
def
.
next_plant
})
if
minetest
.
registered_nodes
[
def
.
next_plant
].
next_plant
then
tick
(
pos
)
return
end
end
end
return
end
-- check if on wet soil
local
below
=
minetest
.
get_node
({
x
=
pos
.
x
,
y
=
pos
.
y
-
1
,
z
=
pos
.
z
})
if
minetest
.
get_item_group
(
below
.
name
,
"soil"
)
<
3
then
tick_again
(
pos
)
return
end
-- check light
local
light
=
minetest
.
get_node_light
(
pos
)
if
not
light
or
light
<
def
.
minlight
or
light
>
def
.
maxlight
then
tick_again
(
pos
)
return
end
-- grow
minetest
.
swap_node
(
pos
,
{
name
=
def
.
next_plant
})
-- new timer needed?
if
minetest
.
registered_nodes
[
def
.
next_plant
].
next_plant
then
tick
(
pos
)
end
return
end
-- Register plants
farming
.
register_plant
=
function
(
name
,
def
)
local
mname
=
name
:
split
(
":"
)[
1
]
local
pname
=
name
:
split
(
":"
)[
2
]
-- Check def table
if
not
def
.
description
then
def
.
description
=
"Seed"
end
if
not
def
.
inventory_image
then
def
.
inventory_image
=
"unknown_item.png"
end
if
not
def
.
steps
then
return
nil
end
if
not
def
.
minlight
then
def
.
minlight
=
1
end
if
not
def
.
maxlight
then
def
.
maxlight
=
14
end
if
not
def
.
fertility
then
def
.
fertility
=
{}
end
-- Register seed
local
lbm_nodes
=
{
mname
..
":seed_"
..
pname
}
local
g
=
{
seed
=
1
,
snappy
=
3
,
attached_node
=
1
}
for
k
,
v
in
pairs
(
def
.
fertility
)
do
g
[
v
]
=
1
end
minetest
.
register_node
(
":"
..
mname
..
":seed_"
..
pname
,
{
description
=
def
.
description
,
tiles
=
{
def
.
inventory_image
},
inventory_image
=
def
.
inventory_image
,
wield_image
=
def
.
inventory_image
,
drawtype
=
"signlike"
,
groups
=
g
,
paramtype
=
"light"
,
paramtype2
=
"wallmounted"
,
walkable
=
false
,
sunlight_propagates
=
true
,
selection_box
=
{
type
=
"fixed"
,
fixed
=
{
-
0
.
5
,
-
0
.
5
,
-
0
.
5
,
0
.
5
,
-
5
/
16
,
0
.
5
},
},
fertility
=
def
.
fertility
,
sounds
=
default
.
node_sound_dirt_defaults
({
dug
=
{
name
=
"default_grass_footstep"
,
gain
=
0
.
2
},
place
=
{
name
=
"default_place_node"
,
gain
=
0
.
25
},
}),
on_place
=
function
(
itemstack
,
placer
,
pointed_thing
)
return
farming
.
place_seed
(
itemstack
,
placer
,
pointed_thing
,
mname
..
":seed_"
..
pname
)
end
,
next_plant
=
mname
..
":"
..
pname
..
"_1"
,
on_timer
=
farming
.
grow_plant
,
minlight
=
def
.
minlight
,
maxlight
=
def
.
maxlight
,
})
-- Register harvest
minetest
.
register_craftitem
(
":"
..
mname
..
":"
..
pname
,
{
description
=
pname
:
gsub
(
"^%l"
,
string.upper
),
inventory_image
=
mname
..
"_"
..
pname
..
".png"
,
})
-- Register growing steps
for
i
=
1
,
def
.
steps
do
local
drop
=
{
items
=
{
{
items
=
{
mname
..
":"
..
pname
},
rarity
=
9
-
i
},
{
items
=
{
mname
..
":"
..
pname
},
rarity
=
18
-
i
*
2
},
{
items
=
{
mname
..
":seed_"
..
pname
},
rarity
=
9
-
i
},
{
items
=
{
mname
..
":seed_"
..
pname
},
rarity
=
18
-
i
*
2
},
}
}
local
nodegroups
=
{
snappy
=
3
,
flammable
=
2
,
plant
=
1
,
not_in_creative_inventory
=
1
,
attached_node
=
1
}
nodegroups
[
pname
]
=
i
local
next_plant
=
nil
if
i
<
def
.
steps
then
next_plant
=
mname
..
":"
..
pname
..
"_"
..
(
i
+
1
)
lbm_nodes
[
#
lbm_nodes
+
1
]
=
mname
..
":"
..
pname
..
"_"
..
i
end
minetest
.
register_node
(
mname
..
":"
..
pname
..
"_"
..
i
,
{
drawtype
=
"plantlike"
,
waving
=
1
,
tiles
=
{
mname
..
"_"
..
pname
..
"_"
..
i
..
".png"
},
paramtype
=
"light"
,
walkable
=
false
,
buildable_to
=
true
,
drop
=
drop
,
selection_box
=
{
type
=
"fixed"
,
fixed
=
{
-
0
.
5
,
-
0
.
5
,
-
0
.
5
,
0
.
5
,
-
5
/
16
,
0
.
5
},
},
groups
=
nodegroups
,
sounds
=
default
.
node_sound_leaves_defaults
(),
next_plant
=
next_plant
,
on_timer
=
farming
.
grow_plant
,
minlight
=
def
.
minlight
,
maxlight
=
def
.
maxlight
,
})
end
-- replacement LBM for pre-nodetimer plants
minetest
.
register_lbm
({
name
=
":"
..
mname
..
":start_nodetimer_"
..
pname
,
nodenames
=
lbm_nodes
,
action
=
function
(
pos
,
node
)
tick_again
(
pos
)
end
,
})
-- Return
local
r
=
{
seed
=
mname
..
":seed_"
..
pname
,
harvest
=
mname
..
":"
..
pname
}
return
r
end
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment