Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

Problem with string.find and string.sub please help ??

Asked by 5 years ago
Edited 5 years ago

Hi all i´m making a script to talk with npcs but i have a problem, i need to cut in some Dialogs the sentences {Player Name} and change it for the actual player´s name and it doesn´t work, so that´s my code.

I´m using string for the dialogs.


local DialogArray = { ["Gretting"] = "Hi {Player Name} I´m jake" -- Dialog } function Talk() local PlayerFound = string.find(DialogArray[1], "{Player Name}") -- Searchs on the string {Player Name} if PlayerFound then local ChangedText = string.sub(PlayerFound, #PlayerFound) -- It try to cut the Word {Player Name} DialogArray[1] = ChangedText print(ChangedText) end end

When i try to print that appears:

ServerScriptService.Script:6: bad argument #1 to 'find' (string expected, got nil) 19:12:12.655 - Stack Begin 19:12:12.656 - Script 'ServerScriptService.Script', Line 6 - global Talk 19:12:12.656 - Script 'ServerScriptService.Script', Line 15 19:12:12.657 - Stack End

This is what I'm trying to print:

Hi imago15 I´m jake"

Please Help me i need this Urgent, I'm sorry if it seems Badly written is because I do not use string well Thanks.

0
Are you using a custom dialog (such as done with guis) or the pre-made ROBLOX Dialog / DialogChoices? SerpentineKing 3885 — 5y
0
Sorry Nope, I´m Using an Array with strings for dialogs imagYTOP 19 — 5y

3 answers

Log in to vote
0
Answered by 5 years ago

Problems:


1: the DialogArray is a dictionary, not an array. Which means that its indexes/keys aren't integers.

2:the length syntax # returns the length of an array, not a dictionary, for dictionaries, it always returns 0.

3:that isn't the use of the sub function, thats the use of the gsub function


Patterns and formatting


most patterns in lua are the percentage symbol followed by a single letter, for example %a for letters, %d for digits, and %w for alphanumeric symbols (numbers + letters).

one of the ways to utilize patterns is the string.format function. An example of which is :

local Str = "Please excuse my dear aunt %w"

print(string.format(Str,"Sally"))--"Please excuse my dear aunt Sally"

You can probably see where it is going at this point.


Heads up for using string patterns


in the example of the string.format function, i just used %w without anything else. Beware that this isn't enough for functions like gmatch and gsub. just using something like %w would only return 1 iteration. For it to return multiple iterations for those functions, you would have to do something along the lines of %w+


Application


With that said:

local PlayerName = "imago15"
local Dialogs = {
    ["Greeting"] = "Hi %w I´m jake" -- Dialog
}

function Talk() 
    local ChangedText = string.format(Dialogs.Greeting,PlayerName)
    DialogArray.Greeting = ChangedText
end

However, if you are using patterns like %w elsewhere, you could still use you original method of substitution

local PlayerName = "imago15"
local Dialogs = {
    ["Greeting"] = "Hi {PlayerName} I´m jake" -- Dialog
}

function Talk() 
    if Dialogs.Greeting:lower():find("{playername}") then--case insensitive
        local ChangedText = Dialogs.Greeting:gsub("{playername}",PlayerName)
        DialogArray.Greeting = ChangedText
    end
end

Use of functions in the string library as methods


You may have noticed that I used some of the functions in the string library as method, that being functions with a : instead of a .. Those are generally used for convenience as the string being modified doesn't have to be defined as a parameter.

But generally, str:format() and string.format(str) are the same thing


Reference Links


string library

0
Thank you, very well explained imagYTOP 19 — 5y
0
I would also like to say that %s would also work theking48989987 2147 — 5y
0
ah ok imagYTOP 19 — 5y
Ad
Log in to vote
0
Answered by
Rare_tendo 3000 Moderation Voter Community Moderator
5 years ago
Edited 5 years ago

string.find returns two values if the pattern was found in the string: the start of the pattern, and the end of the pattern. You can these two values(you should also know that the greeting there doesn't have an index of one, it's index is 'Greeting'.

local tbl = {
       'hi'; -- has an index of 1
       'roblox'; -- has an index of 2
       ['rlua'] = 'roblox lua'; value is 'roblox lua', but its index is 'rlua'
}

-- code break

local DialogArray = {
    ["Gretting"] = "Hi {Player Name} I´m jake" -- Dialog
}

function Talk() 
    local s, e = string.find(DialogArray['Greeting'], "{Player Name}")

    if PlayerFound then
        local ChangedText = string.sub(DialogArray['Greeting'], s, e)
        DialogArray['Greeting'] = ChangedText
    end
end
Log in to vote
0
Answered by 5 years ago
Edited 5 years ago

So I'm going to suggest at least two ways to circumvent this first, if you're not against using a LocalScript (which is most likely preferred for this since you want the Dialog to be player dependent) then you could do the following:

local player = game.Players.LocalPlayer

local DialogArray = {
["Greeting"] = ("Hi "..player.Name..", I'm Jake"),
["Next"] = ("Next")
}

function Talk()
    print(DialogArray["Greeting"])
end

Talk()

On a Server Script, you could edit the table like so:

local DialogArray = {}

game.Players.PlayerAdded:Connect(function(player)

DialogArray = {
["Greeting"] = ("Hi "..player.Name..", I'm Jake"),
["Next"] = ("Next")
}

local function Talk()
    print(DialogArray["Greeting"])
end

Talk()

end)

The PlayerAdded event could be substituted for a .Touched or .Changed Event or other similar event if you preferred to alter the Dialog that way (as long as they are able to produce the player's name).

If you place the local Talk function outside the PlayerAdded function in this example, adding a wait time will ensure that the new value for dialog is read (but this would affect the entire server and only be altered once)

This would remove the need for the string-based changes.

In addition, the use of the ["Greeting"] defines the key of that value, which would otherwise be DialogArray[1] (as you attempted to write within your script) if the key had not been pre-defined.

Regarding String Changes, the above Answer covers this.

0
I'm sorry but you left the topic :/ imagYTOP 19 — 5y

Answer this question