Skip to content
Permalink
Browse files

Carts: Merge boost_cart as "carts" mod

This is all the working code from SmallJoker's boost_cart, poored into
a more suitable form for minetest_game.

- Mesecons and moreores stuff was removed entirely.
- Textures were all renamed and moved out of default/
- Updated license, readme.txt, attribution
- Changed code license to MIT, left artwork at CC0
- removed default:rail and made aliases for it
- :carts:rail is now carts:rail.
- localized entity def
- removed copper rail entirely
- startstop rail was removed, as well as detector rail
- remodeled to b3d using stujones11 excellent blend model, but sizes
  of cart adjusted to make pixel sizes consistent (0.625) everywhere.
- slightly more complex texture map for the cart (front/side visibly
  different)
- rail parameters are passed as a separate def table, and stored in
  a private list. This avoids having to call `get_meta` on every
  node. In return, we need the node name, though.
- adds metal sounds (based on default metal sound function) and
  cart moving sound.
- reduced cart speeds to max 7, 5 by pushing.
- Added on_step() rail event handler, gets called when a cart is on
  a rail.
- Added various rebased updates from upstream (thanks Krock)
- Included a fix that removes the 'reverse jiggle' when stopping.
- Included reworked textures by sofar.

The mod namespace is still public, but I'm NOT declaring it an API. I'd
rather see it localized instead, for now. Any public interface in this
code is *experimental* at best, and should be considered non-stable and
unsupported for now.
  • Loading branch information
sofar authored and paramat committed Oct 8, 2016
1 parent 75caa91 commit 1e691c442907d6bb5602bc34fdbb3c9a7436c223
Showing with 780 additions and 33 deletions.
  1. +22 −0 game_api.txt
  2. +20 −0 mods/carts/README.txt
  3. +1 −0 mods/carts/depends.txt
  4. +221 −0 mods/carts/functions.lua
  5. +403 −0 mods/carts/init.lua
  6. +54 −0 mods/carts/license.txt
  7. BIN mods/carts/models/carts_cart.b3d
  8. BIN mods/carts/models/carts_cart.blend
  9. +58 −0 mods/carts/rails.lua
  10. BIN mods/carts/sounds/carts_cart_moving.1.ogg
  11. BIN mods/carts/sounds/carts_cart_moving.2.ogg
  12. BIN mods/carts/sounds/carts_cart_moving.3.ogg
  13. BIN mods/carts/textures/carts_cart.png
  14. BIN mods/carts/textures/carts_cart_front.png
  15. BIN mods/carts/textures/carts_cart_side.png
  16. BIN mods/carts/textures/carts_cart_top.png
  17. BIN mods/carts/textures/carts_rail_crossing.png
  18. BIN mods/carts/textures/carts_rail_crossing_brk.png
  19. BIN mods/carts/textures/carts_rail_crossing_pwr.png
  20. BIN mods/carts/textures/carts_rail_curved.png
  21. BIN mods/carts/textures/carts_rail_curved_brk.png
  22. BIN mods/carts/textures/carts_rail_curved_pwr.png
  23. BIN mods/carts/textures/carts_rail_straight.png
  24. BIN mods/carts/textures/carts_rail_straight_brk.png
  25. BIN mods/carts/textures/carts_rail_straight_pwr.png
  26. BIN mods/carts/textures/carts_rail_t_junction.png
  27. BIN mods/carts/textures/carts_rail_t_junction_brk.png
  28. BIN mods/carts/textures/carts_rail_t_junction_pwr.png
  29. +1 −1 mods/default/aliases.lua
  30. +0 −9 mods/default/crafting.lua
  31. +0 −23 mods/default/nodes.lua
  32. BIN mods/default/textures/default_rail.png
  33. BIN mods/default/textures/default_rail_crossing.png
  34. BIN mods/default/textures/default_rail_curved.png
  35. BIN mods/default/textures/default_rail_t_junction.png
@@ -650,3 +650,25 @@ Trees

* `default.grow_new_snowy_pine_tree(pos)`
* Grows a new design snowy pine tree at pos

Carts
-----

carts.register_rail(
"mycarts:myrail", -- Rail name
nodedef, -- standard nodedef
railparams -- rail parameter struct (optional)
)

railparams = {
on_step(obj, dtime), -- Event handler called when
-- cart is on rail
acceleration, -- integer acceleration factor (negative
-- values to brake)
}

The event handler is called after all default calculations
are made, so the custom on_step handler can override things
like speed, acceleration, player attachment. The handler will
likely be called many times per second, so the function needs
to make sure that the event is handled properly.
@@ -0,0 +1,20 @@
Carts (formerly boost_cart)
==========================

Cleaned up for merge based almost entirely on SmallJoker's boost_cart
mod (github.com/smalljoker/boost_cart).

That in turn was based on (and fully compatible with) the mod "carts"
by PilzAdam

The model was redone, but based on github.com/stujones11/railcart, CC-0

Cart Textures are based on original work from PixelBOX (WTFPL).


Features
----------
- A fast cart for your railway or roller coaster (up to 7 m/s!)
- Boost and brake rails
- Rail junction switching with the 'right-left' walking keys
- Handbrake with the 'back' key
@@ -0,0 +1 @@
default
@@ -0,0 +1,221 @@
function carts:get_sign(z)
if z == 0 then
return 0
else
return z / math.abs(z)
end
end

function carts:manage_attachment(player, obj)
if not player then
return
end
local status = obj ~= nil
local player_name = player:get_player_name()
if default.player_attached[player_name] == status then
return
end
default.player_attached[player_name] = status

if status then
player:set_attach(obj, "", {x=0, y=6, z=0}, {x=0, y=0, z=0})
player:set_eye_offset({x=0, y=-4, z=0},{x=0, y=-4, z=0})
else
player:set_detach()
player:set_eye_offset({x=0, y=0, z=0},{x=0, y=0, z=0})
end
end

function carts:velocity_to_dir(v)
if math.abs(v.x) > math.abs(v.z) then
return {x=carts:get_sign(v.x), y=carts:get_sign(v.y), z=0}
else
return {x=0, y=carts:get_sign(v.y), z=carts:get_sign(v.z)}
end
end

function carts:is_rail(pos, railtype)
local node = minetest.get_node(pos).name
if node == "ignore" then
local vm = minetest.get_voxel_manip()
local emin, emax = vm:read_from_map(pos, pos)
local area = VoxelArea:new{
MinEdge = emin,
MaxEdge = emax,
}
local data = vm:get_data()
local vi = area:indexp(pos)
node = minetest.get_name_from_content_id(data[vi])
end
if minetest.get_item_group(node, "rail") == 0 then
return false
end
if not railtype then
return true
end
return minetest.get_item_group(node, "connect_to_raillike") == railtype
end

function carts:check_front_up_down(pos, dir_, check_up, railtype)
local dir = vector.new(dir_)
local cur

-- Front
dir.y = 0
cur = vector.add(pos, dir)
if carts:is_rail(cur, railtype) then
return dir
end
-- Up
if check_up then
dir.y = 1
cur = vector.add(pos, dir)
if carts:is_rail(cur, railtype) then
return dir
end
end
-- Down
dir.y = -1
cur = vector.add(pos, dir)
if carts:is_rail(cur, railtype) then
return dir
end
return nil
end

function carts:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
local pos = vector.round(pos_)
local cur
local left_check, right_check = true, true

-- Check left and right
local left = {x=0, y=0, z=0}
local right = {x=0, y=0, z=0}
if dir.z ~= 0 and dir.x == 0 then
left.x = -dir.z
right.x = dir.z
elseif dir.x ~= 0 and dir.z == 0 then
left.z = dir.x
right.z = -dir.x
end

if ctrl then
if old_switch == 1 then
left_check = false
elseif old_switch == 2 then
right_check = false
end
if ctrl.left and left_check then
cur = carts:check_front_up_down(pos, left, false, railtype)
if cur then
return cur, 1
end
left_check = false
end
if ctrl.right and right_check then
cur = carts:check_front_up_down(pos, right, false, railtype)
if cur then
return cur, 2
end
right_check = true
end
end

-- Normal
cur = carts:check_front_up_down(pos, dir, true, railtype)
if cur then
return cur
end

-- Left, if not already checked
if left_check then
cur = carts:check_front_up_down(pos, left, false, railtype)
if cur then
return cur
end
end

-- Right, if not already checked
if right_check then
cur = carts:check_front_up_down(pos, right, false, railtype)
if cur then
return cur
end
end

-- Backwards
if not old_switch then
cur = carts:check_front_up_down(pos, {
x = -dir.x,
y = dir.y,
z = -dir.z
}, true, railtype)
if cur then
return cur
end
end

return {x=0, y=0, z=0}
end

function carts:pathfinder(pos_, expected_pos, old_dir, ctrl, pf_switch, railtype)
local pos = vector.round(pos_)
local pf_pos = vector.round(expected_pos)
local pf_dir = vector.new(old_dir)

for i = 1, 3 do
if vector.equals(pf_pos, pos) then
-- Success! Cart moved on correctly
return true
end

pf_dir, pf_switch = carts:get_rail_direction(pf_pos, pf_dir, ctrl, pf_switch, railtype)
if vector.equals(pf_dir, {x=0, y=0, z=0}) then
-- No way forwards
return false
end

pf_pos = vector.add(pf_pos, pf_dir)
end
-- Cart not found
return false
end

function carts:register_rail(name, def, railparams)
local def_default = {
drawtype = "raillike",
paramtype = "light",
sunlight_propagates = true,
is_ground_content = true,
walkable = false,
selection_box = {
type = "fixed",
fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
},
sounds = default.node_sound_metal_defaults()
}
for k, v in pairs(def_default) do
def[k] = v
end
if not def.inventory_image then
def.wield_image = def.tiles[1]
def.inventory_image = def.tiles[1]
end

if railparams then
carts.railparams[name] = table.copy(railparams)
end

minetest.register_node(name, def)
end

function carts:get_rail_groups(additional_groups)
-- Get the default rail groups and add more when a table is given
local groups = {dig_immediate = 2, attached_node = 1, rail = 1, connect_to_raillike = 1}
if type(additional_groups) == "table" then
for k, v in pairs(additional_groups) do
groups[k] = v
end
end
return groups
end

0 comments on commit 1e691c4

Please sign in to comment.
You can’t perform that action at this time.