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.
 
 
 
 
 
 

279 lines
7.9 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 "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. ScriptApiNode::ScriptApiNode() {
  86. }
  87. ScriptApiNode::~ScriptApiNode() {
  88. }
  89. bool ScriptApiNode::node_on_punch(v3s16 p, MapNode node,
  90. ServerActiveObject *puncher, PointedThing pointed)
  91. {
  92. SCRIPTAPI_PRECHECKHEADER
  93. int error_handler = PUSH_ERROR_HANDLER(L);
  94. INodeDefManager *ndef = getServer()->ndef();
  95. // Push callback function on stack
  96. if (!getItemCallback(ndef->get(node).name.c_str(), "on_punch", &p))
  97. return false;
  98. // Call function
  99. push_v3s16(L, p);
  100. pushnode(L, node, ndef);
  101. objectrefGetOrCreate(L, puncher);
  102. pushPointedThing(pointed);
  103. PCALL_RES(lua_pcall(L, 4, 0, error_handler));
  104. lua_pop(L, 1); // Pop error handler
  105. return true;
  106. }
  107. bool ScriptApiNode::node_on_dig(v3s16 p, MapNode node,
  108. ServerActiveObject *digger)
  109. {
  110. SCRIPTAPI_PRECHECKHEADER
  111. int error_handler = PUSH_ERROR_HANDLER(L);
  112. INodeDefManager *ndef = getServer()->ndef();
  113. // Push callback function on stack
  114. if (!getItemCallback(ndef->get(node).name.c_str(), "on_dig", &p))
  115. return false;
  116. // Call function
  117. push_v3s16(L, p);
  118. pushnode(L, node, ndef);
  119. objectrefGetOrCreate(L, digger);
  120. PCALL_RES(lua_pcall(L, 3, 0, error_handler));
  121. lua_pop(L, 1); // Pop error handler
  122. return true;
  123. }
  124. void ScriptApiNode::node_on_construct(v3s16 p, MapNode node)
  125. {
  126. SCRIPTAPI_PRECHECKHEADER
  127. int error_handler = PUSH_ERROR_HANDLER(L);
  128. INodeDefManager *ndef = getServer()->ndef();
  129. // Push callback function on stack
  130. if (!getItemCallback(ndef->get(node).name.c_str(), "on_construct", &p))
  131. return;
  132. // Call function
  133. push_v3s16(L, p);
  134. PCALL_RES(lua_pcall(L, 1, 0, error_handler));
  135. lua_pop(L, 1); // Pop error handler
  136. }
  137. void ScriptApiNode::node_on_destruct(v3s16 p, MapNode node)
  138. {
  139. SCRIPTAPI_PRECHECKHEADER
  140. int error_handler = PUSH_ERROR_HANDLER(L);
  141. INodeDefManager *ndef = getServer()->ndef();
  142. // Push callback function on stack
  143. if (!getItemCallback(ndef->get(node).name.c_str(), "on_destruct", &p))
  144. return;
  145. // Call function
  146. push_v3s16(L, p);
  147. PCALL_RES(lua_pcall(L, 1, 0, error_handler));
  148. lua_pop(L, 1); // Pop error handler
  149. }
  150. bool ScriptApiNode::node_on_flood(v3s16 p, MapNode node, MapNode newnode)
  151. {
  152. SCRIPTAPI_PRECHECKHEADER
  153. int error_handler = PUSH_ERROR_HANDLER(L);
  154. INodeDefManager *ndef = getServer()->ndef();
  155. // Push callback function on stack
  156. if (!getItemCallback(ndef->get(node).name.c_str(), "on_flood", &p))
  157. return false;
  158. // Call function
  159. push_v3s16(L, p);
  160. pushnode(L, node, ndef);
  161. pushnode(L, newnode, ndef);
  162. PCALL_RES(lua_pcall(L, 3, 1, error_handler));
  163. lua_remove(L, error_handler);
  164. return readParam<bool>(L, -1, false);
  165. }
  166. void ScriptApiNode::node_after_destruct(v3s16 p, MapNode node)
  167. {
  168. SCRIPTAPI_PRECHECKHEADER
  169. int error_handler = PUSH_ERROR_HANDLER(L);
  170. INodeDefManager *ndef = getServer()->ndef();
  171. // Push callback function on stack
  172. if (!getItemCallback(ndef->get(node).name.c_str(), "after_destruct", &p))
  173. return;
  174. // Call function
  175. push_v3s16(L, p);
  176. pushnode(L, node, ndef);
  177. PCALL_RES(lua_pcall(L, 2, 0, error_handler));
  178. lua_pop(L, 1); // Pop error handler
  179. }
  180. bool ScriptApiNode::node_on_timer(v3s16 p, MapNode node, f32 dtime)
  181. {
  182. SCRIPTAPI_PRECHECKHEADER
  183. int error_handler = PUSH_ERROR_HANDLER(L);
  184. INodeDefManager *ndef = getServer()->ndef();
  185. // Push callback function on stack
  186. if (!getItemCallback(ndef->get(node).name.c_str(), "on_timer", &p))
  187. return false;
  188. // Call function
  189. push_v3s16(L, p);
  190. lua_pushnumber(L,dtime);
  191. PCALL_RES(lua_pcall(L, 2, 1, error_handler));
  192. lua_remove(L, error_handler);
  193. return readParam<bool>(L, -1, false);
  194. }
  195. void ScriptApiNode::node_on_receive_fields(v3s16 p,
  196. const std::string &formname,
  197. const StringMap &fields,
  198. ServerActiveObject *sender)
  199. {
  200. SCRIPTAPI_PRECHECKHEADER
  201. int error_handler = PUSH_ERROR_HANDLER(L);
  202. INodeDefManager *ndef = getServer()->ndef();
  203. // If node doesn't exist, we don't know what callback to call
  204. MapNode node = getEnv()->getMap().getNodeNoEx(p);
  205. if (node.getContent() == CONTENT_IGNORE)
  206. return;
  207. // Push callback function on stack
  208. if (!getItemCallback(ndef->get(node).name.c_str(), "on_receive_fields", &p))
  209. return;
  210. // Call function
  211. push_v3s16(L, p); // pos
  212. lua_pushstring(L, formname.c_str()); // formname
  213. lua_newtable(L); // fields
  214. StringMap::const_iterator it;
  215. for (it = fields.begin(); it != fields.end(); ++it) {
  216. const std::string &name = it->first;
  217. const std::string &value = it->second;
  218. lua_pushstring(L, name.c_str());
  219. lua_pushlstring(L, value.c_str(), value.size());
  220. lua_settable(L, -3);
  221. }
  222. objectrefGetOrCreate(L, sender); // player
  223. PCALL_RES(lua_pcall(L, 4, 0, error_handler));
  224. lua_pop(L, 1); // Pop error handler
  225. }