minetest 5.0.0rc1 adapt

master
rnd 2019-02-04 22:54:28 +01:00
parent b3bcffee6a
commit 082e5a6f95
35 changed files with 956 additions and 200 deletions

View File

@ -110,7 +110,7 @@ end
minetest.register_abm({ -- very slowly create energy
nodenames = {"alchemy:lab"},
neighbors = {""},
neighbors = {},
interval = 30,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)

View File

@ -30,36 +30,6 @@ function prevent_place_above(name)
local old_after_place_node = minetest.registered_nodes[name];--.after_place_node;
--after_place_node = func(pos, placer, itemstack, pointed_thing)
if old_after_place_node then
old_after_place_node=old_after_place_node.after_place_node
local table = minetest.registered_nodes[name];
local table2 = {}
for i,v in pairs(table) do
table2[i] = v
end
table2.after_place_node=function(pos, placer, itemstack, pointed_thing)
--after_place_node = func(pos, placer, itemstack, pointed_thing)
if pos.y>4 then
local pname = placer:get_player_name();
local privs = antigrief[pname];
if privs == nil then privs = minetest.get_player_privs(pname).kick; antigrief[pname] = privs end
if not privs then
minetest.chat_send_player(pname,"ANTIGRIEF: place liquids below height 4")
minetest.log("action","ANTI GRIEF " .. pname .. " tried to place " .. name .. " at " .. minetest.pos_to_string(pos));
minetest.set_node(pos, {name = "air"});
return itemstack
end
end
end
minetest.register_node(":"..name, table2)
return;
end
if old_on_place and old_on_place.on_place then
old_on_place=old_on_place.on_place;
minetest.registered_craftitems[name].on_place=function(itemstack, placer, pointed_thing)
@ -78,6 +48,37 @@ function prevent_place_above(name)
end
return;
end
if old_after_place_node then
old_after_place_node=old_after_place_node.after_place_node
local table = minetest.registered_nodes[name];
local table2 = {}
for i,v in pairs(table) do
table2[i] = v
end
table2.after_place_node=function(pos, placer, itemstack, pointed_thing)
--after_place_node = func(pos, placer, itemstack, pointed_thing)
local pos = pointed_thing.above
if pos.y>4 then
local pname = placer:get_player_name();
local privs = antigrief[pname];
if privs == nil then privs = minetest.get_player_privs(pname).kick; antigrief[pname] = privs end
if not privs then
minetest.chat_send_player(pname,"ANTIGRIEF: place liquids below height 4")
minetest.log("action","ANTI GRIEF " .. pname .. " tried to place " .. name .. " at " .. minetest.pos_to_string(pos));
minetest.set_node(pos, {name = "air"});
return itemstack
end
end
end
minetest.register_node(":"..name, table2)
return;
end
return;

View File

@ -1,8 +1,3 @@
--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
-- There is a certain fuel cost to operate
-- recipe list: [in] ={fuel cost, out, quantity of material required for processing}
@ -12,33 +7,12 @@ basic_machines.grinder_recipes = {
["default:cobble"] = {1,"default:gravel",1},
["default:gravel"] = {0.5,"default:dirt",1},
["default:dirt"] = {0.5,"default:clay_lump 4",1},
["es:aikerum_crystal"] ={16,"es:aikerum_dust 2",1}, -- added for es mod
["es:ruby_crystal"] = {16,"es:ruby_dust 2",1},
["es:emerald_crystal"] = {16,"es:emerald_dust 2",1},
["es:purpellium_lump"] = {16,"es:purpellium_dust 2",1},
["default:obsidian_shard"] = {199,"default:lava_source",1},
["gloopblocks:basalt"] = {1, "default:cobble",1}, -- enable coble farms with gloopblocks mod
["default:ice"] = {1, "default:snow 4",1},
["darkage:silt_lump"]={1,"darkage:chalk_powder",1},
};
-- es gems dust cooking
local es_gems = function()
local es_gems = {
{name = "emerald", cooktime = 1200},{name = "ruby", cooktime = 1500},{name = "purpellium", cooktime = 1800},
{name = "aikerum", cooktime = 2000}}
for _,v in pairs(es_gems) do
minetest.register_craft({
type = "cooking",
recipe = "es:"..v.name.."_dust",
output = "es:"..v.name .."_crystal",
cooktime = v.cooktime
})
end
end
minetest.after(0,es_gems);
local grinder_process = function(pos)
@ -278,7 +252,7 @@ local function register_dust(name,input_node_name,ingot,grindcost,cooktime,R,G,B
if not G then G = "FF" end
if not B then B = "FF" end
local purity_table = {"33","66"};
local purity_table = {"00","33","66"};
for i = 1,#purity_table do
local purity = purity_table[i];
@ -292,7 +266,7 @@ local function register_dust(name,input_node_name,ingot,grindcost,cooktime,R,G,B
if ingot~="" then
for i = 1,#purity_table-1 do
for i = 2,#purity_table-1 do
minetest.register_craft({
type = "cooking",
recipe = "basic_machines:"..name.."_dust_".. purity_table[i],
@ -319,10 +293,10 @@ register_dust("tin","default:tin_lump","default:tin_ingot",4,8,"9F","9F","9F")
register_dust("gold","default:gold_lump","default:gold_ingot",6,25,"FF","FF","00")
-- grinding ingots gives dust too
basic_machines.grinder_recipes["default:steel_ingot"] = {4,"basic_machines:iron_dust_33 2",1};
basic_machines.grinder_recipes["default:copper_ingot"] = {4,"basic_machines:copper_dust_33 2",1};
basic_machines.grinder_recipes["default:gold_ingot"] = {6,"basic_machines:gold_dust_33 2",1};
basic_machines.grinder_recipes["default:tin_ingot"] = {4,"basic_machines:tin_dust_33 2",1};
basic_machines.grinder_recipes["default:steel_ingot"] = {4,"basic_machines:iron_dust_00 2",1};
basic_machines.grinder_recipes["default:copper_ingot"] = {4,"basic_machines:copper_dust_00 2",1};
basic_machines.grinder_recipes["default:gold_ingot"] = {6,"basic_machines:gold_dust_00 2",1};
basic_machines.grinder_recipes["default:tin_ingot"] = {4,"basic_machines:tin_dust_00 2",1};
-- are moreores (tin, silver, mithril) present?
@ -331,8 +305,8 @@ local table = minetest.registered_items["moreores:tin_lump"]; if table then
register_dust("silver","moreores:silver_lump","moreores:silver_ingot",5,15,"BB","BB","BB")
register_dust("mithril","moreores:mithril_lump","moreores:mithril_ingot",16,750,"00","00","FF")
basic_machines.grinder_recipes["moreores:tin_ingot"] = {4,"basic_machines:tin_dust_33 2",1};
basic_machines.grinder_recipes["moreores:silver_ingot"] = {5,"basic_machines:silver_dust_33 2",1};
basic_machines.grinder_recipes["moreores:tin_ingot"] = {4,"basic_machines:tin_dust_00 2",1};
basic_machines.grinder_recipes["moreores:silver_ingot"] = {5,"basic_machines:silver_dust_00 2",1};
basic_machines.grinder_recipes["moreores:mithril_ingot"] = {16,"basic_machines:mithril_dust_33 2",1};
end
@ -385,4 +359,70 @@ minetest.register_craft({
recipe = {
{"default:dirt","default:water_flowing"}
}
})
})
-- dust_33 from dust_00 recipe xxx
minetest.register_craft({
output = 'basic_machines:iron_dust_33',
recipe = {
{'default:leaves','default:leaves','basic_machines:iron_dust_00'},
}
})
minetest.register_craft({
output = 'basic_machines:copper_dust_33',
recipe = {
{'default:papyrus','default:papyrus','basic_machines:copper_dust_00'},
}
})
minetest.register_craft({
output = 'basic_machines:tin_dust_33',
recipe = {
{'farming:cocoa_beans','farming:cocoa_beans','basic_machines:tin_dust_00'},
}
})
minetest.register_craft({
output = 'basic_machines:gold_dust_33',
recipe = {
{'basic_machines:tin_extractor','basic_machines:copper_extractor','basic_machines:gold_dust_00'},
}
})
minetest.register_craft({
output = 'basic_machines:mese_dust_33',
recipe = {
{'farming:rhubarb','farming:rhubarb','basic_machines:mese_dust_00'},
}
})
minetest.register_craft({
output = 'basic_machines:diamond_dust_33',
recipe = {
{'farming:wheat','farming:cotton','basic_machines:diamond_dust_00'},
}
})
local function register_extractor(name,R,G,B)
if not R then R = "FF" end
if not G then G = "FF" end
if not B then B = "FF" end
minetest.register_craftitem("basic_machines:"..name.."_extractor", {
description = "chemical used in extraction of " .. name ,
inventory_image = "ore_extractor.png^[colorize:#"..R..G..B..":180",
})
end
register_extractor("iron","99","99","99")
register_extractor("copper","C8","80","0D")
register_extractor("tin","C8","9F","9F")
register_extractor("gold","FF","FF","00")
register_extractor("mese","CC","CC","00")
register_extractor("diamond","00","EE","FF")
register_extractor("mithril","00","00","FF")

View File

@ -249,6 +249,8 @@ local find_and_connect_battery = function(pos)
return nil
end
local check_for_falling = minetest.check_for_falling or nodeupdate; -- 1st for mt 5.0.0+, 2nd for 0.4.17.1 and older
-- MOVER --
minetest.register_node("basic_machines:mover", {
@ -798,7 +800,7 @@ minetest.register_node("basic_machines:mover", {
end
end
if not(source_chest) and not(harvest) then
if dig then nodeupdate(pos1) end
if dig then check_for_falling(pos1) end -- pre 5.0.0 nodeupdate(pos1)
minetest.set_node(pos1, {name = "air"});
end
end,
@ -1449,7 +1451,7 @@ minetest.register_chatcommand("clockgen", { -- test: toggle machine running with
-- CLOCK GENERATOR : periodically activates machine on top of it
minetest.register_abm({
nodenames = {"basic_machines:clockgen"},
neighbors = {""},
neighbors = {},
interval = machines_timer,
chance = 1,

View File

@ -1,24 +1 @@
outlet -> change to battery
battery: craft with meseblock and 3 steel and 1 diamond
-upgradeable, start with 10 storage units, each upgrade requires 1.25x more mese blocks and adds 10 storage units ( 1 unit = 1 coal lump)??
-display will use entity to show battery bar status on side of battery - determined by where player stands when placing it ( only if there is air there)
-battery can be refueled using any valid furnace fuel or by power cells/rods - on fuel insert it will instantly convert to energy, if there is enough energy
storage ofc
-on activation it will power furnace on top of it, just like outlet does now
-when digged and put in invetory it should retain its upgrade info
movers: instead of looking for locked chest with fuel it will look for nearby battery
power plant block: costly to make: 8 diamondblocks, battery in center
-upgradeable, each diamondblock+lava_bucket will add ammount of energy cells produced in cycle ( 5 seconds) and increase its internal energy storage capacity
initially produces 1 power cell, storage capacity 10, with each level of upgrade it adds 1 power cell, 10 storage capacity
when it generates power it will also fill the battery on top of it ( if any), speed of refill equalls speed of power generation, it will put all energy
possible in battery until is filled, will make recharge sound - electric discharge like in factorio game?
power cell: produced by power plant, have caloric value of 1 coal lump
9 power cells craft 1 power cell block: caloric value of coal block
9 power cell blocks 1 power rod
machines will check power: if battery not sufficient capacity for operation it wont work ( it should be able to do at least 10 operations with its capacity)
grinder: creates dust_0, must be mixed with extractor chemical to get dust_33

View File

@ -462,7 +462,7 @@ minetest.register_node("basic_machines:generator", {
minetest.register_abm({
nodenames = {"basic_machines:generator"},
neighbors = {""},
neighbors = {},
interval = 19,
chance = 1,
action = function(pos, node, active_object_count, active_object_count_wider)

View File

@ -156,10 +156,10 @@ basic_protect.protect_new = function(p,name)
local skyid = skyblock.players[name].id;
local skypos = skyblock.get_island_pos(skyid);
local dist = math.max(math.abs(p.x-skypos.x),math.abs(p.z-skypos.z));
if dist>=skyblock.islands_gap and p.y<500 then
if dist>=skyblock.islands_gap then
local privs = minetest.get_player_privs(name);
if not privs.kick then
minetest.chat_send_player(name, "#PROTECTOR: you can only protect empty space or your island or above it OR above height 500")
minetest.chat_send_player(name, "#PROTECTOR: you can only protect empty space or your island or above it")
minetest.set_node(p,{name = "air"}) -- clear protector
return
end

View File

@ -136,12 +136,12 @@ basic_robot.commands.dig = function(name,dir)
--require energy to dig
if basic_robot.dig_require_energy then
local digcost = basic_robot.digcosts[nodename];
local digcost = basic_robot.digcosts[nodename] or 1/(5*25); -- default 1/5th of stone dig
if digcost then
local data = basic_robot.data[name];
local energy = (data.menergy or 0) - digcost;
if energy<0 then
error("need " .. digcost .. " energy to dig " .. nodename .. ". Use machine.generate(...) to get some energy.");
error("need " .. digcost .. " energy to dig " .. nodename .. ". Use machine.generate to get some energy.");
end
data.menergy = energy;
end
@ -866,30 +866,26 @@ basic_robot.technic = { -- data cache
["default:cobble"] = {1,"default:gravel",1},
["default:gravel"] = {0.5,"default:dirt",1},
["default:dirt"] = {0.5,"default:clay_lump 4",1},
["es:aikerum_crystal"] ={16,"es:aikerum_dust 2",1}, -- added for es mod
["es:ruby_crystal"] = {16,"es:ruby_dust 2",1},
["es:emerald_crystal"] = {16,"es:emerald_dust 2",1},
["es:purpellium_lump"] = {16,"es:purpellium_dust 2",1},
["default:obsidian_shard"] = {199,"default:lava_source",1},
["gloopblocks:basalt"] = {1, "default:cobble",1}, -- enable coble farms with gloopblocks mod
["default:ice"] = {1, "default:snow 4",1},
["darkage:silt_lump"]={1,"darkage:chalk_powder",1},
["default:diamond"] = {16, "basic_machines:diamond_dust_33 2", 1},
["default:diamond"] = {16, "basic_machines:diamond_dust_00 2", 1},
["default:ice"] = {1, "default:snow", 1},
["moreores:tin_lump"] = {4,"basic_machines:tin_dust_33 2",1},
["moreores:tin_lump"] = {4,"basic_machines:tin_dust_00 2",1},
["default:obsidian_shard"] = {199, "default:lava_source",1},
["default:mese_crystal"] = {8, "basic_machines:mese_dust_33 2",1},
["default:mese_crystal"] = {8, "basic_machines:mese_dust_00 2",1},
["moreores:mithril_ingot"] = {16, "basic_machines:mithril_dust_33 2",1},
["moreores:silver_ingot"] = {5, "basic_machines:silver_dust_33 2",1},
["moreores:tin_ingot"] = {4,"basic_machines:tin_dust_33 2",1},
["moreores:tin_ingot"] = {4,"basic_machines:tin_dust_00 2",1},
["moreores:mithril_lump"] = {16, "basic_machines:mithril_dust_33 2",1},
["default:steel_ingot"] = {4, "basic_machines:iron_dust_33 2",1},
["default:steel_ingot"] = {4, "basic_machines:iron_dust_00 2",1},
["moreores:silver_lump"] = {5, "basic_machines:silver_dust_33 2",1},
["default:gold_ingot"] = {6, "basic_machines:gold_dust_33 2", 1},
["default:copper_ingot"] = {4, "basic_machines:copper_dust_33 2",1},
["default:gold_lump"] = {6, "basic_machines:gold_dust_33 2", 1},
["default:iron_lump"] = {4, "basic_machines:iron_dust_33 2",1},
["default:copper_lump"] = {4, "basic_machines:copper_dust_33 2",1},
["default:gold_ingot"] = {6, "basic_machines:gold_dust_00 2", 1},
["default:copper_ingot"] = {4, "basic_machines:copper_dust_00 2",1},
["default:gold_lump"] = {6, "basic_machines:gold_dust_00 2", 1},
["default:iron_lump"] = {4, "basic_machines:iron_dust_00 2",1},
["default:copper_lump"] = {4, "basic_machines:copper_dust_00 2",1},
},
compressor_recipes = { --[in] ={fuel cost, out, quantity of material required for processing}

View File

@ -217,29 +217,6 @@ function getSandboxEnv (name)
return commands.display_text(obj,text,linesize,size)
end,
sound = function(sample,volume, pos)
if pos then
return minetest.sound_play( sample,
{
pos = pos,
gain = volume or 1,
max_hear_distance = 32, -- default, uses an euclidean metric
})
end
local obj = basic_robot.data[name].obj;
return minetest.sound_play( sample,
{
object = obj,
gain = volume or 1,
max_hear_distance = 32, -- default, uses an euclidean metric
})
end,
sound_stop = function(handle)
minetest.sound_stop(handle)
end,
},
machine = {-- adds technic like functionality to robots: power generation, smelting, grinding, compressing
@ -478,7 +455,9 @@ function getSandboxEnv (name)
if authlevel>=1 then -- robot privs
env.self.sound = minetest.sound_play
env.self.sound_stop = minetest.sound_stop
env.table = {
concat = table.concat,
insert = table.insert,

View File

@ -20,7 +20,7 @@ if not init then
"SOKOBAN 3D. RULES:\n1. pushable blocks: white,gray,yellow. you can not push block if another block is on top of it,\n2. elevator block: yellow - can push other blocks on top of it,"..
"\n3. if block falls it breaks, unless it falls less than 1 deep onto green block\n"..
"4. if you push block into blue it dissapears\n"..
"5. you can only push block by standing in front of it, not too low below it or too high above it\n"..
"5. you can only push block by standing close in front of it, not too low below it or too high above it\n"..
"LEVEL 1: push white block on top of red block")
pushables = {[1] = true,[2] = true,[6] = true} -- button types: white,gray, yellow

View File

@ -0,0 +1,91 @@
-- ACTIVITY GENERATOR + modified /status
-- makes server appear more active: virtual players join/leave, talk
if not init then
minetest.forceload_block(self.pos(),true)
self.label("activity generator")
local chatc = _G.core.registered_chatcommands["status"];
if chatc then
if not rom.chatc then rom.chatc = chatc end
--self.label(serialize(chatc))
hidden_players = {
rnd = false,
}
extra_players = {
"Piojoblanco","Bryan0911","EmmaBTS","atmaca","pausc05","bobo","marquez","Maike-008","odiseu","jere700182","_z","erick07","elvergalarga01","follow","Mantano10","AW","0987654321","lavraimeriem","formless","kanekii","cuchita","X_Pro_X","Tron","MGPe","Budrow42","lahina","shaahin18","dolphin","Stickman301","Galves58","Appelbaum747jdjxi","agy","E23","Utsler26","Rafael_Aaron_PROOO","cloe","Athans82","Love_Girl","jklu","Marne485hv","xXNicoXx","Dootson22","squad","fatima","Cucuzza62"
}
extra_joined = {};
greetings = {"hi","hello","pls help","help","how to play?", "i have only 2 blocks?","cool",":(","someone help","HI"}
_G.core.registered_chatcommands["status"] =
{
description = "Print server status",
func = function(name, param)
local connected = minetest.get_connected_players();
local ret = {};
for i = 1,#connected do
local pname = connected[i]:get_player_name();
if not hidden_players[pname] then ret[#ret+1] = pname end
end
local clients = table.concat(ret,", ");
local extras = {};
for name,_ in pairs(extra_joined) do extras[#extras+1] = name end
if #extras>0 then clients = clients ..", " .. table.concat(extras, ", ") end
return true, "# Server: version=0.4.17.1, uptime = ".. math.floor(minetest.get_server_uptime()*10)/10 ..", max_lag = 0.1, clients = {".. clients .. "}"
end,
}
--_G.core.registered_chatcommands["status"] = rom.chatc -- uncomment this to restore
end
t=0
init = true
end
t=t+1;
if t%5 == 0 then
local r = math.random(10)
if r <= 2 then -- add random new player
--say(t)
local idx = math.random(#extra_players)
local pname = extra_players[idx];
if pname and not extra_joined[pname] then
extra_joined[pname] = true
minetest.chat_send_all("*** " .. pname .. " joined the game.")
end
elseif r<=4 then -- disconnect random extra
local count = 0;
for pname,_ in pairs(extra_joined) do count = count + 1 end
local idx = math.random(count)
count = 0;
for pname,_ in pairs(extra_joined) do
count = count + 1
if count == idx then
minetest.chat_send_all("*** " .. pname .. " left the game.")
extra_joined[pname] = nil
break
end
end
elseif r<=6 then -- chat
if math.random(5) == 1 then
local count = 0
for pname,_ in pairs(extra_joined) do count = count + 1 end
local idx = math.random(count)
count = 0;
for pname,_ in pairs(extra_joined) do
count = count + 1
if count == idx then
r = math.random(#greetings);
minetest.chat_send_all("<" .. pname .. "> " ..greetings[r])
break
end
end
end
end
end
--self.remove()

View File

@ -0,0 +1,16 @@
compact_inventory = function(item)
local size = 32
local count = 0
for i = 1,size do
local stringname = check_inventory.self("","main",i);
local itemname, j = stringname:match("(%S+) (%d+)")
if itemname == item then
count = count + tonumber(j)
end
end
say(string.format("total count of %s is %s",item,count))
insert.forward(string.format("%s %s",item,count)) -- will join all items together
end

View File

@ -171,6 +171,7 @@ if not init then
local res = {}; -- list of boxes
local air_id = xxx
for x=1,dx do
boxdata[x] = {}
for y = 1,dy do

View File

@ -0,0 +1,89 @@
-- digital money: transform items into key (stand on chest and write \buy) and later get them back (\sell code)
--[[
instructions: put items in chest, stand on top of it and say: \buy. this gives you code, you can later write in
'\sell code' and get stuff back.
--]]
if not init then
self.label("digital banker bot")
password = "super secret password"
buydb = {};
starttime = minetest.get_gametime()
_G.minetest.forceload_block(self.pos(),true)
import_inventory = function(pos) -- read inventory and output digital money
local meta = minetest.get_meta(pos); if not meta then return end
local inv = meta:get_inventory(); if not inv then return end
if not inv:get_size("main") then return end
if inv:is_empty("main") then return end
local invlist = {};
for i = 1, inv:get_size("main") do
local stack = inv:get_stack("main", i):to_string();
local i = string.find(stack, " ");
local itemname = stack;
local count = 0;
if i then
itemname = string.sub(stack,1,i-1)
count = count + (tonumber(string.sub(stack,i+1)) or 1)
end
if count == 0 then count = 1 end
if itemname ~= "" then invlist[itemname] = (invlist[itemname] or 0) + count end
end
local t = minetest.get_gametime()
local out = string.sub(serialize(invlist),7)
inv:set_list("main",{})
return minetest.get_password_hash("",t .. out .. password) .. " " .. t .. " " .. out
end
export_inventory = function(speaker,msg) -- import digital money and give items
local i1 = string.find(msg," "); if not i1 then return end
local i2 = string.find(msg," ",i1+1); if not i2 then return end
local sig = string.sub(msg,1,i1-1);
local t = tonumber(string.sub(msg,i1+1,i2-1)) or 0;
local out = string.sub(msg,i2+1);
local sigm = minetest.get_password_hash("",t .. out .. password);
if sigm~=sig then return end
if t< starttime then return end -- invalid time, before bot start
if buydb[t] then -- already used, prevent double spending
return
else
buydb[t] = true;
end
local p = minetest.get_player_by_name(speaker);
local inv = p:get_inventory();
local invlist = deserialize("return " ..out);
for item, count in pairs(invlist) do
inv:add_item("main", item .. (count==1 and "" or " " .. count))
end
end
round = function(x) if x>0 then return math.floor(x+0.5) else return -math.floor(-x+0.5) end end
init = true
self.listen(1)
end
speaker,msg = self.listen_msg()
if msg then
if msg == "buy" then
local pos = minetest.get_player_by_name(speaker):getpos();
pos.x = round(pos.x);pos.y = round(pos.y);pos.z = round(pos.z)
if pos.y>0 then pos.y = pos.y-1 end
local out = import_inventory(pos);
if out then
local text = "Your code is between BEGIN and END:\nBEGIN\n" .. out.."\nEND\nSave it for future use, to reclaim items say: /sell code. code is valid until next restart."
local form = "size[8,8]".. "textarea[0.,0;11.,9.5;text;digital money;".. minetest.formspec_escape(text) .. "]"
self.show_form(speaker, form)
end
elseif string.sub(msg,1,4) == "sell" then
export_inventory(speaker,string.sub(msg,6))
end
end

View File

@ -0,0 +1,40 @@
--TODO: unfinished
if not init then
state = 0
init = true
walkdb = {};
spos = self.spawnpos();
step = 0
startstep = 0; -- mark the step when next walk around begins
local get_dir = function()
local dir = self.viewdir()
end
rot_left = function(dir) local tmp = dir.x;dir.x = -dir.z; dir.z = tmp end
rot_right = function(dir) local tmp = dir.x;dir.x = dir.z; dir.z = -tmp end
end
if state == 0 then
if not move.forward() then state = 1; turn.right(); startstep = 1 end
elseif state == 1 then
step = step + 1
local pos = self.pos();
local x = pos.x-spos.x; local z = pos.z-spos.z;
if not walkdb[x] then walkdb[x] = {} end walkdb[x][z] = step; -- add position
local dir = self.viewdir();
local node = read_node.left();
rot_left(dir) -- rotate left
local xr = x + dir.x; local zr = z + dir.z
if node == "air" and (not dir[xr] or not dir[xr][zr]) then turn.left() end
if not move.forward() and (not dir[xn] or not dir[xn][zn]) then turn.right() move.forward() end
end
self.label(state)

View File

@ -0,0 +1,46 @@
-- simple turtlebot with loops, rnd, 30 mins
if not init then
init = true
commands = {
["f"] = function() move.forward() end,
["l"] = function() move.left() end,
["r"] = function() move.right() end,
["u"] = function() move.up() end,
["d"] = function() move.down() end,
[">"] = function() turn.right() end,
["<"] = function() turn.left() end,
["p"] = function() place.down("default:dirt") end,
["P"] = function() place.forward_down("default:dirt") end,
}
program = "R3[Pfu]<"
loop = {start = 1, quit = 1, count = 1};
step = 1
end
c = string.sub(program,step,step)
if c == "R" then -- loop
local i = string.find(program,"%[",step+1);
loop.count = tonumber(string.sub(program,step+1, i-1)) or 1;
loop.start = i+1;
i = string.find(program,"]",i+1);
loop.quit = i-1
step = loop.start-1
else -- normal command
command = commands[c];
if command then
command()
elseif step>string.len(program) then
step = 0
end
end
self.label(step)
step = step +1
if loop.count>0 then -- are we in loop?
if step>loop.quit then loop.count = loop.count - 1; step = loop.start end
if loop.count == 0 then step = loop.quit + 2 end
end

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

18
basic_shop/README Normal file
View File

@ -0,0 +1,18 @@
BASIC_SHOP - 'online shopping' for minetest 0.4.17+
(c) 2018 rnd
gui design by Jozet (2018)
---------------------------------------------------------------------
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
----------------------------------------------------------------------

491
basic_shop/init.lua Normal file
View File

@ -0,0 +1,491 @@
--[[
basic_shop by rnd, gui design by Jozet, 2018
TODO:
buying: /shop opens gui OK
gui basics OK
filter OK
buy button action OK
sorting
selling: /sell price adds items in hand to shop OK
--]]
modname = "basic_shop";
basic_shop = {};
basic_shop.data = {}; -- {"item name", quantity, price, time_left, seller, minimal sell quantity}
basic_shop.guidata = {}; -- [name] = {idx = idx, filter = filter, sort = sort } (start index on cur. page, filter item name, sort_coloumn)
basic_shop.bank = {}; -- bank for offline players, [name] = {balance, deposit_time},
basic_shop.items_on_page = 8
basic_shop.maxprice = 1000000
basic_shop.time_left = 60*60*24*7; -- 1 week before shop removed/bank account reset
local filepath = minetest.get_worldpath()..'/' .. modname;
minetest.mkdir(filepath) -- create if non existent
save_shops = function()
local file,err = io.open(filepath..'/shops', 'wb');
if err then minetest.log("#basic_shop: error cant save data") return end
file:write(minetest.serialize(basic_shop.data));file:close()
end
local player_shops = {}; --[name] = count
load_shops = function()
local file,err = io.open(filepath..'/shops', 'rb')
if err then minetest.log("#basic_shop: error cant load data") return end
local told = minetest.get_gametime() - basic_shop.time_left;
local data = minetest.deserialize(file:read("*a")) or {};file:close()
local out = {}
for i = 1,#data do
if data[i][4]>told then -- not too old
out[#out+1] = data[i]
player_shops[data[i][5]] = (player_shops[data[i][5]] or 0) + 1 -- how many shops player has
end
end
basic_shop.data = out
end
local toplist = {};
load_bank = function()
local file,err = io.open(filepath..'/bank', 'rb')
if err then minetest.log("#basic_shop: error cant load bank data"); return end
local data = minetest.deserialize(file:read("*a")) or {}; file:close()
local out = {};
local told = minetest.get_gametime() - basic_shop.time_left;
for k,v in pairs(data) do
if k~="_top" then
if v[2]>told then out[k] = v end
else
out[k] = v
end
end
basic_shop.bank = out
if not basic_shop.bank["_top"] then
basic_shop.bank["_top"] = {["_min"] = ""} -- [name] = balance
end
toplist = basic_shop.bank["_top"];
end
local check_toplist = function(name,balance) -- too small to be on toplist -- attempt to insert possible toplist balance
local mink = toplist["_min"]; -- minimal element on the list
local minb = toplist[mink] or 0; -- minimal value
if balance<minb then
if toplist[name] then toplist["_min"] = name; toplist[name] = balance end
return -- too small to be on toplist
end
local n = 0; for k,v in pairs(toplist) do n = n + 1 end
local list = {};
toplist[name] = balance
if n+1>10 then toplist[mink] = nil end --remove minimal
--more than 10, have to throw out smallest one
minb = 10^9; mink = "" -- find new minimal element
for k,v in pairs(toplist) do
if k~="_min" and v<minb then mink = k minb = v end
end
toplist["_min"] = mink
end
local display_toplist = function()
local out = {};
for k,v in pairs(toplist) do
if k ~= "_min" then
out[#out+1] = {k,v}
end
end
table.sort(out, function(a,b) return a[2]>b[2] end)
local ret = {"TOP RICHEST"};
for i = 1,#out do
ret[#ret+1] = i .. ". " .. out[i][1] .. " " .. out[i][2]
end
minetest.chat_send_all(table.concat(ret,"\n"))
end
save_bank = function()
local file,err = io.open(filepath..'/bank', 'wb');
if err then minetest.log("#basic_shop: error cant save bank data") return end
file:write(minetest.serialize(basic_shop.bank)); file:close()
end
minetest.after(0, function() -- problem: before minetest.get_gametime() is nil
load_shops()
load_bank()
end)
minetest.register_on_shutdown(function()
save_bank()
save_shops()
end)
get_money = function(player)
local inv = player:get_inventory();
local stack = inv:get_stack(modname,1);
if not stack then return 0 end
return tonumber(stack:to_string()) or 0
end
set_money = function(player, amount)
local inv = player:get_inventory();
if inv:get_size(modname)<1 then inv:set_size(modname, 2) end
inv:set_stack(modname, 1, ItemStack(amount))
check_toplist(player:get_player_name(),amount)
end
init_guidata = function(name)
--[name] = {idx = idx, filter = filter, sort = sort } (start index on cur. page, filter item name, sort_coloumn)
basic_shop.guidata[name] = {idx = 1, filter = "",sort = 0, count = #basic_shop.data};
end
basic_shop.show_shop_gui = function(name)
local guidata = basic_shop.guidata[name];
if not guidata then init_guidata(name); guidata = basic_shop.guidata[name]; end
local idx = guidata.idx;
local sort = guidata.sort;
local filter = guidata.filter;
local data = basic_shop.data; -- whole list of items for sale
local idxdata = {}; -- list of idx of items for sale
if filter == "" then
for i = 1,#data do idxdata[i] = i end
else
for i = 1,#data do
if string.find(data[i][1],filter) then
idxdata[#idxdata+1] = i
end
end
end
if guidata.sort>0 then
if guidata.sort == 1 then -- sort price increasing
local sortf = function(a,b) return data[a][3]<data[b][3] end
table.sort(idxdata,sortf)
elseif guidata.sort == 2 then
local sortf = function(a,b) return data[a][3]>data[b][3] end
table.sort(idxdata,sortf)
end
end
local m = basic_shop.items_on_page; -- default 8 items per page
local n = #idxdata; -- how many items in current selection
local form = "size[10,8]".. -- width, height
"bgcolor[#222222cc; true]" ..
"background[0,0;8,8;gui_formbg.png;true]" ..
"label[0.4,-0.1;".. minetest.colorize("#6f6e6e", "Basic ") .. minetest.colorize("#6f6e6e", "Shop") .. "]" ..
"label[5,-0.1;" .. minetest.colorize("#aaa", "Your money: ".. get_money(minetest.get_player_by_name(name)) .. " $, shops ".. (player_shops[name] or 0)) .. "]" ..
"label[0.4,0.7;" .. minetest.colorize("#aaa", "item") .. "]" ..
--"label[3,0.7;" .. minetest.colorize("#aaa", "price") .. "]" ..
"button[3,0.7;1,0.5;price;" .. minetest.colorize("#aaa", "price") .. "]" ..
"label[5,0.7;" .. minetest.colorize("#aaa", "time left") .. "]" ..
"label[6.5,0.7;" .. minetest.colorize("#aaa", "seller") .. "]" ..
"box[0.35,-0.1;9.05,0.65;#111]".."box[5,-0.1;4.4,0.65;#111]"..
"box[0.35,7.2;9.05,0.15;#111]" .. -- horizontal lines
"field[0.65,7.9;2,0.5;search;;".. guidata.filter .."] button[2.5,7.6;1.5,0.5;filter;refresh]"..
"button[6.6,7.6;1,0.5;left;<] button[8.6,7.6;1,0.5;right;>]" ..
"label[7.6,7.6; " .. math.floor(idx/m)+1 .." / " .. math.floor(n/m)+1 .."]";
local tabdata = {};
local idxhigh = math.min(idx + m,n);
local t = basic_shop.time_left-minetest.get_gametime();
for i = idx, idxhigh do
local id = idxdata[i];
local y = 1.3+(i-idx)*0.65
local ti = tonumber(data[id][4]) or 0;
ti = (t+ti)/60; -- time left in minutes: time_left - (t-ti) = time_left-t + ti
if ti<0 then ti = 0 end
local time_left = ""
if ti<60 then
time_left = math.floor(ti*10)/10 .. "m"
elseif ti< 1440 then
time_left = math.floor(ti/60*10)/10 .. "h"
else
time_left = math.floor(ti/1440*10)/10 .. "d"
end
tabdata[i-idx+1] =
"item_image[0.4,".. y-0.1 .. ";0.7,0.7;".. data[id][1] .. "]" .. -- image
"label[1.1,".. y .. ";x ".. data[id][2] .. "/" .. data[id][6] .. "]" .. -- total_quantity
"label[3,".. y .. ";" .. minetest.colorize("#00ff36", data[id][3].." $") .."]" .. -- price
"label[5,".. y ..";" .. time_left .."]" .. -- time left
"label[6.5," .. y .. ";" .. minetest.colorize("#EE0", data[id][5]) .."]" .. -- seller
"image_button[8.5," .. y .. ";1.25,0.7;wool_black.png;buy".. id ..";buy ".. id .."]" -- buy button
.."tooltip[buy".. id ..";".. data[id][1] .. "]"
end
minetest.show_formspec(name, "basic_shop", form .. table.concat(tabdata,""))
end
local dout = minetest.chat_send_all;
local make_table_copy = function(tab)
local out = {};
for i = 1,#tab do out[i] = tab[i] end
return out
end
minetest.register_on_player_receive_fields(
function(player, formname, fields)
local name = player:get_player_name()
if not basic_shop.guidata[name] then init_guidata(name) end
if fields.left then
local guidata = basic_shop.guidata[name]
local idx = guidata.idx;
local n = guidata.count;
local m = basic_shop.items_on_page;
idx = idx - m-1;
if idx<0 then idx = math.max(n - m,0)+1 end
guidata.idx = idx;
basic_shop.show_shop_gui(name)
return
elseif fields.right then
local guidata = basic_shop.guidata[name]
local idx = guidata.idx;
local n = guidata.count;
local m = basic_shop.items_on_page;
idx = idx + m+1;
if idx>n then idx = 1 end
guidata.idx = idx;
basic_shop.show_shop_gui(name)
return
elseif fields.filter then
local guidata = basic_shop.guidata[name]
guidata.filter = tostring(fields.search or "") or ""
if guidata.filter == "" then guidata.count = #basic_shop.data end
guidata.idx = 1
basic_shop.show_shop_gui(name)
elseif fields.price then -- change sorting
local guidata = basic_shop.guidata[name]
guidata.sort = (guidata.sort+1)%3 --0,1,2
basic_shop.show_shop_gui(name)
return
end
for k,v in pairs(fields) do
if string.sub(k,1,3) == "buy" then
local sel = tonumber(string.sub(v,5));
if not sel then return end
local shop_item = basic_shop.data[sel];
if not shop_item then return end
local balance = get_money(player);
local price = shop_item[3];
local seller = shop_item[5]
if seller ~= name then -- owner buys for free
if balance<price then
minetest.chat_send_player(name,"#basic_shop : you need " .. price .. " money to buy item " .. sel .. ", you only have " .. balance)
return
end
balance = balance - price;set_money(player,balance) -- change balance for buyer
local splayer = minetest.get_player_by_name(seller);
if splayer then
set_money(splayer, get_money(splayer) + price)
else
-- player offline, add to bank instead
local bank_account = basic_shop.bank[seller] or {}; -- {deposit time, value}
local bank_balance = bank_account[1] or 0;
basic_shop.bank[seller] = {bank_balance + price, minetest.get_gametime()} -- balance, time of deposit.
end
end
local inv = player:get_inventory();
inv:add_item("main",shop_item[1] .. " " .. shop_item[2]);
-- remove item from shop
shop_item[6] = shop_item[6] - shop_item[2];
shop_item[4] = minetest.get_gametime() -- time refresh
if shop_item[6]<=0 then --remove shop
player_shops[seller] = (player_shops[seller] or 1) - 1;
local data = {};
-- expensive, but ok for 'small'<1000 number of shops
for i = 1,sel-1 do data[i] = make_table_copy(basic_shop.data[i]) end
for i = sel+1,#basic_shop.data do data[i-1] = make_table_copy(basic_shop.data[i]) end
basic_shop.data = data;
end
minetest.chat_send_player(name,"#basic_shop : you bought " .. shop_item[1] .." x " .. shop_item[2] .. ", price " .. price .." $")
basic_shop.show_shop_gui(name)
end
end
end
)
minetest.register_on_joinplayer( -- if player has money from bank, give him the money
function(player)
local name = player:get_player_name();
local bank_account = basic_shop.bank[name] or {}; -- {deposit time, value}
local bank_balance = bank_account[1] or 0;
if bank_balance>0 then
local balance = get_money(player) + bank_balance;
set_money(player,balance)
basic_shop.bank[name] = nil
minetest.chat_send_player(name,"#basic_shop: you get " .. bank_balance .. "$ from shops, new balance " .. balance .. "$ ")
end
end
)
local ts = 0
minetest.register_globalstep(function(dtime) -- time based income
ts = ts + dtime
if ts<720 then return end-- 720 = 12*60
ts = 0
local players = minetest.get_connected_players()
for i = 1,#players do
local balance = get_money(players[i]);
if balance<100 then -- above 100 no pay
set_money(players[i],balance+1) -- 5 money/hr
end
end
end)
-- CHATCOMMANDS
minetest.register_chatcommand("shop", { -- display shop browser
description = "",
privs = {
privs = interact
},
func = function(name, param)
basic_shop.show_shop_gui(name)
end
});
minetest.register_chatcommand("shop_top", {
description = "",
privs = {
privs = interact
},
func = function(name, param)
display_toplist()
end
});
minetest.register_chatcommand("sell", {
description = "",
privs = {
privs = interact
},
func = function(name, param)
local words = {};
for word in param:gmatch("%S+") do words[#words+1]=word end
local price, count, total_count
if #words == 0 then
minetest.chat_send_player(name,"#basic_shop: /sell price, where price must be between 0 and " .. basic_shop.maxprice .."\nadvanced: /sell price count total_sell_count")
return
end
price = tonumber(words[1]) or 0
if price<0 or price>basic_shop.maxprice then
minetest.chat_send_player(name,"#basic_shop: /sell price, where price must be between 0 and " .. basic_shop.maxprice .."\nadvanced: /sell price count total_sell_count")
return
end
count = tonumber(words[2])
total_count = tonumber(words[3])
local player = minetest.get_player_by_name(name); if not player then return end
local stack = player:get_wielded_item()
local itemname = stack:get_name();
if not count then count = stack:get_count() else count = tonumber(count) or 1 end
if count<1 then count = 1 end
if not total_count then total_count = count else total_count = tonumber(total_count) or count end
if total_count<count then total_count = count end;
if itemname == "" then return end
local shop_count = (player_shops[name] or 0)+1;
local balance = get_money(player);
local allow = true
if balance < 5 then -- new player
minetest.chat_send_player(name,"#basic_shop: you need at least 5$ to sell items")
return
elseif balance<100 then -- noob
if shop_count>1 then allow = false end
elseif balance<1000 then -- medium
if shop_count>5 then allow = false end
else -- pro
if shop_count>25 then allow = false end
end
if not allow then
minetest.chat_send_player(name,"#basic_shop: you need more money if you want more shops (100 for 5, 1000+ for 25).")
return
end
if stack:get_wear()>0 then
minetest.chat_send_player(name,"#basic_shop: you can't sell used tools/weapons")
return
end
local sstack = ItemStack(itemname.. " " .. total_count);
if not player:get_inventory():contains_item("main", sstack) then
minetest.chat_send_player(name,"#basic_shop: you need at least " .. total_count .. " of " .. itemname)
return
end
player_shops[name] = shop_count;
player:get_inventory():remove_item("main", sstack)
local data = basic_shop.data;
--{"item name", quantity, price, time_left, seller}
data[#data+1 ] = { itemname, count, price, minetest.get_gametime(), name, total_count};
minetest.chat_send_player(name,"#basic_shop : " .. itemname .. " x " .. count .."/"..total_count .." put on sale for the price " .. price .. ". To remove item simply go /shop and buy it (for free).")
end
})
minetest.register_chatcommand("shop_money", {
description = "",
privs = {
privs = interact
},
func = function(name, param)
if not param or param == "" then param = name end
local player = minetest.get_player_by_name(param)
if not player then return end
minetest.chat_send_player(name,"#basic_shop: " .. param .. " has " .. get_money(player) .. " money.")
end
})
minetest.register_chatcommand("shop_set_money", {
description = "",
privs = {
privs = kick
},
func = function(name, param)
local pname, amount
pname,amount = string.match(param,"(%a+) (%d+)");
if not pname or not amount then minetest.chat_send_player(name,"usage: shop_set_money NAME AMOUNT") return end
amount = tonumber(amount) or 0;
local player = minetest.get_player_by_name(pname); if not player then return end
set_money(player,amount)
minetest.chat_send_player(name,"#basic_shop: " .. param .. " now has " .. amount .. " money.")
end
})

Binary file not shown.

Before

Width:  |  Height:  |  Size: 776 B

After

Width:  |  Height:  |  Size: 785 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 483 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 487 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 461 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 698 B

View File

@ -126,46 +126,26 @@ minetest.register_craft({
minetest.register_craft({
output = 'default:stone_with_iron 2',
recipe = {
{'skyblock:iron_extractor'},
{'basic_machines:iron_extractor'},
{'default:stone'},
}
})
minetest.register_craft({
output = 'skyblock:iron_extractor',
recipe = {
{'default:leaves','default:leaves','default:iron_lump'},
}
})
-- stone_with_copper
minetest.register_craft({
output = 'default:stone_with_copper 2',
recipe = {
{'skyblock:copper_extractor'},
{'basic_machines:copper_extractor'},
{'default:stone'},
}
})
minetest.register_craft({
output = 'skyblock:copper_extractor',
recipe = {
{'default:papyrus','default:papyrus','default:copper_lump'},
}
})
minetest.register_craft({
output = 'skyblock:tin_extractor',
recipe = {
{'farming:cocoa_beans','farming:cocoa_beans','default:tin_lump'},
}
})
minetest.register_craft({
output = 'default:stone_with_tin 2',
recipe = {
{'skyblock:tin_extractor'},
{'basic_machines:tin_extractor'},
{'default:stone'},
}
})
@ -175,78 +155,67 @@ minetest.register_craft({
minetest.register_craft({
output = 'default:stone_with_gold 2',
recipe = {
{'skyblock:gold_extractor'},
{'basic_machines:gold_extractor'},
{'default:stone'},
}
})
minetest.register_craft({
output = 'skyblock:gold_extractor',
recipe = {
{'skyblock:tin_extractor','skyblock:copper_extractor','default:gold_lump'},
}
})
-- stone_with_mese
minetest.register_craft({
output = 'default:stone_with_mese 2',
recipe = {
{'skyblock:mese_extractor'},
{'basic_machines:mese_extractor'},
{'default:stone'},
}
})
minetest.register_craft({
output = 'skyblock:mese_extractor',
recipe = {
{'farming:rhubarb','farming:rhubarb','default:mese_crystal'},
}
})
-- stone_with_diamond
minetest.register_craft({
output = 'default:stone_with_diamond 2',
recipe = {
{'skyblock:diamond_extractor'},
{'basic_machines:diamond_extractor'},
{'default:stone'},
}
})
minetest.register_craft({
output = 'skyblock:diamond_extractor',
output = 'basic_machines:iron_extractor',
recipe = {
{'farming:wheat','farming:cotton','default:diamond'},
{'default:leaves','default:leaves','default:iron_lump'},
}
})
minetest.register_craft({
output = 'basic_machines:copper_extractor',
recipe = {
{'default:papyrus','default:papyrus','default:copper_lump'},
}
})
-- ORE EXTRACTORS
minetest.register_craft({
output = 'basic_machines:tin_extractor',
recipe = {
{'farming:cocoa_beans','farming:cocoa_beans','default:tin_lump'},
}
})
minetest.register_craft({
output = 'basic_machines:gold_extractor',
recipe = {
{'basic_machines:tin_extractor','basic_machines:copper_extractor','default:gold_lump'},
}
})
local function register_extractor(name,R,G,B)
if not R then R = "FF" end
if not G then G = "FF" end
if not B then B = "FF" end
minetest.register_craftitem("skyblock:"..name.."_extractor", {
description = "chemical used in extraction of " .. name ,
inventory_image = "ore_extractor.png^[colorize:#"..R..G..B..":180",
})
end
register_extractor("iron","99","99","99")
register_extractor("copper","C8","80","0D")
register_extractor("tin","C8","9F","9F")
register_extractor("gold","FF","FF","00")
register_extractor("mese","CC","CC","00")
register_extractor("diamond","00","EE","FF")
register_extractor("mithril","00","00","FF")
minetest.register_craft({
output = 'basic_machines:mese_extractor',
recipe = {
{'farming:rhubarb','farming:rhubarb','default:mese_crystal'},
}
})
-- VARIOUS SKYBLOCK CRAFTS