From 30dd71ea5a0ec1be65d664941037ab2fd1ba4e4e Mon Sep 17 00:00:00 2001 From: orwell96 Date: Sun, 28 Aug 2016 20:59:54 +0200 Subject: Add a platform node, make some nodes (esp. fences) not blocking trains, implement benchmarking better and optimize some things --- depends.txt | 1 + init.lua | 4 +- misc_nodes.lua | 61 ++++++++++++++++++ textures/advtrains_platform.png | Bin 0 -> 193 bytes trackplacer.lua | 1 + tracks.lua | 1 + trainlogic.lua | 136 ++++++++++++++++++++++++++++------------ wagons.lua | 2 +- 8 files changed, 163 insertions(+), 43 deletions(-) create mode 100644 depends.txt create mode 100644 misc_nodes.lua create mode 100644 textures/advtrains_platform.png diff --git a/depends.txt b/depends.txt new file mode 100644 index 0000000..331d858 --- /dev/null +++ b/depends.txt @@ -0,0 +1 @@ +default \ No newline at end of file diff --git a/init.lua b/init.lua index 64b41a6..3633491 100644 --- a/init.lua +++ b/init.lua @@ -20,4 +20,6 @@ dofile(advtrains.modpath.."/wagons.lua") dofile(advtrains.modpath.."/pseudoload.lua"); dofile(advtrains.modpath.."/couple.lua"); -dofile(advtrains.modpath.."/damage.lua"); \ No newline at end of file +dofile(advtrains.modpath.."/damage.lua"); + +dofile(advtrains.modpath.."/misc_nodes.lua"); diff --git a/misc_nodes.lua b/misc_nodes.lua new file mode 100644 index 0000000..3e4742c --- /dev/null +++ b/misc_nodes.lua @@ -0,0 +1,61 @@ +--all nodes that do not fit in any other category + +function advtrains.register_platform(preset) + local ndef=minetest.registered_nodes[preset] + if not ndef then + minetest.log("warning", "[advtrains] register_platform couldn't find preset node "..preset) + return + end + minetest.log("action", dump(ndef)) + local btex=ndef.tiles + if type(btex)=="table" then + btex=btex[1] + end + local desc=ndef.description or "" + local nodename=string.match(preset, ":(.+)$") + minetest.register_node("advtrains:platform_low_"..nodename, { + description = desc.." Platform (low)", + tiles = {btex.."^advtrains_platform.png", btex, btex, btex, btex, btex}, + groups = {cracky = 1, not_blocking_trains = 1}, + sounds = default.node_sound_stone_defaults(), + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.5, -0.1, -0.1, 0.5, 0 , 0.5}, + {-0.5, -0.5, 0 , 0.5, -0.1, 0.5} + }, + }, + paramtype2="facedir", + paramtype = "light", + sunlight_propagates = true, + }) + minetest.register_node("advtrains:platform_high_"..nodename, { + description = desc.." Platform (high)", + tiles = {btex.."^advtrains_platform.png", btex, btex, btex, btex, btex}, + groups = {cracky = 1, not_blocking_trains = 1}, + sounds = default.node_sound_stone_defaults(), + drawtype = "nodebox", + node_box = { + type = "fixed", + fixed = { + {-0.5, 0.3, -0.1, 0.5, 0.5, 0.5}, + {-0.5, -0.5, 0 , 0.5, 0.3, 0.5} + }, + }, + paramtype2="facedir", + paramtype = "light", + sunlight_propagates = true, + }) +end + +minetest.register_abm({ + name = "advtrains:platform_high", + -- In the following two fields, also group:groupname will work. + nodenames = {"advtrains:platform_high"}, + interval=1, + chance=1, + action = function(pos, node, active_object_count, active_object_count_wider) minetest.set_node(pos, {name="advtrains:platform_high_stonebrick", param2=node.param2}) end, + }) + +advtrains.register_platform("default:stonebrick") diff --git a/textures/advtrains_platform.png b/textures/advtrains_platform.png new file mode 100644 index 0000000..5ba9663 Binary files /dev/null and b/textures/advtrains_platform.png differ diff --git a/trackplacer.lua b/trackplacer.lua index 7f04f93..a864b35 100644 --- a/trackplacer.lua +++ b/trackplacer.lua @@ -144,6 +144,7 @@ function tp.register_track_placer(nnprefix, imgprefix, dispname) description = dispname, inventory_image = imgprefix.."_placer.png", wield_image = imgprefix.."_placer.png", + groups={}, on_place = function(itemstack, placer, pointed_thing) if pointed_thing.type=="node" then local pos=pointed_thing.above diff --git a/tracks.lua b/tracks.lua index 34c4e38..d64f6d8 100644 --- a/tracks.lua +++ b/tracks.lua @@ -173,6 +173,7 @@ function advtrains.register_tracks(tracktype, def, preset) ["advtrains_track_"..tracktype]=1, dig_immediate=2, not_in_creative_inventory=(not in_creative_inv and 1 or nil), + not_blocking_trains=1, }, } end diff --git a/trainlogic.lua b/trainlogic.lua index c8c4b9d..71d7086 100644 --- a/trainlogic.lua +++ b/trainlogic.lua @@ -3,14 +3,41 @@ local print=function(t, ...) minetest.log("action", table.concat({t, ...}, " ")) minetest.chat_send_all(table.concat({t, ...}, " ")) end +local benchmark=false --printbm=function(str, t) print("[advtrains]"..str.." "..((os.clock()-t)*1000).."ms") end -printbm=function() end +local bm={} +local bmlt=0 +local bmsteps=0 +local bmstepint=200 +printbm=function(action, ta) + if not benchmark then return end + local t=(os.clock()-ta)*1000 + if not bm[action] then + bm[action]=t + else + bm[action]=bm[action]+t + end + bmlt=bmlt+t +end +function endstep() + if not benchmark then return end + bmsteps=bmsteps-1 + if bmsteps<=0 then + bmsteps=bmstepint + for key, value in pairs(bm) do + minetest.chat_send_all(key.." "..(value/bmstepint).." ms avg.") + end + minetest.chat_send_all("Total time consumed by all advtrains actions per step: "..(bmlt/bmstepint).." ms avg.") + bm={} + bmlt=0 + end +end advtrains.train_accel_force=2--per second and divided by number of wagons advtrains.train_brake_force=3--per second, not divided by number of wagons advtrains.train_emerg_force=10--for emergency brakes(when going off track) -advtrains.audit_interval=10 +advtrains.audit_interval=30 advtrains.all_traintypes={} function advtrains.register_train_type(name, drives_on, max_speed) @@ -127,16 +154,21 @@ minetest.register_globalstep(function(dtime) advtrains.train_step(k, v, dtime) end printbm("trainsteps", t) + endstep() end) function advtrains.train_step(id, train, dtime) --TODO check for all vars to be present - + if not train.velocity then + train.velocity=0 + end --very unimportant thing: check if couple is here if train.couple_eid_front and (not minetest.luaentities[train.couple_eid_front] or not minetest.luaentities[train.couple_eid_front].is_couple) then train.couple_eid_front=nil end if train.couple_eid_back and (not minetest.luaentities[train.couple_eid_back] or not minetest.luaentities[train.couple_eid_back].is_couple) then train.couple_eid_back=nil end + --skip certain things (esp. collision) when not moving + local train_moves=train.velocity~=0 --if not train.last_pos then advtrains.trains[id]=nil return end @@ -170,49 +202,47 @@ function advtrains.train_step(id, train, dtime) if train.tarvelocity<0 then train.tarvelocity=0 end end - if not train.velocity then - train.velocity=0 - end - --check for collisions by finding objects - --front - local search_radius=4 - - --coupling - local couple_outward=1 - local posfront=advtrains.get_real_index_position(path, train.index+couple_outward) - local posback=advtrains.get_real_index_position(path, train_end_index-couple_outward) - for _,pos in ipairs({posfront, posback}) do - if pos then - local objrefs=minetest.get_objects_inside_radius(pos, search_radius) + if train_moving then + --check for collisions by finding objects + --front + local search_radius=4 + + --coupling + local couple_outward=1 + local posfront=advtrains.get_real_index_position(path, train.index+couple_outward) + local posback=advtrains.get_real_index_position(path, train_end_index-couple_outward) + for _,pos in ipairs({posfront, posback}) do + if pos then + local objrefs=minetest.get_objects_inside_radius(pos, search_radius) + for _,v in pairs(objrefs) do + local le=v:get_luaentity() + if le and le.is_wagon and le.initialized and le.train_id~=id then + advtrains.try_connect_trains(id, le.train_id) + end + end + end + end + --new train collisions (only search in the direction of the driving train) + local coll_search_radius=2 + local coll_grace=0 + local collpos + if train.velocity>0 then + collpos=advtrains.get_real_index_position(path, train.index-coll_grace) + elseif train.velocity<0 then + collpos=advtrains.get_real_index_position(path, train_end_index+coll_grace) + end + if collpos then + local objrefs=minetest.get_objects_inside_radius(collpos, coll_search_radius) for _,v in pairs(objrefs) do local le=v:get_luaentity() if le and le.is_wagon and le.initialized and le.train_id~=id then - advtrains.try_connect_trains(id, le.train_id) + train.recently_collided_with_env=true + train.velocity=-0.5*train.velocity + train.tarvelocity=0 end end end end - --new train collisions (only search in the direction of the driving train) - local coll_search_radius=2 - local coll_grace=0 - local collpos - if train.velocity>0 then - collpos=advtrains.get_real_index_position(path, train.index-coll_grace) - elseif train.velocity<0 then - collpos=advtrains.get_real_index_position(path, train_end_index+coll_grace) - end - if collpos then - local objrefs=minetest.get_objects_inside_radius(collpos, coll_search_radius) - for _,v in pairs(objrefs) do - local le=v:get_luaentity() - if le and le.is_wagon and le.initialized and le.train_id~=id then - train.recently_collided_with_env=true - train.velocity=-0.5*train.velocity - train.tarvelocity=0 - end - end - end - --check for any trainpart entities if they have been unloaded. do this only if train is near a player, to not spawn entities into unloaded areas train.check_trainpartload=(train.check_trainpartload or 0)-dtime local node_range=(math.max((minetest.setting_get("active_block_range") or 0),1)*16) @@ -257,14 +287,14 @@ function advtrains.train_step(id, train, dtime) end end end - train.check_trainpartload=2 + train.check_trainpartload=10 end --handle collided_with_env if train.recently_collided_with_env then train.tarvelocity=0 - if train.velocity==0 then + if not train_moving then train.recently_collided_with_env=false--reset status when stopped end end @@ -741,3 +771,27 @@ function advtrains.invalidate_all_paths() v.max_index_on_track=nil end end + +--not blocking trains group +function advtrains.train_collides(node) + if node and minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].walkable then + if not minetest.registered_nodes[node.name].groups.not_blocking_trains then + return true + end + end + return false +end + +local nonblocknodes={ + "default:fence_wood", + "default:torch", + "default:sign_wall", + "signs:sign_post", +} +minetest.after(0, function() + for _,name in ipairs(nonblocknodes) do + if minetest.registered_nodes[name] then + minetest.registered_nodes[name].groups.not_blocking_trains=1 + end + end +end) diff --git a/wagons.lua b/wagons.lua index 038c448..6ad2ffa 100644 --- a/wagons.lua +++ b/wagons.lua @@ -246,7 +246,7 @@ function wagon:on_step(dtime) for y=0,2 do for z=-1,1 do local node=minetest.get_node_or_nil(vector.add(first_pos, {x=x, y=y, z=z})) - if node and minetest.registered_nodes[node.name] and minetest.registered_nodes[node.name].walkable then + if (advtrains.train_collides(node)) then collides=true end end -- cgit v1.2.3