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
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
Illuna-Minetest
minetest_game
Commits
81f8c8ae
Commit
81f8c8ae
authored
8 years ago
by
SmallJoker
Committed by
paramat
8 years ago
Browse files
Options
Downloads
Patches
Plain Diff
Carts: Move entity definition to seperate file
parent
9bbe7f99
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
mods/carts/cart_entity.lua
+384
-0
384 additions, 0 deletions
mods/carts/cart_entity.lua
mods/carts/init.lua
+1
-384
1 addition, 384 deletions
mods/carts/init.lua
with
385 additions
and
384 deletions
mods/carts/cart_entity.lua
0 → 100644
+
384
−
0
View file @
81f8c8ae
local
cart_entity
=
{
physical
=
false
,
-- otherwise going uphill breaks
collisionbox
=
{
-
0
.
5
,
-
0
.
5
,
-
0
.
5
,
0
.
5
,
0
.
5
,
0
.
5
},
visual
=
"mesh"
,
mesh
=
"carts_cart.b3d"
,
visual_size
=
{
x
=
1
,
y
=
1
},
textures
=
{
"carts_cart.png"
},
driver
=
nil
,
punched
=
false
,
-- used to re-send velocity and position
velocity
=
{
x
=
0
,
y
=
0
,
z
=
0
},
-- only used on punch
old_dir
=
{
x
=
1
,
y
=
0
,
z
=
0
},
-- random value to start the cart on punch
old_pos
=
nil
,
old_switch
=
0
,
railtype
=
nil
,
attached_items
=
{}
}
function
cart_entity
:
on_rightclick
(
clicker
)
if
not
clicker
or
not
clicker
:
is_player
()
then
return
end
local
player_name
=
clicker
:
get_player_name
()
if
self
.
driver
and
player_name
==
self
.
driver
then
self
.
driver
=
nil
carts
:
manage_attachment
(
clicker
,
nil
)
elseif
not
self
.
driver
then
self
.
driver
=
player_name
carts
:
manage_attachment
(
clicker
,
self
.
object
)
end
end
function
cart_entity
:
on_activate
(
staticdata
,
dtime_s
)
self
.
object
:
set_armor_groups
({
immortal
=
1
})
if
string.sub
(
staticdata
,
1
,
string.len
(
"return"
))
~=
"return"
then
return
end
local
data
=
minetest
.
deserialize
(
staticdata
)
if
not
data
or
type
(
data
)
~=
"table"
then
return
end
self
.
railtype
=
data
.
railtype
if
data
.
old_dir
then
self
.
old_dir
=
data
.
old_dir
end
if
data
.
old_vel
then
self
.
old_vel
=
data
.
old_vel
end
end
function
cart_entity
:
get_staticdata
()
return
minetest
.
serialize
({
railtype
=
self
.
railtype
,
old_dir
=
self
.
old_dir
,
old_vel
=
self
.
old_vel
})
end
function
cart_entity
:
on_punch
(
puncher
,
time_from_last_punch
,
tool_capabilities
,
direction
)
local
pos
=
self
.
object
:
getpos
()
if
not
self
.
railtype
then
local
node
=
minetest
.
get_node
(
pos
).
name
self
.
railtype
=
minetest
.
get_item_group
(
node
,
"connect_to_raillike"
)
end
if
not
puncher
or
not
puncher
:
is_player
()
then
local
cart_dir
=
carts
:
get_rail_direction
(
pos
,
self
.
old_dir
,
nil
,
nil
,
self
.
railtype
)
if
vector
.
equals
(
cart_dir
,
{
x
=
0
,
y
=
0
,
z
=
0
})
then
return
end
self
.
velocity
=
vector
.
multiply
(
cart_dir
,
3
)
self
.
punched
=
true
return
end
if
puncher
:
get_player_control
().
sneak
then
if
self
.
sound_handle
then
minetest
.
sound_stop
(
self
.
sound_handle
)
end
-- Pick up cart: Drop all attachments
if
self
.
driver
then
if
self
.
old_pos
then
self
.
object
:
setpos
(
self
.
old_pos
)
end
local
player
=
minetest
.
get_player_by_name
(
self
.
driver
)
carts
:
manage_attachment
(
player
,
nil
)
end
for
_
,
obj_
in
ipairs
(
self
.
attached_items
)
do
if
obj_
then
obj_
:
set_detach
()
end
end
local
leftover
=
puncher
:
get_inventory
():
add_item
(
"main"
,
"carts:cart"
)
if
not
leftover
:
is_empty
()
then
minetest
.
add_item
(
self
.
object
:
getpos
(),
leftover
)
end
self
.
object
:
remove
()
return
end
local
vel
=
self
.
object
:
getvelocity
()
if
puncher
:
get_player_name
()
==
self
.
driver
then
if
math.abs
(
vel
.
x
+
vel
.
z
)
>
carts
.
punch_speed_max
then
return
end
end
local
punch_dir
=
carts
:
velocity_to_dir
(
puncher
:
get_look_dir
())
punch_dir
.
y
=
0
local
cart_dir
=
carts
:
get_rail_direction
(
pos
,
punch_dir
,
nil
,
nil
,
self
.
railtype
)
if
vector
.
equals
(
cart_dir
,
{
x
=
0
,
y
=
0
,
z
=
0
})
then
return
end
local
punch_interval
=
1
if
tool_capabilities
and
tool_capabilities
.
full_punch_interval
then
punch_interval
=
tool_capabilities
.
full_punch_interval
end
time_from_last_punch
=
math.min
(
time_from_last_punch
or
punch_interval
,
punch_interval
)
local
f
=
2
*
(
time_from_last_punch
/
punch_interval
)
self
.
velocity
=
vector
.
multiply
(
cart_dir
,
f
)
self
.
old_dir
=
cart_dir
self
.
punched
=
true
end
local
function
rail_on_step_event
(
handler
,
obj
,
dtime
)
if
handler
then
handler
(
obj
,
dtime
)
end
end
-- sound refresh interval = 1.0sec
local
function
rail_sound
(
self
,
dtime
)
if
not
self
.
sound_ttl
then
self
.
sound_ttl
=
1
.
0
return
elseif
self
.
sound_ttl
>
0
then
self
.
sound_ttl
=
self
.
sound_ttl
-
dtime
return
end
self
.
sound_ttl
=
1
.
0
if
self
.
sound_handle
then
local
handle
=
self
.
sound_handle
self
.
sound_handle
=
nil
minetest
.
after
(
0
.
2
,
minetest
.
sound_stop
,
handle
)
end
local
vel
=
self
.
object
:
getvelocity
()
local
speed
=
vector
.
length
(
vel
)
if
speed
>
0
then
self
.
sound_handle
=
minetest
.
sound_play
(
"carts_cart_moving"
,
{
object
=
self
.
object
,
gain
=
(
speed
/
carts
.
speed_max
)
/
2
,
loop
=
true
,
})
end
end
local
function
rail_on_step
(
self
,
dtime
)
local
pos
=
self
.
object
:
getpos
()
local
node
=
minetest
.
get_node
(
pos
)
local
railparams
=
carts
.
railparams
[
node
.
name
]
or
{}
local
vel
=
self
.
object
:
getvelocity
()
local
update
=
{}
if
self
.
punched
then
vel
=
vector
.
add
(
vel
,
self
.
velocity
)
self
.
object
:
setvelocity
(
vel
)
self
.
old_dir
.
y
=
0
elseif
vector
.
equals
(
vel
,
{
x
=
0
,
y
=
0
,
z
=
0
})
then
return
end
-- stop cart if velocity vector flips
if
self
.
old_vel
and
(((
self
.
old_vel
.
x
*
vel
.
x
)
<
0
)
or
((
self
.
old_vel
.
z
*
vel
.
z
)
<
0
))
and
(
self
.
old_vel
.
y
==
0
)
then
self
.
old_dir
=
{
x
=
0
,
y
=
0
,
z
=
0
}
self
.
old_vel
=
{
x
=
0
,
y
=
0
,
z
=
0
}
self
.
velocity
=
{
x
=
0
,
y
=
0
,
z
=
0
}
self
.
old_pos
=
pos
self
.
object
:
setvelocity
(
vector
.
new
())
self
.
object
:
setacceleration
(
vector
.
new
())
rail_on_step_event
(
railparams
.
on_step
,
self
,
dtime
)
return
end
self
.
old_vel
=
vector
.
new
(
vel
)
if
self
.
old_pos
and
not
self
.
punched
then
local
flo_pos
=
vector
.
round
(
pos
)
local
flo_old
=
vector
.
round
(
self
.
old_pos
)
if
vector
.
equals
(
flo_pos
,
flo_old
)
then
-- Do not check one node multiple times
rail_on_step_event
(
railparams
.
on_step
,
self
,
dtime
)
return
end
end
local
ctrl
,
player
-- Get player controls
if
self
.
driver
then
player
=
minetest
.
get_player_by_name
(
self
.
driver
)
if
player
then
ctrl
=
player
:
get_player_control
()
end
end
if
self
.
old_pos
then
-- Detection for "skipping" nodes
local
expected_pos
=
vector
.
add
(
self
.
old_pos
,
self
.
old_dir
)
local
found_path
=
carts
:
pathfinder
(
pos
,
expected_pos
,
self
.
old_dir
,
ctrl
,
self
.
old_switch
,
self
.
railtype
)
if
not
found_path
then
-- No rail found: reset back to the expected position
pos
=
vector
.
new
(
self
.
old_pos
)
update
.
pos
=
true
end
end
local
cart_dir
=
carts
:
velocity_to_dir
(
vel
)
-- dir: New moving direction of the cart
-- switch_keys: Currently pressed L/R key, used to ignore the key on the next rail node
local
dir
,
switch_keys
=
carts
:
get_rail_direction
(
pos
,
cart_dir
,
ctrl
,
self
.
old_switch
,
self
.
railtype
)
local
new_acc
=
{
x
=
0
,
y
=
0
,
z
=
0
}
if
vector
.
equals
(
dir
,
{
x
=
0
,
y
=
0
,
z
=
0
})
then
vel
=
{
x
=
0
,
y
=
0
,
z
=
0
}
pos
=
vector
.
round
(
pos
)
update
.
pos
=
true
update
.
vel
=
true
else
-- If the direction changed
if
dir
.
x
~=
0
and
self
.
old_dir
.
z
~=
0
then
vel
.
x
=
dir
.
x
*
math.abs
(
vel
.
z
)
vel
.
z
=
0
pos
.
z
=
math.floor
(
pos
.
z
+
0
.
5
)
update
.
pos
=
true
end
if
dir
.
z
~=
0
and
self
.
old_dir
.
x
~=
0
then
vel
.
z
=
dir
.
z
*
math.abs
(
vel
.
x
)
vel
.
x
=
0
pos
.
x
=
math.floor
(
pos
.
x
+
0
.
5
)
update
.
pos
=
true
end
-- Up, down?
if
dir
.
y
~=
self
.
old_dir
.
y
then
vel
.
y
=
dir
.
y
*
math.abs
(
vel
.
x
+
vel
.
z
)
pos
=
vector
.
round
(
pos
)
update
.
pos
=
true
end
-- Slow down or speed up..
local
acc
=
dir
.
y
*
-
4
.
0
-- no need to check for railparams == nil since we always make it exist.
local
speed_mod
=
railparams
.
acceleration
if
speed_mod
and
speed_mod
~=
0
then
-- Try to make it similar to the original carts mod
acc
=
acc
+
speed_mod
else
-- Handbrake
if
ctrl
and
ctrl
.
down
then
acc
=
acc
-
1
.
6
else
acc
=
acc
-
0
.
4
end
end
new_acc
=
vector
.
multiply
(
dir
,
acc
)
end
-- Limits
local
max_vel
=
carts
.
speed_max
for
_
,
v
in
ipairs
({
"x"
,
"y"
,
"z"
})
do
if
math.abs
(
vel
[
v
])
>
max_vel
then
vel
[
v
]
=
carts
:
get_sign
(
vel
[
v
])
*
max_vel
new_acc
[
v
]
=
0
update
.
vel
=
true
end
end
self
.
object
:
setacceleration
(
new_acc
)
self
.
old_pos
=
vector
.
new
(
pos
)
if
not
vector
.
equals
(
dir
,
{
x
=
0
,
y
=
0
,
z
=
0
})
then
self
.
old_dir
=
vector
.
new
(
dir
)
end
self
.
old_switch
=
switch_keys
if
self
.
punched
then
-- Collect dropped items
for
_
,
obj_
in
ipairs
(
minetest
.
get_objects_inside_radius
(
pos
,
1
))
do
if
not
obj_
:
is_player
()
and
obj_
:
get_luaentity
()
and
not
obj_
:
get_luaentity
().
physical_state
and
obj_
:
get_luaentity
().
name
==
"__builtin:item"
then
obj_
:
set_attach
(
self
.
object
,
""
,
{
x
=
0
,
y
=
0
,
z
=
0
},
{
x
=
0
,
y
=
0
,
z
=
0
})
self
.
attached_items
[
#
self
.
attached_items
+
1
]
=
obj_
end
end
self
.
punched
=
false
update
.
vel
=
true
end
if
not
(
update
.
vel
or
update
.
pos
)
then
rail_on_step_event
(
railparams
.
on_step
,
self
,
dtime
)
return
end
local
yaw
=
0
if
self
.
old_dir
.
x
<
0
then
yaw
=
0
.
5
elseif
self
.
old_dir
.
x
>
0
then
yaw
=
1
.
5
elseif
self
.
old_dir
.
z
<
0
then
yaw
=
1
end
self
.
object
:
setyaw
(
yaw
*
math.pi
)
local
anim
=
{
x
=
0
,
y
=
0
}
if
dir
.
y
==
-
1
then
anim
=
{
x
=
1
,
y
=
1
}
elseif
dir
.
y
==
1
then
anim
=
{
x
=
2
,
y
=
2
}
end
self
.
object
:
set_animation
(
anim
,
1
,
0
)
self
.
object
:
setvelocity
(
vel
)
if
update
.
pos
then
self
.
object
:
setpos
(
pos
)
end
-- call event handler
rail_on_step_event
(
railparams
.
on_step
,
self
,
dtime
)
end
function
cart_entity
:
on_step
(
dtime
)
rail_on_step
(
self
,
dtime
)
rail_sound
(
self
,
dtime
)
end
minetest
.
register_entity
(
"carts:cart"
,
cart_entity
)
minetest
.
register_craftitem
(
"carts:cart"
,
{
description
=
"Cart (Sneak+Click to pick up)"
,
inventory_image
=
minetest
.
inventorycube
(
"carts_cart_top.png"
,
"carts_cart_side.png"
,
"carts_cart_side.png"
),
wield_image
=
"carts_cart_side.png"
,
on_place
=
function
(
itemstack
,
placer
,
pointed_thing
)
if
not
pointed_thing
.
type
==
"node"
then
return
end
if
carts
:
is_rail
(
pointed_thing
.
under
)
then
minetest
.
add_entity
(
pointed_thing
.
under
,
"carts:cart"
)
elseif
carts
:
is_rail
(
pointed_thing
.
above
)
then
minetest
.
add_entity
(
pointed_thing
.
above
,
"carts:cart"
)
else
return
end
minetest
.
sound_play
({
name
=
"default_place_node_metal"
,
gain
=
0
.
5
},
{
pos
=
pointed_thing
.
above
})
if
not
minetest
.
setting_getbool
(
"creative_mode"
)
then
itemstack
:
take_item
()
end
return
itemstack
end
,
})
minetest
.
register_craft
({
output
=
"carts:cart"
,
recipe
=
{
{
"default:steel_ingot"
,
""
,
"default:steel_ingot"
},
{
"default:steel_ingot"
,
"default:steel_ingot"
,
"default:steel_ingot"
},
},
})
This diff is collapsed.
Click to expand it.
mods/carts/init.lua
+
1
−
384
View file @
81f8c8ae
...
...
@@ -17,387 +17,4 @@ if not default.player_attached then
default
.
player_attached
=
{}
end
local
cart_entity
=
{
physical
=
false
,
-- otherwise going uphill breaks
collisionbox
=
{
-
0
.
5
,
-
0
.
5
,
-
0
.
5
,
0
.
5
,
0
.
5
,
0
.
5
},
visual
=
"mesh"
,
mesh
=
"carts_cart.b3d"
,
visual_size
=
{
x
=
1
,
y
=
1
},
textures
=
{
"carts_cart.png"
},
driver
=
nil
,
punched
=
false
,
-- used to re-send velocity and position
velocity
=
{
x
=
0
,
y
=
0
,
z
=
0
},
-- only used on punch
old_dir
=
{
x
=
1
,
y
=
0
,
z
=
0
},
-- random value to start the cart on punch
old_pos
=
nil
,
old_switch
=
0
,
railtype
=
nil
,
attached_items
=
{}
}
function
cart_entity
:
on_rightclick
(
clicker
)
if
not
clicker
or
not
clicker
:
is_player
()
then
return
end
local
player_name
=
clicker
:
get_player_name
()
if
self
.
driver
and
player_name
==
self
.
driver
then
self
.
driver
=
nil
carts
:
manage_attachment
(
clicker
,
nil
)
elseif
not
self
.
driver
then
self
.
driver
=
player_name
carts
:
manage_attachment
(
clicker
,
self
.
object
)
end
end
function
cart_entity
:
on_activate
(
staticdata
,
dtime_s
)
self
.
object
:
set_armor_groups
({
immortal
=
1
})
if
string.sub
(
staticdata
,
1
,
string.len
(
"return"
))
~=
"return"
then
return
end
local
data
=
minetest
.
deserialize
(
staticdata
)
if
not
data
or
type
(
data
)
~=
"table"
then
return
end
self
.
railtype
=
data
.
railtype
if
data
.
old_dir
then
self
.
old_dir
=
data
.
old_dir
end
if
data
.
old_vel
then
self
.
old_vel
=
data
.
old_vel
end
end
function
cart_entity
:
get_staticdata
()
return
minetest
.
serialize
({
railtype
=
self
.
railtype
,
old_dir
=
self
.
old_dir
,
old_vel
=
self
.
old_vel
})
end
function
cart_entity
:
on_punch
(
puncher
,
time_from_last_punch
,
tool_capabilities
,
direction
)
local
pos
=
self
.
object
:
getpos
()
if
not
self
.
railtype
then
local
node
=
minetest
.
get_node
(
pos
).
name
self
.
railtype
=
minetest
.
get_item_group
(
node
,
"connect_to_raillike"
)
end
if
not
puncher
or
not
puncher
:
is_player
()
then
local
cart_dir
=
carts
:
get_rail_direction
(
pos
,
self
.
old_dir
,
nil
,
nil
,
self
.
railtype
)
if
vector
.
equals
(
cart_dir
,
{
x
=
0
,
y
=
0
,
z
=
0
})
then
return
end
self
.
velocity
=
vector
.
multiply
(
cart_dir
,
3
)
self
.
punched
=
true
return
end
if
puncher
:
get_player_control
().
sneak
then
if
self
.
sound_handle
then
minetest
.
sound_stop
(
self
.
sound_handle
)
end
-- Pick up cart: Drop all attachments
if
self
.
driver
then
if
self
.
old_pos
then
self
.
object
:
setpos
(
self
.
old_pos
)
end
local
player
=
minetest
.
get_player_by_name
(
self
.
driver
)
carts
:
manage_attachment
(
player
,
nil
)
end
for
_
,
obj_
in
ipairs
(
self
.
attached_items
)
do
if
obj_
then
obj_
:
set_detach
()
end
end
local
leftover
=
puncher
:
get_inventory
():
add_item
(
"main"
,
"carts:cart"
)
if
not
leftover
:
is_empty
()
then
minetest
.
add_item
(
self
.
object
:
getpos
(),
leftover
)
end
self
.
object
:
remove
()
return
end
local
vel
=
self
.
object
:
getvelocity
()
if
puncher
:
get_player_name
()
==
self
.
driver
then
if
math.abs
(
vel
.
x
+
vel
.
z
)
>
carts
.
punch_speed_max
then
return
end
end
local
punch_dir
=
carts
:
velocity_to_dir
(
puncher
:
get_look_dir
())
punch_dir
.
y
=
0
local
cart_dir
=
carts
:
get_rail_direction
(
pos
,
punch_dir
,
nil
,
nil
,
self
.
railtype
)
if
vector
.
equals
(
cart_dir
,
{
x
=
0
,
y
=
0
,
z
=
0
})
then
return
end
local
punch_interval
=
1
if
tool_capabilities
and
tool_capabilities
.
full_punch_interval
then
punch_interval
=
tool_capabilities
.
full_punch_interval
end
time_from_last_punch
=
math.min
(
time_from_last_punch
or
punch_interval
,
punch_interval
)
local
f
=
2
*
(
time_from_last_punch
/
punch_interval
)
self
.
velocity
=
vector
.
multiply
(
cart_dir
,
f
)
self
.
old_dir
=
cart_dir
self
.
punched
=
true
end
local
function
rail_on_step_event
(
handler
,
obj
,
dtime
)
if
handler
then
handler
(
obj
,
dtime
)
end
end
-- sound refresh interval = 1.0sec
local
function
rail_sound
(
self
,
dtime
)
if
not
self
.
sound_ttl
then
self
.
sound_ttl
=
1
.
0
return
elseif
self
.
sound_ttl
>
0
then
self
.
sound_ttl
=
self
.
sound_ttl
-
dtime
return
end
self
.
sound_ttl
=
1
.
0
if
self
.
sound_handle
then
local
handle
=
self
.
sound_handle
self
.
sound_handle
=
nil
minetest
.
after
(
0
.
2
,
minetest
.
sound_stop
,
handle
)
end
local
vel
=
self
.
object
:
getvelocity
()
local
speed
=
vector
.
length
(
vel
)
if
speed
>
0
then
self
.
sound_handle
=
minetest
.
sound_play
(
"carts_cart_moving"
,
{
object
=
self
.
object
,
gain
=
(
speed
/
carts
.
speed_max
)
/
2
,
loop
=
true
,
})
end
end
local
function
rail_on_step
(
self
,
dtime
)
local
pos
=
self
.
object
:
getpos
()
local
node
=
minetest
.
get_node
(
pos
)
local
railparams
=
carts
.
railparams
[
node
.
name
]
or
{}
local
vel
=
self
.
object
:
getvelocity
()
local
update
=
{}
if
self
.
punched
then
vel
=
vector
.
add
(
vel
,
self
.
velocity
)
self
.
object
:
setvelocity
(
vel
)
self
.
old_dir
.
y
=
0
elseif
vector
.
equals
(
vel
,
{
x
=
0
,
y
=
0
,
z
=
0
})
then
return
end
-- stop cart if velocity vector flips
if
self
.
old_vel
and
(((
self
.
old_vel
.
x
*
vel
.
x
)
<
0
)
or
((
self
.
old_vel
.
z
*
vel
.
z
)
<
0
))
and
(
self
.
old_vel
.
y
==
0
)
then
self
.
old_dir
=
{
x
=
0
,
y
=
0
,
z
=
0
}
self
.
old_vel
=
{
x
=
0
,
y
=
0
,
z
=
0
}
self
.
velocity
=
{
x
=
0
,
y
=
0
,
z
=
0
}
self
.
old_pos
=
pos
self
.
object
:
setvelocity
(
vector
.
new
())
self
.
object
:
setacceleration
(
vector
.
new
())
rail_on_step_event
(
railparams
.
on_step
,
self
,
dtime
)
return
end
self
.
old_vel
=
vector
.
new
(
vel
)
if
self
.
old_pos
and
not
self
.
punched
then
local
flo_pos
=
vector
.
round
(
pos
)
local
flo_old
=
vector
.
round
(
self
.
old_pos
)
if
vector
.
equals
(
flo_pos
,
flo_old
)
then
-- Do not check one node multiple times
rail_on_step_event
(
railparams
.
on_step
,
self
,
dtime
)
return
end
end
local
ctrl
,
player
-- Get player controls
if
self
.
driver
then
player
=
minetest
.
get_player_by_name
(
self
.
driver
)
if
player
then
ctrl
=
player
:
get_player_control
()
end
end
if
self
.
old_pos
then
-- Detection for "skipping" nodes
local
expected_pos
=
vector
.
add
(
self
.
old_pos
,
self
.
old_dir
)
local
found_path
=
carts
:
pathfinder
(
pos
,
expected_pos
,
self
.
old_dir
,
ctrl
,
self
.
old_switch
,
self
.
railtype
)
if
not
found_path
then
-- No rail found: reset back to the expected position
pos
=
vector
.
new
(
self
.
old_pos
)
update
.
pos
=
true
end
end
local
cart_dir
=
carts
:
velocity_to_dir
(
vel
)
-- dir: New moving direction of the cart
-- switch_keys: Currently pressed L/R key, used to ignore the key on the next rail node
local
dir
,
switch_keys
=
carts
:
get_rail_direction
(
pos
,
cart_dir
,
ctrl
,
self
.
old_switch
,
self
.
railtype
)
local
new_acc
=
{
x
=
0
,
y
=
0
,
z
=
0
}
if
vector
.
equals
(
dir
,
{
x
=
0
,
y
=
0
,
z
=
0
})
then
vel
=
{
x
=
0
,
y
=
0
,
z
=
0
}
pos
=
vector
.
round
(
pos
)
update
.
pos
=
true
update
.
vel
=
true
else
-- If the direction changed
if
dir
.
x
~=
0
and
self
.
old_dir
.
z
~=
0
then
vel
.
x
=
dir
.
x
*
math.abs
(
vel
.
z
)
vel
.
z
=
0
pos
.
z
=
math.floor
(
pos
.
z
+
0
.
5
)
update
.
pos
=
true
end
if
dir
.
z
~=
0
and
self
.
old_dir
.
x
~=
0
then
vel
.
z
=
dir
.
z
*
math.abs
(
vel
.
x
)
vel
.
x
=
0
pos
.
x
=
math.floor
(
pos
.
x
+
0
.
5
)
update
.
pos
=
true
end
-- Up, down?
if
dir
.
y
~=
self
.
old_dir
.
y
then
vel
.
y
=
dir
.
y
*
math.abs
(
vel
.
x
+
vel
.
z
)
pos
=
vector
.
round
(
pos
)
update
.
pos
=
true
end
-- Slow down or speed up..
local
acc
=
dir
.
y
*
-
4
.
0
-- no need to check for railparams == nil since we always make it exist.
local
speed_mod
=
railparams
.
acceleration
if
speed_mod
and
speed_mod
~=
0
then
-- Try to make it similar to the original carts mod
acc
=
acc
+
speed_mod
else
-- Handbrake
if
ctrl
and
ctrl
.
down
then
acc
=
acc
-
1
.
6
else
acc
=
acc
-
0
.
4
end
end
new_acc
=
vector
.
multiply
(
dir
,
acc
)
end
-- Limits
local
max_vel
=
carts
.
speed_max
for
_
,
v
in
ipairs
({
"x"
,
"y"
,
"z"
})
do
if
math.abs
(
vel
[
v
])
>
max_vel
then
vel
[
v
]
=
carts
:
get_sign
(
vel
[
v
])
*
max_vel
new_acc
[
v
]
=
0
update
.
vel
=
true
end
end
self
.
object
:
setacceleration
(
new_acc
)
self
.
old_pos
=
vector
.
new
(
pos
)
if
not
vector
.
equals
(
dir
,
{
x
=
0
,
y
=
0
,
z
=
0
})
then
self
.
old_dir
=
vector
.
new
(
dir
)
end
self
.
old_switch
=
switch_keys
if
self
.
punched
then
-- Collect dropped items
for
_
,
obj_
in
ipairs
(
minetest
.
get_objects_inside_radius
(
pos
,
1
))
do
if
not
obj_
:
is_player
()
and
obj_
:
get_luaentity
()
and
not
obj_
:
get_luaentity
().
physical_state
and
obj_
:
get_luaentity
().
name
==
"__builtin:item"
then
obj_
:
set_attach
(
self
.
object
,
""
,
{
x
=
0
,
y
=
0
,
z
=
0
},
{
x
=
0
,
y
=
0
,
z
=
0
})
self
.
attached_items
[
#
self
.
attached_items
+
1
]
=
obj_
end
end
self
.
punched
=
false
update
.
vel
=
true
end
if
not
(
update
.
vel
or
update
.
pos
)
then
rail_on_step_event
(
railparams
.
on_step
,
self
,
dtime
)
return
end
local
yaw
=
0
if
self
.
old_dir
.
x
<
0
then
yaw
=
0
.
5
elseif
self
.
old_dir
.
x
>
0
then
yaw
=
1
.
5
elseif
self
.
old_dir
.
z
<
0
then
yaw
=
1
end
self
.
object
:
setyaw
(
yaw
*
math.pi
)
local
anim
=
{
x
=
0
,
y
=
0
}
if
dir
.
y
==
-
1
then
anim
=
{
x
=
1
,
y
=
1
}
elseif
dir
.
y
==
1
then
anim
=
{
x
=
2
,
y
=
2
}
end
self
.
object
:
set_animation
(
anim
,
1
,
0
)
self
.
object
:
setvelocity
(
vel
)
if
update
.
pos
then
self
.
object
:
setpos
(
pos
)
end
-- call event handler
rail_on_step_event
(
railparams
.
on_step
,
self
,
dtime
)
end
function
cart_entity
:
on_step
(
dtime
)
rail_on_step
(
self
,
dtime
)
rail_sound
(
self
,
dtime
)
end
minetest
.
register_entity
(
"carts:cart"
,
cart_entity
)
minetest
.
register_craftitem
(
"carts:cart"
,
{
description
=
"Cart (Sneak+Click to pick up)"
,
inventory_image
=
minetest
.
inventorycube
(
"carts_cart_top.png"
,
"carts_cart_side.png"
,
"carts_cart_side.png"
),
wield_image
=
"carts_cart_side.png"
,
on_place
=
function
(
itemstack
,
placer
,
pointed_thing
)
if
not
pointed_thing
.
type
==
"node"
then
return
end
if
carts
:
is_rail
(
pointed_thing
.
under
)
then
minetest
.
add_entity
(
pointed_thing
.
under
,
"carts:cart"
)
elseif
carts
:
is_rail
(
pointed_thing
.
above
)
then
minetest
.
add_entity
(
pointed_thing
.
above
,
"carts:cart"
)
else
return
end
minetest
.
sound_play
({
name
=
"default_place_node_metal"
,
gain
=
0
.
5
},
{
pos
=
pointed_thing
.
above
})
if
not
minetest
.
setting_getbool
(
"creative_mode"
)
then
itemstack
:
take_item
()
end
return
itemstack
end
,
})
minetest
.
register_craft
({
output
=
"carts:cart"
,
recipe
=
{
{
"default:steel_ingot"
,
""
,
"default:steel_ingot"
},
{
"default:steel_ingot"
,
"default:steel_ingot"
,
"default:steel_ingot"
},
},
})
dofile
(
carts
.
modpath
..
"/cart_entity.lua"
)
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