From a7bd6e96afa02e4bddfbd105e31616900be2edfb Mon Sep 17 00:00:00 2001 From: orwell96 Date: Wed, 1 Jun 2016 11:24:39 +0200 Subject: [PATCH] re-implement train collisions --- trainlogic.lua | 75 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 50 insertions(+), 25 deletions(-) diff --git a/trainlogic.lua b/trainlogic.lua index 1ac5dea..561b428 100644 --- a/trainlogic.lua +++ b/trainlogic.lua @@ -172,7 +172,7 @@ function advtrains.train_step(id, train, dtime) 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) + advtrains.try_connect_trains_and_check_collision(id, le.train_id) end end end @@ -182,7 +182,7 @@ function advtrains.train_step(id, train, dtime) 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) + advtrains.try_connect_trains_and_check_collision(id, le.train_id) end end end @@ -231,7 +231,7 @@ function advtrains.train_step(id, train, dtime) end end end - train.check_trainpartload=1 + train.check_trainpartload=2 end @@ -523,37 +523,62 @@ end --->backpos's will match --4. R<->F F<->R flip one of these trains and take it as new parent --->frontpos's will match -function advtrains.try_connect_trains(id1, id2) +function advtrains.try_connect_trains_and_check_collision(id1, id2) local train1=advtrains.trains[id1] local train2=advtrains.trains[id2] if not train1 or not train2 then return end if not train1.path or not train2.path then return end - if train1.traintype~=train2.traintype then - --TODO implement collision without connection - return - end 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 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)) - - if not frontpos1 or not frontpos2 or not backpos1 or not backpos2 then return end - - --case 1 (first train is front) - if vector.distance(frontpos2, backpos1)<0.5 then - advtrains.spawn_couple_if_neccessary(backpos1, frontpos2, id1, id2, true, false) - --case 2 (second train is front) - elseif vector.distance(frontpos1, backpos2)<0.5 then - advtrains.spawn_couple_if_neccessary(backpos2, frontpos1, id2, id1, true, false) - --case 3 - elseif vector.distance(backpos2, backpos1)<0.5 then - advtrains.spawn_couple_if_neccessary(backpos1, backpos2, id1, id2, true, true) - --case 4 - elseif vector.distance(frontpos2, frontpos1)<0.5 then - advtrains.spawn_couple_if_neccessary(frontpos1, frontpos2, id1, id2, false, false) + --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)) + + if not frontpos1 or not frontpos2 or not backpos1 or not backpos2 then return end + + --case 1 (first train is front) + if vector.distance(frontpos2, backpos1)<0.5 then + advtrains.spawn_couple_if_neccessary(backpos1, frontpos2, id1, id2, true, false) + --case 2 (second train is front) + elseif vector.distance(frontpos1, backpos2)<0.5 then + advtrains.spawn_couple_if_neccessary(backpos2, frontpos1, id2, id1, true, false) + --case 3 + elseif vector.distance(backpos2, backpos1)<0.5 then + advtrains.spawn_couple_if_neccessary(backpos1, backpos2, id1, id2, true, true) + --case 4 + elseif vector.distance(frontpos2, frontpos1)<0.5 then + advtrains.spawn_couple_if_neccessary(frontpos1, frontpos2, id1, id2, false, false) + end end + --check if one train invaded another's critical path area... + if not train1.recently_collided_with_env and not train2.recently_collided_with_env then + --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 + local testpos=advtrains.get_real_index_position(train2.path,i) + if vector.distance(testpos, backpos1) < 0.5 then + --TODO physics + train1.velocity=1 + train2.velocity=-1 + train1.recently_collided_with_env=true + train2.recently_collided_with_env=true + return + end + if vector.distance(testpos, frontpos1) < 0.5 then + train1.velocity=-1 + train2.velocity=1 + train1.recently_collided_with_env=true + train2.recently_collided_with_env=true + return + end + + end + end + end --order of trains may be irrelevant in some cases. check opposite cases. TODO does this work? --pos1 and pos2 are just needed to form a median.