• There is NO official Otland's Discord server and NO official Otland's server list. The Otland's Staff does not manage any Discord server or server list. Moderators or administrator of any Discord server or server lists have NO connection to the Otland's Staff. Do not get scammed!

Solved target name contains [tfs 1.2]

Aeronx

Intermediate OT User
Joined
Dec 17, 2015
Messages
735
Solutions
9
Reaction score
119
Hello guys!

I've been trying all day long, searched the whole internet, but i have been totally unsuccesfull and i am on my nerves lol

I have this table:
Lua:
local config = {
     ['gang member'] = {amount = 20, storage = 21901, startstorage = 45553, startvalue = 1},
     ['smuggler'] = {amount = 20, storage = 21902, startstorage = 45553, startvalue = 1},
     ['orc'] = {amount = 10, storage = 21903, startstorage = 45553, startvalue = 2},
     ['orc warrior'] = {amount = 10, storage = 21904, startstorage = 45553, startvalue = 2},
     ['orc berserker'] = {amount = 5, storage = 21905, startstorage = 45553, startvalue = 2},
     ['orc shaman'] = {amount = 5, storage = 21906, startstorage = 45553, startvalue = 2},
     ['elf'] = {amount = 20, storage = 21907, startstorage = 45553, startvalue = 3},
     ['elf scout'] = {amount = 15, storage = 21908, startstorage = 45553, startvalue = 3},
     ['elf arcanist'] = {amount = 5, storage = 21909, startstorage = 45553, startvalue = 3},
     ['cyclops'] = {amount = 20, storage = 21910, startstorage = 45553, startvalue = 4},
     ['cyclops drone'] = {amount = 10, storage = 21911, startstorage = 45553, startvalue = 4},
     ['cyclops smith'] = {amount = 5, storage = 21912, startstorage = 45553, startvalue = 4},
     ['lizard sentinel'] = {amount = 30, storage = 21914, startstorage = 45554, startvalue = 2},
     ['lizard snakecharmer'] = {amount = 30, storage = 21915, startstorage = 45554, startvalue = 2},
     ['lizard templar'] = {amount = 30, storage = 21916, startstorage = 45554, startvalue = 2},
     ['dragon'] = {amount = 100, storage = 21917, startstorage = 45554, startvalue = 4},
     ['yeti'] = {amount = 100, storage = 21919, startstorage = 45555, startvalue = 2},
     ['frost dragon'] = {amount = 50, storage = 21920, startstorage = 45555, startvalue = 3},
}

Monsters names have level. So instead of being for example "gang member" name is "gang member [Lv.1]"

Before i could easily use this:
Lua:
local monster = config[target:getName():lower()]
But now it doesnt recognize the name. So to avoid making this table 10000xtimes I wanted to somehow get the monster name
but erase the part [Lv.X] or check the name if contains at least "gang member" on its name.

To try to accomplish this i have used string.find, gsub, and many others that i found here and other forums, but i totally failed.

Any help would be welcome!

This is the whole code in case you need it:
Lua:
local config = {
     ['gang member'] = {amount = 20, storage = 21901, startstorage = 45553, startvalue = 1},
     ['smuggler'] = {amount = 20, storage = 21902, startstorage = 45553, startvalue = 1},
     ['orc'] = {amount = 10, storage = 21903, startstorage = 45553, startvalue = 2},
     ['orc warrior'] = {amount = 10, storage = 21904, startstorage = 45553, startvalue = 2},
     ['orc berserker'] = {amount = 5, storage = 21905, startstorage = 45553, startvalue = 2},
     ['orc shaman'] = {amount = 5, storage = 21906, startstorage = 45553, startvalue = 2},
     ['elf'] = {amount = 20, storage = 21907, startstorage = 45553, startvalue = 3},
     ['elf scout'] = {amount = 15, storage = 21908, startstorage = 45553, startvalue = 3},
     ['elf arcanist'] = {amount = 5, storage = 21909, startstorage = 45553, startvalue = 3},
     ['cyclops'] = {amount = 20, storage = 21910, startstorage = 45553, startvalue = 4},
     ['cyclops drone'] = {amount = 10, storage = 21911, startstorage = 45553, startvalue = 4},
     ['cyclops smith'] = {amount = 5, storage = 21912, startstorage = 45553, startvalue = 4},
     ['lizard sentinel'] = {amount = 30, storage = 21914, startstorage = 45554, startvalue = 2},
     ['lizard snakecharmer'] = {amount = 30, storage = 21915, startstorage = 45554, startvalue = 2},
     ['lizard templar'] = {amount = 30, storage = 21916, startstorage = 45554, startvalue = 2},
     ['dragon'] = {amount = 100, storage = 21917, startstorage = 45554, startvalue = 4},
     ['yeti'] = {amount = 100, storage = 21919, startstorage = 45555, startvalue = 2},
     ['frost dragon'] = {amount = 50, storage = 21920, startstorage = 45555, startvalue = 3},
}

function onKill(player, target)
     --local player, target = Player(player), Creature(target) -- for TFS 1.0, delete this line if you use 1.1
     local monster = config[target:getName():lower()]
     if target:isPlayer() or not monster or target:getMaster() then
         return true
     end
     local stor = player:getStorageValue(monster.storage)+1
     if stor < monster.amount and player:getStorageValue(monster.startstorage) >= monster.startvalue then
         player:setStorageValue(monster.storage, stor)
         player:sendTextMessage(MESSAGE_STATUS_CONSOLE_ORANGE, 'Task message: '..(stor +1)..' of '..monster.amount..' '..target:getName()..'s killed.')
     end
     if (stor +1) == monster.amount then
         player:sendTextMessage(MESSAGE_INFO_DESCR, 'Congratulations, you have killed '..(stor +1)..' '..target:getName()..'s and completed the '..target:getName()..'s mission.')
         player:setStorageValue(monster.storage, stor +1)
     end
     return true
end

Thanks for your time.
 
Lua:
local fullName = target:getName():lower()
local name = string.split(fullName, "["):match("^%s*(.-)%s*$")
local monster = config[name]
 
no point in splitting the string, just use match
Lua:
local name = target:getName():lower():match("([%a%s]*) %[Lv. %d*%]")
 
Solution
Thank you guys! that solved the issue!

@Static_ Would you mind explaining or poiting me out where can I find the meaning of %a%s%d the combination with *] etc.. I am trying to learn a bit about it.
Thank you for your time.
 
The pil has extra information Programming in Lua : 20.2

Basically:
target:getName() = gets the name
target:getName():lower() = lower the name
"string":match("([%a%s]*) %[Lv. %d*%]") = searches for the pattern in the "string"

about the pattern:
([%a%s]*) %[Lv. %d*%]: NEVER analyze a pattern seeing the whole, start by small parts otherwise you'll get confused very very fast.
for this case I'm assuming two parts, and I'll be splitting them until we find something we can analyze.
first part: ([%a%s]*)
second part: %[Lv. %d*%]

for the first part, %a represents all letters and %s the spaces, so basically I make a set containing both when using the [%a%s]. If we have "Demon Skeleton" it will match "n " because it's the only set containing a letter and a space together; The trick here is the * outside of the set, it means 0 or infinite recurrences and will always try to match the most;
In the case of "Demon Skeleton" is easy to see we would have to do "%a%a%a%a%a%s%a%a%a%a%a%a%a%a" which is really annoying since its a %a for every letter and %s for every space. So we can use %a*%s*%a* which also works, but it's a problem when we have creatures with more than two names because it will only match the first two. So basically when we use [%a%s]* we are telling: bring me anything that is a set of chars with any set of spaces with any set of chars with any set of spaces... and so go on.

Ok, so [%a%s]* brings us the name of the character.

As for the second part: %[ is used to represent the '[' and the same applies to %] so we are looking for anything in the middle of brackets. this alone could totally do the trick: %[.*%] because it says: give me anything that is inside brackets but he wanted to follow your pattern specifically, so he used Lv. %d* that is basically matches anything that is in the format "Lv. any number" %d is digits and %d* says: it can be any number of digits so your level can be higher than 9.

Hope you understood
 
@Night Wolf Thank you sir. I had an idea after reading the link that @Static_ posted, but your post helped me to understand some other concepts.

Really appreciate the time you took to write the post, thank you for the lesson.
 
You're welcome ;]

Pattern matching is very confusing at first, but it's very similar to how Nondeterministic finite automaton - Wikipedia works.
It simply reads regular expressions. A few years ago I was like "wtf, I'll never learn pattern matching" but now I use it to almost everything (I'm not kidding). A few days ago I literally used pattern matching to extract all the items from all npcs and separate them in buy/sell. Exported this data to excel and removed duplicates just to check which items could be bought/sold in the entire game.

Once you go pattern, you can never go back haha
 
Wow.. that's actually usefull, checking NPC.
Hmm i may try myself!

Thank you again sir!
 
Back
Top