-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathseat.lua
More file actions
235 lines (210 loc) · 6.62 KB
/
seat.lua
File metadata and controls
235 lines (210 loc) · 6.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
--[[
Hyperloop Mod
=============
Copyright (C) 2017-2019 Joachim Stolberg
LGPLv2.1+
See LICENSE.txt for more information
]]--
-- for lazy programmers
--local SP = function(pos) if pos then return minetest.pos_to_string(pos) end end
--local P = minetest.string_to_pos
local M = minetest.get_meta
-- Load support for intllib.
local S = hyperloop.S
local I, _ = dofile( minetest.get_modpath("hyperloop").."/intllib.lua")
local PlayerNameTags = {}
local function enter_display(tStation, text)
-- determine position
if tStation ~= nil then
local lcd_pos = hyperloop.new_pos(tStation.pos, tStation.facedir, "1F", 2)
-- update display
minetest.registered_nodes["hyperloop:lcd"].update(lcd_pos, text)
end
end
local function on_final_close_door(tStation)
-- close the door and play sound if no player is around
if hyperloop.is_player_around(tStation.pos) then
-- try again later
minetest.after(3.0, on_final_close_door, tStation)
else
hyperloop.close_pod_door(tStation)
enter_display(tStation, I(" | | << Hyperloop >> | be anywhere"))
end
end
local function on_open_door(tArrival)
-- open the door and play sound
local meta = minetest.get_meta(tArrival.pos)
meta:set_int("arrival_time", 0) -- finished
-- open door
hyperloop.open_pod_door(tArrival)
-- prepare display for the next trip
enter_display(tArrival, I("Thank you | for | travelling | with | Hyperloop."))
minetest.after(5.0, on_final_close_door, tArrival, tArrival.facedir)
end
local function on_arrival(tDeparture, tArrival, player_name, sound)
local player = minetest.get_player_by_name(player_name)
-- activate display
local text = I(" | Welcome at | | ")..string.sub(tArrival.name, 1, 13)
enter_display(tArrival, text)
-- stop timer
minetest.get_node_timer(tDeparture.pos):stop()
-- move player to the arrival station
if player ~= nil then
local pos = table.copy(tArrival.pos)
pos.y = pos.y + 0.5
player:set_pos(pos)
-- rotate player to look in correct arrival direction
-- calculate the look correction
-- workaround to prevent server crashes
local val1 = hyperloop.facedir_to_rad(tDeparture.facedir)
local val2 = player:get_look_horizontal()
if val1 ~= nil and val2 ~= nil then
local offs = val1 - val2
local yaw = hyperloop.facedir_to_rad(tArrival.facedir) - offs
player:set_look_horizontal(yaw)
end
-- set player name again
if PlayerNameTags[player_name] then
player:set_nametag_attributes(PlayerNameTags[player_name])
PlayerNameTags[player_name] = nil
end
end
-- play arrival sound
minetest.sound_stop(sound)
minetest.sound_play("down2", {
pos = tArrival.pos,
gain = 0.5,
max_hear_distance = 2
})
minetest.after(4.0, on_open_door, tArrival)
end
local function on_travel(tDeparture, tArrival, player_name, atime)
-- play sound and switch door state
local sound = minetest.sound_play("normal2", {
pos = tDeparture.pos,
gain = 0.5,
max_hear_distance = 2,
loop = true,
})
hyperloop.animate_pod_door(tDeparture)
minetest.after(atime, on_arrival, tDeparture, tArrival, player_name, sound)
minetest.after(atime, on_final_close_door, tDeparture)
end
local function display_timer(pos, elapsed)
-- update display with trip data
local tStation = hyperloop.get_base_station(pos)
if tStation then
local meta = M(pos)
local atime = meta:get_int("arrival_time") - 1
meta:set_int("arrival_time", atime)
local text = meta:get_string("lcd_text")
if atime > 2 then
enter_display(tStation, text..atime.." sec")
return true
else
return false
end
end
return false
end
local function meter_to_km(dist)
if dist < 1000 then
return tostring(dist).." m"
elseif dist < 10000 then
return string.format("%.3f km", dist/1000)
else
return string.format("%.1f km", dist/1000)
end
end
-- place the player, close the door, activate display
local function on_start_travel(pos, node, clicker)
-- arrival data
local meta = M(pos)
local player_name = clicker:get_player_name()
local tDeparture, departure_pos = hyperloop.get_base_station(pos)
local arrival_pos = hyperloop.get_arrival(departure_pos)
if arrival_pos == nil then
minetest.chat_send_player(player_name, S("[Hyperloop] No booking entered!"))
return
end
local tArrival = hyperloop.get_station(arrival_pos)
if tDeparture == nil or tArrival == nil then
return
end
minetest.sound_play("up2", {
pos = pos,
gain = 0.5,
max_hear_distance = 2
})
-- close the door at arrival station
hyperloop.close_pod_door(tArrival)
-- place player on the seat
pos.y = pos.y - 0.5
clicker:set_pos(pos)
-- rotate player to look in move direction
clicker:set_look_horizontal(hyperloop.facedir_to_rad(tDeparture.facedir))
-- hide player name
PlayerNameTags[player_name] = clicker:get_nametag_attributes()
clicker:set_nametag_attributes({text = " "})
-- activate display
local dist = hyperloop.distance(pos, tArrival.pos)
local text = I("Destination:").." | "..string.sub(tArrival.name, 1, 13).." | "..I("Distance:").." | "..
meter_to_km(dist).." | "..I("Arrival in:").." | "
local atime
if dist < 1000 then
atime = 10 + math.floor(dist/200) -- 10..15 sec
elseif dist < 10000 then
atime = 15 + math.floor(dist/600) -- 16..32 sec
else
atime = 32 -- 32 sec is the maximum
end
enter_display(tDeparture, text..atime.." sec")
-- block departure and arrival stations
hyperloop.block(departure_pos, arrival_pos, atime+10)
-- store some data for on_timer()
meta:set_int("arrival_time", atime)
meta:set_string("lcd_text", text)
minetest.get_node_timer(pos):start(1.0)
hyperloop.close_pod_door(tDeparture)
atime = atime - 7 -- substract start/arrival time
minetest.after(4.9, on_travel, tDeparture, tArrival, player_name, atime)
end
-- Hyperloop Seat
minetest.register_node("hyperloop:seat", {
description = S("Hyperloop Pod Seat"),
tiles = {
"hyperloop_seat-top.png",
"hyperloop_seat-side.png",
"hyperloop_seat-side.png",
"hyperloop_seat-side.png",
"hyperloop_seat-side.png",
"hyperloop_seat-side.png",
},
drawtype = "nodebox",
paramtype = 'light',
light_source = 1,
paramtype2 = "facedir",
is_ground_content = false,
walkable = false,
drop = "",
groups = {not_in_creative_inventory=1, crumbly=3},
node_box = {
type = "fixed",
fixed = {
{ -6/16, -8/16, -8/16, 6/16, -2/16, 5/16},
{ -8/16, -8/16, -8/16, -6/16, 4/16, 8/16},
{ 6/16, -8/16, -8/16, 8/16, 4/16, 8/16},
{ -6/16, -8/16, 4/16, 6/16, 6/16, 8/16},
},
},
selection_box = {
type = "fixed",
fixed = { -8/16, -8/16, -8/16, 8/16, -2/16, 8/16 },
},
on_timer = display_timer,
on_rightclick = on_start_travel,
on_rotate = screwdriver.disallow,
auto_place_node = function(pos, facedir, sStationPos)
M(pos):set_string("sStationPos", sStationPos)
end,
})