aboutsummaryrefslogtreecommitdiff
path: root/src/script/lua_api/l_vmanip.cpp
blob: 0d8123acd437eaea75b8e8c08398df5a5667fcef (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
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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
/*
Minetest
Copyright (C) 2013 kwolekr, Ryan Kwolek <kwolekr@minetest.net>

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) 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 "lua_api/l_vmanip.h"
#include "lua_api/l_internal.h"
#include "common/c_content.h"
#include "common/c_converter.h"
#include "emerge.h"
#include "environment.h"
#include "map.h"
#include "server.h"
#include "mapgen.h"

// garbage collector
int LuaVoxelManip::gc_object(lua_State *L)
{
	LuaVoxelManip *o = *(LuaVoxelManip **)(lua_touserdata(L, 1));
	delete o;

	return 0;
}

int LuaVoxelManip::l_read_from_map(lua_State *L)
{
	MAP_LOCK_REQUIRED;

	LuaVoxelManip *o = checkobject(L, 1);
	MMVManip *vm = o->vm;

	v3s16 bp1 = getNodeBlockPos(check_v3s16(L, 2));
	v3s16 bp2 = getNodeBlockPos(check_v3s16(L, 3));
	sortBoxVerticies(bp1, bp2);

	vm->initialEmerge(bp1, bp2);

	push_v3s16(L, vm->m_area.MinEdge);
	push_v3s16(L, vm->m_area.MaxEdge);

	return 2;
}

int LuaVoxelManip::l_get_data(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaVoxelManip *o = checkobject(L, 1);
	bool use_buffer  = lua_istable(L, 2);

	MMVManip *vm = o->vm;

	u32 volume = vm->m_area.getVolume();

	if (use_buffer)
		lua_pushvalue(L, 2);
	else
		lua_newtable(L);

	for (u32 i = 0; i != volume; i++) {
		lua_Integer cid = vm->m_data[i].getContent();
		lua_pushinteger(L, cid);
		lua_rawseti(L, -2, i + 1);
	}

	return 1;
}

int LuaVoxelManip::l_set_data(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaVoxelManip *o = checkobject(L, 1);
	MMVManip *vm = o->vm;

	if (!lua_istable(L, 2))
		return 0;

	u32 volume = vm->m_area.getVolume();
	for (u32 i = 0; i != volume; i++) {
		lua_rawgeti(L, 2, i + 1);
		content_t c = lua_tointeger(L, -1);

		vm->m_data[i].setContent(c);

		lua_pop(L, 1);
	}

	return 0;
}

int LuaVoxelManip::l_write_to_map(lua_State *L)
{
	MAP_LOCK_REQUIRED;

	LuaVoxelManip *o = checkobject(L, 1);
	MMVManip *vm = o->vm;

	vm->blitBackAll(&o->modified_blocks);

	return 0;
}

int LuaVoxelManip::l_get_node_at(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	INodeDefManager *ndef = getServer(L)->getNodeDefManager();

	LuaVoxelManip *o = checkobject(L, 1);
	v3s16 pos        = check_v3s16(L, 2);

	pushnode(L, o->vm->getNodeNoExNoEmerge(pos), ndef);
	return 1;
}

int LuaVoxelManip::l_set_node_at(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	INodeDefManager *ndef = getServer(L)->getNodeDefManager();

	LuaVoxelManip *o = checkobject(L, 1);
	v3s16 pos        = check_v3s16(L, 2);
	MapNode n        = readnode(L, 3, ndef);

	o->vm->setNodeNoEmerge(pos, n);

	return 0;
}

int LuaVoxelManip::l_update_liquids(lua_State *L)
{
	GET_ENV_PTR;

	LuaVoxelManip *o = checkobject(L, 1);

	Map *map = &(env->getMap());
	INodeDefManager *ndef = getServer(L)->getNodeDefManager();
	MMVManip *vm = o->vm;

	Mapgen mg;
	mg.vm   = vm;
	mg.ndef = ndef;

	mg.updateLiquid(&map->m_transforming_liquid,
			vm->m_area.MinEdge, vm->m_area.MaxEdge);

	return 0;
}

int LuaVoxelManip::l_calc_lighting(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaVoxelManip *o = checkobject(L, 1);
	if (!o->is_mapgen_vm)
		return 0;

	INodeDefManager *ndef = getServer(L)->getNodeDefManager();
	EmergeManager *emerge = getServer(L)->getEmergeManager();
	MMVManip *vm = o->vm;

	v3s16 yblock = v3s16(0, 1, 0) * MAP_BLOCKSIZE;
	v3s16 fpmin  = vm->m_area.MinEdge;
	v3s16 fpmax  = vm->m_area.MaxEdge;
	v3s16 pmin   = lua_istable(L, 2) ? check_v3s16(L, 2) : fpmin + yblock;
	v3s16 pmax   = lua_istable(L, 3) ? check_v3s16(L, 3) : fpmax - yblock;
	bool propagate_shadow = lua_isboolean(L, 4) ? lua_toboolean(L, 4) : true;

	sortBoxVerticies(pmin, pmax);
	if (!vm->m_area.contains(VoxelArea(pmin, pmax)))
		throw LuaError("Specified voxel area out of VoxelManipulator bounds");

	Mapgen mg;
	mg.vm          = vm;
	mg.ndef        = ndef;
	mg.water_level = emerge->mgparams->water_level;

	mg.calcLighting(pmin, pmax, fpmin, fpmax, propagate_shadow);

	return 0;
}

int LuaVoxelManip::l_set_lighting(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaVoxelManip *o = checkobject(L, 1);
	if (!o->is_mapgen_vm)
		return 0;

	if (!lua_istable(L, 2))
		return 0;

	u8 light;
	light  = (getintfield_default(L, 2, "day",   0) & 0x0F);
	light |= (getintfield_default(L, 2, "night", 0) & 0x0F) << 4;

	MMVManip *vm = o->vm;

	v3s16 yblock = v3s16(0, 1, 0) * MAP_BLOCKSIZE;
	v3s16 pmin = lua_istable(L, 3) ? check_v3s16(L, 3) : vm->m_area.MinEdge + yblock;
	v3s16 pmax = lua_istable(L, 4) ? check_v3s16(L, 4) : vm->m_area.MaxEdge - yblock;

	sortBoxVerticies(pmin, pmax);
	if (!vm->m_area.contains(VoxelArea(pmin, pmax)))
		throw LuaError("Specified voxel area out of VoxelManipulator bounds");

	Mapgen mg;
	mg.vm = vm;

	mg.setLighting(light, pmin, pmax);

	return 0;
}

int LuaVoxelManip::l_get_light_data(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaVoxelManip *o = checkobject(L, 1);
	MMVManip *vm = o->vm;

	u32 volume = vm->m_area.getVolume();

	lua_newtable(L);
	for (u32 i = 0; i != volume; i++) {
		lua_Integer light = vm->m_data[i].param1;
		lua_pushinteger(L, light);
		lua_rawseti(L, -2, i + 1);
	}

	return 1;
}

int LuaVoxelManip::l_set_light_data(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaVoxelManip *o = checkobject(L, 1);
	MMVManip *vm = o->vm;

	if (!lua_istable(L, 2))
		return 0;

	u32 volume = vm->m_area.getVolume();
	for (u32 i = 0; i != volume; i++) {
		lua_rawgeti(L, 2, i + 1);
		u8 light = lua_tointeger(L, -1);

		vm->m_data[i].param1 = light;

		lua_pop(L, 1);
	}

	return 0;
}

int LuaVoxelManip::l_get_param2_data(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaVoxelManip *o = checkobject(L, 1);
	MMVManip *vm = o->vm;

	u32 volume = vm->m_area.getVolume();

	lua_newtable(L);
	for (u32 i = 0; i != volume; i++) {
		lua_Integer param2 = vm->m_data[i].param2;
		lua_pushinteger(L, param2);
		lua_rawseti(L, -2, i + 1);
	}

	return 1;
}

int LuaVoxelManip::l_set_param2_data(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaVoxelManip *o = checkobject(L, 1);
	MMVManip *vm = o->vm;

	if (!lua_istable(L, 2))
		return 0;

	u32 volume = vm->m_area.getVolume();
	for (u32 i = 0; i != volume; i++) {
		lua_rawgeti(L, 2, i + 1);
		u8 param2 = lua_tointeger(L, -1);

		vm->m_data[i].param2 = param2;

		lua_pop(L, 1);
	}

	return 0;
}

int LuaVoxelManip::l_update_map(lua_State *L)
{
	GET_ENV_PTR;

	LuaVoxelManip *o = checkobject(L, 1);
	if (o->is_mapgen_vm)
		return 0;

	Map *map = &(env->getMap());

	// TODO: Optimize this by using Mapgen::calcLighting() instead
	std::map<v3s16, MapBlock *> lighting_mblocks;
	std::map<v3s16, MapBlock *> *mblocks = &o->modified_blocks;

	lighting_mblocks.insert(mblocks->begin(), mblocks->end());

	map->updateLighting(lighting_mblocks, *mblocks);

	MapEditEvent event;
	event.type = MEET_OTHER;
	for (std::map<v3s16, MapBlock *>::iterator
		it = mblocks->begin();
		it != mblocks->end(); ++it)
		event.modified_blocks.insert(it->first);

	map->dispatchEvent(&event);

	mblocks->clear();

	return 0;
}

int LuaVoxelManip::l_was_modified(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaVoxelManip *o = checkobject(L, 1);
	MMVManip *vm = o->vm;

	lua_pushboolean(L, vm->m_is_dirty);

	return 1;
}

int LuaVoxelManip::l_get_emerged_area(lua_State *L)
{
	NO_MAP_LOCK_REQUIRED;

	LuaVoxelManip *o = checkobject(L, 1);

	push_v3s16(L, o->vm->m_area.MinEdge);
	push_v3s16(L, o->vm->m_area.MaxEdge);

	return 2;
}

LuaVoxelManip::LuaVoxelManip(MMVManip *mmvm, bool is_mg_vm)
{
	this->vm           = mmvm;
	this->is_mapgen_vm = is_mg_vm;
}

LuaVoxelManip::LuaVoxelManip(Map *map)
{
	this->vm = new MMVManip(map);
	this->is_mapgen_vm = false;
}

LuaVoxelManip::LuaVoxelManip(Map *map, v3s16 p1, v3s16 p2)
{
	this->vm = new MMVManip(map);
	this->is_mapgen_vm = false;

	v3s16 bp1 = getNodeBlockPos(p1);
	v3s16 bp2 = getNodeBlockPos(p2);
	sortBoxVerticies(bp1, bp2);
	vm->initialEmerge(bp1, bp2);
}

LuaVoxelManip::~LuaVoxelManip()
{
	if (!is_mapgen_vm)
		delete vm;
}

// LuaVoxelManip()
// Creates an LuaVoxelManip and leaves it on top of stack
int LuaVoxelManip::create_object(lua_State *L)
{
	GET_ENV_PTR;

	Map *map = &(env->getMap());
	LuaVoxelManip *o = (lua_istable(L, 1) && lua_istable(L, 2)) ?
		new LuaVoxelManip(map, check_v3s16(L, 1), check_v3s16(L, 2)) :
		new LuaVoxelManip(map);

	*(void **)(lua_newuserdata(L, sizeof(void *))) = o;
	luaL_getmetatable(L, className);
	lua_setmetatable(L, -2);
	return 1;
}

LuaVoxelManip *LuaVoxelManip::checkobject(lua_State *L, int narg)
{
	NO_MAP_LOCK_REQUIRED;

	luaL_checktype(L, narg, LUA_TUSERDATA);

	void *ud = luaL_checkudata(L, narg, className);
	if (!ud)
		luaL_typerror(L, narg, className);

	return *(LuaVoxelManip **)ud;  // unbox pointer
}

void LuaVoxelManip::Register(lua_State *L)
{
	lua_newtable(L);
	int methodtable = lua_gettop(L);
	luaL_newmetatable(L, className);
	int metatable = lua_gettop(L);

	lua_pushliteral(L, "__metatable");
	lua_pushvalue(L, methodtable);
	lua_settable(L, metatable);  // hide metatable from Lua getmetatable()

	lua_pushliteral(L, "__index");
	lua_pushvalue(L, methodtable);
	lua_settable(L, metatable);

	lua_pushliteral(L, "__gc");
	lua_pushcfunction(L, gc_object);
	lua_settable(L, metatable);

	lua_pop(L, 1);  // drop metatable

	luaL_openlib(L, 0, methods, 0);  // fill methodtable
	lua_pop(L, 1);  // drop methodtable

	// Can be created from Lua (VoxelManip())
	lua_register(L, className, create_object);
}

const char LuaVoxelManip::className[] = "VoxelManip";
const luaL_reg LuaVoxelManip::methods[] = {
	luamethod(LuaVoxelManip, read_from_map),
	luamethod(LuaVoxelManip, get_data),
	luamethod(LuaVoxelManip, set_data),
	luamethod(LuaVoxelManip, get_node_at),
	luamethod(LuaVoxelManip, set_node_at),
	luamethod(LuaVoxelManip, write_to_map),
	luamethod(LuaVoxelManip, update_map),
	luamethod(LuaVoxelManip, update_liquids),
	luamethod(LuaVoxelManip, calc_lighting),
	luamethod(LuaVoxelManip, set_lighting),
	luamethod(LuaVoxelManip, get_light_data),
	luamethod(LuaVoxelManip, set_light_data),
	luamethod(LuaVoxelManip, get_param2_data),
	luamethod(LuaVoxelManip, set_param2_data),
	luamethod(LuaVoxelManip, was_modified),
	luamethod(LuaVoxelManip, get_emerged_area),
	{0,0}
};
>msgstr "三線性過濾器" #: builtin/mainmenu/tab_settings.lua msgid "No Mipmap" msgstr "無 Mip 貼圖" #: builtin/mainmenu/tab_settings.lua msgid "Mipmap" msgstr "Mip 貼圖" #: builtin/mainmenu/tab_settings.lua msgid "Mipmap + Aniso. Filter" msgstr "Mip 貼圖 + Aniso. 過濾器" #: builtin/mainmenu/tab_settings.lua builtin/mainmenu/tab_texturepacks.lua msgid "None" msgstr "無" #: builtin/mainmenu/tab_settings.lua msgid "2x" msgstr "2x" #: builtin/mainmenu/tab_settings.lua msgid "4x" msgstr "4x" #: builtin/mainmenu/tab_settings.lua msgid "8x" msgstr "8x" #: builtin/mainmenu/tab_settings.lua msgid "Are you sure to reset your singleplayer world?" msgstr "您確定要要重置您的單人遊戲世界嗎?" #: builtin/mainmenu/tab_settings.lua msgid "No!!!" msgstr "否!!!" #: builtin/mainmenu/tab_settings.lua msgid "Smooth Lighting" msgstr "平滑光線" #: builtin/mainmenu/tab_settings.lua msgid "Enable Particles" msgstr "啟用粒子" #: builtin/mainmenu/tab_settings.lua msgid "3D Clouds" msgstr "3D 雲朵" #: builtin/mainmenu/tab_settings.lua msgid "Opaque Water" msgstr "不透明水" #: builtin/mainmenu/tab_settings.lua msgid "Connected Glass" msgstr "連貫的玻璃" #: builtin/mainmenu/tab_settings.lua msgid "Node Highlighting" msgstr "突顯節點" #: builtin/mainmenu/tab_settings.lua msgid "Texturing:" msgstr "紋理:" #: builtin/mainmenu/tab_settings.lua msgid "Antialiasing:" msgstr "反鋸齒:" #: builtin/mainmenu/tab_settings.lua msgid "Shaders" msgstr "著色器" #: builtin/mainmenu/tab_settings.lua msgid "Change keys" msgstr "變更按鍵" #: builtin/mainmenu/tab_settings.lua msgid "Reset singleplayer world" msgstr "重置單人遊戲世界" #: builtin/mainmenu/tab_settings.lua msgid "GUI scale factor" msgstr "圖形使用者介面縮放係數" #: builtin/mainmenu/tab_settings.lua msgid "Scaling factor applied to menu elements: " msgstr "套用在選單元素的縮放係數: " #: builtin/mainmenu/tab_settings.lua msgid "Touch free target" msgstr "碰觸自由目標" #: builtin/mainmenu/tab_settings.lua msgid "Touchthreshold (px)" msgstr "碰觸限值(像素)" #: builtin/mainmenu/tab_settings.lua msgid "Bumpmapping" msgstr "映射貼圖" #: builtin/mainmenu/tab_settings.lua msgid "Generate Normalmaps" msgstr "生成一般地圖" #: builtin/mainmenu/tab_settings.lua msgid "Parallax Occlusion" msgstr "視差遮蔽" #: builtin/mainmenu/tab_settings.lua msgid "Waving Water" msgstr "波動的水" #: builtin/mainmenu/tab_settings.lua msgid "Waving Leaves" msgstr "葉子擺動" #: builtin/mainmenu/tab_settings.lua msgid "Waving Plants" msgstr "植物擺動" #: builtin/mainmenu/tab_settings.lua msgid "To enable shaders the OpenGL driver needs to be used." msgstr "要啟用著色器,必須使用 OpenGL 驅動程式。" #: builtin/mainmenu/tab_settings.lua msgid "Settings" msgstr "設定" #: builtin/mainmenu/tab_simple_main.lua msgid "Start Singleplayer" msgstr "開始單人遊戲" #: builtin/mainmenu/tab_simple_main.lua msgid "Config mods" msgstr "設定 mod" #: builtin/mainmenu/tab_simple_main.lua msgid "Main" msgstr "主要" #: builtin/mainmenu/tab_singleplayer.lua src/keycode.cpp msgid "Play" msgstr "玩" #: builtin/mainmenu/tab_singleplayer.lua msgid "Singleplayer" msgstr "單人遊戲" #: builtin/mainmenu/tab_texturepacks.lua msgid "Select texture pack:" msgstr "選取材質包:" #: builtin/mainmenu/tab_texturepacks.lua msgid "No information available" msgstr "不提供資訊" #: builtin/mainmenu/tab_texturepacks.lua msgid "Texturepacks" msgstr "材質包" #: src/client.cpp msgid "Connection timed out." msgstr "連線逾時。" #: src/client.cpp msgid "Loading textures..." msgstr "正在載入材質..." #: src/client.cpp msgid "Rebuilding shaders..." msgstr "正在重新構建著色器..." #: src/client.cpp msgid "Initializing nodes..." msgstr "正在初始化節點..." #: src/client.cpp msgid "Initializing nodes" msgstr "正在初始化節點" #: src/client.cpp msgid "Item textures..." msgstr "物品材質..." #: src/client.cpp msgid "Done!" msgstr "完成!" #: src/client/clientlauncher.cpp msgid "Main Menu" msgstr "主選單" #: src/client/clientlauncher.cpp msgid "Player name too long." msgstr "玩家名稱太長。" #: src/client/clientlauncher.cpp msgid "Connection error (timed out?)" msgstr "連線錯誤(逾時?)" #: src/client/clientlauncher.cpp msgid "No world selected and no address provided. Nothing to do." msgstr "未有已被選取的世界,且未提供地址。無事可做。" #: src/client/clientlauncher.cpp msgid "Provided world path doesn't exist: " msgstr "提供的世界路徑不存在: " #: src/client/clientlauncher.cpp msgid "Could not find or load game \"" msgstr "找不到或無法載入遊戲 \"" #: src/client/clientlauncher.cpp msgid "Invalid gamespec." msgstr "無效的遊戲規格。" #: src/fontengine.cpp msgid "needs_fallback_font" msgstr "needs_fallback_font" #: src/game.cpp src/guiFormSpecMenu.cpp msgid "Proceed" msgstr "開始" #: src/game.cpp msgid "You died." msgstr "您已經死亡。" #: src/game.cpp msgid "Respawn" msgstr "重生" #: src/game.cpp msgid "" "Default Controls:\n" "No menu visible:\n" "- single tap: button activate\n" "- double tap: place/use\n" "- slide finger: look around\n" "Menu/Inventory visible:\n" "- double tap (outside):\n" " -->close\n" "- touch stack, touch slot:\n" " --> move stack\n" "- touch&drag, tap 2nd finger\n" " --> place single item to slot\n" msgstr "" "預設控制:\n" "無可見選單:\n" "- 輕擊一次:啟動按鈕\n" "- 輕擊兩次:放置/使用\n" "- 滑動手指:轉動視角\n" "檢視選單/物品欄:\n" "- 輕擊兩次(外面):\n" " -->關閉\n" "- 碰觸堆疊,碰觸槽:\n" " --> 移動堆疊\n" "- 碰觸並拖曳,以第二隻手指輕擊\n" " --> 放置單一物品到槽中\n" #: src/game.cpp msgid "" "Default Controls:\n" "- WASD: move\n" "- Space: jump/climb\n" "- Shift: sneak/go down\n" "- Q: drop item\n" "- I: inventory\n" "- Mouse: turn/look\n" "- Mouse left: dig/punch\n" "- Mouse right: place/use\n" "- Mouse wheel: select item\n" "- T: chat\n" msgstr "" "預設控制:\n" "- WASD:移動\n" "- Space:跳躍/攀爬\n" "- Shift:潛行/往下\n" "- Q:丟棄物品\n" "- I:物品欄\n" "- 滑鼠:旋轉/觀看\n" "- 滑鼠左鍵:挖/推擠\n" "- 滑鼠右鍵:放置/使用\n" "- 滑鼠滾輪:選取物品\n" "- T:聊天\n" #: src/game.cpp msgid "Continue" msgstr "繼續" #: src/game.cpp msgid "Change Password" msgstr "變更密碼" #: src/game.cpp msgid "Sound Volume" msgstr "音量" #: src/game.cpp msgid "Change Keys" msgstr "變更按鍵" #: src/game.cpp msgid "Exit to Menu" msgstr "離開到選單" #: src/game.cpp msgid "Exit to OS" msgstr "離開到作業系統" #: src/game.cpp msgid "Shutting down..." msgstr "關閉..." #: src/game.cpp msgid "Creating server..." msgstr "正在建立伺服器..." #: src/game.cpp msgid "Creating client..." msgstr "正在建立客戶端..." #: src/game.cpp msgid "Resolving address..." msgstr "正在解析地址……" #: src/game.cpp msgid "Connecting to server..." msgstr "正在連線至伺服器..." #: src/game.cpp msgid "Item definitions..." msgstr "物品定義..." #: src/game.cpp msgid "Node definitions..." msgstr "節點定義..." #: src/game.cpp msgid "Media..." msgstr "媒體..." #: src/game.cpp msgid "KiB/s" msgstr "KiB/s" #: src/game.cpp msgid "MiB/s" msgstr "MiB/s" #: src/game.cpp msgid "" "\n" "Check debug.txt for details." msgstr "" "\n" "檢視 debug.txt 以取得更多資訊。" #: src/guiFormSpecMenu.cpp msgid "Enter " msgstr "輸入 " #: src/guiFormSpecMenu.cpp msgid "ok" msgstr "確定" #: src/guiKeyChangeMenu.cpp msgid "Keybindings. (If this menu screws up, remove stuff from minetest.conf)" msgstr "按鍵綁定。(若此選單鎖住了,從 minetest.conf 移除相關參數)" #: src/guiKeyChangeMenu.cpp msgid "\"Use\" = climb down" msgstr "「使用」=向下攀爬" #: src/guiKeyChangeMenu.cpp msgid "Double tap \"jump\" to toggle fly" msgstr "輕擊兩次「跳躍」以切換成飛行" #: src/guiKeyChangeMenu.cpp msgid "Key already in use" msgstr "此按鍵已被使用" #: src/guiKeyChangeMenu.cpp msgid "press key" msgstr "按下按鍵" #: src/guiKeyChangeMenu.cpp msgid "Forward" msgstr "前進" #: src/guiKeyChangeMenu.cpp msgid "Backward" msgstr "後退" #: src/guiKeyChangeMenu.cpp src/keycode.cpp msgid "Left" msgstr "左" #: src/guiKeyChangeMenu.cpp src/keycode.cpp msgid "Right" msgstr "右" #: src/guiKeyChangeMenu.cpp msgid "Use" msgstr "使用" #: src/guiKeyChangeMenu.cpp msgid "Jump" msgstr "跳躍" #: src/guiKeyChangeMenu.cpp msgid "Sneak" msgstr "潛行" #: src/guiKeyChangeMenu.cpp msgid "Drop" msgstr "丟棄" #: src/guiKeyChangeMenu.cpp msgid "Inventory" msgstr "物品欄" #: src/guiKeyChangeMenu.cpp msgid "Chat" msgstr "聊天" #: src/guiKeyChangeMenu.cpp msgid "Command" msgstr "指令" #: src/guiKeyChangeMenu.cpp msgid "Console" msgstr "終端機" #: src/guiKeyChangeMenu.cpp msgid "Toggle fly" msgstr "切換飛行" #: src/guiKeyChangeMenu.cpp msgid "Toggle fast" msgstr "切換快速" #: src/guiKeyChangeMenu.cpp msgid "Toggle Cinematic" msgstr "切換過場動畫" #: src/guiKeyChangeMenu.cpp msgid "Toggle noclip" msgstr "切換無省略" #: src/guiKeyChangeMenu.cpp msgid "Range select" msgstr "選擇範圍" #: src/guiKeyChangeMenu.cpp msgid "Print stacks" msgstr "印出堆疊" #: src/guiPasswordChange.cpp msgid "Old Password" msgstr "舊密碼" #: src/guiPasswordChange.cpp msgid "New Password" msgstr "新密碼" #: src/guiPasswordChange.cpp msgid "Confirm Password" msgstr "確認密碼" #: src/guiPasswordChange.cpp msgid "Change" msgstr "變更" #: src/guiPasswordChange.cpp msgid "Passwords do not match!" msgstr "密碼不符合!" #: src/guiVolumeChange.cpp msgid "Sound Volume: " msgstr "音量: " #: src/guiVolumeChange.cpp msgid "Exit" msgstr "離開" #: src/keycode.cpp msgid "Left Button" msgstr "左鍵" #: src/keycode.cpp msgid "Middle Button" msgstr "中鍵" #: src/keycode.cpp msgid "Right Button" msgstr "右鍵" #: src/keycode.cpp msgid "X Button 1" msgstr "X 按鈕 1" #: src/keycode.cpp msgid "Back" msgstr "Back" #: src/keycode.cpp msgid "Clear" msgstr "清除" #: src/keycode.cpp msgid "Return" msgstr "Return" #: src/keycode.cpp msgid "Tab" msgstr "Tab" #: src/keycode.cpp msgid "X Button 2" msgstr "X 按鈕 2" #: src/keycode.cpp msgid "Capital" msgstr "大寫" #: src/keycode.cpp msgid "Control" msgstr "Control" #: src/keycode.cpp msgid "Kana" msgstr "假名" #: src/keycode.cpp msgid "Menu" msgstr "選單" #: src/keycode.cpp msgid "Pause" msgstr "暫停" #: src/keycode.cpp msgid "Shift" msgstr "Shift" #: src/keycode.cpp msgid "Convert" msgstr "轉換" #: src/keycode.cpp msgid "Escape" msgstr "Escape" #: src/keycode.cpp msgid "Final" msgstr "Final" #: src/keycode.cpp msgid "Junja" msgstr "Junja" #: src/keycode.cpp msgid "Kanji" msgstr "日文漢字" #: src/keycode.cpp msgid "Nonconvert" msgstr "不轉換" #: src/keycode.cpp msgid "End" msgstr "End" #: src/keycode.cpp msgid "Home" msgstr "Home" #: src/keycode.cpp msgid "Mode Change" msgstr "模式變更" #: src/keycode.cpp msgid "Next" msgstr "下一個" #: src/keycode.cpp msgid "Prior" msgstr "上一個" #: src/keycode.cpp msgid "Space" msgstr "Space" #: src/keycode.cpp msgid "Down" msgstr "下" #: src/keycode.cpp msgid "Execute" msgstr "執行" #: src/keycode.cpp msgid "Print" msgstr "列印" #: src/keycode.cpp msgid "Select" msgstr "選擇" #: src/keycode.cpp msgid "Up" msgstr "上" #: src/keycode.cpp msgid "Help" msgstr "說明" #: src/keycode.cpp msgid "Insert" msgstr "插入" #: src/keycode.cpp msgid "Snapshot" msgstr "螢幕截圖" #: src/keycode.cpp msgid "Left Windows" msgstr "左方視窗" #: src/keycode.cpp msgid "Apps" msgstr "應用程式" #: src/keycode.cpp msgid "Numpad 0" msgstr "數字鍵 0" #: src/keycode.cpp msgid "Numpad 1" msgstr "數字鍵 1" #: src/keycode.cpp msgid "Right Windows" msgstr "右方視窗" #: src/keycode.cpp msgid "Sleep" msgstr "睡眠" #: src/keycode.cpp msgid "Numpad 2" msgstr "數字鍵 2" #: src/keycode.cpp msgid "Numpad 3" msgstr "數字鍵 3" #: src/keycode.cpp msgid "Numpad 4" msgstr "數字鍵 4" #: src/keycode.cpp msgid "Numpad 5" msgstr "數字鍵 5" #: src/keycode.cpp msgid "Numpad 6" msgstr "數字鍵 6" #: src/keycode.cpp msgid "Numpad 7" msgstr "數字鍵 7" #: src/keycode.cpp msgid "Numpad *" msgstr "數字鍵 *" #: src/keycode.cpp msgid "Numpad +" msgstr "數字鍵 +" #: src/keycode.cpp msgid "Numpad -" msgstr "數字鍵 -" #: src/keycode.cpp msgid "Numpad /" msgstr "數字鍵 /" #: src/keycode.cpp msgid "Numpad 8" msgstr "數字鍵 8" #: src/keycode.cpp msgid "Numpad 9" msgstr "數字鍵 9" #: src/keycode.cpp msgid "Num Lock" msgstr "Num Lock" #: src/keycode.cpp msgid "Scroll Lock" msgstr "Scroll Lock" #: src/keycode.cpp msgid "Left Shift" msgstr "左邊 Shift" #: src/keycode.cpp msgid "Right Shift" msgstr "右邊 Shift" #: src/keycode.cpp msgid "Left Control" msgstr "左邊 Control" #: src/keycode.cpp msgid "Left Menu" msgstr "左邊選單鍵" #: src/keycode.cpp msgid "Right Control" msgstr "右邊 Control" #: src/keycode.cpp msgid "Right Menu" msgstr "右邊選單鍵" #: src/keycode.cpp msgid "Comma" msgstr "逗號" #: src/keycode.cpp msgid "Minus" msgstr "減號" #: src/keycode.cpp msgid "Period" msgstr "句號" #: src/keycode.cpp msgid "Plus" msgstr "加號" #: src/keycode.cpp msgid "Attn" msgstr "Attn" #: src/keycode.cpp msgid "CrSel" msgstr "CrSel" #: src/keycode.cpp msgid "Erase OEF" msgstr "抹除 OEF" #: src/keycode.cpp msgid "ExSel" msgstr "ExSel" #: src/keycode.cpp msgid "OEM Clear" msgstr "OEM 清除" #: src/keycode.cpp msgid "PA1" msgstr "PA1" #: src/keycode.cpp msgid "Zoom" msgstr "縮放"