aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authororwell96 <mono96.mml@gmail.com>2017-02-09 00:11:28 +0100
committerorwell96 <mono96.mml@gmail.com>2017-02-09 00:13:36 +0100
commit3f382974b85c99fdd9b985cba20b19dded42dd6b (patch)
tree1bc84065dbdeddb57f701c1255901b4219a76f0b
parent4abb967f921c9d965c0746230b0756736f540dd3 (diff)
downloadadvtrains-3f382974b85c99fdd9b985cba20b19dded42dd6b.tar.gz
advtrains-3f382974b85c99fdd9b985cba20b19dded42dd6b.tar.bz2
advtrains-3f382974b85c99fdd9b985cba20b19dded42dd6b.zip
Proper implementation for getting on by walking into train, rework damage and player controls in train, fix death and join bugs, do not spawn bones on death
-rw-r--r--advtrains.zipbin5122262 -> 5122882 bytes
-rw-r--r--advtrains/advtrains/api_doc.txt4
-rw-r--r--advtrains/advtrains/damage.lua28
-rw-r--r--advtrains/advtrains/init.lua5
-rw-r--r--advtrains/advtrains/trainlogic.lua81
-rw-r--r--advtrains/advtrains/wagons.lua102
-rw-r--r--advtrains/advtrains_train_japan/init.lua2
-rw-r--r--advtrains/advtrains_train_subway/init.lua1
8 files changed, 139 insertions, 84 deletions
diff --git a/advtrains.zip b/advtrains.zip
index b668390..6652233 100644
--- a/advtrains.zip
+++ b/advtrains.zip
Binary files differ
diff --git a/advtrains/advtrains/api_doc.txt b/advtrains/advtrains/api_doc.txt
index 09b3cc1..db72dda 100644
--- a/advtrains/advtrains/api_doc.txt
+++ b/advtrains/advtrains/api_doc.txt
@@ -60,6 +60,10 @@ advtrains.register_wagon(name, prototype, description, inventory_image)
[1]={frames={x=60, y=80}, time=1} -- close right doors
}
},
+ door_entry={ 1.5, -1.5 }
+ ^- optional. If defined, defines the locations of the doors on the model as distance from the object center on the path.
+ ^- Getting on by walking in then takes effect.
+ ^- Positive values mean front, negative ones back. Resulting position is automatically shifted to the right side.
wagon_span=2,
^- How far this wagon extends from its base position. Is the half of the wagon length.
diff --git a/advtrains/advtrains/damage.lua b/advtrains/advtrains/damage.lua
deleted file mode 100644
index e05d00d..0000000
--- a/advtrains/advtrains/damage.lua
+++ /dev/null
@@ -1,28 +0,0 @@
---damage.lua
---a globalstep that damages players overrolled by trains.
-
-advtrains.player_to_train_mapping={}
-
-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 (not advtrains.player_to_train_mapping[player:get_player_name()] or le.train_id~=advtrains.player_to_train_mapping[player:get_player_name()]) 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)
- elseif (not advtrains.player_to_train_mapping[player:get_player_name()] or le.train_id~=advtrains.player_to_train_mapping[player:get_player_name()]) and le:train().door_open~=0 then
- le:on_rightclick(player)
- end
- end
- end
- end
-
- tmr=0.5
- end
-end)
diff --git a/advtrains/advtrains/init.lua b/advtrains/advtrains/init.lua
index c60b2f1..970bbb6 100644
--- a/advtrains/advtrains/init.lua
+++ b/advtrains/advtrains/init.lua
@@ -7,7 +7,7 @@ end
--advtrains
-advtrains = {trains={}, wagon_save={}}
+advtrains = {trains={}, wagon_save={}, player_to_train_mapping={}}
advtrains.modpath = minetest.get_modpath("advtrains")
@@ -84,7 +84,6 @@ dofile(advtrains.modpath.."/wagons.lua")
dofile(advtrains.modpath.."/trackdb_legacy.lua")
dofile(advtrains.modpath.."/nodedb.lua")
dofile(advtrains.modpath.."/couple.lua")
-dofile(advtrains.modpath.."/damage.lua")
dofile(advtrains.modpath.."/signals.lua")
dofile(advtrains.modpath.."/misc_nodes.lua")
@@ -105,6 +104,7 @@ else
--congrats, we have the new save format.
advtrains.trains = tbl.trains
advtrains.wagon_save = tbl.wagon_save
+ advtrains.player_to_train_mapping = tbl.ptmap or {}
advtrains.ndb.load_data(tbl.ndb)
advtrains.atc.load_data(tbl.atc)
else
@@ -174,6 +174,7 @@ advtrains.save = function()
local save_tbl={
trains = advtrains.trains,
wagon_save = advtrains.wagon_save,
+ ptmap = advtrains.player_to_train_mapping,
atc = advtrains.atc.save_data(),
ndb = advtrains.ndb.save_data(),
version = 1,
diff --git a/advtrains/advtrains/trainlogic.lua b/advtrains/advtrains/trainlogic.lua
index 5fafb89..0b28129 100644
--- a/advtrains/advtrains/trainlogic.lua
+++ b/advtrains/advtrains/trainlogic.lua
@@ -36,10 +36,9 @@ advtrains.train_brake_force=3--per second, not divided by number of wagons
advtrains.train_roll_force=0.5--per second, not divided by number of wagons, acceleration when rolling without brake
advtrains.train_emerg_force=10--for emergency brakes(when going off track)
-advtrains.audit_interval=10
+advtrains.save_interval=10
+advtrains.save_timer=advtrains.save_interval
-
-advtrains.save_and_audit_timer=advtrains.audit_interval
minetest.register_globalstep(function(dtime_mt)
--limit dtime: if trains move too far in one step, automation may cause stuck and wrongly braking trains
local dtime=dtime_mt
@@ -48,14 +47,23 @@ minetest.register_globalstep(function(dtime_mt)
dtime=0.2
end
- advtrains.save_and_audit_timer=advtrains.save_and_audit_timer-dtime
- if advtrains.save_and_audit_timer<=0 then
+ advtrains.save_timer=advtrains.save_timer-dtime
+ if advtrains.save_timer<=0 then
local t=os.clock()
--save
advtrains.save()
- advtrains.save_and_audit_timer=advtrains.audit_interval
+ advtrains.save_timer=advtrains.save_interval
atprintbm("saving", t)
end
+ --build a table of all players indexed by pts. used by damage and door system.
+ advtrains.playersbypts={}
+ for _, player in pairs(minetest.get_connected_players()) do
+ if not advtrains.player_to_train_mapping[player:get_player_name()] then
+ --players in train are not subject to damage
+ local ptspos=minetest.pos_to_string(vector.round(player:getpos()))
+ advtrains.playersbypts[ptspos]=player
+ end
+ end
--regular train step
-- do in two steps:
-- a: predict path and add all nodes to the advtrains.detector.on_node table
@@ -67,13 +75,48 @@ minetest.register_globalstep(function(dtime_mt)
advtrains.train_step_a(k, v, dtime)
end
for k,v in pairs(advtrains.trains) do
- advtrains.train_step_b(k, v, dtime)
+ advtrains.train_step_b(k, v, dtime, playersbypts)
end
atprintbm("trainsteps", t)
endstep()
end)
+minetest.register_on_joinplayer(function(player)
+ local pname=player:get_player_name()
+ local id=advtrains.player_to_train_mapping[pname]
+ if id then
+ local train=advtrains.trains[id]
+ if not train then advtrains.player_to_train_mapping[pname]=nil return end
+ --set the player to the train position.
+ --minetest will emerge the area and load the objects, which then will call reattach_all().
+ --because player is in mapping, it will not be subject to dying.
+ player:setpos(train.last_pos_prev)
+ --independent of this, cause all wagons of the train which are loaded to reattach their players
+ --needed because already loaded wagons won't call reattach_all()
+ for _,wagon in pairs(minetest.luaentities) do
+ if wagon.is_wagon and wagon.initialized and wagon.train_id==id then
+ wagon:reattach_all()
+ end
+ end
+ end
+end)
+
+minetest.register_on_dieplayer(function(player)
+ local pname=player:get_player_name()
+ local id=advtrains.player_to_train_mapping[pname]
+ if id then
+ local train=advtrains.trains[id]
+ if not train then advtrains.player_to_train_mapping[pname]=nil return end
+ for _,wagon in pairs(minetest.luaentities) do
+ if wagon.is_wagon and wagon.initialized and wagon.train_id==id then
+ --when player dies, detach him from the train
+ --call get_off_plr on every wagon since we don't know which one he's on.
+ wagon:get_off_plr(pname)
+ end
+ end
+ end
+end)
--[[
train step structure:
@@ -440,14 +483,11 @@ end
function advtrains.train_step_b(id, train, dtime)
- --- 8. check for collisions with other trains ---
+ --- 8. check for collisions with other trains and damage players ---
local train_moves=(train.velocity~=0)
if train_moves then
-
- --heh, new collision again.
- --this time, based on NODES and the advtrains.detector.on_node table.
local collpos
local coll_grace=1
if train.movedir==1 then
@@ -460,6 +500,7 @@ function advtrains.train_step_b(id, train, dtime)
for x=-1,1 do
for z=-1,1 do
local testpos=vector.add(rcollpos, {x=x, y=0, z=z})
+ --- 8a Check collision ---
local testpts=minetest.pos_to_string(testpos)
if advtrains.detector.on_node[testpts] and advtrains.detector.on_node[testpts]~=id then
--collides
@@ -470,11 +511,27 @@ function advtrains.train_step_b(id, train, dtime)
train.movedir=train.movedir*-1
train.tarvelocity=0
end
+ --- 8b damage players ---
+ local player=advtrains.playersbypts[testpts]
+ if player and train.velocity>3 then
+ --instantly kill player
+ --drop inventory contents first, to not to spawn bones
+ local player_inv=player:get_inventory()
+ for i=1,player_inv:get_size("main") do
+ minetest.add_item(testpos, player_inv:get_stack("main", i))
+ end
+ for i=1,player_inv:get_size("craft") do
+ minetest.add_item(testpos, player_inv:get_stack("craft", i))
+ end
+ -- empty lists main and craft
+ player_inv:set_list("main", {})
+ player_inv:set_list("craft", {})
+ player:set_hp(0)
+ end
end
end
end
end
-
end
diff --git a/advtrains/advtrains/wagons.lua b/advtrains/advtrains/wagons.lua
index 3efa6b8..461dfb5 100644
--- a/advtrains/advtrains/wagons.lua
+++ b/advtrains/advtrains/wagons.lua
@@ -223,12 +223,13 @@ function wagon:on_step(dtime)
atprint("[wagon "..self.unique_id.."] missing train_id, destroying")
self.object:remove()
return
- elseif not self.initialized then
- self.initialized=true
end
if not self.seatp then
self.seatp={}
end
+
+ --Legacy: remove infotext since it does not work this way anyways
+ self.infotext=nil
--custom on_step function
if self.custom_on_step then
@@ -237,43 +238,38 @@ function wagon:on_step(dtime)
--driver control
for seatno, seat in ipairs(self.seats) do
- if seat.driving_ctrl_access then
- local driver=self.seatp[seatno] and minetest.get_player_by_name(self.seatp[seatno])
- local get_off_pressed=false
- if driver and driver:get_player_control_bits()~=self.old_player_control_bits then
- local pc=driver:get_player_control()
-
+ local driver=self.seatp[seatno] and minetest.get_player_by_name(self.seatp[seatno])
+ if seat.driving_ctrl_access and driver then
+ advtrains.update_driver_hud(driver:get_player_name(), self:train(), self.wagon_flipped)
+ end
+ if driver and driver:get_player_control_bits()~=self.seatpc[seatno] then
+ local pc=driver:get_player_control()
+ self.seatpc[seatno]=driver:get_player_control_bits()
+
+ if seat.driving_ctrl_access then
+ --regular driver stand controls
advtrains.on_control_change(pc, self:train(), self.wagon_flipped)
- if pc.aux1 and pc.sneak then
- get_off_pressed=true
- end
-
- self.old_player_control_bits=driver:get_player_control_bits()
+ else
+ -- If on a passenger seat and doors are open, get off when W or D pressed.
+ local pass = self.seatp[seatno] and minetest.get_player_by_name(self.seatp[seatno])
+ if pass and self:train().door_open~=0 then
+ local pc=pass:get_player_control()
+ if pc.up or pc.down then
+ self:get_off(seatno)
+ end
+ end
end
- if driver then
- if get_off_pressed then
- self:get_off(seatno)
- else
- advtrains.update_driver_hud(driver:get_player_name(), self:train(), self.wagon_flipped)
- end
+ if pc.aux1 and pc.sneak then
+ self:get_off(seatno)
end
- else
- local pass = self.seatp[seatno] and minetest.get_player_by_name(self.seatp[seatno])
- if pass and self:train().door_open~=0 then
- local pc=pass:get_player_control()
- if pc.up or pc.down then
- self:get_off(seatno)
- end
- end
end
end
local gp=self:train()
-
+ local fct=self.wagon_flipped and -1 or 1
--door animation
if self.doors then
if (self.door_anim_timer or 0)<=0 then
- local fct=self.wagon_flipped and -1 or 1
local dstate = (gp.door_open or 0) * fct
if dstate ~= self.door_state then
local at
@@ -299,6 +295,7 @@ function wagon:on_step(dtime)
self.door_anim_timer = (self.door_anim_timer or 0) - dtime
end
end
+
--DisCouple
if self.pos_in_trainparts and self.pos_in_trainparts>1 then
if gp.velocity==0 and not self.lock_couples then
@@ -334,6 +331,31 @@ function wagon:on_step(dtime)
local index=advtrains.get_real_path_index(self:train(), self.pos_in_train)
--atprint("trainindex "..gp.index.." wagonindex "..index)
+ --automatic get_on
+ --needs to know index and path
+ if self.door_entry and gp.door_open and gp.door_open~=0 and gp.velocity==0 then
+ --using the mapping created by the trainlogic globalstep
+ for i, ino in ipairs(self.door_entry) do
+ --fct is the flipstate flag from door animation above
+ local aci = index + ino*fct
+ local ix1=gp.path[math.floor(aci)]
+ local ix2=gp.path[math.floor(aci+1)]
+ -- the two wanted positions are ix1 and ix2 + (2nd-1st rotated by 90deg)
+ -- (x z) rotated by 90deg is (-z x) (http://stackoverflow.com/a/4780141)
+ local add = { x = (ix2.z-ix1.z)*gp.door_open, y = 0, z = (ix1.x-ix2.x)*gp.door_open }
+ local pts1=minetest.pos_to_string(vector.round(vector.add(ix1, add)))
+ local pts2=minetest.pos_to_string(vector.round(vector.add(ix2, add)))
+
+ if advtrains.playersbypts[pts1] then
+ self:on_rightclick(advtrains.playersbypts[pts1])
+ end
+ if advtrains.playersbypts[pts2] then
+ self:on_rightclick(advtrains.playersbypts[pts2])
+ end
+
+ end
+ end
+
--position recalculation
local first_pos=gp.path[math.floor(index)]
local second_pos=gp.path[math.floor(index)+1]
@@ -490,6 +512,8 @@ function wagon:on_rightclick(clicker)
self:get_off(no)
end
else
+ --do not attach if already on a train
+ if advtrains.player_to_train_mapping[pname] then return end
if self.seat_groups then
if #self.seats==0 then
if self.has_inventory and self.get_inventory_formspec then
@@ -518,9 +542,9 @@ function wagon:on_rightclick(clicker)
end
function wagon:get_on(clicker, seatno)
- if not self.seatp then
- self.seatp={}
- end
+ if not self.seatp then self.seatp={}end
+ if not self.seatpc then self.seatpc={}end--player controls in driver stands
+
if not self.seats[seatno] then return end
local oldno=self:get_seatno(clicker:get_player_name())
if oldno then
@@ -535,6 +559,7 @@ function wagon:get_on(clicker, seatno)
end
atprint("get_on: attaching",clicker:get_player_name())
self.seatp[seatno] = clicker:get_player_name()
+ self.seatpc[seatno] = clicker:get_player_control_bits()
advtrains.player_to_train_mapping[clicker:get_player_name()]=self.train_id
clicker:set_attach(self.object, "", self.seats[seatno].attach_offset, {x=0,y=0,z=0})
clicker:set_eye_offset(self.seats[seatno].view_offset, self.seats[seatno].view_offset)
@@ -569,12 +594,14 @@ function wagon:get_off(seatno)
--abuse helper function
for _,r in ipairs({-1, 1}) do
local p=vector.add({x=isx and r or 0, y=0, z=not isx and r or 0}, objpos)
+ local offp=vector.add({x=isx and r*2 or 0, y=1, z=not isx and r*2 or 0}, objpos)
if minetest.get_item_group(minetest.get_node(p).name, "platform")>0 then
- minetest.after(0.2, function() clicker:setpos({x=p.x, y=p.y+1, z=p.z}) end)
+ minetest.after(0.2, function() clicker:setpos(offp) end)
end
end
end
self.seatp[seatno]=nil
+ self.seatpc[seatno]=nil
end
function wagon:show_get_on_form(pname)
if not self.initialized then return end
@@ -660,7 +687,6 @@ minetest.register_on_player_receive_fields(function(player, formname, fields)
end
uid=string.match(formname, "^advtrains_prop_(.+)$")
if uid then
- atprint(fields)
for _,wagon in pairs(minetest.luaentities) do
if wagon.is_wagon and wagon.initialized and wagon.unique_id==uid then
local pname=player:get_player_name()
@@ -731,13 +757,6 @@ function wagon:reattach_all()
end
end
end
-minetest.register_on_joinplayer(function(player)
- for _,wagon in pairs(minetest.luaentities) do
- if wagon.is_wagon and wagon.initialized then
- wagon:reattach_all()
- end
- end
-end)
function advtrains.register_wagon(sysname, prototype, desc, inv_img)
setmetatable(prototype, {__index=wagon})
@@ -772,7 +791,6 @@ function advtrains.register_wagon(sysname, prototype, desc, inv_img)
local le=ob:get_luaentity()
le.owner=placer:get_player_name()
- le.infotext=desc..", owned by "..placer:get_player_name()
local wagon_uid=le:init_new_instance(id, {})
diff --git a/advtrains/advtrains_train_japan/init.lua b/advtrains/advtrains_train_japan/init.lua
index ffe169f..8816db3 100644
--- a/advtrains/advtrains_train_japan/init.lua
+++ b/advtrains/advtrains_train_japan/init.lua
@@ -66,6 +66,7 @@ advtrains.register_wagon("engine_japan", {
[1]={frames={x=60, y=80}, time=1}
}
},
+ door_entry={-1},
visual_size = {x=1, y=1},
wagon_span=2.5,
is_locomotive=true,
@@ -134,6 +135,7 @@ advtrains.register_wagon("wagon_japan", {
[1]={frames={x=60, y=80}, time=1}
}
},
+ door_entry={-1, 1},
visual_size = {x=1, y=1},
wagon_span=2.3,
collisionbox = {-1.0,-0.5,-1.0, 1.0,2.5,1.0},
diff --git a/advtrains/advtrains_train_subway/init.lua b/advtrains/advtrains_train_subway/init.lua
index faf8ceb..8864e92 100644
--- a/advtrains/advtrains_train_subway/init.lua
+++ b/advtrains/advtrains_train_subway/init.lua
@@ -66,6 +66,7 @@ advtrains.register_wagon("subway_wagon", {
[1]={frames={x=60, y=80}, time=1}
}
},
+ door_entry={-1, 1},
visual_size = {x=1, y=1},
wagon_span=2,
--collisionbox = {-1.0,-0.5,-1.8, 1.0,2.5,1.8},