You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

2081 lines
56 KiB

  1. /*
  2. Minetest
  3. Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #include "lua_api/l_object.h"
  17. #include "lua_api/l_internal.h"
  18. #include "lua_api/l_inventory.h"
  19. #include "lua_api/l_item.h"
  20. #include "lua_api/l_playermeta.h"
  21. #include "common/c_converter.h"
  22. #include "common/c_content.h"
  23. #include "log.h"
  24. #include "tool.h"
  25. #include "serverobject.h"
  26. #include "content_sao.h"
  27. #include "remoteplayer.h"
  28. #include "server.h"
  29. #include "hud.h"
  30. #include "scripting_server.h"
  31. struct EnumString es_HudElementType[] =
  32. {
  33. {HUD_ELEM_IMAGE, "image"},
  34. {HUD_ELEM_TEXT, "text"},
  35. {HUD_ELEM_STATBAR, "statbar"},
  36. {HUD_ELEM_INVENTORY, "inventory"},
  37. {HUD_ELEM_WAYPOINT, "waypoint"},
  38. {0, NULL},
  39. };
  40. struct EnumString es_HudElementStat[] =
  41. {
  42. {HUD_STAT_POS, "position"},
  43. {HUD_STAT_POS, "pos"}, /* Deprecated, only for compatibility's sake */
  44. {HUD_STAT_NAME, "name"},
  45. {HUD_STAT_SCALE, "scale"},
  46. {HUD_STAT_TEXT, "text"},
  47. {HUD_STAT_NUMBER, "number"},
  48. {HUD_STAT_ITEM, "item"},
  49. {HUD_STAT_DIR, "direction"},
  50. {HUD_STAT_ALIGN, "alignment"},
  51. {HUD_STAT_OFFSET, "offset"},
  52. {HUD_STAT_WORLD_POS, "world_pos"},
  53. {0, NULL},
  54. };
  55. struct EnumString es_HudBuiltinElement[] =
  56. {
  57. {HUD_FLAG_HOTBAR_VISIBLE, "hotbar"},
  58. {HUD_FLAG_HEALTHBAR_VISIBLE, "healthbar"},
  59. {HUD_FLAG_CROSSHAIR_VISIBLE, "crosshair"},
  60. {HUD_FLAG_WIELDITEM_VISIBLE, "wielditem"},
  61. {HUD_FLAG_BREATHBAR_VISIBLE, "breathbar"},
  62. {HUD_FLAG_MINIMAP_VISIBLE, "minimap"},
  63. {HUD_FLAG_MINIMAP_RADAR_VISIBLE, "minimap_radar"},
  64. {0, NULL},
  65. };
  66. /*
  67. ObjectRef
  68. */
  69. ObjectRef* ObjectRef::checkobject(lua_State *L, int narg)
  70. {
  71. luaL_checktype(L, narg, LUA_TUSERDATA);
  72. void *ud = luaL_checkudata(L, narg, className);
  73. if (!ud) luaL_typerror(L, narg, className);
  74. return *(ObjectRef**)ud; // unbox pointer
  75. }
  76. ServerActiveObject* ObjectRef::getobject(ObjectRef *ref)
  77. {
  78. ServerActiveObject *co = ref->m_object;
  79. return co;
  80. }
  81. LuaEntitySAO* ObjectRef::getluaobject(ObjectRef *ref)
  82. {
  83. ServerActiveObject *obj = getobject(ref);
  84. if (obj == NULL)
  85. return NULL;
  86. if (obj->getType() != ACTIVEOBJECT_TYPE_LUAENTITY)
  87. return NULL;
  88. return (LuaEntitySAO*)obj;
  89. }
  90. PlayerSAO* ObjectRef::getplayersao(ObjectRef *ref)
  91. {
  92. ServerActiveObject *obj = getobject(ref);
  93. if (obj == NULL)
  94. return NULL;
  95. if (obj->getType() != ACTIVEOBJECT_TYPE_PLAYER)
  96. return NULL;
  97. return (PlayerSAO*)obj;
  98. }
  99. RemotePlayer *ObjectRef::getplayer(ObjectRef *ref)
  100. {
  101. PlayerSAO *playersao = getplayersao(ref);
  102. if (playersao == NULL)
  103. return NULL;
  104. return playersao->getPlayer();
  105. }
  106. // Exported functions
  107. // garbage collector
  108. int ObjectRef::gc_object(lua_State *L) {
  109. ObjectRef *o = *(ObjectRef **)(lua_touserdata(L, 1));
  110. //infostream<<"ObjectRef::gc_object: o="<<o<<std::endl;
  111. delete o;
  112. return 0;
  113. }
  114. // remove(self)
  115. int ObjectRef::l_remove(lua_State *L)
  116. {
  117. GET_ENV_PTR;
  118. ObjectRef *ref = checkobject(L, 1);
  119. ServerActiveObject *co = getobject(ref);
  120. if (co == NULL)
  121. return 0;
  122. if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
  123. return 0;
  124. const std::unordered_set<int> &child_ids = co->getAttachmentChildIds();
  125. for (int child_id : child_ids) {
  126. // Child can be NULL if it was deleted earlier
  127. if (ServerActiveObject *child = env->getActiveObject(child_id))
  128. child->setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0));
  129. }
  130. verbosestream << "ObjectRef::l_remove(): id=" << co->getId() << std::endl;
  131. co->m_pending_removal = true;
  132. return 0;
  133. }
  134. // get_pos(self)
  135. // returns: {x=num, y=num, z=num}
  136. int ObjectRef::l_get_pos(lua_State *L)
  137. {
  138. NO_MAP_LOCK_REQUIRED;
  139. ObjectRef *ref = checkobject(L, 1);
  140. ServerActiveObject *co = getobject(ref);
  141. if (co == NULL) return 0;
  142. v3f pos = co->getBasePosition() / BS;
  143. lua_newtable(L);
  144. lua_pushnumber(L, pos.X);
  145. lua_setfield(L, -2, "x");
  146. lua_pushnumber(L, pos.Y);
  147. lua_setfield(L, -2, "y");
  148. lua_pushnumber(L, pos.Z);
  149. lua_setfield(L, -2, "z");
  150. return 1;
  151. }
  152. // set_pos(self, pos)
  153. int ObjectRef::l_set_pos(lua_State *L)
  154. {
  155. NO_MAP_LOCK_REQUIRED;
  156. ObjectRef *ref = checkobject(L, 1);
  157. //LuaEntitySAO *co = getluaobject(ref);
  158. ServerActiveObject *co = getobject(ref);
  159. if (co == NULL) return 0;
  160. // pos
  161. v3f pos = checkFloatPos(L, 2);
  162. // Do it
  163. co->setPos(pos);
  164. return 0;
  165. }
  166. // move_to(self, pos, continuous=false)
  167. int ObjectRef::l_move_to(lua_State *L)
  168. {
  169. NO_MAP_LOCK_REQUIRED;
  170. ObjectRef *ref = checkobject(L, 1);
  171. //LuaEntitySAO *co = getluaobject(ref);
  172. ServerActiveObject *co = getobject(ref);
  173. if (co == NULL) return 0;
  174. // pos
  175. v3f pos = checkFloatPos(L, 2);
  176. // continuous
  177. bool continuous = readParam<bool>(L, 3);
  178. // Do it
  179. co->moveTo(pos, continuous);
  180. return 0;
  181. }
  182. // punch(self, puncher, time_from_last_punch, tool_capabilities, dir)
  183. int ObjectRef::l_punch(lua_State *L)
  184. {
  185. NO_MAP_LOCK_REQUIRED;
  186. ObjectRef *ref = checkobject(L, 1);
  187. ObjectRef *puncher_ref = checkobject(L, 2);
  188. ServerActiveObject *co = getobject(ref);
  189. ServerActiveObject *puncher = getobject(puncher_ref);
  190. if (co == NULL) return 0;
  191. if (puncher == NULL) return 0;
  192. v3f dir;
  193. if (lua_type(L, 5) != LUA_TTABLE)
  194. dir = co->getBasePosition() - puncher->getBasePosition();
  195. else
  196. dir = read_v3f(L, 5);
  197. float time_from_last_punch = 1000000;
  198. if (lua_isnumber(L, 3))
  199. time_from_last_punch = lua_tonumber(L, 3);
  200. ToolCapabilities toolcap = read_tool_capabilities(L, 4);
  201. dir.normalize();
  202. s16 src_original_hp = co->getHP();
  203. s16 dst_origin_hp = puncher->getHP();
  204. // Do it
  205. co->punch(dir, &toolcap, puncher, time_from_last_punch);
  206. // If the punched is a player, and its HP changed
  207. if (src_original_hp != co->getHP() &&
  208. co->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
  209. getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co, PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, puncher));
  210. }
  211. // If the puncher is a player, and its HP changed
  212. if (dst_origin_hp != puncher->getHP() &&
  213. puncher->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
  214. getServer(L)->SendPlayerHPOrDie((PlayerSAO *)puncher,
  215. PlayerHPChangeReason(PlayerHPChangeReason::PLAYER_PUNCH, co));
  216. }
  217. return 0;
  218. }
  219. // right_click(self, clicker); clicker = an another ObjectRef
  220. int ObjectRef::l_right_click(lua_State *L)
  221. {
  222. NO_MAP_LOCK_REQUIRED;
  223. ObjectRef *ref = checkobject(L, 1);
  224. ObjectRef *ref2 = checkobject(L, 2);
  225. ServerActiveObject *co = getobject(ref);
  226. ServerActiveObject *co2 = getobject(ref2);
  227. if (co == NULL) return 0;
  228. if (co2 == NULL) return 0;
  229. // Do it
  230. co->rightClick(co2);
  231. return 0;
  232. }
  233. // set_hp(self, hp)
  234. // hp = number of hitpoints (2 * number of hearts)
  235. // returns: nil
  236. int ObjectRef::l_set_hp(lua_State *L)
  237. {
  238. NO_MAP_LOCK_REQUIRED;
  239. // Get Object
  240. ObjectRef *ref = checkobject(L, 1);
  241. luaL_checknumber(L, 2);
  242. ServerActiveObject *co = getobject(ref);
  243. if (co == NULL)
  244. return 0;
  245. // Get HP
  246. int hp = lua_tonumber(L, 2);
  247. // Get Reason
  248. PlayerHPChangeReason reason(PlayerHPChangeReason::SET_HP);
  249. reason.from_mod = true;
  250. if (lua_istable(L, 3)) {
  251. lua_pushvalue(L, 3);
  252. lua_getfield(L, -1, "type");
  253. if (lua_isstring(L, -1) &&
  254. !reason.setTypeFromString(readParam<std::string>(L, -1))) {
  255. errorstream << "Bad type given!" << std::endl;
  256. }
  257. lua_pop(L, 1);
  258. reason.lua_reference = luaL_ref(L, LUA_REGISTRYINDEX);
  259. }
  260. // Do it
  261. co->setHP(hp, reason);
  262. if (co->getType() == ACTIVEOBJECT_TYPE_PLAYER)
  263. {
  264. getServer(L)->SendPlayerHPOrDie((PlayerSAO *)co, reason);
  265. }
  266. if (reason.hasLuaReference())
  267. {
  268. luaL_unref(L, LUA_REGISTRYINDEX, reason.lua_reference);
  269. }
  270. // Return
  271. return 0;
  272. }
  273. // get_hp(self)
  274. // returns: number of hitpoints (2 * number of hearts)
  275. // 0 if not applicable to this type of object
  276. int ObjectRef::l_get_hp(lua_State *L)
  277. {
  278. NO_MAP_LOCK_REQUIRED;
  279. ObjectRef *ref = checkobject(L, 1);
  280. ServerActiveObject *co = getobject(ref);
  281. if (co == NULL) {
  282. // Default hp is 1
  283. lua_pushnumber(L, 1);
  284. return 1;
  285. }
  286. int hp = co->getHP();
  287. /*infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
  288. <<" hp="<<hp<<std::endl;*/
  289. // Return
  290. lua_pushnumber(L, hp);
  291. return 1;
  292. }
  293. // get_inventory(self)
  294. int ObjectRef::l_get_inventory(lua_State *L)
  295. {
  296. NO_MAP_LOCK_REQUIRED;
  297. ObjectRef *ref = checkobject(L, 1);
  298. ServerActiveObject *co = getobject(ref);
  299. if (co == NULL) return 0;
  300. // Do it
  301. InventoryLocation loc = co->getInventoryLocation();
  302. if (getServer(L)->getInventory(loc) != NULL)
  303. InvRef::create(L, loc);
  304. else
  305. lua_pushnil(L); // An object may have no inventory (nil)
  306. return 1;
  307. }
  308. // get_wield_list(self)
  309. int ObjectRef::l_get_wield_list(lua_State *L)
  310. {
  311. NO_MAP_LOCK_REQUIRED;
  312. ObjectRef *ref = checkobject(L, 1);
  313. ServerActiveObject *co = getobject(ref);
  314. if (co == NULL) return 0;
  315. // Do it
  316. lua_pushstring(L, co->getWieldList().c_str());
  317. return 1;
  318. }
  319. // get_wield_index(self)
  320. int ObjectRef::l_get_wield_index(lua_State *L)
  321. {
  322. NO_MAP_LOCK_REQUIRED;
  323. ObjectRef *ref = checkobject(L, 1);
  324. ServerActiveObject *co = getobject(ref);
  325. if (co == NULL) return 0;
  326. // Do it
  327. lua_pushinteger(L, co->getWieldIndex() + 1);
  328. return 1;
  329. }
  330. // get_wielded_item(self)
  331. int ObjectRef::l_get_wielded_item(lua_State *L)
  332. {
  333. NO_MAP_LOCK_REQUIRED;
  334. ObjectRef *ref = checkobject(L, 1);
  335. ServerActiveObject *co = getobject(ref);
  336. if (co == NULL) {
  337. // Empty ItemStack
  338. LuaItemStack::create(L, ItemStack());
  339. return 1;
  340. }
  341. // Do it
  342. LuaItemStack::create(L, co->getWieldedItem());
  343. return 1;
  344. }
  345. // set_wielded_item(self, itemstack or itemstring or table or nil)
  346. int ObjectRef::l_set_wielded_item(lua_State *L)
  347. {
  348. NO_MAP_LOCK_REQUIRED;
  349. ObjectRef *ref = checkobject(L, 1);
  350. ServerActiveObject *co = getobject(ref);
  351. if (co == NULL) return 0;
  352. // Do it
  353. ItemStack item = read_item(L, 2, getServer(L)->idef());
  354. bool success = co->setWieldedItem(item);
  355. if (success && co->getType() == ACTIVEOBJECT_TYPE_PLAYER) {
  356. getServer(L)->SendInventory(((PlayerSAO*)co));
  357. }
  358. lua_pushboolean(L, success);
  359. return 1;
  360. }
  361. // set_armor_groups(self, groups)
  362. int ObjectRef::l_set_armor_groups(lua_State *L)
  363. {
  364. NO_MAP_LOCK_REQUIRED;
  365. ObjectRef *ref = checkobject(L, 1);
  366. ServerActiveObject *co = getobject(ref);
  367. if (co == NULL) return 0;
  368. // Do it
  369. ItemGroupList groups;
  370. read_groups(L, 2, groups);
  371. co->setArmorGroups(groups);
  372. return 0;
  373. }
  374. // get_armor_groups(self)
  375. int ObjectRef::l_get_armor_groups(lua_State *L)
  376. {
  377. NO_MAP_LOCK_REQUIRED;
  378. ObjectRef *ref = checkobject(L, 1);
  379. ServerActiveObject *co = getobject(ref);
  380. if (co == NULL)
  381. return 0;
  382. // Do it
  383. push_groups(L, co->getArmorGroups());
  384. return 1;
  385. }
  386. // set_physics_override(self, physics_override_speed, physics_override_jump,
  387. // physics_override_gravity, sneak, sneak_glitch, new_move)
  388. int ObjectRef::l_set_physics_override(lua_State *L)
  389. {
  390. NO_MAP_LOCK_REQUIRED;
  391. ObjectRef *ref = checkobject(L, 1);
  392. PlayerSAO *co = (PlayerSAO *) getobject(ref);
  393. if (co == NULL) return 0;
  394. // Do it
  395. if (lua_istable(L, 2)) {
  396. co->m_physics_override_speed = getfloatfield_default(
  397. L, 2, "speed", co->m_physics_override_speed);
  398. co->m_physics_override_jump = getfloatfield_default(
  399. L, 2, "jump", co->m_physics_override_jump);
  400. co->m_physics_override_gravity = getfloatfield_default(
  401. L, 2, "gravity", co->m_physics_override_gravity);
  402. co->m_physics_override_sneak = getboolfield_default(
  403. L, 2, "sneak", co->m_physics_override_sneak);
  404. co->m_physics_override_sneak_glitch = getboolfield_default(
  405. L, 2, "sneak_glitch", co->m_physics_override_sneak_glitch);
  406. co->m_physics_override_new_move = getboolfield_default(
  407. L, 2, "new_move", co->m_physics_override_new_move);
  408. co->m_physics_override_sent = false;
  409. } else {
  410. // old, non-table format
  411. if (!lua_isnil(L, 2)) {
  412. co->m_physics_override_speed = lua_tonumber(L, 2);
  413. co->m_physics_override_sent = false;
  414. }
  415. if (!lua_isnil(L, 3)) {
  416. co->m_physics_override_jump = lua_tonumber(L, 3);
  417. co->m_physics_override_sent = false;
  418. }
  419. if (!lua_isnil(L, 4)) {
  420. co->m_physics_override_gravity = lua_tonumber(L, 4);
  421. co->m_physics_override_sent = false;
  422. }
  423. }
  424. return 0;
  425. }
  426. // get_physics_override(self)
  427. int ObjectRef::l_get_physics_override(lua_State *L)
  428. {
  429. NO_MAP_LOCK_REQUIRED;
  430. ObjectRef *ref = checkobject(L, 1);
  431. PlayerSAO *co = (PlayerSAO *)getobject(ref);
  432. if (co == NULL)
  433. return 0;
  434. // Do it
  435. lua_newtable(L);
  436. lua_pushnumber(L, co->m_physics_override_speed);
  437. lua_setfield(L, -2, "speed");
  438. lua_pushnumber(L, co->m_physics_override_jump);
  439. lua_setfield(L, -2, "jump");
  440. lua_pushnumber(L, co->m_physics_override_gravity);
  441. lua_setfield(L, -2, "gravity");
  442. lua_pushboolean(L, co->m_physics_override_sneak);
  443. lua_setfield(L, -2, "sneak");
  444. lua_pushboolean(L, co->m_physics_override_sneak_glitch);
  445. lua_setfield(L, -2, "sneak_glitch");
  446. lua_pushboolean(L, co->m_physics_override_new_move);
  447. lua_setfield(L, -2, "new_move");
  448. return 1;
  449. }
  450. // set_animation(self, frame_range, frame_speed, frame_blend, frame_loop)
  451. int ObjectRef::l_set_animation(lua_State *L)
  452. {
  453. NO_MAP_LOCK_REQUIRED;
  454. ObjectRef *ref = checkobject(L, 1);
  455. ServerActiveObject *co = getobject(ref);
  456. if (co == NULL) return 0;
  457. // Do it
  458. v2f frames = v2f(1, 1);
  459. if (!lua_isnil(L, 2))
  460. frames = read_v2f(L, 2);
  461. float frame_speed = 15;
  462. if (!lua_isnil(L, 3))
  463. frame_speed = lua_tonumber(L, 3);
  464. float frame_blend = 0;
  465. if (!lua_isnil(L, 4))
  466. frame_blend = lua_tonumber(L, 4);
  467. bool frame_loop = true;
  468. if (lua_isboolean(L, 5))
  469. frame_loop = readParam<bool>(L, 5);
  470. co->setAnimation(frames, frame_speed, frame_blend, frame_loop);
  471. return 0;
  472. }
  473. // get_animation(self)
  474. int ObjectRef::l_get_animation(lua_State *L)
  475. {
  476. NO_MAP_LOCK_REQUIRED;
  477. ObjectRef *ref = checkobject(L, 1);
  478. ServerActiveObject *co = getobject(ref);
  479. if (co == NULL)
  480. return 0;
  481. // Do it
  482. v2f frames = v2f(1,1);
  483. float frame_speed = 15;
  484. float frame_blend = 0;
  485. bool frame_loop = true;
  486. co->getAnimation(&frames, &frame_speed, &frame_blend, &frame_loop);
  487. push_v2f(L, frames);
  488. lua_pushnumber(L, frame_speed);
  489. lua_pushnumber(L, frame_blend);
  490. lua_pushboolean(L, frame_loop);
  491. return 4;
  492. }
  493. // set_local_animation(self, {stand/idle}, {walk}, {dig}, {walk+dig}, frame_speed)
  494. int ObjectRef::l_set_local_animation(lua_State *L)
  495. {
  496. NO_MAP_LOCK_REQUIRED;
  497. ObjectRef *ref = checkobject(L, 1);
  498. RemotePlayer *player = getplayer(ref);
  499. if (player == NULL)
  500. return 0;
  501. // Do it
  502. v2s32 frames[4];
  503. for (int i=0;i<4;i++) {
  504. if (!lua_isnil(L, 2+1))
  505. frames[i] = read_v2s32(L, 2+i);
  506. }
  507. float frame_speed = 30;
  508. if (!lua_isnil(L, 6))
  509. frame_speed = lua_tonumber(L, 6);
  510. if (!getServer(L)->setLocalPlayerAnimations(player, frames, frame_speed))
  511. return 0;
  512. lua_pushboolean(L, true);
  513. return 0;
  514. }
  515. // get_local_animation(self)
  516. int ObjectRef::l_get_local_animation(lua_State *L)
  517. {
  518. NO_MAP_LOCK_REQUIRED
  519. ObjectRef *ref = checkobject(L, 1);
  520. RemotePlayer *player = getplayer(ref);
  521. if (player == NULL)
  522. return 0;
  523. v2s32 frames[4];
  524. float frame_speed;
  525. player->getLocalAnimations(frames, &frame_speed);
  526. for (int i = 0; i < 4; i++) {
  527. push_v2s32(L, frames[i]);
  528. }
  529. lua_pushnumber(L, frame_speed);
  530. return 5;
  531. }
  532. // set_eye_offset(self, v3f first pv, v3f third pv)
  533. int ObjectRef::l_set_eye_offset(lua_State *L)
  534. {
  535. NO_MAP_LOCK_REQUIRED;
  536. ObjectRef *ref = checkobject(L, 1);
  537. RemotePlayer *player = getplayer(ref);
  538. if (player == NULL)
  539. return 0;
  540. // Do it
  541. v3f offset_first = v3f(0, 0, 0);
  542. v3f offset_third = v3f(0, 0, 0);
  543. if (!lua_isnil(L, 2))
  544. offset_first = read_v3f(L, 2);
  545. if (!lua_isnil(L, 3))
  546. offset_third = read_v3f(L, 3);
  547. // Prevent abuse of offset values (keep player always visible)
  548. offset_third.X = rangelim(offset_third.X,-10,10);
  549. offset_third.Z = rangelim(offset_third.Z,-5,5);
  550. /* TODO: if possible: improve the camera colision detetion to allow Y <= -1.5) */
  551. offset_third.Y = rangelim(offset_third.Y,-10,15); //1.5*BS
  552. if (!getServer(L)->setPlayerEyeOffset(player, offset_first, offset_third))
  553. return 0;
  554. lua_pushboolean(L, true);
  555. return 0;
  556. }
  557. // get_eye_offset(self)
  558. int ObjectRef::l_get_eye_offset(lua_State *L)
  559. {
  560. NO_MAP_LOCK_REQUIRED;
  561. ObjectRef *ref = checkobject(L, 1);
  562. RemotePlayer *player = getplayer(ref);
  563. if (player == NULL)
  564. return 0;
  565. // Do it
  566. push_v3f(L, player->eye_offset_first);
  567. push_v3f(L, player->eye_offset_third);
  568. return 2;
  569. }
  570. // send_mapblock(self, pos)
  571. int ObjectRef::l_send_mapblock(lua_State *L)
  572. {
  573. NO_MAP_LOCK_REQUIRED;
  574. ObjectRef *ref = checkobject(L, 1);
  575. RemotePlayer *player = getplayer(ref);
  576. if (!player)
  577. return 0;
  578. v3s16 p = read_v3s16(L, 2);
  579. u16 peer_id = player->getPeerId();
  580. bool r = getServer(L)->SendBlock(peer_id, p);
  581. lua_pushboolean(L, r);
  582. return 1;
  583. }
  584. // set_animation_frame_speed(self, frame_speed)
  585. int ObjectRef::l_set_animation_frame_speed(lua_State *L)
  586. {
  587. NO_MAP_LOCK_REQUIRED;
  588. ObjectRef *ref = checkobject(L, 1);
  589. ServerActiveObject *co = getobject(ref);
  590. if (co == NULL)
  591. return 0;
  592. // Do it
  593. if (!lua_isnil(L, 2)) {
  594. float frame_speed = lua_tonumber(L, 2);
  595. co->setAnimationSpeed(frame_speed);
  596. lua_pushboolean(L, true);
  597. } else {
  598. lua_pushboolean(L, false);
  599. }
  600. return 1;
  601. }
  602. // set_bone_position(self, std::string bone, v3f position, v3f rotation)
  603. int ObjectRef::l_set_bone_position(lua_State *L)
  604. {
  605. NO_MAP_LOCK_REQUIRED;
  606. ObjectRef *ref = checkobject(L, 1);
  607. ServerActiveObject *co = getobject(ref);
  608. if (co == NULL) return 0;
  609. // Do it
  610. std::string bone = "";
  611. if (!lua_isnil(L, 2))
  612. bone = readParam<std::string>(L, 2);
  613. v3f position = v3f(0, 0, 0);
  614. if (!lua_isnil(L, 3))
  615. position = check_v3f(L, 3);
  616. v3f rotation = v3f(0, 0, 0);
  617. if (!lua_isnil(L, 4))
  618. rotation = check_v3f(L, 4);
  619. co->setBonePosition(bone, position, rotation);
  620. return 0;
  621. }
  622. // get_bone_position(self, bone)
  623. int ObjectRef::l_get_bone_position(lua_State *L)
  624. {
  625. NO_MAP_LOCK_REQUIRED;
  626. ObjectRef *ref = checkobject(L, 1);
  627. ServerActiveObject *co = getobject(ref);
  628. if (co == NULL)
  629. return 0;
  630. // Do it
  631. std::string bone = "";
  632. if (!lua_isnil(L, 2))
  633. bone = readParam<std::string>(L, 2);
  634. v3f position = v3f(0, 0, 0);
  635. v3f rotation = v3f(0, 0, 0);
  636. co->getBonePosition(bone, &position, &rotation);
  637. push_v3f(L, position);
  638. push_v3f(L, rotation);
  639. return 2;
  640. }
  641. // set_attach(self, parent, bone, position, rotation)
  642. int ObjectRef::l_set_attach(lua_State *L)
  643. {
  644. GET_ENV_PTR;
  645. ObjectRef *ref = checkobject(L, 1);
  646. ObjectRef *parent_ref = checkobject(L, 2);
  647. ServerActiveObject *co = getobject(ref);
  648. ServerActiveObject *parent = getobject(parent_ref);
  649. if (co == NULL)
  650. return 0;
  651. if (parent == NULL)
  652. return 0;
  653. // Do it
  654. int parent_id = 0;
  655. std::string bone = "";
  656. v3f position = v3f(0, 0, 0);
  657. v3f rotation = v3f(0, 0, 0);
  658. co->getAttachment(&parent_id, &bone, &position, &rotation);
  659. if (parent_id) {
  660. ServerActiveObject *old_parent = env->getActiveObject(parent_id);
  661. old_parent->removeAttachmentChild(co->getId());
  662. }
  663. bone = "";
  664. if (!lua_isnil(L, 3))
  665. bone = readParam<std::string>(L, 3);
  666. position = v3f(0, 0, 0);
  667. if (!lua_isnil(L, 4))
  668. position = read_v3f(L, 4);
  669. rotation = v3f(0, 0, 0);
  670. if (!lua_isnil(L, 5))
  671. rotation = read_v3f(L, 5);
  672. co->setAttachment(parent->getId(), bone, position, rotation);
  673. parent->addAttachmentChild(co->getId());
  674. return 0;
  675. }
  676. // get_attach(self)
  677. int ObjectRef::l_get_attach(lua_State *L)
  678. {
  679. GET_ENV_PTR;
  680. ObjectRef *ref = checkobject(L, 1);
  681. ServerActiveObject *co = getobject(ref);
  682. if (co == NULL)
  683. return 0;
  684. // Do it
  685. int parent_id = 0;
  686. std::string bone = "";
  687. v3f position = v3f(0, 0, 0);
  688. v3f rotation = v3f(0, 0, 0);
  689. co->getAttachment(&parent_id, &bone, &position, &rotation);
  690. if (!parent_id)
  691. return 0;
  692. ServerActiveObject *parent = env->getActiveObject(parent_id);
  693. getScriptApiBase(L)->objectrefGetOrCreate(L, parent);
  694. lua_pushlstring(L, bone.c_str(), bone.size());
  695. push_v3f(L, position);
  696. push_v3f(L, rotation);
  697. return 4;
  698. }
  699. // set_detach(self)
  700. int ObjectRef::l_set_detach(lua_State *L)
  701. {
  702. GET_ENV_PTR;
  703. ObjectRef *ref = checkobject(L, 1);
  704. ServerActiveObject *co = getobject(ref);
  705. if (co == NULL)
  706. return 0;
  707. int parent_id = 0;
  708. std::string bone = "";
  709. v3f position;
  710. v3f rotation;
  711. co->getAttachment(&parent_id, &bone, &position, &rotation);
  712. ServerActiveObject *parent = NULL;
  713. if (parent_id) {
  714. parent = env->getActiveObject(parent_id);
  715. co->setAttachment(0, "", position, rotation);
  716. } else {
  717. co->setAttachment(0, "", v3f(0, 0, 0), v3f(0, 0, 0));
  718. }
  719. // Do it
  720. if (parent != NULL)
  721. parent->removeAttachmentChild(co->getId());
  722. return 0;
  723. }
  724. // set_properties(self, properties)
  725. int ObjectRef::l_set_properties(lua_State *L)
  726. {
  727. NO_MAP_LOCK_REQUIRED;
  728. ObjectRef *ref = checkobject(L, 1);
  729. ServerActiveObject *co = getobject(ref);
  730. if (co == NULL) return 0;
  731. ObjectProperties *prop = co->accessObjectProperties();
  732. if (!prop)
  733. return 0;
  734. read_object_properties(L, 2, prop, getServer(L)->idef());
  735. co->notifyObjectPropertiesModified();
  736. return 0;
  737. }
  738. // get_properties(self)
  739. int ObjectRef::l_get_properties(lua_State *L)
  740. {
  741. NO_MAP_LOCK_REQUIRED;
  742. ObjectRef *ref = checkobject(L, 1);
  743. ServerActiveObject *co = getobject(ref);
  744. if (co == NULL)
  745. return 0;
  746. ObjectProperties *prop = co->accessObjectProperties();
  747. if (!prop)
  748. return 0;
  749. push_object_properties(L, prop);
  750. return 1;
  751. }
  752. // is_player(self)
  753. int ObjectRef::l_is_player(lua_State *L)
  754. {
  755. NO_MAP_LOCK_REQUIRED;
  756. ObjectRef *ref = checkobject(L, 1);
  757. RemotePlayer *player = getplayer(ref);
  758. lua_pushboolean(L, (player != NULL));
  759. return 1;
  760. }
  761. // set_nametag_attributes(self, attributes)
  762. int ObjectRef::l_set_nametag_attributes(lua_State *L)
  763. {
  764. NO_MAP_LOCK_REQUIRED;
  765. ObjectRef *ref = checkobject(L, 1);
  766. ServerActiveObject *co = getobject(ref);
  767. if (co == NULL)
  768. return 0;
  769. ObjectProperties *prop = co->accessObjectProperties();
  770. if (!prop)
  771. return 0;
  772. lua_getfield(L, 2, "color");
  773. if (!lua_isnil(L, -1)) {
  774. video::SColor color = prop->nametag_color;
  775. read_color(L, -1, &color);
  776. prop->nametag_color = color;
  777. }
  778. lua_pop(L, 1);
  779. std::string nametag = getstringfield_default(L, 2, "text", "");
  780. prop->nametag = nametag;
  781. co->notifyObjectPropertiesModified();
  782. lua_pushboolean(L, true);
  783. return 1;
  784. }
  785. // get_nametag_attributes(self)
  786. int ObjectRef::l_get_nametag_attributes(lua_State *L)
  787. {
  788. NO_MAP_LOCK_REQUIRED;
  789. ObjectRef *ref = checkobject(L, 1);
  790. ServerActiveObject *co = getobject(ref);
  791. if (co == NULL)
  792. return 0;
  793. ObjectProperties *prop = co->accessObjectProperties();
  794. if (!prop)
  795. return 0;
  796. video::SColor color = prop->nametag_color;
  797. lua_newtable(L);
  798. push_ARGB8(L, color);
  799. lua_setfield(L, -2, "color");
  800. lua_pushstring(L, prop->nametag.c_str());
  801. lua_setfield(L, -2, "text");
  802. return 1;
  803. }
  804. /* LuaEntitySAO-only */
  805. // set_velocity(self, {x=num, y=num, z=num})
  806. int ObjectRef::l_set_velocity(lua_State *L)
  807. {
  808. NO_MAP_LOCK_REQUIRED;
  809. ObjectRef *ref = checkobject(L, 1);
  810. LuaEntitySAO *co = getluaobject(ref);
  811. if (co == NULL) return 0;
  812. v3f pos = checkFloatPos(L, 2);
  813. // Do it
  814. co->setVelocity(pos);
  815. return 0;
  816. }
  817. // add_velocity(self, {x=num, y=num, z=num})
  818. int ObjectRef::l_add_velocity(lua_State *L)
  819. {
  820. NO_MAP_LOCK_REQUIRED;
  821. ObjectRef *ref = checkobject(L, 1);
  822. LuaEntitySAO *co = getluaobject(ref);
  823. if (!co)
  824. return 0;
  825. v3f pos = checkFloatPos(L, 2);
  826. // Do it
  827. co->addVelocity(pos);
  828. return 0;
  829. }
  830. // get_velocity(self)
  831. int ObjectRef::l_get_velocity(lua_State *L)
  832. {
  833. NO_MAP_LOCK_REQUIRED;
  834. ObjectRef *ref = checkobject(L, 1);
  835. LuaEntitySAO *co = getluaobject(ref);
  836. if (co == NULL) return 0;
  837. // Do it
  838. v3f v = co->getVelocity();
  839. pushFloatPos(L, v);
  840. return 1;
  841. }
  842. // set_acceleration(self, {x=num, y=num, z=num})
  843. int ObjectRef::l_set_acceleration(lua_State *L)
  844. {
  845. NO_MAP_LOCK_REQUIRED;
  846. ObjectRef *ref = checkobject(L, 1);
  847. LuaEntitySAO *co = getluaobject(ref);
  848. if (co == NULL) return 0;
  849. // pos
  850. v3f pos = checkFloatPos(L, 2);
  851. // Do it
  852. co->setAcceleration(pos);
  853. return 0;
  854. }
  855. // get_acceleration(self)
  856. int ObjectRef::l_get_acceleration(lua_State *L)
  857. {
  858. NO_MAP_LOCK_REQUIRED;
  859. ObjectRef *ref = checkobject(L, 1);
  860. LuaEntitySAO *co = getluaobject(ref);
  861. if (co == NULL) return 0;
  862. // Do it
  863. v3f v = co->getAcceleration();
  864. pushFloatPos(L, v);
  865. return 1;
  866. }
  867. // set_yaw(self, radians)
  868. int ObjectRef::l_set_yaw(lua_State *L)
  869. {
  870. NO_MAP_LOCK_REQUIRED;
  871. ObjectRef *ref = checkobject(L, 1);
  872. LuaEntitySAO *co = getluaobject(ref);
  873. if (co == NULL) return 0;
  874. if (isNaN(L, 2))
  875. throw LuaError("ObjectRef::set_yaw: NaN value is not allowed.");
  876. float yaw = readParam<float>(L, 2) * core::RADTODEG;
  877. // Do it
  878. co->setYaw(yaw);
  879. return 0;
  880. }
  881. // get_yaw(self)
  882. int ObjectRef::l_get_yaw(lua_State *L)
  883. {
  884. NO_MAP_LOCK_REQUIRED;
  885. ObjectRef *ref = checkobject(L, 1);
  886. LuaEntitySAO *co = getluaobject(ref);
  887. if (co == NULL) return 0;
  888. // Do it
  889. float yaw = co->getYaw() * core::DEGTORAD;
  890. lua_pushnumber(L, yaw);
  891. return 1;
  892. }
  893. // set_rotation(self, {x=num, y=num, z=num})
  894. // Each 'num' is in radians
  895. int ObjectRef::l_set_rotation(lua_State *L)
  896. {
  897. NO_MAP_LOCK_REQUIRED;
  898. return 0;
  899. }
  900. int ObjectRef::l_get_rotation (lua_State *L)
  901. {
  902. NO_MAP_LOCK_REQUIRED;
  903. ObjectRef *ref = checkobject (L, 1);
  904. LuaEntitySAO *co = getluaobject (ref);
  905. if (!co) return 0;
  906. lua_newtable (L);
  907. v3f rotation = v3f (0,0,0);
  908. push_v3f (L, rotation);
  909. return 1;
  910. }
  911. // set_texture_mod(self, mod)
  912. int ObjectRef::l_set_texture_mod(lua_State *L)
  913. {
  914. NO_MAP_LOCK_REQUIRED;
  915. ObjectRef *ref = checkobject(L, 1);
  916. LuaEntitySAO *co = getluaobject(ref);
  917. if (co == NULL) return 0;
  918. // Do it
  919. std::string mod = luaL_checkstring(L, 2);
  920. co->setTextureMod(mod);
  921. return 0;
  922. }
  923. // get_texture_mod(self)
  924. int ObjectRef::l_get_texture_mod(lua_State *L)
  925. {
  926. NO_MAP_LOCK_REQUIRED;
  927. ObjectRef *ref = checkobject(L, 1);
  928. LuaEntitySAO *co = getluaobject(ref);
  929. if (co == NULL) return 0;
  930. // Do it
  931. std::string mod = co->getTextureMod();
  932. lua_pushstring(L, mod.c_str());
  933. return 1;
  934. }
  935. // set_sprite(self, p={x=0,y=0}, num_frames=1, framelength=0.2,
  936. // select_horiz_by_yawpitch=false)
  937. int ObjectRef::l_set_sprite(lua_State *L)
  938. {
  939. NO_MAP_LOCK_REQUIRED;
  940. ObjectRef *ref = checkobject(L, 1);
  941. LuaEntitySAO *co = getluaobject(ref);
  942. if (co == NULL) return 0;
  943. // Do it
  944. v2s16 p(0,0);
  945. if (!lua_isnil(L, 2))
  946. p = read_v2s16(L, 2);
  947. int num_frames = 1;
  948. if (!lua_isnil(L, 3))
  949. num_frames = lua_tonumber(L, 3);
  950. float framelength = 0.2;
  951. if (!lua_isnil(L, 4))
  952. framelength = lua_tonumber(L, 4);
  953. bool select_horiz_by_yawpitch = false;
  954. if (!lua_isnil(L, 5))
  955. select_horiz_by_yawpitch = readParam<bool>(L, 5);
  956. co->setSprite(p, num_frames, framelength, select_horiz_by_yawpitch);
  957. return 0;
  958. }
  959. // DEPRECATED
  960. // get_entity_name(self)
  961. int ObjectRef::l_get_entity_name(lua_State *L)
  962. {
  963. NO_MAP_LOCK_REQUIRED;
  964. ObjectRef *ref = checkobject(L, 1);
  965. LuaEntitySAO *co = getluaobject(ref);
  966. log_deprecated(L,"Deprecated call to \"get_entity_name");
  967. if (co == NULL) return 0;
  968. // Do it
  969. std::string name = co->getName();
  970. lua_pushstring(L, name.c_str());
  971. return 1;
  972. }
  973. // get_luaentity(self)
  974. int ObjectRef::l_get_luaentity(lua_State *L)
  975. {
  976. NO_MAP_LOCK_REQUIRED;
  977. ObjectRef *ref = checkobject(L, 1);
  978. LuaEntitySAO *co = getluaobject(ref);
  979. if (co == NULL) return 0;
  980. // Do it
  981. luaentity_get(L, co->getId());
  982. return 1;
  983. }
  984. /* Player-only */
  985. // is_player_connected(self)
  986. int ObjectRef::l_is_player_connected(lua_State *L)
  987. {
  988. NO_MAP_LOCK_REQUIRED;
  989. // This method was once added for a bugfix, but never documented
  990. log_deprecated(L, "is_player_connected is undocumented and "
  991. "will be removed in a future release");
  992. ObjectRef *ref = checkobject(L, 1);
  993. RemotePlayer *player = getplayer(ref);
  994. lua_pushboolean(L, (player != NULL && player->getPeerId() != PEER_ID_INEXISTENT));
  995. return 1;
  996. }
  997. // get_player_name(self)
  998. int ObjectRef::l_get_player_name(lua_State *L)
  999. {
  1000. NO_MAP_LOCK_REQUIRED;
  1001. ObjectRef *ref = checkobject(L, 1);
  1002. RemotePlayer *player = getplayer(ref);
  1003. if (player == NULL) {
  1004. lua_pushlstring(L, "", 0);
  1005. return 1;
  1006. }
  1007. // Do it
  1008. lua_pushstring(L, player->getName());
  1009. return 1;
  1010. }
  1011. // get_player_velocity(self)
  1012. int ObjectRef::l_get_player_velocity(lua_State *L)
  1013. {
  1014. NO_MAP_LOCK_REQUIRED;
  1015. ObjectRef *ref = checkobject(L, 1);
  1016. RemotePlayer *player = getplayer(ref);
  1017. if (player == NULL) {
  1018. lua_pushnil(L);
  1019. return 1;
  1020. }
  1021. // Do it
  1022. push_v3f(L, player->getSpeed() / BS);
  1023. return 1;
  1024. }
  1025. // get_look_dir(self)
  1026. int ObjectRef::l_get_look_dir(lua_State *L)
  1027. {
  1028. NO_MAP_LOCK_REQUIRED;
  1029. ObjectRef *ref = checkobject(L, 1);
  1030. PlayerSAO* co = getplayersao(ref);
  1031. if (co == NULL) return 0;
  1032. // Do it
  1033. float pitch = co->getRadPitchDep();
  1034. float yaw = co->getRadYawDep();
  1035. v3f v(cos(pitch)*cos(yaw), sin(pitch), cos(pitch)*sin(yaw));
  1036. push_v3f(L, v);
  1037. return 1;
  1038. }
  1039. // DEPRECATED
  1040. // get_look_pitch(self)
  1041. int ObjectRef::l_get_look_pitch(lua_State *L)
  1042. {
  1043. NO_MAP_LOCK_REQUIRED;
  1044. log_deprecated(L,
  1045. "Deprecated call to get_look_pitch, use get_look_vertical instead");
  1046. ObjectRef *ref = checkobject(L, 1);
  1047. PlayerSAO* co = getplayersao(ref);
  1048. if (co == NULL) return 0;
  1049. // Do it
  1050. lua_pushnumber(L, co->getRadPitchDep());
  1051. return 1;
  1052. }
  1053. // DEPRECATED
  1054. // get_look_yaw(self)
  1055. int ObjectRef::l_get_look_yaw(lua_State *L)
  1056. {
  1057. NO_MAP_LOCK_REQUIRED;
  1058. log_deprecated(L,
  1059. "Deprecated call to get_look_yaw, use get_look_horizontal instead");
  1060. ObjectRef *ref = checkobject(L, 1);
  1061. PlayerSAO* co = getplayersao(ref);
  1062. if (co == NULL) return 0;
  1063. // Do it
  1064. lua_pushnumber(L, co->getRadYawDep());
  1065. return 1;
  1066. }
  1067. // get_look_pitch2(self)
  1068. int ObjectRef::l_get_look_vertical(lua_State *L)
  1069. {
  1070. NO_MAP_LOCK_REQUIRED;
  1071. ObjectRef *ref = checkobject(L, 1);
  1072. PlayerSAO* co = getplayersao(ref);
  1073. if (co == NULL) return 0;
  1074. // Do it
  1075. lua_pushnumber(L, co->getRadPitch());
  1076. return 1;
  1077. }
  1078. // get_look_yaw2(self)
  1079. int ObjectRef::l_get_look_horizontal(lua_State *L)
  1080. {
  1081. NO_MAP_LOCK_REQUIRED;
  1082. ObjectRef *ref = checkobject(L, 1);
  1083. PlayerSAO* co = getplayersao(ref);
  1084. if (co == NULL) return 0;
  1085. // Do it
  1086. lua_pushnumber(L, co->getRadYaw());
  1087. return 1;
  1088. }
  1089. // set_look_vertical(self, radians)
  1090. int ObjectRef::l_set_look_vertical(lua_State *L)
  1091. {
  1092. NO_MAP_LOCK_REQUIRED;
  1093. ObjectRef *ref = checkobject(L, 1);
  1094. PlayerSAO* co = getplayersao(ref);
  1095. if (co == NULL) return 0;
  1096. float pitch = readParam<float>(L, 2) * core::RADTODEG;
  1097. // Do it
  1098. co->setPitchAndSend(pitch);
  1099. return 1;
  1100. }
  1101. // set_look_horizontal(self, radians)
  1102. int ObjectRef::l_set_look_horizontal(lua_State *L)
  1103. {
  1104. NO_MAP_LOCK_REQUIRED;
  1105. ObjectRef *ref = checkobject(L, 1);
  1106. PlayerSAO* co = getplayersao(ref);
  1107. if (co == NULL) return 0;
  1108. float yaw = readParam<float>(L, 2) * core::RADTODEG;
  1109. // Do it
  1110. co->setYawAndSend(yaw);
  1111. return 1;
  1112. }
  1113. // DEPRECATED
  1114. // set_look_pitch(self, radians)
  1115. int ObjectRef::l_set_look_pitch(lua_State *L)
  1116. {
  1117. NO_MAP_LOCK_REQUIRED;
  1118. log_deprecated(L,
  1119. "Deprecated call to set_look_pitch, use set_look_vertical instead.");
  1120. ObjectRef *ref = checkobject(L, 1);
  1121. PlayerSAO* co = getplayersao(ref);
  1122. if (co == NULL) return 0;
  1123. float pitch = readParam<float>(L, 2) * core::RADTODEG;
  1124. // Do it
  1125. co->setPitchAndSend(pitch);
  1126. return 1;
  1127. }
  1128. // DEPRECATED
  1129. // set_look_yaw(self, radians)
  1130. int ObjectRef::l_set_look_yaw(lua_State *L)
  1131. {
  1132. NO_MAP_LOCK_REQUIRED;
  1133. log_deprecated(L,
  1134. "Deprecated call to set_look_yaw, use set_look_horizontal instead.");
  1135. ObjectRef *ref = checkobject(L, 1);
  1136. PlayerSAO* co = getplayersao(ref);
  1137. if (co == NULL) return 0;
  1138. float yaw = readParam<float>(L, 2) * core::RADTODEG;
  1139. // Do it
  1140. co->setYawAndSend(yaw);
  1141. return 1;
  1142. }
  1143. // set_breath(self, breath)
  1144. int ObjectRef::l_set_breath(lua_State *L)
  1145. {
  1146. NO_MAP_LOCK_REQUIRED;
  1147. ObjectRef *ref = checkobject(L, 1);
  1148. PlayerSAO* co = getplayersao(ref);
  1149. if (co == NULL) return 0;
  1150. u16 breath = luaL_checknumber(L, 2);
  1151. co->setBreath(breath);
  1152. return 0;
  1153. }
  1154. // get_breath(self)
  1155. int ObjectRef::l_get_breath(lua_State *L)
  1156. {
  1157. NO_MAP_LOCK_REQUIRED;
  1158. ObjectRef *ref = checkobject(L, 1);
  1159. PlayerSAO* co = getplayersao(ref);
  1160. if (co == NULL) return 0;
  1161. // Do it
  1162. u16 breath = co->getBreath();
  1163. lua_pushinteger (L, breath);
  1164. return 1;
  1165. }
  1166. // set_attribute(self, attribute, value)
  1167. int ObjectRef::l_set_attribute(lua_State *L)
  1168. {
  1169. ObjectRef *ref = checkobject(L, 1);
  1170. PlayerSAO* co = getplayersao(ref);
  1171. if (co == NULL)
  1172. return 0;
  1173. std::string attr = luaL_checkstring(L, 2);
  1174. if (lua_isnil(L, 3)) {
  1175. co->getMeta().removeString(attr);
  1176. } else {
  1177. std::string value = luaL_checkstring(L, 3);
  1178. co->getMeta().setString(attr, value);
  1179. }
  1180. return 1;
  1181. }
  1182. // get_attribute(self, attribute)
  1183. int ObjectRef::l_get_attribute(lua_State *L)
  1184. {
  1185. ObjectRef *ref = checkobject(L, 1);
  1186. PlayerSAO* co = getplayersao(ref);
  1187. if (co == NULL) return 0;
  1188. std::string attr = luaL_checkstring(L, 2);
  1189. std::string value = "";
  1190. if (co->getMeta().getStringToRef(attr, value)) {
  1191. lua_pushstring(L, value.c_str());
  1192. return 1;
  1193. }
  1194. return 0;
  1195. }
  1196. // get_meta(self, attribute)
  1197. int ObjectRef::l_get_meta(lua_State *L)
  1198. {
  1199. ObjectRef *ref = checkobject(L, 1);
  1200. PlayerSAO *co = getplayersao(ref);
  1201. if (co == NULL)
  1202. return 0;
  1203. PlayerMetaRef::create(L, &co->getMeta());
  1204. return 1;
  1205. }
  1206. // set_inventory_formspec(self, formspec)
  1207. int ObjectRef::l_set_inventory_formspec(lua_State *L)
  1208. {
  1209. NO_MAP_LOCK_REQUIRED;
  1210. ObjectRef *ref = checkobject(L, 1);
  1211. RemotePlayer *player = getplayer(ref);
  1212. if (player == NULL) return 0;
  1213. std::string formspec = luaL_checkstring(L, 2);
  1214. player->inventory_formspec = formspec;
  1215. getServer(L)->reportInventoryFormspecModified(player->getName());
  1216. lua_pushboolean(L, true);
  1217. return 1;
  1218. }
  1219. // get_inventory_formspec(self) -> formspec
  1220. int ObjectRef::l_get_inventory_formspec(lua_State *L)
  1221. {
  1222. NO_MAP_LOCK_REQUIRED;
  1223. ObjectRef *ref = checkobject(L, 1);
  1224. RemotePlayer *player = getplayer(ref);
  1225. if (player == NULL) return 0;
  1226. std::string formspec = player->inventory_formspec;
  1227. lua_pushlstring(L, formspec.c_str(), formspec.size());
  1228. return 1;
  1229. }
  1230. // get_player_control(self)
  1231. int ObjectRef::l_get_player_control(lua_State *L)
  1232. {
  1233. NO_MAP_LOCK_REQUIRED;
  1234. ObjectRef *ref = checkobject(L, 1);
  1235. RemotePlayer *player = getplayer(ref);
  1236. if (player == NULL) {
  1237. lua_pushlstring(L, "", 0);
  1238. return 1;
  1239. }
  1240. const PlayerControl &control = player->getPlayerControl();
  1241. lua_newtable(L);
  1242. lua_pushboolean(L, control.up);
  1243. lua_setfield(L, -2, "up");
  1244. lua_pushboolean(L, control.down);
  1245. lua_setfield(L, -2, "down");
  1246. lua_pushboolean(L, control.left);
  1247. lua_setfield(L, -2, "left");
  1248. lua_pushboolean(L, control.right);
  1249. lua_setfield(L, -2, "right");
  1250. lua_pushboolean(L, control.jump);
  1251. lua_setfield(L, -2, "jump");
  1252. lua_pushboolean(L, control.aux1);
  1253. lua_setfield(L, -2, "aux1");
  1254. lua_pushboolean(L, control.sneak);
  1255. lua_setfield(L, -2, "sneak");
  1256. lua_pushboolean(L, control.LMB);
  1257. lua_setfield(L, -2, "LMB");
  1258. lua_pushboolean(L, control.RMB);
  1259. lua_setfield(L, -2, "RMB");
  1260. return 1;
  1261. }
  1262. // get_player_control_bits(self)
  1263. int ObjectRef::l_get_player_control_bits(lua_State *L)
  1264. {
  1265. NO_MAP_LOCK_REQUIRED;
  1266. ObjectRef *ref = checkobject(L, 1);
  1267. RemotePlayer *player = getplayer(ref);
  1268. if (player == NULL) {
  1269. lua_pushlstring(L, "", 0);
  1270. return 1;
  1271. }
  1272. // Do it
  1273. lua_pushnumber(L, player->keyPressed);
  1274. return 1;
  1275. }
  1276. // hud_add(self, form)
  1277. int ObjectRef::l_hud_add(lua_State *L)
  1278. {
  1279. NO_MAP_LOCK_REQUIRED;
  1280. ObjectRef *ref = checkobject(L, 1);
  1281. RemotePlayer *player = getplayer(ref);
  1282. if (player == NULL)
  1283. return 0;
  1284. HudElement *elem = new HudElement;
  1285. elem->type = (HudElementType)getenumfield(L, 2, "hud_elem_type",
  1286. es_HudElementType, HUD_ELEM_TEXT);
  1287. lua_getfield(L, 2, "position");
  1288. elem->pos = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
  1289. lua_pop(L, 1);
  1290. lua_getfield(L, 2, "scale");
  1291. elem->scale = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
  1292. lua_pop(L, 1);
  1293. lua_getfield(L, 2, "size");
  1294. elem->size = lua_istable(L, -1) ? read_v2s32(L, -1) : v2s32();
  1295. lua_pop(L, 1);
  1296. elem->name = getstringfield_default(L, 2, "name", "");
  1297. elem->text = getstringfield_default(L, 2, "text", "");
  1298. elem->number = getintfield_default(L, 2, "number", 0);
  1299. elem->item = getintfield_default(L, 2, "item", 0);
  1300. elem->dir = getintfield_default(L, 2, "direction", 0);
  1301. // Deprecated, only for compatibility's sake
  1302. if (elem->dir == 0)
  1303. elem->dir = getintfield_default(L, 2, "dir", 0);
  1304. lua_getfield(L, 2, "alignment");
  1305. elem->align = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
  1306. lua_pop(L, 1);
  1307. lua_getfield(L, 2, "offset");
  1308. elem->offset = lua_istable(L, -1) ? read_v2f(L, -1) : v2f();
  1309. lua_pop(L, 1);
  1310. lua_getfield(L, 2, "world_pos");
  1311. elem->world_pos = lua_istable(L, -1) ? read_v3f(L, -1) : v3f();
  1312. lua_pop(L, 1);
  1313. /* check for known deprecated element usage */
  1314. if ((elem->type == HUD_ELEM_STATBAR) && (elem->size == v2s32())) {
  1315. log_deprecated(L,"Deprecated usage of statbar without size!");
  1316. }
  1317. u32 id = getServer(L)->hudAdd(player, elem);
  1318. if (id == U32_MAX) {
  1319. delete elem;
  1320. return 0;
  1321. }
  1322. lua_pushnumber(L, id);
  1323. return 1;
  1324. }
  1325. // hud_remove(self, id)
  1326. int ObjectRef::l_hud_remove(lua_State *L)
  1327. {
  1328. NO_MAP_LOCK_REQUIRED;
  1329. ObjectRef *ref = checkobject(L, 1);
  1330. RemotePlayer *player = getplayer(ref);
  1331. if (player == NULL)
  1332. return 0;
  1333. u32 id = -1;
  1334. if (!lua_isnil(L, 2))
  1335. id = lua_tonumber(L, 2);
  1336. if (!getServer(L)->hudRemove(player, id))
  1337. return 0;
  1338. lua_pushboolean(L, true);
  1339. return 1;
  1340. }
  1341. // hud_change(self, id, stat, data)
  1342. int ObjectRef::l_hud_change(lua_State *L)
  1343. {
  1344. NO_MAP_LOCK_REQUIRED;
  1345. ObjectRef *ref = checkobject(L, 1);
  1346. RemotePlayer *player = getplayer(ref);
  1347. if (player == NULL)
  1348. return 0;
  1349. u32 id = lua_isnumber(L, 2) ? lua_tonumber(L, 2) : -1;
  1350. HudElement *e = player->getHud(id);
  1351. if (!e)
  1352. return 0;
  1353. HudElementStat stat = HUD_STAT_NUMBER;
  1354. if (lua_isstring(L, 3)) {
  1355. int statint;
  1356. std::string statstr = lua_tostring(L, 3);
  1357. stat = string_to_enum(es_HudElementStat, statint, statstr) ?
  1358. (HudElementStat)statint : HUD_STAT_NUMBER;
  1359. }
  1360. void *value = NULL;
  1361. switch (stat) {
  1362. case HUD_STAT_POS:
  1363. e->pos = read_v2f(L, 4);
  1364. value = &e->pos;
  1365. break;
  1366. case HUD_STAT_NAME:
  1367. e->name = luaL_checkstring(L, 4);
  1368. value = &e->name;
  1369. break;
  1370. case HUD_STAT_SCALE:
  1371. e->scale = read_v2f(L, 4);
  1372. value = &e->scale;
  1373. break;
  1374. case HUD_STAT_TEXT:
  1375. e->text = luaL_checkstring(L, 4);
  1376. value = &e->text;
  1377. break;
  1378. case HUD_STAT_NUMBER:
  1379. e->number = luaL_checknumber(L, 4);
  1380. value = &e->number;
  1381. break;
  1382. case HUD_STAT_ITEM:
  1383. e->item = luaL_checknumber(L, 4);
  1384. value = &e->item;
  1385. break;
  1386. case HUD_STAT_DIR:
  1387. e->dir = luaL_checknumber(L, 4);
  1388. value = &e->dir;
  1389. break;
  1390. case HUD_STAT_ALIGN:
  1391. e->align = read_v2f(L, 4);
  1392. value = &e->align;
  1393. break;
  1394. case HUD_STAT_OFFSET:
  1395. e->offset = read_v2f(L, 4);
  1396. value = &e->offset;
  1397. break;
  1398. case HUD_STAT_WORLD_POS:
  1399. e->world_pos = read_v3f(L, 4);
  1400. value = &e->world_pos;
  1401. break;
  1402. case HUD_STAT_SIZE:
  1403. e->size = read_v2s32(L, 4);
  1404. value = &e->size;
  1405. break;
  1406. }
  1407. getServer(L)->hudChange(player, id, stat, value);
  1408. lua_pushboolean(L, true);
  1409. return 1;
  1410. }
  1411. // hud_get(self, id)
  1412. int ObjectRef::l_hud_get(lua_State *L)
  1413. {
  1414. NO_MAP_LOCK_REQUIRED;
  1415. ObjectRef *ref = checkobject(L, 1);
  1416. RemotePlayer *player = getplayer(ref);
  1417. if (player == NULL)
  1418. return 0;
  1419. u32 id = lua_tonumber(L, -1);
  1420. HudElement *e = player->getHud(id);
  1421. if (!e)
  1422. return 0;
  1423. lua_newtable(L);
  1424. lua_pushstring(L, es_HudElementType[(u8)e->type].str);
  1425. lua_setfield(L, -2, "type");
  1426. push_v2f(L, e->pos);
  1427. lua_setfield(L, -2, "position");
  1428. lua_pushstring(L, e->name.c_str());
  1429. lua_setfield(L, -2, "name");
  1430. push_v2f(L, e->scale);
  1431. lua_setfield(L, -2, "scale");
  1432. lua_pushstring(L, e->text.c_str());
  1433. lua_setfield(L, -2, "text");
  1434. lua_pushnumber(L, e->number);
  1435. lua_setfield(L, -2, "number");
  1436. lua_pushnumber(L, e->item);
  1437. lua_setfield(L, -2, "item");
  1438. lua_pushnumber(L, e->dir);
  1439. lua_setfield(L, -2, "direction");
  1440. // Deprecated, only for compatibility's sake
  1441. lua_pushnumber(L, e->dir);
  1442. lua_setfield(L, -2, "dir");
  1443. push_v3f(L, e->world_pos);
  1444. lua_setfield(L, -2, "world_pos");
  1445. return 1;
  1446. }
  1447. // hud_set_flags(self, flags)
  1448. int ObjectRef::l_hud_set_flags(lua_State *L)
  1449. {
  1450. NO_MAP_LOCK_REQUIRED;
  1451. ObjectRef *ref = checkobject(L, 1);
  1452. RemotePlayer *player = getplayer(ref);
  1453. if (player == NULL)
  1454. return 0;
  1455. u32 flags = 0;
  1456. u32 mask = 0;
  1457. bool flag;
  1458. const EnumString *esp = es_HudBuiltinElement;
  1459. for (int i = 0; esp[i].str; i++) {
  1460. if (getboolfield(L, 2, esp[i].str, flag)) {
  1461. flags |= esp[i].num * flag;
  1462. mask |= esp[i].num;
  1463. }
  1464. }
  1465. if (!getServer(L)->hudSetFlags(player, flags, mask))
  1466. return 0;
  1467. lua_pushboolean(L, true);
  1468. return 1;
  1469. }
  1470. int ObjectRef::l_hud_get_flags(lua_State *L)
  1471. {
  1472. NO_MAP_LOCK_REQUIRED;
  1473. ObjectRef *ref = checkobject(L, 1);
  1474. RemotePlayer *player = getplayer(ref);
  1475. if (player == NULL)
  1476. return 0;
  1477. lua_newtable(L);
  1478. lua_pushboolean(L, player->hud_flags & HUD_FLAG_HOTBAR_VISIBLE);
  1479. lua_setfield(L, -2, "hotbar");
  1480. lua_pushboolean(L, player->hud_flags & HUD_FLAG_HEALTHBAR_VISIBLE);
  1481. lua_setfield(L, -2, "healthbar");
  1482. lua_pushboolean(L, player->hud_flags & HUD_FLAG_CROSSHAIR_VISIBLE);
  1483. lua_setfield(L, -2, "crosshair");
  1484. lua_pushboolean(L, player->hud_flags & HUD_FLAG_WIELDITEM_VISIBLE);
  1485. lua_setfield(L, -2, "wielditem");
  1486. lua_pushboolean(L, player->hud_flags & HUD_FLAG_BREATHBAR_VISIBLE);
  1487. lua_setfield(L, -2, "breathbar");
  1488. lua_pushboolean(L, player->hud_flags & HUD_FLAG_MINIMAP_VISIBLE);
  1489. lua_setfield(L, -2, "minimap");
  1490. lua_pushboolean(L, player->hud_flags & HUD_FLAG_MINIMAP_RADAR_VISIBLE);
  1491. lua_setfield(L, -2, "minimap_radar");
  1492. return 1;
  1493. }
  1494. // hud_set_hotbar_itemcount(self, hotbar_itemcount)
  1495. int ObjectRef::l_hud_set_hotbar_itemcount(lua_State *L)
  1496. {
  1497. NO_MAP_LOCK_REQUIRED;
  1498. ObjectRef *ref = checkobject(L, 1);
  1499. RemotePlayer *player = getplayer(ref);
  1500. if (player == NULL)
  1501. return 0;
  1502. s32 hotbar_itemcount = lua_tonumber(L, 2);
  1503. if (!getServer(L)->hudSetHotbarItemcount(player, hotbar_itemcount))
  1504. return 0;
  1505. lua_pushboolean(L, true);
  1506. return 1;
  1507. }
  1508. // hud_get_hotbar_itemcount(self)
  1509. int ObjectRef::l_hud_get_hotbar_itemcount(lua_State *L)
  1510. {
  1511. NO_MAP_LOCK_REQUIRED;
  1512. ObjectRef *ref = checkobject(L, 1);
  1513. RemotePlayer *player = getplayer(ref);
  1514. if (player == NULL)
  1515. return 0;
  1516. lua_pushnumber(L, player->getHotbarItemcount());
  1517. return 1;
  1518. }
  1519. // hud_set_hotbar_image(self, name)
  1520. int ObjectRef::l_hud_set_hotbar_image(lua_State *L)
  1521. {
  1522. NO_MAP_LOCK_REQUIRED;
  1523. ObjectRef *ref = checkobject(L, 1);
  1524. RemotePlayer *player = getplayer(ref);
  1525. if (player == NULL)
  1526. return 0;
  1527. std::string name = readParam<std::string>(L, 2);
  1528. getServer(L)->hudSetHotbarImage(player, name);
  1529. return 1;
  1530. }
  1531. // hud_get_hotbar_image(self)
  1532. int ObjectRef::l_hud_get_hotbar_image(lua_State *L)
  1533. {
  1534. NO_MAP_LOCK_REQUIRED;
  1535. ObjectRef *ref = checkobject(L, 1);
  1536. RemotePlayer *player = getplayer(ref);
  1537. if (player == NULL)
  1538. return 0;
  1539. const std::string &name = player->getHotbarImage();
  1540. lua_pushlstring(L, name.c_str(), name.size());
  1541. return 1;
  1542. }
  1543. // hud_set_hotbar_selected_image(self, name)
  1544. int ObjectRef::l_hud_set_hotbar_selected_image(lua_State *L)
  1545. {
  1546. NO_MAP_LOCK_REQUIRED;
  1547. ObjectRef *ref = checkobject(L, 1);
  1548. RemotePlayer *player = getplayer(ref);
  1549. if (player == NULL)
  1550. return 0;
  1551. std::string name = readParam<std::string>(L, 2);
  1552. getServer(L)->hudSetHotbarSelectedImage(player, name);
  1553. return 1;
  1554. }
  1555. // hud_get_hotbar_selected_image(self)
  1556. int ObjectRef::l_hud_get_hotbar_selected_image(lua_State *L)
  1557. {
  1558. NO_MAP_LOCK_REQUIRED;
  1559. ObjectRef *ref = checkobject(L, 1);
  1560. RemotePlayer *player = getplayer(ref);
  1561. if (player == NULL)
  1562. return 0;
  1563. const std::string &name = getServer(L)->hudGetHotbarSelectedImage(player);
  1564. lua_pushlstring(L, name.c_str(), name.size());
  1565. return 1;
  1566. }
  1567. // set_sky(self, bgcolor, type, list, clouds = true)
  1568. int ObjectRef::l_set_sky(lua_State *L)
  1569. {
  1570. NO_MAP_LOCK_REQUIRED;
  1571. ObjectRef *ref = checkobject(L, 1);
  1572. RemotePlayer *player = getplayer(ref);
  1573. if (player == NULL)
  1574. return 0;
  1575. video::SColor bgcolor(255,255,255,255);
  1576. read_color(L, 2, &bgcolor);
  1577. std::string type = luaL_checkstring(L, 3);
  1578. std::vector<std::string> params;
  1579. if (lua_istable(L, 4)) {
  1580. lua_pushnil(L);
  1581. while (lua_next(L, 4) != 0) {
  1582. // key at index -2 and value at index -1
  1583. if (lua_isstring(L, -1))
  1584. params.push_back(readParam<std::string>(L, -1));
  1585. else
  1586. params.push_back("");
  1587. // removes value, keeps key for next iteration
  1588. lua_pop(L, 1);
  1589. }
  1590. }
  1591. if (type == "skybox" && params.size() != 6)
  1592. throw LuaError("skybox expects 6 textures");
  1593. bool clouds = true;
  1594. if (lua_isboolean(L, 5))
  1595. clouds = readParam<bool>(L, 5);
  1596. if (!getServer(L)->setSky(player, bgcolor, type, params, clouds))
  1597. return 0;
  1598. lua_pushboolean(L, true);
  1599. return 1;
  1600. }
  1601. // get_sky(self)
  1602. int ObjectRef::l_get_sky(lua_State *L)
  1603. {
  1604. NO_MAP_LOCK_REQUIRED;
  1605. ObjectRef *ref = checkobject(L, 1);
  1606. RemotePlayer *player = getplayer(ref);
  1607. if (player == NULL)
  1608. return 0;
  1609. video::SColor bgcolor(255, 255, 255, 255);
  1610. std::string type;
  1611. std::vector<std::string> params;
  1612. bool clouds;
  1613. player->getSky(&bgcolor, &type, &params, &clouds);
  1614. type = type == "" ? "regular" : type;
  1615. push_ARGB8(L, bgcolor);
  1616. lua_pushlstring(L, type.c_str(), type.size());
  1617. lua_newtable(L);
  1618. s16 i = 1;
  1619. for (std::vector<std::string>::iterator it = params.begin();
  1620. it != params.end(); ++it) {
  1621. lua_pushlstring(L, it->c_str(), it->size());
  1622. lua_rawseti(L, -2, i);
  1623. i++;
  1624. }
  1625. lua_pushboolean(L, clouds);
  1626. return 4;
  1627. }
  1628. int ObjectRef::l_set_clouds (lua_State *L)
  1629. {
  1630. NO_MAP_LOCK_REQUIRED;
  1631. return 0;
  1632. }
  1633. int ObjectRef::l_get_clouds (lua_State *L)
  1634. {
  1635. NO_MAP_LOCK_REQUIRED;
  1636. return 0;
  1637. }
  1638. int ObjectRef::l_set_formspec_prepend (lua_State *L)
  1639. {
  1640. NO_MAP_LOCK_REQUIRED;
  1641. return 0;
  1642. }
  1643. int ObjectRef::l_get_formspec_prepend (lua_State *L)
  1644. {
  1645. NO_MAP_LOCK_REQUIRED;
  1646. return 0;
  1647. }
  1648. // override_day_night_ratio(self, brightness=0...1)
  1649. int ObjectRef::l_override_day_night_ratio(lua_State *L)
  1650. {
  1651. NO_MAP_LOCK_REQUIRED;
  1652. ObjectRef *ref = checkobject(L, 1);
  1653. RemotePlayer *player = getplayer(ref);
  1654. if (player == NULL)
  1655. return 0;
  1656. bool do_override = false;
  1657. float ratio = 0.0f;
  1658. if (!lua_isnil(L, 2)) {
  1659. do_override = true;
  1660. ratio = readParam<float>(L, 2);
  1661. }
  1662. if (!getServer(L)->overrideDayNightRatio(player, do_override, ratio))
  1663. return 0;
  1664. lua_pushboolean(L, true);
  1665. return 1;
  1666. }
  1667. // get_day_night_ratio(self)
  1668. int ObjectRef::l_get_day_night_ratio(lua_State *L)
  1669. {
  1670. NO_MAP_LOCK_REQUIRED;
  1671. ObjectRef *ref = checkobject(L, 1);
  1672. RemotePlayer *player = getplayer(ref);
  1673. if (player == NULL)
  1674. return 0;
  1675. bool do_override;
  1676. float ratio;
  1677. player->getDayNightRatio(&do_override, &ratio);
  1678. if (do_override)
  1679. lua_pushnumber(L, ratio);
  1680. else
  1681. lua_pushnil(L);
  1682. return 1;
  1683. }
  1684. ObjectRef::ObjectRef(ServerActiveObject *object):
  1685. m_object(object)
  1686. {
  1687. //infostream<<"ObjectRef created for id="<<m_object->getId()<<std::endl;
  1688. }
  1689. ObjectRef::~ObjectRef()
  1690. {
  1691. /*if (m_object)
  1692. infostream<<"ObjectRef destructing for id="
  1693. <<m_object->getId()<<std::endl;
  1694. else
  1695. infostream<<"ObjectRef destructing for id=unknown"<<std::endl;*/
  1696. }
  1697. // Creates an ObjectRef and leaves it on top of stack
  1698. // Not callable from Lua; all references are created on the C side.
  1699. void ObjectRef::create(lua_State *L, ServerActiveObject *object)
  1700. {
  1701. ObjectRef *o = new ObjectRef(object);
  1702. //infostream<<"ObjectRef::create: o="<<o<<std::endl;
  1703. *(void **)(lua_newuserdata(L, sizeof(void *))) = o;
  1704. luaL_getmetatable(L, className);
  1705. lua_setmetatable(L, -2);
  1706. }
  1707. void ObjectRef::set_null(lua_State *L)
  1708. {
  1709. ObjectRef *o = checkobject(L, -1);
  1710. o->m_object = NULL;
  1711. }
  1712. void ObjectRef::Register(lua_State *L)
  1713. {
  1714. lua_newtable(L);
  1715. int methodtable = lua_gettop(L);
  1716. luaL_newmetatable(L, className);
  1717. int metatable = lua_gettop(L);
  1718. lua_pushliteral(L, "__metatable");
  1719. lua_pushvalue(L, methodtable);
  1720. lua_settable(L, metatable); // hide metatable from Lua getmetatable()
  1721. lua_pushliteral(L, "__index");
  1722. lua_pushvalue(L, methodtable);
  1723. lua_settable(L, metatable);
  1724. lua_pushliteral(L, "__gc");
  1725. lua_pushcfunction(L, gc_object);
  1726. lua_settable(L, metatable);
  1727. lua_pop(L, 1); // drop metatable
  1728. luaL_openlib(L, 0, methods, 0); // fill methodtable
  1729. lua_pop(L, 1); // drop methodtable
  1730. // Cannot be created from Lua
  1731. //lua_register(L, className, create_object);
  1732. }
  1733. const char ObjectRef::className[] = "ObjectRef";
  1734. const luaL_Reg ObjectRef::methods[] = {
  1735. // ServerActiveObject
  1736. luamethod(ObjectRef, remove),
  1737. luamethod_aliased(ObjectRef, get_pos, getpos),
  1738. luamethod_aliased(ObjectRef, set_pos, setpos),
  1739. luamethod_aliased(ObjectRef, move_to, moveto),
  1740. luamethod(ObjectRef, punch),
  1741. luamethod(ObjectRef, right_click),
  1742. luamethod(ObjectRef, set_hp),
  1743. luamethod(ObjectRef, get_hp),
  1744. luamethod(ObjectRef, get_inventory),
  1745. luamethod(ObjectRef, get_wield_list),
  1746. luamethod(ObjectRef, get_wield_index),
  1747. luamethod(ObjectRef, get_wielded_item),
  1748. luamethod(ObjectRef, set_wielded_item),
  1749. luamethod(ObjectRef, set_armor_groups),
  1750. luamethod(ObjectRef, get_armor_groups),
  1751. luamethod(ObjectRef, set_animation),
  1752. luamethod(ObjectRef, get_animation),
  1753. luamethod(ObjectRef, set_animation_frame_speed),
  1754. luamethod(ObjectRef, set_bone_position),
  1755. luamethod(ObjectRef, get_bone_position),
  1756. luamethod(ObjectRef, set_attach),
  1757. luamethod(ObjectRef, get_attach),
  1758. luamethod(ObjectRef, set_detach),
  1759. luamethod(ObjectRef, set_properties),
  1760. luamethod(ObjectRef, get_properties),
  1761. luamethod(ObjectRef, set_nametag_attributes),
  1762. luamethod(ObjectRef, get_nametag_attributes),
  1763. // LuaEntitySAO-only
  1764. luamethod_aliased(ObjectRef, set_velocity, setvelocity),
  1765. luamethod(ObjectRef, add_velocity),
  1766. luamethod_aliased(ObjectRef, get_velocity, getvelocity),
  1767. luamethod_aliased(ObjectRef, set_acceleration, setacceleration),
  1768. luamethod_aliased(ObjectRef, get_acceleration, getacceleration),
  1769. luamethod_aliased(ObjectRef, set_yaw, setyaw),
  1770. luamethod_aliased(ObjectRef, get_yaw, getyaw),
  1771. luamethod(ObjectRef, set_rotation),
  1772. luamethod(ObjectRef, get_rotation),
  1773. luamethod_aliased(ObjectRef, set_texture_mod, settexturemod),
  1774. luamethod_aliased(ObjectRef, set_sprite, setsprite),
  1775. luamethod(ObjectRef, get_entity_name),
  1776. luamethod(ObjectRef, get_luaentity),
  1777. // Player-only
  1778. luamethod(ObjectRef, is_player),
  1779. luamethod(ObjectRef, is_player_connected),
  1780. luamethod(ObjectRef, get_player_name),
  1781. luamethod(ObjectRef, get_player_velocity),
  1782. luamethod(ObjectRef, get_look_dir),
  1783. luamethod(ObjectRef, get_look_pitch),
  1784. luamethod(ObjectRef, get_look_yaw),
  1785. luamethod(ObjectRef, get_look_vertical),
  1786. luamethod(ObjectRef, get_look_horizontal),
  1787. luamethod(ObjectRef, set_look_horizontal),
  1788. luamethod(ObjectRef, set_look_vertical),
  1789. luamethod(ObjectRef, set_look_yaw),
  1790. luamethod(ObjectRef, set_look_pitch),
  1791. luamethod(ObjectRef, get_breath),
  1792. luamethod(ObjectRef, set_breath),
  1793. luamethod(ObjectRef, get_attribute),
  1794. luamethod(ObjectRef, set_attribute),
  1795. luamethod(ObjectRef, get_meta),
  1796. luamethod(ObjectRef, set_inventory_formspec),
  1797. luamethod(ObjectRef, get_inventory_formspec),
  1798. luamethod(ObjectRef, get_player_control),
  1799. luamethod(ObjectRef, get_player_control_bits),
  1800. luamethod(ObjectRef, set_physics_override),
  1801. luamethod(ObjectRef, get_physics_override),
  1802. luamethod(ObjectRef, hud_add),
  1803. luamethod(ObjectRef, hud_remove),
  1804. luamethod(ObjectRef, hud_change),
  1805. luamethod(ObjectRef, hud_get),
  1806. luamethod(ObjectRef, hud_set_flags),
  1807. luamethod(ObjectRef, hud_get_flags),
  1808. luamethod(ObjectRef, hud_set_hotbar_itemcount),
  1809. luamethod(ObjectRef, hud_get_hotbar_itemcount),
  1810. luamethod(ObjectRef, hud_set_hotbar_image),
  1811. luamethod(ObjectRef, hud_get_hotbar_image),
  1812. luamethod(ObjectRef, hud_set_hotbar_selected_image),
  1813. luamethod(ObjectRef, hud_get_hotbar_selected_image),
  1814. luamethod(ObjectRef, set_sky),
  1815. luamethod(ObjectRef, get_sky),
  1816. luamethod(ObjectRef, set_clouds),
  1817. luamethod(ObjectRef, get_clouds),
  1818. luamethod(ObjectRef, set_formspec_prepend),
  1819. luamethod(ObjectRef, get_formspec_prepend),
  1820. luamethod(ObjectRef, override_day_night_ratio),
  1821. luamethod(ObjectRef, get_day_night_ratio),
  1822. luamethod(ObjectRef, set_local_animation),
  1823. luamethod(ObjectRef, get_local_animation),
  1824. luamethod(ObjectRef, set_eye_offset),
  1825. luamethod(ObjectRef, get_eye_offset),
  1826. luamethod(ObjectRef, send_mapblock),
  1827. {0,0}
  1828. };