summaryrefslogtreecommitdiff
path: root/src/script/common/c_content.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/script/common/c_content.cpp')
-rw-r--r--src/script/common/c_content.cpp472
1 files changed, 437 insertions, 35 deletions
diff --git a/src/script/common/c_content.cpp b/src/script/common/c_content.cpp
index 541744895..c0e29abf0 100644
--- a/src/script/common/c_content.cpp
+++ b/src/script/common/c_content.cpp
@@ -20,7 +20,6 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "common/c_converter.h"
#include "common/c_types.h"
#include "nodedef.h"
-#include "itemdef.h"
#include "object_properties.h"
#include "cpp_api/s_node.h"
#include "lua_api/l_object.h"
@@ -33,31 +32,37 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "porting.h"
#include "mg_schematic.h"
#include "noise.h"
+#include "util/pointedthing.h"
+#include "debug.h" // For FATAL_ERROR
#include <json/json.h>
struct EnumString es_TileAnimationType[] =
{
{TAT_NONE, "none"},
{TAT_VERTICAL_FRAMES, "vertical_frames"},
+ {TAT_SHEET_2D, "sheet_2d"},
{0, NULL},
};
/******************************************************************************/
-ItemDefinition read_item_definition(lua_State* L,int index,
- ItemDefinition default_def)
+void read_item_definition(lua_State* L, int index,
+ const ItemDefinition &default_def, ItemDefinition &def)
{
- if(index < 0)
+ if (index < 0)
index = lua_gettop(L) + 1 + index;
- // Read the item definition
- ItemDefinition def = default_def;
-
def.type = (ItemType)getenumfield(L, index, "type",
es_ItemType, ITEM_NONE);
getstringfield(L, index, "name", def.name);
getstringfield(L, index, "description", def.description);
getstringfield(L, index, "inventory_image", def.inventory_image);
getstringfield(L, index, "wield_image", def.wield_image);
+ getstringfield(L, index, "palette", def.palette_image);
+
+ // Read item color.
+ lua_getfield(L, index, "color");
+ read_color(L, -1, &def.color);
+ lua_pop(L, 1);
lua_getfield(L, index, "wield_scale");
if(lua_istable(L, -1)){
@@ -112,13 +117,66 @@ ItemDefinition read_item_definition(lua_State* L,int index,
// "" = no prediction
getstringfield(L, index, "node_placement_prediction",
def.node_placement_prediction);
+}
+
+/******************************************************************************/
+void push_item_definition(lua_State *L, const ItemDefinition &i)
+{
+ lua_newtable(L);
+ lua_pushstring(L, i.name.c_str());
+ lua_setfield(L, -2, "name");
+ lua_pushstring(L, i.description.c_str());
+ lua_setfield(L, -2, "description");
+}
- return def;
+void push_item_definition_full(lua_State *L, const ItemDefinition &i)
+{
+ std::string type(es_ItemType[(int)i.type].str);
+
+ lua_newtable(L);
+ lua_pushstring(L, i.name.c_str());
+ lua_setfield(L, -2, "name");
+ lua_pushstring(L, i.description.c_str());
+ lua_setfield(L, -2, "description");
+ lua_pushstring(L, type.c_str());
+ lua_setfield(L, -2, "type");
+ lua_pushstring(L, i.inventory_image.c_str());
+ lua_setfield(L, -2, "inventory_image");
+ lua_pushstring(L, i.wield_image.c_str());
+ lua_setfield(L, -2, "wield_image");
+ lua_pushstring(L, i.palette_image.c_str());
+ lua_setfield(L, -2, "palette_image");
+ push_ARGB8(L, i.color);
+ lua_setfield(L, -2, "color");
+ push_v3f(L, i.wield_scale);
+ lua_setfield(L, -2, "wield_scale");
+ lua_pushinteger(L, i.stack_max);
+ lua_setfield(L, -2, "stack_max");
+ lua_pushboolean(L, i.usable);
+ lua_setfield(L, -2, "usable");
+ lua_pushboolean(L, i.liquids_pointable);
+ lua_setfield(L, -2, "liquids_pointable");
+ if (i.type == ITEM_TOOL) {
+ push_tool_capabilities(L, ToolCapabilities(
+ i.tool_capabilities->full_punch_interval,
+ i.tool_capabilities->max_drop_level,
+ i.tool_capabilities->groupcaps,
+ i.tool_capabilities->damageGroups));
+ lua_setfield(L, -2, "tool_capabilities");
+ }
+ push_groups(L, i.groups);
+ lua_setfield(L, -2, "groups");
+ push_soundspec(L, i.sound_place);
+ lua_setfield(L, -2, "sound_place");
+ push_soundspec(L, i.sound_place_failed);
+ lua_setfield(L, -2, "sound_place_failed");
+ lua_pushstring(L, i.node_placement_prediction.c_str());
+ lua_setfield(L, -2, "node_placement_prediction");
}
/******************************************************************************/
void read_object_properties(lua_State *L, int index,
- ObjectProperties *prop)
+ ObjectProperties *prop, IItemDefManager *idef)
{
if(index < 0)
index = lua_gettop(L) + 1 + index;
@@ -216,6 +274,10 @@ void read_object_properties(lua_State *L, int index,
}
lua_pop(L, 1);
getstringfield(L, -1, "infotext", prop->infotext);
+ lua_getfield(L, -1, "wield_item");
+ if (!lua_isnil(L, -1))
+ prop->wield_item = read_item(L, -1, idef).getItemString();
+ lua_pop(L, 1);
}
/******************************************************************************/
@@ -284,6 +346,8 @@ void push_object_properties(lua_State *L, ObjectProperties *prop)
lua_setfield(L, -2, "automatic_face_movement_max_rotation_per_sec");
lua_pushlstring(L, prop->infotext.c_str(), prop->infotext.size());
lua_setfield(L, -2, "infotext");
+ lua_pushlstring(L, prop->wield_item.c_str(), prop->wield_item.size());
+ lua_setfield(L, -2, "wield_item");
}
/******************************************************************************/
@@ -321,7 +385,7 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype)
}
else if(lua_istable(L, index))
{
- // {name="default_lava.png", animation={}}
+ // name="default_lava.png"
tiledef.name = "";
getstringfield(L, index, "name", tiledef.name);
getstringfield(L, index, "image", tiledef.name); // MaterialSpec compat.
@@ -331,20 +395,13 @@ TileDef read_tiledef(lua_State *L, int index, u8 drawtype)
L, index, "tileable_horizontal", default_tiling);
tiledef.tileable_vertical = getboolfield_default(
L, index, "tileable_vertical", default_tiling);
+ // color = ...
+ lua_getfield(L, index, "color");
+ tiledef.has_color = read_color(L, -1, &tiledef.color);
+ lua_pop(L, 1);
// animation = {}
lua_getfield(L, index, "animation");
- if(lua_istable(L, -1)){
- // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
- tiledef.animation.type = (TileAnimationType)
- getenumfield(L, -1, "type", es_TileAnimationType,
- TAT_NONE);
- tiledef.animation.aspect_w =
- getintfield_default(L, -1, "aspect_w", 16);
- tiledef.animation.aspect_h =
- getintfield_default(L, -1, "aspect_h", 16);
- tiledef.animation.length =
- getfloatfield_default(L, -1, "length", 1.0);
- }
+ tiledef.animation = read_animation_definition(L, -1);
lua_pop(L, 1);
}
@@ -426,6 +483,34 @@ ContentFeatures read_content_features(lua_State *L, int index)
}
lua_pop(L, 1);
+ // overlay_tiles = {}
+ lua_getfield(L, index, "overlay_tiles");
+ if (lua_istable(L, -1)) {
+ int table = lua_gettop(L);
+ lua_pushnil(L);
+ int i = 0;
+ while (lua_next(L, table) != 0) {
+ // Read tiledef from value
+ f.tiledef_overlay[i] = read_tiledef(L, -1, f.drawtype);
+ // removes value, keeps key for next iteration
+ lua_pop(L, 1);
+ i++;
+ if (i == 6) {
+ lua_pop(L, 1);
+ break;
+ }
+ }
+ // Copy last value to all remaining textures
+ if (i >= 1) {
+ TileDef lasttile = f.tiledef_overlay[i - 1];
+ while (i < 6) {
+ f.tiledef_overlay[i] = lasttile;
+ i++;
+ }
+ }
+ }
+ lua_pop(L, 1);
+
// special_tiles = {}
lua_getfield(L, index, "special_tiles");
// If nil, try the deprecated name "special_materials" instead
@@ -460,6 +545,13 @@ ContentFeatures read_content_features(lua_State *L, int index)
if (usealpha)
f.alpha = 0;
+ // Read node color.
+ lua_getfield(L, index, "color");
+ read_color(L, -1, &f.color);
+ lua_pop(L, 1);
+
+ getstringfield(L, index, "palette", f.palette_name);
+
/* Other stuff */
lua_getfield(L, index, "post_effect_color");
@@ -471,6 +563,13 @@ ContentFeatures read_content_features(lua_State *L, int index)
f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2",
ScriptApiNode::es_ContentParamType2, CPT2_NONE);
+ if (f.palette_name != "" &&
+ !(f.param_type_2 == CPT2_COLOR ||
+ f.param_type_2 == CPT2_COLORED_FACEDIR ||
+ f.param_type_2 == CPT2_COLORED_WALLMOUNTED))
+ warningstream << "Node " << f.name.c_str()
+ << " has a palette, but not a suitable paramtype2." << std::endl;
+
// Warn about some deprecated fields
warn_if_field_exists(L, index, "wall_mounted",
"Deprecated; use paramtype2 = 'wallmounted'");
@@ -616,6 +715,204 @@ ContentFeatures read_content_features(lua_State *L, int index)
return f;
}
+void push_content_features(lua_State *L, const ContentFeatures &c)
+{
+ std::string paramtype(ScriptApiNode::es_ContentParamType[(int)c.param_type].str);
+ std::string paramtype2(ScriptApiNode::es_ContentParamType2[(int)c.param_type_2].str);
+ std::string drawtype(ScriptApiNode::es_DrawType[(int)c.drawtype].str);
+ std::string liquid_type(ScriptApiNode::es_LiquidType[(int)c.liquid_type].str);
+
+ /* Missing "tiles" because I don't see a usecase (at least not yet). */
+
+ lua_newtable(L);
+ lua_pushboolean(L, c.has_on_construct);
+ lua_setfield(L, -2, "has_on_construct");
+ lua_pushboolean(L, c.has_on_destruct);
+ lua_setfield(L, -2, "has_on_destruct");
+ lua_pushboolean(L, c.has_after_destruct);
+ lua_setfield(L, -2, "has_after_destruct");
+ lua_pushstring(L, c.name.c_str());
+ lua_setfield(L, -2, "name");
+ push_groups(L, c.groups);
+ lua_setfield(L, -2, "groups");
+ lua_pushstring(L, paramtype.c_str());
+ lua_setfield(L, -2, "paramtype");
+ lua_pushstring(L, paramtype2.c_str());
+ lua_setfield(L, -2, "paramtype2");
+ lua_pushstring(L, drawtype.c_str());
+ lua_setfield(L, -2, "drawtype");
+ if (!c.mesh.empty()) {
+ lua_pushstring(L, c.mesh.c_str());
+ lua_setfield(L, -2, "mesh");
+ }
+#ifndef SERVER
+ push_ARGB8(L, c.minimap_color); // I know this is not set-able w/ register_node,
+ lua_setfield(L, -2, "minimap_color"); // but the people need to know!
+#endif
+ lua_pushnumber(L, c.visual_scale);
+ lua_setfield(L, -2, "visual_scale");
+ lua_pushnumber(L, c.alpha);
+ lua_setfield(L, -2, "alpha");
+ if (!c.palette_name.empty()) {
+ push_ARGB8(L, c.color);
+ lua_setfield(L, -2, "color");
+
+ lua_pushstring(L, c.palette_name.c_str());
+ lua_setfield(L, -2, "palette_name");
+
+ push_palette(L, c.palette);
+ lua_setfield(L, -2, "palette");
+ }
+ lua_pushnumber(L, c.waving);
+ lua_setfield(L, -2, "waving");
+ lua_pushnumber(L, c.connect_sides);
+ lua_setfield(L, -2, "connect_sides");
+
+ lua_newtable(L);
+ u16 i = 1;
+ for (std::vector<std::string>::const_iterator it = c.connects_to.begin();
+ it != c.connects_to.end(); ++it) {
+ lua_pushlstring(L, it->c_str(), it->size());
+ lua_rawseti(L, -2, i);
+ }
+ lua_setfield(L, -2, "connects_to");
+
+ push_ARGB8(L, c.post_effect_color);
+ lua_setfield(L, -2, "post_effect_color");
+ lua_pushnumber(L, c.leveled);
+ lua_setfield(L, -2, "leveled");
+ lua_pushboolean(L, c.sunlight_propagates);
+ lua_setfield(L, -2, "sunlight_propagates");
+ lua_pushnumber(L, c.light_source);
+ lua_setfield(L, -2, "light_source");
+ lua_pushboolean(L, c.is_ground_content);
+ lua_setfield(L, -2, "is_ground_content");
+ lua_pushboolean(L, c.walkable);
+ lua_setfield(L, -2, "walkable");
+ lua_pushboolean(L, c.pointable);
+ lua_setfield(L, -2, "pointable");
+ lua_pushboolean(L, c.diggable);
+ lua_setfield(L, -2, "diggable");
+ lua_pushboolean(L, c.climbable);
+ lua_setfield(L, -2, "climbable");
+ lua_pushboolean(L, c.buildable_to);
+ lua_setfield(L, -2, "buildable_to");
+ lua_pushboolean(L, c.rightclickable);
+ lua_setfield(L, -2, "rightclickable");
+ lua_pushnumber(L, c.damage_per_second);
+ lua_setfield(L, -2, "damage_per_second");
+ if (c.isLiquid()) {
+ lua_pushstring(L, liquid_type.c_str());
+ lua_setfield(L, -2, "liquid_type");
+ lua_pushstring(L, c.liquid_alternative_flowing.c_str());
+ lua_setfield(L, -2, "liquid_alternative_flowing");
+ lua_pushstring(L, c.liquid_alternative_source.c_str());
+ lua_setfield(L, -2, "liquid_alternative_source");
+ lua_pushnumber(L, c.liquid_viscosity);
+ lua_setfield(L, -2, "liquid_viscosity");
+ lua_pushboolean(L, c.liquid_renewable);
+ lua_setfield(L, -2, "liquid_renewable");
+ lua_pushnumber(L, c.liquid_range);
+ lua_setfield(L, -2, "liquid_range");
+ }
+ lua_pushnumber(L, c.drowning);
+ lua_setfield(L, -2, "drowning");
+ lua_pushboolean(L, c.floodable);
+ lua_setfield(L, -2, "floodable");
+ push_nodebox(L, c.node_box);
+ lua_setfield(L, -2, "node_box");
+ push_nodebox(L, c.selection_box);
+ lua_setfield(L, -2, "selection_box");
+ push_nodebox(L, c.collision_box);
+ lua_setfield(L, -2, "collision_box");
+ lua_newtable(L);
+ push_soundspec(L, c.sound_footstep);
+ lua_setfield(L, -2, "sound_footstep");
+ push_soundspec(L, c.sound_dig);
+ lua_setfield(L, -2, "sound_dig");
+ push_soundspec(L, c.sound_dug);
+ lua_setfield(L, -2, "sound_dug");
+ lua_setfield(L, -2, "sounds");
+ lua_pushboolean(L, c.legacy_facedir_simple);
+ lua_setfield(L, -2, "legacy_facedir_simple");
+ lua_pushboolean(L, c.legacy_wallmounted);
+ lua_setfield(L, -2, "legacy_wallmounted");
+}
+
+/******************************************************************************/
+void push_nodebox(lua_State *L, const NodeBox &box)
+{
+ lua_newtable(L);
+ switch (box.type)
+ {
+ case NODEBOX_REGULAR:
+ lua_pushstring(L, "regular");
+ lua_setfield(L, -2, "type");
+ break;
+ case NODEBOX_LEVELED:
+ case NODEBOX_FIXED:
+ lua_pushstring(L, "fixed");
+ lua_setfield(L, -2, "type");
+ push_box(L, box.fixed);
+ lua_setfield(L, -2, "fixed");
+ break;
+ case NODEBOX_WALLMOUNTED:
+ lua_pushstring(L, "wallmounted");
+ lua_setfield(L, -2, "type");
+ push_aabb3f(L, box.wall_top);
+ lua_setfield(L, -2, "wall_top");
+ push_aabb3f(L, box.wall_bottom);
+ lua_setfield(L, -2, "wall_bottom");
+ push_aabb3f(L, box.wall_side);
+ lua_setfield(L, -2, "wall_side");
+ break;
+ case NODEBOX_CONNECTED:
+ lua_pushstring(L, "connected");
+ lua_setfield(L, -2, "type");
+ push_box(L, box.connect_top);
+ lua_setfield(L, -2, "connect_top");
+ push_box(L, box.connect_bottom);
+ lua_setfield(L, -2, "connect_bottom");
+ push_box(L, box.connect_front);
+ lua_setfield(L, -2, "connect_front");
+ push_box(L, box.connect_back);
+ lua_setfield(L, -2, "connect_back");
+ push_box(L, box.connect_left);
+ lua_setfield(L, -2, "connect_left");
+ push_box(L, box.connect_right);
+ lua_setfield(L, -2, "connect_right");
+ break;
+ default:
+ FATAL_ERROR("Invalid box.type");
+ break;
+ }
+}
+
+void push_box(lua_State *L, const std::vector<aabb3f> &box)
+{
+ lua_newtable(L);
+ u8 i = 1;
+ for (std::vector<aabb3f>::const_iterator it = box.begin();
+ it != box.end(); ++it) {
+ push_aabb3f(L, (*it));
+ lua_rawseti(L, -2, i);
+ }
+}
+
+/******************************************************************************/
+void push_palette(lua_State *L, const std::vector<video::SColor> *palette)
+{
+ lua_createtable(L, palette->size(), 0);
+ int newTable = lua_gettop(L);
+ int index = 1;
+ std::vector<video::SColor>::const_iterator iter;
+ for (iter = palette->begin(); iter != palette->end(); ++iter) {
+ push_ARGB8(L, (*iter));
+ lua_rawseti(L, newTable, index);
+ index++;
+ }
+}
+
/******************************************************************************/
void read_server_sound_params(lua_State *L, int index,
ServerSoundParams &params)
@@ -627,6 +924,7 @@ void read_server_sound_params(lua_State *L, int index,
if(lua_istable(L, index)){
getfloatfield(L, index, "gain", params.gain);
getstringfield(L, index, "to_player", params.to_player);
+ getfloatfield(L, index, "fade", params.fade);
lua_getfield(L, index, "pos");
if(!lua_isnil(L, -1)){
v3f p = read_v3f(L, -1)*BS;
@@ -659,11 +957,23 @@ void read_soundspec(lua_State *L, int index, SimpleSoundSpec &spec)
} else if(lua_istable(L, index)){
getstringfield(L, index, "name", spec.name);
getfloatfield(L, index, "gain", spec.gain);
+ getfloatfield(L, index, "fade", spec.fade);
} else if(lua_isstring(L, index)){
spec.name = lua_tostring(L, index);
}
}
+void push_soundspec(lua_State *L, const SimpleSoundSpec &spec)
+{
+ lua_newtable(L);
+ lua_pushstring(L, spec.name.c_str());
+ lua_setfield(L, -2, "name");
+ lua_pushnumber(L, spec.gain);
+ lua_setfield(L, -2, "gain");
+ lua_pushnumber(L, spec.fade);
+ lua_setfield(L, -2, "fade");
+}
+
/******************************************************************************/
NodeBox read_nodebox(lua_State *L, int index)
{
@@ -776,7 +1086,7 @@ bool string_to_enum(const EnumString *spec, int &result,
}
/******************************************************************************/
-ItemStack read_item(lua_State* L, int index,Server* srv)
+ItemStack read_item(lua_State* L, int index, IItemDefManager *idef)
{
if(index < 0)
index = lua_gettop(L) + 1 + index;
@@ -795,7 +1105,6 @@ ItemStack read_item(lua_State* L, int index,Server* srv)
{
// Convert from itemstring
std::string itemstring = lua_tostring(L, index);
- IItemDefManager *idef = srv->idef();
try
{
ItemStack item;
@@ -812,15 +1121,34 @@ ItemStack read_item(lua_State* L, int index,Server* srv)
else if(lua_istable(L, index))
{
// Convert from table
- IItemDefManager *idef = srv->idef();
std::string name = getstringfield_default(L, index, "name", "");
int count = getintfield_default(L, index, "count", 1);
int wear = getintfield_default(L, index, "wear", 0);
- std::string metadata = getstringfield_default(L, index, "metadata", "");
- return ItemStack(name, count, wear, metadata, idef);
- }
- else
- {
+
+ ItemStack istack(name, count, wear, idef);
+
+ // BACKWARDS COMPATIBLITY
+ std::string value = getstringfield_default(L, index, "metadata", "");
+ istack.metadata.setString("", value);
+
+ // Get meta
+ lua_getfield(L, index, "meta");
+ int fieldstable = lua_gettop(L);
+ if (lua_istable(L, fieldstable)) {
+ lua_pushnil(L);
+ while (lua_next(L, fieldstable) != 0) {
+ // key at index -2 and value at index -1
+ std::string key = lua_tostring(L, -2);
+ size_t value_len;
+ const char *value_cs = lua_tolstring(L, -1, &value_len);
+ std::string value(value_cs, value_len);
+ istack.metadata.setString(key, value);
+ lua_pop(L, 1); // removes value, keeps key for next iteration
+ }
+ }
+
+ return istack;
+ } else {
throw LuaError("Expecting itemstack, itemstring, table or nil");
}
}
@@ -836,7 +1164,7 @@ void push_tool_capabilities(lua_State *L,
lua_newtable(L);
// For each groupcap
for (ToolGCMap::const_iterator i = toolcap.groupcaps.begin();
- i != toolcap.groupcaps.end(); i++) {
+ i != toolcap.groupcaps.end(); ++i) {
// Create groupcap table
lua_newtable(L);
const std::string &name = i->first;
@@ -844,7 +1172,7 @@ void push_tool_capabilities(lua_State *L,
// Create subtable "times"
lua_newtable(L);
for (UNORDERED_MAP<int, float>::const_iterator
- i = groupcap.times.begin(); i != groupcap.times.end(); i++) {
+ i = groupcap.times.begin(); i != groupcap.times.end(); ++i) {
lua_pushinteger(L, i->first);
lua_pushnumber(L, i->second);
lua_settable(L, -3);
@@ -863,7 +1191,7 @@ void push_tool_capabilities(lua_State *L,
lua_newtable(L);
// For each damage group
for (DamageGroup::const_iterator i = toolcap.damageGroups.begin();
- i != toolcap.damageGroups.end(); i++) {
+ i != toolcap.damageGroups.end(); ++i) {
// Create damage group table
lua_pushinteger(L, i->second);
lua_setfield(L, -2, i->first.c_str());
@@ -902,7 +1230,7 @@ void read_inventory_list(lua_State *L, int tableindex,
InventoryList *invlist = inv->addList(name, listsize);
int index = 0;
for(std::vector<ItemStack>::const_iterator
- i = items.begin(); i != items.end(); i++){
+ i = items.begin(); i != items.end(); ++i){
if(forcesize != -1 && index == forcesize)
break;
invlist->changeItem(index, *i);
@@ -915,6 +1243,41 @@ void read_inventory_list(lua_State *L, int tableindex,
}
/******************************************************************************/
+struct TileAnimationParams read_animation_definition(lua_State *L, int index)
+{
+ if(index < 0)
+ index = lua_gettop(L) + 1 + index;
+
+ struct TileAnimationParams anim;
+ anim.type = TAT_NONE;
+ if (!lua_istable(L, index))
+ return anim;
+
+ anim.type = (TileAnimationType)
+ getenumfield(L, index, "type", es_TileAnimationType,
+ TAT_NONE);
+ if (anim.type == TAT_VERTICAL_FRAMES) {
+ // {type="vertical_frames", aspect_w=16, aspect_h=16, length=2.0}
+ anim.vertical_frames.aspect_w =
+ getintfield_default(L, index, "aspect_w", 16);
+ anim.vertical_frames.aspect_h =
+ getintfield_default(L, index, "aspect_h", 16);
+ anim.vertical_frames.length =
+ getfloatfield_default(L, index, "length", 1.0);
+ } else if (anim.type == TAT_SHEET_2D) {
+ // {type="sheet_2d", frames_w=5, frames_h=3, frame_length=0.5}
+ getintfield(L, index, "frames_w",
+ anim.sheet_2d.frames_w);
+ getintfield(L, index, "frames_h",
+ anim.sheet_2d.frames_h);
+ getfloatfield(L, index, "frame_length",
+ anim.sheet_2d.frame_length);
+ }
+
+ return anim;
+}
+
+/******************************************************************************/
ToolCapabilities read_tool_capabilities(
lua_State *L, int table)
{
@@ -1124,7 +1487,7 @@ std::vector<ItemStack> read_items(lua_State *L, int index, Server *srv)
if (items.size() < (u32) key) {
items.resize(key);
}
- items[key - 1] = read_item(L, -1, srv);
+ items[key - 1] = read_item(L, -1, srv->idef());
lua_pop(L, 1);
}
return items;
@@ -1332,3 +1695,42 @@ void read_json_value(lua_State *L, Json::Value &root, int index, u8 recursion)
}
lua_pop(L, 1); // Pop value
}
+
+void push_pointed_thing(lua_State *L, const PointedThing &pointed, bool csm)
+{
+ lua_newtable(L);
+ if (pointed.type == POINTEDTHING_NODE) {
+ lua_pushstring(L, "node");
+ lua_setfield(L, -2, "type");
+ push_v3s16(L, pointed.node_undersurface);
+ lua_setfield(L, -2, "under");
+ push_v3s16(L, pointed.node_abovesurface);
+ lua_setfield(L, -2, "above");
+ } else if (pointed.type == POINTEDTHING_OBJECT) {
+ lua_pushstring(L, "object");
+ lua_setfield(L, -2, "type");
+
+ if (csm) {
+ lua_pushinteger(L, pointed.object_id);
+ lua_setfield(L, -2, "id");
+ } else {
+ push_objectRef(L, pointed.object_id);
+ lua_setfield(L, -2, "ref");
+ }
+ } else {
+ lua_pushstring(L, "nothing");
+ lua_setfield(L, -2, "type");
+ }
+}
+
+void push_objectRef(lua_State *L, const u16 id)
+{
+ // Get core.object_refs[i]
+ lua_getglobal(L, "core");
+ lua_getfield(L, -1, "object_refs");
+ luaL_checktype(L, -1, LUA_TTABLE);
+ lua_pushnumber(L, id);
+ lua_gettable(L, -2);
+ lua_remove(L, -2); // object_refs
+ lua_remove(L, -2); // core
+}