basic-robot-csm for Debian
-------------------------

Please be noted that using client side mod (CSM) in public servers might be
an unethical behaviour because some players think that it is cheating.
And be respectful to the server admins if they dislike any CSM.

## Start using basic_robot_csm

First, we need to make sure that client side mod is enabled.
Please go "Settings" tab (by clicking the gears icon).
And then check "Show advanced settings" checkbox.
Search for "enable_client_modding" and enable it.

You can also check ~/.minetest/minetest.conf to see if there is
"enable_client_modding = true"

To start using basic-robot-csm, please create a file called
~/.minetest/clientmods/mods.conf

The content of the above file should contains:
  load_mod_basic_robot_csm = true

If you have another client side mods, just make sure that
"load_mod_<csm_name> = true" is in that file too.

After the above settings are done, restart the client.
Use ".b" command in Luanti and it will show you a window
to paste your program.

## Some basic_robot_csm code examples.

Here we give some examples of using basic_robot_csm.
For more functions, please check the following documents and examples.

 * examples in /usr/share/doc/minetest-mod-basic-robot-csm/examples
 * /usr/share/doc/luanti/client_lua_api.md.gz from luanti-data package.

### say(message, send_to_server)

Send a message.

Ex:
  -- This will be sent to the server and will be seen by other players.
  say("hi", true)
  -- This will only show locally on your screen.
  say("Hello World!!", false)
  self.remove()

### self.pos()

Get the player's position.

Ex:
  mypos = self.pos()
  say("x="..mypos.x..", y="..mypos.y..", z="..mypos.z, false)

### self.viewdir()

Get the player's view angle.

Ex:
  myangle = self.viewdir()
  yaw = math.atan2(myangle.x, myangle.z)
  yawAngle = 180.0 * yaw / math.pi
  pitch = math.asin(myangle.y)
  pitchAngle = 180.0 * pitch / math.pi
  say("yaw="..yawAngle.." pitch="..pitchAngle, false)

### self.remove()

Pause the bot.
Otherwise the code will run periodically.

### self.name()

Get player's name

Ex:
  say("My name is "..self.name(), false)
  self.remove()

### minetest.get_csm_restrictions()

Get CSM restrictions

Ex:
  r = minetest.get_csm_restrictions()
  for k,v in pairs(r) do
    if type(v) == "boolean" then
      if v then
        say(""..k..": ".."true", false)
      else
        say(""..k..": ".."false", false)
      end
    elseif type(v) == "number" then
      say(""..k..": "..v, false)
    else
      say(""..k..": "..v, false)
    end
  end
  self.remove()

### minetest.get_node_or_nil(pos)

Get a node at a specified position.

Sometimes this function returns nil. It might because your client or server
restrict the distance of this function.

On local games, you have to change csm_restriction_noderange value.
You can change this value from "Settings" tab and click "All Settings" and
then search it.
It is also in the config file ~/.minetest/minetest.conf
For example "csm_restriction_noderange = 20" will give you the rights to read
nodes within 20 distance.
If you play on a server, your client by default will respect the value
given from the server so the settings in minetest.conf won't be used.

Ex:
  pos1 = self.pos()
  pos1.x = math.floor(pos1.x+0.5)
  pos1.y = math.floor(pos1.y+0.5)
  pos1.z = math.floor(pos1.z+0.5)

  node = minetest.get_node_or_nil(pos1)
  if node then
    say("node.name="..node.name.." node.param2="..node.param2, false)
  else
    say("node is nil.", false)
  end

### minetest.get_node_light(pos)

Get node light at a specified position.

Ex:
  pos1 = self.pos()
  pos1.x = math.floor(pos1.x+0.5)
  pos1.y = math.floor(pos1.y+0.5)
  pos1.z = math.floor(pos1.z+0.5)

  nodename = minetest.get_node_or_nil(pos1).name
  nodelight = minetest.get_node_light(pos1)

  say("node="..nodename.." light="..nodelight, false)

### minetest.get_meta(pos)

Get node's metadata.

Ex:
  -- stand on a chest. List inventory.
  pos1 = self.pos()
  pos1.x = math.floor(pos1.x+0.5)
  pos1.y = math.floor(pos1.y+0.5)-1
  pos1.z = math.floor(pos1.z+0.5)

  nodemeta = minetest.get_meta(pos1):to_table()
  if nodemeta then
    for k,v in pairs(nodemeta) do
      if (k == "inventory") then
        for k1,v1 in pairs(v) do
          if (k1 == "main") then
            for k2,v2 in pairs(v1) do
               r1 = v2:to_table()
               if r1 then
                 itemName=""
                 itemCount=0
                 for k3,v3 in pairs(r1) do
                   if (k3 == "name") then
                     itemName=v3
                   end
                   if (k3 == "count") then
                     itemCount=v3
                   end
                 end
                 if (itemCount > 0) then
                   say("item: "..itemName.." count: "..itemCount,false)
                 end
               end
            end
          end
        end
      end
    end
  else
    say("node's meta is nil.", false)
  end
  self.remove()

### minetest.register_on_damage_taken(function(hp))

When damage is taken, run the function.
Once the function is registered, even the bot is stopped, the function
will still run when the event is triggered.

Ex:
  function toSpawn(hp)
    say("/spawn", true)
  end
  minetest.register_on_damage_taken(toSpawn)
  self.remove()

 -- Ying-Chun Liu (PaulLiu) <paulliu@debian.org>  Sat, 08 Oct 2022 04:47:56 +0800
