Compare commits

...

5 Commits

Author SHA1 Message Date
orwell96 2b21817b4f On_Joinplayer: fix train ID check for attachment update
Previously, statement was always false because train_id is no longer in the luaentity
2022-06-13 14:17:24 +02:00
Antonia 744aee2cdd Minor change to README
45 degree platform design is not a sound
2022-03-03 00:12:43 +01:00
orwell96 8beacdc508 Fix new wagon positioning when wheel positions are asymmetric, and remove leftover train.debug 2022-02-24 22:04:39 +01:00
orwell96 3cb21a80dc Wagons: Add two-pos wheel positioning logic for more realistic look of long wagons
Adds field "wheel_positions" in wagon definition
2022-02-09 23:06:02 +01:00
orwell96 ef8391a60d atc_reset(): Removed unused string parameter and also clear ATC autocouple flag (Cpl)
Fixes H#189 and H#190
2021-12-31 16:04:04 +01:00
6 changed files with 75 additions and 39 deletions

View File

@ -83,6 +83,7 @@ Small code contributions:
* Inventory images : mbb
* Node texture for LuaATC controller: Jeija (from Mesecons)
* Mod Description : hajo
* 45 degree platforms design : Och_Noe
#### Sounds:
@ -91,7 +92,7 @@ Small code contributions:
* advtrains\_steam\_whistle : googol
* advtrains\_subway\_horn : https://freesound.org/people/Mullumbimby/sounds/385283/
* advtrains\_subway\_\* : Gabriel (gbl08ma)
* 45 degree platforms design : Och_Noe
### Testers:

View File

@ -85,6 +85,13 @@ advtrains.register_wagon(name, prototype, description, inventory_image)
wagon_span=2,
^- How far this wagon extends from its base position. Is the half of the wagon length.
^- Used to determine in which distance the other wagons have to be positioned. Will require tweaking.
wheel_positions = {1.5, -1.5},
^- Optional: if defined, the wagon will be placed so that these 2 wheel positions are on the track
^- This parameter is recommended for long wagons (wagon_span >= 2).
^- The position is a distance relative to the center of the wagon.
^- Must have exactly 2 entries, corresponding to the front (1) and rear (2) wheel of the wagon object. 1st must be greater than 2nd.
^- If not provided, the simple 1-position positioning logic will be used (wagon is positioned with the center on the track)
extent_h = 1,
^- Determines the collision box extent in x/z direction. Defaults to 1 (=3x3)
^- The actual bounding box size is (extent_h*2)+1, so 0 means 1x1, 1 means 3x3 and 2 means 5x5

View File

@ -93,6 +93,7 @@ function atc.train_reset_command(train, keep_tarvel)
train.atc_delay=nil
train.atc_brake_target=nil
train.atc_wait_finish=nil
train.atc_wait_autocouple=nil
train.atc_arrow=nil
if not keep_tarvel then
train.tarvelocity=nil

View File

@ -143,8 +143,11 @@ minetest.register_on_joinplayer(function(player)
local id=advtrains.player_to_train_mapping[pname]
if id then
for _,wagon in pairs(minetest.luaentities) do
if wagon.is_wagon and wagon.initialized and wagon.train_id==id then
wagon:reattach_all()
if wagon.is_wagon and wagon.initialized and wagon.id then
local wdata = advtrains.wagons[wagon.id]
if wdata and wdata.train_id == id then
wagon:reattach_all()
end
end
end
end

View File

@ -413,13 +413,38 @@ function wagon:on_step(dtime)
end
-- Calculate new position, yaw and direction vector
-- note: "index" is needed to be the center index, required by door code
local index = advtrains.path_get_index_by_offset(train, train.index, -data.pos_in_train)
local pos, yaw, npos, npos2 = advtrains.path_get_interpolated(train, index)
local vdir = vector.normalize(vector.subtract(npos2, npos))
local pos, yaw, npos, npos2, vdir
-- use new position logic?
if self.wheel_positions then
-- request two positions, calculate difference and yaw from this
-- depending on flipstate, need to invert wheel pos indices -> wheelpos * fct
local index1 = advtrains.path_get_index_by_offset(train, index, self.wheel_positions[1] * fct)
local index2 = advtrains.path_get_index_by_offset(train, index, self.wheel_positions[2] * fct)
local pos1 = advtrains.path_get_interpolated(train, index1)
local pos2 = advtrains.path_get_interpolated(train, index2)
npos = advtrains.path_get(train, atfloor(index)) -- need npos just for node loaded check
-- calculate center of 2 positions and vdir vector
-- if wheel positions are asymmetric, needs to weight by the difference!
local fact = self.wheel_positions[1] / (self.wheel_positions[1]-self.wheel_positions[2])
pos = {x=pos1.x-(pos1.x-pos2.x)*fact, y=pos1.y-(pos1.y-pos2.y)*fact, z=pos1.z-(pos1.z-pos2.z)*fact}
if data.wagon_flipped then
vdir = vector.normalize(vector.subtract(pos2, pos1))
else
vdir = vector.normalize(vector.subtract(pos1, pos2))
end
yaw = math.atan2(-vdir.x, vdir.z)
else
--old position logic (for small wagons): use center index and just get position
pos, yaw, npos, npos2 = advtrains.path_get_interpolated(train, index)
vdir = vector.normalize(vector.subtract(npos2, npos))
end
--automatic get_on
--needs to know index and path
if self.door_entry and train.door_open and train.door_open~=0 and train.velocity==0 then
if train.velocity==0 and self.door_entry and train.door_open and train.door_open~=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
@ -470,28 +495,32 @@ function wagon:on_step(dtime)
end
end
--DisCouple
-- Spawn discouple object when train stands, in all other cases remove it.
-- FIX: Need to do this after the yaw calculation
if is_in_loaded_area and data.pos_in_trainparts and data.pos_in_trainparts>1 then
if train.velocity==0 then
if not self.discouple or not self.discouple.object:get_yaw() then
atprint(self.id,"trying to spawn discouple")
local dcpl_pos = vector.add(pos, {y=0, x=-math.sin(yaw)*self.wagon_span, z=math.cos(yaw)*self.wagon_span})
local object=minetest.add_entity(dcpl_pos, "advtrains:discouple")
if object then
local le=object:get_luaentity()
le.wagon=self
--box is hidden when attached, so unuseful.
--object:set_attach(self.object, "", {x=0, y=0, z=self.wagon_span*10}, {x=0, y=0, z=0})
self.discouple=le
end
end
else
if self.discouple and self.discouple.object:get_yaw() then
self.discouple.object:remove()
atprint(self.id," removing discouple")
if train.velocity==0 and is_in_loaded_area and data.pos_in_trainparts and data.pos_in_trainparts>1 then
if not self.discouple or not self.discouple.object:get_yaw() then
atprint(self.id,"trying to spawn discouple")
local dcpl_pos = vector.add(pos, {y=0, x=-math.sin(yaw)*self.wagon_span, z=math.cos(yaw)*self.wagon_span})
local object=minetest.add_entity(dcpl_pos, "advtrains:discouple")
if object then
local le=object:get_luaentity()
le.wagon=self
--box is hidden when attached, so unuseful.
--object:set_attach(self.object, "", {x=0, y=0, z=self.wagon_span*10}, {x=0, y=0, z=0})
self.discouple=le
end
end
else
if self.discouple and self.discouple.object:get_yaw() then
self.discouple.object:remove()
atprint(self.id," removing discouple")
end
end
-- object yaw (corrected by flipstate)
local oyaw = yaw
if data.wagon_flipped then
oyaw = yaw + math.pi
end
--FIX: use index of the wagon, not of the train.
@ -500,10 +529,6 @@ function wagon:on_step(dtime)
local velocityvec = vector.multiply(vdir, velocity)
local accelerationvec = vector.multiply(vdir, acceleration)
if data.wagon_flipped then
yaw=yaw+math.pi
end
-- this timer runs off every 2 seconds.
self.updatepct_timer=(self.updatepct_timer or 0)-dtime
local updatepct_timer_elapsed = self.updatepct_timer<=0
@ -540,19 +565,19 @@ function wagon:on_step(dtime)
or not vector.equals(velocityvec, self.old_velocity_vector)
or not self.old_acceleration_vector
or not vector.equals(accelerationvec, self.old_acceleration_vector)
or self.old_yaw~=yaw
or self.old_yaw~=oyaw
or updatepct_timer_elapsed then--only send update packet if something changed
self.object:set_pos(pos)
self.object:set_velocity(velocityvec)
self.object:set_acceleration(accelerationvec)
if #self.seats > 0 and self.old_yaw ~= yaw then
if #self.seats > 0 and self.old_yaw ~= oyaw then
if not self.player_yaw then
self.player_yaw = {}
end
if not self.old_yaw then
self.old_yaw=yaw
self.old_yaw=oyaw
end
for _,name in pairs(data.seatp) do
local p = minetest.get_player_by_name(name)
@ -562,11 +587,11 @@ function wagon:on_step(dtime)
self.player_yaw[name] = p:get_look_horizontal()-self.old_yaw
end
-- set player looking direction using calculated offset
p:set_look_horizontal((self.player_yaw[name] or 0)+yaw)
p:set_look_horizontal((self.player_yaw[name] or 0)+oyaw)
end
end
self.turning = true
elseif self.old_yaw == yaw then
elseif self.old_yaw == oyaw then
-- train is no longer turning
self.turning = false
end
@ -576,9 +601,9 @@ function wagon:on_step(dtime)
if data.wagon_flipped then
pitch = -pitch
end
self.object:set_rotation({x=pitch, y=yaw, z=0})
self.object:set_rotation({x=pitch, y=oyaw, z=0})
else
self.object:set_yaw(yaw)
self.object:set_yaw(oyaw)
end
if self.update_animation then
@ -597,7 +622,7 @@ function wagon:on_step(dtime)
self.old_velocity_vector=velocityvec
self.old_velocity = train.velocity
self.old_acceleration_vector=accelerationvec
self.old_yaw=yaw
self.old_yaw=oyaw
atprintbm("wagon step", t)
end

View File

@ -130,9 +130,8 @@ function r.fire_event(pos, evtdata, appr_internal)
get_rc = function()
return train.routingcode
end,
atc_reset = function(cmd)
atc_reset = function()
if not train_id then return false end
assertt(cmd, "string")
advtrains.atc.train_reset_command(train)
return true
end,