1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 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
}
|