Post your modding questions here

RREDesigns
Member
 
Posts: 10
Joined: Fri Jan 08, 2016 04:32
GitHub: rredesigns
IRC: R_R_E_Designs
In-game: R_R_E_Designs

Re: Post your modding questions here

by RREDesigns » Fri Jan 08, 2016 14:09

Why "playerName = minetest.get_player_name()" doesn't work alone?
 

RREDesigns
Member
 
Posts: 10
Joined: Fri Jan 08, 2016 04:32
GitHub: rredesigns
IRC: R_R_E_Designs
In-game: R_R_E_Designs

Re: Post your modding questions here

by RREDesigns » Fri Jan 08, 2016 14:13

Ok, it works now, with func(name), since all I wanted was the player name, no parameters has to be passed.

Image

Big thanks for the help.
 

RREDesigns
Member
 
Posts: 10
Joined: Fri Jan 08, 2016 04:32
GitHub: rredesigns
IRC: R_R_E_Designs
In-game: R_R_E_Designs

Re: Post your modding questions here

by RREDesigns » Fri Jan 08, 2016 14:19

This is the code in init.lua for the teleport requests I was talking earlier:

Code: Select all
local timeout_delay = 60

-- Set to true to register tpr_admin priv
local regnewpriv = false

local version = "1.1"

local tpr_list = {}
local tphr_list = {}

--Teleport Request System
local function tpr_send(sender, receiver)
   if receiver == "" then
      minetest.chat_send_player(sender, "Usage: /tpr <Player name>")
      return
   end

   --If paremeter is valid, Send teleport message and set the table.
   if not minetest.get_player_by_name(receiver) then
      return
   end

   minetest.chat_send_player(receiver, sender ..' is requesting to teleport to you. /tpy to accept.')
   minetest.chat_send_player(sender, 'Teleport request sent! It will time out in '.. timeout_delay ..' seconds.')

   --Write name values to list and clear old values.
   tpr_list[receiver] = sender
   --Teleport timeout delay
   minetest.after(timeout_delay, function(name)
      if tpr_list[name] then
         tpr_list[name] = nil
      end
   end, sender)
end

local function tphr_send(sender, receiver)
   if receiver == "" then
      minetest.chat_send_player(sender, "Usage: /tphr <Player name>")
      return
   end

   --If paremeter is valid, Send teleport message and set the table.
   if not minetest.get_player_by_name(receiver) then
      return
   end

   minetest.chat_send_player(receiver, sender ..' is requesting that you teleport to them. /tpy to accept; /tpn to deny')
   minetest.chat_send_player(sender, 'Teleport request sent! It will time out in '.. timeout_delay ..' seconds.')

   --Write name values to list and clear old values.
   tphr_list[receiver] = sender
   --Teleport timeout delay
   minetest.after(timeout_delay, function(name)
      if tphr_list[name] then
         tphr_list[name] = nil
      end
   end, sender)
end

local function tpr_deny(name)
   if tpr_list[name] then
      minetest.chat_send_player(tpr_list[name], 'Teleport request denied.')
      tpr_list[name] = nil
   end
   if tphr_list[name] then
      minetest.chat_send_player(tphr_list[name], 'Teleport request denied.')
      tphr_list[name] = nil
   end
end

-- Copied from Celeron-55's /teleport command. Thanks Celeron!
local function find_free_position_near(pos)
   local tries = {
      {x=1,y=0,z=0},
      {x=-1,y=0,z=0},
      {x=0,y=0,z=1},
      {x=0,y=0,z=-1},
   }
   for _,d in pairs(tries) do
      local p = vector.add(pos, d)
      if not minetest.registered_nodes[minetest.get_node(p).name].walkable then
         return p, true
      end
   end
   return pos, false
end


--Teleport Accept Systems
local function tpr_accept(name, param)

   --Check to prevent constant teleporting.
   if not tpr_list[name]
   and not tphr_list[name] then
      minetest.chat_send_player(name, "Usage: /tpy allows you to accept teleport requests sent to you by other players")
      return
   end

   local chatmsg, source, target, name2

   if tpr_list[name] then
      name2 = tpr_list[name]
      source = minetest.get_player_by_name(name)
      target = minetest.get_player_by_name(name2)
      chatmsg = name2 .. " is teleporting to you."
      tpr_list[name] = nil
   elseif tphr_list[name] then
      name2 = tphr_list[name]
      source = minetest.get_player_by_name(name2)
      target = minetest.get_player_by_name(name)
      chatmsg = "You are teleporting to " .. name2 .. "."
      tphr_list[name] = nil
   else
      return
   end

   -- Could happen if either player disconnects (or timeout); if so just abort
   if not source
   or not target then
      return
   end

   minetest.chat_send_player(name2, "Request Accepted!")
   minetest.chat_send_player(name, chatmsg)

   target:setpos(find_free_position_near(source:getpos()))
end

--Initalize Permissions.

if regnewpriv then
   minetest.register_privilege("tpr_admin", {
      description = "Permission to override teleport to other players. UNFINISHED",
      give_to_singleplayer = true
   })
end

--Initalize Commands.

minetest.register_chatcommand("tpr", {
   description = "Request teleport to another player",
   params = "<playername> | leave playername empty to see help message",
   privs = {interact=true},
   func = tpr_send
})

minetest.register_chatcommand("tphr", {
   description = "Request player to teleport to you",
   params = "<playername> | leave playername empty to see help message",
   privs = {interact=true},
   func = tphr_send
})

minetest.register_chatcommand("tpy", {
   description = "Accept teleport requests from another player",
   func = tpr_accept
})

minetest.register_chatcommand("tpn", {
   description = "Deny teleport requests from another player",
   func = tpr_deny
})

minetest.log("info", "[Teleport Request] Teleport Request v" .. version .. " Loaded.")
 

User avatar
rubenwardy
Moderator
 
Posts: 5965
Joined: Tue Jun 12, 2012 18:11
Location: United Kingdom
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy

Re: Post your modding questions here

by rubenwardy » Fri Jan 08, 2016 14:37

Minetest does that for you.

In the following code:

Code: Select all
function foo(param1, param2)

end


param1 and param2 are local variables in that function.
Think of it a little like this, although this code won't work:

Code: Select all
function foo()
    local param1
    local param2

   -- both can be accessed here
end

-- there is no param1 or param2 here.


The caller sets the value of the params like so:

Code: Select all
function foo(param1, param2)

end

foo("one value", 123)


It's minetest that calls the function for you and gives it that value. So somewhere there will be code like this:

Code: Select all
local cmd = somehowGetTheCommandFromItsName(cmd_name)
local ret, msg = cmd.func(callername, parampassed)
if ret then
   print("command was successful")
else
    print("command was unsuccessful")
end
print(msg)


That about code is example code, and won't work.
 

User avatar
Hybrid Dog
Member
 
Posts: 2726
Joined: Thu Nov 01, 2012 12:46

Re: Post your modding questions here

by Hybrid Dog » Fri Jan 08, 2016 14:56

iangp wrote:Hey guys,
Is there some way to a mod cause some error like that?
Code: Select all
*** Error in `minetest': double free or corruption (fasttop): 0x0000000001239c60 ***
Abortado (imagem do núcleo gravada)

Or Is just my minetest build? I just retype and then it runs but it's a strange issue

l don't think a mod causes such an error message.
viewforum.php?f=6

‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪
 

User avatar
iangp
Member
 
Posts: 114
Joined: Sat May 31, 2014 19:26
Location: Brasil - ES
GitHub: 14NGiestas
IRC: iangp
In-game: iangp

Re: Post your modding questions here

by iangp » Fri Jan 08, 2016 16:19

RREDesigns wrote:I tried to do that about 20 times, in different ways, including a funtion defined outside the list. It just doesn't work. I think I forgot to make a list this last time, so I fixed it, but it doesn't work. Then I tried to copy the code provided by "iangp" and that doesn't work either, the error:

ServerError: Lua: Runtime error from mod 'testmod' in callback on_chat_message():***/init.lua:11: bad argument #1 to 'chat_send_player' (string expected, got nil)

I clearly said I wanted to retrieve the player's name. All I need is to store it's name in a var to use it later in other strings operations. I used the chat to print it, just to check wheter it was working or not.

try replace tostring() to dump() on my code...
God's not dead, He's surely alive!
エル プサイ コングルー

My mods (WIP):
 

User avatar
rubenwardy
Moderator
 
Posts: 5965
Joined: Tue Jun 12, 2012 18:11
Location: United Kingdom
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy

Re: Post your modding questions here

by rubenwardy » Fri Jan 08, 2016 16:26

RREDesigns wrote:Why "playerName = minetest.get_player_name()" doesn't work alone?


Where would minetest be getting the name from? Mods are ran on the serverside, not the client side. Therefore there can be more than one player, so minetest.get_player_name() won't know which one.

If you have a player object, you can do player:get_player_name()

Also, make sure you use local:

Code: Select all
local playerName = player:get_player_name()


See here for more info: http://rubenwardy.com/minetest_modding_ ... and-global

RREDesigns wrote:This is the code in init.lua for the teleport requests I was talking earlier:

Code: Select all
local timeout_delay = 60

-- Set to true to register tpr_admin priv
local regnewpriv = false

local version = "1.1"

local tpr_list = {}
local tphr_list = {}

--Teleport Request System
local function tpr_send(sender, receiver)
   if receiver == "" then
      minetest.chat_send_player(sender, "Usage: /tpr <Player name>")
      return
   end

   --If paremeter is valid, Send teleport message and set the table.
   if not minetest.get_player_by_name(receiver) then
      return
   end

   minetest.chat_send_player(receiver, sender ..' is requesting to teleport to you. /tpy to accept.')
   minetest.chat_send_player(sender, 'Teleport request sent! It will time out in '.. timeout_delay ..' seconds.')

   --Write name values to list and clear old values.
   tpr_list[receiver] = sender
   --Teleport timeout delay
   minetest.after(timeout_delay, function(name)
      if tpr_list[name] then
         tpr_list[name] = nil
      end
   end, sender)
end

local function tphr_send(sender, receiver)
   if receiver == "" then
      minetest.chat_send_player(sender, "Usage: /tphr <Player name>")
      return
   end

   --If paremeter is valid, Send teleport message and set the table.
   if not minetest.get_player_by_name(receiver) then
      return
   end

   minetest.chat_send_player(receiver, sender ..' is requesting that you teleport to them. /tpy to accept; /tpn to deny')
   minetest.chat_send_player(sender, 'Teleport request sent! It will time out in '.. timeout_delay ..' seconds.')

   --Write name values to list and clear old values.
   tphr_list[receiver] = sender
   --Teleport timeout delay
   minetest.after(timeout_delay, function(name)
      if tphr_list[name] then
         tphr_list[name] = nil
      end
   end, sender)
end

local function tpr_deny(name)
   if tpr_list[name] then
      minetest.chat_send_player(tpr_list[name], 'Teleport request denied.')
      tpr_list[name] = nil
   end
   if tphr_list[name] then
      minetest.chat_send_player(tphr_list[name], 'Teleport request denied.')
      tphr_list[name] = nil
   end
end

-- Copied from Celeron-55's /teleport command. Thanks Celeron!
local function find_free_position_near(pos)
   local tries = {
      {x=1,y=0,z=0},
      {x=-1,y=0,z=0},
      {x=0,y=0,z=1},
      {x=0,y=0,z=-1},
   }
   for _,d in pairs(tries) do
      local p = vector.add(pos, d)
      if not minetest.registered_nodes[minetest.get_node(p).name].walkable then
         return p, true
      end
   end
   return pos, false
end


--Teleport Accept Systems
local function tpr_accept(name, param)

   --Check to prevent constant teleporting.
   if not tpr_list[name]
   and not tphr_list[name] then
      minetest.chat_send_player(name, "Usage: /tpy allows you to accept teleport requests sent to you by other players")
      return
   end

   local chatmsg, source, target, name2

   if tpr_list[name] then
      name2 = tpr_list[name]
      source = minetest.get_player_by_name(name)
      target = minetest.get_player_by_name(name2)
      chatmsg = name2 .. " is teleporting to you."
      tpr_list[name] = nil
   elseif tphr_list[name] then
      name2 = tphr_list[name]
      source = minetest.get_player_by_name(name2)
      target = minetest.get_player_by_name(name)
      chatmsg = "You are teleporting to " .. name2 .. "."
      tphr_list[name] = nil
   else
      return
   end

   -- Could happen if either player disconnects (or timeout); if so just abort
   if not source
   or not target then
      return
   end

   minetest.chat_send_player(name2, "Request Accepted!")
   minetest.chat_send_player(name, chatmsg)

   target:setpos(find_free_position_near(source:getpos()))
end

--Initalize Permissions.

if regnewpriv then
   minetest.register_privilege("tpr_admin", {
      description = "Permission to override teleport to other players. UNFINISHED",
      give_to_singleplayer = true
   })
end

--Initalize Commands.

minetest.register_chatcommand("tpr", {
   description = "Request teleport to another player",
   params = "<playername> | leave playername empty to see help message",
   privs = {interact=true},
   func = tpr_send
})

minetest.register_chatcommand("tphr", {
   description = "Request player to teleport to you",
   params = "<playername> | leave playername empty to see help message",
   privs = {interact=true},
   func = tphr_send
})

minetest.register_chatcommand("tpy", {
   description = "Accept teleport requests from another player",
   func = tpr_accept
})

minetest.register_chatcommand("tpn", {
   description = "Deny teleport requests from another player",
   func = tpr_deny
})

minetest.log("info", "[Teleport Request] Teleport Request v" .. version .. " Loaded.")


Those variables are function parameters, and are defined when the function is defined, here:

Code: Select all
local function tphr_send(sender, receiver)


iangp wrote:try replace tostring() to dump() on my code...


No. Your code is not the correct solution, he's trying to find out the name of the caller not the param passed.

Anyway, it would be player:get_player_name() not tostring or dump.
dump(player) will return <userdata>.
 

RREDesigns
Member
 
Posts: 10
Joined: Fri Jan 08, 2016 04:32
GitHub: rredesigns
IRC: R_R_E_Designs
In-game: R_R_E_Designs

Re: Post your modding questions here

by RREDesigns » Fri Jan 08, 2016 17:06

Ok, that explains a lot. I was missing some of that.

In the code for the telport requests, sender and receiver are declared, but never defined. That's one of my biggest issues, I don't know how those vars get their value, or how the engine sorts them. Can I change those vars with, let's say paka and paka2, and get the same value assigned to those by the engine?
 

User avatar
rubenwardy
Moderator
 
Posts: 5965
Joined: Tue Jun 12, 2012 18:11
Location: United Kingdom
GitHub: rubenwardy
IRC: rubenwardy
In-game: rubenwardy

Re: Post your modding questions here

by rubenwardy » Fri Jan 08, 2016 17:10

Yes. Both these will work:

Code: Select all
function foo(one, two)
    print(one, two)
end


Code: Select all
function foo(dog, cat)
    print(dog, cat)
end


What matters is the order, not the names.

Somewhere is in the code gives it their value, see above.

Code: Select all
foo("something", "happened")


Runs the code in foo, starts with
one = dog = "something"
two = cat = "happened"
 

User avatar
everamzah
Member
 
Posts: 490
Joined: Thu Jan 29, 2015 00:47
GitHub: everamzah
IRC: everamzah
In-game: everamzah

Re: Post your modding questions here

by everamzah » Fri Jan 08, 2016 18:00

Why doesn't this work? Or, more specifically, why would this make minetest run at 100% CPU and become unresponsive?
Code: Select all
minetest.register_node("kalite:plastic_grass", {
        tiles = "default_grass.png"
})

minetest.register_on_generated(function(minp, maxp, seed)
        if minp.y >= 14360 and minp.y <= 14440 then
                for x = minp.x, maxp.x do
                for z = minp.z, maxp.z do
                        minetest.set_node({x = x, y = 14400, z = z}, {name="default:cloud"})--[[
                        minetest.set_node({x = x, y = 14401, z = z}, {name="kalite:plastic_grass"})--]]
                end
                end
        end
end)


https://github.com/cornernote/minetest- ... it.lua#L25
 

User avatar
stu
Member
 
Posts: 923
Joined: Sat Feb 02, 2013 02:51
Location: United Kingdom
GitHub: stujones11

Re: Post your modding questions here

by stu » Fri Jan 08, 2016 18:14

everamzah wrote:Why doesn't this work? Or, more specifically, why would this make minetest run at 100% CPU and become unresponsive?

I would guess it has something to do with the 3000+ calls to minetest.set_node. This looks more like a job for the LVM ;-)

Edit: nvm 3000, it's actually more like 12000 :O
Last edited by stu on Fri Jan 08, 2016 19:01, edited 1 time in total.
 

RREDesigns
Member
 
Posts: 10
Joined: Fri Jan 08, 2016 04:32
GitHub: rredesigns
IRC: R_R_E_Designs
In-game: R_R_E_Designs

Re: Post your modding questions here

by RREDesigns » Fri Jan 08, 2016 18:51

Ok, thanks for your time.

I think you are the same guy who wrote the mod manual, so, could you include this information there. Apparently, it is hard to figure out just reading from the API reference, so it would be great help for future readers. I can make some images with marks and tags to explain how pieces in a function fit togheter and how they come to get a value from callbacks. :D
 

User avatar
paramat
Developer
 
Posts: 3555
Joined: Sun Oct 28, 2012 00:05
Location: UK
GitHub: paramat
IRC: paramat

Re: Post your modding questions here

by paramat » Fri Jan 08, 2016 20:59

everamzah use the lua voxel manipulator to set those nodes in bulk instead of 12800 individual map accesses.
See my lua mapgen mods for examples (strip out all the noise code).
 

User avatar
Hybrid Dog
Member
 
Posts: 2726
Joined: Thu Nov 01, 2012 12:46

Re: Post your modding questions here

by Hybrid Dog » Fri Jan 08, 2016 22:11

paramat wrote:everamzah use the lua voxel manipulator to set those nodes in bulk instead of 12800 individual map accesses.
See my lua mapgen mods for examples (strip out all the noise code).

Somewhere l read that minetest.set_node works faster when it's used in an on_generated, is it true?

‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪
 

User avatar
everamzah
Member
 
Posts: 490
Joined: Thu Jan 29, 2015 00:47
GitHub: everamzah
IRC: everamzah
In-game: everamzah

Re: Post your modding questions here

by everamzah » Sat Jan 09, 2016 02:30

+ Spoiler

This is about as far as I've gotten. I started with the example at http://dev.minetest.net/voxel_manipulation#Example -- Am I close?

Edit: This actually works! I'm quite pleased, but am wondering about making it faster. For example, this line: https://github.com/minetest/minetest/bl ... .txt#L2983 talks about using a flat array to make on_generated faster?
 

User avatar
Hybrid Dog
Member
 
Posts: 2726
Joined: Thu Nov 01, 2012 12:46

Re: Post your modding questions here

by Hybrid Dog » Sat Jan 09, 2016 09:10

everamzah wrote:
+ Spoiler

This is about as far as I've gotten. I started with the example at http://dev.minetest.net/voxel_manipulation#Example -- Am I close?

Edit: This actually works! I'm quite pleased, but am wondering about making it faster. For example, this line: https://github.com/minetest/minetest/bl ... .txt#L2983 talks about using a flat array to make on_generated faster?

l guess you use singlenode, so you don't need to set air:
Code: Select all
       for z = z0, z1 do
                for x = x0, x1 do
                        data[area:index(x, 14400, z)] = c_cloud
                        data[area:index(x, 14401, z)] = c_plastic_grass
                end
        end

you could also calculate the area index yourself (l think there are 5*16+2*16-1 z, y, and xs) or use the iter function:
Code: Select all
       for vi in area:iter(x0, 14400, z0, x1, 14400, z1) do
              data[vi] = c_cloud
       end
       for vi in area:iter(x0, 14401, z0, x1, 14401, z1) do
              data[vi] = c_plastic_grass
       end

And you could change that limit where it generates.
Code: Select all
if maxp.y < 14400 or
            minp.y > 14401 then
                return

‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪‮
‮‪
 

User avatar
everamzah
Member
 
Posts: 490
Joined: Thu Jan 29, 2015 00:47
GitHub: everamzah
IRC: everamzah
In-game: everamzah

Re: Post your modding questions here

by everamzah » Sat Jan 09, 2016 09:16

Oh thank you very much HybridDog! I guess I do have to set air though, because I'm using mgv6. Thanks again.

Edit: This is what I've got now:
+ Spoiler


Option 2 seemed to be the fastest. Also, I tried without air and it still works. Were you talking about the singlenode mapgen or the fact that I was only working with a couple of single nodes?
 

User avatar
stu
Member
 
Posts: 923
Joined: Sat Feb 02, 2013 02:51
Location: United Kingdom
GitHub: stujones11

Re: Post your modding questions here

by stu » Sat Jan 09, 2016 16:51

What is the best way to make placement of a certain node require a particular privilege? I am sure this one should be easy but I'm just not seeing it.
 

User avatar
everamzah
Member
 
Posts: 490
Joined: Thu Jan 29, 2015 00:47
GitHub: everamzah
IRC: everamzah
In-game: everamzah

Re: Post your modding questions here

by everamzah » Sat Jan 09, 2016 17:13

Server Essentials by Gunship Penguin uses some method to restrict placement of TNT nodes, or whatever node you specify in its config. FireGuard by (indriApollo?) uses a priv "fglava" to restrict placing using a lava bucket. Perhaps one of those might do. My first guess was to use after_place_node, however, and check player privs there.
 

User avatar
Don
Member
 
Posts: 1643
Joined: Sat May 17, 2014 18:40
GitHub: DonBatman
IRC: Batman
In-game: Batman

Re: Post your modding questions here

by Don » Sat Jan 09, 2016 17:20

I would use on_place and check for priv. If not priv then return else set_node.
Many of my mods are now a part of Minetest-mods. A place where you know they are maintained!

A list of my mods can be found here
 

User avatar
everamzah
Member
 
Posts: 490
Joined: Thu Jan 29, 2015 00:47
GitHub: everamzah
IRC: everamzah
In-game: everamzah

Re: Post your modding questions here

by everamzah » Sat Jan 09, 2016 17:24

I think using on_place will require managing the itemstack and so on, whereas after_place_node won't.
 

User avatar
Don
Member
 
Posts: 1643
Joined: Sat May 17, 2014 18:40
GitHub: DonBatman
IRC: Batman
In-game: Batman

Re: Post your modding questions here

by Don » Sat Jan 09, 2016 17:33

everamzah wrote:I think using on_place will require managing the itemstack and so on, whereas after_place_node won't.

If you place a node and then use after_place_node wouldn't that mean that you would have to remove the placed node and return it to the player? I might not understand the process of each enough. Could you expand on what you are saying?
Many of my mods are now a part of Minetest-mods. A place where you know they are maintained!

A list of my mods can be found here
 

User avatar
stu
Member
 
Posts: 923
Joined: Sat Feb 02, 2013 02:51
Location: United Kingdom
GitHub: stujones11

Re: Post your modding questions here

by stu » Sat Jan 09, 2016 17:52

Don wrote:If you place a node and then use after_place_node wouldn't that mean that you would have to remove the placed node and return it to the player?

Yeah, that's exactly what I am trying to avoid, how does one tell on_place to abort and not actually place anything?

@everamzah, thanks, I will look at those other mods you mentioned.

Edit:To abort on_place you simply return nil, duh :/ Thanks for the replies.
Last edited by stu on Sat Jan 09, 2016 19:59, edited 1 time in total.
 

User avatar
everamzah
Member
 
Posts: 490
Joined: Thu Jan 29, 2015 00:47
GitHub: everamzah
IRC: everamzah
In-game: everamzah

Re: Post your modding questions here

by everamzah » Sat Jan 09, 2016 19:59

Not sure about after_place_node without testing, but I wonder if it only visually shows up to the client, and is not actually added. I would be tempted to look at https://github.com/minetest/minetest/bl ... m.lua#L196 -- But that somehow feels improper.
 

User avatar
stu
Member
 
Posts: 923
Joined: Sat Feb 02, 2013 02:51
Location: United Kingdom
GitHub: stujones11

Re: Post your modding questions here

by stu » Sat Jan 09, 2016 20:00

Sorry, I edited just as you posted, see above ^
 

PreviousNext

Return to Modding Discussion



Who is online

Users browsing this forum: sorcerykid and 2 guests