From e449704a92c8c1931fb687e58f095bea27db3ddc Mon Sep 17 00:00:00 2001 From: orwell96 Date: Thu, 2 Jun 2016 14:42:01 +0200 Subject: [PATCH] use real pos-in-train calculation also for trainlen calculation, fix bugs and add damage by trains --- couple.lua | 9 ++++++--- damage.lua | 23 +++++++++++++++++++++++ init.lua | 3 ++- trainlogic.lua | 35 ++++++++++++++++++++++++----------- wagons.lua | 33 ++++++++++++++++++++------------- 5 files changed, 75 insertions(+), 28 deletions(-) create mode 100644 damage.lua diff --git a/couple.lua b/couple.lua index e34969d..ba4949c 100644 --- a/couple.lua +++ b/couple.lua @@ -32,6 +32,7 @@ minetest.register_entity("advtrains:discouple", { advtrains.split_train_at_wagon(self.wagon)--found in trainlogic.lua end, on_step=function(self, dtime) + local t=os.clock() if not self.wagon then self.object:remove() end @@ -42,6 +43,7 @@ minetest.register_entity("advtrains:discouple", { self.object:setvelocity(velocityvec) self.updatepct_timer=2 end + printbm("discouple_step", t) end, }) @@ -93,6 +95,7 @@ minetest.register_entity("advtrains:couple", { self.object:remove() end, on_step=function(self, dtime) + local t=os.clock() if not self.train_id_1 or not self.train_id_2 then print("wtf no train ids?")return end local train1=advtrains.trains[self.train_id_1] local train2=advtrains.trains[self.train_id_2] @@ -105,15 +108,14 @@ minetest.register_entity("advtrains:couple", { if not self.train1_is_backpos then tp1=advtrains.get_real_index_position(train1.path, train1.index) else - tp1=advtrains.get_real_index_position(train1.path, train1.index-(train1.trainlen or 2)) + tp1=advtrains.get_real_index_position(train1.path, advtrains.get_train_end_index(train1)) end local tp2 if not self.train2_is_backpos then tp2=advtrains.get_real_index_position(train2.path, train2.index) else - tp2=advtrains.get_real_index_position(train2.path, train2.index-(train2.trainlen or 2)) + tp2=advtrains.get_real_index_position(train2.path, advtrains.get_train_end_index(train2)) end - local function nilsave_pts(pos) return pos and minetest.pos_to_string(pos) or "nil" end if not tp1 or not tp2 or not (vector.distance(tp1,tp2)<0.5) then self.object:remove() return @@ -123,5 +125,6 @@ minetest.register_entity("advtrains:couple", { self.object:setpos(pos_median) end end + printbm("couple step", t) end, }) diff --git a/damage.lua b/damage.lua new file mode 100644 index 0000000..860feaa --- /dev/null +++ b/damage.lua @@ -0,0 +1,23 @@ +--damage.lua +--a globalstep that damages players overrolled by trains. +local tmr=0 +minetest.register_globalstep(function(dtime) + tmr=tmr-dtime + if tmr<=0 then + + for _, player in pairs(minetest.get_connected_players()) do + local pos=player:getpos() + for _, object in pairs(minetest.get_objects_inside_radius(pos, 1)) do + local le=object:get_luaentity() + if le and le.is_wagon and le.initialized and le:train() then + if le.driver~=player and math.abs(le:train().velocity)>2 then + --player:punch(object, 1000, {damage={fleshy=3*math.abs(le:train().velocity)}}) + player:set_hp(player:get_hp()-math.abs(le:train().velocity)-3) + end + end + end + end + + tmr=0.5 + end +end) diff --git a/init.lua b/init.lua index 5811b4e..64b41a6 100644 --- a/init.lua +++ b/init.lua @@ -19,4 +19,5 @@ dofile(advtrains.modpath.."/tracks.lua") dofile(advtrains.modpath.."/wagons.lua") dofile(advtrains.modpath.."/pseudoload.lua"); -dofile(advtrains.modpath.."/couple.lua"); \ No newline at end of file +dofile(advtrains.modpath.."/couple.lua"); +dofile(advtrains.modpath.."/damage.lua"); \ No newline at end of file diff --git a/trainlogic.lua b/trainlogic.lua index 561b428..de56d4e 100644 --- a/trainlogic.lua +++ b/trainlogic.lua @@ -3,7 +3,10 @@ local print=function(t, ...) minetest.log("action", table.concat({t, ...}, " ")) minetest.chat_send_all(table.concat({t, ...}, " ")) end -advtrains.train_accel_force=5--per second and divided by number of wagons +--printbm=function(str, t) print("[advtrains]"..str.." "..((os.clock()-t)*1000).."ms") end +printbm=function() 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) @@ -100,6 +103,7 @@ advtrains.save_and_audit_timer=advtrains.audit_interval minetest.register_globalstep(function(dtime) advtrains.save_and_audit_timer=advtrains.save_and_audit_timer-dtime if advtrains.save_and_audit_timer<=0 then + local t=os.clock() --print("[advtrains] audit step") --clean up orphaned trains for k,v in pairs(advtrains.trains) do @@ -111,11 +115,14 @@ minetest.register_globalstep(function(dtime) --save advtrains.save() advtrains.save_and_audit_timer=advtrains.audit_interval + printbm("saving", t) end --regular train step + local t=os.clock() for k,v in pairs(advtrains.trains) do advtrains.train_step(k, v, dtime) end + printbm("trainsteps", t) end) function advtrains.train_step(id, train, dtime) @@ -143,9 +150,11 @@ function advtrains.train_step(id, train, dtime) print("train has no path for whatever reason") return end + + local train_end_index=advtrains.get_train_end_index(train) --apply off-track handling: local front_off_track=train.max_index_on_track and train.index>train.max_index_on_track - local back_off_track=train.min_index_on_track and (train.index-train.trainlen)1 then train.tarvelocity=1 end if train.tarvelocity<-1 then train.tarvelocity=-1 end @@ -176,7 +185,7 @@ function advtrains.train_step(id, train, dtime) end end end - local posback=path[math.floor(train.index-(train.trainlen or 0)-1)] + local posback=path[math.floor(train_end_index-1)] if posback then local objrefs=minetest.get_objects_inside_radius(posback, search_radius) for _,v in pairs(objrefs) do @@ -385,7 +394,7 @@ function advtrains.pathpredict(id, train) end local minn=advtrains.minN(train.path) - while (train.index-minn) < (train.trainlen or 0) + 2 do --post_generate. has to be at least trainlen. + while (train.index-minn) < (train.trainlen or 0) + 2 do --post_generate. has to be at least trainlen. (we let go of the exact calculation here since this would be unuseful here) --print("[advtrains]minn conway for ",minn,minetest.pos_to_string(path[minn]),minn+1,minetest.pos_to_string(path[minn+1])) local conway=advtrains.conway(train.path[minn], train.path[minn+1], train.traintype) if conway then @@ -421,6 +430,9 @@ function advtrains.pathpredict(id, train) end return train.path end +function advtrains.get_train_end_index(train) + return advtrains.get_real_path_index(train, train.trainlen or 2)--this function can be found inside wagons.lua since it's more related to wagons. we just set trainlen as pos_in_train +end function advtrains.get_or_create_path(id, train) if not train.path then return advtrains.pathpredict(id, train) end @@ -473,8 +485,9 @@ end function advtrains.split_train_at_wagon(wagon) --get train local train=advtrains.trains[wagon.train_id] - local pos_for_new_train=advtrains.get_or_create_path(wagon.train_id, train)[math.floor((train.index or 0)-wagon.pos_in_train+wagon.wagon_span)] - local pos_for_new_train_prev=advtrains.get_or_create_path(wagon.train_id, train)[math.floor((train.index or 0)-wagon.pos_in_train-1+wagon.wagon_span)] + local real_pos_in_train=advtrains.get_real_path_index(train, wagon.pos_in_train) + local pos_for_new_train=advtrains.get_or_create_path(wagon.train_id, train)[math.floor(real_pos_in_train+wagon.wagon_span)] + local pos_for_new_train_prev=advtrains.get_or_create_path(wagon.train_id, train)[math.floor(real_pos_in_train-1+wagon.wagon_span)] --before doing anything, check if both are rails. else do not allow if not pos_for_new_train then @@ -531,11 +544,11 @@ function advtrains.try_connect_trains_and_check_collision(id1, id2) if #train1.trainparts==0 or #train2.trainparts==0 then return end local frontpos1=advtrains.get_real_index_position(train1.path, train1.index) - local backpos1=advtrains.get_real_index_position(train1.path, train1.index-(train1.trainlen or 2)) + local backpos1=advtrains.get_real_index_position(train1.path, advtrains.get_train_end_index(train1)) --couple logic if train1.traintype==train2.traintype then local frontpos2=advtrains.get_real_index_position(train2.path, train2.index) - local backpos2=advtrains.get_real_index_position(train2.path, train2.index-(train2.trainlen or 2)) + local backpos2=advtrains.get_real_index_position(train2.path, advtrains.get_train_end_index(train2)) if not frontpos1 or not frontpos2 or not backpos1 or not backpos2 then return end @@ -558,7 +571,7 @@ function advtrains.try_connect_trains_and_check_collision(id1, id2) --try to find one of these inside the other train's path --iterated start and end numbers are decimal values, since lua should count i up by one each iteration, this should be no problem. --0.5: some grace interval, since else the couple entity does not appear - for i=(train2.index-(train2.trainlen or 2))+0.5,train2.index-0.5 do + for i=(advtrains.get_train_end_index(train2)+0.5),train2.index-0.5 do local testpos=advtrains.get_real_index_position(train2.path,i) if vector.distance(testpos, backpos1) < 0.5 then --TODO physics @@ -667,7 +680,7 @@ function advtrains.invert_train(train_id) local old_path=advtrains.get_or_create_path(train_id, train) train.path={} - train.index=-train.index+train.trainlen + train.index= - advtrains.get_train_end_index(train1) train.velocity=-train.velocity train.tarvelocity=-train.tarvelocity for k,v in pairs(old_path) do @@ -693,7 +706,7 @@ function advtrains.is_train_at_pos(pos) local path=advtrains.get_or_create_path(le.train_id, le:train()) if path then --print("has path") - for i=math.floor(le:train().index-le:train().trainlen+0.5),math.floor(le:train().index+0.5) do + for i=math.floor(advtrains.get_train_end_index(le:train())+0.5),math.floor(le:train().index+0.5) do if path[i] then --print("has pathitem "..i.." "..minetest.pos_to_string(path[i])) if vector.equals(advtrains.round_vector_floor_y(path[i]), pos) then diff --git a/wagons.lua b/wagons.lua index 54d41fb..31a07b2 100644 --- a/wagons.lua +++ b/wagons.lua @@ -134,6 +134,7 @@ function wagon:on_punch(puncher, time_from_last_punch, tool_capabilities, direct end function wagon:on_step(dtime) + local t=os.clock() local pos = self.object:getpos() if not self.initialized_pre then print("[advtrains] wagon stepping while not yet initialized_pre, returning") @@ -210,19 +211,7 @@ function wagon:on_step(dtime) return end - local pos_in_train_left=self.pos_in_train+0 - local index=gp.index - if pos_in_train_left>(index-math.floor(index))*(gp.path_dist[math.floor(index)] or 1) then - pos_in_train_left=pos_in_train_left - (index-math.floor(index))*(gp.path_dist[math.floor(index)] or 1) - index=math.floor(index) - while pos_in_train_left>(gp.path_dist[index-1] or 1) do - pos_in_train_left=pos_in_train_left - (gp.path_dist[index-1] or 1) - index=index-1 - end - index=index-(pos_in_train_left/(gp.path_dist[index-1] or 1)) - else - index=index-(pos_in_train_left*(gp.path_dist[math.floor(index-1)] or 1)) - end + local index=advtrains.get_real_path_index(self:train(), self.pos_in_train) --print("trainindex "..gp.index.." wagonindex "..index) --position recalculation @@ -283,6 +272,24 @@ function wagon:on_step(dtime) self.old_velocity_vector=velocityvec self.old_yaw=yaw + printbm("wagon step", t) +end + +function advtrains.get_real_path_index(train, pit) + local pos_in_train_left=pit + local index=train.index + if pos_in_train_left>(index-math.floor(index))*(train.path_dist[math.floor(index)] or 1) then + pos_in_train_left=pos_in_train_left - (index-math.floor(index))*(train.path_dist[math.floor(index)] or 1) + index=math.floor(index) + while pos_in_train_left>(train.path_dist[index-1] or 1) do + pos_in_train_left=pos_in_train_left - (train.path_dist[index-1] or 1) + index=index-1 + end + index=index-(pos_in_train_left/(train.path_dist[index-1] or 1)) + else + index=index-(pos_in_train_left*(train.path_dist[math.floor(index-1)] or 1)) + end + return index end