s_node.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  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. {CPT2_COLORED_DEGROTATE, "colordegrotate"},
  62. {CPT2_4DIR, "4dir"},
  63. {CPT2_COLORED_4DIR, "color4dir"},
  64. {0, NULL},
  65. };
  66. struct EnumString ScriptApiNode::es_LiquidType[] =
  67. {
  68. {LIQUID_NONE, "none"},
  69. {LIQUID_FLOWING, "flowing"},
  70. {LIQUID_SOURCE, "source"},
  71. {0, NULL},
  72. };
  73. struct EnumString ScriptApiNode::es_ContentParamType[] =
  74. {
  75. {CPT_NONE, "none"},
  76. {CPT_LIGHT, "light"},
  77. {0, NULL},
  78. };
  79. struct EnumString ScriptApiNode::es_NodeBoxType[] =
  80. {
  81. {NODEBOX_REGULAR, "regular"},
  82. {NODEBOX_FIXED, "fixed"},
  83. {NODEBOX_WALLMOUNTED, "wallmounted"},
  84. {NODEBOX_LEVELED, "leveled"},
  85. {NODEBOX_CONNECTED, "connected"},
  86. {0, NULL},
  87. };
  88. struct EnumString ScriptApiNode::es_TextureAlphaMode[] =
  89. {
  90. {ALPHAMODE_OPAQUE, "opaque"},
  91. {ALPHAMODE_CLIP, "clip"},
  92. {ALPHAMODE_BLEND, "blend"},
  93. {0, NULL},
  94. };
  95. bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node,
  96. ServerActiveObject *puncher, const PointedThing &pointed)
  97. {
  98. SCRIPTAPI_PRECHECKHEADER
  99. int error_handler = PUSH_ERROR_HANDLER(L);
  100. const NodeDefManager *ndef = getServer()->ndef();
  101. // Push callback function on stack
  102. if (!getItemCallback(ndef->get(node).name.c_str(), "on_punch", &p))
  103. return false;
  104. // Call function
  105. push_v3s16(L, p);
  106. pushnode(L, node);
  107. objectrefGetOrCreate(L, puncher);
  108. pushPointedThing(pointed);
  109. PCALL_RES(lua_pcall(L, 4, 0, error_handler));
  110. lua_pop(L, 1); // Pop error handler
  111. return true;
  112. }
  113. bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node,
  114. ServerActiveObject *digger)
  115. {
  116. SCRIPTAPI_PRECHECKHEADER
  117. int error_handler = PUSH_ERROR_HANDLER(L);
  118. const NodeDefManager *ndef = getServer()->ndef();
  119. // Push callback function on stack
  120. if (!getItemCallback(ndef->get(node).name.c_str(), "on_dig", &p))
  121. return false;
  122. // Call function
  123. push_v3s16(L, p);
  124. pushnode(L, node);
  125. objectrefGetOrCreate(L, digger);
  126. PCALL_RES(lua_pcall(L, 3, 1, error_handler));
  127. // nil is treated as true for backwards compat
  128. bool result = lua_isnil(L, -1) || lua_toboolean(L, -1);
  129. lua_pop(L, 2); // Pop error handler and result
  130. return result;
  131. }
  132. void ScriptApiNode::node_on_construct(v3s16 p, MapNode node)
  133. {
  134. SCRIPTAPI_PRECHECKHEADER
  135. int error_handler = PUSH_ERROR_HANDLER(L);
  136. const NodeDefManager *ndef = getServer()->ndef();
  137. // Push callback function on stack
  138. if (!getItemCallback(ndef->get(node).name.c_str(), "on_construct", &p))
  139. return;
  140. // Call function
  141. push_v3s16(L, p);
  142. PCALL_RES(lua_pcall(L, 1, 0, error_handler));
  143. lua_pop(L, 1); // Pop error handler
  144. }
  145. void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node)
  146. {
  147. SCRIPTAPI_PRECHECKHEADER
  148. int error_handler = PUSH_ERROR_HANDLER(L);
  149. const NodeDefManager *ndef = getServer()->ndef();
  150. // Push callback function on stack
  151. if (!getItemCallback(ndef->get(node).name.c_str(), "on_destruct", &p))
  152. return;
  153. // Call function
  154. push_v3s16(L, p);
  155. PCALL_RES(lua_pcall(L, 1, 0, error_handler));
  156. lua_pop(L, 1); // Pop error handler
  157. }
  158. bool ScriptApiNode::node_on_flood(v3s16 p, MapNode node, MapNode newnode)
  159. {
  160. SCRIPTAPI_PRECHECKHEADER
  161. int error_handler = PUSH_ERROR_HANDLER(L);
  162. const NodeDefManager *ndef = getServer()->ndef();
  163. // Push callback function on stack
  164. if (!getItemCallback(ndef->get(node).name.c_str(), "on_flood", &p))
  165. return false;
  166. // Call function
  167. push_v3s16(L, p);
  168. pushnode(L, node);
  169. pushnode(L, newnode);
  170. PCALL_RES(lua_pcall(L, 3, 1, error_handler));
  171. lua_remove(L, error_handler);
  172. return readParam<bool>(L, -1, false);
  173. }
  174. void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
  175. {
  176. SCRIPTAPI_PRECHECKHEADER
  177. int error_handler = PUSH_ERROR_HANDLER(L);
  178. const NodeDefManager *ndef = getServer()->ndef();
  179. // Push callback function on stack
  180. if (!getItemCallback(ndef->get(node).name.c_str(), "after_destruct", &p))
  181. return;
  182. // Call function
  183. push_v3s16(L, p);
  184. pushnode(L, node);
  185. PCALL_RES(lua_pcall(L, 2, 0, error_handler));
  186. lua_pop(L, 1); // Pop error handler
  187. }
  188. bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime)
  189. {
  190. SCRIPTAPI_PRECHECKHEADER
  191. int error_handler = PUSH_ERROR_HANDLER(L);
  192. const NodeDefManager *ndef = getServer()->ndef();
  193. // Push callback function on stack
  194. if (!getItemCallback(ndef->get(node).name.c_str(), "on_timer", &p))
  195. return false;
  196. // Call function
  197. push_v3s16(L, p);
  198. lua_pushnumber(L,dtime);
  199. PCALL_RES(lua_pcall(L, 2, 1, error_handler));
  200. lua_remove(L, error_handler);
  201. return readParam<bool>(L, -1, false);
  202. }
  203. void ScriptApiNode::node_on_receive_fields(v3s16 p,
  204. const std::string &formname,
  205. const StringMap &fields,
  206. ServerActiveObject *sender)
  207. {
  208. SCRIPTAPI_PRECHECKHEADER
  209. int error_handler = PUSH_ERROR_HANDLER(L);
  210. const NodeDefManager *ndef = getServer()->ndef();
  211. // If node doesn't exist, we don't know what callback to call
  212. MapNode node = getEnv()->getMap().getNode(p);
  213. if (node.getContent() == CONTENT_IGNORE)
  214. return;
  215. // Push callback function on stack
  216. if (!getItemCallback(ndef->get(node).name.c_str(), "on_receive_fields", &p))
  217. return;
  218. // Call function
  219. push_v3s16(L, p); // pos
  220. lua_pushstring(L, formname.c_str()); // formname
  221. lua_newtable(L); // fields
  222. StringMap::const_iterator it;
  223. for (it = fields.begin(); it != fields.end(); ++it) {
  224. const std::string &name = it->first;
  225. const std::string &value = it->second;
  226. lua_pushstring(L, name.c_str());
  227. lua_pushlstring(L, value.c_str(), value.size());
  228. lua_settable(L, -3);
  229. }
  230. objectrefGetOrCreate(L, sender); // player
  231. PCALL_RES(lua_pcall(L, 4, 0, error_handler));
  232. lua_pop(L, 1); // Pop error handler
  233. }