Server/TechWelt/RobotWorld: Difference between revisions
>Hajo (→Brickmaker: chest-renewer) |
>Hajo (→Brickmaker: chest-renewer) |
Latest revision as of 14:18, 10 February 2018
This is part of TechWelt, a server showing technical mods for educational purposes.
Robots & Machines
- Basic_robots - a mod about programmable robots that can do almost everything.
- Basic_machines - a mod for automation and production.
The main focus here is on basic_robots, using only a few of the machine-parts (mostly the keypad).
Robots can also generate power and craft items,
so almost everything machines can do,
can be done with robots too.
- Activating a robot is the main exception,
- we need the keypad, clock-generator and detector for that.
Other players can look at the code inside a robot
(as opposed to machines, where the settings are only visible to the owner),
so it is easier to understand how a robot works.
- It is also possible to hide the code, but that requires extra effort.
Robots-Intro
The basic-robots use the concept of a spawner + worker.
The spawner is a block that needs to be put on the ground before using,
much like a chest.
The spawner contains the robot's inventory and the source-code,
as well as buttons (START, STOP, SAVE, STORAGE, etc.)
When started, a worker-robot is created ('spawned') on the spot above the spawner.
This worker executes the instructions of the code
and can move around, dig, build etc.
It disappears when the program ends.
- Programs that don't need to move, can run without the worker,
- eg. programs that only listen+talk via chat.
Robot standalone
To get a robot, enter the chat-command:
- /giveme basic_robot:spawner
To use, set this robot-spawner on the ground.
- You cannot do this if the area is owned by someone else.
To activate the robot, rightclick the spawner, and press the START-button.
Now the robot-worker will appear on top of the spawner,
but it will do nothing because there is no program, yet.
Rightclick the spawner again, and press the STOP-button.
Enter a short program into the edit-area, such as
turn.left()
Then press the SAVE-button,
and the START-button again.
The robot-worker should appear again, and turn around.
Other buttons inside the robot:
- Storage - opens the robot's inventory (same size as a chest)
- picking up the robot-spawner is not possible with items in the inventory.
- Library - opens the robot's library (same size as a bookshelf)
- The robot can read & write books here, eg. with text and/or code.
- By specifying a library-position, the robot can use the library of another robot.
- Help - shows a page with the available commands.
...
Robot with remote
Without programming, a robot can be used with a remotecontrol.
How to get, via chat-commands:
- /giveme basic_robot:spawner
- /giveme basic_robot:control
To use, set the robot-spawner on the ground,
and put the remote on the hotbar.
To activate the robot, rightclick the spawner, and press the START-button.
The remote has two modes, "buttons" and "edit",
that can be accessed by rightclick and leftclick onto empty space.
The buttons of the button-mode allows the robot to move around, and dig.
The edit-mode shows a small input-field for setting the id,
a bigger input-field for entering a (short) program, and a SAVE-button.
id: You can have several remotes on the hotbar, each controlling a different robot.
- Without the robot-priv, you can only run two robots at the same time.
edit: enter a short program, such as
say("Hi")
Then press the SAVE-button.
When the robot is active, the program in the edit-field is executed by the robot with a leftclick.
- While the edit-field has text in it, the button-mode cannot be used.
Machines-Intro
Basic_machines - a mod for automation and production.
It is possible to build an automated Factory that produces diamonds,
or any other item that can be crafted.
Constructor
This is like a special crafting-table,
used to create all the other basic_machines.
How to use
- Place it on the ground,
- Open it with rightclick,
- Select the type of machine you want --> it shows the needed materials
- Put in the needed materials (eg. a wooden plank and a stick)
- Press the CRAFT-button
- Take out your new machine (eg. a keypad)
Machines:
- Light - a block that gives light, can be turned on and off
- Keypad - a big button, that sends signals to turn machines on & off
- and can do much more (see next chapter)
- Detector - can detect light, players, blocks, etc.
- it can then send a signal to activate machines, open doors, etc.
- Distributor - sends an input-signal to several other machines (up to 10 spaces away)
- As opposed to mesecons, there are no wires - just a table of coordinates
- clock-generator - periodically activates the device on top, every 5 seconds.
- eg. to keep a furnace running.
- Generator - generates powercells, that can be used as fuel
- with upgrades, it can produce the more powerful powerblocks and powerrods
- Battery - uses powercells to power other machines
- eg. a mover, a grinder or a furnace on top of the battery
- Mover - can move everything
- eg. it can move powercells from the generator to a battery,
- it can harvest trees and wheat, move stuff from chest into machines, etc.
- The mover can also act as a teleporter or elevator.
- Grinder - grind materials to dusts, which doubles the output when smelted.
- see Grinder recipes
- AutoCrafter - automated crafting. Set up a recipe, then fill in raw materials.
- Recycler - recyle machines (yields 75% of the building materials).
- Ball-spawner - spawn an energy ball that can activate stuff
- Environment - change physics settings (e.g. gravity) and the skybox
...
Lights & Keypad
The light is a simple block that gives light, and can be turned on and off (eg. with a keypad).
The keypad is a big button that can send a signal to another block.
It is very versatile, as it can be used to enter text, enter passwords,
write text on blocks (eg. on signs or chests), repeat a signal several times,
play sounds, etc.
In combination with robots, the main use of keypads is to allow other players to activate a robot.
- Normally, only the owner can start a robot.
...
Robot-Tutorial - Overview
## | Title | command introduced |
---|---|---|
01 | Hallo | say(), turn.DIR(), -- where DIR is one of left, right, angle |
02 | Hallo2 | self.remove(), var |
03 | robots-version | .. |
04 | more-output | self.label(), self.display_text(), if, \n |
05 | TimeDate | os.date(), write_text.DIR() where DIR is one of forward, backward, up, down, left, right, forward_down ... |
06 | Greeter | find_player() |
07 | look-around | read_node.DIR() |
08 | chest-inventory | for, check_inventory.DIR() check_inventory can also use the DIRection 'self', to look are the robot's inventory |
09 | furnace-feeder1 | take.DIR(), insert.DIR() |
10 | pickup() | self.display_text() |
11 | Teleporter | puzzle, find_player() |
12 | Keyboard-button-maker | keyboard.set() |
13 | dig | self.reset() |
14 | dig & place | function() |
15 | mini-farmer | function() |
16 | x | y |
- #16 - chat-listener / self.listen()
- #17 - Builder /
- #18 - Demolisher / {} table of functions
- #19 - move-demo / string.find()
- #20 - Color-Tower
- ...
Robot #01 - Hello
The robot outputs the text "Hallo" via chat, and turns on the spot.
This repeats until it is turned off,
or another robot with the same id is started.
-- #1 Hallo --
-- Programm wird jede Sekunde neu ausgefuehrt
-- daher wiederholt sich die Ausgabe, und Robot dreht sich.
say("Hallo")
turn.left()
- Text after -- is a comment, and is ignored.
- The command say() is for text-output (like 'print()' in other languages)
- turn.left() lets the robot-worker turn by 90 degree.
Robot #02 - Hello2
This program uses a string-variable for the output,
and adds a command to stop the execution.
-- #2 Hallo2 --
-- Programm wird jede Sekunde neu ausgefuehrt
msg="Hallo"
say(msg)
say("und Tschüss !")
self.remove() -- stop
-- aber hier ist gleich nach dem ersten Durchlauf Schluss
- The command self.remove() removes the worker, and stops the program.
- see also 'self.spam()', below
Robot #03 - robot-version
This shows the installed version of the basic_robots - mod.
-- #3 robot-version --
v=robot_version()
say("robot version="..v) -- .. verbindet strings
self.remove()
- robot_version() is a built-in function, that returns a string with the version-number.
- v is a variable, that gets assigned the result of the function robot_version().
- in lua, each variable can contain everything (number, text, table ...)
- '..' is an operation used to concatenate two strings.
Robot #04 - more output
This demonstrates some more ways a robot can show output.
-- #4 more-output --
if not i then i=0 -- nur einmal
turn.left() -- face to user
say("Hallo")
end
-- ab hier werden die Befehle wiederholt:
i=i+1
self.label(i) -- Anzeige in gruen, ueber dem Robot
if i==4 then
msg="ab jetzt vorn mit Text-\nAnzeige" -- \n : newline
--123456789+123456789+
say(msg)
self.display_text(msg,10,1) -- Text-Anzeige anstelle des 'Gesicht'
end
--if i>6 and i<15 then turn.right() end
if i>20 then
say("Stop")
self.remove()
end
- if -- compare values, then depending on the outcome, execute some code
- self.label(i) -- show that number i as a text floating above the robot
- self.display_text(msg,10,1) -- show the text from variable msg on the 'face' of the robot
- 10 is the lenght of each line on that display
- 1 is the size for the display - 1 is normal, 2 means 'double size'.
Robot #05 - TimeDate
Shows the current time and date, and writes text on other blocks.
-- #5 TimeDate --
self.label("TimeDate") -- program runs too short for this to be visible
td = os.date("%Y-%m-%d %H:%M:%S")
msg = "Time and date"
say(msg..": "..td)
ok=write_text.up(msg) -- label the button above the robot
ok=write_text.down("This robot was last run: "..td) -- write text on cpu-box
self.remove() -- stop program
To see the text written on the blocks, point at it with the crosshair (just like signs).
- os.date() -- call the operating-system, to return a number that represents the time & date
- the string inside the brackets specifies how you want to format that information,
- e.g. "YEAR-MONTH-DAY HOUR:MINUTE:SECOND"
- write_text.up() -- write text on the block above the robot
- write_text.down() -- write text on the block below the robot
Robot #06 - Greeter
This gets the names of all nearby player, and greets them via chat.
-- #6 Greeter --
if not pn then pn="Greeter"
p=find_player(5)
if p==nil then say("Hallo, niemand da?"); self.remove() end
n=#p; --say(n)
msg="Hi "
-- if p==nil then s="Hello !" else s="Hello "..p[1].." !" end
for i=1, n do
msg=msg..p[i].." "
end
msg=msg.."!"
say(msg)
end
--
self.remove()
- find_player(5) -- returns a table of playernames
- nil -- a special value for 'nothing'
- #p -- the length of the table p (= how many entries the table has)
- for i=1, n do -- a loop that runs for all values from 1 to n
- that is, once for every player that was detected
Robot #07 - look around
This robot turns around, looks at the surrounding blocks,
and outputs their names.
It also counts the (quarter-)turns and stops after 4 have been done.
-- #7 look around --
if not i then i=0 end
n=read_node.forward()
say(i..": "..n)
i=i+1
if i>=4 then self.remove() end
turn.left()
- say()
- read_node.forward()
Robot #08 - list chest-inventory
Lists the items in the first 5 slots of the chest.
- list only 5 items, so the chat-text doesn't scroll off
-- #8 list chest-inventory --
if not i then i=0
say("Inhalt der Kiste:") -- "Contents of chest:"
end
for i=1,5 do
m = check_inventory.forward("","main",i)
say(i..": "..m)
end
self.remove()
- check_inventory -- look at the "main"-inventory inside the block in front of the robot
- and return the name from the item contained in slot number i
- for i=1,5 do -- loop that repeats with i set to the values 1, 2, 3, 4, 5.
Robot #09 - furnace-feeder
The robot takes cobblestones and coal from the chest,
puts them into the furnace
and activates the furnace so it starts to burn.
A lump of coal burns long enough to turn 13 cobble into stone.
-- #9 furnace-feeder --
m="default:cobble 13"
ok = check_inventory.forward_down(m,"main")
if ok then
take.forward_down(m)
insert.backward(m,"src")
else
say("no "..m); self.remove()
end
m="default:coal_lump"
ok = check_inventory.forward_down(m,"main")
if ok then
take.forward_down(m)
insert.backward(m,"fuel")
else
say("no "..m); self.remove()
end
activate.backward(1)
say("Furnace activated")
self.remove()
- take.DIR()
- insert.DIR()
- activate.DIR()
- DIR
The furnace has 3 different inventories:
- src - "source" : for input-material (eg. cobble, ore, flour)
- dst - "destination" : for the output (eg. stone, ingots, etc.)
- fuel - for fuel (eg. wood, coal, etc.)
Robot #10 - Pickup
Collecting loose stuff, such as saplings that drop from trees,
or eggs dropped by chicken.
-- #10 pickup --
if not pn then pn="Pickup"
self.spam(1) -- allow more than 1 output via say()
p=0 -- counter
turn.left();
self.display_text(pn,10,1)
end
m=pickup(8) -- range 8, if successful returns a table of the items picked up
if m then
--say( serialize(m) ) -- easy way to output any datatype
for i=1,#m do
say( "picked up: "..m[i] )
end
p=p+1
end
self.label(p)
- self.spam() -- allow more than 1 output via say() to be seen by other players
- pickup() -- picks up 'loose items', eg. saplings that drop when harvesting a tree
- m -- the table returned by pickup()
- #m -- length of table m
- m[i] -- the element of the table m, at position i
- serialize(m) -- returns a representation of m, as a printable string
Robot #11 - Teleporter
Teleport a player.
This robot needs the puzzle-priv.
-- #11 Teleporter--
--puzzle.get_player('hajo'):move_to({x=-23,y=26,z=-990})
-- 1,2,33 Starter-Bay
-- 0,3,75 House
-- 4,26,-994 Robot&Machines
-- 1755,45,699 Mese-Welt
if not pn then pn="Teleporter"
p=find_player(4)
if p==nil then say("Come closer!"); self.remove()
else
n=p[1]; --say(n)
puzzle.get_player(n):move_to( {x=-23,y=26,z=-990} )
end
end
self.remove()
Short version:
puzzle.get_player('hajo'):move_to({x=-23,y=26,z=-990})
- pn -- short for program_name
- find_player(4) -- returns table of player-names within range 4
- p[1] -- first element of table p --> name of first player found within range
- puzzle.get_player(n):move_to() -- gets a handle to the player with name n, then moves /teleports him to the target-location
- {x=-23,y=26,z=-990} -- a table with elements x,y,z, designating the target-location.
Robot #12 - Buttonmaker1
Create a single keyboard-button.
See also robot #13.
-- #12 simple Buttonmaker--
-- make 1 button at the position of the robot-worker
p = self.pos();
c = 3 -- 1=white 2=grey 3=red 4=green 5=blue 6=yellow 7-16="0"-"9" 17=black
keyboard.set(p,c)
--
self.remove()
- self.pos() -- returns the position of the robot-worker
- At the start of the program, this is the space above the spawner
- keyboard.set(position,color) -- create a keyboard-button
- The position must be within range 10 of the spawner
Originally, these keyboard-buttons were designed as an input-device,
that the robot can monitor for keypresses.
But keyboard-buttons can also be used as a cheap building material.
Robot #13 - dig
Dig the keyboard-button created by robot #12, and puts it into the chest above the worker.
-- #13 dig--
move.forward()
ok=dig.forward()
if ok then say("ok") else say("fail") end
--say( serialize(ok) )
self.reset()
m = check_inventory.self("","main",1); -- say(m)
insert.up(m)
self.remove()
--
- dig.DIR() --
- self.reset() -- moves the worker back to its position when the program started
- check_inventory.self() -- check the robot's own inventory
- insert.DIR() -- put stuff into a container
Note: the robot can dig only one item per turn, and digging stone might also need energy.
Note: the robot can dig its own spawner, thereby destroying it. AVOID THIS !
Robot #14 - dig & place
This robot digs the block of cobblestone at one side,
and places the same block on the other side of the spawner.
This will not work with some types of blocks:
- stone - digging stone can be configured to require energy, and the robot has none, yet.
- clay - digging a block of clay turns it into 4 clay-lumps.
- liquids - the robot cannot dig water or lava.
- mobs - mobs are no blocks, but entities - so digging is not possible.
-- #14 --
-- !! Don't use stone, or clay for this demo !!
function t2() -- a simple function
turn.left(); turn.left();
end
if not i then i=0
say("dig & place")
end
n=read_node.forward(); say(n)
if n~="air" then
dig.forward()
t2()
place.forward(n)
end
i=i+1
t2()
if i>1 then
self.remove()
end
--
- ~= -- compare for 'not-equeal'
- comparison-operators are ==, ~=, <, >, <=, >=
- place.DIR(m) -- build a block of material m in direction DIR
- function t2() -- defines a function, here without parameters, and without return-value.
- This is just to show how a simple function is used.
Robot #15 - mini-farmer
Wheat grows from wheat-seeds planted on soil, and needs water nearby.
Here, we have one space with a watersource, and
4 spaces around that for planting and harvesting wheat,
-- #15 --
if not pn then pn="mini-farmer";
function fwd(c9)
for i=1,c9 do
ok=move.forward()
end
return ok
end
function init() -- needs to be defined before first call
say(pn)
t=0
air ="air"
soil="farming:soil_wet"
seed="farming:seed_wheat"
ripe="farming:wheat_8"
crop="farming:wheat"
turn.left()
_=fwd(3) -- here, we don't need the result.
end
init()
end
function work()
pickup(8)
nd=read_node.forward_down()
nf=read_node.forward();
say(t.." work: " .. nf.." - "..nd)
if nf==ripe then say("harvesting")
dig.forward()
return -- done for now
end
if nf==air and nd==soil then say("planting")
place.forward(seed)
return
end
turn.right(); t=t+1
--return
end
work()
if t>=4 then say("stop"); self.remove() end
The robot moves to the space over the watersource,
then turns around to reach the 4 spaces growing wheat.
Soil is made from dirt with a hoe near water,
this must be done by the player.
In this example, we don't need the return-values of the functions.
So we use a dummy-variable _.
Robot #16 - chat-listener
This robot listens to the chat, and report who said what.
If someone says 'stop', the program ends.
if not pn then pn="chat-listener"; say(pn)
self.listen(1)
self.spam(1)
end
speaker, msg = self.listen_msg()
if msg then
say( "["..speaker.."] said >>"..msg.."<<")
end
if msg=="stop" then
say("Bye !")
self.remove()
end
--
- the function self.listen_msg() returns a result that consists of 2 values
- the name of the player that speaks, and his text
Robot #17 - Builder
This robot builds a small, phonebooth-sized house around the spawner.
It needs the building-materials in its inventory (but doesn't check).
if not pn then pn="Instant shelter v1.7" say(pn)
pickup(8)
i=0
m0="default:dirt" m1="default:glass" m2="default:cobble"
m8="default:sand" m9="default:torch"
mS=m0 mC=m2 -- material for sides and corners
end
i=i+1; say(i)
if i<100 then
dig.forward(); move.forward()
place.right(mC)
move.backward()
place.forward(mS)
turn.left()
end
if i== 4 then move.up() place.down(m8) mS=m1 end
if i== 8 then move.up() place.down(m8) mS=m0 end
if i==12 then
place.up(m1);
i=100
end
if i==101 then
dig.down(); move.down()
place.up(m9);
end
if i>=102 then
dig.down();
say(pn .." done."); self.remove()
end
--
As shown above, the robot uses cobble for the corners
and dirt for the sides of the house.
The center of the sides are built with a block of glass.
Also, a single block of glass is placed as a roof,
with a torch beneath.
The robot uses sand as filler, so it can move up
more than one space above the ground.
The player can stand on the spawner before starting the program.
To get out, simply dig the glass and dirt from one of the sides.
Robot #18 - Demolition
This is a turtle-bot, with a script for digging the building made by robot #17.
--
if not pn then pn="DemoliTurtle v1b"
s = "-f<->>-<"
s3=s..s..s
script = "i@"..">ff"..s3 .."@>uff-"..s3 -- demolish levels 0 & 1
cmds = {
["f"] = function() move.forward() end,
["b"] = function() move.backward() end,
["l"] = function() move.left() end,
["r"] = function() move.right() end,
["u"] = function() move.up() end,
["d"] = function() move.down() end,
["<"] = function() turn.left() end,
[">"] = function() turn.right() end,
["-"] = function() dig.forward() end,
["_"] = function() dig.forward_down() end,
["^"] = function() dig.up() end,
["v"] = function() dig.down() end,
["@"] = function() self.reset(); pickup(8) end,
["i"] = function() say(pn) end,
["!"] = function() say("Hello") end,
}
n=string.len(script)
i=0;
end
if i>=n then say("done."); self.remove()
else i=i+1 end
c=string.sub(script,i,i); say(i.." --> "..c)
cmds[c]();
--
A turtle-bot get its instructions from a script.
Each character represents one operation, such as ">" for 'turn.right()'.
Robot #19 - move-demo
Location -6 26 -1000
This robot looks at the floor below to decide what to do.
It moves along the trench behind the spawner,
and finally activates the switch for the light.
-- #19 move-demo --
n=read_node.down()
if string.find(n,"dirt") then n="DIRT" end
say(n)
if n=="basic_robot:spawner" then
turn.right(); turn.right();
move.forward()
end
if n=="air" then move.down() end
if n=="DIRT" then move.forward() end
if n=="default:cobble" then
turn.right()
move.forward()
end
if n=="default:stone" then
move.up()
turn.right()
move.forward()
end
if n=="default:gravel" then
move.up()
turn.right()
activate.forward()
self.remove()
end
--
- string.find(n,"dirt") -- string-operation: return the position of "dirt" within string n
- see also paver-robot
Robot #20 - Color-Tower
This robot builds a tower made of keyboard-blocks, of max. height 10.
The color for each level can be specified by textinput via keypad.
Eg. entering "RGBg" means red, green, blue, gray.
--#22--
function keytype(k)
-- 0=air 1=white 2=grey 3=red 4=green 5=blue 6=yellow 7="0" 17=black
return string.find("wgRGBY0123456789k",k) or 0
end
function lv(h,c) -- build one level of the tower, at height h, in color c
if c=="" then return end
kt=keytype(c); --say(h..":"..c.."->"..kt)
--sides:
keyboard.set({x=pos.x+1,y=pos.y+h,z=pos.z },kt)
keyboard.set({x=pos.x-1,y=pos.y+h,z=pos.z },kt)
keyboard.set({x=pos.x, y=pos.y+h,z=pos.z+1},kt)
keyboard.set({x=pos.x, y=pos.y+h,z=pos.z-1},kt)
--corners:
keyboard.set({x=pos.x+1,y=pos.y+h,z=pos.z+1},kt)
keyboard.set({x=pos.x+1,y=pos.y+h,z=pos.z-1},kt)
keyboard.set({x=pos.x-1,y=pos.y+h,z=pos.z+1},kt)
keyboard.set({x=pos.x-1,y=pos.y+h,z=pos.z-1},kt)
--center
if h>0 then keyboard.set({x=pos.x+0,y=pos.y+h,z=pos.z }, 0) end
end
if not pn then pn="ColorTowerBuilder"; v="0.5b"; say(pn.." "..v) -- 2018-01-13
i=0
pos = self.spawnpos();
--read text from robot-spawner / written by keypad:
b=read_text.down(); s=string.sub(b,1,8)
if s=="overheat" then b="kgwRYGBk20" end
if s=="overheat" then b="kgwR22B" end
say("Buildplan:"..b)
end
i=i+1
t=string.sub(b,i,i)
lv(i, t)
--dig passages into the sides of the two bottom tower-levels:
dig.forward(); turn.right()
if i==4 then move.up() end
if i>9 then
say(pn.." done: "..b);
self.remove()
end
- string.sub(b,1,8) -- returns the substring from b, from position 1 to 8.
Robot #21 - Countdown
This program mainly just counts down, then stops.
- Greeting the player, and picking up loose stuff are extras.
But the robot-spawner sits in a pit deep enough so that a player without help cannot get out.
While the program is running, the player can jump onto the robot-worker,
and get out of the pit.
if not pn then pn="Countdown"; --say(pn)
p=pickup(8)
if p then say(pn.." pickup:"..p[1]) end
p=find_player(2)
if p then say("Hello "..p[1])
else say(pn..": no player nearby"); self.remove() end
i=11
end
i=i-1
self.label(i)
if i<0 then self.remove() end
- ...
Robot #22 - X
--todo
- ...
Useful Robots
Some robots that might be useful in a normal game, or useful for the admin.
This would include some of the tutorial-robots too, such as the teleporter.
BigDisplay
This shows a welcome-message on a big display, plays a sound, and ends the program after a countdown.
if not pn then pn="BigDisplay"
spin=function() -- turn robot until something other than air is at its back
for i=1,4 do
n=read_node.backward(); --say(n)
if n~="air" then return end
turn.right()
end
end
spin()
--msg="\n* Hello *"
--self.display_text(msg,9,1)
msg="\n Willkommen\n".." auf\n".." TechWelt !\n"
msg=msg.."\n- -- ** -- -\n"
msg=msg.." Welcome\n".." on\n".." TechWelt !\n"
self.display_text(msg,12,1) -- 1: normal-size
i=10
end
self.label(i)
i=i-1;
if i==8 then
self.sound("dingdong",1)
self.display_text(msg,12,2) -- 2: double-size
end
if i==3 then
self.sound("dingdong",1)
self.display_text(msg,12,3) -- 3: triple-size
end
if i<0 then self.remove() end
--
- spin=function() -- this is another variant how to define a function
- There is a torch behind the robot.
- This is used to turn the robot with its display towards the player.
Mailbox
Location: 6 26 -983
This shows a dialog/formspec to the player,
for writing a message to the owner of the robot.
The messages are written into books in the robot's library.
-- from https://wiki.minetest.net/Mods/basic_robot/Programs#Mailbox
-- mail & feedback using formspec, based on rnd's mailrobot
if not pn then pn="Mailbox" -- hajo 2017-03-07
s=0
daynr=os.date("%w") -- %w : weekday [0-6 = Sunday-Saturday]
booknr=tonumber(daynr); -- say(daynr.."/"..booknr)
msgsize = 2500;
_,text = book.read(booknr); text = text or "";
write_msg = function(sender,msg)
local newsize = string.len(text)+string.len(msg);
if newsize>msgsize then return "messages space exceeded" end
text = text .. "\n"..os.date("%Y-%m-%d %H:%M") .. " " .. sender .. ": " .. msg;
book.write(booknr,"messages #"..booknr, text)
end
end
--textarea[X,Y;W,H;name;label;default]
--button[X,Y;W,H;name;label]
if s == 0 then
players = find_player(4);
if players and players[1] then
s=1
local form = "size[8,4.5]" ..
"textarea[0,0;9,4.5;msg;YOUR FEEDBACK-MESSAGE;]"..
"button_exit[-0.5,4.15;2,1;send;send]"
self.show_form(players[1],form)
end
elseif s==1 then
sender,fields = self.read_form();
if sender then
if fields.send then
msg = fields.msg;
if msg and msg~="" then
write_msg(sender,msg); -- activate.up(1)
--_G.minetest.chat_send_player(sender,"#mailbot: your message has been stored")
say("#mailbot: your message has been stored")
end
end
self.remove()
end
end
--
Paver
Location: 5 25 -995, sunk into the road
Pave a road with gravel.
The robot needs enough gravel in its inventory.
Moves straight ahead, and replaces all kinds of dirt with gravel
on the ground below the robot.
Stops when movement is blocked,
when it finds something other then dirt or gravel,
or when it runs out of gravel for paving.
-- hajo, 2017-12-31
if not progname then progname=" paver"
self.spam(1)
say("# "..progname.." started #")
m="default:gravel"
end
ok=move.forward()
if not ok then
say("blocked")
self.remove()
end
n=read_node.down(); --say(n)
if n=="default:dirt" then n="DIRT" end
if n=="default:dirt_with_snow" then n="DIRT" end
if n=="default:dirt_with_grass" then n="DIRT" end
if n=="default:dirt_with_dry_grass" then n="DIRT" end
if n=="default:dirt_with_rainforest_litter" then n="DIRT" end
say(n)
if n=="DIRT" then
dig.down()
ok=place.down(m)
say("ok=".. serialize(ok) )
if not ok then say("empty"); self.remove() end
elseif n==m then
-- already done
else
say("stop"); self.remove()
end
--
- self.spam(1) -- allow more then one output from say() to other players
- if .. elseif
- ok=place.down(m) -- returns true if successful
- serialize(ok)
Brickmaker
This is an extended version of robot #12 'simple brickmaker':
It makes a set of keyboard-buttons (all colors, all numbers),
and puts them into the chest.
-- Brickmaker--
if not pn then pn="Keyboard-button-maker"
c=1 -- 1=white 2=grey 3=red 4=green 5=blue 6=yellow 7-16="0"-"9" 17=black
p0 = self.spawnpos();
--turn.left(); turn.left();
end
keyboard.set( {x=p0.x, y=p0.y+2, z=p0.z}, c)
dig.up()
m = check_inventory.self("","main",1); -- say(m)
self.label(c.."-->"..m)
--say(c.."-->"..m)
insert.forward(m)
--c=99 -- uncomment this to stop after making the first button
c=c+1;
if c>17 then
c=1 -- repeat, make another set of buttons
say(pn.." done."); self.remove() -- uncomment this to stop after first set
end
--
- self.spawnpos() -- returns the position of the robot-spawner, as a table
- {x=p0.x, y=p0.y+2, z=p0.z} -- specifies a new table, with elements from table p0
- y+2 means '2 spaces above the spawner'
- check_inventory.self("","main",1) -- returns the name of the item in slot 1 of the robot's inventory
After the button is created, the robot digs it.
The button goes into slot 1 of the robot's inventory,
and is put into the chest in front of the robot.
New chest
This program 'cleans' the chest with all the generated buttons.
if not pn then pn="chest-renewer"; say(pn)
turn.left(); turn.left(); -- turn worker towards chest
m="default:chest"
end
dig.forward() -- !! this destroys the chest-contents !!
place.forward(m)
say(pn.." done.")
self.remove()
It simply digs the chest (thereby destroying the contents),
and places a new chest at the same location.
Buttonmaker2
This is an extended version of robot #12 'simple brickmaker':
It makes a set of keyboard-buttons for use as turtle-commands,
and puts them into the chest.
--todo
if not pn then pn="Buttonmaker2"; say(pn)
c=1 -- 1=white 2=grey 3=red 4=green 5=blue 6=yellow 7-16="0"-"9" 17=black
p0 = self.spawnpos();
--turn.left(); turn.left();
end
keyboard.set( {x=p0.x, y=p0.y+2, z=p0.z}, c)
dig.up()
m = check_inventory.self("","main",1); -- say(m)
self.label(c.."-->"..m)
--say(c.."-->"..m)
insert.forward(m)
--c=99 -- uncomment this to stop after making the first button
c=c+1;
if c>17 then
c=1 -- repeat, make another set of buttons
say(pn.." done."); self.remove() -- uncomment this to stop after first set
end
--
say(pn.." done.")
self.remove()
Math-Quiz
Math-Quiz, using chat.
It asks questions like
WHAT is 12*13 ?,
and listens to the chat for players to answer.
Puts reward for correct answer into chest.
- It doesn't check who gives an answer, and who takes the rewards from the chest.
-- from https://wiki.minetest.net/Basic_robot/Tutorial#Math_quiz2
-- QUIZ: asks math question, like ""WHAT IS 12*13 ?"
if not state then
state = 1;
a=0; b=0; question = "";
function generate_question()
a = math.random(12)+10;
b = math.random(12)+10;
t=0
question = "WHAT IS " .. a .."*".. b .. " ? ";
say(question)
end
generate_question()
self.listen(1)
end
speaker, msg = self.listen_msg()
msg = tonumber(msg)
if msg then
if msg == a*b then
say(speaker .. " ANSWERED CORRECTLY! You get reward in chest")
insert.up("default:apple")
insert.up("default:pine_tree")
generate_question()
else
say("WRONG! " .. question)
end
end
turn.left();
t=t+1; self.label(t)
if t>30 then self.remove() end
--
- speaker,msg=self.listen_msg() -- the function returns 2 results: the speaker, and his text
- tonumber(msg) -- tries to convert a text to a number
- only numbers are considered as answers to the quiz, other text is ignored
The robot stops if there is no answer within 30 seconds.
Simple Shop
Shop - Robot sells 1 Keypad for 2 Steel-ingots.
To use, the player must put the payment into the chest, then press the keypad-button.
-- from https://wiki.minetest.net/Mods/basic_robot#Simple_Shop
--say("Shop out of order ... check back soon !"); self.remove()
--
if not pn then pn="SimpleShop v0.2" -- Hajo, 2017-03-03+
say(pn)
p=find_player(4)
if p==nil then s="Hello !" else s="Hello "..p[1].." !" end
say(s)
--
-- m1="default:torch"; m2="default:dirt" --Test
--m1="default:sword_steel" -- Example 1: sell 1 sword for 1 gold
--m2="default:gold_ingot"
m1="basic_machines:keypad" -- Example 2: sell 1 keypad for 2 steel
m2="default:steel_ingot 2"
ok1 = check_inventory.self(m1,"main") -- look at robot's inventory
if not ok1 then say("Out of stock: "..m1); self.remove() end
ok2 = check_inventory.up(m2,"main") -- look at chest above robot
if not ok2 then say("No payment in chest ("..m2..")"); self.remove() end
say("Selling "..m1.." for "..m2)
take.up(m2)
insert.up(m1)
say("Thanks for your purchase !");
end
The robot first checks his inventory if there still are items to sell.
Then it checks the chest for payment.
If both are ok, it takes the payment from the chest, and puts the goods into the chest.
- Note: another player could try to steal the payment or the sold item from the chest.
Multi-language sign
Location: -33,26,-973
Shows some text like the program 'BigDisplay' above,
but also listens to chat to switch the text.
-- 2018-02-02, hajo
function sign(msg)
self.display_text(msg,24,2)
self.label("")
end
if not pn then pn="Multilanguage-sign v1.1"; --say(pn)
--self.spam(1)
msg="Select via chat:\n\n"
msg=msg.."EN: to show english text"
--msg=msg.."DE: für deutschen Text\n" -- Umlaute !!
msg=msg.."DE: deutschen Text anzeigen\n"
sign(msg)
self.listen(1)
--say("I',m listening...")
end
speaker, inp = self.listen_msg()
--if inp then say( "player ["..speaker.."] said >>"..inp.."<<") end
if inp=="DE" then sign("Deutscher Text.\n") end
if inp=="EN" then msg="english text\n....+....1....+....2...\n"
msg=msg.."3\n4\n5\n6\n7\n8\n9\n10\n"
msg=msg.."11\n12\n13\n14\n15\n16\n17\n18\n19\n20\n21\n22"
sign(msg)
end
if inp=="#" or inp=="stop" then -- cannot use . or /
say("Bye !")
pickup(8)
self.remove()
end
This program could be extended, eg. to listen only to nearby players,
and to get the texts to display from books stored in the robots library.
Outfitter
--todo
Robo-Farm
This is a much extended version of the mini-farmer, robot #15.
Wheat grows on soil, and needs water within 2 spaces.
Here, we have set up a 5x5 wheat-field around a 3x3 pont with a fountain in the center.
The robot drives around this field, harvests ripe wheat, and plants new seeds.
The robot normally drives forward, and turns right when it hits an obstacle.
There are some trapdoors at the corners of the field that act as an obstacle/free space
depending on their open/closed state.
They can be switched by the robot with activate().
This is used to 'switch lanes' while moving around the field.
There is a chest at the border of the field, where the robot unloads some wheat whenever it reaches that location.
Also on the border are some bee-hives that produce honey,
and the robot takes some of that honey out when it drives by.
Finally, the robot picks up 'loose items' and announces what was found.
- Eg. eggs from chickens, or raw meat that drops when animal-mobs drown in the central pont.
-- robot-farmer --
-- !! the field must be prepared first, by hand / hoe !!
if not pn then pn="robo-farmer v1"; say(pn)
seed="farming:seed_wheat"
ripe="farming:wheat_8"
crop="farming:wheat"
self.spam(1)
end
m=pickup(8) -- collect meat, eggs, saplings etc.
if m then say(pn..": pickup "..m[1]) end
n=read_node.forward();
if n=="default:chest" then n=""
--say(pn..": unload")
insert.forward(crop.." 16")
end
if n=="xdecor:hive" then n=""
--say(pn..": get honey")
take.forward("xdecor:honey".." 2","honey")
end
if n==ripe then n=""
dig.forward()
place.forward(seed)
end
--if n~="" then say(n) end -- debug
activate.forward(1) -- trapdoor
ok=move.forward()
if not ok then turn.right() end
--
Ideas & Homework:
- Detect spaces without planted seed, and spaces without soil (eg. holes, or plain dirt).
- Check if the robot has seeds in its inventory.
- Extend this program to unload different types of collected stuff into different chests.
- replace the wheat-chest with another robot, and activate it after unloading
- let this 2nd robot process the wheat into flour, and bake that into bread (see robot #8)
- move the finished bread to a shop-robot
- Same for eggs and meat that was picked up from animals.
- Extend this program to also plant & harvest cotton, and make wool.
- Install farming-redo, and also farm the other plants (pumpkin, blueberry, etc),
and make other products from that mod (donuts, blueberry-pie, pumpkin-bread, etc.)
Demos: Robots&Machines
Machines&Robots working together.
Street-lanterns
Keypad, Distributor, Lights
There are several street-lanterns
that can be switched on and off with a keypad.
A distributor is used to transmit the signal from the keypad to the lights.
Production-Demo
Generator, Battery, Furnace, Robots
A generator produces powercells, a battery powers a furnace, robots move powercells around, and craft items.
...