aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerttu Ahola <celeron55@gmail.com>2012-06-05 23:09:18 +0300
committerPerttu Ahola <celeron55@gmail.com>2012-06-05 23:10:07 +0300
commitc3658e7c797cbf5b9d04a6d950505d37dcdd422b (patch)
treeb8c50c53fbadcd076d6e1ab5c2561455911859c2
parentb0f81c3253cb73c47d6e46a9ec75800a3679897c (diff)
downloadminetest-c3658e7c797cbf5b9d04a6d950505d37dcdd422b.tar.gz
minetest-c3658e7c797cbf5b9d04a6d950505d37dcdd422b.tar.bz2
minetest-c3658e7c797cbf5b9d04a6d950505d37dcdd422b.zip
place_node, dig_node and punch_node; an in-game tester tool; remove old code
-rw-r--r--builtin/item.lua10
-rw-r--r--doc/lua_api.txt12
-rw-r--r--games/minimal/mods/experimental/init.lua280
-rw-r--r--games/minimal/mods/give_initial_stuff/init.lua1
-rw-r--r--src/scriptapi.cpp104
5 files changed, 166 insertions, 241 deletions
diff --git a/builtin/item.lua b/builtin/item.lua
index 3d545eece..6d75fbf70 100644
--- a/builtin/item.lua
+++ b/builtin/item.lua
@@ -250,10 +250,12 @@ function minetest.node_dig(pos, node, digger)
wielded:add_wear(dp.wear)
digger:set_wielded_item(wielded)
- -- Add dropped items
- local _, dropped_item
- for _, dropped_item in ipairs(drops) do
- digger:get_inventory():add_item("main", dropped_item)
+ -- Add dropped items to object's inventory
+ if digger:get_inventory() then
+ local _, dropped_item
+ for _, dropped_item in ipairs(drops) do
+ digger:get_inventory():add_item("main", dropped_item)
+ end
end
end
diff --git a/doc/lua_api.txt b/doc/lua_api.txt
index 8b2b81c75..5e0f2f118 100644
--- a/doc/lua_api.txt
+++ b/doc/lua_api.txt
@@ -842,13 +842,23 @@ EnvRef: basically ServerEnvironment and ServerMap combined.
methods:
- set_node(pos, node)
- add_node(pos, node): alias set_node(pos, node)
-- remove_node(pos): equivalent to set_node(pos, "air")
+ ^ Set node at position (node = {name="foo", param1=0, param2=0})
+- remove_node(pos)
+ ^ Equivalent to set_node(pos, "air")
- get_node(pos)
^ Returns {name="ignore", ...} for unloaded area
- get_node_or_nil(pos)
^ Returns nil for unloaded area
- get_node_light(pos, timeofday) -> 0...15 or nil
^ timeofday: nil = current time, 0 = night, 0.5 = day
+
+- place_node(pos, node)
+ ^ Place node with the same effects that a player would cause
+- dig_node(pos)
+ ^ Dig node with the same effects that a player would cause
+- punch_node(pos)
+ ^ Punch node with the same effects that a player would cause
+
- add_entity(pos, name): Spawn Lua-defined entity at position
^ Returns ObjectRef, or nil if failed
- add_item(pos, itemstring): Spawn item
diff --git a/games/minimal/mods/experimental/init.lua b/games/minimal/mods/experimental/init.lua
index 8f92c13ee..ea11e6d3b 100644
--- a/games/minimal/mods/experimental/init.lua
+++ b/games/minimal/mods/experimental/init.lua
@@ -6,6 +6,11 @@
experimental = {}
+function experimental.print_to_everything(msg)
+ minetest.log("action", msg)
+ minetest.chat_send_all(msg)
+end
+
--[[
experimental.player_visual_index = 0
function switch_player_visual()
@@ -97,235 +102,10 @@ function on_step(dtime)
end
minetest.register_globalstep(on_step)
--- An example furnace-thing implemented in Lua
-
---[[
-minetest.register_node("experimental:luafurnace", {
- tile_images = {"default_lava.png", "default_furnace_side.png",
- "default_furnace_side.png", "default_furnace_side.png",
- "default_furnace_side.png", "default_furnace_front.png"},
- --inventory_image = "furnace_front.png",
- inventory_image = minetest.inventorycube("default_furnace_front.png"),
- paramtype = "facedir_simple",
- metadata_name = "generic",
- material = minetest.digprop_stonelike(3.0),
-})
-
-minetest.register_on_placenode(function(pos, newnode, placer)
- if newnode.name == "experimental:luafurnace" then
- local meta = minetest.env:get_meta(pos)
- meta:inventory_set_list("fuel", {""})
- meta:inventory_set_list("src", {""})
- meta:inventory_set_list("dst", {"","","",""})
- meta:set_inventory_draw_spec(
- "invsize[8,9;]"
- .."list[current_name;fuel;2,3;1,1;]"
- .."list[current_name;src;2,1;1,1;]"
- .."list[current_name;dst;5,1;2,2;]"
- .."list[current_player;main;0,5;8,4;]"
- )
-
- local total_cooked = 0;
- meta:set_string("total_cooked", total_cooked)
- meta:set_infotext("Lua Furnace: total cooked: "..total_cooked)
- end
-end)
-
-minetest.register_abm({
- nodenames = {"experimental:luafurnace"},
- interval = 1.0,
- chance = 1,
- action = function(pos, node, active_object_count, active_object_count_wider)
- local meta = minetest.env:get_meta(pos)
- for i, name in ipairs({
- "fuel_totaltime",
- "fuel_time",
- "src_totaltime",
- "src_time"
- }) do
- if not meta:get_string(name) then
- meta:set_string(name, 0)
- end
- end
-
- local inv = meta:get_inventory()
-
- local fuelitem = inv:get_stack("fuel", 1):peek_item()
- local srcitem = inv:get_stack("src", 1):peek_item()
- --print("fuelitem="..dump(fuelitem))
- --print("srcitem="..dump(srcitem))
-
- local was_active = false
-
- local src_cooktime = -1
- local result_stackstring = nil
-
- if srcitem then
- local prop = get_item_definition(srcitem)
- if prop and prop.cookresult_itemstring ~= "" then
- result_stackstring = prop.cookresult_itemstring
- src_cooktime = prop.furnace_cooktime or 3
- end
- end
-
- print("src_cooktime="..dump(src_cooktime))
- print("result_stackstring="..dump(result_stackstring))
-
- if tonumber(meta:get_string("fuel_time")) < tonumber(meta:get_string("fuel_totaltime")) then
- was_active = true
- meta:set_string("fuel_time", tonumber(meta:get_string("fuel_time")) + 1)
- meta:set_string("src_time", tonumber(meta:get_string("src_time")) + 1)
- --print("result_stackstring="..dump(result_stackstring))
- --print('tonumber(meta:get_string("src_time"))='..dump(tonumber(meta:get_string("src_time"))))
- --print("src_cooktime="..dump(src_cooktime))
- if result_stackstring and tonumber(meta:get_string("src_time")) >= src_cooktime and src_cooktime >= 0 then
- -- Put result in "dst" list
- success = inv:autoinsert_stackstring("dst", result_stackstring)
- if not success then
- print("Could not autoinsert '"..result_stackstring.."'")
- end
- -- If succeeded, take stuff from "src" list
- if success then
- srcstack = inv:get_stack("src", 1)
- srcstack:take_item()
- inv:set_stack("src", 1, srcstack)
- end
- meta:set_string("src_time", 0)
- end
- end
-
- if tonumber(meta:get_string("fuel_time")) < tonumber(meta:get_string("fuel_totaltime")) then
- meta:set_infotext("Furnace active: "..(tonumber(meta:get_string("fuel_time"))/tonumber(meta:get_string("fuel_totaltime"))*100).."%")
- return
- end
-
- local srcitem = inv:get_stack("src", 1):peek_item()
-
- local src_cooktime = 0
- local result_stackstring = nil
-
- if srcitem then
- local prop = get_item_definition(srcitem)
- if prop and prop.cookresult_itemstring ~= "" then
- result_stackstring = prop.cookresult_itemstring
- src_cooktime = prop.furnace_cooktime or 3
- end
- end
-
- local fuelitem = inv:get_stack("fuel", 1):peek_item()
-
- if not result_stackstring or not fuelitem then
- if was_active then
- meta:set_infotext("Furnace is empty")
- end
- return
- end
-
- local burntime = -1
- if fuelitem then
- local prop = get_item_definition(fuelitem)
- if prop then
- burntime = prop.furnace_burntime or -1
- end
- end
-
- if burntime <= 0 then
- meta:set_infotext("Furnace out of fuel")
- return
- end
-
- meta:set_string("fuel_totaltime", burntime)
- meta:set_string("fuel_time", 0)
-
- local stack = inv:get_stack("fuel", 1)
- stack:take_item()
- inv:set_stack("fuel", 1, stack)
- end,
-})
-minetest.register_abm({
- nodenames = {"experimental:luafurnace"},
- interval = 1.0,
- chance = 1,
- action = function(pos, node, active_object_count, active_object_count_wider)
- local meta = minetest.env:get_meta(pos)
- local fuellist = meta:inventory_get_list("fuel")
- local srclist = meta:inventory_get_list("src")
- local dstlist = meta:inventory_get_list("dst")
- if fuellist == nil or srclist == nil or dstlist == nil then
- return
- end
- _, srcitem = stackstring_take_item(srclist[1])
- _, fuelitem = stackstring_take_item(fuellist[1])
- if not srcitem or not fuelitem then return end
- if fuelitem.type == "node" then
- local prop = minetest.registered_nodes[fuelitem.name]
- if prop == nil then return end
- if prop.furnace_burntime < 0 then return end
- else
- return
- end
- local resultstack = nil
- if srcitem.type == "node" then
- local prop = minetest.registered_nodes[srcitem.name]
- if prop == nil then return end
- if prop.cookresult_item == "" then return end
- resultstack = prop.cookresult_item
- else
- return
- end
-
- if resultstack == nil then
- return
- end
-
- dstlist[1], success = stackstring_put_stackstring(dstlist[1], resultstack)
- if not success then
- return
- end
-
- fuellist[1], _ = stackstring_take_item(fuellist[1])
- srclist[1], _ = stackstring_take_item(srclist[1])
-
- meta:inventory_set_list("fuel", fuellist)
- meta:inventory_set_list("src", srclist)
- meta:inventory_set_list("dst", dstlist)
-
- local total_cooked = meta:get_string("total_cooked")
- total_cooked = tonumber(total_cooked) + 1
- meta:set_string("total_cooked", total_cooked)
- meta:set_infotext("Lua Furnace: total cooked: "..total_cooked)
- end,
-})
-minetest.register_craft({
- output = 'node "experimental:luafurnace" 1',
- recipe = {
- {'node "default:cobble"', 'node "default:cobble"', 'node "default:cobble"'},
- {'node "default:cobble"', 'node "default:steel_ingot"', 'node "default:cobble"'},
- {'node "default:cobble"', 'node "default:cobble"', 'node "default:cobble"'},
- }
-})
---]]
-
--
-- Random stuff
--
---[[
-minetest.register_tool("experimental:horribletool", {
- image = "default_lava.png",
- basetime = 2.0
- dt_weight = 0.2
- dt_crackiness = 0.2
- dt_crumbliness = 0.2
- dt_cuttability = 0.2
- basedurability = 50
- dd_weight = -5
- dd_crackiness = -5
- dd_crumbliness = -5
- dd_cuttability = -5
-})
---]]
-
--
-- TNT (not functional)
--
@@ -662,6 +442,56 @@ minetest.register_abm({
end,
})--]]
+minetest.register_node("experimental:tester_node_1", {
+ description = "Tester Node 1",
+ tile_images = {"wieldhand.png"},
+ groups = {oddly_breakable_by_hand=2},
+ sounds = default.node_sound_wood_defaults(),
+
+ on_construct = function(pos)
+ experimental.print_to_everything("experimental:tester_node_1:on_construct("..minetest.pos_to_string(pos)..")")
+ local meta = minetest.env:get_meta(pos)
+ meta:set_string("mine", "test")
+ end,
+
+ after_place_node = function(pos, placer)
+ experimental.print_to_everything("experimental:tester_node_1:after_place_node("..minetest.pos_to_string(pos)..")")
+ local meta = minetest.env:get_meta(pos)
+ if meta:get_string("mine") == "test" then
+ experimental.print_to_everything("correct metadata found")
+ else
+ experimental.print_to_everything("incorrect metadata found")
+ end
+ end,
+
+ on_destruct = function(pos)
+ experimental.print_to_everything("experimental:tester_node_1:on_destruct("..minetest.pos_to_string(pos)..")")
+ end,
+
+ after_dig_node = function(pos, oldnode, oldmetadata, digger)
+ experimental.print_to_everything("experimental:tester_node_1:after_dig_node("..minetest.pos_to_string(pos)..")")
+ end,
+})
+
+minetest.register_craftitem("experimental:tester_tool_1", {
+ description = "Tester Tool 1",
+ inventory_image = "experimental_tester_tool_1.png",
+ on_use = function(itemstack, user, pointed_thing)
+ --print(dump(pointed_thing))
+ if pointed_thing.type == "node" then
+ if minetest.env:get_node(pointed_thing.under).name == "experimental:tester_node_1" then
+ local p = pointed_thing.under
+ minetest.log("action", "Tester tool used at "..minetest.pos_to_string(p))
+ minetest.env:dig_node(p)
+ else
+ local p = pointed_thing.above
+ minetest.log("action", "Tester tool used at "..minetest.pos_to_string(p))
+ minetest.env:place_node(p, {name="experimental:tester_node_1"})
+ end
+ end
+ end,
+})
+
minetest.log("experimental modname="..dump(minetest.get_current_modname()))
minetest.log("experimental modpath="..dump(minetest.get_modpath("experimental")))
minetest.log("experimental worldpath="..dump(minetest.get_worldpath()))
diff --git a/games/minimal/mods/give_initial_stuff/init.lua b/games/minimal/mods/give_initial_stuff/init.lua
index fef23c328..29b835c7d 100644
--- a/games/minimal/mods/give_initial_stuff/init.lua
+++ b/games/minimal/mods/give_initial_stuff/init.lua
@@ -11,5 +11,6 @@ minetest.register_on_newplayer(function(player)
player:get_inventory():add_item('main', 'default:pick_mese')
player:get_inventory():add_item('main', 'default:mese 99')
player:get_inventory():add_item('main', 'default:water_source 99')
+ player:get_inventory():add_item('main', 'experimental:tester_tool_1')
end)
diff --git a/src/scriptapi.cpp b/src/scriptapi.cpp
index 50e7236c8..5091216dc 100644
--- a/src/scriptapi.cpp
+++ b/src/scriptapi.cpp
@@ -2465,7 +2465,11 @@ private:
{
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *co = getobject(ref);
- if(co == NULL) return 0;
+ if(co == NULL){
+ // Default hp is 1
+ lua_pushnumber(L, 1);
+ return 1;
+ }
int hp = co->getHP();
/*infostream<<"ObjectRef::l_get_hp(): id="<<co->getId()
<<" hp="<<hp<<std::endl;*/
@@ -2485,7 +2489,7 @@ private:
if(get_server(L)->getInventory(loc) != NULL)
InvRef::create(L, loc);
else
- lua_pushnil(L);
+ lua_pushnil(L); // An object may have no inventory (nil)
return 1;
}
@@ -2516,7 +2520,11 @@ private:
{
ObjectRef *ref = checkobject(L, 1);
ServerActiveObject *co = getobject(ref);
- if(co == NULL) return 0;
+ if(co == NULL){
+ // Empty ItemStack
+ LuaItemStack::create(L, ItemStack());
+ return 1;
+ }
// Do it
LuaItemStack::create(L, co->getWieldedItem());
return 1;
@@ -2856,11 +2864,11 @@ const luaL_reg ObjectRef::methods[] = {
{0,0}
};
-// Creates a new anonymous reference if id=0
+// Creates a new anonymous reference if cobj=NULL or id=0
static void objectref_get_or_create(lua_State *L,
ServerActiveObject *cobj)
{
- if(cobj->getId() == 0){
+ if(cobj == NULL || cobj->getId() == 0){
ObjectRef::create(L, cobj);
} else {
objectref_get(L, cobj->getId());
@@ -3013,7 +3021,6 @@ private:
// pos = {x=num, y=num, z=num}
static int l_set_node(lua_State *L)
{
- //infostream<<"EnvRef::l_set_node()"<<std::endl;
EnvRef *o = checkobject(L, 1);
ServerEnvironment *env = o->m_env;
if(env == NULL) return 0;
@@ -3043,17 +3050,16 @@ private:
// pos = {x=num, y=num, z=num}
static int l_remove_node(lua_State *L)
{
- //infostream<<"EnvRef::l_remove_node()"<<std::endl;
EnvRef *o = checkobject(L, 1);
ServerEnvironment *env = o->m_env;
if(env == NULL) return 0;
- // pos
v3s16 pos = read_v3s16(L, 2);
// Do it
// Call destructor
MapNode n = env->getMap().getNodeNoEx(pos);
scriptapi_node_on_destruct(L, pos, n);
// Replace with air
+ // This is slightly optimized compared to addNodeWithEvent(air)
bool succeeded = env->getMap().removeNodeWithEvent(pos);
lua_pushboolean(L, succeeded);
// Air doesn't require constructor
@@ -3064,7 +3070,6 @@ private:
// pos = {x=num, y=num, z=num}
static int l_get_node(lua_State *L)
{
- //infostream<<"EnvRef::l_get_node()"<<std::endl;
EnvRef *o = checkobject(L, 1);
ServerEnvironment *env = o->m_env;
if(env == NULL) return 0;
@@ -3081,7 +3086,6 @@ private:
// pos = {x=num, y=num, z=num}
static int l_get_node_or_nil(lua_State *L)
{
- //infostream<<"EnvRef::l_get_node()"<<std::endl;
EnvRef *o = checkobject(L, 1);
ServerEnvironment *env = o->m_env;
if(env == NULL) return 0;
@@ -3128,6 +3132,82 @@ private:
}
}
+ // EnvRef:place_node(pos, node)
+ // pos = {x=num, y=num, z=num}
+ static int l_place_node(lua_State *L)
+ {
+ EnvRef *o = checkobject(L, 1);
+ ServerEnvironment *env = o->m_env;
+ if(env == NULL) return 0;
+ v3s16 pos = read_v3s16(L, 2);
+ MapNode n = readnode(L, 3, env->getGameDef()->ndef());
+
+ // Don't attempt to load non-loaded area as of now
+ MapNode n_old = env->getMap().getNodeNoEx(pos);
+ if(n_old.getContent() == CONTENT_IGNORE){
+ lua_pushboolean(L, false);
+ return 1;
+ }
+ // Create item to place
+ INodeDefManager *ndef = get_server(L)->ndef();
+ IItemDefManager *idef = get_server(L)->idef();
+ ItemStack item(ndef->get(n).name, 1, 0, "", idef);
+ // Make pointed position
+ PointedThing pointed;
+ pointed.type = POINTEDTHING_NODE;
+ pointed.node_abovesurface = pos;
+ pointed.node_undersurface = pos + v3s16(0,-1,0);
+ // Place it with a NULL placer (appears in Lua as a non-functional
+ // ObjectRef)
+ bool success = scriptapi_item_on_place(L, item, NULL, pointed);
+ lua_pushboolean(L, success);
+ return 1;
+ }
+
+ // EnvRef:dig_node(pos)
+ // pos = {x=num, y=num, z=num}
+ static int l_dig_node(lua_State *L)
+ {
+ EnvRef *o = checkobject(L, 1);
+ ServerEnvironment *env = o->m_env;
+ if(env == NULL) return 0;
+ v3s16 pos = read_v3s16(L, 2);
+
+ // Don't attempt to load non-loaded area as of now
+ MapNode n = env->getMap().getNodeNoEx(pos);
+ if(n.getContent() == CONTENT_IGNORE){
+ lua_pushboolean(L, false);
+ return 1;
+ }
+ // Dig it out with a NULL digger (appears in Lua as a
+ // non-functional ObjectRef)
+ bool success = scriptapi_node_on_dig(L, pos, n, NULL);
+ lua_pushboolean(L, success);
+ return 1;
+ }
+
+ // EnvRef:punch_node(pos)
+ // pos = {x=num, y=num, z=num}
+ static int l_punch_node(lua_State *L)
+ {
+ EnvRef *o = checkobject(L, 1);
+ ServerEnvironment *env = o->m_env;
+ if(env == NULL) return 0;
+ v3s16 pos = read_v3s16(L, 2);
+
+ // Don't attempt to load non-loaded area as of now
+ MapNode n = env->getMap().getNodeNoEx(pos);
+ if(n.getContent() == CONTENT_IGNORE){
+ lua_pushboolean(L, false);
+ return 1;
+ }
+ // Punch it with a NULL puncher (appears in Lua as a non-functional
+ // ObjectRef)
+ bool success = scriptapi_node_on_punch(L, pos, n, NULL);
+ lua_pushboolean(L, success);
+ return 1;
+ }
+
// EnvRef:add_entity(pos, entityname) -> ObjectRef or nil
// pos = {x=num, y=num, z=num}
static int l_add_entity(lua_State *L)
@@ -3482,6 +3562,9 @@ const luaL_reg EnvRef::methods[] = {
method(EnvRef, get_node),
method(EnvRef, get_node_or_nil),
method(EnvRef, get_node_light),
+ method(EnvRef, place_node),
+ method(EnvRef, dig_node),
+ method(EnvRef, punch_node),
method(EnvRef, add_entity),
method(EnvRef, add_item),
method(EnvRef, add_rat),
@@ -4351,7 +4434,6 @@ void scriptapi_export(lua_State *L, Server *server)
lua_getglobal(L, "minetest");
// Add tables to minetest
-
lua_newtable(L);
lua_setfield(L, -2, "object_refs");
lua_newtable(L);