aboutsummaryrefslogtreecommitdiff
path: root/advtrains/advtrains_train_industrial/init.lua
blob: 2eed2b12e023542554b806bd8048eb79740cee93 (plain)
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
-- Boilerplate to support localized strings if intllib mod is installed.
local S
if minetest.get_modpath("intllib") then
    S = intllib.Getter()
else
    S = function(s,a,...)a={a,...}return s:gsub("@(%d+)",function(n)return a[tonumber(n)]end)end
end

advtrains.register_wagon("engine_industrial", {
	mesh="advtrains_engine_industrial.b3d",
	textures = {"advtrains_engine_industrial.png"},
	drives_on={default=true},
	max_speed=20,
	seats = {
		{
			name=S("Driver Stand (left)"),
			attach_offset={x=-5, y=10, z=-10},
			view_offset={x=0, y=10, z=0},
			driving_ctrl_access=true,
			group = "dstand",
		},
		{
			name=S("Driver Stand (right)"),
			attach_offset={x=5, y=10, z=-10},
			view_offset={x=0, y=10, z=0},
			driving_ctrl_access=true,
			group = "dstand",
		},
	},
	seat_groups = {
		dstand={
			name = "Driver Stand",
			access_to = {},
		},
	},
	assign_to_seat_group = {"dstand"},
	visual_size = {x=1, y=1},
	wagon_span=2.6,
	is_locomotive=true,
	collisionbox = {-1.0,-0.5,-1.0, 1.0,2.5,1.0},
	drops={"default:steelblock 4"},
}, S("Industrial Train Engine"), "advtrains_engine_industrial_inv.png")
advtrains.register_wagon("wagon_tank", {
	mesh="advtrains_wagon_tank.b3d",
	textures = {"advtrains_wagon_tank.png"},
	seats = {},
	drives_on={default=true},
	max_speed=20,
	visual_size = {x=1, y=1},
	wagon_span=2.2,
	collisionbox = {-1.0,-0.5,-1.0, 1.0,2.5,1.0},
	drops={"default:steelblock 4"},
	has_inventory = true,
	get_inventory_formspec = function(self)
		return "size[8,11]"..
			"list[detached:advtrains_wgn_"..self.unique_id..";box;0,0;8,6;]"..
			"list[current_player;main;0,7;8,4;]"..
			"listring[]"
	end,
	inventory_list_sizes = {
		box=8*6,
	},
}, S("Industrial tank wagon"), "advtrains_wagon_tank_inv.png")
advtrains.register_wagon("wagon_wood", {
	mesh="advtrains_wagon_wood.b3d",
	textures = {"advtrains_wagon_wood.png"},
	seats = {},
	drives_on={default=true},
	max_speed=20,
	visual_size = {x=1, y=1},
	wagon_span=1.8,
	collisionbox = {-1.0,-0.5,-1.0, 1.0,2.5,1.0},
	drops={"default:steelblock 4"},
	has_inventory = true,
	get_inventory_formspec = function(self)
		return "size[8,11]"..
			"list[detached:advtrains_wgn_"..self.unique_id..";box;0,0;8,6;]"..
			"list[current_player;main;0,7;8,4;]"..
			"listring[]"
	end,
	inventory_list_sizes = {
		box=8*6,
	},
}, S("Industrial wood wagon"), "advtrains_wagon_wood_inv.png")
any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #include "config.h" #if USE_CURSES #include "version.h" #include "terminal_chat_console.h" #include "porting.h" #include "settings.h" #include "util/numeric.h" #include "util/string.h" #include "chat_interface.h" TerminalChatConsole g_term_console; // include this last to avoid any conflicts // (likes to set macros to common names, conflicting various stuff) #if CURSES_HAVE_NCURSESW_NCURSES_H #include <ncursesw/ncurses.h> #elif CURSES_HAVE_NCURSESW_CURSES_H #include <ncursesw/curses.h> #elif CURSES_HAVE_CURSES_H #include <curses.h> #elif CURSES_HAVE_NCURSES_H #include <ncurses.h> #elif CURSES_HAVE_NCURSES_NCURSES_H #include <ncurses/ncurses.h> #elif CURSES_HAVE_NCURSES_CURSES_H #include <ncurses/curses.h> #endif // Some functions to make drawing etc position independent static bool reformat_backend(ChatBackend *backend, int rows, int cols) { if (rows < 2) return false; backend->reformat(cols, rows - 2); return true; } static void move_for_backend(int row, int col) { move(row + 1, col); } void TerminalChatConsole::initOfCurses() { initscr(); cbreak(); //raw(); noecho(); keypad(stdscr, TRUE); nodelay(stdscr, TRUE); timeout(100); // To make esc not delay up to one second. According to the internet, // this is the value vim uses, too. set_escdelay(25); getmaxyx(stdscr, m_rows, m_cols); m_can_draw_text = reformat_backend(&m_chat_backend, m_rows, m_cols); } void TerminalChatConsole::deInitOfCurses() { endwin(); } void *TerminalChatConsole::run() { BEGIN_DEBUG_EXCEPTION_HANDLER std::cout << "========================" << std::endl; std::cout << "Begin log output over terminal" << " (no stdout/stderr backlog during that)" << std::endl; // Make the loggers to stdout/stderr shut up. // Go over our own loggers instead. LogLevelMask err_mask = g_logger.removeOutput(&stderr_output); LogLevelMask out_mask = g_logger.removeOutput(&stdout_output); g_logger.addOutput(&m_log_output); // Inform the server of our nick m_chat_interface->command_queue.push_back( new ChatEventNick(CET_NICK_ADD, m_nick)); { // Ensures that curses is deinitialized even on an exception being thrown CursesInitHelper helper(this); while (!stopRequested()) { int ch = getch(); if (stopRequested()) break; step(ch); } } if (m_kill_requested) *m_kill_requested = true; g_logger.removeOutput(&m_log_output); g_logger.addOutputMasked(&stderr_output, err_mask); g_logger.addOutputMasked(&stdout_output, out_mask); std::cout << "End log output over terminal" << " (no stdout/stderr backlog during that)" << std::endl; std::cout << "========================" << std::endl; END_DEBUG_EXCEPTION_HANDLER return NULL; } void TerminalChatConsole::typeChatMessage(const std::wstring &msg) { // Discard empty line if (msg.empty()) return; // Send to server m_chat_interface->command_queue.push_back( new ChatEventChat(m_nick, msg)); // Print if its a command (gets eaten by server otherwise) if (msg[0] == L'/') { m_chat_backend.addMessage(L"", (std::wstring)L"Issued command: " + msg); } } void TerminalChatConsole::handleInput(int ch, bool &complete_redraw_needed) { ChatPrompt &prompt = m_chat_backend.getPrompt(); // Helpful if you want to collect key codes that aren't documented /*if (ch != ERR) { m_chat_backend.addMessage(L"", (std::wstring)L"Pressed key " + utf8_to_wide( std::string(keyname(ch)) + " (code " + itos(ch) + ")")); complete_redraw_needed = true; }//*/ // All the key codes below are compatible to xterm // Only add new ones if you have tried them there, // to ensure compatibility with not just xterm but the wide // range of terminals that are compatible to xterm. switch (ch) { case ERR: // no input break; case 27: // ESC // Toggle ESC mode m_esc_mode = !m_esc_mode; break; case KEY_PPAGE: m_chat_backend.scrollPageUp(); complete_redraw_needed = true; break; case KEY_NPAGE: m_chat_backend.scrollPageDown(); complete_redraw_needed = true; break; case KEY_ENTER: case '\r': case '\n': { prompt.addToHistory(prompt.getLine()); typeChatMessage(prompt.replace(L"")); break; } case KEY_UP: prompt.historyPrev(); break; case KEY_DOWN: prompt.historyNext(); break; case KEY_LEFT: // Left pressed // move character to the left prompt.cursorOperation( ChatPrompt::CURSOROP_MOVE, ChatPrompt::CURSOROP_DIR_LEFT, ChatPrompt::CURSOROP_SCOPE_CHARACTER); break; case 545: // Ctrl-Left pressed // move word to the left prompt.cursorOperation( ChatPrompt::CURSOROP_MOVE, ChatPrompt::CURSOROP_DIR_LEFT, ChatPrompt::CURSOROP_SCOPE_WORD); break; case KEY_RIGHT: // Right pressed // move character to the right prompt.cursorOperation( ChatPrompt::CURSOROP_MOVE, ChatPrompt::CURSOROP_DIR_RIGHT, ChatPrompt::CURSOROP_SCOPE_CHARACTER); break; case 560: // Ctrl-Right pressed // move word to the right prompt.cursorOperation( ChatPrompt::CURSOROP_MOVE, ChatPrompt::CURSOROP_DIR_RIGHT, ChatPrompt::CURSOROP_SCOPE_WORD); break; case KEY_HOME: // Home pressed // move to beginning of line prompt.cursorOperation( ChatPrompt::CURSOROP_MOVE, ChatPrompt::CURSOROP_DIR_LEFT, ChatPrompt::CURSOROP_SCOPE_LINE); break; case KEY_END: // End pressed // move to end of line prompt.cursorOperation( ChatPrompt::CURSOROP_MOVE, ChatPrompt::CURSOROP_DIR_RIGHT, ChatPrompt::CURSOROP_SCOPE_LINE); break; case KEY_BACKSPACE: case '\b': case 127: // Backspace pressed // delete character to the left prompt.cursorOperation( ChatPrompt::CURSOROP_DELETE, ChatPrompt::CURSOROP_DIR_LEFT, ChatPrompt::CURSOROP_SCOPE_CHARACTER); break; case KEY_DC: // Delete pressed // delete character to the right prompt.cursorOperation( ChatPrompt::CURSOROP_DELETE, ChatPrompt::CURSOROP_DIR_RIGHT, ChatPrompt::CURSOROP_SCOPE_CHARACTER); break; case 519: // Ctrl-Delete pressed // delete word to the right prompt.cursorOperation( ChatPrompt::CURSOROP_DELETE, ChatPrompt::CURSOROP_DIR_RIGHT, ChatPrompt::CURSOROP_SCOPE_WORD); break; case 21: // Ctrl-U pressed // kill line to left end prompt.cursorOperation( ChatPrompt::CURSOROP_DELETE, ChatPrompt::CURSOROP_DIR_LEFT, ChatPrompt::CURSOROP_SCOPE_LINE); break; case 11: // Ctrl-K pressed // kill line to right end prompt.cursorOperation( ChatPrompt::CURSOROP_DELETE, ChatPrompt::CURSOROP_DIR_RIGHT, ChatPrompt::CURSOROP_SCOPE_LINE); break; case KEY_TAB: // Tab pressed // Nick completion prompt.nickCompletion(m_nicks, false); break; default: // Add character to the prompt, // assuming UTF-8. if (IS_UTF8_MULTB_START(ch)) { m_pending_utf8_bytes.append(1, (char)ch); m_utf8_bytes_to_wait += UTF8_MULTB_START_LEN(ch) - 1; } else if (m_utf8_bytes_to_wait != 0) { m_pending_utf8_bytes.append(1, (char)ch); m_utf8_bytes_to_wait--; if (m_utf8_bytes_to_wait == 0) { std::wstring w = utf8_to_wide(m_pending_utf8_bytes); m_pending_utf8_bytes = "";