s_node.cpp 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  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 "cpp_api/s_node.h"
  17. #include "cpp_api/s_internal.h"
  18. #include "common/c_converter.h"
  19. #include "common/c_content.h"
  20. #include "nodedef.h"
  21. #include "server.h"
  22. #include "environment.h"
  23. #include "util/pointedthing.h"
  24. // Should be ordered exactly like enum NodeDrawType in nodedef.h
  25. struct EnumString ScriptApiNode::es_DrawType[] =
  26. {
  27. {NDT_NORMAL, "normal"},
  28. {NDT_AIRLIKE, "airlike"},
  29. {NDT_LIQUID, "liquid"},
  30. {NDT_FLOWINGLIQUID, "flowingliquid"},
  31. {NDT_GLASSLIKE, "glasslike"},
  32. {NDT_ALLFACES, "allfaces"},
  33. {NDT_ALLFACES_OPTIONAL, "allfaces_optional"},
  34. {NDT_TORCHLIKE, "torchlike"},
  35. {NDT_SIGNLIKE, "signlike"},
  36. {NDT_PLANTLIKE, "plantlike"},
  37. {NDT_FENCELIKE, "fencelike"},
  38. {NDT_RAILLIKE, "raillike"},
  39. {NDT_NODEBOX, "nodebox"},
  40. {NDT_GLASSLIKE_FRAMED, "glasslike_framed"},
  41. {NDT_FIRELIKE, "firelike"},
  42. {NDT_GLASSLIKE_FRAMED_OPTIONAL, "glasslike_framed_optional"},
  43. {NDT_MESH, "mesh"},
  44. {NDT_PLANTLIKE_ROOTED, "plantlike_rooted"},
  45. {0, NULL},
  46. };
  47. struct EnumString ScriptApiNode::es_ContentParamType2[] =
  48. {
  49. {CPT2_NONE, "none"},
  50. {CPT2_FULL, "full"},
  51. {CPT2_FLOWINGLIQUID, "flowingliquid"},
  52. {CPT2_FACEDIR, "facedir"},
  53. {CPT2_WALLMOUNTED, "wallmounted"},
  54. {CPT2_LEVELED, "leveled"},
  55. {CPT2_DEGROTATE, "degrotate"},
  56. {CPT2_MESHOPTIONS, "meshoptions"},
  57. {CPT2_COLOR, "color"},
  58. {CPT2_COLORED_FACEDIR, "colorfacedir"},
  59. {CPT2_COLORED_WALLMOUNTED, "colorwallmounted"},
  60. {CPT2_GLASSLIKE_LIQUID_LEVEL, "glasslikeliquidlevel"},
  61. {0, NULL},
  62. };
  63. struct EnumString ScriptApiNode::es_LiquidType[] =
  64. {
  65. {LIQUID_NONE, "none"},
  66. {LIQUID_FLOWING, "flowing"},
  67. {LIQUID_SOURCE, "source"},
  68. {0, NULL},
  69. };
  70. struct EnumString ScriptApiNode::es_ContentParamType[] =
  71. {
  72. {CPT_NONE, "none"},
  73. {CPT_LIGHT, "light"},
  74. {0, NULL},
  75. };
  76. struct EnumString ScriptApiNode::es_NodeBoxType[] =
  77. {
  78. {NODEBOX_REGULAR, "regular"},
  79. {NODEBOX_FIXED, "fixed"},
  80. {NODEBOX_WALLMOUNTED, "wallmounted"},
  81. {NODEBOX_LEVELED, "leveled"},
  82. {NODEBOX_CONNECTED, "connected"},
  83. {0, NULL},
  84. };
  85. bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node,
  86. ServerActiveObject *puncher, PointedThing pointed)
  87. {
  88. SCRIPTAPI_PRECHECKHEADER
  89. int error_handler = PUSH_ERROR_HANDLER(L);
  90. const NodeDefManager *ndef = getServer()->ndef();
  91. // Push callback function on stack
  92. if (!getItemCallback(ndef->get(node).name.c_str(), "on_punch", &p))
  93. return false;
  94. // Call function
  95. push_v3s16(L, p);
  96. pushnode(L, node, ndef);
  97. objectrefGetOrCreate(L, puncher);
  98. pushPointedThing(pointed);
  99. PCALL_RES(lua_pcall(L, 4, 0, error_handler));
  100. lua_pop(L, 1); // Pop error handler
  101. return true;
  102. }
  103. bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node,
  104. ServerActiveObject *digger)
  105. {
  106. SCRIPTAPI_PRECHECKHEADER
  107. int error_handler = PUSH_ERROR_HANDLER(L);
  108. const NodeDefManager *ndef = getServer()->ndef();
  109. // Push callback function on stack
  110. if (!getItemCallback(ndef->get(node).name.c_str(), "on_dig", &p))
  111. return false;
  112. // Call function
  113. push_v3s16(L, p);
  114. pushnode(L, node, ndef);
  115. objectrefGetOrCreate(L, digger);
  116. PCALL_RES(lua_pcall(L, 3, 0, error_handler));
  117. lua_pop(L, 1); // Pop error handler
  118. return true;
  119. }
  120. void ScriptApiNode::node_on_construct(v3s16 p, MapNode node)
  121. {
  122. SCRIPTAPI_PRECHECKHEADER
  123. int error_handler = PUSH_ERROR_HANDLER(L);
  124. const NodeDefManager *ndef = getServer()->ndef();
  125. // Push callback function on stack
  126. if (!getItemCallback(ndef->get(node).name.c_str(), "on_construct", &p))
  127. return;
  128. // Call function
  129. push_v3s16(L, p);
  130. PCALL_RES(lua_pcall(L, 1, 0, error_handler));
  131. lua_pop(L, 1); // Pop error handler
  132. }
  133. void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node)
  134. {
  135. SCRIPTAPI_PRECHECKHEADER
  136. int error_handler = PUSH_ERROR_HANDLER(L);
  137. const NodeDefManager *ndef = getServer()->ndef();
  138. // Push callback function on stack
  139. if (!getItemCallback(ndef->get(node).name.c_str(), "on_destruct", &p))
  140. return;
  141. // Call function
  142. push_v3s16(L, p);
  143. PCALL_RES(lua_pcall(L, 1, 0, error_handler));
  144. lua_pop(L, 1); // Pop error handler
  145. }
  146. bool ScriptApiNode::node_on_flood(v3s16 p, MapNode node, MapNode newnode)
  147. {
  148. SCRIPTAPI_PRECHECKHEADER
  149. int error_handler = PUSH_ERROR_HANDLER(L);
  150. const NodeDefManager *ndef = getServer()->ndef();
  151. // Push callback function on stack
  152. if (!getItemCallback(ndef->get(node).name.c_str(), "on_flood", &p))
  153. return false;
  154. // Call function
  155. push_v3s16(L, p);
  156. pushnode(L, node, ndef);
  157. pushnode(L, newnode, ndef);
  158. PCALL_RES(lua_pcall(L, 3, 1, error_handler));
  159. lua_remove(L, error_handler);
  160. return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1);
  161. }
  162. void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
  163. {
  164. SCRIPTAPI_PRECHECKHEADER
  165. int error_handler = PUSH_ERROR_HANDLER(L);
  166. const NodeDefManager *ndef = getServer()->ndef();
  167. // Push callback function on stack
  168. if (!getItemCallback(ndef->get(node).name.c_str(), "after_destruct", &p))
  169. return;
  170. // Call function
  171. push_v3s16(L, p);
  172. pushnode(L, node, ndef);
  173. PCALL_RES(lua_pcall(L, 2, 0, error_handler));
  174. lua_pop(L, 1); // Pop error handler
  175. }
  176. bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime)
  177. {
  178. SCRIPTAPI_PRECHECKHEADER
  179. int error_handler = PUSH_ERROR_HANDLER(L);
  180. const NodeDefManager *ndef = getServer()->ndef();
  181. // Push callback function on stack
  182. if (!getItemCallback(ndef->get(node).name.c_str(), "on_timer", &p))
  183. return false;
  184. // Call function
  185. push_v3s16(L, p);
  186. lua_pushnumber(L,dtime);
  187. PCALL_RES(lua_pcall(L, 2, 1, error_handler));
  188. lua_remove(L, error_handler);
  189. return (bool) lua_isboolean(L, -1) && (bool) lua_toboolean(L, -1);
  190. }
  191. void ScriptApiNode::node_on_receive_fields(v3s16 p,
  192. const std::string &formname,
  193. const StringMap &fields,
  194. ServerActiveObject *sender)
  195. {
  196. SCRIPTAPI_PRECHECKHEADER
  197. int error_handler = PUSH_ERROR_HANDLER(L);
  198. const NodeDefManager *ndef = getServer()->ndef();
  199. // If node doesn't exist, we don't know what callback to call
  200. MapNode node = getEnv()->getMap().getNodeNoEx(p);
  201. if (node.getContent() == CONTENT_IGNORE)
  202. return;
  203. // Push callback function on stack
  204. if (!getItemCallback(ndef->get(node).name.c_str(), "on_receive_fields", &p))
  205. return;
  206. // Call function
  207. push_v3s16(L, p); // pos
  208. lua_pushstring(L, formname.c_str()); // formname
  209. lua_newtable(L); // fields
  210. StringMap::const_iterator it;
  211. for (it = fields.begin(); it != fields.end(); ++it) {
  212. const std::string &name = it->first;
  213. const std::string &value = it->second;
  214. lua_pushstring(L, name.c_str());
  215. lua_pushlstring(L, value.c_str(), value.size());
  216. lua_settable(L, -3);
  217. }
  218. objectrefGetOrCreate(L, sender); // player
  219. PCALL_RES(lua_pcall(L, 4, 0, error_handler));
  220. lua_pop(L, 1); // Pop error handler
  221. }