🎃 Halloween Update

master
Lars Mueller 2019-10-31 21:54:06 +01:00
parent 7739976318
commit 53f17c0440
3 changed files with 47 additions and 42 deletions

View File

@ -1,5 +1,5 @@
function cmd_ext.show_help_formspec(sendername, query)
local chatcommand_info = chatcommand_info
local chatcommand_info = cmd_ext.chatcommand_info
if query then
local query = query:lower()
local function search(chatcommands)

View File

@ -3,9 +3,10 @@ include("cmdlib", "trie.lua")
local override_minetest = false
local error_format = minetest.get_color_escape_sequence("#FF0000").."%s"
local success_format = minetest.get_color_escape_sequence("#00FF00").."%s"
local chatcommands = trie.new()
chatcommand_info = {}
cmd_ext = {
chatcommands = trie.new(),
chatcommand_info = {},
error = function(str)
return string.format(error_format, str)
end,
@ -131,15 +132,15 @@ cmd_ext = {
definition.func = cmd_ext.build_func(definition)
local scopes=string_ext.split_without_limit(name, " ")
if #scopes == 1 then
chatcommand_info[name] = table_ext.tablecopy(definition)
trie.insert(chatcommands, name, definition, override)
cmd_ext.chatcommand_info[name] = table_ext.tablecopy(definition)
trie.insert(cmd_ext.chatcommands, name, definition, override)
else
local supercommand, super_info = trie.get(chatcommands, scopes[1]), chatcommand_info[scopes[1]]
local supercommand, super_info = trie.get(cmd_ext.chatcommands, scopes[1]), cmd_ext.chatcommand_info[scopes[1]]
if not supercommand then
supercommand = {subcommands = {}, func = function() end}
trie.insert(chatcommands, scopes[1], supercommand)
trie.insert(cmd_ext.chatcommands, scopes[1], supercommand)
super_info = {subcommands = {}}
chatcommand_info[scopes[1]] = super_info
cmd_ext.chatcommand_info[scopes[1]] = super_info
end
local inherited_privs = table_ext.tablecopy(supercommand.privs or {})
for i = 2, #scopes-1 do
@ -187,7 +188,7 @@ cmd_ext = {
function cmd_ext.handle_chat_message(sendername, message)
if message:sub(1, 1) == "/" then
local last_space, next_space = 2, message:find(" ")
local command_trie, command_name = chatcommands
local command_trie, command_name = cmd_ext.chatcommands
local cmd, suggestion
repeat
next_space = next_space or message:len()+1
@ -257,5 +258,5 @@ minetest.register_on_mods_loaded(function()
table.sort(new_info, function(d1, d2) return d1.name < d2.name end)
return new_info
end
chatcommand_info = convert(chatcommand_info)
cmd_ext.chatcommand_info = convert(cmd_ext.chatcommand_info)
end)

View File

@ -3,32 +3,26 @@ trie = {}
local tr = trie
-- creates new trie : {}
function trie.new()
return {}
end
function trie.new() return {} end
-- inserts word into trie
function trie.insert(trie, word, value, overwrite)
for i=1, word:len() do
local char = word:sub(i,i)
for i = 1, word:len() do
local char = word:sub(i, i)
trie[char] = trie[char] or {}
trie = trie[char]
end
local was_leaf = trie.is_leaf
if (not was_leaf) or overwrite then
trie.is_leaf = value or true
end
if (not was_leaf) or overwrite then trie.is_leaf = value or true end
return was_leaf
end
-- removes word from trie if exists
function trie.remove(trie, word)
local branch, character = trie, word:sub(1, 1)
for i=1, word:len()-1 do
local char = word:sub(i,i)
if not trie[char] then
return nil
end
for i = 1, word:len() - 1 do
local char = word:sub(i, i)
if not trie[char] then return nil end
if trie[char].is_leaf or next(trie, next(trie)) then
branch = trie
character = char
@ -36,26 +30,20 @@ function trie.remove(trie, word)
trie = trie[char]
end
local char = word:sub(word:len())
if not trie[char] then
return nil
end
if not trie[char] then return nil end
trie = trie[char]
local was_leaf = trie.is_leaf
trie.is_leaf = nil
if branch and not next(trie) then
branch[character] = nil
end
if branch and not next(trie) then branch[character] = nil end
return was_leaf
end
-- check whether trie contains word, returns value or false, subset of trie.search, higher performance when not found (searches no suggestion)
function trie.get(trie, word)
for i=1, word:len() do
local char = word:sub(i,i)
for i = 1, word:len() do
local char = word:sub(i, i)
trie = trie[char]
if not trie then
return nil
end
if not trie then return nil end
end
return trie.is_leaf
end
@ -65,11 +53,11 @@ function trie.suggestion(trie, remainder)
local subtries = {[trie] = until_now}
local suggestion, value
while next(subtries) do
local new_subtries={}
local new_subtries = {}
local leaves = {}
for trie, word in pairs(subtries) do
if trie.is_leaf then
table.insert(leaves, {word=word, value=trie.is_leaf})
table.insert(leaves, {word = word, value = trie.is_leaf})
end
end
if #leaves > 0 then
@ -79,7 +67,7 @@ function trie.suggestion(trie, remainder)
for _, leaf in pairs(leaves) do
local score = 0
for i = 1, math.min(#leaf.word, string.len(remainder)) do -- calculate intersection
if remainder:sub(i,i) == leaf.word[i] then
if remainder:sub(i, i) == leaf.word[i] then
score = score + 1
end
end
@ -109,12 +97,12 @@ end
-- searches word in trie, returns true if found, or (false, suggestion) when not
function trie.search(trie, word)
for i=1, word:len() do
local char = word:sub(i,i)
for i = 1, word:len() do
local char = word:sub(i, i)
if not trie[char] then
local until_now = word:sub(1, i-1)
local until_now = word:sub(1, i - 1)
local suggestion, value = tr.suggestion(trie, word:sub(i))
return nil, until_now..suggestion, value
return nil, until_now .. suggestion, value
end
trie = trie[char]
end
@ -122,5 +110,21 @@ function trie.search(trie, word)
if is_leaf then return is_leaf end
local until_now = word
local suggestion, value = tr.suggestion(trie)
return nil, until_now..suggestion, value
return nil, until_now .. suggestion, value
end
function trie.find_longest(trie, query, query_offset)
local leaf_pos = query_offset
local last_leaf
for i = query_offset, query:len() do
local char = query:sub(i, i)
trie = trie[char]
if not trie then
break
elseif trie.is_leaf then
last_leaf = trie.is_leaf
leaf_pos = i
end
end
return last_leaf, leaf_pos
end