diff options
Diffstat (limited to 'LuaSL/LSL.lua')
-rw-r--r-- | LuaSL/LSL.lua | 870 |
1 files changed, 0 insertions, 870 deletions
diff --git a/LuaSL/LSL.lua b/LuaSL/LSL.lua deleted file mode 100644 index 662c880..0000000 --- a/LuaSL/LSL.lua +++ /dev/null | |||
@@ -1,870 +0,0 @@ | |||
1 | -- A module of LSL stuffs. | ||
2 | |||
3 | -- Using a module means it gets compiled each time? Maybe not if I can use bytecode files. Perhaps LuaJIT caches these? | ||
4 | -- Does not seem to be slowing it down noticably, but that might change once the stubs are filled out. | ||
5 | |||
6 | -- Use it like this - | ||
7 | -- local _LSL = require 'LSL' | ||
8 | |||
9 | --[[ From http://lua-users.org/wiki/LuaModuleFunctionCritiqued | ||
10 | A related note on C code: The luaL_register [9] function in C is | ||
11 | somewhat analogous to the module function in Lua, so luaL_register | ||
12 | shares similar problems, at least when a non-NULL libname is used. | ||
13 | Furthermore, the luaL_newmetatable/luaL_getmetatable/luaL_checkudata | ||
14 | functions use a C string as a key into the global registry. This poses | ||
15 | some potential for name conflicts--either because the modules were | ||
16 | written by different people or because they are different versions of | ||
17 | the same module loaded simultaneously. To address this, one may instead | ||
18 | use a lightuserdata (pointer to variable of static linkage to ensure | ||
19 | global uniqueness) for this key or store the metatable as an | ||
20 | upvalue--either way is a bit more efficient and less error prone. | ||
21 | ]] | ||
22 | |||
23 | -- http://www.lua.org/pil/15.4.html looks useful. | ||
24 | -- http://www.lua.org/pil/15.5.html the last part about autoloading functions might be useful. | ||
25 | |||
26 | |||
27 | local LSL = {}; | ||
28 | local SID = ""; | ||
29 | local scriptName = ""; | ||
30 | local running = true | ||
31 | local paused = false | ||
32 | local currentState = {} | ||
33 | local detectedGroups = {} | ||
34 | local detectedGrabs = {} | ||
35 | local detectedKeys = {} | ||
36 | local detectedLinkNumbers = {} | ||
37 | local detectedNames = {} | ||
38 | local detectedOwners = {} | ||
39 | local detectedPoss = {} | ||
40 | local detectedRots = {} | ||
41 | local detectedTouchBinormals = {} | ||
42 | local detectedTouchFaces = {} | ||
43 | local detectedTouchNormals = {} | ||
44 | local detectedTouchPoss = {} | ||
45 | local detectedTouchSTs = {} | ||
46 | local detectedTouchUVs = {} | ||
47 | local detectedTypes = {} | ||
48 | local detectedVels = {} | ||
49 | local waitAndProcess | ||
50 | |||
51 | |||
52 | -- Debugging aids | ||
53 | |||
54 | -- Functions to print tables. | ||
55 | local print_table, print_table_start | ||
56 | |||
57 | function print_table_start(table, space, name) | ||
58 | print(space .. name .. ": "); | ||
59 | print(space .. "{"); | ||
60 | print_table(table, space .. " "); | ||
61 | print(space .. "}"); | ||
62 | end | ||
63 | |||
64 | function print_table(table, space) | ||
65 | for k, v in pairs(table) do | ||
66 | if type(v) == "table" then | ||
67 | print_table_start(v, space, k); | ||
68 | elseif type(v) == "string" then | ||
69 | print(space .. k .. ': "' .. v .. '";') | ||
70 | else | ||
71 | print(space .. k .. ": " .. v .. ";") | ||
72 | end | ||
73 | end | ||
74 | end | ||
75 | |||
76 | function msg(...) | ||
77 | print(SID, ...) -- The comma adds a tab, fancy that. B-) | ||
78 | end | ||
79 | |||
80 | |||
81 | -- Stuff called from the wire protocol has to be global, but I think this means just global to this file. | ||
82 | |||
83 | events = {} | ||
84 | |||
85 | function start() paused = false end | ||
86 | function stop() paused = true end | ||
87 | function quit() running = false end | ||
88 | |||
89 | function events.detectedGroups(list) detectedGroups = list end | ||
90 | function events.detectedGrabs(list) detectedGrabs = list end | ||
91 | function events.detectedKeys(list) detectedKeys = list end | ||
92 | function events.detectedLinkNumbers(list) detectedLinkNumbers = list end | ||
93 | function events.detectedNames(list) detectedNames = list end | ||
94 | function events.detectedOwners(list) detectedOwners = list end | ||
95 | function events.detectedPoss(list) detectedPoss = list end | ||
96 | function events.detectedRots(list) detectedRots = list end | ||
97 | function events.detectedTouchBinormals(list) detectedTouchBinormals = list end | ||
98 | function events.detectedTouchFaces(list) detectedTouchFaces = list end | ||
99 | function events.detectedTouchNormals(list) detectedTouchNormals = list end | ||
100 | function events.detectedTouchPoss(list) detectedTouchPoss = list end | ||
101 | function events.detectedTouchSTs(list) detectedTouchSTs = list end | ||
102 | function events.detectedTouchUVs(list) detectedTouchUVs = list end | ||
103 | function events.detectedTypes(list) detectedTypes = list end | ||
104 | function events.detectedVels(list) detectedVels = list end | ||
105 | |||
106 | function events.detectsClear() | ||
107 | detectedGroups = {} | ||
108 | detectedGrabs = {} | ||
109 | detectedKeys = {} | ||
110 | detectedLinkNumbers = {} | ||
111 | detectedNames = {} | ||
112 | detectedOwners = {} | ||
113 | detectedPoss = {} | ||
114 | detectedRots = {} | ||
115 | detectedTouchBinormals = {} | ||
116 | detectedTouchFaces = {} | ||
117 | detectedTouchNormals = {} | ||
118 | detectedTouchPoss = {} | ||
119 | detectedTouchSTs = {} | ||
120 | detectedTouchUVs = {} | ||
121 | detectedTypes = {} | ||
122 | detectedVels = {} | ||
123 | end | ||
124 | |||
125 | function events.at_rot_target(tnum, targetrot, ourrot) if nil ~= currentState.at_rot_target then currentState.at_rot_target(tnum, targetrot, ourrot) end events.detectsClear() end | ||
126 | function events.at_target(tnum, targetpos, ourpos) if nil ~= currentState.at_target then currentState.at_target(tnum, targetpos, ourpos) end events.detectsClear() end | ||
127 | function events.attach(id) if nil ~= currentState.attach then currentState.attach(id) end events.detectsClear() end | ||
128 | function events.changed(change) if nil ~= currentState.changed then currentState.changed(change) end events.detectsClear() end | ||
129 | function events.collision_start(num_detected) if nil ~= currentState.collision_start then currentState.collision_start(num_detected) end events.detectsClear() end | ||
130 | function events.collision(num_detected) if nil ~= currentState.collision then currentState.collision(num_detected) end events.detectsClear() end | ||
131 | function events.collision_end(num_detected) if nil ~= currentState.collision_end then currentState.collision_end(num_detected) end events.detectsClear() end | ||
132 | function events.control(id, held, changed) if nil ~= currentState.control then currentState.control(id, held, changed) end events.detectsClear() end | ||
133 | function events.dataserver(queryid, data) if nil ~= currentState.dataserver then currentState.dataserver(queryid, data) end events.detectsClear() end | ||
134 | function events.email(Time, address, subj, message, num_left) if nil ~= currentState.email then currentState.email(Time, address, subj, message, num_left) end events.detectsClear() end | ||
135 | function events.http_request(request_id, status, metadata, body) if nil ~= currentState.http_request then currentState.http_request(request_id, status, metadata, body) end events.detectsClear() end | ||
136 | function events.http_response(request_id, status, metadata, body) if nil ~= currentState.http_response then currentState.http_response(request_id, status, metadata, body) end events.detectsClear() end | ||
137 | function events.land_collision_start(pos) if nil ~= currentState.land_collision_start then currentState.land_collision_start(pos) end events.detectsClear() end | ||
138 | function events.land_collision(pos) if nil ~= currentState.land_collision then currentState.land_collision(pos) end events.detectsClear() end | ||
139 | function events.land_collision_end(pos) if nil ~= currentState.land_collision_end then currentState.land_collision_end(pos) end events.detectsClear() end | ||
140 | function events.link_message(sender_num, num, str, id) if nil ~= currentState.link_message then currentState.link_message(sender_num, num, str, id) end events.detectsClear() end | ||
141 | function events.listen(channel, name, id, message) if nil ~= currentState.listen then currentState.listen(channel, name, id, message) end events.detectsClear() end | ||
142 | function events.money(id, amount) if nil ~= currentState.money then currentState.money(id, amount) end events.detectsClear() end | ||
143 | function events.moving_start() if nil ~= currentState.moving_start then currentState.moving_start() end events.detectsClear() end | ||
144 | function events.moving_end() if nil ~= currentState.moving_end then currentState.moving_end() end events.detectsClear() end | ||
145 | function events.no_sensor() if nil ~= currentState.no_sensor then currentState.no_sensor() end events.detectsClear() end | ||
146 | function events.not_at_rot_target() if nil ~= currentState.not_at_rot_target then currentState.not_at_rot_target() end events.detectsClear() end | ||
147 | function events.not_at_target() if nil ~= currentState.not_at_target then currentState.not_at_target() end events.detectsClear() end | ||
148 | function events.object_rez(id) if nil ~= currentState.object_rez then currentState.object_rez() end events.detectsClear() end | ||
149 | function events.on_rez(start_param) if nil ~= currentState.on_rezz then currentState.on_rez(start_param) end events.detectsClear() end | ||
150 | function events.remote_data(event_type, channel, message_id, sender, idata, sdata) if nil ~= currentState.remote_data then currentState.remote_data(event_type, channel, message_id, sender, idata, sdata) end events.detectsClear() end | ||
151 | function events.run_time_permissions(perm) if nil ~= currentState.run_time_permisions then currentState.run_time_permissions(perm) end events.detectsClear() end | ||
152 | function events.sensor(num_detected) if nil ~= currentState.sensor then currentState.sensor(num_detected) end events.detectsClear() end | ||
153 | function events.state_entry() if nil ~= currentState.state_entry then currentState.state_entry() end events.detectsClear() end | ||
154 | function events.state_exit() if nil ~= currentState.state_exit then currentState.state_exit() end events.detectsClear() end | ||
155 | function events.timer() if nil ~= currentState.timer then currentState.timer() end events.detectsClear() end | ||
156 | function events.touch_start(num_detected) if nil ~= currentState.touch_start then currentState.touch_start(num_detected) end events.detectsClear() end | ||
157 | function events.touch(num_detected) if nil ~= currentState.touch then currentState.touch(num_detected) end events.detectsClear() end | ||
158 | function events.touch_end(num_detected) if nil ~= currentState.touch_end then currentState.touch_end(num_detected) end events.detectsClear() end | ||
159 | function events.transaction_result(id, success, data) if nil ~= currentState.transaction_result then currentState.transaction_result(id, success, data) end events.detectsClear() end | ||
160 | |||
161 | |||
162 | -- LSL function and constant creation stuff. | ||
163 | |||
164 | local args2string -- Pre declare this. | ||
165 | local functions = {} | ||
166 | local mt = {} | ||
167 | |||
168 | local function value2string(value, Type) | ||
169 | local temp = "" | ||
170 | |||
171 | if "float" == Type then temp = temp .. value | ||
172 | elseif "integer" == Type then temp = temp .. value | ||
173 | elseif "key" == Type then temp = "\"" .. value .. "\"" | ||
174 | elseif "list" == Type then temp = "[" .. args2string(true, unpack(value)) .. "]" | ||
175 | elseif "table" == Type then temp = "[" .. args2string(true, unpack(value)) .. "]" | ||
176 | elseif "string" == Type then temp = "\"" .. value .. "\"" | ||
177 | elseif "rotation" == Type then temp = "<" .. value.x .. ", " .. value.y .. ", " .. value.z .. ", " .. value.s .. ">" | ||
178 | elseif "vector" == Type then temp = "<" .. value.x .. ", " .. value.y .. ", " .. value.z .. ">" | ||
179 | else | ||
180 | temp = temp .. value | ||
181 | end | ||
182 | return temp | ||
183 | end | ||
184 | |||
185 | function args2string(doType, ...) | ||
186 | local temp = "" | ||
187 | local first = true | ||
188 | |||
189 | for j,w in ipairs( {...} ) do | ||
190 | if first then first = false else temp = temp .. ", " end | ||
191 | if doType then | ||
192 | temp = temp .. value2string(w, type(w)) | ||
193 | else | ||
194 | temp = temp .. w | ||
195 | end | ||
196 | end | ||
197 | return temp | ||
198 | end | ||
199 | |||
200 | function mt.callAndReturn(name, ...) | ||
201 | luaproc.sendback(name .. "(" .. args2string(true, ...) .. ")") | ||
202 | end | ||
203 | |||
204 | function mt.callAndWait(name, ...) | ||
205 | mt.callAndReturn(name, ...); | ||
206 | -- Eventually a sendForth() is called, which should end up passing through SendToChannel(). | ||
207 | -- Wait for the result, which should be a Lua value as a string. | ||
208 | return waitAndProcess(true) | ||
209 | end | ||
210 | |||
211 | local function newConst(Type, name, value) | ||
212 | LSL[name] = value | ||
213 | return { Type = Type, name = name } | ||
214 | end | ||
215 | |||
216 | local function newFunc(Type, name, ... ) | ||
217 | functions[name] = { Type = Type, args = {...} } | ||
218 | if "" == Type then | ||
219 | LSL[name] = function(...) mt.callAndReturn(name, ... ) end | ||
220 | else | ||
221 | LSL[name] = function(...) return mt.callAndWait(name, ... ) end | ||
222 | end | ||
223 | end | ||
224 | |||
225 | |||
226 | -- LSL constants. | ||
227 | |||
228 | local constants = | ||
229 | { | ||
230 | newConst("float", "PI", 3.14159265358979323846264338327950), | ||
231 | newConst("float", "PI_BY_TWO", LSL.PI / 2), -- 1.57079632679489661923132169163975 | ||
232 | newConst("float", "TWO_PI", LSL.PI * 2), -- 6.28318530717958647692528676655900 | ||
233 | newConst("float", "DEG_TO_RAD", LSL.PI / 180.0), -- 0.01745329252 | ||
234 | newConst("float", "RAD_TO_DEG", 180.0 / LSL.PI), -- 57.2957795131 | ||
235 | newConst("float", "SQRT2", 1.4142135623730950488016887242097), | ||
236 | |||
237 | newConst("integer", "CHANGED_INVENTORY", 0x001), | ||
238 | newConst("integer", "CHANGED_COLOR", 0x002), | ||
239 | newConst("integer", "CHANGED_SHAPE", 0x004), | ||
240 | newConst("integer", "CHANGED_SCALE", 0x008), | ||
241 | newConst("integer", "CHANGED_TEXTURE", 0x010), | ||
242 | newConst("integer", "CHANGED_LINK", 0x020), | ||
243 | newConst("integer", "CHANGED_ALLOWED_DROP", 0x040), | ||
244 | newConst("integer", "CHANGED_OWNER", 0x080), | ||
245 | newConst("integer", "CHANGED_REGION", 0x100), | ||
246 | newConst("integer", "CHANGED_TELEPORT", 0x200), | ||
247 | newConst("integer", "CHANGED_REGION_START", 0x400), | ||
248 | newConst("integer", "CHANGED_MEDIA", 0x800), | ||
249 | |||
250 | newConst("integer", "DEBUG_CHANNEL", 2147483647), | ||
251 | newConst("integer", "PUBLIC_CHANNEL", 0), | ||
252 | |||
253 | newConst("integer", "INVENTORY_ALL", -1), | ||
254 | newConst("integer", "INVENTORY_NONE", -1), | ||
255 | newConst("integer", "INVENTORY_TEXTURE", 0), | ||
256 | newConst("integer", "INVENTORY_SOUND", 1), | ||
257 | newConst("integer", "INVENTORY_LANDMARK", 3), | ||
258 | newConst("integer", "INVENTORY_CLOTHING", 5), | ||
259 | newConst("integer", "INVENTORY_OBJECT", 6), | ||
260 | newConst("integer", "INVENTORY_NOTECARD", 7), | ||
261 | newConst("integer", "INVENTORY_SCRIPT", 10), | ||
262 | newConst("integer", "INVENTORY_BODYPART", 13), | ||
263 | newConst("integer", "INVENTORY_ANIMATION", 20), | ||
264 | newConst("integer", "INVENTORY_GESTURE", 21), | ||
265 | |||
266 | newConst("integer", "ALL_SIDES", -1), | ||
267 | newConst("integer", "LINK_SET", -1), | ||
268 | newConst("integer", "LINK_ROOT", 1), | ||
269 | newConst("integer", "LINK_ALL_OTHERS", -2), | ||
270 | newConst("integer", "LINK_ALL_CHILDREN", -3), | ||
271 | newConst("integer", "LINK_THIS", -4), | ||
272 | |||
273 | newConst("integer", "PERM_ALL", 0x7FFFFFFF), | ||
274 | newConst("integer", "PERM_COPY", 0x00008000), | ||
275 | newConst("integer", "PERM_MODIFY", 0x00004000), | ||
276 | newConst("integer", "PERM_MOVE", 0x00080000), | ||
277 | newConst("integer", "PERM_TRANSFER", 0x00002000), | ||
278 | newConst("integer", "MASK_BASE", 0), | ||
279 | newConst("integer", "MASK_OWNER", 1), | ||
280 | newConst("integer", "MASK_GROUP", 2), | ||
281 | newConst("integer", "MASK_EVERYONE", 3), | ||
282 | newConst("integer", "MASK_NEXT", 4), | ||
283 | newConst("integer", "PERMISSION_DEBIT", 0x0002), | ||
284 | newConst("integer", "PERMISSION_TAKE_CONTROLS", 0x0004), | ||
285 | newConst("integer", "PERMISSION_TRIGGER_ANIMATION", 0x0010), | ||
286 | newConst("integer", "PERMISSION_ATTACH", 0x0020), | ||
287 | newConst("integer", "PERMISSION_CHANGE_LINKS", 0x0080), | ||
288 | newConst("integer", "PERMISSION_TRACK_CAMERA", 0x0400), | ||
289 | newConst("integer", "PERMISSION_CONTRAL_CAMERA", 0x0800), | ||
290 | |||
291 | newConst("integer", "AGENT", 0x01), | ||
292 | newConst("integer", "ACTIVE", 0x02), | ||
293 | newConst("integer", "PASSIVE", 0x04), | ||
294 | newConst("integer", "SCRIPTED", 0x08), | ||
295 | |||
296 | newConst("integer", "OBJECT_UNKNOWN_DETAIL", -1), | ||
297 | |||
298 | newConst("integer", "PRIM_BUMP_SHINY", 19), | ||
299 | newConst("integer", "PRIM_COLOR", 18), | ||
300 | newConst("integer", "PRIM_FLEXIBLE", 21), | ||
301 | newConst("integer", "PRIM_FULLBRIGHT", 20), | ||
302 | newConst("integer", "PRIM_GLOW", 25), | ||
303 | newConst("integer", "PRIM_MATERIAL", 2), | ||
304 | newConst("integer", "PRIM_PHANTOM", 5), | ||
305 | newConst("integer", "PRIM_PHYSICS", 3), | ||
306 | newConst("integer", "PRIM_POINT_LIGHT", 23), | ||
307 | newConst("integer", "PRIM_POSITION", 6), | ||
308 | newConst("integer", "PRIM_ROTATION", 8), | ||
309 | newConst("integer", "PRIM_SIZE", 7), | ||
310 | newConst("integer", "PRIM_TEMP_ON_REZ", 4), | ||
311 | newConst("integer", "PRIM_TYPE", 9), | ||
312 | newConst("integer", "PRIM_TYPE_OLD", 1), | ||
313 | newConst("integer", "PRIM_TEXGEN", 22), | ||
314 | newConst("integer", "PRIM_TEXTURE", 17), | ||
315 | newConst("integer", "PRIM_TEXT", 26), | ||
316 | |||
317 | newConst("integer", "PRIM_BUMP_NONE", 0), | ||
318 | newConst("integer", "PRIM_BUMP_BRIGHT", 1), | ||
319 | newConst("integer", "PRIM_BUMP_DARK", 2), | ||
320 | newConst("integer", "PRIM_BUMP_WOOD", 3), | ||
321 | newConst("integer", "PRIM_BUMP_BARK", 4), | ||
322 | newConst("integer", "PRIM_BUMP_BRICKS", 5), | ||
323 | newConst("integer", "PRIM_BUMP_CHECKER", 6), | ||
324 | newConst("integer", "PRIM_BUMP_CONCRETE", 7), | ||
325 | newConst("integer", "PRIM_BUMP_TILE", 8), | ||
326 | newConst("integer", "PRIM_BUMP_STONE", 9), | ||
327 | newConst("integer", "PRIM_BUMP_DISKS", 10), | ||
328 | newConst("integer", "PRIM_BUMP_GRAVEL", 11), | ||
329 | newConst("integer", "PRIM_BUMP_BLOBS", 12), | ||
330 | newConst("integer", "PRIM_BUMP_SIDING", 13), | ||
331 | newConst("integer", "PRIM_BUMP_LARGETILE", 14), | ||
332 | newConst("integer", "PRIM_BUMP_STUCCO", 15), | ||
333 | newConst("integer", "PRIM_BUMP_SUCTION", 16), | ||
334 | newConst("integer", "PRIM_BUMP_WEAVE", 17), | ||
335 | |||
336 | newConst("integer", "PRIM_HOLE_DEFAULT", 0), | ||
337 | newConst("integer", "PRIM_HOLE_CIRCLE", 16), | ||
338 | newConst("integer", "PRIM_HOLE_SQUARE", 32), | ||
339 | newConst("integer", "PRIM_HOLE_TRIANGLE", 48), | ||
340 | |||
341 | newConst("integer", "PRIM_MATERIAL_STONE", 0), | ||
342 | newConst("integer", "PRIM_MATERIAL_METAL", 1), | ||
343 | newConst("integer", "PRIM_MATERIAL_GLASS", 2), | ||
344 | newConst("integer", "PRIM_MATERIAL_WOOD", 3), | ||
345 | newConst("integer", "PRIM_MATERIAL_FLESH", 4), | ||
346 | newConst("integer", "PRIM_MATERIAL_PLASTIC", 5), | ||
347 | newConst("integer", "PRIM_MATERIAL_RUBBER", 6), | ||
348 | newConst("integer", "PRIM_MATERIAL_LIGHT", 7), | ||
349 | |||
350 | newConst("integer", "PRIM_SCULPT_TYPE_SPHERE", 1), | ||
351 | newConst("integer", "PRIM_SCULPT_TYPE_TORUS", 2), | ||
352 | newConst("integer", "PRIM_SCULPT_TYPE_PLANE", 3), | ||
353 | newConst("integer", "PRIM_SCULPT_TYPE_CYLINDER", 4), | ||
354 | newConst("integer", "PRIM_SCULPT_TYPE_MESH", 5), | ||
355 | newConst("integer", "PRIM_SCULPT_TYPE_MIMESH", 6), | ||
356 | |||
357 | newConst("integer", "PRIM_SHINY_NONE", 0), | ||
358 | newConst("integer", "PRIM_SHINY_LOW", 1), | ||
359 | newConst("integer", "PRIM_SHINY_MEDIUM", 2), | ||
360 | newConst("integer", "PRIM_SHINY_HIGH", 3), | ||
361 | |||
362 | newConst("integer", "PRIM_TYPE_BOX", 0), | ||
363 | newConst("integer", "PRIM_TYPE_CYLINDER", 1), | ||
364 | newConst("integer", "PRIM_TYPE_PRISM", 2), | ||
365 | newConst("integer", "PRIM_TYPE_SPHERE", 3), | ||
366 | newConst("integer", "PRIM_TYPE_TORUS", 4), | ||
367 | newConst("integer", "PRIM_TYPE_TUBE", 5), | ||
368 | newConst("integer", "PRIM_TYPE_RING", 6), | ||
369 | newConst("integer", "PRIM_TYPE_SCULPT", 7), | ||
370 | |||
371 | newConst("integer", "STRING_TRIM", 3), | ||
372 | newConst("integer", "STRING_TRIM_HEAD", 1), | ||
373 | newConst("integer", "STRING_TRIM_TAIL", 2), | ||
374 | |||
375 | newConst("integer", "TRUE", 1), | ||
376 | newConst("integer", "FALSE", 0), | ||
377 | |||
378 | newConst("integer", "TOUCH_INVALID_FACE", 0x7FFFFFFF), | ||
379 | newConst("vector", "TOUCH_INVALID_TEXCOORD", {x=-1.0, y=-1.0, z=0.0}), | ||
380 | newConst("vector", "TOUCH_INVALID_VECTOR", {x=0.0, y=0.0, z=0.0}), | ||
381 | |||
382 | newConst("integer", "TYPE_INTEGER", 1), | ||
383 | newConst("integer", "TYPE_FLOAT", 2), | ||
384 | newConst("integer", "TYPE_STRING", 3), | ||
385 | newConst("integer", "TYPE_KEY", 4), | ||
386 | newConst("integer", "TYPE_VECTOR", 5), | ||
387 | newConst("integer", "TYPE_ROTATION", 6), | ||
388 | newConst("integer", "TYPE_INVALID", 0), | ||
389 | |||
390 | newConst("string", "NULL_KEY", "00000000-0000-0000-0000-000000000000"), | ||
391 | newConst("string", "EOF", "\\n\\n\\n"), -- Corner case, dealt with later. | ||
392 | |||
393 | newConst("rotation", "ZERO_ROTATION", {x=0.0, y=0.0, z=0.0, s=1.0}), | ||
394 | newConst("vector", "ZERO_VECTOR", {x=0.0, y=0.0, z=0.0}), | ||
395 | |||
396 | -- TODO - Temporary dummy variables to get vector and rotation thingies to work for now. | ||
397 | |||
398 | newConst("float", "s", 1.0), | ||
399 | newConst("float", "x", 0.0), | ||
400 | newConst("float", "y", 0.0), | ||
401 | newConst("float", "z", 0.0), | ||
402 | } | ||
403 | |||
404 | -- ll*() function definitions | ||
405 | |||
406 | -- LSL avatar functions | ||
407 | newFunc("key", "llAvatarOnSitTarget") | ||
408 | newFunc("list", "llGetAnimationList", "key id") | ||
409 | newFunc("integer", "llGetPermissions") | ||
410 | newFunc("key", "llGetPermissionsKey") | ||
411 | newFunc("string", "llKey2Name", "key avatar") | ||
412 | newFunc("", "llRequestPermissions", "key avatar", "integer perms") | ||
413 | newFunc("integer", "llSameGroup", "key avatar") | ||
414 | newFunc("", "llStartAnimation", "string anim") | ||
415 | newFunc("", "llStopAnimation", "string anim") | ||
416 | newFunc("", "llUnSit", "key avatar") | ||
417 | |||
418 | -- LSL collision / detect / sensor functions | ||
419 | newFunc("integer", "llDetectedGroup", "integer index") | ||
420 | newFunc("vector", "llDetectedGrab", "integer index") | ||
421 | newFunc("key", "llDetectedKey", "integer index") | ||
422 | newFunc("integer", "llDetectedLinkNumber", "integer index") | ||
423 | newFunc("string", "llDetectedName", "integer index") | ||
424 | newFunc("key", "llDetectedOwner", "integer index") | ||
425 | newFunc("vector", "llDetectedPos", "integer index") | ||
426 | newFunc("rotation", "llDetectedRot", "integer index") | ||
427 | newFunc("vector", "llDetectedTouchBinormal", "integer index") | ||
428 | newFunc("integer", "llDetectedTouchFace", "integer index") | ||
429 | newFunc("vector", "llDetectedTouchNormal", "integer index") | ||
430 | newFunc("vector", "llDetectedTouchPos", "integer index") | ||
431 | newFunc("vector", "llDetectedTouchST", "integer index") | ||
432 | newFunc("vector", "llDetectedTouchUV", "integer index") | ||
433 | newFunc("integer", "llDetectedType", "integer index") | ||
434 | newFunc("vector", "llDetectedVel", "integer index") | ||
435 | |||
436 | |||
437 | -- LSL communications functions | ||
438 | newFunc("", "llDialog", "key avatar", "string caption", "list arseBackwardsMenu", "integer channel") | ||
439 | newFunc("integer", "llListen", "integer channel", "string name", "key id", "string msg") | ||
440 | newFunc("", "llListenRemove", "integer handle") | ||
441 | newFunc("", "llOwnerSay", "string text") | ||
442 | newFunc("", "llSay", "integer channel", "string text") | ||
443 | newFunc("", "llShout", "integer channel", "string text") | ||
444 | newFunc("", "llWhisper", "integer channel", "string text") | ||
445 | newFunc("", "llMessageLinked", "integer link", "integer num", "string text", "key aKey") | ||
446 | |||
447 | -- LSL inventory functions. | ||
448 | newFunc("string", "llGetInventoryName", "integer Type", "integer index") | ||
449 | newFunc("integer", "llGetInventoryNumber", "integer Type") | ||
450 | newFunc("integer", "llGetInventoryType", "string name") | ||
451 | newFunc("key", "llGetNotecardLine", "string name", "integer index") | ||
452 | newFunc("", "llRezAtRoot", "string name", "vector position", "vector velocity", "rotation rot", "integer channel") | ||
453 | newFunc("", "llRezObject", "string name", "vector position", "vector velocity", "rotation rot", "integer channel") | ||
454 | |||
455 | -- LSL list functions. | ||
456 | newFunc("list", "llCSV2List", "string text") | ||
457 | newFunc("list", "llDeleteSubList", "list l", "integer start", "integer End") | ||
458 | newFunc("string", "llDumpList2String", "list l", "string separator") | ||
459 | newFunc("integer", "llGetListLength", "list l") | ||
460 | newFunc("string", "llList2CSV", "list l") | ||
461 | newFunc("float", "llList2Float", "list l", "integer index") | ||
462 | newFunc("integer", "llList2Integer", "list l", "integer index") | ||
463 | newFunc("key", "llList2Key", "list l", "integer index") | ||
464 | newFunc("list", "llList2List", "list l", "integer start", "integer End") | ||
465 | newFunc("string", "llList2String", "list l", "integer index") | ||
466 | newFunc("rotation", "llList2Rotation", "list l", "integer index") | ||
467 | newFunc("vector", "llList2Vector", "list l", "integer index") | ||
468 | newFunc("integer", "llListFindList", "list l", "list l1") | ||
469 | newFunc("list", "llListInsertList", "list l", "list l1", "integer index") | ||
470 | newFunc("list", "llListReplaceList", "list l", "list part", "integer start", "integer End") | ||
471 | newFunc("list", "llListSort", "list l", "integer stride", "integer ascending") | ||
472 | newFunc("list", "llParseString2List", "string In", "list l", "list l1") | ||
473 | newFunc("list", "llParseStringKeepNulls", "string In", "list l", "list l1") | ||
474 | |||
475 | -- LSL math functions | ||
476 | newFunc("rotation", "llEuler2Rot", "vector vec") | ||
477 | newFunc("float", "llFrand", "float max") | ||
478 | newFunc("float", "llPow", "float number", "float places") | ||
479 | newFunc("vector", "llRot2Euler", "rotation rot") | ||
480 | newFunc("integer", "llRound", "float number") | ||
481 | |||
482 | -- LSL media functions | ||
483 | newFunc("", "llPlaySound", "string name", "float volume") | ||
484 | |||
485 | -- LSL object / prim functions | ||
486 | newFunc("", "llDie") | ||
487 | newFunc("key", "llGetKey") | ||
488 | newFunc("integer", "llGetLinkNumber") | ||
489 | newFunc("string", "llGetObjectDesc") | ||
490 | newFunc("string", "llGetObjectName") | ||
491 | newFunc("key", "llGetOwner") | ||
492 | newFunc("", "llSetObjectDesc", "string text") | ||
493 | newFunc("", "llSetObjectName", "string text") | ||
494 | newFunc("", "llSetPrimitiveParams", "list params") | ||
495 | newFunc("", "llSetSitText", "string text") | ||
496 | newFunc("", "llSetText", "string text", "vector colour", "float alpha") | ||
497 | newFunc("", "llSitTarget", "vector pos", "rotation rot") | ||
498 | |||
499 | -- LSL rotation / scaling / translation functions | ||
500 | newFunc("vector", "llGetPos") | ||
501 | newFunc("rotation", "llGetRot") | ||
502 | newFunc("", "llSetPos", "vector pos") | ||
503 | newFunc("", "llSetRot", "rotation rot") | ||
504 | newFunc("", "llSetScale", "vector scale") | ||
505 | |||
506 | -- LSL script functions | ||
507 | newFunc("integer", "llGetFreeMemory") | ||
508 | newFunc("string", "llGetScriptName") | ||
509 | newFunc("", "llResetOtherScript", "string name") | ||
510 | newFunc("", "llResetScript") | ||
511 | newFunc("", "llSetScriptState", "string name", "integer running") | ||
512 | |||
513 | -- LSL string functions | ||
514 | newFunc("string", "llGetSubString", "string text", "integer start", "integer End") | ||
515 | newFunc("integer", "llStringLength", "string text") | ||
516 | newFunc("string", "llStringTrim", "string text", "integer type") | ||
517 | newFunc("integer", "llSubStringIndex", "string text", "string sub") | ||
518 | |||
519 | -- LSL texture functions | ||
520 | newFunc("float", "llGetAlpha", "integer side") | ||
521 | newFunc("", "llSetAlpha", "float alpha", "integer side") | ||
522 | newFunc("", "llSetColor", "vector colour", "integer side") | ||
523 | |||
524 | -- LSL time functions | ||
525 | newFunc("float", "llGetTime") | ||
526 | newFunc("", "llResetTime") | ||
527 | newFunc("", "llSetTimerEvent", "float seconds") | ||
528 | newFunc("float", "llSleep", "float seconds") -- Faked return type, it actually does not return anything. This forces it to wait. Actually fully implements llSleep(). B-) | ||
529 | |||
530 | |||
531 | -- TODO - fake this for now. | ||
532 | function --[[integer]] LSL.llGetInventoryType(--[[string]] name) return LSL.INVENTORY_SCRIPT end; | ||
533 | |||
534 | |||
535 | -- LSL collision / detect / sensor functions | ||
536 | function --[[integer]] LSL.llDetectedGroup( --[[integer]] index) return detectedGroups [index + 1] or false end | ||
537 | function --[[vector]] LSL.llDetectedGrab( --[[integer]] index) return detectedGrabs [index + 1] or LSL.ZERO_VECTOR end | ||
538 | function --[[key]] LSL.llDetectedKey( --[[integer]] index) return detectedKeys [index + 1] or LSL.NULL_KEY end -- LL says "returns empty key" which is "", but LSL Wiki says NULL_KEY | ||
539 | function --[[integer]] LSL.llDetectedLinkNumber( --[[integer]] index) return detectedLinkNumbers [index + 1] or 0 end | ||
540 | function --[[string]] LSL.llDetectedName( --[[integer]] index) return detectedNames [index + 1] or "" end -- LL says it returns NULL_KEY, LSL Wiki says an empty string. Apparently there used to be an exploit for creating multi kb names, normally they are 255 characters. | ||
541 | function --[[key]] LSL.llDetectedOwner( --[[integer]] index) return detectedOwners [index + 1] or LSL.NULL_KEY end -- LL says "returns empty key" which is "", but LSL Wiki says NULL_KEY | ||
542 | function --[[vector]] LSL.llDetectedPos( --[[integer]] index) return detectedPoss [index + 1] or LSL.ZERO_VECTOR end | ||
543 | function --[[rotation]] LSL.llDetectedRot( --[[integer]] index) return detectedRots [index + 1] or LSL.ZERO_ROTATION end | ||
544 | function --[[vector]] LSL.llDetectedTouchBinormal( --[[integer]] index) return detectedTouchBinormals [index + 1] or LSL.TOUCH_INVALID_VECTOR end | ||
545 | function --[[integer]] LSL.llDetectedTouchFace( --[[integer]] index) return detectedTouchFaces [index + 1] or LSL.TOUCH_INVALID_FACE end | ||
546 | function --[[vector]] LSL.llDetectedTouchNormal( --[[integer]] index) return detectedTouchNormals [index + 1] or LSL.TOUCH_INVALID_VECTOR end | ||
547 | function --[[vector]] LSL.llDetectedTouchPos( --[[integer]] index) return detectedTouchPoss [index + 1] or LSL.TOUCH_INVALID_VECTOR end | ||
548 | function --[[vector]] LSL.llDetectedTouchST( --[[integer]] index) return detectedTouchSTs [index + 1] or LSL.TOUCH_INVALID_TEXCOORD end | ||
549 | function --[[vector]] LSL.llDetectedTouchUV( --[[integer]] index) return detectedTouchUVs [index + 1] or LSL.TOUCH_INVALID_TEXCOORD end | ||
550 | function --[[integer]] LSL.llDetectedType( --[[integer]] index) return detectedTypes [index + 1] or 0 end | ||
551 | function --[[vector]] LSL.llDetectedVel( --[[integer]] index) return detectedVels [index + 1] or LSL.ZERO_VECTOR end | ||
552 | |||
553 | |||
554 | -- LSL list functions. | ||
555 | |||
556 | --function --[[list]] LSL.llCSV2List(--[[string]] text) return {} end; | ||
557 | function --[[list]] LSL.llDeleteSubList(--[[list]] l,--[[integer]] start,--[[integer]] eNd) | ||
558 | local result = {} | ||
559 | local x = 1 | ||
560 | |||
561 | -- Deal with the impedance mismatch. | ||
562 | start = start + 1 | ||
563 | eNd = eNd + 1 | ||
564 | for i = 1,#l do | ||
565 | if i < start then result[x] = l[i]; x = x + 1 | ||
566 | elseif i > eNd then result[x] = l[i]; x = x + 1 | ||
567 | end | ||
568 | end | ||
569 | |||
570 | return result | ||
571 | end | ||
572 | |||
573 | function --[[string]] LSL.llDumpList2String(--[[list]] l, --[[string]] separator) | ||
574 | local result = "" | ||
575 | for i = 1,#l do | ||
576 | if "" ~= result then result = result .. separator end | ||
577 | result = result .. l[i] | ||
578 | end | ||
579 | return result | ||
580 | end | ||
581 | |||
582 | function --[[integer]] LSL.llGetListLength(--[[list]] l) | ||
583 | return #l | ||
584 | end | ||
585 | |||
586 | function --[[string]] LSL.llList2CSV(--[[list]] l) | ||
587 | return LSL.llDumpList2String(l, ",") | ||
588 | end | ||
589 | |||
590 | function --[[float]] LSL.llList2Float(--[[list]] l,--[[integer]] index) | ||
591 | local result = tonumber(l[index]) | ||
592 | if nil == result then result = 0.0 end | ||
593 | return result | ||
594 | end | ||
595 | |||
596 | function --[[integer]] LSL.llList2Integer(--[[list]] l,--[[integer]] index) | ||
597 | local result = tonumber(l[index+1]) | ||
598 | if nil == result then result = 0 end | ||
599 | return result | ||
600 | end | ||
601 | |||
602 | function --[[key]] LSL.llList2Key(--[[list]] l,--[[integer]] index) | ||
603 | local result = l[index+1] | ||
604 | if result then return "" .. result else return LSL.NULL_KEY end | ||
605 | end | ||
606 | |||
607 | function --[[list]] LSL.llList2List(--[[list]] l,--[[integer]] start,--[[integer]] eNd) | ||
608 | local result = {} | ||
609 | local x = 1 | ||
610 | |||
611 | --[[ TODO - | ||
612 | Using negative numbers for start and/or end causes the index to count backwards from the length of the list, so 0, -1 would capture the entire list. | ||
613 | If start is larger than end the list returned is the exclusion of the entries, so 6, 4 would give the entire list except for the 5th entry. | ||
614 | ]] | ||
615 | |||
616 | -- Deal with the impedance mismatch. | ||
617 | start = start + 1 | ||
618 | eNd = eNd + 1 | ||
619 | for i = 1,#l do | ||
620 | if i >= start then result[x] = l[i]; x = x + 1 | ||
621 | elseif i <= eNd then result[x] = l[i]; x = x + 1 | ||
622 | end | ||
623 | end | ||
624 | |||
625 | return result | ||
626 | end | ||
627 | |||
628 | function --[[string]] LSL.llList2String(--[[list]] l,--[[integer]] index) | ||
629 | local result = l[index+1] | ||
630 | if result then return "" .. result else return "" end | ||
631 | end | ||
632 | |||
633 | function --[[rotation]] LSL.llList2Rotation(--[[list]] l,--[[integer]] index) | ||
634 | local result = l[index+1] | ||
635 | if nil == result then result = LSL.ZERO_ROTATION end | ||
636 | -- TODO - check if it's not an actual rotation, then return LSS.ZERO_ROTATION | ||
637 | return result | ||
638 | end | ||
639 | |||
640 | function --[[vector]] LSL.llList2Vector(--[[list]] l,--[[integer]] index) | ||
641 | local result = l[index+1] | ||
642 | if nil == result then result = LSL.ZERO_VECTOR end | ||
643 | -- TODO - check if it's not an actual rotation, then return LSS.ZERO_VECTOR | ||
644 | return result | ||
645 | end | ||
646 | |||
647 | --function --[[integer]] LSL.llListFindList(--[[list]] l, --[[list]] l1) return 0 end; | ||
648 | function --[[list]] LSL.llListInsertList(--[[list]] l, --[[list]] l1,--[[integer]] index) | ||
649 | local result = {} | ||
650 | local x = 1 | ||
651 | local y | ||
652 | for i = 1,index do | ||
653 | result[x] = l[i] | ||
654 | x = x + 1 | ||
655 | end | ||
656 | y = x | ||
657 | for i = 1,#ll do | ||
658 | result[x] = ll[i] | ||
659 | x = x + 1 | ||
660 | end | ||
661 | for i = y,#l do | ||
662 | result[x] = l[i] | ||
663 | x = x + 1 | ||
664 | end | ||
665 | return result | ||
666 | end | ||
667 | |||
668 | function --[[list]] LSL.llListReplaceList(--[[list]] l, --[[list]] part,--[[integer]] start,--[[integer]] eNd) | ||
669 | local result = {} | ||
670 | local x = 1 | ||
671 | local y | ||
672 | for i = 1,index do | ||
673 | result[x] = l[i] | ||
674 | x = x + 1 | ||
675 | end | ||
676 | for i = 1,#part do | ||
677 | result[x] = part[i] | ||
678 | x = x + 1 | ||
679 | end | ||
680 | for i = index,#l do | ||
681 | result[x] = l[i] | ||
682 | x = x + 1 | ||
683 | end | ||
684 | return result | ||
685 | end | ||
686 | |||
687 | function --[[list]] LSL.llListSort(--[[list]] l,--[[integer]] stride,--[[integer]] ascending) | ||
688 | local result = {} | ||
689 | |||
690 | -- TODO - Deal with stride and ascending. | ||
691 | for i = 1,#l do | ||
692 | result[x] = l[i]; x = x + 1 | ||
693 | end | ||
694 | table.sort(result) | ||
695 | |||
696 | return result | ||
697 | end | ||
698 | |||
699 | --function --[[list]] LSL.llParseString2List(--[[string]] In, --[[list]] l, --[[list]] l1) return {} end; | ||
700 | --function --[[list]] LSL.llParseStringKeepNulls(--[[string]] In, --[[list]] l, --[[list]] l1) return {} end; | ||
701 | |||
702 | |||
703 | -- LSL script functions | ||
704 | |||
705 | function --[[string]] LSL.llGetScriptName() | ||
706 | return scriptName | ||
707 | end | ||
708 | |||
709 | |||
710 | -- LSL string functions | ||
711 | |||
712 | function --[[string]] LSL.llGetSubString(--[[string]] text, --[[integer]] start, --[[integer]] End) | ||
713 | -- Deal with the impedance mismatch. | ||
714 | if 0 <= start then start = start + 1 end | ||
715 | if 0 <= End then End = End + 1 end | ||
716 | -- TODO - If start is larger than end the substring is the exclusion of the entries, so 6,4 would give the entire string except for the 5th character. | ||
717 | return string.sub(text, start, End) | ||
718 | end | ||
719 | |||
720 | function --[[integer]] LSL.llSubStringIndex(--[[string]] text, --[[string]] sub) | ||
721 | local start, End = string.find(text, sub, 1, true) | ||
722 | |||
723 | if nil == start then return -1 else return start - 1 end | ||
724 | end | ||
725 | |||
726 | |||
727 | -- Crements stuff. | ||
728 | |||
729 | function LSL.preDecrement(name) _G[name] = _G[name] - 1; return _G[name]; end; | ||
730 | function LSL.preIncrement(name) _G[name] = _G[name] + 1; return _G[name]; end; | ||
731 | function LSL.postDecrement(name) local temp = _G[name]; _G[name] = _G[name] - 1; return temp; end; | ||
732 | function LSL.postIncrement(name) local temp = _G[name]; _G[name] = _G[name] + 1; return temp; end; | ||
733 | |||
734 | |||
735 | -- State stuff | ||
736 | |||
737 | function LSL.stateChange(x) | ||
738 | if currentState ~= x then -- Changing to the same state is a NOP. | ||
739 | -- TODO - Should clear out pending events, except timer() | ||
740 | -- Also forget about any event setup that needs setting up via some ll*() function, except timer(). | ||
741 | if nil ~= currentState.state_exit then | ||
742 | currentState.state_exit(); | ||
743 | end | ||
744 | currentState = x; | ||
745 | --[[ Never return to the current states event handler. In theory. lol | ||
746 | Notably, it's not actually legal to do a state change from a function, only from handlers. | ||
747 | There is a hack though, but it's unsupported, so I don't have to worry about it so much. | ||
748 | |||
749 | Write out "state new;" as "return _LSL.stateChange(newState);", with stateChange() returning new.state_entry()) which will force two tail calls. | ||
750 | |||
751 | The caller of stateChange() might be a function rather than an event handler. | ||
752 | Which will return to the event handler (possibly via other nested function calls) as if the state never changed. | ||
753 | http://lslwiki.net/lslwiki/wakka.php?wakka=FunctionStateChangeHack seems to imply that this is exactly what LSL does. | ||
754 | Soooo, this might actually work perfectly. | ||
755 | Except for one minor quirk, as that page shows - only the top level function's state sticks, unless the handler does one to, then the handlers one overrides things. | ||
756 | Which I can probably ignore anyway, as this entire calling states within functions thing is an unsupported hack. | ||
757 | ]] | ||
758 | if nil ~= currentState.state_entry then | ||
759 | return currentState.state_entry(); | ||
760 | end | ||
761 | end | ||
762 | end; | ||
763 | |||
764 | function LSL.mainLoop(sid, name, x) | ||
765 | local status, errorMsg | ||
766 | local result | ||
767 | |||
768 | SID = sid | ||
769 | scriptName = name | ||
770 | LSL.EOF = "\n\n\n" -- Fix this up now. | ||
771 | |||
772 | LSL.stateChange(x); | ||
773 | waitAndProcess(false) | ||
774 | msg("Script quitting.") | ||
775 | end | ||
776 | |||
777 | function waitAndProcess(returnWanted) | ||
778 | local Type = "event" | ||
779 | |||
780 | if returnWanted then Type = "result" end | ||
781 | while running do | ||
782 | local message = luaproc.receive(SID) | ||
783 | if message then | ||
784 | -- TODO - should we be discarding return values while paused? I don't think so, so we need to process those, | ||
785 | if paused then | ||
786 | if "start()" == message then paused = false end | ||
787 | else | ||
788 | result, errorMsg = loadstring(message) -- "The environment of the returned function is the global environment." Though normally, a function inherits it's environment from the function creating it. Which is what we want. lol | ||
789 | if nil == result then | ||
790 | msg("Not a valid " .. Type .. ": " .. message .. " ERROR MESSAGE: " .. errorMsg) | ||
791 | else | ||
792 | -- Set the functions environment to ours, for the protection of the script, coz loadstring sets it to the global environment instead. | ||
793 | -- TODO - On the other hand, we will need the global environment when we call event handlers. So we should probably stash it around here somewhere. | ||
794 | -- Meh, seems to be working fine as it is. | ||
795 | setfenv(result, getfenv(1)) | ||
796 | status, result = pcall(result) | ||
797 | if not status then | ||
798 | msg("Error from " .. Type .. ": " .. message .. " ERROR MESSAGE: " .. result) | ||
799 | elseif result then | ||
800 | -- Check if we are waiting for a return, and got it. | ||
801 | if returnWanted and string.match(message, "^return ") then | ||
802 | return result | ||
803 | end | ||
804 | -- Otherwise, just run it and keep looping. | ||
805 | status, errorMsg = luaproc.send(sid, result) | ||
806 | if not status then | ||
807 | msg("Error sending results from " .. Type .. ": " .. message .. " ERROR MESSAGE: " .. errorMsg) | ||
808 | end | ||
809 | end | ||
810 | end | ||
811 | end | ||
812 | end | ||
813 | end | ||
814 | end | ||
815 | |||
816 | -- Typecasting stuff. | ||
817 | |||
818 | function LSL.floatTypecast(x) | ||
819 | local temp = tonumber(x) | ||
820 | if nil == temp then temp = 0 end | ||
821 | return temp; | ||
822 | end | ||
823 | |||
824 | function LSL.integerTypecast(x) | ||
825 | local temp = tonumber(x) | ||
826 | if nil == temp then temp = 0 end | ||
827 | return temp; | ||
828 | end | ||
829 | |||
830 | function LSL.keyTypecast(x) | ||
831 | return "" .. x; | ||
832 | end | ||
833 | |||
834 | function LSL.listTypecast(x) | ||
835 | return {x}; | ||
836 | end | ||
837 | |||
838 | function LSL.rotationTypecast(x) | ||
839 | return x; | ||
840 | end | ||
841 | |||
842 | function LSL.stringTypecast(x) | ||
843 | return "" .. x; | ||
844 | end | ||
845 | |||
846 | function LSL.vectorTypecast(x) | ||
847 | return x; | ||
848 | end | ||
849 | |||
850 | |||
851 | -- Called at compiler set up time, to produce the constants.lsl file. | ||
852 | function LSL.gimmeLSL() | ||
853 | for i,v in ipairs(constants) do | ||
854 | local value = LSL[v.name] | ||
855 | |||
856 | print(v.Type .. " " .. v.name .. " = " .. value2string(value, v.Type) .. ";") | ||
857 | end | ||
858 | |||
859 | for k in pairs(functions) do | ||
860 | local v = functions[k] | ||
861 | if nil == v.args then | ||
862 | print(v.Type .. " " .. k .. "(){}") | ||
863 | else | ||
864 | print(v.Type .. " " .. k .. "(" .. args2string(false, unpack(v.args)) .. "){}") | ||
865 | end | ||
866 | end | ||
867 | end | ||
868 | |||
869 | |||
870 | return LSL; | ||