summaryrefslogtreecommitdiff
path: root/lib/mods/theme/core/util.lua
diff options
context:
space:
mode:
Diffstat (limited to 'lib/mods/theme/core/util.lua')
-rw-r--r--lib/mods/theme/core/util.lua257
1 files changed, 257 insertions, 0 deletions
diff --git a/lib/mods/theme/core/util.lua b/lib/mods/theme/core/util.lua
new file mode 100644
index 00000000..997f1eba
--- /dev/null
+++ b/lib/mods/theme/core/util.lua
@@ -0,0 +1,257 @@
+-- various stuff to make scripters life easier
+
+-- Beware of the scary undefined globals
+function safe_getglobal(x)
+ local v = rawget(globals(), x)
+
+ if v then
+ return v
+ else
+ error("undefined global variable '"..x.."'")
+ end
+end
+
+function set_safe_globals()
+ settagmethod(tag(nil), "getglobal", safe_getglobal)
+end
+function unset_safe_globals()
+ settagmethod(tag(nil), "getglobal", nil)
+end
+
+set_safe_globals()
+
+-- Patch modules
+__patch_modules = {}
+
+function patch_version(name, version)
+ assert(not __patch_modules[name], "Patch " .. name .. " already loaded!!!")
+ __patch_modules[name] = version
+end
+
+function patchs_list()
+ local k, e, first
+ first = FALSE
+ for k, e in __patch_modules do
+ if first == FALSE then print_hook("\n\n [Patch modules]\n") first = TRUE end
+ print_hook("\n "..k.." version "..e)
+ end
+ if first == TRUE then print_hook("\n") end
+end
+
+function patchs_display()
+ local k, e
+ for k, e in __patch_modules do
+ msg_print("Patch: "..k.." version "..e)
+ end
+end
+
+
+-- Better hook interface
+__hooks_list_callback = {}
+__hooks_list_callback_max = 0
+
+function add_hooks(h_table, name_prefix)
+ local k, e
+
+ if not name_prefix then name_prefix = "" end
+ for k, e in h_table do
+ add_hook_script(k, "__"..name_prefix.."__hooks_list_callback"..__hooks_list_callback_max, "__"..name_prefix.."__hooks_list_callback"..__hooks_list_callback_max)
+ setglobal("__"..name_prefix.."__hooks_list_callback"..__hooks_list_callback_max, e)
+ __hooks_list_callback_max = __hooks_list_callback_max + 1
+ end
+end
+
+-- Wrapper for the real msg_print and cmsg_print
+-- it understands if we want color or not
+function msg_print(c, m)
+ if type(c) == "number" then
+ cmsg_print(c, m)
+ else
+ call(%msg_print, { c })
+ end
+end
+
+-- Returns the direction of the compass that y2, x2 is from y, x
+-- the return value will be one of the following: north, south,
+-- east, west, north-east, south-east, south-west, north-west,
+-- or "close" if it is within 2 tiles.
+function compass(y, x, y2, x2)
+ local y_axis, x_axis, y_diff, x_diff, compass_dir
+
+ -- is it close to the north/south meridian?
+ y_diff = y2 - y
+
+ -- determine if y2, x2 is to the north or south of y, x
+ if (y_diff > -3) and (y_diff < 3) then
+ y_axis = nil
+ elseif y2 > y then
+ y_axis = "south"
+ else
+ y_axis = "north"
+ end
+
+ -- is it close to the east/west meridian?
+ x_diff = x2 - x
+
+ -- determine if y2, x2 is to the east or west of y, x
+ if (x_diff > -3) and (x_diff < 3) then
+ x_axis = nil
+ elseif x2 > x then
+ x_axis = "east"
+ else
+ x_axis = "west"
+ end
+
+ -- Maybe it is very close
+ if ((not x_axis) and (not y_axis)) then compass_dir = "close"
+ -- Maybe it is (almost) due N/S
+ elseif not x_axis then compass_dir = y_axis
+ -- Maybe it is (almost) due E/W
+ elseif not y_axis then compass_dir = x_axis
+ -- or if it is neither
+ else compass_dir = y_axis.."-"..x_axis
+ end
+
+ return compass_dir
+end
+
+-- Returns a relative approximation of the 'distance' of y2, x2 from y, x.
+function approximate_distance(y, x, y2, x2)
+ local y_diff, x_diff, most_dist
+
+ -- how far to away to the north/south
+ y_diff = y2 - y
+
+ -- make sure it's a positive integer
+ if y_diff < 0 then
+ y_diff = 0 - y_diff
+ end
+
+ -- how far to away to the east/west
+ x_diff = x2 - x
+
+ -- make sure it's a positive integer
+ if x_diff < 0 then
+ x_diff = 0 - x_diff
+ end
+
+ -- find which one is the larger distance
+ if x_diff > y_diff then
+ most_dist = x_diff
+ else
+ most_dist = y_diff
+ end
+
+ -- how far away then?
+ if most_dist >= 41 then
+ how_far = "a very long way"
+ elseif most_dist >= 25 then
+ how_far = "a long way"
+ elseif most_dist >= 8 then
+ how_far = "quite some way"
+ else
+ how_far = "not very far"
+ end
+
+ return how_far
+
+end
+
+-- better timer add function
+__timers_callback_max = 0
+
+function new_timer(t)
+ assert(t.delay > 0, "no timer delay")
+ assert(t.enabled, "no timer enabled state")
+ assert(t.callback, "no timer callback")
+
+ local timer
+ if type(t.callback) == "function" then
+ setglobal("__timers_callback_"..__timers_callback_max, t.callback)
+ timer = %new_timer("__timers_callback_"..__timers_callback_max, t.delay)
+ __timers_callback_max = __timers_callback_max + 1
+ else
+ timer = %new_timer(t.callback, t.delay)
+ end
+
+ timer.enabled = t.enabled
+
+ return timer
+end
+
+-- saves all timer values
+function save_timer(name)
+ add_loadsave(name..".enabled", FALSE)
+ add_loadsave(name..".delay", 1)
+ add_loadsave(name..".countdown", 1)
+end
+
+
+-- displays a scrolling list
+function display_list(y, x, h, w, title, list, begin, sel, sel_color)
+ local l = create_list(getn(list))
+
+ for i = 1, getn(list) do
+ add_to_list(l, i - 1, list[i])
+ end
+
+ %display_list(y, x, h, w, title, l, getn(list), begin - 1, sel - 1, sel_color)
+
+ delete_list(l, getn(list))
+end
+
+-- Easier access to special gene stuff
+function set_monster_generation(monster, state)
+ if type(monster) == "string" then
+ m_allow_special[test_monster_name(monster) + 1] = state
+ else
+ m_allow_special[monster + 1] = state
+ end
+end
+function set_object_generation(obj, state)
+ if type(obj) == "string" then
+ m_allow_special[test_item_name(obj) + 1] = state
+ else
+ m_allow_special[obj + 1] = state
+ end
+end
+function set_artifact_generation(obj, state)
+ m_allow_special[obj + 1] = state
+end
+
+-- Strings
+function strcap(str)
+ if strlen(str) > 1 then
+ return strupper(strsub(str, 1, 1))..strsub(str, 2)
+ elseif strlen(str) == 1 then
+ return strupper(str)
+ else
+ return str
+ end
+end
+
+function msg_format(...)
+ msg_print(call(format, arg))
+end
+
+-- Stacks
+function stack_push(stack, val)
+ tinsert(stack, val)
+end
+function stack_pop(stack)
+ if getn(stack) >= 1 then
+ return tremove(stack)
+ else
+ error("Tried to unstack an empty stack")
+ return nil
+ end
+end
+
+-- A way to check if the game is now running(as opposed to initialization/character gen)
+game = {}
+add_hooks
+{
+ [HOOK_GAME_START] = function ()
+ game.started = TRUE
+ end
+}