merge basic machines branch

master
Juraj Vajda 2018-07-08 09:41:15 -04:00
commit afcc7114f2
10 changed files with 179 additions and 68 deletions

View File

@ -357,9 +357,21 @@ minetest.register_node("basic_machines:autocrafter", {
if type(ttl)~="number" then ttl = 1 end
if ttl<0 then return end -- machines_TTL prevents infinite recursion
run_autocrafter(pos, craft_time);
end
end,
can_dig = function(pos)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory();
if not (inv:is_empty("src")) or not (inv:is_empty("dst")) then return false end -- all inv must be empty to be dug
return true
end
}
}
--on_timer = run_autocrafter -- rnd
})

View File

@ -245,7 +245,7 @@ minetest.register_entity("basic_machines:ball",{
if minetest.is_protected(pos,self.owner) then return end
end
local effector = table.mesecons.effector;
local count = ballcount[self.owner] or 1; count=count-1; ballcount[self.owner] = count;
self.object:remove();
if energy>0 then
@ -393,7 +393,8 @@ minetest.register_node("basic_machines:ball_spawner", {
end,
mesecons = {effector = {
action_on = function (pos, node,ttl)
action_on = function (pos, node,ttl)
if type(ttl)~="number" then ttl = 1 end
if ttl<0 then return end
local meta = minetest.get_meta(pos);
@ -422,10 +423,10 @@ minetest.register_node("basic_machines:ball_spawner", {
local owner = meta:get_string("owner");
local count = ballcount[owner];
if not count or count<0 then count = 0 end
if count>=2 then
if t1-t0>20 then count = 0
else return
if count>=2 then
if t1-t0>10 then count = 0
else return
end
end
@ -496,8 +497,9 @@ minetest.register_node("basic_machines:ball_spawner", {
end,
action_off = function (pos, node,ttl)
action_off = function (pos, node,ttl)
if type(ttl)~="number" then ttl = 1 end
if ttl<0 then return end
pos.x = round(pos.x);pos.y = round(pos.y);pos.z = round(pos.z);
local obj = minetest.add_entity({x=pos.x,y=pos.y,z=pos.z}, "basic_machines:ball");

View File

@ -227,6 +227,17 @@ minetest.register_node("basic_machines:constructor", {
constructor_update_meta(pos);
end,
can_dig = function(pos)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory();
if not (inv:is_empty("main")) then return false end -- main inv must be empty to be dug
return true
end
})

View File

@ -82,6 +82,7 @@ minetest.register_node("basic_machines:enviro", {
meta:set_string("owner",name);
local privs = minetest.get_player_privs(name);
if privs.privs then meta:set_int("admin",1) end
if privs.machines then meta:set_int("machines",1) end
local inv = meta:get_inventory();
inv:set_size("fuel",1*1);
@ -92,6 +93,9 @@ minetest.register_node("basic_machines:enviro", {
mesecons = {effector = {
action_on = function (pos, node,ttl)
local meta = minetest.get_meta(pos);
local machines = meta:get_int("machines");
if not machines == 1 then meta:set_string("infotext","Error. You need machines privs.") return end
local admin = meta:get_int("admin");
local inv = meta:get_inventory(); local stack = ItemStack("default:diamond 1");
@ -222,6 +226,12 @@ minetest.register_node("basic_machines:enviro", {
if meta:get_string("owner")~=player:get_player_name() and not privs.privs then return 0 end
return stack:get_count();
end,
can_dig = function(pos, player) -- dont dig if fuel is inside, cause it will be destroyed
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory();
return inv:is_empty("fuel")
end,
})
@ -377,7 +387,7 @@ minetest.register_on_punchplayer( -- bring gravity closer to normal with each pu
local gravity = player:get_physics_override().gravity;
if gravity<1 then
gravity = 0.5*gravity+0.5;
gravity = 1;
player:set_physics_override({gravity=gravity})
end
end

View File

@ -1,3 +1,5 @@
--todo: when grinding multiple items compare battery maxpower with number of items and attempt to grind as much as possible
-- rnd 2016:
-- this node works as technic grinder
@ -6,6 +8,7 @@
-- recipe list: [in] ={fuel cost, out, quantity of material required for processing}
basic_machines.grinder_recipes = {
["default:stone"] = {2,"default:sand",1},
["default:desert_stone"] = {2,"default:desert_sand 4",1},
["default:cobble"] = {1,"default:gravel",1},
["default:gravel"] = {0.5,"default:dirt",1},
["default:dirt"] = {0.5,"default:clay_lump 4",1},
@ -233,6 +236,16 @@ minetest.register_node("basic_machines:grinder", {
end
grinder_update_meta(pos);
end,
can_dig = function(pos)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory();
if not (inv:is_empty("fuel")) or not (inv:is_empty("src")) or not (inv:is_empty("dst")) then return false end -- all inv must be empty to be dug
return true
end
})

View File

@ -19,6 +19,7 @@
basic_machines = {};
dofile(minetest.get_modpath("basic_machines").."/mark.lua") -- used for markings, borrowed and adapted from worldedit mod
dofile(minetest.get_modpath("basic_machines").."/mover.lua") -- mover, detector, keypad, distributor
dofile(minetest.get_modpath("basic_machines").."/technic_power.lua") -- technic power for mover

118
mover.lua
View File

@ -11,7 +11,7 @@ local machines_minstep = 1 -- minimal allowed activation timestep, if faster mac
local max_range = 10; -- machines normal range of operation
local machines_operations = 10; -- 1 coal will provide 10 mover basic operations ( moving dirt 1 block distance)
local machines_TTL = 16; -- time to live for signals, how many hops before signal dissipates
basic_machines.version = "12/29/2017a";
basic_machines.version = "05/23/2018a";
basic_machines.clockgen = 1; -- if 0 all background continuously running activity (clockgen/keypad) repeating is disabled
-- how hard it is to move blocks, default factor 1, note fuel cost is this multiplied by distance and divided by machine_operations..
@ -19,10 +19,11 @@ basic_machines.hardness = {
["default:stone"]=4,
["default:tree"]=2,
["default:jungletree"]=2,
["default:pinetree"]=2,
["default:pine_tree"]=2,
["default:aspen_tree"]=2,
["default:acacia_tree"]=2,
["default:lava_source"]=21890,
["default:water_source"]=11000,
["default:lava_source"]=5950,
["default:water_source"]=5950,
["default:obsidian"]=20,
["bedrock2:bedrock"]=999999,
["spawners_env:mobs_spider_spawner"]=999999,
@ -32,6 +33,7 @@ basic_machines.hardness = {
["spawners_env:spawners_mobs_uruk_hai_spawner_active"]=999999,
["spawners_env:spawners_mobs_uruk_hai_spawner_waiting"]=999999
};
--move machines for free
basic_machines.hardness["basic_machines:mover"]=0.;
basic_machines.hardness["basic_machines:keypad"]=0.;
@ -63,8 +65,8 @@ basic_machines.hardness["mese_crystals:mese_crystal_ore4"] = 10;
-- define which nodes are dug up completely, like a tree
basic_machines.dig_up_table = {["default:cactus"]=true,["default:tree"]=true,["default:jungletree"]=true,["default:pinetree"]=true,
["default:acacia_tree"]=true,["default:papyrus"]=true};
basic_machines.dig_up_table = {["default:cactus"]=true,["default:tree"]=true,["default:jungletree"]=true,["default:pine_tree"]=true,
["default:acacia_tree"]=true,["default:aspen_tree"]=true,["default:papyrus"]=true};
-- set up nodes for harvest when digging: [nodename] = {what remains after harvest, harvest result}
basic_machines.harvest_table = {
@ -93,9 +95,12 @@ basic_machines.no_teleport_table = {
basic_machines.limit_inventory_table = { -- node name = {list of bad inventories to take from}
["basic_machines:autocrafter"]= {["recipe"]=1, ["output"]=1},
["basic_machines:constructor"]= {["recipe"]=1},
["basic_machines:battery"] = {["upgrade"] = 1},
["basic_machines:battery_0"] = {["upgrade"] = 1},
["basic_machines:battery_1"] = {["upgrade"] = 1},
["basic_machines:battery_2"] = {["upgrade"] = 1},
["basic_machines:generator"] = {["upgrade"] = 1},
["basic_machines:mover"] = {["upgrade"] = 1},
["moreblocks:circular_saw"] = {["input"]=1,["recycle"]=1,["micro"]=1,["output"]=1},
}
-- when activated with keypad these will be "punched" to update their text too
@ -295,7 +300,7 @@ minetest.register_node("basic_machines:mover", {
can_dig = function(pos, player) -- dont dig if upgrades inside, cause they will be destroyed
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory();
return not(inv:contains_item("upgrade", ItemStack({name="default:mese"})));
return inv:is_empty("upgrade")
end,
@ -722,7 +727,9 @@ minetest.register_node("basic_machines:mover", {
if dig_up == true then -- dig up to 16 nodes
local r = 1; if node1.name == "default:cactus" or node1.name == "default:papyrus" then r = 0 end
local r = 1;
if node1.name == "default:cactus" or node1.name == "default:papyrus" then r = 0 end
if node1.name == "default:acacia_tree" then r = 2 end -- acacia trees grow wider than others
local positions = minetest.find_nodes_in_area( --
{x=pos1.x-r, y=pos1.y, z=pos1.z-r},
@ -847,8 +854,11 @@ minetest.register_node("basic_machines:mover", {
if type(ttl)~="number" then ttl = 1 end
local meta = minetest.get_meta(pos);
local mreverse = meta:get_int("reverse");
if mreverse == 1 then mreverse = 0 elseif mreverse==0 then mreverse = 1 end
meta:set_int("reverse",mreverse);
local mode = meta:get_string("mode");
if mode ~= "dig" then -- reverse switching is not very helpful when auto harvest trees for example
if mreverse == 1 then mreverse = 0 elseif mreverse==0 then mreverse = 1 end
meta:set_int("reverse",mreverse);
end
end
}
@ -930,7 +940,7 @@ local function use_keypad(pos,ttl, again) -- position, time to live ( how many t
-- pass the signal on to target, depending on mode
local tpos = {x=x0,y=y0,z=z0};
local tpos = {x=x0,y=y0,z=z0}; -- target position
local node = minetest.get_node(tpos);if not node.name then return end -- error
local text = meta:get_string("text");
@ -940,7 +950,8 @@ local function use_keypad(pos,ttl, again) -- position, time to live ( how many t
meta:set_string("input",""); -- clear input again
end
if string.byte(text) == 33 then -- if text starts with !, then we send chat text to all nearby players, radius 5
local bit = string.byte(text);
if bit == 33 then -- if text starts with !, then we send chat text to all nearby players, radius 5
text = string.sub(text,2) ; if not text or text == "" then return end
local players = minetest.get_connected_players();
for _,player in pairs(players) do
@ -951,14 +962,15 @@ local function use_keypad(pos,ttl, again) -- position, time to live ( how many t
end
end
return
elseif string.byte(text) == 36 then-- text starts with $, play sound
elseif bit == 36 then-- text starts with $, play sound
text = string.sub(text,2) ; if not text or text == "" then return end
minetest.sound_play(text, {pos=pos,gain=1.0,max_hear_distance = 16,})
end
local tmeta = minetest.get_meta(tpos);if not tmeta then return end
tmeta:set_string("infotext", text);
if basic_machines.signs[node.name] then -- update text on signs with signs_lib
tmeta:set_string("infotext", text);
tmeta:set_string("text",text);
local table = minetest.registered_nodes[node.name];
if not table.on_punch then return end -- error
@ -970,36 +982,49 @@ local function use_keypad(pos,ttl, again) -- position, time to live ( how many t
return
end
-- target is keypad, special functions: @, % that output to target keypad text
if node.name == "basic_machines:keypad" then -- special modify of target keypad text and change its target
local ttext = tmeta:get_string("text");
x0=tmeta:get_int("x0");y0=tmeta:get_int("y0");z0=tmeta:get_int("z0");
x0=tpos.x+x0;y0=tpos.y+y0;z0=tpos.z+z0;
tpos = {x=x0,y=y0,z=z0};
if string.byte(ttext) == 64 then -- target keypad's text starts with @ ( ascii code 64) -> character replacement
ttext =string.sub(ttext,2); if not ttext or ttext == "" then return end
ttext = string.gsub(ttext, "@", text); -- replace every @ in ttext with text
-- set target keypad's target's infotext
tmeta = minetest.get_meta(tpos);if not tmeta then return end
tmeta:set_string("infotext", ttext);
elseif string.byte(ttext) == 37 then -- target keypad's text starts with % ( ascii code 37) -> word extraction
local i = tonumber(string.sub(ttext,2,2)) or 1; --read the number following the %
if string.byte(text) == 64 then -- target keypad's text starts with @ ( ascii code 64) -> character replacement
text = string.sub(text,2); if not text or text == "" then return end
--read words[j] from blocks above keypad:
local j=0;
text = string.gsub(text, "@",
function()
j=j+1;
return minetest.get_meta({x=pos.x,y=pos.y+j,z=pos.z}):get_string("infotext")
end
) ; -- replace every @ in ttext with string on blocks above
-- set target keypad's text xxx
--tmeta = minetest.get_meta(tpos);if not tmeta then return end
tmeta:set_string("text", text);
elseif string.byte(text) == 37 then -- target keypad's text starts with % ( ascii code 37) -> word extraction
local ttext = minetest.get_meta({x=pos.x,y=pos.y+1,z=pos.z}):get_string("infotext")
local i = tonumber(string.sub(text,2,2)) or 1; --read the number following the %
--extract i-th word from text
local j = 0;
for word in string.gmatch(text, "%S+") do
j=j+1; if j == i then ttext = word; break; end
for word in string.gmatch(ttext, "%S+") do
j=j+1; if j == i then text = word; break; end
end
-- set target keypad's target's infotext
tmeta = minetest.get_meta(tpos);if not tmeta then return end
tmeta:set_string("infotext", ttext);
else
-- set target keypad's target's text
--tmeta = minetest.get_meta(tpos); if not tmeta then return end
tmeta:set_string("text", text);
else
if string.byte(text) == 64 then -- if text starts with @ clear target keypad text
tmeta:set_string("text","");
return
end
tmeta = minetest.get_meta(tpos);if not tmeta then return end
tmeta:set_string("infotext", ttext);
-- just set text..
--tmeta = minetest.get_meta(tpos); if not tmeta then return end
tmeta:set_string("infotext", text);
end
return
end
@ -1034,8 +1059,11 @@ local function use_keypad(pos,ttl, again) -- position, time to live ( how many t
return
end
tmeta:set_string("infotext", text); -- else just set text
end
--activate target
local table = minetest.registered_nodes[node.name];
if not table then return end -- error
if not table.mesecons then return end -- error
@ -1612,10 +1640,11 @@ minetest.register_node("basic_machines:distributor", {
--ret = pcall(function() if not table.mesecons.effector then end end); -- exception handling to determine if structure exists
local effector=table.mesecons.effector;
local active_i = active[i];
if (active[i] == 1 or active[i] == 2) and effector.action_on then -- normal OR only forward input ON
if (active_i == 1 or active_i == 2) and effector.action_on then -- normal OR only forward input ON
effector.action_on(posf[i],node,ttl-1);
elseif active[i] == -1 and effector.action_off then
elseif active_i == -1 and effector.action_off then
effector.action_off(posf[i],node,ttl-1)
end
end
@ -1624,7 +1653,15 @@ minetest.register_node("basic_machines:distributor", {
end
end
if delay>0 then minetest.after(delay, activate) else activate() end
if delay>0 then
minetest.after(delay, activate)
elseif delay == 0 then
activate()
else -- delay <0 - do random activation: delay = -500 means 500/1000 chance to activate
if math.random(1000)<=-delay then
activate()
end
end
end,
@ -2241,8 +2278,8 @@ minetest.register_on_player_receive_fields(function(player,formname,fields)
"\n\nplaying sound to nearby players : set text to \"$sound_name\""..
"\n\nadvanced: "..
"\ntext replacement : Suppose keypad A is set with text \"@some @. text @!\" and keypad B is set with text \"insertion\". Suppose we target A with B and activate B. Then text of keypad A will be set to \"some insertion. text insertion!\" insertion\""..
"\nword extraction: Suppose keypad A is set with text \"%1\". Then upon activation text of keypad A will be set to 1.st word of keypad B.";
"\ntext replacement : Suppose keypad A is set with text \"@some @. text @!\" and there are blocks on top of keypad A with infotext '1' and '2'. Suppose we target B with A and activate A. Then text of keypad B will be set to \"some 1. text 2!\""..
"\nword extraction: Suppose similiar setup but now keypad A is set with text \"%1\". Then upon activation text of keypad B will be set to 1.st word of infotext";
local form = "size [6,7] textarea[0,0;6.5,8.5;help;KEYPAD HELP;".. text.."]"
minetest.show_formspec(name, "basic_machines:help_keypad", form)
@ -2273,6 +2310,7 @@ minetest.register_on_player_receive_fields(function(player,formname,fields)
if fields.text then
meta:set_string("text", fields.text);
if string.find(fields.text, "!") then minetest.log("action", string.format("%s set up keypad for message display at %s", name, minetest.pos_to_string(pos))) end
end
meta:set_int("iter",math.min(tonumber(fields.iter) or 1,500));meta:set_int("mode",mode);
@ -2492,7 +2530,7 @@ minetest.register_on_player_receive_fields(function(player,formname,fields)
"Numbers in each row represent (from left to right) : first 3 numbers are target coordinates,\n"..
"last number controls how signal is passed to target. For example, to only pass OFF signal use -2,\n"..
"to only pass ON use 2, -1 negates the signal, 1 = pass original signal, 0 blocks signal\n"..
"delay option adds delay to activations, in seconds\n\n"..
"delay option adds delay to activations, in seconds. With negative delay activation is randomized with probability -delay/1000.\n\n"..
"ADVANCED: you can use distributor as an event handler. First you must deactivate first target by putting 0 at\n"..
"last place in first line. Meanings of first 2 numbers are as follows: first number 0/1 controls if node/n".. "listens to failed interact attempts around it, second number -1/1 listens to chat and can mute it";
local form = "size [5.5,5.5] textarea[0,0;6,7;help;DISTRIBUTOR HELP;".. text.."]"

View File

@ -5,7 +5,7 @@
local old_is_protected = minetest.is_protected
local round = math.floor;
local machines_TTL=5
local machines_TTL=16
function minetest.is_protected(pos, digger)

View File

@ -115,6 +115,9 @@ local recycler_process = function(pos)
-- inv:set_stack("dst", i, ItemStack(""));
-- end
--take 1 item from src inventory for each activation
stack=stack:take_item(reqcount); inv:remove_item("src", stack)
for _, v in pairs(itemlist) do
if math.random(1, 4)<=3 then -- probability 3/4 = 75%
if not string.find(v,"group") then -- dont add if item described with group
@ -127,8 +130,7 @@ local recycler_process = function(pos)
end
end
--take 1 item from src inventory for each activation
stack=stack:take_item(reqcount); inv:remove_item("src", stack)
minetest.sound_play("recycler", {pos=pos,gain=0.5,max_hear_distance = 16,})
@ -142,7 +144,7 @@ local recycler_update_meta = function(pos)
local meta = minetest.get_meta(pos)
local list_name = "nodemeta:"..pos.x..','..pos.y..','..pos.z
local form =
"size[8,8]".. -- width, height
"size[8,8]".. -- width, heightinv:get_stack
--"size[6,10]".. -- width, height
"label[0,0;IN] label[1,0;OUT] label[0,2;FUEL] "..
"list["..list_name..";src;0.,0.5;1,1;]"..
@ -244,6 +246,17 @@ minetest.register_node("basic_machines:recycler", {
meta:set_string("node",""); -- this will force to reread recipe on next use
recycler_update_meta(pos);
end,
can_dig = function(pos)
local meta = minetest.get_meta(pos);
local inv = meta:get_inventory();
if not (inv:is_empty("fuel")) or not (inv:is_empty("src")) or not (inv:is_empty("dst")) then return false end -- all inv must be empty to be dug
return true
end
})

View File

@ -47,13 +47,14 @@ battery_recharge = function(pos)
if add_energy>0 then
if pos.y>1500 then add_energy=2*add_energy end -- in space recharge is more efficient
crystal = true;
if energy+add_energy<=capacity then
if add_energy<=capacity then
stack:take_item(1);
inv:set_stack("fuel", 1, stack)
else
else
meta:set_string("infotext", "recharge problem: capacity " .. capacity .. ", needed " .. energy+add_energy)
return energy
end
else -- try do determine caloric value
else -- try do determine caloric value of fuel inside battery
local fuellist = inv:get_list("fuel");if not fuellist then return energy end
local fueladd, afterfuel = minetest.get_craft_result({method = "fuel", width = 1, items = fuellist})
if fueladd.time > 0 then
@ -65,14 +66,12 @@ battery_recharge = function(pos)
end
if add_energy>0 then
if energy+add_energy<=capacity then
energy=energy+add_energy
if energy<0 then energy = 0 end
meta:set_float("energy",energy);
meta:set_string("infotext", "(R) energy: " .. math.ceil(energy*10)/10 .. " / ".. capacity);
--TODO2: add entity power status display
minetest.sound_play("electric_zap", {pos=pos,gain=0.05,max_hear_distance = 8,})
end
energy=energy+add_energy
if energy<0 then energy = 0 end
if energy>capacity then energy = capacity end -- excess energy is wasted
meta:set_float("energy",energy);
meta:set_string("infotext", "(R) energy: " .. math.ceil(energy*10)/10 .. " / ".. capacity);
minetest.sound_play("electric_zap", {pos=pos,gain=0.05,max_hear_distance = 8,})
end
local full_coef = math.floor(energy/capacity*3); if full_coef > 2 then full_coef = 2 end
@ -175,9 +174,10 @@ minetest.register_node("basic_machines:battery_0", {
-- update energy display
end
if energy<0 then
energy = 0
else -- only accelerate if we had enough energy
else -- only accelerate if we had enough energy, note: upgrade*0.1*0.25<power_rod is limit upgrade, so upgrade = 40*100 = 4000
fmeta:set_float("src_time",src_time+machines_timer*upgrade); -- accelerated smelt: with 99 upgrade battery furnace works 11x faster
end
@ -287,7 +287,12 @@ minetest.register_node("basic_machines:battery_0", {
can_dig = function(pos)
local meta = minetest.get_meta(pos);
if meta:get_int("upgrade")~=0 then return false else return true end
local inv = meta:get_inventory();
if not (inv:is_empty("fuel")) or not (inv:is_empty("upgrade")) then return false end -- fuel AND upgrade inv must be empty to be dug
return true
end
})
@ -423,7 +428,12 @@ minetest.register_node("basic_machines:generator", {
can_dig = function(pos)
local meta = minetest.get_meta(pos);
if meta:get_int("upgrade")~=0 then return false else return true end
local inv = meta:get_inventory();
if not inv:is_empty("upgrade") then return false end -- fuel inv is not so important as generator generates it
return true
end
})
@ -483,6 +493,7 @@ function basic_machines.check_power(pos, power_draw) -- mover checks power sourc
if power_draw>energy then
energy = battery_recharge(pos); -- try recharge battery and continue operation immidiately
if not energy then return 0 end
end
energy = energy-power_draw;