#include "mapblock.h" // For getNodeBlockPos
#include "content_nodemeta.h"
#include "utility.h"
+#include "tool.h"
+#include "daynightratio.h"
static void stackDump(lua_State *L, std::ostream &o)
{
return result;
}
+static void setintfield(lua_State *L, int table,
+ const char *fieldname, int value)
+{
+ lua_pushinteger(L, value);
+ if(table < 0)
+ table -= 1;
+ lua_setfield(L, table, fieldname);
+}
+
static void setfloatfield(lua_State *L, int table,
const char *fieldname, float value)
{
lua_setfield(L, table, fieldname);
}
+static void setboolfield(lua_State *L, int table,
+ const char *fieldname, bool value)
+{
+ lua_pushboolean(L, value);
+ if(table < 0)
+ table -= 1;
+ lua_setfield(L, table, fieldname);
+}
+
static void warn_if_field_exists(lua_State *L, int table,
const char *fieldname, const std::string &message)
{
{
{CPT_NONE, "none"},
{CPT_LIGHT, "light"},
- {CPT_MINERAL, "mineral"},
- {CPT_FACEDIR_SIMPLE, "facedir_simple"},
+ {0, NULL},
+};
+
+struct EnumString es_ContentParamType2[] =
+{
+ {CPT2_NONE, "none"},
+ {CPT2_FULL, "full"},
+ {CPT2_FLOWINGLIQUID, "flowingliquid"},
+ {CPT2_FACEDIR, "facedir"},
+ {CPT2_WALLMOUNTED, "wallmounted"},
{0, NULL},
};
{0, NULL},
};
-struct EnumString es_Diggability[] =
-{
- {DIGGABLE_NOT, "not"},
- {DIGGABLE_NORMAL, "normal"},
- {DIGGABLE_CONSTANT, "constant"},
- {0, NULL},
-};
-
/*
C struct <-> Lua table converter functions
*/
return box;
}
+#if 0
/*
- ToolDiggingProperties
+ MaterialProperties
*/
-static ToolDiggingProperties read_tool_digging_properties(
+static MaterialProperties read_material_properties(
lua_State *L, int table)
{
- ToolDiggingProperties prop;
- getfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
- getfloatfield(L, table, "basetime", prop.basetime);
- getfloatfield(L, table, "dt_weight", prop.dt_weight);
- getfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
- getfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
- getfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
- getfloatfield(L, table, "basedurability", prop.basedurability);
- getfloatfield(L, table, "dd_weight", prop.dd_weight);
- getfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
- getfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
- getfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
+ MaterialProperties prop;
+ prop.diggability = (Diggability)getenumfield(L, -1, "diggability",
+ es_Diggability, DIGGABLE_NORMAL);
+ getfloatfield(L, -1, "constant_time", prop.constant_time);
+ getfloatfield(L, -1, "weight", prop.weight);
+ getfloatfield(L, -1, "crackiness", prop.crackiness);
+ getfloatfield(L, -1, "crumbliness", prop.crumbliness);
+ getfloatfield(L, -1, "cuttability", prop.cuttability);
+ getfloatfield(L, -1, "flammability", prop.flammability);
return prop;
}
+#endif
+
+/*
+ Groups
+*/
+static void read_groups(lua_State *L, int index,
+ std::map<std::string, int> &result)
+{
+ result.clear();
+ lua_pushnil(L);
+ if(index < 0)
+ index -= 1;
+ while(lua_next(L, index) != 0){
+ // key at index -2 and value at index -1
+ std::string name = luaL_checkstring(L, -2);
+ int rating = luaL_checkinteger(L, -1);
+ result[name] = rating;
+ // removes value, keeps key for next iteration
+ lua_pop(L, 1);
+ }
+}
+
+/*
+ ToolCapabilities
+*/
+
+static ToolCapabilities read_tool_capabilities(
+ lua_State *L, int table)
+{
+ ToolCapabilities toolcap;
+ getfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval);
+ getintfield(L, table, "max_drop_level", toolcap.max_drop_level);
+ lua_getfield(L, table, "groupcaps");
+ if(lua_istable(L, -1)){
+ int table_groupcaps = lua_gettop(L);
+ lua_pushnil(L);
+ while(lua_next(L, table_groupcaps) != 0){
+ // key at index -2 and value at index -1
+ std::string groupname = luaL_checkstring(L, -2);
+ if(lua_istable(L, -1)){
+ int table_groupcap = lua_gettop(L);
+ // This will be created
+ ToolGroupCap groupcap;
+ // Read simple parameters
+ getfloatfield(L, table_groupcap, "maxwear", groupcap.maxwear);
+ getintfield(L, table_groupcap, "maxlevel", groupcap.maxlevel);
+ // Read "times" table
+ lua_getfield(L, table_groupcap, "times");
+ if(lua_istable(L, -1)){
+ int table_times = lua_gettop(L);
+ lua_pushnil(L);
+ while(lua_next(L, table_times) != 0){
+ // key at index -2 and value at index -1
+ int rating = luaL_checkinteger(L, -2);
+ float time = luaL_checknumber(L, -1);
+ groupcap.times[rating] = time;
+ // removes value, keeps key for next iteration
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ // Insert groupcap into toolcap
+ toolcap.groupcaps[groupname] = groupcap;
+ }
+ // removes value, keeps key for next iteration
+ lua_pop(L, 1);
+ }
+ }
+ lua_pop(L, 1);
+ return toolcap;
+}
+
+static void set_tool_capabilities(lua_State *L, int table,
+ const ToolCapabilities &toolcap)
+{
+ setfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval);
+ setintfield(L, table, "max_drop_level", toolcap.max_drop_level);
+ // Create groupcaps table
+ lua_newtable(L);
+ // For each groupcap
+ for(std::map<std::string, ToolGroupCap>::const_iterator
+ i = toolcap.groupcaps.begin(); i != toolcap.groupcaps.end(); i++){
+ // Create groupcap table
+ lua_newtable(L);
+ const std::string &name = i->first;
+ const ToolGroupCap &groupcap = i->second;
+ // Create subtable "times"
+ lua_newtable(L);
+ for(std::map<int, float>::const_iterator
+ i = groupcap.times.begin(); i != groupcap.times.end(); i++){
+ int rating = i->first;
+ float time = i->second;
+ lua_pushinteger(L, rating);
+ lua_pushnumber(L, time);
+ lua_settable(L, -3);
+ }
+ // Set subtable "times"
+ lua_setfield(L, -2, "times");
+ // Set simple parameters
+ setfloatfield(L, -1, "maxwear", groupcap.maxwear);
+ setintfield(L, -1, "maxlevel", groupcap.maxlevel);
+ // Insert groupcap table into groupcaps table
+ lua_setfield(L, -2, name.c_str());
+ }
+ // Set groupcaps table
+ lua_setfield(L, -2, "groupcaps");
+}
-static void set_tool_digging_properties(lua_State *L, int table,
- const ToolDiggingProperties &prop)
+static void push_tool_capabilities(lua_State *L,
+ const ToolCapabilities &prop)
{
- setfloatfield(L, table, "full_punch_interval", prop.full_punch_interval);
- setfloatfield(L, table, "basetime", prop.basetime);
- setfloatfield(L, table, "dt_weight", prop.dt_weight);
- setfloatfield(L, table, "dt_crackiness", prop.dt_crackiness);
- setfloatfield(L, table, "dt_crumbliness", prop.dt_crumbliness);
- setfloatfield(L, table, "dt_cuttability", prop.dt_cuttability);
- setfloatfield(L, table, "basedurability", prop.basedurability);
- setfloatfield(L, table, "dd_weight", prop.dd_weight);
- setfloatfield(L, table, "dd_crackiness", prop.dd_crackiness);
- setfloatfield(L, table, "dd_crumbliness", prop.dd_crumbliness);
- setfloatfield(L, table, "dd_cuttability", prop.dd_cuttability);
+ lua_newtable(L);
+ set_tool_capabilities(L, -1, prop);
+}
+
+/*
+ DigParams
+*/
+
+static void set_dig_params(lua_State *L, int table,
+ const DigParams ¶ms)
+{
+ setboolfield(L, table, "diggable", params.diggable);
+ setfloatfield(L, table, "time", params.time);
+ setintfield(L, table, "wear", params.wear);
+}
+
+static void push_dig_params(lua_State *L,
+ const DigParams ¶ms)
+{
+ lua_newtable(L);
+ set_dig_params(L, -1, params);
+}
+
+/*
+ HitParams
+*/
+
+static void set_hit_params(lua_State *L, int table,
+ const HitParams ¶ms)
+{
+ setintfield(L, table, "hp", params.hp);
+ setintfield(L, table, "wear", params.wear);
}
-static void push_tool_digging_properties(lua_State *L,
- const ToolDiggingProperties &prop)
+static void push_hit_params(lua_State *L,
+ const HitParams ¶ms)
{
lua_newtable(L);
- set_tool_digging_properties(L, -1, prop);
+ set_hit_params(L, -1, params);
}
/*
}
}
+/*
+ SimpleSoundSpec
+*/
+
+static void read_soundspec(lua_State *L, int index, SimpleSoundSpec &spec)
+{
+ if(index < 0)
+ index = lua_gettop(L) + 1 + index;
+ if(lua_isnil(L, index)){
+ } else if(lua_istable(L, index)){
+ getstringfield(L, index, "name", spec.name);
+ getfloatfield(L, index, "gain", spec.gain);
+ } else if(lua_isstring(L, index)){
+ spec.name = lua_tostring(L, index);
+ }
+}
+
/*
ItemDefinition
*/
getboolfield(L, index, "liquids_pointable", def.liquids_pointable);
- lua_getfield(L, index, "tool_digging_properties");
+ warn_if_field_exists(L, index, "tool_digging_properties",
+ "deprecated: use tool_capabilities");
+
+ lua_getfield(L, index, "tool_capabilities");
if(lua_istable(L, -1)){
- def.tool_digging_properties = new ToolDiggingProperties(
- read_tool_digging_properties(L, -1));
+ def.tool_capabilities = new ToolCapabilities(
+ read_tool_capabilities(L, -1));
}
- lua_pop(L, 1);
- // If name is "" (hand), ensure there are ToolDiggingProperties
+ // If name is "" (hand), ensure there are ToolCapabilities
// because it will be looked up there whenever any other item has
- // no ToolDiggingProperties
- if(def.name == "" && def.tool_digging_properties == NULL){
- def.tool_digging_properties = new ToolDiggingProperties();
+ // no ToolCapabilities
+ if(def.name == "" && def.tool_capabilities == NULL){
+ def.tool_capabilities = new ToolCapabilities();
}
+ lua_getfield(L, index, "groups");
+ read_groups(L, -1, def.groups);
+ lua_pop(L, 1);
+
return def;
}
index = lua_gettop(L) + 1 + index;
ContentFeatures f;
+ /* Name */
getstringfield(L, index, "name", f.name);
+ /* Groups */
+ lua_getfield(L, index, "groups");
+ read_groups(L, -1, f.groups);
+ lua_pop(L, 1);
+
/* Visual definition */
f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype", es_DrawType,
f.param_type = (ContentParamType)getenumfield(L, index, "paramtype",
es_ContentParamType, CPT_NONE);
+ f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2",
+ es_ContentParamType2, CPT2_NONE);
+
+ // Warn about some deprecated fields
+ warn_if_field_exists(L, index, "wall_mounted",
+ "deprecated: use paramtype2 = 'wallmounted'");
+ warn_if_field_exists(L, index, "light_propagates",
+ "deprecated: determined from paramtype");
+ warn_if_field_exists(L, index, "dug_item",
+ "deprecated: use 'drop' field");
+ warn_if_field_exists(L, index, "extra_dug_item",
+ "deprecated: use 'drop' field");
+ warn_if_field_exists(L, index, "extra_dug_item_rarity",
+ "deprecated: use 'drop' field");
// True for all ground-like things like stone and mud, false for eg. trees
getboolfield(L, index, "is_ground_content", f.is_ground_content);
f.light_propagates = (f.param_type == CPT_LIGHT);
- warn_if_field_exists(L, index, "light_propagates",
- "deprecated: determined from paramtype");
getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates);
// This is used for collision detection.
// Also for general solidness queries.
getboolfield(L, index, "climbable", f.climbable);
// Player can build on these
getboolfield(L, index, "buildable_to", f.buildable_to);
- // If true, param2 is set to direction when placed. Used for torches.
- // NOTE: the direction format is quite inefficient and should be changed
- getboolfield(L, index, "wall_mounted", f.wall_mounted);
- // Inventory item string as which the node appears in inventory when dug.
- // Mineral overrides this.
- getstringfield(L, index, "dug_item", f.dug_item);
- // Extra dug item and its rarity
- getstringfield(L, index, "extra_dug_item", f.extra_dug_item);
- // Usual get interval for extra dug item
- getintfield(L, index, "extra_dug_item_rarity", f.extra_dug_item_rarity);
// Metadata name of node (eg. "furnace")
getstringfield(L, index, "metadata_name", f.metadata_name);
// Whether the node is non-liquid, source liquid or flowing liquid
}
lua_pop(L, 1);
- lua_getfield(L, index, "material");
+ // Set to true if paramtype used to be 'facedir_simple'
+ getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple);
+ // Set to true if wall_mounted used to be set to true
+ getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted);
+
+ // Sound table
+ lua_getfield(L, index, "sounds");
if(lua_istable(L, -1)){
- f.material.diggability = (Diggability)getenumfield(L, -1, "diggability",
- es_Diggability, DIGGABLE_NORMAL);
-
- getfloatfield(L, -1, "constant_time", f.material.constant_time);
- getfloatfield(L, -1, "weight", f.material.weight);
- getfloatfield(L, -1, "crackiness", f.material.crackiness);
- getfloatfield(L, -1, "crumbliness", f.material.crumbliness);
- getfloatfield(L, -1, "cuttability", f.material.cuttability);
- getfloatfield(L, -1, "flammability", f.material.flammability);
+ lua_getfield(L, -1, "footstep");
+ read_soundspec(L, -1, f.sound_footstep);
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "dig");
+ read_soundspec(L, -1, f.sound_dig);
+ lua_pop(L, 1);
+ lua_getfield(L, -1, "dug");
+ read_soundspec(L, -1, f.sound_dug);
+ lua_pop(L, 1);
}
lua_pop(L, 1);
return 1;
}
- // get_tool_digging_properties(self) -> table
+ // get_tool_capabilities(self) -> table
// Returns the effective tool digging properties.
// Returns those of the hand ("") if this item has none associated.
- static int l_get_tool_digging_properties(lua_State *L)
+ static int l_get_tool_capabilities(lua_State *L)
{
LuaItemStack *o = checkobject(L, 1);
ItemStack &item = o->m_stack;
- const ToolDiggingProperties &prop =
- item.getToolDiggingProperties(get_server(L)->idef());
- push_tool_digging_properties(L, prop);
+ const ToolCapabilities &prop =
+ item.getToolCapabilities(get_server(L)->idef());
+ push_tool_capabilities(L, prop);
return 1;
}
method(LuaItemStack, get_free_space),
method(LuaItemStack, is_known),
method(LuaItemStack, get_definition),
- method(LuaItemStack, get_tool_digging_properties),
+ method(LuaItemStack, get_tool_capabilities),
method(LuaItemStack, add_wear),
method(LuaItemStack, add_item),
method(LuaItemStack, item_fits),
return 1;
}
+ // set_owner(self, string)
+ static int l_set_owner(lua_State *L)
+ {
+ NodeMetaRef *ref = checkobject(L, 1);
+ NodeMetadata *meta = getmeta(ref);
+ if(meta == NULL) return 0;
+ // Do it
+ std::string owner = luaL_checkstring(L, 2);
+ meta->setOwner(owner);
+ reportMetadataChange(ref);
+ return 1;
+ }
+
+ // get_allow_removal(self)
+ static int l_get_allow_removal(lua_State *L)
+ {
+ NodeMetaRef *ref = checkobject(L, 1);
+ NodeMetadata *meta = getmeta(ref);
+ if(meta == NULL){
+ lua_pushboolean(L, true);
+ return 1;
+ }
+ // Do it
+ lua_pushboolean(L, !meta->nodeRemovalDisabled());
+ return 1;
+ }
+
/* IGenericNodeMetadata interface */
// set_infotext(self, text)
method(NodeMetaRef, set_text),
method(NodeMetaRef, get_text),
method(NodeMetaRef, get_owner),
+ method(NodeMetaRef, set_owner),
+ method(NodeMetaRef, get_allow_removal),
method(NodeMetaRef, set_infotext),
method(NodeMetaRef, get_inventory),
method(NodeMetaRef, set_inventory_draw_spec),
static const char className[];
static const luaL_reg methods[];
-
+public:
static ObjectRef *checkobject(lua_State *L, int narg)
{
luaL_checktype(L, narg, LUA_TUSERDATA);
ServerActiveObject *co = ref->m_object;
return co;
}
-
+private:
static LuaEntitySAO* getluaobject(ObjectRef *ref)
{
ServerActiveObject *obj = getobject(ref);
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *co = getobject(ref);
if(co == NULL) return 0;
- infostream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
+ verbosestream<<"ObjectRef::l_remove(): id="<<co->getId()<<std::endl;
co->m_removed = true;
return 0;
}
return 0;
}
- // punch(self, puncher); puncher = an another ObjectRef
+ // punch(self, puncher, tool_capabilities, direction, time_from_last_punch)
static int l_punch(lua_State *L)
{
ObjectRef *ref = checkobject(L, 1);
- ObjectRef *ref2 = checkobject(L, 2);
+ ObjectRef *puncher_ref = checkobject(L, 2);
ServerActiveObject *co = getobject(ref);
- ServerActiveObject *co2 = getobject(ref2);
+ ServerActiveObject *puncher = getobject(puncher_ref);
if(co == NULL) return 0;
- if(co2 == NULL) return 0;
+ if(puncher == NULL) return 0;
+ ToolCapabilities toolcap = read_tool_capabilities(L, 3);
+ v3f dir = read_v3f(L, 4);
+ float time_from_last_punch = 1000000;
+ if(lua_isnumber(L, 5))
+ time_from_last_punch = lua_tonumber(L, 5);
// Do it
- co->punch(co2);
+ puncher->punch(dir, &toolcap, puncher, time_from_last_punch);
return 0;
}
ServerActiveObject *co = getobject(ref);
if(co == NULL) return 0;
int hp = lua_tonumber(L, 2);
- infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
- <<" hp="<<hp<<std::endl;
+ /*infostream<<"ObjectRef::l_set_hp(): id="<<co->getId()
+ <<" hp="<<hp<<std::endl;*/
// Do it
co->setHP(hp);
// Return
ServerActiveObject *co = getobject(ref);
if(co == NULL) return 0;
int hp = co->getHP();
- infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
- <<" hp="<<hp<<std::endl;
+ /*infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
+ <<" hp="<<hp<<std::endl;*/
// Return
lua_pushnumber(L, hp);
return 1;
return 0;
}
+ // set_armor_groups(self, groups)
+ static int l_set_armor_groups(lua_State *L)
+ {
+ ObjectRef *ref = checkobject(L, 1);
+ LuaEntitySAO *co = getluaobject(ref);
+ if(co == NULL) return 0;
+ // Do it
+ ItemGroupList groups;
+ read_groups(L, 2, groups);
+ co->setArmorGroups(groups);
+ return 0;
+ }
+
// DEPRECATED
// get_entity_name(self)
static int l_get_entity_name(lua_State *L)
method(ObjectRef, getyaw),
method(ObjectRef, settexturemod),
method(ObjectRef, setsprite),
+ method(ObjectRef, set_armor_groups),
method(ObjectRef, get_entity_name),
method(ObjectRef, get_luaentity),
// Player-only
if(item.empty() || !item.isKnown(get_server(L)->idef()))
return 0;
// Do it
- ServerActiveObject *obj = new ItemSAO(env, pos, item.getItemString());
+ ServerActiveObject *obj = createItemSAO(env, pos, item.getItemString());
int objectid = env->addActiveObject(obj);
// If failed to add, return nothing (reads as nil)
if(objectid == 0)
// pos = {x=num, y=num, z=num}
static int l_add_rat(lua_State *L)
{
- infostream<<"EnvRef::l_add_rat()"<<std::endl;
- EnvRef *o = checkobject(L, 1);
- ServerEnvironment *env = o->m_env;
- if(env == NULL) return 0;
- // pos
- v3f pos = checkFloatPos(L, 2);
- // Do it
- ServerActiveObject *obj = new RatSAO(env, pos);
- env->addActiveObject(obj);
+ infostream<<"EnvRef::l_add_rat(): C++ mobs have been removed."
+ <<" Doing nothing."<<std::endl;
return 0;
}
// pos = {x=num, y=num, z=num}
static int l_add_firefly(lua_State *L)
{
- infostream<<"EnvRef::l_add_firefly()"<<std::endl;
- EnvRef *o = checkobject(L, 1);
- ServerEnvironment *env = o->m_env;
- if(env == NULL) return 0;
- // pos
- v3f pos = checkFloatPos(L, 2);
- // Do it
- ServerActiveObject *obj = new FireflySAO(env, pos);
- env->addActiveObject(obj);
+ infostream<<"EnvRef::l_add_firefly(): C++ mobs have been removed."
+ <<" Doing nothing."<<std::endl;
return 0;
}
return 1;
}
+ // EnvRef:set_timeofday(val)
+ // val = 0...1
+ static int l_set_timeofday(lua_State *L)
+ {
+ EnvRef *o = checkobject(L, 1);
+ ServerEnvironment *env = o->m_env;
+ if(env == NULL) return 0;
+ // Do it
+ float timeofday_f = luaL_checknumber(L, 2);
+ assert(timeofday_f >= 0.0 && timeofday_f <= 1.0);
+ int timeofday_mh = (int)(timeofday_f * 24000.0);
+ // This should be set directly in the environment but currently
+ // such changes aren't immediately sent to the clients, so call
+ // the server instead.
+ //env->setTimeOfDay(timeofday_mh);
+ get_server(L)->setTimeOfDay(timeofday_mh);
+ return 0;
+ }
+
+ // EnvRef:get_timeofday() -> 0...1
+ static int l_get_timeofday(lua_State *L)
+ {
+ EnvRef *o = checkobject(L, 1);
+ ServerEnvironment *env = o->m_env;
+ if(env == NULL) return 0;
+ // Do it
+ int timeofday_mh = env->getTimeOfDay();
+ float timeofday_f = (float)timeofday_mh / 24000.0;
+ lua_pushnumber(L, timeofday_f);
+ return 1;
+ }
+
static int gc_object(lua_State *L) {
EnvRef *o = *(EnvRef **)(lua_touserdata(L, 1));
delete o;
EnvRef(ServerEnvironment *env):
m_env(env)
{
- infostream<<"EnvRef created"<<std::endl;
+ //infostream<<"EnvRef created"<<std::endl;
}
~EnvRef()
{
- infostream<<"EnvRef destructing"<<std::endl;
+ //infostream<<"EnvRef destructing"<<std::endl;
}
// Creates an EnvRef and leaves it on top of stack
method(EnvRef, get_meta),
method(EnvRef, get_player_by_name),
method(EnvRef, get_objects_inside_radius),
+ method(EnvRef, set_timeofday),
+ method(EnvRef, get_timeofday),
{0,0}
};
-/*
- Global functions
-*/
-
class LuaABM : public ActiveBlockModifier
{
private:
}
};
+/*
+ ServerSoundParams
+*/
+
+static void read_server_sound_params(lua_State *L, int index,
+ ServerSoundParams ¶ms)
+{
+ if(index < 0)
+ index = lua_gettop(L) + 1 + index;
+ // Clear
+ params = ServerSoundParams();
+ if(lua_istable(L, index)){
+ getfloatfield(L, index, "gain", params.gain);
+ getstringfield(L, index, "to_player", params.to_player);
+ lua_getfield(L, index, "pos");
+ if(!lua_isnil(L, -1)){
+ v3f p = read_v3f(L, -1)*BS;
+ params.pos = p;
+ params.type = ServerSoundParams::SSP_POSITIONAL;
+ }
+ lua_pop(L, 1);
+ lua_getfield(L, index, "object");
+ if(!lua_isnil(L, -1)){
+ ObjectRef *ref = ObjectRef::checkobject(L, -1);
+ ServerActiveObject *sao = ObjectRef::getobject(ref);
+ if(sao){
+ params.object = sao->getId();
+ params.type = ServerSoundParams::SSP_OBJECT;
+ }
+ }
+ lua_pop(L, 1);
+ params.max_hear_distance = BS*getfloatfield_default(L, index,
+ "max_hear_distance", params.max_hear_distance/BS);
+ getboolfield(L, index, "loop", params.loop);
+ }
+}
+
+/*
+ Global functions
+*/
+
// debug(text)
// Writes a line to dstream
static int l_debug(lua_State *L)
lua_getfield(L, table, "name");
if(lua_isstring(L, -1)){
std::string name = lua_tostring(L, -1);
- infostream<<"register_item_raw: "<<name<<std::endl;
+ verbosestream<<"register_item_raw: "<<name<<std::endl;
} else {
throw LuaError(L, "register_item_raw: name is not defined or not a string");
}
// Do it
lua_newtable(L);
int table = lua_gettop(L);
- u64 privs_i = server->getPlayerAuthPrivs(name);
- // Special case for the "name" setting (local player / server owner)
- if(name == g_settings->get("name"))
- privs_i = PRIV_ALL;
+ u64 privs_i = server->getPlayerEffectivePrivs(name);
std::set<std::string> privs_s = privsToSet(privs_i);
for(std::set<std::string>::const_iterator
i = privs_s.begin(); i != privs_s.end(); i++){
return 1;
}
+// get_dig_params(groups, tool_capabilities[, time_from_last_punch])
+static int l_get_dig_params(lua_State *L)
+{
+ std::map<std::string, int> groups;
+ read_groups(L, 1, groups);
+ ToolCapabilities tp = read_tool_capabilities(L, 2);
+ if(lua_isnoneornil(L, 3))
+ push_dig_params(L, getDigParams(groups, &tp));
+ else
+ push_dig_params(L, getDigParams(groups, &tp,
+ luaL_checknumber(L, 3)));
+ return 1;
+}
+
+// get_hit_params(groups, tool_capabilities[, time_from_last_punch])
+static int l_get_hit_params(lua_State *L)
+{
+ std::map<std::string, int> groups;
+ read_groups(L, 1, groups);
+ ToolCapabilities tp = read_tool_capabilities(L, 2);
+ if(lua_isnoneornil(L, 3))
+ push_hit_params(L, getHitParams(groups, &tp));
+ else
+ push_hit_params(L, getHitParams(groups, &tp,
+ luaL_checknumber(L, 3)));
+ return 1;
+}
+
// get_current_modname()
static int l_get_current_modname(lua_State *L)
{
return 1;
}
+// get_worldpath()
+static int l_get_worldpath(lua_State *L)
+{
+ std::string worldpath = get_server(L)->getWorldPath();
+ lua_pushstring(L, worldpath.c_str());
+ return 1;
+}
+
+// sound_play(spec, parameters)
+static int l_sound_play(lua_State *L)
+{
+ SimpleSoundSpec spec;
+ read_soundspec(L, 1, spec);
+ ServerSoundParams params;
+ read_server_sound_params(L, 2, params);
+ s32 handle = get_server(L)->playSound(spec, params);
+ lua_pushinteger(L, handle);
+ return 1;
+}
+
+// sound_stop(handle)
+static int l_sound_stop(lua_State *L)
+{
+ int handle = luaL_checkinteger(L, 1);
+ get_server(L)->stopSound(handle);
+ return 0;
+}
+
static const struct luaL_Reg minetest_f [] = {
{"debug", l_debug},
{"log", l_log},
{"chat_send_player", l_chat_send_player},
{"get_player_privs", l_get_player_privs},
{"get_inventory", l_get_inventory},
+ {"get_dig_params", l_get_dig_params},
+ {"get_hit_params", l_get_hit_params},
{"get_current_modname", l_get_current_modname},
{"get_modpath", l_get_modpath},
+ {"get_worldpath", l_get_worldpath},
+ {"sound_play", l_sound_play},
+ {"sound_stop", l_sound_stop},
{NULL, NULL}
};
{
realitycheck(L);
assert(lua_checkstack(L, 20));
- infostream<<"scriptapi_export"<<std::endl;
+ verbosestream<<"scriptapi_export()"<<std::endl;
StackUnroller stack_unroller(L);
// Store server as light userdata in registry
{
realitycheck(L);
assert(lua_checkstack(L, 20));
- infostream<<"scriptapi_add_environment"<<std::endl;
+ verbosestream<<"scriptapi_add_environment"<<std::endl;
StackUnroller stack_unroller(L);
// Create EnvRef on stack
assert(lua_checkstack(L, 20));
StackUnroller stack_unroller(L);
+ dstream<<"player: "<<player<<" id: "<<player->getId()<<std::endl;
+
bool positioning_handled_by_some = false;
// Get minetest.registered_on_respawnplayers
}
/*
- item callbacks
+ item callbacks and node callbacks
*/
// Retrieves minetest.registered_items[name][callbackname]
return true;
}
-/*
- environment
-*/
-
-void scriptapi_environment_step(lua_State *L, float dtime)
+bool scriptapi_node_on_punch(lua_State *L, v3s16 pos, MapNode node,
+ ServerActiveObject *puncher)
{
realitycheck(L);
assert(lua_checkstack(L, 20));
- //infostream<<"scriptapi_environment_step"<<std::endl;
StackUnroller stack_unroller(L);
- // Get minetest.registered_globalsteps
- lua_getglobal(L, "minetest");
- lua_getfield(L, -1, "registered_globalsteps");
- luaL_checktype(L, -1, LUA_TTABLE);
- int table = lua_gettop(L);
- // Foreach
- lua_pushnil(L);
- while(lua_next(L, table) != 0){
- // key at index -2 and value at index -1
- luaL_checktype(L, -1, LUA_TFUNCTION);
- // Call function
- lua_pushnumber(L, dtime);
- if(lua_pcall(L, 1, 0, 0))
- script_error(L, "error: %s", lua_tostring(L, -1));
- // value removed, keep key for next iteration
- }
-}
+ INodeDefManager *ndef = get_server(L)->ndef();
-void scriptapi_environment_on_placenode(lua_State *L, v3s16 p, MapNode newnode,
- ServerActiveObject *placer)
-{
- realitycheck(L);
- assert(lua_checkstack(L, 20));
- //infostream<<"scriptapi_environment_on_placenode"<<std::endl;
- StackUnroller stack_unroller(L);
+ // Push callback function on stack
+ if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_punch"))
+ return false;
- // Get the writable node definition manager from the server
- IWritableNodeDefManager *ndef =
- get_server(L)->getWritableNodeDefManager();
-
- // Get minetest.registered_on_placenodes
- lua_getglobal(L, "minetest");
- lua_getfield(L, -1, "registered_on_placenodes");
- luaL_checktype(L, -1, LUA_TTABLE);
- int table = lua_gettop(L);
- // Foreach
- lua_pushnil(L);
- while(lua_next(L, table) != 0){
- // key at index -2 and value at index -1
- luaL_checktype(L, -1, LUA_TFUNCTION);
- // Call function
- push_v3s16(L, p);
- pushnode(L, newnode, ndef);
- objectref_get_or_create(L, placer);
- if(lua_pcall(L, 3, 0, 0))
- script_error(L, "error: %s", lua_tostring(L, -1));
- // value removed, keep key for next iteration
- }
+ // Call function
+ push_v3s16(L, pos);
+ pushnode(L, node, ndef);
+ objectref_get_or_create(L, puncher);
+ if(lua_pcall(L, 3, 0, 0))
+ script_error(L, "error: %s", lua_tostring(L, -1));
+ return true;
}
-void scriptapi_environment_on_dignode(lua_State *L, v3s16 p, MapNode oldnode,
+bool scriptapi_node_on_dig(lua_State *L, v3s16 pos, MapNode node,
ServerActiveObject *digger)
{
realitycheck(L);
assert(lua_checkstack(L, 20));
- //infostream<<"scriptapi_environment_on_dignode"<<std::endl;
StackUnroller stack_unroller(L);
- // Get the writable node definition manager from the server
- IWritableNodeDefManager *ndef =
- get_server(L)->getWritableNodeDefManager();
-
- // Get minetest.registered_on_dignodes
- lua_getglobal(L, "minetest");
- lua_getfield(L, -1, "registered_on_dignodes");
- luaL_checktype(L, -1, LUA_TTABLE);
- int table = lua_gettop(L);
- // Foreach
- lua_pushnil(L);
- while(lua_next(L, table) != 0){
- // key at index -2 and value at index -1
- luaL_checktype(L, -1, LUA_TFUNCTION);
- // Call function
- push_v3s16(L, p);
- pushnode(L, oldnode, ndef);
- objectref_get_or_create(L, digger);
- if(lua_pcall(L, 3, 0, 0))
- script_error(L, "error: %s", lua_tostring(L, -1));
- // value removed, keep key for next iteration
- }
+ INodeDefManager *ndef = get_server(L)->ndef();
+
+ // Push callback function on stack
+ if(!get_item_callback(L, ndef->get(node).name.c_str(), "on_dig"))
+ return false;
+
+ // Call function
+ push_v3s16(L, pos);
+ pushnode(L, node, ndef);
+ objectref_get_or_create(L, digger);
+ if(lua_pcall(L, 3, 0, 0))
+ script_error(L, "error: %s", lua_tostring(L, -1));
+ return true;
}
-void scriptapi_environment_on_punchnode(lua_State *L, v3s16 p, MapNode node,
- ServerActiveObject *puncher)
+/*
+ environment
+*/
+
+void scriptapi_environment_step(lua_State *L, float dtime)
{
realitycheck(L);
assert(lua_checkstack(L, 20));
- //infostream<<"scriptapi_environment_on_punchnode"<<std::endl;
+ //infostream<<"scriptapi_environment_step"<<std::endl;
StackUnroller stack_unroller(L);
- // Get the writable node definition manager from the server
- IWritableNodeDefManager *ndef =
- get_server(L)->getWritableNodeDefManager();
-
- // Get minetest.registered_on_punchnodes
+ // Get minetest.registered_globalsteps
lua_getglobal(L, "minetest");
- lua_getfield(L, -1, "registered_on_punchnodes");
+ lua_getfield(L, -1, "registered_globalsteps");
luaL_checktype(L, -1, LUA_TTABLE);
int table = lua_gettop(L);
// Foreach
// key at index -2 and value at index -1
luaL_checktype(L, -1, LUA_TFUNCTION);
// Call function
- push_v3s16(L, p);
- pushnode(L, node, ndef);
- objectref_get_or_create(L, puncher);
- if(lua_pcall(L, 3, 0, 0))
+ lua_pushnumber(L, dtime);
+ if(lua_pcall(L, 1, 0, 0))
script_error(L, "error: %s", lua_tostring(L, -1));
// value removed, keep key for next iteration
}
luaentity
*/
-bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name,
- const std::string &staticdata)
+bool scriptapi_luaentity_add(lua_State *L, u16 id, const char *name)
{
realitycheck(L);
assert(lua_checkstack(L, 20));
- infostream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
+ verbosestream<<"scriptapi_luaentity_add: id="<<id<<" name=\""
<<name<<"\""<<std::endl;
StackUnroller stack_unroller(L);
lua_pushvalue(L, object); // Copy object to top of stack
lua_settable(L, -3);
+ return true;
+}
+
+void scriptapi_luaentity_activate(lua_State *L, u16 id,
+ const std::string &staticdata)
+{
+ realitycheck(L);
+ assert(lua_checkstack(L, 20));
+ verbosestream<<"scriptapi_luaentity_activate: id="<<id<<std::endl;
+ StackUnroller stack_unroller(L);
+
+ // Get minetest.luaentities[id]
+ luaentity_get(L, id);
+ int object = lua_gettop(L);
+
// Get on_activate function
lua_pushvalue(L, object);
lua_getfield(L, -1, "on_activate");
lua_pushlstring(L, staticdata.c_str(), staticdata.size());
// Call with 2 arguments, 0 results
if(lua_pcall(L, 2, 0, 0))
- script_error(L, "error running function %s:on_activate: %s\n",
- name, lua_tostring(L, -1));
+ script_error(L, "error running function on_activate: %s\n",
+ lua_tostring(L, -1));
}
-
- return true;
}
void scriptapi_luaentity_rm(lua_State *L, u16 id)
{
realitycheck(L);
assert(lua_checkstack(L, 20));
- infostream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
+ verbosestream<<"scriptapi_luaentity_rm: id="<<id<<std::endl;
// Get minetest.luaentities table
lua_getglobal(L, "minetest");
{
realitycheck(L);
assert(lua_checkstack(L, 20));
- infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
+ //infostream<<"scriptapi_luaentity_get_staticdata: id="<<id<<std::endl;
StackUnroller stack_unroller(L);
// Get minetest.luaentities[id]
{
realitycheck(L);
assert(lua_checkstack(L, 20));
- infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
+ //infostream<<"scriptapi_luaentity_get_properties: id="<<id<<std::endl;
StackUnroller stack_unroller(L);
// Get minetest.luaentities[id]
/* Read stuff */
+ prop->hp_max = getintfield_default(L, -1, "hp_max", 10);
+
getboolfield(L, -1, "physical", prop->physical);
getfloatfield(L, -1, "weight", prop->weight);
script_error(L, "error running function 'on_step': %s\n", lua_tostring(L, -1));
}
-// Calls entity:on_punch(ObjectRef puncher, time_from_last_punch)
+// Calls entity:on_punch(ObjectRef puncher, time_from_last_punch,
+// tool_capabilities, direction)
void scriptapi_luaentity_punch(lua_State *L, u16 id,
- ServerActiveObject *puncher, float time_from_last_punch)
+ ServerActiveObject *puncher, float time_from_last_punch,
+ const ToolCapabilities *toolcap, v3f dir)
{
realitycheck(L);
assert(lua_checkstack(L, 20));
lua_pushvalue(L, object); // self
objectref_get_or_create(L, puncher); // Clicker reference
lua_pushnumber(L, time_from_last_punch);
- // Call with 2 arguments, 0 results
- if(lua_pcall(L, 3, 0, 0))
+ push_tool_capabilities(L, *toolcap);
+ push_v3f(L, dir);
+ // Call with 5 arguments, 0 results
+ if(lua_pcall(L, 5, 0, 0))
script_error(L, "error running function 'on_punch': %s\n", lua_tostring(L, -1));
}