Merge default

Thanks, friend :)
This commit is contained in:
Maksim Gamarnik 2016-03-04 19:40:20 +02:00
parent 7b524269e3
commit a7bf6b60b3
110 changed files with 1450 additions and 1346 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 295 B

After

Width:  |  Height:  |  Size: 294 B

View File

@ -1,24 +0,0 @@
Minetest mod: boost_cart
=======================
Based on (and fully compatible with) the mod "carts" by PilzAdam
Target: Run smoothly and do not use too much CPU.
Edited by TenPlus1 to drop cart when no-one inside
License of source code:
-----------------------
WTFPL
License of media (textures, sounds and models):
-----------------------------------------------
CC-0
Authors of media files:
-----------------------
kddekadenz:
cart_bottom.png
cart_side.png
cart_top.png
Zeg9:
cart.x
cart.png

View File

@ -1,4 +0,0 @@
default
mesecons?
moreores?
mobs?

View File

@ -1,150 +0,0 @@
function boost_cart:get_sign(z)
if z == 0 then
return 0
else
return z / math.abs(z)
end
end
function boost_cart:velocity_to_dir(v)
if math.abs(v.x) > math.abs(v.z) then
return {x=boost_cart:get_sign(v.x), y=boost_cart:get_sign(v.y), z=0}
else
return {x=0, y=boost_cart:get_sign(v.y), z=boost_cart:get_sign(v.z)}
end
end
function boost_cart: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 boost_cart:check_front_up_down(pos, dir_, check_down, railtype)
local dir = vector.new(dir_)
local cur = nil
-- Front
dir.y = 0
cur = vector.add(pos, dir)
if boost_cart:is_rail(cur, railtype) then
return dir
end
-- Up
if check_down then
dir.y = 1
cur = vector.add(pos, dir)
if boost_cart:is_rail(cur, railtype) then
return dir
end
end
-- Down
dir.y = -1
cur = vector.add(pos, dir)
if boost_cart:is_rail(cur, railtype) then
return dir
end
return nil
end
function boost_cart:get_rail_direction(pos_, dir, ctrl, old_switch, railtype)
local pos = vector.round(pos_)
local cur = nil
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 = boost_cart: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 = boost_cart:check_front_up_down(pos, right, false, railtype)
if cur then
return cur, 2
end
right_check = true
end
end
-- Normal
cur = boost_cart:check_front_up_down(pos, dir, true, railtype)
if cur then
return cur
end
-- Left, if not already checked
if left_check then
cur = boost_cart: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 = boost_cart:check_front_up_down(pos, right, false, railtype)
if cur then
return cur
end
end
-- Backwards
if not old_switch then
cur = boost_cart: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 boost_cart:boost_rail(pos, amount)
minetest.get_meta(pos):set_string("cart_acceleration", tostring(amount))
for _,obj_ in ipairs(minetest.get_objects_inside_radius(pos, 0.5)) do
if not obj_:is_player()
and obj_:get_luaentity()
and obj_:get_luaentity().name == "carts:cart" then
obj_:get_luaentity():on_punch()
end
end
end

View File

@ -1,380 +0,0 @@
boost_cart = {}
boost_cart.modpath = minetest.get_modpath("boost_cart")
boost_cart.speed_max = 10
function vector.floor(v)
return {
x = math.floor(v.x),
y = math.floor(v.y),
z = math.floor(v.z)
}
end
dofile(boost_cart.modpath.."/functions.lua")
dofile(boost_cart.modpath.."/rails.lua")
-- Support for non-default games
if not default.player_attached then
default.player_attached = {}
end
boost_cart.cart = {
physical = false,
collisionbox = {-0.5, -0.5, -0.5, 0.5, 0.5, 0.5},
visual = "mesh",
mesh = "cart.x",
visual_size = {x=1, y=1},
textures = {"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=0, y=0, z=0},
old_pos = nil,
old_switch = 0,
railtype = nil,
attached_items = {},
}
local function get_v(v)
return math.sqrt(v.x ^ 2 + v.z ^ 2)
end
function boost_cart.cart: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
clicker:set_detach()
elseif not self.driver then
self.driver = player_name
default.player_attached[player_name] = true
clicker:set_attach(self.object, "", {x=0, y=3, z=0}, {x=0, y=0, z=0})
end
end
function boost_cart.cart:on_activate(staticdata, dtime_s)
if mobs and mobs.entity and mobs.entity == false then
self.object:remove()
return
end
self.object:set_armor_groups({immortal=1})
self.driver = nil
self.count = 0
self.snd = 0
self.handle = nil
end
function boost_cart.cart: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(vector.floor(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 = boost_cart:get_rail_direction(pos, {x=1, y=0, z=0}, 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.old_pos = nil
self.punched = true
return
end
if puncher:get_player_control().sneak then
if self.driver then
if self.old_pos then
self.object:setpos(self.old_pos)
end
if self.handle then
minetest.sound_stop(self.handle)
self.handle = nil
self.snd = 0
end
default.player_attached[self.driver] = nil
local player = minetest.get_player_by_name(self.driver)
if player then
player:set_detach()
end
end
for _,obj_ in ipairs(self.attached_items) do
if obj_ then
obj_:set_detach()
end
end
local inv = puncher:get_inventory()
if inv:room_for_item("main", "carts:cart") then
inv:add_item("main", "carts:cart")
else
minetest.add_item(self.object:getpos(), "carts:cart")
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) > 7 then
return
end
end
local punch_dir = boost_cart:velocity_to_dir(puncher:get_look_dir())
punch_dir.y = 0
local cart_dir = boost_cart:get_rail_direction(pos, punch_dir, nil, nil, self.railtype)
if vector.equals(cart_dir, {x=0, y=0, z=0}) then
return
end
time_from_last_punch = math.min(time_from_last_punch, tool_capabilities.full_punch_interval)
local f = 3 * (time_from_last_punch / tool_capabilities.full_punch_interval)
self.velocity = vector.multiply(cart_dir, f)
self.old_pos = nil
self.punched = true
end
function boost_cart.cart:on_step(dtime)
self.count = self.count + dtime
-- no driver inside
if self.count > 10 and not self.driver then
minetest.add_item(self.object:getpos(), "carts:cart")
self.object:remove()
return
-- driver inside
elseif self.driver then
self.count = 0
-- items inside
elseif #self.attached_items > 0 then
self.count = 0
end
local vel = self.object:getvelocity()
local vv = get_v(vel) ; --print ("vel", vv, self.driver)
if vv > 1 and self.driver and self.snd == 0 then
self.handle = minetest.sound_play("cart_ride", {
-- to_player = self.player,
object = self.object,
gain = 1.0,
loop = true,
})
if self.handle then
self.snd = 1
end
end
if (vv < 1 or not self.driver) and self.snd == 1 then
if self.handle then
minetest.sound_stop(self.handle)
self.handle = nil
self.snd = 0
end
end
if self.punched then
vel = vector.add(vel, self.velocity)
self.object:setvelocity(vel)
elseif vector.equals(vel, {x=0, y=0, z=0}) then
return
end
local dir, last_switch = nil, nil
local pos = self.object:getpos()
if self.old_pos and not self.punched then
local flo_pos = vector.floor(pos)
local flo_old = vector.floor(self.old_pos)
if vector.equals(flo_pos, flo_old) then
return
end
end
local update = {}
local ctrl, player = nil, nil
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
local diff = vector.subtract(self.old_pos, pos)
for _,v in ipairs({"x","y","z"}) do
if math.abs(diff[v]) > 1.1 then
local expected_pos = vector.add(self.old_pos, self.old_dir)
dir, last_switch = boost_cart:get_rail_direction(pos, self.old_dir, ctrl, self.old_switch, self.railtype)
if vector.equals(dir, {x=0, y=0, z=0}) then
dir = false
pos = vector.new(expected_pos)
update.pos = true
end
break
end
end
end
if vel.y == 0 then
for _,v in ipairs({"x", "z"}) do
if vel[v] ~= 0 and math.abs(vel[v]) < 0.9 then
vel[v] = 0
update.vel = true
end
end
end
local cart_dir = boost_cart:velocity_to_dir(vel)
local max_vel = boost_cart.speed_max
if not dir then
dir, last_switch = boost_cart:get_rail_direction(pos, cart_dir, ctrl, self.old_switch, self.railtype)
end
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}
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 * -1.8
local speed_mod = tonumber(minetest.get_meta(pos):get_string("cart_acceleration"))
if speed_mod and speed_mod ~= 0 then
if speed_mod > 0 then
for _,v in ipairs({"x","y","z"}) do
if math.abs(vel[v]) >= max_vel then
speed_mod = 0
break
end
end
end
acc = acc + (speed_mod * 8)
else
acc = acc - 0.4
-- Handbrake
if ctrl and ctrl.down and math.abs(vel.x + vel.z) > 1.2 then
acc = acc - 1.2
end
end
new_acc = vector.multiply(dir, acc)
end
self.object:setacceleration(new_acc)
self.old_pos = vector.new(pos)
self.old_dir = vector.new(dir)
self.old_switch = last_switch
-- Limits
for _,v in ipairs({"x","y","z"}) do
if math.abs(vel[v]) > max_vel then
vel[v] = boost_cart:get_sign(vel[v]) * max_vel
update.vel = true
end
end
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
end
if not (update.vel or update.pos) then
return
end
local yaw = 0
if dir.x < 0 then
yaw = 0.5
elseif dir.x > 0 then
yaw = 1.5
elseif 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
update = nil
end
minetest.register_entity(":carts:cart", boost_cart.cart)
minetest.register_craftitem(":carts:cart", {
description = "Cart",
inventory_image = minetest.inventorycube("cart_top.png", "cart_side.png", "cart_side.png"),
wield_image = "cart_side.png",
on_place = function(itemstack, placer, pointed_thing)
if not pointed_thing.type == "node" then
return
end
if boost_cart:is_rail(pointed_thing.under) then
minetest.add_entity(pointed_thing.under, "carts:cart")
elseif boost_cart:is_rail(pointed_thing.above) then
minetest.add_entity(pointed_thing.above, "carts:cart")
else return end
itemstack:take_item()
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"},
},
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 216 B

View File

@ -1,339 +0,0 @@
xof 0303txt 0032
Frame Root {
FrameTransformMatrix {
1.000000, 0.000000, 0.000000, 0.000000,
0.000000, 0.000000, 1.000000, 0.000000,
0.000000, 1.000000,-0.000000, 0.000000,
0.000000, 0.000000, 0.000000, 1.000000;;
}
Frame Cube {
FrameTransformMatrix {
5.000000, 0.000000,-0.000000, 0.000000,
-0.000000, 3.535534, 3.535534, 0.000000,
0.000000,-3.535534, 3.535534, 0.000000,
0.000000,-3.000000, 3.000000, 1.000000;;
}
Mesh { //Cube_001 Mesh
72;
-1.000000; 1.000000;-1.000000;,
-1.000000;-1.000000;-1.000000;,
1.000000;-1.000000;-1.000000;,
1.000000; 1.000000;-1.000000;,
-0.833334;-1.000000; 1.000000;,
-1.000000;-1.000000; 1.000000;,
-1.000000;-0.833333; 1.000000;,
-0.833334;-0.833333; 1.000000;,
-1.000000;-1.000000;-1.000000;,
-1.000000;-1.000000; 1.000000;,
0.999999;-1.000001; 1.000000;,
1.000000;-1.000000;-1.000000;,
0.999999;-1.000001; 1.000000;,
0.833332;-1.000000; 1.000000;,
0.833333;-0.833334; 1.000000;,
1.000000;-0.833334; 1.000000;,
0.833332;-1.000000; 1.000000;,
-0.833334;-1.000000; 1.000000;,
-0.833334;-0.833333; 1.000000;,
0.833333;-0.833334; 1.000000;,
1.000000; 0.833333; 1.000000;,
0.833334; 0.833333; 1.000000;,
0.833334; 1.000000; 1.000000;,
1.000000; 0.999999; 1.000000;,
1.000000;-0.833334; 1.000000;,
0.833333;-0.833334; 1.000000;,
0.833334; 0.833333; 1.000000;,
1.000000; 0.833333; 1.000000;,
0.833334; 0.833333; 1.000000;,
-0.833333; 0.833333; 1.000000;,
-0.833333; 1.000000; 1.000000;,
0.833334; 1.000000; 1.000000;,
0.833334; 0.833333;-0.800000;,
-0.833333; 0.833333;-0.800000;,
-0.833333; 0.833333; 1.000000;,
0.833334; 0.833333; 1.000000;,
-0.833333; 0.833333; 1.000000;,
-1.000000; 0.833333; 1.000000;,
-1.000000; 1.000000; 1.000000;,
-0.833333; 1.000000; 1.000000;,
-0.833334;-0.833333; 1.000000;,
-1.000000;-0.833333; 1.000000;,
-1.000000; 0.833333; 1.000000;,
-0.833333; 0.833333; 1.000000;,
0.833333;-0.833334;-0.800000;,
-0.833334;-0.833333;-0.800000;,
-0.833333; 0.833333;-0.800000;,
0.833334; 0.833333;-0.800000;,
-0.833333; 0.833333;-0.800000;,
-0.833334;-0.833333;-0.800000;,
-0.833334;-0.833333; 1.000000;,
-0.833333; 0.833333; 1.000000;,
-0.833334;-0.833333;-0.800000;,
0.833333;-0.833334;-0.800000;,
0.833333;-0.833334; 1.000000;,
-0.833334;-0.833333; 1.000000;,
0.833333;-0.833334;-0.800000;,
0.833334; 0.833333;-0.800000;,
0.833334; 0.833333; 1.000000;,
0.833333;-0.833334; 1.000000;,
-1.000000; 1.000000;-1.000000;,
-1.000000; 1.000000; 1.000000;,
-1.000000;-1.000000; 1.000000;,
-1.000000;-1.000000;-1.000000;,
-1.000000; 1.000000; 1.000000;,
-1.000000; 1.000000;-1.000000;,
1.000000; 1.000000;-1.000000;,
1.000000; 0.999999; 1.000000;,
1.000000;-1.000000;-1.000000;,
0.999999;-1.000001; 1.000000;,
1.000000; 0.999999; 1.000000;,
1.000000; 1.000000;-1.000000;;
18;
4;0;1;2;3;,
4;4;5;6;7;,
4;8;9;10;11;,
4;12;13;14;15;,
4;16;17;18;19;,
4;20;21;22;23;,
4;24;25;26;27;,
4;28;29;30;31;,
4;32;33;34;35;,
4;36;37;38;39;,
4;40;41;42;43;,
4;44;45;46;47;,
4;48;49;50;51;,
4;52;53;54;55;,
4;56;57;58;59;,
4;60;61;62;63;,
4;64;65;66;67;,
4;68;69;70;71;;
MeshNormals { //Cube_001 Normals
72;
0.000000; 0.000000;-1.000000;,
0.000000; 0.000000;-1.000000;,
0.000000; 0.000000;-1.000000;,
0.000000; 0.000000;-1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
-0.000000;-1.000000;-0.000000;,
-0.000000;-1.000000;-0.000000;,
-0.000000;-1.000000;-0.000000;,
-0.000000;-1.000000;-0.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
-0.000000;-1.000000; 0.000000;,
-0.000000;-1.000000; 0.000000;,
-0.000000;-1.000000; 0.000000;,
-0.000000;-1.000000; 0.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
0.000000;-0.000000; 1.000000;,
1.000000;-0.000000; 0.000000;,
1.000000;-0.000000; 0.000000;,
1.000000;-0.000000; 0.000000;,
1.000000;-0.000000; 0.000000;,
0.000000; 1.000000; 0.000000;,
0.000000; 1.000000; 0.000000;,
0.000000; 1.000000; 0.000000;,
0.000000; 1.000000; 0.000000;,
-1.000000; 0.000000; 0.000000;,
-1.000000; 0.000000; 0.000000;,
-1.000000; 0.000000; 0.000000;,
-1.000000; 0.000000; 0.000000;,
-1.000000; 0.000000;-0.000000;,
-1.000000; 0.000000;-0.000000;,
-1.000000; 0.000000;-0.000000;,
-1.000000; 0.000000;-0.000000;,
0.000000; 1.000000; 0.000000;,
0.000000; 1.000000; 0.000000;,
0.000000; 1.000000; 0.000000;,
0.000000; 1.000000; 0.000000;,
1.000000;-0.000000; 0.000000;,
1.000000;-0.000000; 0.000000;,
1.000000;-0.000000; 0.000000;,
1.000000;-0.000000; 0.000000;;
18;
4;0;1;2;3;,
4;4;5;6;7;,
4;8;9;10;11;,
4;12;13;14;15;,
4;16;17;18;19;,
4;20;21;22;23;,
4;24;25;26;27;,
4;28;29;30;31;,
4;32;33;34;35;,
4;36;37;38;39;,
4;40;41;42;43;,
4;44;45;46;47;,
4;48;49;50;51;,
4;52;53;54;55;,
4;56;57;58;59;,
4;60;61;62;63;,
4;64;65;66;67;,
4;68;69;70;71;;
} //End of Cube_001 Normals
MeshMaterialList { //Cube_001 Material List
1;
18;
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0;;
Material Material {
0.640000; 0.640000; 0.640000; 1.000000;;
96.078431;
0.500000; 0.500000; 0.500000;;
0.000000; 0.000000; 0.000000;;
TextureFilename {"cart.png";}
}
} //End of Cube_001 Material List
MeshTextureCoords { //Cube_001 UV Coordinates
72;
0.000000; 0.500000;,
0.500000; 0.500000;,
0.500000; 1.000000;,
0.000000; 1.000000;,
0.031250; 0.500000;,
-0.000000; 0.500000;,
-0.000000; 0.468750;,
0.031250; 0.468750;,
0.500000; 0.500000;,
0.500000; 0.000000;,
1.000000; 0.000000;,
1.000000; 0.500000;,
0.468750; 0.468750;,
0.500000; 0.468750;,
0.500000; 0.500000;,
0.468750; 0.500000;,
0.031250; 0.468750;,
0.468750; 0.468750;,
0.468750; 0.500000;,
0.031250; 0.500000;,
0.468750; 0.000000;,
0.500000; 0.000000;,
0.500000; 0.031250;,
0.468750; 0.031250;,
0.468750; 0.031250;,
0.500000; 0.031250;,
0.500000; 0.468750;,
0.468750; 0.468750;,
0.468750; 0.031250;,
0.031250; 0.031250;,
0.031250; 0.000000;,
0.468750; 0.000000;,
1.000000; 0.500000;,
0.500000; 0.500000;,
0.500000; 0.000000;,
1.000000; 0.000000;,
0.031250; 0.031250;,
0.000000; 0.031250;,
0.000000; 0.000000;,
0.031250; 0.000000;,
0.031250; 0.468750;,
-0.000000; 0.468750;,
0.000000; 0.031250;,
0.031250; 0.031250;,
0.000000; 0.500000;,
0.500000; 0.500000;,
0.500000; 1.000000;,
0.000000; 1.000000;,
1.000000; 0.500000;,
0.500000; 0.500000;,
0.500000; 0.000000;,
1.000000; 0.000000;,
1.000000; 0.500000;,
0.500000; 0.500000;,
0.500000; 0.000000;,
1.000000; 0.000000;,
1.000000; 0.500000;,
0.500000; 0.500000;,
0.500000; 0.000000;,
1.000000; 0.000000;,
0.500000; 0.500000;,
0.500000; 0.000000;,
1.000000; 0.000000;,
1.000000; 0.500000;,
1.000000; 0.000000;,
1.000000; 0.500000;,
0.500000; 0.500000;,
0.500000; 0.000000;,
0.500000; 0.500000;,
0.500000; 0.000000;,
1.000000; 0.000000;,
1.000000; 0.500000;;
} //End of Cube_001 UV Coordinates
} //End of Cube_001 Mesh
} //End of Cube
} //End of Root Frame
AnimationSet {
Animation {
{Cube}
AnimationKey { //Position
2;
4;
0;3; 0.000000, 0.000000, 0.000000;;,
1;3; 0.000000, 3.000000, 3.000000;;,
2;3; 0.000000,-3.000000, 3.000000;;,
3;3; 0.000000,-3.000000, 3.000000;;;
}
AnimationKey { //Rotation
0;
4;
0;4; -1.000000, 0.000000, 0.000000, 0.000000;;,
1;4; -0.923880,-0.382683,-0.000000, 0.000000;;,
2;4; -0.923880, 0.382683, 0.000000, 0.000000;;,
3;4; -0.923880, 0.382683, 0.000000, 0.000000;;;
}
AnimationKey { //Scale
1;
4;
0;3; 5.000000, 5.000000, 5.000000;;,
1;3; 5.000000, 5.000000, 5.000000;;,
2;3; 5.000000, 5.000000, 5.000000;;,
3;3; 5.000000, 5.000000, 5.000000;;;
}
}
} //End of AnimationSet

View File

@ -1,115 +0,0 @@
minetest.register_node("boost_cart:rail", {
description = "Rail",
drawtype = "raillike",
tiles = {"default_rail.png", "default_rail_curved.png", "default_rail_t_junction.png", "default_rail_crossing.png"},
inventory_image = "default_rail.png",
wield_image = "default_rail.png",
paramtype = "light",
sunlight_propagates = true,
is_ground_content = false,
walkable = false,
selection_box = {
type = "fixed",
fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
},
groups = {dig_immediate = 2, attached_node = 1, rail = 1, connect_to_raillike = 1},
})
minetest.register_craft({
output = 'boost_cart:rail 15',
recipe = {
{'default:steel_ingot', '', 'default:steel_ingot'},
{'default:steel_ingot', 'default:stick', 'default:steel_ingot'},
{'default:steel_ingot', '', 'default:steel_ingot'},
}
})
-- Speed up
minetest.register_node(":carts:powerrail", {
description = "Powered rail",
drawtype = "raillike",
tiles = {"carts_rail_pwr.png", "carts_rail_curved_pwr.png", "carts_rail_t_junction_pwr.png", "carts_rail_crossing_pwr.png"},
inventory_image = "carts_rail_pwr.png",
wield_image = "carts_rail_pwr.png",
paramtype = "light",
sunlight_propagates = true,
is_ground_content = false,
walkable = false,
selection_box = {
type = "fixed",
fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
},
groups = {dig_immediate = 2, attached_node = 1, rail = 1, connect_to_raillike = 1},
after_place_node = function(pos, placer, itemstack)
if not mesecon then
minetest.get_meta(pos):set_string("cart_acceleration", "0.5")
end
end,
mesecons = {
effector = {
action_on = function(pos, node)
boost_cart:boost_rail(pos, 0.5)
end,
action_off = function(pos, node)
minetest.get_meta(pos):set_string("cart_acceleration", "0")
end,
},
},
})
minetest.register_craft({
output = "carts:powerrail 6",
recipe = {
{"default:steel_ingot", "default:mese_crystal_fragment", "default:steel_ingot"},
{"default:steel_ingot", "group:stick", "default:steel_ingot"},
{"default:steel_ingot", "default:mese_crystal_fragment", "default:steel_ingot"},
}
})
minetest.register_node(":carts:brakerail", {
description = "Brake rail",
drawtype = "raillike",
tiles = {"carts_rail_brk.png", "carts_rail_curved_brk.png", "carts_rail_t_junction_brk.png", "carts_rail_crossing_brk.png"},
inventory_image = "carts_rail_brk.png",
wield_image = "carts_rail_brk.png",
paramtype = "light",
sunlight_propagates = true,
is_ground_content = false,
walkable = false,
selection_box = {
type = "fixed",
fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
},
groups = {dig_immediate = 2, attached_node = 1, rail = 1, connect_to_raillike = 1},
after_place_node = function(pos, placer, itemstack)
if not mesecon then
minetest.get_meta(pos):set_string("cart_acceleration", "-0.2")
end
end,
mesecons = {
effector = {
action_on = function(pos, node)
boost_cart:boost_rail(pos, -0.2)
end,
action_off = function(pos, node)
minetest.get_meta(pos):set_string("cart_acceleration", "0")
end,
},
},
})
minetest.register_craft({
output = "carts:brakerail 6",
recipe = {
{"default:steel_ingot", "default:coal_lump", "default:steel_ingot"},
{"default:steel_ingot", "group:stick", "default:steel_ingot"},
{"default:steel_ingot", "default:coal_lump", "default:steel_ingot"},
}
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 147 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 131 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 442 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 393 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 389 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 399 B

View File

@ -1,73 +0,0 @@
local default_spawn_settings = minetest.setting_get("static_spawnpoint")
minetest.register_globalstep(function(dtime)
local players = minetest.get_connected_players()
for i,player in ipairs(players) do
local function has_compass(player)
for _,stack in ipairs(player:get_inventory():get_list("main")) do
if minetest.get_item_group(stack:get_name(), "compass") ~= 0 then
return true
end
end
return false
end
if has_compass(player) then
local spawn = beds_player_spawns[player:get_player_name()] or
minetest.setting_get("static_spawnpoint") or
{x=0,y=0,z=0}
pos = player:getpos()
dir = player:get_look_yaw()
local angle_north = math.deg(math.atan2(spawn.x - pos.x, spawn.z - pos.z))
if angle_north < 0 then angle_north = angle_north + 360 end
angle_dir = 90 - math.deg(dir)
local angle_relative = (angle_north - angle_dir) % 360
local compass_image = math.floor((angle_relative/30) + 0.5)%12
for j,stack in ipairs(player:get_inventory():get_list("main")) do
if minetest.get_item_group(stack:get_name(), "compass") ~= 0 and
minetest.get_item_group(stack:get_name(), "compass")-1 ~= compass_image then
player:get_inventory():set_stack("main", j, "compass:"..compass_image)
end
end
end
end
end)
local images = {
"compass_0.png",
"compass_1.png",
"compass_2.png",
"compass_3.png",
"compass_4.png",
"compass_5.png",
"compass_6.png",
"compass_7.png",
"compass_8.png",
"compass_9.png",
"compass_10.png",
"compass_11.png",
}
local i
for i,img in ipairs(images) do
local inv = 1
if i == 1 then
inv = 0
end
minetest.register_tool("compass:"..(i-1), {
description = "Compass",
inventory_image = img,
wield_image = img,
stack_max = 1,
groups = {not_in_creative_inventory=inv,compass=i, tools = inv}
})
end
minetest.register_craft({
output = 'compass:1',
recipe = {
{'', 'default:iron_ingot', ''},
{'default:iron_ingot', 'default_bluestone_dust', 'default:iron_ingot'},
{'', 'default:iron_ingot', ''}
}
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 337 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 332 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 208 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 207 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 210 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 209 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 206 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 401 B

After

Width:  |  Height:  |  Size: 360 B

View File

@ -1921,26 +1921,4 @@ minetest.register_node("default:snowblock", {
footstep = {name="default_grass_footstep", gain=0.4},
}),
drop = "default:snow 4",
})
minetest.register_node("default:cobweb", {
description = "Cobweb",
drawtype = "plantlike",
visual_scale = 1.1,
stack_max = 64,
tiles = {"web.png"},
inventory_image = "web.png",
paramtype = "light",
sunlight_propagates = true,
liquid_viscosity = 14,
liquidtype = "source",
liquid_alternative_flowing = "default:cobweb",
liquid_alternative_source = "default:cobweb",
liquid_renewable = false,
liquid_range = 0,
walkable = false,
groups = {snappy=1,liquid=3,flammable=2, decorative = 1},
drop = "farming:string",
})
minetest.register_alias('mobs:cobweb','default:cobweb')
})

Binary file not shown.

After

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 271 B

View File

@ -1,5 +1,9 @@
Minetest 0.4 mod: fire
======================
Fire Redo 0.2
by TenPlus1
Based on Minetest 0.4 mod: fire with changes by HybridDog
=========================================================
License of source code:
-----------------------
@ -7,14 +11,14 @@ Copyright (C) 2012 Perttu Ahola (celeron55) <celeron55@gmail.com>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 3.0 of the License, or
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
http://www.gnu.org/licenses/lgpl-3.0.html
http://www.gnu.org/licenses/lgpl-2.1.html
License of media (textures and sounds)
--------------------------------------
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
Attribution-ShareAlike 3.0 Unported (CC BY-SA 3.0)
http://creativecommons.org/licenses/by-sa/3.0/
Authors of media files

View File

@ -0,0 +1 @@
default

View File

@ -1,37 +1,17 @@
-- minetest/fire/init.lua (HybridDog pull request changes)
-- Tweaked by TenPlus1 to add chest drops, also removed sounds which are now
-- handled by Ambience mod.
-- Global namespace for functions
fire = {}
fire.mod = "redo"
-- initial check to see if fire is disabled
local disable_fire = minetest.setting_getbool("disable_fire")
-- Register flame nodes
minetest.register_node("fire:basic_flame", {
description = "Basic Flame",
drawtype = "plantlike",
tiles = {
{
name = "fire_basic_flame_animated.png",
animation = {
type="vertical_frames",
aspect_w = 16,
aspect_h = 16,
length = 1
},
},
},
inventory_image = "fire_basic_flame.png",
paramtype = "light",
light_source = 14,
walkable = false,
buildable_to = true,
sunlight_propagates = true,
damage_per_second = 4,
groups = {igniter = 2, dig_immediate = 3},
drop = '',
on_blast = function()
end, -- unaffected by explosions
})
minetest.register_node("fire:permanent_flame", {
local flamedef = {
description = "Permanent Flame",
drawtype = "firelike",
tiles = {
@ -56,83 +36,162 @@ minetest.register_node("fire:permanent_flame", {
drop = "",
on_blast = function()
end,
})
end, -- unaffected by explosions
}
minetest.register_node("fire:permanent_flame", table.copy(flamedef))
-- compatibility
minetest.register_alias("fire:eternal_flame", "fire:permanent_flame")
flamedef.description = "Basic Flame"
flamedef.drawtype = "plantlike" -- quick draw for basic flame, fancy for permanent
-- extinguish flames quickly with dedicated ABM
minetest.register_abm({
nodenames = {"fire:basic_flame"},
interval = 7,
chance = 2,
catch_up = false,
action = function(p0, node, _, _)
if not disable_fire then return end
minetest.set_node(p0, {name = "air"})
end,
})
minetest.register_node("fire:basic_flame", flamedef)
-- Return positions for flames around a burning node
function fire.find_pos_for_flame_around(pos)
return minetest.find_node_near(pos, 1, {"air"})
end
-- Detect nearby extinguishing nodes
function fire.flame_should_extinguish(pos)
return minetest.find_node_near(pos, 1, {"group:puts_out_fire"})
end
-- Extinguish all flames quickly with water, snow, ice
-- extinguish flames quickly with water, snow, ice
minetest.register_abm({
nodenames = {"fire:basic_flame", "fire:permanent_flame"},
neighbors = {"group:puts_out_fire"},
interval = 3,
chance = 2,
chance = 1,
catch_up = false,
action = function(p0, node, _, _)
minetest.set_node(p0, {name = "air"})
action = function(p0)
-- fire node holds no metadata so quickly swap out for air
minetest.swap_node(p0, {name = "air"})
minetest.sound_play("fire_extinguish_flame",
{pos = p0, max_hear_distance = 16, gain = 0.15})
{pos = p0, max_hear_distance = 16, gain = 0.25})
end,
})
-- ignite neighboring nodes
minetest.register_abm({
nodenames = {"group:flammable"},
neighbors = {"group:igniter"},
interval = 7,
chance = 16,
catch_up = false,
action = function(p0, node, _, _)
-- check to see if fire is still disabled
disable_fire = minetest.setting_getbool("disable_fire")
--print ("disable fire set to ", disable_fire)
-- if there is water or stuff like that around flame, don't ignite
if disable_fire
or minetest.find_node_near(p0, 1, {"group:puts_out_fire"}) then
return
-- Enable the following ABMs according to 'disable fire' setting
if minetest.setting_getbool("disable_fire") then
-- Remove basic flames only
minetest.register_abm({
nodenames = {"fire:basic_flame"},
interval = 7,
chance = 1,
catch_up = false,
action = function(p0)
-- fire node holds no metadata so quickly swap out for air
minetest.swap_node(p0, {name = "air"})
end
local p = minetest.find_node_near(p0, 1, {"air"})
if p then
minetest.set_node(p, {name = "fire:basic_flame"})
end
end,
})
})
-- remove flammable nodes and flame
minetest.register_abm({
nodenames = {"fire:basic_flame"},
interval = 5,
chance = 16,
catch_up = false,
action = function(p0, node, _, _)
else
-- If there are no flammable nodes around flame, remove flame
if not minetest.find_node_near(p0, 1, {"group:flammable"}) then
minetest.set_node(p0, {name = "air"})
return
end
-- Ignite neighboring nodes, add basic flames
if math.random(1, 4) == 1 then
-- remove a flammable node around flame
local p = minetest.find_node_near(p0, 1, {"group:flammable"})
if p then
minetest.set_node(p, {name = "air"})
-- nodeupdate(p)
minetest.register_abm({
nodenames = {"group:flammable"},
neighbors = {"group:igniter"},
interval = 7,
chance = 16,
catch_up = false,
action = function(p0)
-- If there is water or stuff like that around node, don't ignite
if fire.flame_should_extinguish(p0) then
return
end
local p = fire.find_pos_for_flame_around(p0)
if p then
-- air node holds no metadata so quickly swap out for fire
minetest.swap_node(p, {name = "fire:basic_flame"})
end
end,
})
-- Remove basic flames and flammable nodes
minetest.register_abm({
nodenames = {"fire:basic_flame"},
interval = 5,
chance = 16,
catch_up = false,
action = function(p0)
-- If there are no flammable nodes around flame, remove flame
if not minetest.find_node_near(p0, 1, {"group:flammable"}) then
-- fire node holds no metadata so quickly swap out for air
minetest.swap_node(p0, {name = "air"})
return
end
if math.random(1, 4) ~= 1 then
return
end
-- remove flammable nodes around flame
local p = minetest.find_node_near(p0, 1, {"group:flammable"})
if not p then
return
end
local node = minetest.get_node(p)
local on_burn = minetest.registered_nodes[node.name].on_burn
if on_burn then
if type(on_burn) == "string" then
node.name = on_burn
minetest.set_node(p, node)
nodeupdate(p)
return
end
if on_burn(p, node) ~= false then
return
end
end
minetest.remove_node(p)
nodeupdate(p)
end,
})
end
-- used to drop items inside a chest or container
function fire.drop_items(pos, invstring)
local meta = minetest.get_meta(pos)
local inv = meta:get_inventory()
for i = 1, inv:get_size(invstring) do
local m_stack = inv:get_stack(invstring, i)
local obj = minetest.add_item(pos, m_stack)
if obj then
obj:setvelocity({
x = math.random(-1, 1),
y = 3,
z = math.random(-1, 1)
})
end
end
end
-- override chest node so that it's flammable
minetest.override_item("default:chest", {
groups = {choppy = 2, oddly_breakable_by_hand = 2, flammable = 3},
on_burn = function(p)
fire.drop_items(p, "main")
minetest.remove_node(p)
end,
})
})

View File

@ -15,16 +15,15 @@ if minetest.get_modpath("mobs") ~= nil then
if mobs.mod ~= nil and mobs.mod == "redo" then
register_food("mobs:cheese", 4)
register_food("mobs:meat", 8)
register_food("mobs:meat_raw", 4, "", 2)
register_food("mobs:meat_raw", 4, "", 3)
register_food("mobs:rat_cooked", 4)
register_food("mobs:rat_meat", 2)
register_food("mobs:honey", 2)
register_food("mobs:pork_raw", 4, "", 2)
register_food("mobs:pork_raw", 3, "", 3)
register_food("mobs:pork_cooked", 8)
register_food("mobs:chicken_cooked", 6)
register_food("mobs:chicken_raw", 2, "", 2)
register_food("mobs:chicken_raw", 2, "", 3)
register_food("mobs:chicken_egg_fried", 2)
register_food("mobs:rotten_flesh", 1, "", 5)
if minetest.get_modpath("bucket") then
register_food("mobs:bucket_milk", 3, "bucket:bucket_empty")
end

View File

@ -22,11 +22,11 @@ dofile(path.."/spider.lua") -- AspireMint
dofile(path.."/zombie.lua") -- Blockmen
dofile(path.."/skeleton.lua") -- Blockmen
-- NPC
dofile(path.."/npc.lua") -- TenPlus1
-- Mob Items
dofile(path.."/crafts.lua")
-- Spawner
dofile(path.."/spawner.lua")
dofile(path.."/spawner.lua")
-- Remove
dofile(path.."/npc.lua")

View File

@ -75,7 +75,7 @@ minetest.register_node("mobs:cobweb", {
liquid_range = 0,
walkable = false,
groups = {snappy = 1, liquid = 3},
drop = "farming:cotton",
--drop = "farming:cotton",
sounds = default.node_sound_leaves_defaults(),
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 144 B

After

Width:  |  Height:  |  Size: 271 B

View File

Before

Width:  |  Height:  |  Size: 161 B

After

Width:  |  Height:  |  Size: 161 B

View File

Before

Width:  |  Height:  |  Size: 127 B

After

Width:  |  Height:  |  Size: 127 B

View File

Before

Width:  |  Height:  |  Size: 230 B

After

Width:  |  Height:  |  Size: 230 B

View File

Before

Width:  |  Height:  |  Size: 173 B

After

Width:  |  Height:  |  Size: 173 B

View File

Before

Width:  |  Height:  |  Size: 197 B

After

Width:  |  Height:  |  Size: 197 B

View File

Before

Width:  |  Height:  |  Size: 192 B

After

Width:  |  Height:  |  Size: 192 B

View File

Before

Width:  |  Height:  |  Size: 153 B

After

Width:  |  Height:  |  Size: 153 B

View File

Before

Width:  |  Height:  |  Size: 177 B

After

Width:  |  Height:  |  Size: 177 B

View File

Before

Width:  |  Height:  |  Size: 167 B

After

Width:  |  Height:  |  Size: 167 B

View File

Before

Width:  |  Height:  |  Size: 177 B

After

Width:  |  Height:  |  Size: 177 B

View File

Before

Width:  |  Height:  |  Size: 153 B

After

Width:  |  Height:  |  Size: 153 B

View File

Before

Width:  |  Height:  |  Size: 187 B

After

Width:  |  Height:  |  Size: 187 B

View File

Before

Width:  |  Height:  |  Size: 573 B

After

Width:  |  Height:  |  Size: 573 B

View File

Before

Width:  |  Height:  |  Size: 334 B

After

Width:  |  Height:  |  Size: 334 B

View File

Before

Width:  |  Height:  |  Size: 207 B

After

Width:  |  Height:  |  Size: 207 B

View File

Before

Width:  |  Height:  |  Size: 192 B

After

Width:  |  Height:  |  Size: 192 B

View File

Before

Width:  |  Height:  |  Size: 129 B

After

Width:  |  Height:  |  Size: 129 B

View File

Before

Width:  |  Height:  |  Size: 153 B

After

Width:  |  Height:  |  Size: 153 B

View File

Before

Width:  |  Height:  |  Size: 192 B

After

Width:  |  Height:  |  Size: 192 B

View File

@ -0,0 +1,21 @@
Minetest Mod - Railcart [railcart]
==================================
License Source Code: LGPL v2.1
License of media (textures, sounds and models not otherwise specified): CC-0
Authors of media files:
-----------------------
HybridDog: WTFPL
cart.png
cart_bottom.png
cart_side.png
cart_top.png
Zeg9:
cart.x

View File

@ -0,0 +1,30 @@
Minetest Mod - Railcart [railcart]
==================================
Minetest version: 0.4.13
Depends: railtrack
Proof of concept ground up re-write of the carts mod. Currently uses media files
borrowed from the original carts mod by PilzAdam.
Please note, this mod makes heavy use of metadata so that carts are able to
travel through unloaded map chunks, therefor a 'carts' privilege is required
to place or pick up carts in multiplayer mode.
Crafting
--------
S = Steel Ingot [default:steel_ingot]
W = Wood [group:wood]
Railcart: [railcart:cart]
+---+---+---+
| S | | S |
+---+---+---+
| S | | S |
+---+---+---+
| W | S | W |
+---+---+---+

View File

@ -0,0 +1 @@
railtrack

View File

@ -0,0 +1,191 @@
local modpath = minetest.get_modpath(minetest.get_current_modname())
dofile(modpath.."/railcart.lua")
local worldpath = minetest.get_worldpath()
local function create_detached_inventory(id)
local inv = minetest.create_detached_inventory("railcart_"..tostring(id), {
on_put = function(inv, listname, index, stack, player)
railcart:save()
end,
on_take = function(inv, listname, index, stack, player)
railcart:save()
end,
allow_put = function(inv, listname, index, stack, player)
return 1
end,
allow_take = function(inv, listname, index, stack, player)
return stack:get_count()
end,
allow_move = function(inv, from_list, from_index, to_list, to_index, count, player)
return count
end,
})
inv:set_size("main", 32)
return inv
end
local input = io.open(worldpath.."/railcart.txt", "r")
if input then
local data = input:read('*all')
if data then
local carts = minetest.deserialize(data) or {}
for id, ref in pairs(carts) do
local cart = railcart.cart:new(ref)
if ref.inv then
local inv = create_detached_inventory(cart.id)
for i, stack in pairs(ref.inv) do
inv:set_stack("main", i, stack)
end
cart.inv = inv
end
railcart.allcarts[id] = cart
end
end
input = nil
end
local function is_valid_player(object)
if object then
return object:is_player()
end
end
railcart:register_entity("railcart:cart_entity", {
on_punch = function(self, puncher, _, _, direction)
if not is_valid_player(puncher) then
return
end
if puncher:get_player_control().sneak then
if self.cart then
if self.cart.id then
if self.cart.inv then
if not self.cart.inv:is_empty("main") then
return
end
end
railcart:remove_cart(self.cart.id)
end
end
self.object:remove()
local inv = puncher:get_inventory()
if minetest.setting_getbool("creative_mode") then
if not inv:contains_item("main", "railcart:cart") then
inv:add_item("main", "railcart:cart")
end
else
inv:add_item("main", "railcart:cart")
end
return
end
if self.cart and direction then
if self.driver then
direction = {x=0, y=0, z=0}
local ld = self.driver:get_look_dir()
if ld.y > -0.99 then
direction = {
x = railtrack:get_sign(ld.x),
z = railtrack:get_sign(ld.z),
y = self.cart.dir.y
}
end
end
local pos = vector.round(self.object:getpos())
local dir = vector.round(vector.normalize(direction))
local speed = railcart:velocity_to_speed(self.cart.vel)
self.timer = 0
self.cart.target = nil
self.cart.prev = pos
self.cart.vel = vector.multiply(dir, 5)
self.cart.accel = railtrack:get_acceleration(pos)
self.object:setvelocity(self.cart.vel)
end
end,
on_rightclick = function(self, clicker)
if not is_valid_player(clicker) then
return
end
if clicker:get_player_control().sneak then
local name = clicker:get_player_name()
local cart = self.cart or {}
if cart.id and name then
local formspec = "size[8,9]"..
default.gui_bg..default.gui_bg_img..default.gui_slots..
"list[detached:railcart_"..cart.id..";main;0,0.3;8,4;]"..
"list[current_player;main;0,4.85;8,1;]"..
"list[current_player;main;0,6.08;8,3;8]"..
"listring[detached:railcart_"..cart.id..";main]"..
"listring[current_player;main]"..
default.get_hotbar_bg(0,4.85)
minetest.show_formspec(name, "inventory", formspec)
end
return
end
if self.driver and clicker == self.driver then
self.driver = nil
clicker:set_detach()
elseif not self.driver then
self.driver = clicker
clicker:set_attach(self.object, "", {x=0,y=5,z=0}, {x=0,y=0,z=0})
end
end,
})
minetest.register_craftitem("railcart:cart", {
description = "Railcart",
inventory_image = minetest.inventorycube("railcart_top.png", "railcart_side.png", "railcart_side.png"),
wield_image = "railcart_side.png",
on_place = function(itemstack, placer, pointed_thing)
local name = placer:get_player_name()
if not name or pointed_thing.type ~= "node" then
return
end
if not minetest.is_singleplayer() then
if not minetest.check_player_privs(name, {carts=true}) then
minetest.chat_send_player(name, "Requires carts privilege")
return
end
end
local pos = pointed_thing.under
if not railtrack:is_railnode(pos) then
return
end
local carts = railcart:get_carts_in_radius(pos, 0.9)
if #carts > 0 then
return
end
local id = railcart:get_new_id()
local ref = {
id = id,
inv = create_detached_inventory(id),
pos = vector.new(pos),
prev = vector.new(pos),
accel = railtrack:get_acceleration(pos),
dir = railcart:get_rail_direction(pos),
}
local cart = railcart.cart:new(ref)
table.insert(railcart.allcarts, cart)
railcart:save()
if not minetest.setting_getbool("creative_mode") then
itemstack:take_item()
end
return itemstack
end,
})
minetest.register_privilege("carts", "Player can pick-up and place carts.")
minetest.register_craft({
output = "railcart:cart",
recipe = {
{"default:steel_ingot", "", "default:steel_ingot"},
{"default:steel_ingot", "", "default:steel_ingot"},
{"group:wood", "default:steel_ingot", "group:wood"},
},
})
minetest.register_on_shutdown(function()
railcart:save()
end)

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,444 @@
local ENTITY_UPDATE_TIME = 1
local OBJECT_UPDATE_TIME = 5
local OBJECT_SAVE_TIME = 10
local RELOAD_DISTANCE = 32
local SNAP_DISTANCE = 0.5
local SPEED_MIN = 0.1
local SPEED_MAX = 15
railcart = {
timer = 0,
allcarts = {},
default_entity = {
physical = false,
collisionbox = {-0.5,-0.5,-0.5, 0.5,0.5,0.5},
visual = "mesh",
mesh = "railcart.b3d",
visual_size = {x=1, y=1},
textures = {"railcart.png"},
cart = nil,
driver = nil,
timer = 0,
},
}
railcart.cart = {
id = nil,
pos = nil,
target = nil,
prev = nil,
accel = nil,
inv = nil,
dir = {x=0, y=0, z=0},
vel = {x=0, y=0, z=0},
acc = {x=0, y=0, z=0},
timer = 0,
name = "railcart:cart_entity",
}
function railcart.cart:new(obj)
obj = obj or {}
setmetatable(obj, self)
self.__index = self
return obj
end
function railcart.cart:is_loaded()
for _, player in pairs(minetest.get_connected_players()) do
local pos = player:getpos()
if pos then
local dist = railtrack:get_distance(pos, self.pos)
if dist <= RELOAD_DISTANCE then
return true
end
end
end
return false
end
function railcart.cart:on_step(dtime)
self.timer = self.timer - dtime
if self.timer > 0 then
return
end
self.timer = OBJECT_UPDATE_TIME
local entity = railcart:get_cart_entity(self.id)
if entity.object then
return
end
if self:is_loaded() then
local object = minetest.add_entity(self.pos, self.name)
if object then
entity = object:get_luaentity() or {}
entity.cart = self
object:setvelocity(self.vel)
object:setacceleration(self.acc)
end
else
self.timer = railcart:update(self, self.timer)
end
end
function railcart:register_entity(name, def)
local ref = {}
for k, v in pairs(railcart.default_entity) do
ref[k] = def[k] or railtrack:copy(v)
end
ref.on_activate = function(self, staticdata, dtime_s)
if type(def.on_activate) == "function" then
def.on_activate(self, staticdata, dtime_s)
end
self.object:set_armor_groups({immortal=1})
if staticdata == "expired" then
self.object:remove()
end
end
ref.on_step = function(self, dtime)
if type(def.on_step) == "function" then
def.on_step(self, dtime)
end
local cart = self.cart
local object = self.object
if not cart or not object then
return
end
self.timer = self.timer - dtime
if self.timer > 0 then
return
end
self.timer = railcart:update(cart, ENTITY_UPDATE_TIME, object)
if type(def.on_update) == "function" then
def.on_update(self)
end
end
ref.get_staticdata = function(self)
if type(def.get_staticdata) == "function" then
def.get_staticdata(self)
end
if self.cart then
if self.cart:is_loaded() == false then
self.cart.timer = 0
self.object:remove()
end
end
return "expired"
end
for k, v in pairs(def) do
ref[k] = ref[k] or v
end
minetest.register_entity(name, ref)
end
function railcart:save()
local carts = {}
for id, cart in pairs(railcart.allcarts) do
local ref = {}
for k, v in pairs(cart) do
ref[k] = v
end
local inv = {}
if ref.inv then
local list = ref.inv:get_list("main")
for i, stack in ipairs(list) do
inv[i] = stack:to_string()
end
end
ref.inv = inv
table.insert(carts, ref)
end
local output = io.open(minetest.get_worldpath().."/railcart.txt",'w')
if output then
output:write(minetest.serialize(carts))
io.close(output)
end
end
function railcart:remove_cart(id)
for i, cart in pairs(railcart.allcarts) do
if cart.id == id then
railcart.allcarts[i] = nil
railcart:save()
break
end
end
end
function railcart:get_rail_direction(pos)
local target = nil
local cons = railtrack:get_connections(pos)
local ymax = pos.y
for _, con in pairs(cons) do
if con.y >= ymax then
ymax = con.y
target = con
end
end
if target then
if #cons == 1 then
target.y = pos.y
end
return railtrack:get_direction(target, pos)
end
return {x=0, y=0, z=0}
end
function railcart:get_new_id()
local id = 0
for _, cart in pairs(railcart.allcarts) do
if cart.id > id then
id = cart.id
end
end
return id + 1
end
function railcart:get_cart_ref(id)
for _, cart in pairs(railcart.allcarts) do
if cart.id == id then
return cart
end
end
end
function railcart:get_cart_entity(id)
local cart_ref = {}
for _, ref in pairs(minetest.luaentities) do
if ref.cart then
if ref.cart.id == id then
cart_ref = ref
break
end
end
end
return cart_ref
end
function railcart:get_carts_in_radius(pos, rad)
local carts = {}
for _, cart in pairs(railcart.allcarts) do
local px = pos.x - cart.pos.x
local py = pos.y - cart.pos.y
local pz = pos.z - cart.pos.z
if (px * px) + (py * py) + (pz * pz) <= rad * rad then
table.insert(carts, cart)
end
end
return carts
end
function railcart:get_cart_in_sight(p1, p2)
local ref = nil
local dist = railtrack:get_distance(p1, p2) + 1
local dir = railtrack:get_direction(p2, p1)
local carts = railcart:get_carts_in_radius(p1, dist)
for _, cart in pairs(carts) do
if not vector.equals(p1, cart.pos) then
local dc = railtrack:get_direction(cart.pos, p1)
if vector.equals(dc, dir) then
local d = railtrack:get_distance(p1, cart.pos)
if d < dist then
dist = d
ref = cart
end
end
end
end
return ref
end
function railcart:get_delta_time(vel, acc, dist)
if vel > 0 then
if acc == 0 then
return dist / vel
end
local r = math.sqrt(vel * vel + 2 * acc * dist)
if r > 0 then
return (-vel + r) / acc
end
end
return 9999 --INF
end
function railcart:velocity_to_dir(v)
if math.abs(v.x) > math.abs(v.z) then
return {x=railtrack:get_sign(v.x), y=railtrack:get_sign(v.y), z=0}
else
return {x=0, y=railtrack:get_sign(v.y), z=railtrack:get_sign(v.z)}
end
end
function railcart:velocity_to_speed(vel)
local speed = math.max(math.abs(vel.x), math.abs(vel.z))
if speed < SPEED_MIN then
speed = 0
elseif speed > SPEED_MAX then
speed = SPEED_MAX
end
return speed
end
function railcart:get_target(pos, vel)
local meta = minetest.get_meta(vector.round(pos))
local dir = self:velocity_to_dir(vel)
local targets = {}
local rots = railtrack.rotations
local contype = meta:get_string("contype") or ""
local s_junc = meta:get_string("junctions") or ""
local s_cons = meta:get_string("connections") or ""
local s_rots = meta:get_string("rotations") or ""
if contype == "section" then
local junctions = minetest.deserialize(s_junc) or {}
for _, p in pairs(junctions) do
table.insert(targets, p)
end
else
local cons = minetest.deserialize(s_cons) or {}
for _, p in pairs(cons) do
table.insert(targets, p)
end
if s_rots ~= "" then
local fwd = false
for _, p in pairs(cons) do
if vector.equals(vector.add(pos, dir), p) then
fwd = true
end
end
if fwd == true or #cons == 1 then
rots = s_rots
end
end
end
local rotations = railtrack:get_rotations(rots, dir)
for _, r in ipairs(rotations) do
for _, t in pairs(targets) do
local d = railtrack:get_direction(t, pos)
if r.x == d.x and r.z == d.z then
return t
end
end
end
end
function railcart:update(cart, time, object)
if object then
cart.pos = object:getpos()
cart.vel = object:getvelocity()
end
if not cart.target then
cart.pos = vector.new(cart.prev)
cart.target = railcart:get_target(cart.pos, cart.vel)
if object then
object:moveto(cart.pos)
end
end
local speed = railcart:velocity_to_speed(cart.vel)
if cart.target then
cart.dir = railtrack:get_direction(cart.target, cart.pos)
else
speed = 0
end
if speed > SPEED_MIN then
local blocked = false
local cis = railcart:get_cart_in_sight(cart.pos, cart.target)
if cis then
if railcart:velocity_to_speed(cis.vel) == 0 then
cart.target = vector.subtract(cis.pos, cart.dir)
blocked = true
end
end
--[[
if object then
local p1 = vector.add(cart.pos, {x=0, y=1, z=0})
local p2 = vector.add(cart.target, {x=0, y=1, z=0})
if minetest.get_node_or_nil(p2) then
local los, bp = minetest.line_of_sight(p1, p2)
if los == false then
bp.y = bp.y - 1
cart.target = vector.subtract(bp, cart.dir)
blocked = true
end
end
end
]]--
local d1 = railtrack:get_distance(cart.prev, cart.target)
local d2 = railtrack:get_distance(cart.prev, cart.pos)
local dist = d1 - d2
if dist > SNAP_DISTANCE then
local accel = railtrack.accel_flat
if cart.dir.y == -1 then
accel = railtrack.accel_down
elseif cart.dir.y == 1 then
accel = railtrack.accel_up
end
accel = cart.accel or accel
if object then
dist = math.max(dist - SNAP_DISTANCE, 0)
end
local dt = railcart:get_delta_time(speed, accel, dist)
if dt < time then
time = dt
end
local dp = speed * time + 0.5 * accel * time * time
local vf = speed + accel * time
if object then
if vf <= 0 then
speed = 0
accel = 0
end
cart.vel = vector.multiply(cart.dir, speed)
cart.acc = vector.multiply(cart.dir, accel)
elseif dp > 0 then
cart.vel = vector.multiply(cart.dir, vf)
cart.pos = vector.add(cart.pos, vector.multiply(cart.dir, dp))
end
else
if blocked and vector.equals(cart.target, cart.prev) then
cart.vel = {x=0, y=0, z=0}
cart.acc = {x=0, y=0, z=0}
else
cart.pos = vector.new(cart.target)
cart.prev = vector.new(cart.target)
cart.accel = railtrack:get_acceleration(cart.target)
cart.target = nil
return 0
end
end
else
cart.dir = railcart:get_rail_direction(cart.pos)
cart.vel = {x=0, y=0, z=0}
cart.acc = {x=0, y=0, z=0}
end
if object then
if cart.dir.y == -1 then
object:set_animation({x=1, y=1}, 1, 0)
elseif cart.dir.y == 1 then
object:set_animation({x=2, y=2}, 1, 0)
else
object:set_animation({x=0, y=0}, 1, 0)
end
if cart.dir.x < 0 then
object:setyaw(math.pi / 2)
elseif cart.dir.x > 0 then
object:setyaw(3 * math.pi / 2)
elseif cart.dir.z < 0 then
object:setyaw(math.pi)
elseif cart.dir.z > 0 then
object:setyaw(0)
end
object:setvelocity(cart.vel)
object:setacceleration(cart.acc)
end
return time
end
minetest.register_globalstep(function(dtime)
for _, cart in pairs(railcart.allcarts) do
cart:on_step(dtime)
end
railcart.timer = railcart.timer + dtime
if railcart.timer > OBJECT_SAVE_TIME then
railcart:save()
railcart.timer = 0
end
end)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

Before

Width:  |  Height:  |  Size: 114 B

After

Width:  |  Height:  |  Size: 114 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 B

View File

@ -0,0 +1,14 @@
Minetest Mod - Railtrack [railtrack]
====================================
License Source Code: LGPL v2.1
License of media (textures, sounds and models not otherwise specified): CC-0
Authors of media files:
-----------------------
rarkenin:
cart_rail_*.png

View File

@ -0,0 +1,72 @@
Minetest Mod - Railtrack [railtrack]
====================================
Minetest version: 0.4.13
Depends: default
Proof of concept rail networking system which enables rail-carts to travel
through unloaded map chunks.
Please note, this mod makes heavy use of metadata so that much of the processing
gets done as tracks are laid, for this reason a 'rails' privilege is required in
order to place rails when using multiplayer mode.
Crafting
--------
R = Rail [default:rail]
F = Mese Crystal Fragment [default:mese_crystal_fragment]
C = Coal Lump [default:coal_lump]
D = Diamond [default:diamond]
M = Mese Block [default:mese]
Powered Rail: [railtrack:powerrail]
By default these rails apply a positive acceleration during the time a cart
remains on a given section of track. When used with the mesecons mod the rails
will require power from a mesecon source to become active.
+---+---+---+
| R | F | R |
+---+---+---+
Braking Rail: [railtrack:brakerail]
By default these rails apply a negative acceleration during the time a cart
remains on a given section of track. When used with the mesecons mod the rails
will require power from a mesecon source to become active.
+---+---+---+
| R | C | R |
+---+---+---+
Superconducting Rail: [railtrack:superrail]
Zero friction rails that are easier to manage and are also a little less
cpu-intensive by avoiding the use of square root calculations.
+---+---+---+
| R | D | R |
+---+---+---+
Switching Rail: [railtrack:switchrail]
Currently depends on mesecons to do much other than provide a convenient, zero
friction union to join long sections of superconducting rails.
+---+---+---+
| R | M | R |
+---+---+---+
Misc Items
----------
Rail Fixer: [railtrack:fixer]
Only available in creative menu or with give(me) privileges.
Rail Inspector [railtrack:inspector]
Only available in creative menu or with give(me) privileges.

View File

@ -0,0 +1 @@
default

View File

@ -0,0 +1,200 @@
local modpath = minetest.get_modpath(minetest.get_current_modname())
dofile(modpath.."/railtrack.lua")
railtrack:register_rail(":default:rail", {
description = "Rail",
tiles = {"default_rail.png", "default_rail_curved.png",
"default_rail_t_junction.png", "default_rail_crossing.png"},
railtype = "rail",
})
railtrack:register_rail("railtrack:superrail", {
description = "Superconducting Rail",
tiles = {"carts_rail_sup.png", "carts_rail_curved_sup.png",
"carts_rail_t_junction_sup.png", "carts_rail_crossing_sup.png"},
railtype = "superrail",
acceleration = 0,
})
railtrack:register_rail("railtrack:powerrail", {
description = "Powered Rail",
tiles = {"carts_rail_pwr.png", "carts_rail_curved_pwr.png",
"carts_rail_t_junction_pwr.png", "carts_rail_crossing_pwr.png"},
railtype = "powerrail",
acceleration = 4,
mesecons = {
effector = {
action_on = function(pos, node)
railtrack:set_acceleration(pos, 4)
end,
action_off = function(pos, node)
railtrack:set_acceleration(pos, nil)
end,
},
},
})
railtrack:register_rail("railtrack:brakerail", {
description = "Braking Rail",
tiles = {"carts_rail_brk.png", "carts_rail_curved_brk.png",
"carts_rail_t_junction_brk.png", "carts_rail_crossing_brk.png"},
railtype = "brakerail",
acceleration = -4,
mesecons = {
effector = {
action_on = function(pos, node)
railtrack:set_acceleration(pos, -4)
end,
action_off = function(pos, node)
railtrack:set_acceleration(pos, nil)
end,
},
},
})
railtrack:register_rail("railtrack:switchrail", {
description = "Switching Rail",
tiles = {"carts_rail_swt.png", "carts_rail_curved_swt.png",
"carts_rail_t_junction_swt.png", "carts_rail_crossing_swt.png"},
railtype = "switchrail",
acceleration = 0,
mesecons = {
effector = {
action_on = function(pos, node)
local meta = minetest.get_meta(pos)
meta:set_string("rotations", "RFLB")
end,
action_off = function(pos, node)
local meta = minetest.get_meta(pos)
meta:set_string("rotations", nil)
end,
},
},
})
minetest.register_privilege("rails", "Player can dig and place rails.")
minetest.register_tool("railtrack:fixer", {
description = "Rail Fixer",
inventory_image = "railtrack_fixer.png",
wield_image = "railtrack_fixer.png",
on_use = function(itemstack, user, pointed_thing)
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
local name = user:get_player_name()
if not pos or not name or pointed_thing.type ~= "node" then
return
end
if not railtrack:is_railnode(pos) then
minetest.chat_send_player(name, "Not a rail node!")
return
end
if not minetest.is_singleplayer() then
if not minetest.check_player_privs(name, {rails=true}) then
minetest.chat_send_player(name, "Requires rails privilege")
return
end
end
local node = minetest.get_node(pos)
if node then
minetest.remove_node(pos)
minetest.set_node(pos, node)
local def = minetest.registered_items[node.name] or {}
local itemstack = ItemStack(node.name)
if type(def.after_place_node) == "function" then
def.after_place_node(pos, user, itemstack)
end
end
end,
})
minetest.register_tool("railtrack:inspector", {
description = "Rail Inspector",
inventory_image = "railtrack_inspector.png",
wield_image = "railtrack_inspector.png",
on_use = function(itemstack, user, pointed_thing)
local name = user:get_player_name()
local pos = minetest.get_pointed_thing_position(pointed_thing, false)
if not name or not pos then
return
end
local node = minetest.get_node(pos) or {}
if not railtrack:is_railnode(pos) or not node.name then
minetest.chat_send_player(name, "Not a rail node!")
return
end
local ref = minetest.registered_items[node.name] or {}
local meta = minetest.get_meta(pos)
local form = ""
local size = 2.5
form = form.."label[0.5,0.5;POS: "..minetest.pos_to_string(pos).."]"
local railtype = ref.railtype or "NIL"
form = form.."label[0.5,1.0;RAILTYPE: "..railtype.."]"
local contype = meta:get_string("contype") or "NIL"
form = form.."label[0.5,1.5;CONTYPE: "..contype.."]"
local accel = meta:get_string("acceleration") or "NIL"
form = form.."label[0.5,2.0;ACCEL: "..accel.."]"
local s_junc = meta:get_string("junctions")
if s_junc then
local junctions = minetest.deserialize(s_junc)
if junctions then
form = form.."label[0.5,2.5;JUNCTIONS:]"
for i, p in ipairs(junctions) do
size = size + 0.5
form = form.."label[0.5,"..size..";#"..i.." "
..minetest.pos_to_string(p).."]"
end
end
end
local s_cons = meta:get_string("connections")
if s_cons then
local cons = minetest.deserialize(s_cons)
if cons then
size = size + 0.5
form = form.."label[0.5,"..size..";CONNECTIONS:]"
for i, p in pairs(cons) do
size = size + 0.5
form = form.."label[0.5,"..size..";#"..i.." "
..minetest.pos_to_string(p).."]"
end
end
end
local s_rots = meta:get_string("rotations")
if s_rots then
size = size + 0.5
form = form.."label[0.5,"..size..";ROTATIONS: "..s_rots.."]"
end
form = form.."button_exit[3.0,"..(size + 1)..";2,0.5;;Ok]"
form = "size[8,"..(size + 2).."]"..form
minetest.show_formspec(name, "info", form)
end,
})
minetest.register_craft({
output = "railtrack:powerrail 2",
recipe = {
{"default:rail", "default:mese_crystal_fragment", "default:rail"},
}
})
minetest.register_craft({
output = "railtrack:brakerail 2",
recipe = {
{"default:rail", "default:coal_lump", "default:rail"},
}
})
minetest.register_craft({
output = "railtrack:switchrail 2",
recipe = {
{"default:rail", "default:mese", "default:rail"},
}
})
minetest.register_craft({
output = "railtrack:superrail 2",
recipe = {
{"default:rail", "default:diamond", "default:rail"},
}
})

View File

@ -0,0 +1,288 @@
local MAX_SECTION_LEN = 20
railtrack = {
rotations = "FLR",
accel_flat = -0.5,
accel_up = -2,
accel_down = 2,
}
railtrack.default_rail = {
description = "Rail",
drawtype = "raillike",
tiles = {"default_rail.png", "default_rail_curved.png",
"default_rail_t_junction.png", "default_rail_crossing.png"},
paramtype = "light",
sunlight_propagates = true,
walkable = false,
is_ground_content = false,
selection_box = {
type = "fixed",
fixed = {-1/2, -1/2, -1/2, 1/2, -1/2+1/16, 1/2},
},
groups = {bendy = 2, dig_immediate = 2, attached_node = 1,
connect_to_raillike = minetest.raillike_group("rail")},
railtype = "rail",
after_place_node = function(pos, placer, itemstack)
local meta = minetest.get_meta(pos)
local def = itemstack:get_definition() or {}
if def.acceleration then
meta:set_string("acceleration", def.acceleration)
end
local junc = {}
local contype = meta:get_string("contype") or ""
local s_cons = meta:get_string("connections") or ""
if contype == "section" then
railtrack:limit_section_len(placer, pos, meta)
elseif s_cons ~= "" then
local cons = minetest.deserialize(s_cons)
for _, con in pairs(cons) do
if railtrack:limit_section_len(placer, con) then
break
end
end
end
end,
on_construct = function(pos)
railtrack:update_rails(pos)
end,
after_destruct = function(pos, oldnode)
local cons = railtrack:get_connections(pos)
for _, p in pairs(cons) do
railtrack:update_rails(p)
end
end,
}
function railtrack:copy(t)
if type(t) ~= "table" then
return t
end
local copy = {}
for k, v in pairs(t) do
copy[k] = v
end
return copy
end
function railtrack:register_rail(name, def)
local udef = {}
for k, v in pairs(railtrack.default_rail) do
if not def[k] then
def[k] = railtrack:copy(v)
end
udef[k] = railtrack:copy(def[k])
end
def.inventory_image = def.inventory_image or def.tiles[1]
def.wield_image = def.wield_image or def.tiles[1]
minetest.register_node(name, def)
udef.drop = name
udef.railtype = udef.railtype.."_union"
udef.groups.not_in_creative_inventory=1
minetest.register_node(name.."_union", udef)
end
function railtrack:limit_section_len(player, pos, meta)
meta = meta or minetest.get_meta(pos)
local contype = meta:get_string("contype") or ""
if contype == "section" then
local s_junc = meta:get_string("junctions") or ""
if s_junc ~= "" then
local junc = minetest.deserialize(s_junc)
if #junc == 2 then
local dist = railtrack:get_distance(junc[1], junc[2])
if dist > MAX_SECTION_LEN then
local node = minetest.get_node(pos) or {}
if node.name then
minetest.swap_node(pos, {name=node.name.."_union"})
railtrack:update_rails(pos)
end
end
end
end
end
end
function railtrack:is_railnode(pos)
local node = minetest.get_node(pos)
if node then
return minetest.get_item_group(node.name, "connect_to_raillike") > 0
end
end
function railtrack:get_sign(z)
if z == 0 then
return 0
else
return z / math.abs(z)
end
end
function railtrack:get_rotations(s_rots, dir)
local rots = {}
for i = 1, string.len(s_rots) do
local r = string.sub(s_rots, i, i)
local rot = nil
if r == "F" then
rot = {x=dir.x, z=dir.z}
elseif r == "L" then
rot = {x=-dir.z, z=dir.x}
elseif r == "R" then
rot = {x=dir.z, z=-dir.x}
elseif r == "B" then
rot = {x=-dir.x, z=-dir.z}
end
if rot then
table.insert(rots, rot)
end
end
return rots
end
function railtrack:get_acceleration(pos)
local meta = minetest.get_meta(pos)
local accel = meta:get_string("acceleration") or ""
if accel ~= "" then
return tonumber(accel)
end
end
function railtrack:get_direction(p1, p2)
local v = vector.subtract(p1, p2)
return {
x = railtrack:get_sign(v.x),
y = railtrack:get_sign(v.y),
z = railtrack:get_sign(v.z),
}
end
function railtrack:get_distance(p1, p2)
local dx = p1.x - p2.x
local dz = p1.z - p2.z
return math.abs(dx) + math.abs(dz)
end
function railtrack:get_railtype(pos)
local node = minetest.get_node(pos) or {}
if node.name then
local ref = minetest.registered_items[node.name] or {}
return ref.railtype
end
end
function railtrack:get_connection_type(pos, cons)
local railtype = railtrack:get_railtype(pos)
if #cons == 0 then
return "single"
elseif #cons == 1 then
return "junction"
elseif #cons == 2 then
if cons[1].x == cons[2].x or cons[1].z == cons[2].z then
if (cons[1].y == cons[2].y and cons[1].y == pos.y) or
(math.abs(cons[1].y - cons[2].y) == 2) then
if railtype == railtrack:get_railtype(cons[1]) and
railtype == railtrack:get_railtype(cons[2]) then
return "section"
end
end
end
end
return "junction"
end
function railtrack:get_connections(pos)
local connections = {}
for y = 1, -1, -1 do
for x = -1, 1 do
for z = -1, 1 do
if math.abs(x) ~= math.abs(z) then
local p = vector.add(pos, {x=x, y=y, z=z})
if railtrack:is_railnode(p) then
table.insert(connections, p)
end
end
end
end
end
return connections
end
function railtrack:get_junctions(pos, last_pos, junctions)
junctions = junctions or {}
local cons = railtrack:get_connections(pos)
local contype = railtrack:get_connection_type(pos, cons)
if contype == "junction" then
table.insert(junctions, pos)
elseif contype == "section" then
if last_pos then
for i, p in pairs(cons) do
if vector.equals(p, last_pos) then
cons[i] = nil
end
end
end
for _, p in pairs(cons) do
railtrack:get_junctions(p, pos, junctions)
end
end
return junctions
end
function railtrack:set_acceleration(pos, accel)
local meta = minetest.get_meta(pos)
local contype = meta:get_string("contype")
if contype == "section" then
local s_junc = meta:get_string("junctions") or ""
local junc = minetest.deserialize(s_junc) or {}
if #junc == 2 then
local p = vector.new(junc[2])
local dir = railtrack:get_direction(junc[1], junc[2])
local dist = railtrack:get_distance(junc[1], junc[2])
for i = 0, dist do
local m = minetest.get_meta(p)
if m then
m:set_string("acceleration", tostring(accel))
end
p = vector.add(dir, p)
end
end
else
meta:set_string("acceleration", tostring(accel))
end
end
function railtrack:update_rails(pos, last_pos, level)
local connections = {}
local junctions = {}
local meta = minetest.get_meta(pos)
local cons = railtrack:get_connections(pos)
local contype = railtrack:get_connection_type(pos, cons)
level = level or 0
for i, p in pairs(cons) do
connections[i] = p
end
if contype == "junction" then
level = level + 1
end
if contype == "section" or level < 2 then
if last_pos then
for i, p in pairs(cons) do
if vector.equals(p, last_pos) then
cons[i] = nil
end
end
end
for _, p in pairs(cons) do
railtrack:update_rails(p, pos, level)
end
end
if contype == "section" then
junctions = railtrack:get_junctions(pos)
connections = {}
end
meta:set_string("connections", minetest.serialize(connections))
meta:set_string("junctions", minetest.serialize(junctions))
meta:set_string("contype", contype)
end

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 385 B

View File

Before

Width:  |  Height:  |  Size: 392 B

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 392 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B

View File

Before

Width:  |  Height:  |  Size: 381 B

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

View File

Before

Width:  |  Height:  |  Size: 441 B

After

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 441 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 383 B

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