1 (*
2 * Hedgewars, a free turn based strategy game
3 * Copyright (c) 2004-2015 Andrey Korotaev <unC0Rr@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; version 2 of the License
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *)
18
19 {$INCLUDE "options.inc"}
20
21 unit uScript;
22 (*
23 * This unit defines, implements and registers functions and
24 * variables/constants bindings for usage in Lua scripts.
25 *
26 * Please keep https://hedgewars.org/kb/LuaAPI up to date!
27 *
28 * Note: If you add a new function, make sure to test if _all_ parameters
29 * work as intended! (Especially conversions errors can sneak in
30 * unnoticed and render the parameter useless!)
31 *)
32 interface
33
34 procedure ScriptPrintStack;
35 procedure ScriptClearStack;
36
ScriptLoadnull37 function ScriptLoad(name : shortstring; mustExist : boolean): boolean;
38 procedure ScriptOnPreviewInit;
39 procedure ScriptOnGameInit;
40 procedure ScriptOnScreenResize;
41 procedure ScriptSetInteger(name : shortstring; value : LongInt);
42 procedure ScriptSetString(name : shortstring; value : shortstring);
43 procedure ScriptSetMapGlobals;
44
45 procedure ScriptCall(fname : shortstring);
ScriptCallnull46 function ScriptCall(fname : shortstring; par1: LongInt) : LongInt;
ScriptCallnull47 function ScriptCall(fname : shortstring; par1, par2: LongInt) : LongInt;
ScriptCallnull48 function ScriptCall(fname : shortstring; par1, par2, par3: LongInt) : LongInt;
ScriptCallnull49 function ScriptCall(fname : shortstring; par1, par2, par3, par4 : LongInt) : LongInt;
ScriptExistsnull50 function ScriptExists(fname : shortstring) : boolean;
51
52 procedure LuaParseString(s: shortString);
53
ParseCommandOverridenull54 //function ParseCommandOverride(key, value : shortstring) : shortstring; This did not work out well
55
56 procedure initModule;
57 procedure freeModule;
58
59 implementation
60
61 uses LuaPas,
62 uConsole,
63 uConsts,
64 uGears,
65 uGearsList,
66 uGearsUtils,
67 uFloat,
68 uWorld,
69 uAmmos,
70 uTeams,
71 uSound,
72 uChat,
73 uStats,
74 uStore,
75 uRandom,
76 uTypes,
77 uVariables,
78 uCommands,
79 uCaptions,
80 uDebug,
81 uCollisions,
82 uRenderUtils,
83 uTextures,
84 uLandGraphics,
85 uUtils,
86 uIO,
87 uVisualGearsList,
88 uGearsHandlersMess,
89 uPhysFSLayer,
90 uLocale,
91 SDLh
92 {$IFNDEF PAS2C}
93 , typinfo
94 {$ENDIF}
95 ;
96
97 var luaState : Plua_State;
98 ScriptAmmoLoadout : shortstring;
99 ScriptAmmoProbability : shortstring;
100 ScriptAmmoDelay : shortstring;
101 ScriptAmmoReinforcement : shortstring;
102 ScriptLoaded : boolean;
103 PointsBuffer: shortstring;
104 PrevCursorX, PrevCursorY: LongInt;
105 PendingTurnTimeLeft, PendingReadyTimeLeft: LongWord;
106 isPendingTurnTimeLeft, isPendingReadyTimeLeft: boolean;
107
108 {$IFDEF USE_LUA_SCRIPT}
109 procedure ScriptPrepareAmmoStore; forward;
110 procedure ScriptApplyAmmoStore; forward;
111 procedure ScriptSetAmmo(ammo : TAmmoType; count, probability, delay, reinforcement: Byte); forward;
112 procedure ScriptSetAmmoDelay(ammo : TAmmoType; delay: LongWord); forward;
113
114 var LuaDebugInfo: lua_Debug;
115
116 procedure SetGlobals; forward;
117 procedure GetGlobals; forward;
118 procedure LuaParseString(s: shortString);
119 begin
120 SetGlobals;
121 AddFileLog('[Lua] input string: ' + s);
122 AddChatString(#3 + '[Lua] > ' + s);
123 if luaL_dostring(luaState, Str2PChar(s)) <> 0 then
124 begin
125 AddFileLog('[Lua] input string parsing error!');
126 AddChatString(#5 + '[Lua] Error while parsing!');
127 end
128 else
129 GetGlobals();
130 end;
131
LuaUpdateDebugInfonull132 function LuaUpdateDebugInfo(): Boolean;
133 begin
134 FillChar(LuaDebugInfo, sizeof(LuaDebugInfo), 0);
135
136 if lua_getstack(luaState, 1, @LuaDebugInfo) = 0 then
137 exit(false); // stack not deep enough
138
139 // get source name and line count
140 lua_getinfo(luaState, PChar('Sl'), @LuaDebugInfo);
141 exit(true);
142 end;
143
144 procedure LuaErrorOrWarning(s: shortstring; isWarning: boolean);
145 var src, intro: shortstring;
146 const
147 maxsrclen = 20;
148 begin
149 if isWarning then
150 intro:= 'LUA WARNING'
151 else
152 intro:= 'LUA ERROR';
153 if LuaUpdateDebugInfo() then
154 begin
155 src:= StrPas(LuaDebugInfo.source);
156 s:= intro + ': [ ... '
157 + copy(src, Length(src) - maxsrclen, maxsrclen - 3) + ':'
158 + inttostr(LuaDebugInfo.currentLine) + ']: ' + s;
159 end
160 else
161 s:= intro + ': ' + s;
162 WriteLnToConsole(s);
163 if isWarning then
164 AddChatString(#0 + s)
165 else
166 AddChatString(#5 + s);
167 if cTestLua and (not isWarning) then
168 halt(HaltTestLuaError);
169 end;
170
171 procedure LuaError(s: shortstring);
172 begin
173 LuaErrorOrWarning(s, false);
174 end;
175
176 procedure LuaWarning(s: shortstring);
177 begin
178 LuaErrorOrWarning(s, true);
179 end;
180
181 procedure LuaCallError(error, call, paramsyntax: shortstring);
182 begin
183 LuaError(call + ': ' + error);
184 LuaError('-- SYNTAX: ' + call + ' ( ' + paramsyntax + ' )');
185 end;
186
187 procedure LuaParameterCountError(expected, call, paramsyntax: shortstring; wrongcount: LongInt); inline;
188 begin
189 // TODO: i18n?
190 LuaCallError('Wrong number of parameters! (is: ' + inttostr(wrongcount) + ', should be: '+ expected + ')', call, paramsyntax);
191 end;
192
193 // compare with allowed count
CheckLuaParamCountnull194 function CheckLuaParamCount(L : Plua_State; count: LongInt; call, paramsyntax: shortstring): boolean; inline;
195 var c: LongInt;
196 begin
197 c:= lua_gettop(L);
198 if c <> count then
199 begin
200 LuaParameterCountError('exactly ' + inttostr(count), call, paramsyntax, c);
201 exit(false);
202 end;
203
204 CheckLuaParamCount:= true;
205 end;
206
207 // check if is either count1 or count2
CheckAndFetchParamCountnull208 function CheckAndFetchParamCount(L : Plua_State; count1, count2: LongInt; call, paramsyntax: shortstring; out actual: LongInt): boolean; inline;
209 begin
210 actual:= lua_gettop(L);
211 if (actual <> count1) and (actual <> count2) then
212 begin
213 LuaParameterCountError('either ' + inttostr(count1) + ' or ' + inttostr(count2), call, paramsyntax, actual);
214 exit(false);
215 end;
216
217 CheckAndFetchParamCount:= true;
218 end;
219
220 // check if is in range of count1 and count2
CheckAndFetchParamCountRangenull221 function CheckAndFetchParamCountRange(L : Plua_State; count1, count2: LongInt; call, paramsyntax: shortstring; out actual: LongInt): boolean; inline;
222 begin
223 actual:= lua_gettop(L);
224 if (actual < count1) or (actual > count2) then
225 begin
226 LuaParameterCountError('at least ' + inttostr(count1) + ', but at most ' + inttostr(count2), call, paramsyntax, actual);
227 exit(false);
228 end;
229
230 CheckAndFetchParamCountRange:= true;
231 end;
232
233 // check if is same or higher as minCount
CheckAndFetchLuaParamMinCountnull234 function CheckAndFetchLuaParamMinCount(L : Plua_State; minCount: LongInt; call, paramsyntax: shortstring; out actual: LongInt): boolean; inline;
235 begin
236 actual:= lua_gettop(L);
237 if (actual < minCount) then
238 begin
239 LuaParameterCountError(inttostr(minCount) + ' or more', call, paramsyntax, actual);
240 exit(false);
241 end;
242
243 CheckAndFetchLuaParamMinCount:= true;
244 end;
245
LuaToGearTypeOrdnull246 function LuaToGearTypeOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
247 begin
248 if lua_isnoneornil(L, i) then i:= -1
249 else i:= Trunc(lua_tonumber(L, i));
250 if (i < ord(Low(TGearType))) or (i > ord(High(TGearType))) then
251 begin
252 LuaCallError('Invalid gearType!', call, paramsyntax);
253 LuaToGearTypeOrd:= -1;
254 end
255 else
256 LuaToGearTypeOrd:= i;
257 end;
258
LuaToVisualGearTypeOrdnull259 function LuaToVisualGearTypeOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
260 begin
261 if lua_isnoneornil(L, i) then i:= -1
262 else i:= Trunc(lua_tonumber(L, i));
263 if (i < ord(Low(TVisualGearType))) or (i > ord(High(TVisualGearType))) then
264 begin
265 LuaCallError('Invalid visualGearType!', call, paramsyntax);
266 LuaToVisualGearTypeOrd:= -1;
267 end
268 else
269 LuaToVisualGearTypeOrd:= i;
270 end;
271
LuaToAmmoTypeOrdnull272 function LuaToAmmoTypeOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
273 begin
274 if lua_isnoneornil(L, i) then i:= -1
275 else i:= Trunc(lua_tonumber(L, i));
276 if (i < ord(Low(TAmmoType))) or (i > ord(High(TAmmoType))) then
277 begin
278 LuaCallError('Invalid ammoType!', call, paramsyntax);
279 LuaToAmmoTypeOrd:= -1;
280 end
281 else
282 LuaToAmmoTypeOrd:= i;
283 end;
284
LuaToStatInfoTypeOrdnull285 function LuaToStatInfoTypeOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
286 begin
287 if lua_isnoneornil(L, i) then i:= -1
288 else i:= Trunc(lua_tonumber(L, i));
289 if (i < ord(Low(TStatInfoType))) or (i > ord(High(TStatInfoType))) then
290 begin
291 LuaCallError('Invalid statInfoType!', call, paramsyntax);
292 LuaToStatInfoTypeOrd:= -1;
293 end
294 else
295 LuaToStatInfoTypeOrd:= i;
296 end;
297
LuaToSoundOrdnull298 function LuaToSoundOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
299 begin
300 if lua_isnoneornil(L, i) then i:= -1
301 else i:= Trunc(lua_tonumber(L, i));
302 if (i < ord(Low(TSound))) or (i > ord(High(TSound))) then
303 begin
304 LuaCallError('Invalid soundId!', call, paramsyntax);
305 LuaToSoundOrd:= -1;
306 end
307 else
308 LuaToSoundOrd:= i;
309 end;
310
LuaToHogEffectOrdnull311 function LuaToHogEffectOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
312 begin
313 if lua_isnoneornil(L, i) then i:= -1
314 else i:= Trunc(lua_tonumber(L, i));
315 if (i < ord(Low(THogEffect))) or (i > ord(High(THogEffect))) then
316 begin
317 LuaCallError('Invalid effect type!', call, paramsyntax);
318 LuaToHogEffectOrd:= -1;
319 end
320 else
321 LuaToHogEffectOrd:= i;
322 end;
323
LuaToCapGroupOrdnull324 function LuaToCapGroupOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
325 begin
326 if lua_isnoneornil(L, i) then i:= -1
327 else i:= Trunc(lua_tonumber(L, i));
328 if (i < ord(Low(TCapGroup))) or (i > ord(High(TCapGroup))) then
329 begin
330 LuaCallError('Invalid capgroup type!', call, paramsyntax);
331 LuaToCapGroupOrd:= -1;
332 end
333 else
334 LuaToCapGroupOrd:= i;
335 end;
336
LuaToSpriteOrdnull337 function LuaToSpriteOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
338 begin
339 if lua_isnoneornil(L, i) then i:= -1
340 else i:= Trunc(lua_tonumber(L, i));
341 if (i < ord(Low(TSprite))) or (i > ord(High(TSprite))) then
342 begin
343 LuaCallError('Invalid sprite id!', call, paramsyntax);
344 LuaToSpriteOrd:= -1;
345 end
346 else
347 LuaToSpriteOrd:= i;
348 end;
349
LuaToMapGenOrdnull350 function LuaToMapGenOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline;
351 begin
352 if lua_isnoneornil(L, i) then i:= -1
353 else i:= Trunc(lua_tonumber(L, i));
354 if (i < ord(Low(TMapGen))) or (i > ord(High(TMapGen))) then
355 begin
356 LuaCallError('Invalid mapgen id!', call, paramsyntax);
357 LuaToMapGenOrd:= -1;
358 end
359 else
360 LuaToMapGenOrd:= i;
361 end;
362
363 // wrapped calls
364
365 // functions called from Lua:
366 // function(L : Plua_State) : LongInt; Cdecl;
367 // where L contains the state, returns the number of return values on the stack
368 // call CheckLuaParamCount or CheckAndFetchParamCount
369 // to validate/get the number of passed arguments (see their call definitions)
370 //
371 // use as return value the number of variables pushed back to the lua script
372
lc_bandnull373 function lc_band(L: PLua_State): LongInt; Cdecl;
374 begin
375 if CheckLuaParamCount(L, 2, 'band', 'value1, value2') then
376 lua_pushnumber(L, Trunc(lua_tonumber(L, 2)) and Trunc(lua_tonumber(L, 1)))
377 else
378 lua_pushnil(L);
379 lc_band := 1;
380 end;
381
lc_bornull382 function lc_bor(L: PLua_State): LongInt; Cdecl;
383 begin
384 if CheckLuaParamCount(L, 2, 'bor', 'value1, value2') then
385 lua_pushnumber(L, Trunc(lua_tonumber(L, 2)) or Trunc(lua_tonumber(L, 1)))
386 else
387 lua_pushnil(L);
388 lc_bor := 1;
389 end;
390
lc_bnotnull391 function lc_bnot(L: PLua_State): LongInt; Cdecl;
392 begin
393 if CheckLuaParamCount(L, 1, 'bnot', 'value') then
394 lua_pushnumber(L, (not Trunc(lua_tonumber(L, 1))))
395 else
396 lua_pushnil(L);
397 lc_bnot := 1;
398 end;
399
lc_divnull400 function lc_div(L: PLua_State): LongInt; Cdecl;
401 begin
402 if CheckLuaParamCount(L, 2, 'div', 'dividend, divisor') then
403 lua_pushnumber(L, Trunc(lua_tonumber(L, 1)) div Trunc(lua_tonumber(L, 2)))
404 else
405 lua_pushnil(L);
406 lc_div := 1;
407 end;
408
lc_getinputmasknull409 function lc_getinputmask(L : Plua_State) : LongInt; Cdecl;
410 begin
411 if CheckLuaParamCount(L, 0, 'GetInputMask', '') then
412 lua_pushnumber(L, InputMask);
413 lc_getinputmask:= 1
414 end;
415
lc_setinputmasknull416 function lc_setinputmask(L : Plua_State) : LongInt; Cdecl;
417 begin
418 if CheckLuaParamCount(L, 1, 'SetInputMask', 'mask') then
419 InputMask:= Trunc(lua_tonumber(L, 1));
420 lc_setinputmask:= 0
421 end;
422
lc_writelntoconsolenull423 function lc_writelntoconsole(L : Plua_State) : LongInt; Cdecl;
424 begin
425 if CheckLuaParamCount(L, 1, 'WriteLnToConsole', 'string') then
426 WriteLnToConsole('Lua: ' + lua_tostring(L ,1));
427 lc_writelntoconsole:= 0;
428 end;
429
lc_writelntochatnull430 function lc_writelntochat(L : Plua_State) : LongInt; Cdecl;
431 begin
432 if CheckLuaParamCount(L, 1, 'WriteLnToChat', 'string') then
433 AddChatString(#2 + lua_tostring(L, 1));
434 lc_writelntochat:= 0;
435 end;
436
lc_parsecommandnull437 function lc_parsecommand(L : Plua_State) : LongInt; Cdecl;
438 var t: PChar;
439 i,c: LongWord;
440 s: shortstring;
441 begin
442 if CheckLuaParamCount(L, 1, 'ParseCommand', 'string') then
443 begin
444 t:= lua_tolstring(L, 1, Psize_t(@c));
445
446 for i:= 1 to c do s[i]:= t[i-1];
447 s[0]:= char(c);
448
449 ParseCommand(s, true, true);
450
451 end;
452 lc_parsecommand:= 0;
453 end;
454
455 // sets weapon to the desired ammo type
lc_setweaponnull456 function lc_setweapon(L : Plua_State) : LongInt; Cdecl;
457 var at: LongInt;
458 const
459 call = 'SetWeapon';
460 params = 'ammoType';
461 begin
462 // no point to run this without any CurrentHedgehog
463 if (CurrentHedgehog <> nil) and (CheckLuaParamCount(L, 1, call, params)) then
464 begin
465 at:= LuaToAmmoTypeOrd(L, 1, call, params);
466 if at >= 0 then
467 ParseCommand('setweap ' + char(at), true, true);
468 end;
469 lc_setweapon:= 0;
470 end;
471
472 // enable/disable cinematic effects
lc_setcinematicmodenull473 function lc_setcinematicmode(L : Plua_State) : LongInt; Cdecl;
474 const
475 call = 'SetCinematicMode';
476 params = 'enable';
477 begin
478 if (CheckLuaParamCount(L, 1, call, params)) then
479 begin
480 CinematicScript:= lua_toboolean(L, 1);
481 end;
482 lc_setcinematicmode:= 0;
483 end;
484
485 // no parameter means reset to default (and 0 means unlimited)
lc_setmaxbuilddistancenull486 function lc_setmaxbuilddistance(L : Plua_State) : LongInt; Cdecl;
487 var np: LongInt;
488 const
489 call = 'SetMaxBuildDistance';
490 params = '[ distInPx ]';
491 begin
492 if CheckAndFetchParamCountRange(L, 0, 1, call, params, np) then
493 begin
494 if np = 0 then
495 begin
496 // no args? reset
497 cBuildMaxDist:= cDefaultBuildMaxDist;
498 end
499 else
500 CBuildMaxDist:= Trunc(lua_tonumber(L, 1));
501 end;
502 lc_setmaxbuilddistance:= 0;
503 end;
504
505 // sets weapon to whatever weapons is next (wraps around, amSkip is skipped)
lc_setnextweaponnull506 function lc_setnextweapon(L : Plua_State) : LongInt; Cdecl;
507 var at : LongInt;
508 nextAmmo : TAmmo;
509 s, a, cs, fa: LongInt;
510 const
511 call = 'SetNextWeapon';
512 params = '';
513 begin
514 if (CurrentHedgehog <> nil) and (CheckLuaParamCount(L, 0, call, params)) then
515 begin
516 at:= -1;
517 with CurrentHedgehog^ do
518 begin
519 cs:= 0; // current slot
520 fa:= 0; // first ammo item to check
521
522 // if something is selected, find it is successor
523 if curAmmoType <> amNothing then
524 begin
525 // get current slot index
526 cs:= Ammoz[CurAmmoType].Slot;
527 // find current ammo index
528 while (fa < cMaxSlotAmmoIndex)
529 and (Ammo^[cs, fa].AmmoType <> CurAmmoType) do
530 inc(fa);
531 // increase once more because we will not successor
532 inc(fa);
533 end;
534
535 // find first available ammo
536 // revisit current slot too (current item might not be first)
537 for s:= cs to cs + cMaxSlotIndex + 1 do
538 begin
539 for a:= fa to cMaxSlotAmmoIndex do
540 begin
541 // check if we went full circle
542 if (a = fa) and (s = cs + cMaxSlotIndex + 1) then
543 exit(0);
544
545 // get ammo
546 nextAmmo:= Ammo^[s mod (cMaxSlotIndex + 1), a];
547 // only switch to ammos the hog actually has
548 if (nextAmmo.AmmoType <> amNothing)
549 and (nextAmmo.AmmoType <> amSkip) and (nextAmmo.Count > 0) then
550 begin
551 at:= ord(nextAmmo.AmmoType);
552 break;
553 end;
554 end;
555 // stop slot loop if something was found
556 if at >= 0 then
557 break;
558 // check following slots starting with first item
559 fa:= 0;
560 end;
561 end;
562
563 if at >= 0 then
564 ParseCommand('setweap ' + char(at), true, true);
565 end;
566 lc_setnextweapon:= 0;
567 end;
568
lc_showmissionnull569 function lc_showmission(L : Plua_State) : LongInt; Cdecl;
570 var n: LongInt;
571 begin
572 if CheckAndFetchParamCount(L, 5, 6, 'ShowMission', 'caption, subcaption, text, icon, time [, forceDisplay]', n) then
573 if n = 5 then
574 ShowMission(lua_tostringA(L, 1), lua_tostringA(L, 2), lua_tostringA(L, 3), Trunc(lua_tonumber(L, 4)), Trunc(lua_tonumber(L, 5)))
575 else
576 ShowMission(lua_tostringA(L, 1), lua_tostringA(L, 2), lua_tostringA(L, 3), Trunc(lua_tonumber(L, 4)), Trunc(lua_tonumber(L, 5)), lua_toboolean(L, 6));
577 lc_showmission:= 0;
578 end;
579
lc_hidemissionnull580 function lc_hidemission(L : Plua_State) : LongInt; Cdecl;
581 begin
582 L:= L; // avoid compiler hint
583 HideMission;
584 lc_hidemission:= 0;
585 end;
586
lc_setammotextsnull587 function lc_setammotexts(L : Plua_State) : LongInt; Cdecl;
588 const
589 call = 'SetAmmoTexts';
590 params = 'ammoType, name, caption, description [, showExtra]';
591 var n: integer;
592 showExtra: boolean;
593 begin
594 if CheckAndFetchParamCount(L, 4, 5, call, params, n) then
595 begin
596 if n = 5 then
597 showExtra:= lua_toboolean(L, 5)
598 else
599 showExtra:= true;
600 SetAmmoTexts(TAmmoType(LuaToAmmoTypeOrd(L, 1, call, params)), lua_tostringA(L, 2), lua_tostringA(L, 3), lua_tostringA(L, 4), showExtra);
601 end;
602 lc_setammotexts:= 0;
603 end;
604
lc_setammodescriptionappendixnull605 function lc_setammodescriptionappendix(L : Plua_State) : LongInt; Cdecl;
606 const
607 call = 'SetAmmoDescriptionAppendix';
608 params = 'ammoType, descAppend';
609 var
610 ammoType: TAmmoType;
611 descAppend: ansistring;
612 begin
613 if CheckLuaParamCount(L, 2, call, params) then
614 begin
615 ammoType := TAmmoType(LuaToAmmoTypeOrd(L, 1, call, params));
616 descAppend := lua_tostringA(L, 2);
617 trluaammoa[Ammoz[ammoType].NameId] := descAppend;
618 end;
619 lc_setammodescriptionappendix := 0;
620 end;
621
lc_enablegameflagsnull622 function lc_enablegameflags(L : Plua_State) : LongInt; Cdecl;
623 var i, n : integer;
624 begin
625 // can have 1 or more arguments
626 if CheckAndFetchLuaParamMinCount(L, 1, 'EnableGameFlags', 'gameFlag, ... ', n) then
627 begin
628 for i:= 1 to n do
629 GameFlags := GameFlags or LongWord(Trunc(lua_tonumber(L, i)));
630 ScriptSetInteger('GameFlags', GameFlags);
631 end;
632 lc_enablegameflags:= 0;
633 end;
634
lc_disablegameflagsnull635 function lc_disablegameflags(L : Plua_State) : LongInt; Cdecl;
636 var i , n: integer;
637 begin
638 // can have 1 or more arguments
639 if CheckAndFetchLuaParamMinCount(L, 1, 'DisableGameFlags', 'gameFlag, ... ', n) then
640 begin
641 for i:= 1 to n do
642 GameFlags := GameFlags and (not LongWord(Trunc(lua_tonumber(L, i))));
643 ScriptSetInteger('GameFlags', GameFlags);
644 end;
645 lc_disablegameflags:= 0;
646 end;
647
lc_cleargameflagsnull648 function lc_cleargameflags(L : Plua_State) : LongInt; Cdecl;
649 begin
650 if CheckLuaParamCount(L, 0, 'ClearGameFlags', '') then
651 begin
652 GameFlags:= 0;
653 ScriptSetInteger('GameFlags', GameFlags);
654 end;
655 lc_cleargameflags:= 0;
656 end;
657
lc_getgameflagnull658 function lc_getgameflag(L : Plua_State) : LongInt; Cdecl;
659 begin
660 if CheckLuaParamCount(L, 1, 'GetGameFlag', 'gameflag') then
661 lua_pushboolean(L, (GameFlags and LongWord(Trunc(lua_tonumber(L, 1))) <> 0))
662 else
663 lua_pushnil(L);
664 lc_getgameflag:= 1;
665 end;
666
lc_addcaptionnull667 function lc_addcaption(L : Plua_State) : LongInt; Cdecl;
668 var cg: LongInt;
669 const
670 call = 'AddCaption';
671 params = 'text [, color, captiongroup]';
672 begin
673 if CheckAndFetchParamCount(L, 1, 3, call, params, cg) then
674 begin
675 if cg = 1 then
676 AddCaption(lua_tostringA(L, 1), capcolDefault, capgrpMessage)
677 else
678 begin
679 cg:= LuaToCapGroupOrd(L, 3, call, params);
680 if cg >= 0 then
681 AddCaption(lua_tostringA(L, 1), Trunc(lua_tonumber(L, 2)) shr 8, TCapGroup(cg));
682 end
683 end;
684 lc_addcaption:= 0;
685 end;
686
lc_spawnfakehealthcratenull687 function lc_spawnfakehealthcrate(L: Plua_State) : LongInt; Cdecl;
688 var gear: PGear;
689 explode, poison: boolean;
690 n: LongInt;
691 begin
692 if CheckAndFetchParamCountRange(L, 2, 4, 'SpawnFakeHealthCrate', 'x, y [, explode [, poison]]', n) then
693 begin
694 explode:= false;
695 poison:= false;
696 if (n >= 3) and (not lua_isnil(L, 3)) then
697 explode:= lua_toboolean(L, 3);
698 if (n = 4) and (not lua_isnil(L, 4)) then
699 poison:= lua_toboolean(L, 4);
700
701 gear := SpawnFakeCrateAt(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)),
702 HealthCrate, explode, poison);
703 if gear <> nil then
704 lua_pushnumber(L, gear^.uid)
705 else lua_pushnil(L)
706 end
707 else
708 lua_pushnil(L);
709 lc_spawnfakehealthcrate := 1;
710 end;
711
lc_spawnfakeammocratenull712 function lc_spawnfakeammocrate(L: PLua_State): LongInt; Cdecl;
713 var gear: PGear;
714 explode, poison: boolean;
715 n: LongInt;
716 begin
717 if CheckAndFetchParamCountRange(L, 2, 4, 'SpawnFakeAmmoCrate', 'x, y [, explode [, poison]]', n) then
718 begin
719 explode:= false;
720 poison:= false;
721 if (n >= 3) and (not lua_isnil(L, 3)) then
722 explode:= lua_toboolean(L, 3);
723 if (n = 4) and (not lua_isnil(L, 4)) then
724 poison:= lua_toboolean(L, 4);
725
726 gear := SpawnFakeCrateAt(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)),
727 AmmoCrate, explode, poison);
728 if gear <> nil then
729 lua_pushnumber(L, gear^.uid)
730 else lua_pushnil(L)
731 end
732 else
733 lua_pushnil(L);
734 lc_spawnfakeammocrate := 1;
735 end;
736
lc_spawnfakeutilitycratenull737 function lc_spawnfakeutilitycrate(L: PLua_State): LongInt; Cdecl;
738 var gear: PGear;
739 explode, poison: boolean;
740 n: LongInt;
741 begin
742 if CheckAndFetchParamCountRange(L, 2, 4, 'SpawnFakeUtilityCrate', 'x, y [, explode [, poison]]', n) then
743 begin
744 explode:= false;
745 poison:= false;
746 if (n >= 3) and (not lua_isnil(L, 3)) then
747 explode:= lua_toboolean(L, 3);
748 if (n = 4) and (not lua_isnil(L, 4)) then
749 poison:= lua_toboolean(L, 4);
750
751 gear := SpawnFakeCrateAt(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)),
752 UtilityCrate, explode, poison);
753 if gear <> nil then
754 lua_pushnumber(L, gear^.uid)
755 else lua_pushnil(L)
756 end
757 else
758 lua_pushnil(L);
759 lc_spawnfakeutilitycrate := 1;
760 end;
761
lc_spawnhealthcratenull762 function lc_spawnhealthcrate(L: Plua_State) : LongInt; Cdecl;
763 var gear: PGear;
764 var health, n: LongInt;
765 begin
766 if CheckAndFetchParamCount(L, 2, 3, 'SpawnHealthCrate', 'x, y [, health]', n) then
767 begin
768 if n = 3 then
769 health:= Trunc(lua_tonumber(L, 3))
770 else
771 health:= cHealthCaseAmount;
772 gear := SpawnCustomCrateAt(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)), HealthCrate, health, 0);
773 if gear <> nil then
774 lua_pushnumber(L, gear^.uid)
775 else lua_pushnil(L);
776 end
777 else
778 lua_pushnil(L);
779 lc_spawnhealthcrate := 1;
780 end;
781
lc_spawnammocratenull782 function lc_spawnammocrate(L: PLua_State): LongInt; Cdecl;
783 var gear: PGear;
784 n : LongInt;
785 begin
786 if CheckAndFetchParamCount(L, 3, 4, 'SpawnAmmoCrate', 'x, y, content [, amount]', n) then
787 begin
788 if n = 3 then
789 gear := SpawnCustomCrateAt(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)), AmmoCrate, Trunc(lua_tonumber(L, 3)), 0)
790 else gear := SpawnCustomCrateAt(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)), AmmoCrate, Trunc(lua_tonumber(L, 3)), Trunc(lua_tonumber(L, 4)));
791 if gear <> nil then
792 lua_pushnumber(L, gear^.uid)
793 else lua_pushnil(L);
794 end
795 else
796 lua_pushnil(L);
797 lc_spawnammocrate := 1;
798 end;
799
lc_spawnutilitycratenull800 function lc_spawnutilitycrate(L: PLua_State): LongInt; Cdecl;
801 var gear: PGear;
802 n : LongInt;
803 begin
804 if CheckAndFetchParamCount(L, 3, 4, 'SpawnUtilityCrate', 'x, y, content [, amount]', n) then
805 begin
806 if n = 3 then
807 gear := SpawnCustomCrateAt(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)), UtilityCrate, Trunc(lua_tonumber(L, 3)), 0)
808 else gear := SpawnCustomCrateAt(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)), UtilityCrate, Trunc(lua_tonumber(L, 3)), Trunc(lua_tonumber(L, 4)));
809 if gear <> nil then
810 lua_pushnumber(L, gear^.uid)
811 else lua_pushnil(L);
812 end
813 else
814 lua_pushnil(L);
815 lc_spawnutilitycrate := 1;
816 end;
817
lc_spawnsupplycratenull818 function lc_spawnsupplycrate(L: PLua_State): LongInt; Cdecl;
819 var gear: PGear;
820 n, at:LongInt;
821 t: TCrateType;
822 begin
823 if CheckAndFetchParamCount(L, 3, 4, 'SpawnSupplyCrate', 'x, y, content [, amount]', n) then
824 begin
825 // Get crate type (ammo or utility)
826 at:= Trunc(lua_tonumber(L, 3));
827 if (Ammoz[TAmmoType(at)].Ammo.Propz and ammoprop_Utility) <> 0 then
828 t:= UtilityCrate
829 else
830 t:= AmmoCrate;
831 if n = 3 then
832 gear := SpawnCustomCrateAt(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)), t, at, 0)
833 else gear := SpawnCustomCrateAt(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)), t, at, Trunc(lua_tonumber(L, 4)));
834 if gear <> nil then
835 lua_pushnumber(L, gear^.uid)
836 else lua_pushnil(L);
837 end
838 else
839 lua_pushnil(L);
840 lc_spawnsupplycrate := 1;
841 end;
842
lc_addgearnull843 function lc_addgear(L : Plua_State) : LongInt; Cdecl;
844 var gear : PGear;
845 x, y, s, t: LongInt;
846 dx, dy: hwFloat;
847 gt: TGearType;
848 const
849 call = 'AddGear';
850 params = 'x, y, gearType, state, dx, dy, timer';
851 begin
852 if CheckLuaParamCount(L, 7, call, params) then
853 begin
854 t:= LuaToGearTypeOrd(L, 3, call, params);
855 if t >= 0 then
856 begin
857 gt:= TGearType(t);
858 x:= Trunc(lua_tonumber(L, 1));
859 y:= Trunc(lua_tonumber(L, 2));
860 s:= Trunc(lua_tonumber(L, 4));
861 dx:= int2hwFloat(Trunc(lua_tonumber(L, 5))) / 1000000;
862 dy:= int2hwFloat(Trunc(lua_tonumber(L, 6))) / 1000000;
863 t:= Trunc(lua_tonumber(L, 7));
864
865 gear:= AddGear(x, y, gt, s, dx, dy, t);
866 lastGearByUID:= gear;
867 lua_pushnumber(L, gear^.uid)
868 end
869 else
870 lua_pushnil(L);
871 end
872 else
873 lua_pushnil(L);
874 lc_addgear:= 1; // 1 return value
875 end;
876
lc_deletegearnull877 function lc_deletegear(L : Plua_State) : LongInt; Cdecl;
878 var gear : PGear;
879 begin
880 if CheckLuaParamCount(L, 1, 'DeleteGear', 'gearUid') then
881 begin
882 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
883 if gear <> nil then
884 gear^.Message:= gear^.Message or gmDelete;
885 end;
886 lc_deletegear:= 0
887 end;
888
lc_addvisualgearnull889 function lc_addvisualgear(L : Plua_State) : LongInt; Cdecl;
890 var vg : PVisualGear;
891 x, y, s, n, layer: LongInt;
892 c: Boolean;
893 vgt: TVisualGearType;
894 uid: Longword;
895 const
896 call = 'AddVisualGear';
897 params = 'x, y, visualGearType, state, critical [, layer]';
898 begin
899 uid:= 0;
900 if CheckAndFetchParamCount(L, 5, 6, call, params, n) then
901 begin
902 s:= LuaToVisualGearTypeOrd(L, 3, call, params);
903 if s >= 0 then
904 begin
905 vgt:= TVisualGearType(s);
906 x:= Trunc(lua_tonumber(L, 1));
907 y:= Trunc(lua_tonumber(L, 2));
908 s:= Trunc(lua_tonumber(L, 4));
909 c:= lua_toboolean(L, 5);
910
911 if n = 6 then
912 begin
913 layer:= Trunc(lua_tonumber(L, 6));
914 vg:= AddVisualGear(x, y, vgt, s, c, layer);
915 end
916 else
917 vg:= AddVisualGear(x, y, vgt, s, c);
918
919 if vg <> nil then
920 begin
921 lastVisualGearByUID:= vg;
922 uid:= vg^.uid;
923 lua_pushnumber(L, uid);
924 end;
925 end
926 else
927 lua_pushnil(L);
928 end
929 else
930 lua_pushnil(L); // return value on stack (nil)
931 lc_addvisualgear:= 1; // 1 return value
932 end;
933
lc_deletevisualgearnull934 function lc_deletevisualgear(L : Plua_State) : LongInt; Cdecl;
935 var vg : PVisualGear;
936 begin
937 vg:= nil;
938 if CheckLuaParamCount(L, 1, 'DeleteVisualGear', 'vgUid') then
939 begin
940 vg:= VisualGearByUID(Trunc(lua_tonumber(L, 1)));
941 if vg <> nil then
942 DeleteVisualGear(vg);
943 end;
944 // allow caller to know whether there was something to delete
945 lua_pushboolean(L, vg <> nil);
946 lc_deletevisualgear:= 1
947 end;
948
lc_getvisualgeartypenull949 function lc_getvisualgeartype(L : Plua_State) : LongInt; Cdecl;
950 var vg : PVisualGear;
951 begin
952 if CheckLuaParamCount(L, 1, 'GetVisualGearType', 'vgUid') then
953 begin
954 vg := VisualGearByUID(Trunc(lua_tonumber(L, 1)));
955 if vg <> nil then
956 lua_pushnumber(L, ord(vg^.Kind))
957 else
958 lua_pushnil(L);
959 end
960 else
961 lua_pushnil(L); // return value on stack (nil)
962 lc_getvisualgeartype:= 1
963 end;
964
965
lc_getvisualgearvaluesnull966 function lc_getvisualgearvalues(L : Plua_State) : LongInt; Cdecl;
967 var vg: PVisualGear;
968 begin
969 if CheckLuaParamCount(L, 1, 'GetVisualGearValues', 'vgUid') then
970 begin
971 vg:= VisualGearByUID(Trunc(lua_tonumber(L, 1)));
972 if vg <> nil then
973 begin
974 lua_pushnumber(L, round(vg^.X));
975 lua_pushnumber(L, round(vg^.Y));
976 lua_pushnumber(L, vg^.dX);
977 lua_pushnumber(L, vg^.dY);
978 lua_pushnumber(L, vg^.Angle);
979 lua_pushnumber(L, vg^.Frame);
980 lua_pushnumber(L, vg^.FrameTicks);
981 lua_pushnumber(L, vg^.State);
982 lua_pushnumber(L, vg^.Timer);
983 lua_pushnumber(L, vg^.Tint);
984 lua_pushnumber(L, vg^.Scale);
985 end
986 else
987 begin
988 lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
989 lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
990 end
991 end
992 else
993 begin
994 lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
995 lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
996 end;
997 lc_getvisualgearvalues:= 10
998 end;
999
lc_setvisualgearvaluesnull1000 function lc_setvisualgearvalues(L : Plua_State) : LongInt; Cdecl;
1001 var vg : PVisualGear;
1002 begin
1003 // Param count can be 1-11 at present
1004 // if CheckLuaParamCount(L, 11, 'SetVisualGearValues', 'vgUid, X, Y, dX, dY, Angle, Frame, FrameTicks, State, Timer, Tint, Scale') then
1005 // begin
1006 vg:= VisualGearByUID(Trunc(lua_tonumber(L, 1)));
1007 if vg <> nil then
1008 begin
1009 if not lua_isnoneornil(L, 2) then
1010 vg^.X:= Trunc(lua_tonumber(L, 2));
1011 if not lua_isnoneornil(L, 3) then
1012 vg^.Y:= Trunc(lua_tonumber(L, 3));
1013 if not lua_isnoneornil(L, 4) then
1014 vg^.dX:= lua_tonumber(L, 4);
1015 if not lua_isnoneornil(L, 5) then
1016 vg^.dY:= lua_tonumber(L, 5);
1017 if not lua_isnoneornil(L, 6) then
1018 vg^.Angle:= lua_tonumber(L, 6);
1019 if not lua_isnoneornil(L, 7) then
1020 vg^.Frame:= Trunc(lua_tonumber(L, 7));
1021 if not lua_isnoneornil(L, 8) then
1022 vg^.FrameTicks:= Trunc(lua_tonumber(L, 8));
1023 if not lua_isnoneornil(L, 9) then
1024 vg^.State:= Trunc(lua_tonumber(L, 9));
1025 if not lua_isnoneornil(L, 10) then
1026 vg^.Timer:= Trunc(lua_tonumber(L, 10));
1027 if not lua_isnoneornil(L, 11) then
1028 vg^.Tint:= Trunc(lua_tonumber(L, 11));
1029 if not lua_isnoneornil(L, 12) then
1030 vg^.Scale:= Trunc(lua_tonumber(L, 12))
1031 end;
1032 // end
1033 // else
1034 // lua_pushnil(L); // return value on stack (nil)
1035 lc_setvisualgearvalues:= 0
1036 end;
1037
1038 // so. going to use this to get/set some of the more obscure gear values which were not already exposed elsewhere
1039 // can keep adding things in the future. isnoneornil makes it safe
lc_getgearvaluesnull1040 function lc_getgearvalues(L : Plua_State) : LongInt; Cdecl;
1041 var gear: PGear;
1042 begin
1043 if CheckLuaParamCount(L, 1, 'GetGearValues', 'gearUid') then
1044 begin
1045 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1046 if gear <> nil then
1047 begin
1048 lua_pushnumber(L, gear^.Angle);
1049 lua_pushnumber(L, gear^.Power);
1050 lua_pushnumber(L, gear^.WDTimer);
1051 lua_pushnumber(L, gear^.Radius);
1052 lua_pushnumber(L, hwRound(gear^.Density * _10000));
1053 lua_pushnumber(L, gear^.Karma);
1054 lua_pushnumber(L, gear^.DirAngle);
1055 lua_pushnumber(L, gear^.AdvBounce);
1056 lua_pushnumber(L, Integer(gear^.ImpactSound));
1057 lua_pushnumber(L, gear^.nImpactSounds);
1058 lua_pushnumber(L, gear^.Tint);
1059 lua_pushnumber(L, gear^.Damage);
1060 lua_pushnumber(L, gear^.Boom)
1061 end
1062 else
1063 begin
1064 lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
1065 lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
1066 lua_pushnil(L); lua_pushnil(L); lua_pushnil(L)
1067 end
1068 end
1069 else
1070 begin
1071 lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
1072 lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
1073 lua_pushnil(L); lua_pushnil(L); lua_pushnil(L)
1074 end;
1075 lc_getgearvalues:= 13
1076 end;
1077
lc_setgearvaluesnull1078 function lc_setgearvalues(L : Plua_State) : LongInt; Cdecl;
1079 var gear : PGear;
1080 begin
1081 // Currently allows 1-14 params
1082 // if CheckLuaParamCount(L, 14, 'SetGearValues', 'gearUid, Angle, Power, WDTimer, Radius, Density, Karma, DirAngle, AdvBounce, ImpactSound, # ImpactSounds, Tint, Damage, Boom') then
1083 // begin
1084 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1085 if gear <> nil then
1086 begin
1087 if not lua_isnoneornil(L, 2) then
1088 gear^.Angle := Trunc(lua_tonumber(L, 2));
1089 if not lua_isnoneornil(L, 3) then
1090 gear^.Power := Trunc(lua_tonumber(L, 3));
1091 if not lua_isnoneornil(L, 4) then
1092 gear^.WDTimer := Trunc(lua_tonumber(L, 4));
1093 if not lua_isnoneornil(L, 5) then
1094 gear^.Radius := Trunc(lua_tonumber(L, 5));
1095 if not lua_isnoneornil(L, 6) then
1096 gear^.Density:= int2hwFloat(Trunc(lua_tonumber(L, 6))) / 10000;
1097 if not lua_isnoneornil(L, 7) then
1098 gear^.Karma := Trunc(lua_tonumber(L, 7));
1099 if not lua_isnoneornil(L, 8) then
1100 gear^.DirAngle:= lua_tonumber(L, 8);
1101 if not lua_isnoneornil(L, 9) then
1102 gear^.AdvBounce := Trunc(lua_tonumber(L, 9));
1103 if not lua_isnoneornil(L, 10) then
1104 gear^.ImpactSound := TSound(Trunc(lua_tonumber(L, 10)));
1105 if not lua_isnoneornil(L, 11) then
1106 gear^.nImpactSounds := Trunc(lua_tonumber(L, 11));
1107 if not lua_isnoneornil(L, 12) then
1108 gear^.Tint := Trunc(lua_tonumber(L, 12));
1109 if not lua_isnoneornil(L, 13) then
1110 gear^.Damage := Trunc(lua_tonumber(L, 13));
1111 if not lua_isnoneornil(L, 14) then
1112 gear^.Boom := Trunc(lua_tonumber(L, 14));
1113 end;
1114 // end
1115 // else
1116 // lua_pushnil(L); // return value on stack (nil)
1117 lc_setgearvalues:= 0
1118 end;
1119
lc_getfollowgearnull1120 function lc_getfollowgear(L : Plua_State) : LongInt; Cdecl;
1121 begin
1122 if CheckLuaParamCount(L, 0, 'GetFollowGear', '') then
1123 begin
1124 if FollowGear = nil then
1125 lua_pushnil(L)
1126 else
1127 lua_pushnumber(L, FollowGear^.uid);
1128 end
1129 else
1130 lua_pushnil(L);
1131 lc_getfollowgear:= 1; // 1 return value
1132 end;
1133
lc_getgeartypenull1134 function lc_getgeartype(L : Plua_State) : LongInt; Cdecl;
1135 var gear : PGear;
1136 begin
1137 if CheckLuaParamCount(L, 1, 'GetGearType', 'gearUid') then
1138 begin
1139 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1140 if gear <> nil then
1141 lua_pushnumber(L, ord(gear^.Kind))
1142 else
1143 lua_pushnil(L);
1144 end
1145 else
1146 lua_pushnil(L); // return value on stack (nil)
1147 lc_getgeartype:= 1
1148 end;
1149
lc_getgearmessagenull1150 function lc_getgearmessage(L : Plua_State) : LongInt; Cdecl;
1151 var gear : PGear;
1152 begin
1153 if CheckLuaParamCount(L, 1, 'GetGearMessage', 'gearUid') then
1154 begin
1155 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1156 if gear <> nil then
1157 lua_pushnumber(L, gear^.message)
1158 else
1159 lua_pushnil(L);
1160 end
1161 else
1162 lua_pushnil(L); // return value on stack (nil)
1163 lc_getgearmessage:= 1
1164 end;
1165
lc_getgearelasticitynull1166 function lc_getgearelasticity(L : Plua_State) : LongInt; Cdecl;
1167 var gear : PGear;
1168 begin
1169 if CheckLuaParamCount(L, 1, 'GetGearElasticity', 'gearUid') then
1170 begin
1171 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1172 if gear <> nil then
1173 lua_pushnumber(L, hwRound(gear^.elasticity * _10000))
1174 else
1175 lua_pushnil(L);
1176 end
1177 else
1178 lua_pushnil(L); // return value on stack (nil)
1179 lc_getgearelasticity:= 1
1180 end;
1181
lc_setgearelasticitynull1182 function lc_setgearelasticity(L : Plua_State) : LongInt; Cdecl;
1183 var gear: PGear;
1184 begin
1185 if CheckLuaParamCount(L, 2, 'SetGearElasticity', 'gearUid, Elasticity') then
1186 begin
1187 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1188 if gear <> nil then
1189 gear^.Elasticity:= int2hwFloat(Trunc(lua_tonumber(L, 2))) / 10000
1190 end;
1191 lc_setgearelasticity:= 0
1192 end;
1193
lc_getgearfrictionnull1194 function lc_getgearfriction(L : Plua_State) : LongInt; Cdecl;
1195 var gear : PGear;
1196 begin
1197 if CheckLuaParamCount(L, 1, 'GetGearFriction', 'gearUid') then
1198 begin
1199 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1200 if gear <> nil then
1201 lua_pushnumber(L, hwRound(gear^.friction * _10000))
1202 else
1203 lua_pushnil(L);
1204 end
1205 else
1206 lua_pushnil(L); // return value on stack (nil)
1207 lc_getgearfriction:= 1
1208 end;
1209
lc_setgearfrictionnull1210 function lc_setgearfriction(L : Plua_State) : LongInt; Cdecl;
1211 var gear: PGear;
1212 begin
1213 if CheckLuaParamCount(L, 2, 'SetGearFriction', 'gearUid, Friction') then
1214 begin
1215 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1216 if gear <> nil then
1217 gear^.Friction:= int2hwFloat(Trunc(lua_tonumber(L, 2))) / 10000
1218 end;
1219 lc_setgearfriction:= 0
1220 end;
1221
lc_setgearmessagenull1222 function lc_setgearmessage(L : Plua_State) : LongInt; Cdecl;
1223 var gear : PGear;
1224 begin
1225 if CheckLuaParamCount(L, 2, 'SetGearMessage', 'gearUid, message') then
1226 begin
1227 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1228 if gear <> nil then
1229 gear^.message:= Trunc(lua_tonumber(L, 2));
1230 end;
1231 lc_setgearmessage:= 0
1232 end;
1233
lc_getgearposnull1234 function lc_getgearpos(L : Plua_State) : LongInt; Cdecl;
1235 var gear : PGear;
1236 begin
1237 if CheckLuaParamCount(L, 1, 'GetGearPos', 'gearUid') then
1238 begin
1239 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1240 if gear <> nil then
1241 lua_pushnumber(L, gear^.Pos)
1242 else
1243 lua_pushnil(L);
1244 end
1245 else
1246 lua_pushnil(L); // return value on stack (nil)
1247 lc_getgearpos:= 1
1248 end;
1249
lc_setgearposnull1250 function lc_setgearpos(L : Plua_State) : LongInt; Cdecl;
1251 var gear : PGear;
1252 begin
1253 if CheckLuaParamCount(L, 2, 'SetGearPos', 'gearUid, value') then
1254 begin
1255 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1256 if gear <> nil then
1257 gear^.Pos:= Trunc(lua_tonumber(L, 2));
1258 end;
1259 lc_setgearpos:= 0
1260 end;
1261
lc_getgearcollisionmasknull1262 function lc_getgearcollisionmask(L : Plua_State) : LongInt; Cdecl;
1263 var gear : PGear;
1264 begin
1265 if CheckLuaParamCount(L, 1, 'GetGearCollisionMask', 'gearUid') then
1266 begin
1267 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1268 if gear <> nil then
1269 lua_pushnumber(L, gear^.CollisionMask)
1270 else
1271 lua_pushnil(L);
1272 end
1273 else
1274 lua_pushnil(L); // return value on stack (nil)
1275 lc_getgearcollisionmask:= 1
1276 end;
1277
lc_setgearcollisionmasknull1278 function lc_setgearcollisionmask(L : Plua_State) : LongInt; Cdecl;
1279 var gear : PGear;
1280 begin
1281 if CheckLuaParamCount(L, 2, 'SetGearCollisionMask', 'gearUid, mask') then
1282 begin
1283 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1284 if gear <> nil then
1285 gear^.CollisionMask:= Trunc(lua_tonumber(L, 2));
1286 end;
1287 lc_setgearcollisionmask:= 0
1288 end;
1289
lc_gethoglevelnull1290 function lc_gethoglevel(L : Plua_State): LongInt; Cdecl;
1291 var gear : PGear;
1292 begin
1293 if CheckLuaParamCount(L, 1, 'GetHogLevel', 'gearUid') then
1294 begin
1295 gear := GearByUID(Trunc(lua_tonumber(L, 1)));
1296 if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
1297 lua_pushnumber(L, gear^.Hedgehog^.BotLevel)
1298 else
1299 lua_pushnil(L);
1300 end;
1301 lc_gethoglevel := 1;
1302 end;
1303
lc_sethoglevelnull1304 function lc_sethoglevel(L : Plua_State) : LongInt; Cdecl;
1305 var gear : PGear;
1306 begin
1307 if CheckLuaParamCount(L, 2, 'SetHogLevel', 'gearUid, level') then
1308 begin
1309 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1310 if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
1311 gear^.Hedgehog^.BotLevel:= Trunc(lua_tonumber(L, 2));
1312 end;
1313 lc_sethoglevel:= 0
1314 end;
1315
lc_gethogclannull1316 function lc_gethogclan(L : Plua_State) : LongInt; Cdecl;
1317 var gear : PGear;
1318 begin
1319 if CheckLuaParamCount(L, 1, 'GetHogClan', 'gearUid') then
1320 begin
1321 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1322 if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
1323 begin
1324 lua_pushnumber(L, gear^.Hedgehog^.Team^.Clan^.ClanIndex)
1325 end
1326 else
1327 lua_pushnil(L);
1328 end
1329 else
1330 lua_pushnil(L); // return value on stack (nil)
1331 lc_gethogclan:= 1
1332 end;
1333
lc_getclancolornull1334 function lc_getclancolor(L : Plua_State) : LongInt; Cdecl;
1335 var idx: integer;
1336 begin
1337 if CheckLuaParamCount(L, 1, 'GetClanColor', 'clanIdx') then
1338 begin
1339 idx:= Trunc(lua_tonumber(L, 1));
1340 if (not lua_isnumber(L, 1)) then
1341 begin
1342 LuaError('Argument ''clanIdx'' must be a number!');
1343 lua_pushnil(L);
1344 end
1345 else if (idx < 0) or (idx >= ClansCount) then
1346 begin
1347 LuaError('Argument ''clanIdx'' out of range! (There are currently ' + IntToStr(ClansCount) + ' clans, so valid range is: 0-' + IntToStr(ClansCount-1) + ')');
1348 lua_pushnil(L);
1349 end
1350 else
1351 lua_pushnumber(L, ClansArray[idx]^.Color shl 8 or $FF);
1352 end
1353 else
1354 lua_pushnil(L); // return value on stack (nil)
1355 lc_getclancolor:= 1
1356 end;
1357
lc_setclancolornull1358 function lc_setclancolor(L : Plua_State) : LongInt; Cdecl;
1359 var clan : PClan;
1360 team : PTeam;
1361 hh : THedgehog;
1362 i, j : LongInt;
1363 colorArg: Int64;
1364 color: LongWord;
1365 begin
1366 if CheckLuaParamCount(L, 2, 'SetClanColor', 'clan, color') then
1367 begin
1368 i:= Trunc(lua_tonumber(L,1));
1369 if i >= ClansCount then exit(0);
1370 clan := ClansArray[i];
1371 colorArg:= Trunc(lua_tonumber(L, 2));
1372 if (colorArg < 0) and (abs(colorArg) <= cClanColors) then
1373 // Pick clan color from settings (recommended)
1374 color:= ClanColorArray[Pred(abs(colorArg))]
1375 else if (colorArg >= 0) and (colorArg <= $ffffffff) then
1376 // Specify color directly
1377 color:= colorArg shr 8
1378 else
1379 begin
1380 OutError('Lua error: SetClanColor: Invalid ''color'' argument, must be between '+IntToStr(-cClanColors)+' and 0xffffffff!', true);
1381 lc_setclancolor:= 0;
1382 exit;
1383 end;
1384
1385 clan^.Color:= color;
1386
1387 for i:= 0 to Pred(clan^.TeamsNumber) do
1388 begin
1389 team:= clan^.Teams[i];
1390 for j:= 0 to cMaxHHIndex do
1391 begin
1392 hh:= team^.Hedgehogs[j];
1393 if (hh.Gear <> nil) or (hh.GearHidden <> nil) then
1394 begin
1395 FreeAndNilTexture(hh.NameTagTex);
1396 hh.NameTagTex:= RenderStringTex(ansistring(hh.Name), clan^.Color, fnt16);
1397 RenderHealth(hh);
1398 team^.Hedgehogs[j]:= hh;
1399 end;
1400 end;
1401 FreeAndNilTexture(team^.NameTagTex);
1402 team^.NameTagTex:= RenderStringTex(ansistring(clan^.Teams[i]^.TeamName), clan^.Color, fnt16);
1403 end;
1404
1405 FreeAndNilTexture(clan^.HealthTex);
1406 clan^.HealthTex:= makeHealthBarTexture(cTeamHealthWidth + 5, clan^.Teams[0]^.NameTagTex^.h, clan^.Color);
1407 end;
1408
1409 lc_setclancolor:= 0
1410 end;
1411
lc_gethogvoicepacknull1412 function lc_gethogvoicepack(L : Plua_State) : LongInt; Cdecl;
1413 var gear : PGear;
1414 begin
1415 if CheckLuaParamCount(L, 1, 'GetHogVoicepack', 'gearUid') then
1416 begin
1417 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1418 if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
1419 lua_pushstring(L, str2pchar(gear^.Hedgehog^.Team^.Voicepack^.name))
1420 else
1421 lua_pushnil(L);
1422 end
1423 else
1424 lua_pushnil(L); // return value on stack (nil)
1425 lc_gethogvoicepack:= 1
1426 end;
1427
lc_gethoggravenull1428 function lc_gethoggrave(L : Plua_State) : LongInt; Cdecl;
1429 var gear : PGear;
1430 begin
1431 if CheckLuaParamCount(L, 1, 'GetHogGrave', 'gearUid') then
1432 begin
1433 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1434 if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
1435 lua_pushstring(L, str2pchar(gear^.Hedgehog^.Team^.GraveName))
1436 else
1437 lua_pushnil(L);
1438 end
1439 else
1440 lua_pushnil(L); // return value on stack (nil)
1441 lc_gethoggrave:= 1
1442 end;
1443
lc_gethogflagnull1444 function lc_gethogflag(L : Plua_State) : LongInt; Cdecl;
1445 var gear : PGear;
1446 begin
1447 if CheckLuaParamCount(L, 1, 'GetHogFlag', 'gearUid') then
1448 begin
1449 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1450 // TODO error messages
1451 if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
1452 lua_pushstring(L, str2pchar(gear^.Hedgehog^.Team^.Flag))
1453 else
1454 lua_pushnil(L);
1455 end
1456 else
1457 lua_pushnil(L); // return value on stack (nil)
1458 lc_gethogflag:= 1
1459 end;
1460
lc_gethogfortnull1461 function lc_gethogfort(L : Plua_State) : LongInt; Cdecl;
1462 var gear : PGear;
1463 begin
1464 if CheckLuaParamCount(L, 1, 'GetHogFort', 'gearUid') then
1465 begin
1466 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1467 // TODO error messages
1468 if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
1469 lua_pushstring(L, str2pchar(gear^.Hedgehog^.Team^.FortName))
1470 else
1471 lua_pushnil(L);
1472 end
1473 else
1474 lua_pushnil(L); // return value on stack (nil)
1475 lc_gethogfort:= 1
1476 end;
1477
lc_ishogalivenull1478 function lc_ishogalive(L : Plua_State) : LongInt; Cdecl;
1479 var gear : PGear;
1480 begin
1481 if CheckLuaParamCount(L, 1, 'IsHogAlive', 'gearUid') then
1482 begin
1483 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1484 if gear <> nil then
1485 if gear^.Kind = gtHedgehog then
1486 if (gear^.Health > 0) and (gear^.Health > gear^.Damage) and ((gear^.State and (gstDrowning or gstHHDeath)) = 0) and ((gear^.Message and gmDestroy) = 0) then
1487 lua_pushboolean(L, true)
1488 else
1489 lua_pushboolean(L, false)
1490 else
1491 lua_pushboolean(L, false)
1492 else
1493 lua_pushboolean(L, false);
1494 end
1495 else
1496 lua_pushnil(L); // return value on stack (nil)
1497 lc_ishogalive:= 1
1498 end;
1499
lc_ishoglocalnull1500 function lc_ishoglocal(L : Plua_State) : LongInt; Cdecl;
1501 var gear : PGear;
1502 begin
1503 if CheckLuaParamCount(L, 1, 'IsHogLocal', 'gearUid') then
1504 begin
1505 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1506 // TODO error messages
1507 if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
1508 lua_pushboolean(L, IsHogLocal(gear^.Hedgehog))
1509 else
1510 lua_pushnil(L);
1511 end
1512 else
1513 lua_pushnil(L); // return value on stack (nil)
1514 lc_ishoglocal:= 1
1515 end;
1516
lc_gethogteamnamenull1517 function lc_gethogteamname(L : Plua_State) : LongInt; Cdecl;
1518 var gear : PGear;
1519 begin
1520 if CheckLuaParamCount(L, 1, 'GetHogTeamName', 'gearUid') then
1521 begin
1522 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1523 // TODO error messages
1524 if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
1525 lua_pushstring(L, str2pchar(gear^.Hedgehog^.Team^.TeamName))
1526 else
1527 lua_pushnil(L);
1528 end
1529 else
1530 lua_pushnil(L); // return value on stack (nil)
1531 lc_gethogteamname:= 1
1532 end;
1533
lc_sethogteamnamenull1534 function lc_sethogteamname(L : Plua_State) : LongInt; Cdecl;
1535 var gear : PGear;
1536 begin
1537 if CheckLuaParamCount(L, 2, 'SetHogTeamName', 'gearUid, name') then
1538 begin
1539 gear := GearByUID(Trunc(lua_tonumber(L, 1)));
1540 if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
1541 begin
1542 gear^.Hedgehog^.Team^.TeamName := lua_tostring(L, 2);
1543
1544 FreeAndNilTexture(gear^.Hedgehog^.Team^.NameTagTex);
1545 gear^.Hedgehog^.Team^.NameTagTex:= RenderStringTex(ansistring(gear^.Hedgehog^.Team^.TeamName), gear^.Hedgehog^.Team^.Clan^.Color, fnt16);
1546 end
1547 else
1548 lua_pushnil(L);
1549 end
1550 else
1551 lua_pushnil(L); // return value on stack (nil)
1552 lc_sethogteamname:= 1
1553 end;
1554
lc_gethognamenull1555 function lc_gethogname(L : Plua_State) : LongInt; Cdecl;
1556 var gear : PGear;
1557 begin
1558 if CheckLuaParamCount(L, 1, 'GetHogName', 'gearUid') then
1559 begin
1560 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1561 if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
1562 begin
1563 lua_pushstring(L, str2pchar(gear^.Hedgehog^.Name))
1564 end
1565 else
1566 lua_pushnil(L);
1567 end
1568 else
1569 lua_pushnil(L); // return value on stack (nil)
1570 lc_gethogname:= 1
1571 end;
1572
lc_sethognamenull1573 function lc_sethogname(L : Plua_State) : LongInt; Cdecl;
1574 var gear : PGear;
1575 begin
1576 if CheckLuaParamCount(L, 2, 'SetHogName', 'gearUid, name') then
1577 begin
1578 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1579 if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
1580 begin
1581 gear^.Hedgehog^.Name:= lua_tostring(L, 2);
1582
1583 FreeAndNilTexture(gear^.Hedgehog^.NameTagTex);
1584 gear^.Hedgehog^.NameTagTex:= RenderStringTex(ansistring(gear^.Hedgehog^.Name), gear^.Hedgehog^.Team^.Clan^.Color, fnt16)
1585 end
1586 end;
1587 lc_sethogname:= 0;
1588 end;
1589
lc_gettimernull1590 function lc_gettimer(L : Plua_State) : LongInt; Cdecl;
1591 var gear : PGear;
1592 begin
1593 if CheckLuaParamCount(L, 1, 'GetTimer', 'gearUid') then
1594 begin
1595 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1596 if gear <> nil then
1597 lua_pushnumber(L, gear^.Timer)
1598 else
1599 lua_pushnil(L);
1600 end
1601 else
1602 lua_pushnil(L); // return value on stack (nil)
1603 lc_gettimer:= 1
1604 end;
1605
lc_getflighttimenull1606 function lc_getflighttime(L : Plua_State) : LongInt; Cdecl;
1607 var gear : PGear;
1608 begin
1609 if CheckLuaParamCount(L, 1, 'GetFlightTime', 'gearUid') then
1610 begin
1611 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1612 if gear <> nil then
1613 lua_pushnumber(L, gear^.FlightTime)
1614 else
1615 lua_pushnil(L);
1616 end
1617 else
1618 lua_pushnil(L); // return value on stack (nil)
1619 lc_getflighttime:= 1
1620 end;
1621
lc_gethealthnull1622 function lc_gethealth(L : Plua_State) : LongInt; Cdecl;
1623 var gear : PGear;
1624 begin
1625 if CheckLuaParamCount(L, 1, 'GetHealth', 'gearUid') then
1626 begin
1627 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1628 if gear <> nil then
1629 lua_pushnumber(L, gear^.Health)
1630 else
1631 lua_pushnil(L);
1632 end
1633 else
1634 lua_pushnil(L); // return value on stack (nil)
1635 lc_gethealth:= 1
1636 end;
1637
lc_getxnull1638 function lc_getx(L : Plua_State) : LongInt; Cdecl;
1639 var gear : PGear;
1640 begin
1641 if CheckLuaParamCount(L, 1, 'GetX', 'gearUid') then
1642 begin
1643 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1644 if gear <> nil then
1645 lua_pushnumber(L, hwRound(gear^.X))
1646 else
1647 lua_pushnil(L);
1648 end
1649 else
1650 lua_pushnil(L); // return value on stack (nil)
1651 lc_getx:= 1
1652 end;
1653
lc_getynull1654 function lc_gety(L : Plua_State) : LongInt; Cdecl;
1655 var gear : PGear;
1656 begin
1657 if CheckLuaParamCount(L, 1, 'GetY', 'gearUid') then
1658 begin
1659 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1660 if gear <> nil then
1661 lua_pushnumber(L, hwRound(gear^.Y))
1662 else
1663 lua_pushnil(L);
1664 end
1665 else
1666 lua_pushnil(L); // return value on stack (nil)
1667 lc_gety:= 1
1668 end;
1669
lc_copypvnull1670 function lc_copypv(L : Plua_State) : LongInt; Cdecl;
1671 var gears, geard : PGear;
1672 begin
1673 if CheckLuaParamCount(L, 2, 'CopyPV', 'fromGearUid, toGearUid') then
1674 begin
1675 gears:= GearByUID(Trunc(lua_tonumber(L, 1)));
1676 geard:= GearByUID(Trunc(lua_tonumber(L, 2)));
1677 if (gears <> nil) and (geard <> nil) then
1678 begin
1679 geard^.X:= gears^.X;
1680 geard^.Y:= gears^.Y;
1681 geard^.dX:= gears^.dX;
1682 geard^.dY:= gears^.dY;
1683 end
1684 end;
1685 lc_copypv:= 0
1686 end;
1687
lc_followgearnull1688 function lc_followgear(L : Plua_State) : LongInt; Cdecl;
1689 var gear : PGear;
1690 begin
1691 if CheckLuaParamCount(L, 1, 'FollowGear', 'gearUid') then
1692 begin
1693 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1694 if gear <> nil then FollowGear:= gear
1695 end;
1696 lc_followgear:= 0
1697 end;
1698
lc_hogsaynull1699 function lc_hogsay(L : Plua_State) : LongInt; Cdecl;
1700 var gear : PGear;
1701 vgear : PVisualGear;
1702 s : LongWord;
1703 n : LongInt;
1704 begin
1705 if CheckAndFetchParamCount(L, 3, 4, 'HogSay', 'gearUid, text, manner [, vgState]', n) then
1706 begin
1707 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1708 if gear <> nil then
1709 begin
1710 // state defaults to 0 if state param is given
1711 if n = 4 then
1712 s:= Trunc(lua_tonumber(L, 4))
1713 else
1714 s:= 0;
1715 vgear:= AddVisualGear(0, 0, vgtSpeechBubble, s, true);
1716 if vgear <> nil then
1717 begin
1718 vgear^.Text:= lua_tostring(L, 2);
1719 if Gear^.Kind = gtHedgehog then
1720 begin
1721 AddChatString(#9+Format(shortstring(trmsg[sidChatHog]), gear^.Hedgehog^.Name, vgear^.text));
1722 vgear^.Hedgehog:= gear^.Hedgehog
1723 end
1724 else vgear^.Frame:= gear^.uid;
1725
1726 vgear^.FrameTicks:= Trunc(lua_tonumber(L, 3));
1727 if (vgear^.FrameTicks < 1) or (vgear^.FrameTicks > 3) then
1728 vgear^.FrameTicks:= 1;
1729 lua_pushnumber(L, vgear^.Uid);
1730 end
1731 end
1732 else
1733 lua_pushnil(L)
1734 end
1735 else
1736 lua_pushnil(L);
1737 lc_hogsay:= 1
1738 end;
1739
lc_switchhognull1740 function lc_switchhog(L : Plua_State) : LongInt; Cdecl;
1741 var gear, prevgear : PGear;
1742 begin
1743 if CheckLuaParamCount(L, 1, 'SwitchHog', 'gearUid') then
1744 begin
1745 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1746 // should we allow this when there is no current hedgehog? might do some odd(er) things to turn sequence.
1747 if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) and (CurrentHedgehog <> nil) then
1748 begin
1749 CurrentHedgehog^.MultiShootAttacks:= 0;
1750 prevgear := CurrentHedgehog^.Gear;
1751 if prevgear <> nil then
1752 begin
1753 prevgear^.Active := false;
1754 prevgear^.State:= prevgear^.State and (not gstHHDriven);
1755 prevgear^.Z := cHHZ;
1756 prevgear^.Message:= prevgear^.Message or gmRemoveFromList or gmAddToList;
1757 end;
1758
1759 SwitchCurrentHedgehog(gear^.Hedgehog);
1760 AmmoMenuInvalidated:= true;
1761 CurrentTeam:= CurrentHedgehog^.Team;
1762
1763 repeat
1764 CurrentTeam^.CurrHedgehog := (CurrentTeam^.CurrHedgehog + 1) mod CurrentTeam^.HedgehogsNumber
1765 until
1766 CurrentTeam^.Hedgehogs[CurrentTeam^.CurrHedgehog].Gear = CurrentHedgehog^.Gear;
1767
1768 gear^.State:= gear^.State or gstHHDriven;
1769 gear^.Active := true;
1770 gear^.Z := cCurrHHZ;
1771 gear^.Message:= gear^.Message or gmRemoveFromList or gmAddToList;
1772 end
1773 end;
1774 lc_switchhog:= 0
1775 end;
1776
lc_enableswitchhognull1777 function lc_enableswitchhog(L : Plua_State) : LongInt; Cdecl;
1778 var gear, iterator: PGear;
1779 alreadySwitching: boolean;
1780 begin
1781 if CheckLuaParamCount(L, 0, 'EnableSwitchHog', '') then
1782 if ((CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil)) then
1783 begin
1784 alreadySwitching:= false;
1785 iterator:= GearsList;
1786 // Check if there's already a switcher gear
1787 while (iterator <> nil) do
1788 begin
1789 if (iterator^.Kind = gtSwitcher) then
1790 begin
1791 alreadySwitching:= true;
1792 lua_pushnumber(L, iterator^.Uid);
1793 break;
1794 end;
1795 iterator:= iterator^.NextGear;
1796 end;
1797 if (not alreadySwitching) then
1798 begin
1799 // Enable switching and return gear UID
1800 gear:= AddGear(hwRound(CurrentHedgehog^.Gear^.X), hwRound(CurrentHedgehog^.Gear^.Y), gtSwitcher, 0, _0, _0, 0);
1801 CurAmmoGear:= gear;
1802 lastGearByUID:= gear;
1803 bShowFinger:= false;
1804 lua_pushnumber(L, gear^.Uid);
1805 end;
1806 end
1807 // Return nil on failure
1808 else
1809 lua_pushnil(L)
1810 else
1811 lua_pushnil(L);
1812 lc_enableswitchhog:= 1;
1813 end;
1814
1815 function lc_addammo(L : Plua_State) : LongInt; Cdecl;
1816 var gear : PGear;
1817 at, n, c: LongInt;
1818 const
1819 call = 'AddAmmo';
1820 params = 'gearUid, ammoType [, ammoCount]';
1821 begin
1822 if CheckAndFetchParamCount(L, 2, 3, call, params, n) then
1823 begin
1824 at:= LuaToAmmoTypeOrd(L, 2, call, params);
1825 if (at >= 0) and (TAmmoType(at) <> amNothing) then
1826 begin
1827 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1828 if (gear <> nil) and (gear^.Hedgehog <> nil) then
1829 if n = 2 then
1830 AddAmmo(gear^.Hedgehog^, TAmmoType(at))
1831 else
1832 begin
1833 c:= Trunc(lua_tonumber(L, 3));
1834 if (c = 0) and (CurrentHedgehog = gear^.Hedgehog) and (gear^.Hedgehog^.CurAmmoType = TAmmoType(at)) then
1835 ParseCommand('setweap ' + char(0), true, true);
1836 SetAmmo(gear^.Hedgehog^, TAmmoType(at), c);
1837 end;
1838 end;
1839 end;
1840 lc_addammo:= 0
1841 end;
1842
1843 function lc_getammocount(L : Plua_State) : LongInt; Cdecl;
1844 var gear : PGear;
1845 ammo : PAmmo;
1846 at : LongInt;
1847 const
1848 call = 'GetAmmoCount';
1849 params = 'gearUid, ammoType';
1850 begin
1851 if CheckLuaParamCount(L, 2, call, params) then
1852 begin
1853 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1854 if (gear <> nil) and (gear^.Hedgehog <> nil) then
1855 begin
1856 at:= LuaToAmmoTypeOrd(L, 2, call, params);
1857 if at >= 0 then
1858 begin
1859 ammo:= GetAmmoEntry(gear^.Hedgehog^, TAmmoType(at));
1860 if ammo^.AmmoType = amNothing then
1861 lua_pushnumber(L, 0)
1862 else
1863 lua_pushnumber(L, ammo^.Count);
1864 end;
1865 end
1866 else lua_pushnumber(L, 0);
1867 end
1868 else
1869 lua_pushnil(L);
1870 lc_getammocount:= 1
1871 end;
1872
1873 function lc_sethealth(L : Plua_State) : LongInt; Cdecl;
1874 var gear : PGear;
1875 begin
1876 if CheckLuaParamCount(L, 2, 'SetHealth', 'gearUid, health') then
1877 begin
1878 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1879 if gear <> nil then
1880 begin
1881 gear^.Health:= Trunc(lua_tonumber(L, 2));
1882
1883 if (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
1884 begin
1885 if gear^.Health > cMaxHogHealth then
1886 gear^.Health:= cMaxHogHealth;
1887 if gear^.Health < 0 then
1888 gear^.Health:= 0;
1889 RenderHealth(gear^.Hedgehog^);
1890 RecountTeamHealth(gear^.Hedgehog^.Team)
1891 end
1892 else if (gear^.RenderHealth) and (gear^.Tex <> nil) then
1893 FreeAndNilTexture(gear^.Tex);
1894 Gear^.Active:= true;
1895 AllInactive:= false
1896 end
1897 end;
1898 lc_sethealth:= 0
1899 end;
1900
1901 function lc_healhog(L : Plua_State) : LongInt; Cdecl;
1902 var gear : PGear;
1903 healthBoost, n: LongInt;
1904 begin
1905 if CheckAndFetchParamCountRange(L, 2, 4, 'HealHog', 'gearUid, healthBoost [, showMessage [, tint]]', n) then
1906 begin
1907 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1908 healthBoost:= Trunc(lua_tonumber(L, 2));
1909 if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) and (healthBoost >= 1) then
1910 begin
1911 healthBoost:= IncHogHealth(gear^.Hedgehog, healthBoost);
1912 RenderHealth(gear^.Hedgehog^);
1913 RecountTeamHealth(gear^.Hedgehog^.Team);
1914 if n = 4 then
1915 HHHeal(gear^.Hedgehog, healthBoost, lua_toboolean(L, 3), Trunc(lua_tonumber(L, 4)))
1916 else if n = 3 then
1917 HHHeal(gear^.Hedgehog, healthBoost, lua_toboolean(L, 3))
1918 else if n = 2 then
1919 HHHeal(gear^.Hedgehog, healthBoost, true);
1920 Gear^.Active:= true;
1921 AllInactive:= false
1922 end
1923 end;
1924 lc_healhog:= 0
1925 end;
1926
1927 function lc_settimer(L : Plua_State) : LongInt; Cdecl;
1928 var gear : PGear;
1929 begin
1930 if CheckLuaParamCount(L, 2, 'SetTimer', 'gearUid, timer') then
1931 begin
1932 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1933 if gear <> nil then
1934 begin
1935 gear^.Timer:= Trunc(lua_tonumber(L, 2));
1936 if gear^.RenderTimer and (gear^.Tex <> nil) then
1937 FreeAndNilTexture(gear^.Tex);
1938 end;
1939 end;
1940 lc_settimer:= 0
1941 end;
1942
1943 function lc_setflighttime(L : Plua_State) : LongInt; Cdecl;
1944 var gear : PGear;
1945 begin
1946 if CheckLuaParamCount(L, 2, 'SetFlightTime', 'gearUid, flighttime') then
1947 begin
1948 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1949 if gear <> nil then gear^.FlightTime:= Trunc(lua_tonumber(L, 2))
1950 end;
1951 lc_setflighttime:= 0
1952 end;
1953
1954 function lc_seteffect(L : Plua_State) : LongInt; Cdecl;
1955 var gear: PGear;
1956 t : LongInt;
1957 const
1958 call = 'SetEffect';
1959 params = 'gearUid, effect, effectState';
1960 begin
1961 if CheckLuaParamCount(L, 3, call, params) then
1962 begin
1963 t:= LuaToHogEffectOrd(L, 2, call, params);
1964 if t >= 0 then
1965 begin
1966 gear := GearByUID(Trunc(lua_tonumber(L, 1)));
1967 if (gear <> nil) and (gear^.Hedgehog <> nil) then
1968 gear^.Hedgehog^.Effects[THogEffect(t)]:= Trunc(lua_tonumber(L, 3));
1969 end;
1970 end;
1971 lc_seteffect := 0;
1972 end;
1973
1974 function lc_geteffect(L : Plua_State) : LongInt; Cdecl;
1975 var gear : PGear;
1976 t : LongInt;
1977 const
1978 call = 'GetEffect';
1979 params = 'gearUid, effect';
1980 begin
1981 if CheckLuaParamCount(L, 2, call, params) then
1982 begin
1983 t:= LuaToHogEffectOrd(L, 2, call, params);
1984 if t >= 0 then
1985 begin
1986 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
1987 if (gear <> nil) and (gear^.Hedgehog <> nil) then
1988 lua_pushnumber(L, gear^.Hedgehog^.Effects[THogEffect(t)])
1989 else
1990 lua_pushnumber(L, 0)
1991 end;
1992 end
1993 else
1994 lua_pushnumber(L, 0);
1995 lc_geteffect:= 1
1996 end;
1997
1998 function lc_setstate(L : Plua_State) : LongInt; Cdecl;
1999 var gear : PGear;
2000 begin
2001 if CheckLuaParamCount(L, 2, 'SetState', 'gearUid, state') then
2002 begin
2003 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
2004 if gear <> nil then
2005 begin
2006 gear^.State:= Trunc(lua_tonumber(L, 2));
2007 SetAllToActive;
2008 end
2009 end;
2010 lc_setstate:= 0
2011 end;
2012
2013 function lc_getstate(L : Plua_State) : LongInt; Cdecl;
2014 var gear : PGear;
2015 begin
2016 if CheckLuaParamCount(L, 1, 'GetState', 'gearUid') then
2017 begin
2018 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
2019 if gear <> nil then
2020 lua_pushnumber(L, gear^.State)
2021 else
2022 lua_pushnil(L)
2023 end
2024 else
2025 lua_pushnil(L); // return value on stack (nil)
2026 lc_getstate:= 1
2027 end;
2028
2029 function lc_gettag(L : Plua_State) : LongInt; Cdecl;
2030 var gear : PGear;
2031 begin
2032 if CheckLuaParamCount(L, 1, 'GetTag', 'gearUid') then
2033 begin
2034 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
2035 if gear <> nil then
2036 lua_pushnumber(L, gear^.Tag)
2037 else
2038 lua_pushnil(L);
2039 end
2040 else
2041 lua_pushnil(L); // return value on stack (nil)
2042 lc_gettag:= 1
2043 end;
2044
2045 function lc_settag(L : Plua_State) : LongInt; Cdecl;
2046 var gear : PGear;
2047 begin
2048 if CheckLuaParamCount(L, 2, 'SetTag', 'gearUid, tag') then
2049 begin
2050 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
2051 if gear <> nil then
2052 begin
2053 gear^.Tag:= Trunc(lua_tonumber(L, 2));
2054 SetAllToActive;
2055 end
2056 end;
2057 lc_settag:= 0
2058 end;
2059
2060 function lc_endgame(L : Plua_State) : LongInt; Cdecl;
2061 begin
2062 L:= L; // avoid compiler hint
2063 GameOver:= true;
2064 AddGear(0, 0, gtATFinishGame, 0, _0, _0, 3000);
2065 lc_endgame:= 0
2066 end;
2067
2068 function lc_endturn(L : Plua_State) : LongInt; Cdecl;
2069 var n: LongInt;
2070 const
2071 call = 'EndTurn';
2072 params = '[noTaunts]';
2073 begin
2074 if CheckAndFetchParamCount(L, 0, 1, call, params, n) then
2075 if n >= 1 then
2076 LuaNoEndTurnTaunts:= lua_toboolean(L, 1);
2077 LuaEndTurnRequested:= true;
2078 lc_endturn:= 0
2079 end;
2080
2081 function lc_retreat(L : Plua_State) : LongInt; Cdecl;
2082 var n, time: LongInt;
2083 respectFactor: Boolean;
2084 const
2085 call = 'Retreat';
2086 params = 'time [, respectGetAwayTimeFactor]';
2087 begin
2088 if CheckAndFetchParamCount(L, 1, 2, call, params, n) then
2089 begin
2090 IsGetAwayTime:= true;
2091 AttackBar:= 0;
2092 time:= Trunc(lua_tonumber(L, 1));
2093 if n = 2 then
2094 respectFactor:= lua_toboolean(L, 2)
2095 else
2096 respectFactor:= True;
2097 if respectFactor then
2098 PendingTurnTimeLeft:= (time * cGetAwayTime) div 100
2099 else
2100 PendingTurnTimeLeft:= time;
2101 isPendingTurnTimeLeft:= true;
2102 if ((CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil)) then
2103 begin
2104 CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State or gstAttacked;
2105 CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State and (not gstAttacking);
2106 end;
2107 end;
2108 lc_retreat:= 0
2109 end;
2110
2111 function lc_skipturn(L : Plua_State): LongInt; Cdecl;
2112 begin
2113 L:= L; // avoid compiler hint
2114 ParseCommand('skip', true, true);
2115 lc_skipturn:= 0;
2116 end;
2117
2118 function lc_sendstat(L : Plua_State) : LongInt; Cdecl;
2119 var statInfo : TStatInfoType;
2120 i, n : LongInt;
2121 color, tn: shortstring;
2122 needsTn : boolean;
2123 const
2124 call = 'SendStat';
2125 params = 'statInfoType, color [, teamname]';
2126 begin
2127 if CheckAndFetchParamCount(L, 2, 3, call, params, n) then
2128 begin
2129 i:= LuaToStatInfoTypeOrd(L, 1, call, params);
2130 if i >= 0 then
2131 begin
2132 statInfo:= TStatInfoType(i);
2133 needsTn:= ((statInfo = siPlayerKills) or (statInfo = siClanHealth));
2134 // check if param count is correct for the used statInfo
2135 if (n = 3) <> needsTn then
2136 begin
2137 if n = 3 then
2138 LuaCallError(EnumToStr(statInfo) + ' does not support the teamname parameter', call, params)
2139 else
2140 LuaCallError(EnumToStr(statInfo) + ' requires the teamname parameter', call, params);
2141 end
2142 else // count is correct!
2143 begin
2144 if needsTn then
2145 begin
2146 // 3: team name
2147 for i:= 0 to Pred(TeamsCount) do
2148 begin
2149 color:= _S'0';
2150 tn:= lua_tostring(L, 3);
2151 with TeamsArray[i]^ do
2152 begin
2153 if TeamName = tn then
2154 begin
2155 color := uUtils.IntToStr(Clan^.Color);
2156 Break;
2157 end
2158 end
2159 end;
2160 if (statInfo = siPlayerKills) then
2161 begin
2162 SendStat(siPlayerKills, color + ' ' +
2163 lua_tostring(L, 2) + ' ' + tn);
2164 end
2165 else if (statInfo = siClanHealth) then
2166 begin
2167 SendStat(siClanHealth, color + ' ' +
2168 lua_tostring(L, 2));
2169 end
2170 end
2171 else
2172 begin
2173 SendStat(statInfo,lua_tostring(L, 2));
2174 end;
2175 end;
2176 end;
2177 end;
2178 lc_sendstat:= 0
2179 end;
2180
2181 function lc_sendgameresultoff(L : Plua_State) : LongInt; Cdecl;
2182 begin
2183 L:= L; // avoid compiler hint
2184 uStats.SendGameResultOn := false;
2185 lc_sendgameresultoff:= 0
2186 end;
2187
2188 function lc_sendrankingstatsoff(L : Plua_State) : LongInt; Cdecl;
2189 begin
2190 L:= L; // avoid compiler hint
2191 uStats.SendRankingStatsOn := false;
2192 lc_sendrankingstatsoff:= 0
2193 end;
2194
2195 function lc_sendachievementsstatsoff(L : Plua_State) : LongInt; Cdecl;
2196 begin
2197 L:= L; // avoid compiler hint
2198 uStats.SendAchievementsStatsOn := false;
2199 lc_sendachievementsstatsoff:= 0
2200 end;
2201
2202 function lc_sendhealthstatsoff(L : Plua_State) : LongInt; Cdecl;
2203 begin
2204 L:= L; // avoid compiler hint
2205 uStats.SendHealthStatsOn := false;
2206 lc_sendhealthstatsoff:= 0
2207 end;
2208
2209 function lc_findplace(L : Plua_State) : LongInt; Cdecl;
2210 var gear: PGear;
2211 fall: boolean;
2212 tryhard: boolean;
2213 left, right, n: LongInt;
2214 begin
2215 if CheckAndFetchParamCount(L, 4, 5, 'FindPlace', 'gearUid, fall, left, right [, tryHarder]', n) then
2216 begin
2217 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
2218 fall:= lua_toboolean(L, 2);
2219 left:= Trunc(lua_tonumber(L, 3));
2220 right:= Trunc(lua_tonumber(L, 4));
2221 if n = 5 then
2222 tryhard:= lua_toboolean(L, 5)
2223 else
2224 tryhard:= false;
2225 if gear <> nil then
2226 FindPlace(gear, fall, left, right, tryhard);
2227 if gear <> nil then
2228 lua_pushnumber(L, gear^.uid)
2229 else
2230 lua_pushnil(L);
2231 end
2232 else
2233 lua_pushnil(L); // return value on stack (nil)
2234 lc_findplace:= 1
2235 end;
2236
2237 function lc_playsound(L : Plua_State) : LongInt; Cdecl;
2238 var gear: PGear;
2239 n, s: LongInt;
2240 instaVoice: boolean;
2241 const
2242 call = 'PlaySound';
2243 params = 'soundId [, hhGearUid [, instaVoice]]';
2244 begin
2245 if CheckAndFetchParamCountRange(L, 1, 3, call, params, n) then
2246 begin
2247 s:= LuaToSoundOrd(L, 1, call, params);
2248 if s >= 0 then
2249 begin
2250 // no gear specified
2251 if n = 1 then
2252 PlaySound(TSound(s), false, true)
2253 else
2254 begin
2255 gear:= GearByUID(Trunc(lua_tonumber(L, 2)));
2256 if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
2257 begin
2258 instaVoice:= false;
2259 if n = 3 then
2260 instaVoice:= lua_toboolean(L, 3);
2261 if instaVoice then
2262 PlaySoundV(TSound(s), gear^.Hedgehog^.Team^.Voicepack, false, true)
2263 else
2264 AddVoice(TSound(s), gear^.Hedgehog^.Team^.Voicepack, true, false);
2265 end;
2266 end;
2267 end;
2268 end;
2269 lc_playsound:= 0;
2270 end;
2271
2272 function lc_playmusicsound(L : Plua_State) : LongInt; Cdecl;
2273 var s: LongInt;
2274 const
2275 call = 'PlayMusicSound';
2276 params = 'soundId';
2277 begin
2278 if CheckLuaParamCount(L, 1, call, params) then
2279 begin
2280 s:= LuaToSoundOrd(L, 1, call, params);
2281 if s >= 0 then
2282 PlayMusicSound(TSound(s))
2283 end;
2284 lc_playmusicsound:= 0;
2285 end;
2286
2287 function lc_stopmusicsound(L : Plua_State) : LongInt; Cdecl;
2288 var s: LongInt;
2289 const
2290 call = 'StopMusicSound';
2291 params = 'soundId';
2292 begin
2293 if CheckLuaParamCount(L, 1, call, params) then
2294 begin
2295 s:= LuaToSoundOrd(L, 1, call, params);
2296 if s >= 0 then
2297 StopMusicSound(TSound(s))
2298 end;
2299 lc_stopmusicsound:= 0;
2300 end;
2301
2302
2303 function lc_setsoundmask(L : Plua_State) : LongInt; Cdecl;
2304 var s: LongInt;
2305 soundState: boolean;
2306 const
2307 call = 'SetSoundMask';
2308 params = 'soundId, isMasked';
2309 begin
2310 if CheckLuaParamCount(L, 2, call, params) then
2311 begin
2312 s:= LuaToSoundOrd(L, 1, call, params);
2313 if s <> Ord(sndNone) then
2314 begin
2315 soundState:= lua_toboolean(L, 2);
2316 MaskedSounds[TSound(s)]:= soundState;
2317 end;
2318 end;
2319 lc_setsoundmask:= 0;
2320 end;
2321
2322 function lc_addteam(L : Plua_State) : LongInt; Cdecl;
2323 var np: LongInt;
2324 colorArg: Int64;
2325 colorStr: shortstring;
2326 begin
2327 if CheckAndFetchParamCount(L, 5, 6, 'AddTeam', 'teamname, color, grave, fort, voicepack [, flag]', np) then
2328 begin
2329 colorArg:= Trunc(lua_tonumber(L, 2));
2330 if (colorArg < 0) and (abs(colorArg) <= cClanColors) then
2331 // Pick clan color from settings (recommended)
2332 colorStr:= IntToStr(ClanColorArray[Pred(abs(colorArg))])
2333 else if (colorArg >= 0) and (colorArg <= $ffffffff) then
2334 // Specify color directly
2335 colorStr:= IntToStr(colorArg)
2336 else
2337 begin
2338 OutError('Lua error: AddTeam: Invalid ''color'' argument, must be between '+IntToStr(-cClanColors)+' and 0xffffffff!', true);
2339 lua_pushnil(L);
2340 lua_pushnil(L);
2341 lc_addteam:= 2;
2342 exit;
2343 end;
2344 ParseCommand('addteam x ' + colorStr + ' ' + lua_tostring(L, 1), true, true);
2345 ParseCommand('grave ' + lua_tostring(L, 3), true, true);
2346 ParseCommand('fort ' + lua_tostring(L, 4), true, true);
2347 ParseCommand('voicepack ' + lua_tostring(L, 5), true, true);
2348 if (np = 6) then ParseCommand('flag ' + lua_tostring(L, 6), true, true);
2349 // If there's a mission team, copy it's control scheme.
2350 // So in singleplayer missions, all teams use the player team's controls.
2351 if MissionTeam <> nil then
2352 CurrentTeam^.Binds:= MissionTeam^.Binds
2353 // Default keys otherwise
2354 else
2355 CurrentTeam^.Binds:= DefaultBinds;
2356 // push team name and index
2357 lua_pushstring(L, str2pchar(CurrentTeam^.TeamName));
2358 lua_pushnumber(L, TeamsCount - 1);
2359 end
2360 else
2361 begin
2362 lua_pushnil(L);
2363 lua_pushnil(L);
2364 end;
2365 lc_addteam:= 2;
2366 end;
2367
lc_addmissionteamnull2368 function lc_addmissionteam(L : Plua_State) : LongInt; Cdecl;
2369 var colorArg: Int64;
2370 colorStr: shortstring;
2371 begin
2372 if CheckLuaParamCount(L, 1, 'AddMissionTeam', 'color') then
2373 begin
2374 if(MissionTeam = nil) then
2375 begin
2376 OutError('Lua error: AddMissionTeam: Could not add team. Note: This function only works in singleplayer missions!', true);
2377 lc_addmissionteam:= 0;
2378 exit;
2379 end;
2380
2381 colorArg:= Trunc(lua_tonumber(L, 1));
2382 if (colorArg < 0) and (abs(colorArg) <= cClanColors) then
2383 // Pick clan color from settings (recommended)
2384 colorStr:= IntToStr(ClanColorArray[Pred(abs(colorArg))])
2385 else if (colorArg >= 0) and (colorArg <= $ffffffff) then
2386 // Specify color directly
2387 colorStr:= IntToStr(colorArg)
2388 else
2389 begin
2390 OutError('Lua error: AddMissionTeam: Invalid ''color'' argument, must be between '+IntToStr(-cClanColors)+' and 0xffffffff!', true);
2391 lua_pushnil(L);
2392 lua_pushnil(L);
2393 lc_addmissionteam:= 2;
2394 exit;
2395 end;
2396
2397 ParseCommand('addteam x ' + colorStr + ' ' + MissionTeam^.TeamName, true, true);
2398 ParseCommand('grave ' + MissionTeam^.GraveName, true, true);
2399 ParseCommand('fort ' + MissionTeam^.FortName, true, true);
2400 ParseCommand('voicepack ' + MissionTeam^.Voicepack^.name, true, true);
2401 ParseCommand('flag ' + MissionTeam^.Flag, true, true);
2402 CurrentTeam^.Binds:= MissionTeam^.Binds;
2403 // push real team name and team index
2404 lua_pushstring(L, str2pchar(CurrentTeam^.TeamName));
2405 lua_pushnumber(L, TeamsCount - 1);
2406 end
2407 else
2408 begin
2409 lua_pushnil(L);
2410 lua_pushnil(L);
2411 end;
2412 lc_addmissionteam:= 2;
2413 end;
2414
lc_setteamlabelnull2415 function lc_setteamlabel(L : Plua_State) : LongInt; Cdecl;
2416 var teamValue: ansistring;
2417 i, n: LongInt;
2418 success: boolean;
2419 begin
2420 success:= false;
2421 if CheckAndFetchParamCount(L, 1, 2, 'SetTeamLabel', 'teamname[, label]', n) then
2422 begin
2423 success:= false;
2424 // fetch team
2425 if TeamsCount > 0 then
2426 for i:= 0 to Pred(TeamsCount) do
2427 begin
2428 // skip teams that don't have matching name
2429 if TeamsArray[i]^.TeamName <> lua_tostring(L, 1) then
2430 continue;
2431
2432 // value of type nil? Then let's clear the team value
2433 if (n < 2) or lua_isnil(L, 2) then
2434 begin
2435 FreeAndNilTexture(TeamsArray[i]^.LuaTeamValueTex);
2436 TeamsArray[i]^.hasLuaTeamValue:= false;
2437 success:= true;
2438 end
2439 // value of type string? Then let's set the team value
2440 else if (lua_isstring(L, 2)) then
2441 begin
2442 teamValue:= lua_tostring(L, 2);
2443 TeamsArray[i]^.LuaTeamValue:= teamValue;
2444 FreeAndNilTexture(TeamsArray[i]^.LuaTeamValueTex);
2445 TeamsArray[i]^.LuaTeamValueTex := RenderStringTex(teamValue, TeamsArray[i]^.Clan^.Color, fnt16);
2446 TeamsArray[i]^.hasLuaTeamValue:= true;
2447 success:= true;
2448 end;
2449 // don't change more than one team
2450 break;
2451 end;
2452 end;
2453 // return true if operation was successful, false otherwise
2454 lua_pushboolean(L, success);
2455 lc_setteamlabel:= 1;
2456 end;
2457
lc_setteampassivenull2458 function lc_setteampassive(L : Plua_State) : LongInt; Cdecl;
2459 var i, j: LongInt;
2460 success, passive, passiveClan: boolean;
2461 begin
2462 success:= false;
2463 if CheckLuaParamCount(L, 2, 'SetTeamPassive', 'teamname, isPassive') then
2464 begin
2465 success:= false;
2466 // fetch team
2467 if TeamsCount > 0 then
2468 for i:= 0 to Pred(TeamsCount) do
2469 if TeamsArray[i]^.TeamName = lua_tostring(L, 1) then
2470 begin
2471 passive:= lua_toboolean(L, 2);
2472 TeamsArray[i]^.Passive:= passive;
2473 // also update clan state
2474 if passive then
2475 begin
2476 passiveClan:= true;
2477 for j:= 0 to Pred(TeamsCount) do
2478 if (not TeamsArray[j]^.Passive) then
2479 begin
2480 passiveClan:= false;
2481 break;
2482 end;
2483 end
2484 else
2485 passiveClan:= false;
2486 TeamsArray[i]^.Clan^.Passive:= passiveClan;
2487
2488 success:= true;
2489 // don't change more than one team
2490 break;
2491 end;
2492 end;
2493 // return true if operation was successful, false otherwise
2494 lua_pushboolean(L, success);
2495 lc_setteampassive:= 1;
2496 end;
2497
2498 function lc_getteamname(L : Plua_State) : LongInt; Cdecl;
2499 var t: LongInt;
2500 begin
2501 if CheckLuaParamCount(L, 1, 'GetTeamName', 'teamIdx') then
2502 begin
2503 t:= Trunc(lua_tonumber(L, 1));
2504 if (t < 0) or (t >= TeamsCount) then
2505 lua_pushnil(L)
2506 else
2507 lua_pushstring(L, str2pchar(TeamsArray[t]^.TeamName));
2508 end
2509 else
2510 lua_pushnil(L);
2511 lc_getteamname:= 1;
2512 end;
2513
2514 function lc_getteamindex(L : Plua_state) : LongInt; Cdecl;
2515 var i: LongInt;
2516 found: boolean;
2517 begin
2518 found:= false;
2519 if CheckLuaParamCount(L, 1, 'GetTeamIndex', 'teamname') then
2520 if TeamsCount > 0 then
2521 for i:= 0 to Pred(TeamsCount) do
2522 begin
2523 // skip teams that don't have matching name
2524 if TeamsArray[i]^.TeamName <> lua_tostring(L, 1) then
2525 continue;
2526 lua_pushnumber(L, i);
2527 found:= true;
2528 break;
2529 end;
2530 if (not found) then
2531 lua_pushnil(L);
2532 lc_getteamindex:= 1;
2533 end;
2534
lc_getteamclannull2535 function lc_getteamclan(L : Plua_state) : LongInt; Cdecl;
2536 var i: LongInt;
2537 found: boolean;
2538 begin
2539 found:= false;
2540 if CheckLuaParamCount(L, 1, 'GetTeamClan', 'teamname') then
2541 if TeamsCount > 0 then
2542 for i:= 0 to Pred(TeamsCount) do
2543 begin
2544 // skip teams that don't have matching name
2545 if TeamsArray[i]^.TeamName <> lua_tostring(L, 1) then
2546 continue;
2547 lua_pushnumber(L, TeamsArray[i]^.Clan^.ClanIndex);
2548 found:= true;
2549 break;
2550 end;
2551 if (not found) then
2552 lua_pushnil(L);
2553 lc_getteamclan:= 1;
2554 end;
2555
2556 function lc_dismissteam(L : Plua_State) : LongInt; Cdecl;
2557 var HHGear: PGear;
2558 i, h : LongInt;
2559 hidden: boolean;
2560 begin
2561 if CheckLuaParamCount(L, 1, 'DismissTeam', 'teamname') then
2562 begin
2563 if TeamsCount > 0 then
2564 for i:= 0 to Pred(TeamsCount) do
2565 begin
2566 // skip teams that don't have matching name
2567 if TeamsArray[i]^.TeamName <> lua_tostring(L, 1) then
2568 continue;
2569
2570 // destroy all hogs of matching team, including the hidden ones
2571 for h:= 0 to cMaxHHIndex do
2572 begin
2573 hidden:= (TeamsArray[i]^.Hedgehogs[h].GearHidden <> nil);
2574 if hidden then
2575 RestoreHog(@TeamsArray[i]^.Hedgehogs[h]);
2576 // destroy hedgehog gear, if any
2577 HHGear:= TeamsArray[i]^.Hedgehogs[h].Gear;
2578 if HHGear <> nil then
2579 begin
2580 // smoke effect
2581 if (not hidden) then
2582 begin
2583 AddVisualGear(hwRound(HHGear^.X), hwRound(HHGear^.Y), vgtSmokeWhite);
2584 AddVisualGear(hwRound(HHGear^.X) - 16 + Random(32), hwRound(HHGear^.Y) - 16 + Random(32), vgtSmokeWhite);
2585 AddVisualGear(hwRound(HHGear^.X) - 16 + Random(32), hwRound(HHGear^.Y) - 16 + Random(32), vgtSmokeWhite);
2586 AddVisualGear(hwRound(HHGear^.X) - 16 + Random(32), hwRound(HHGear^.Y) - 16 + Random(32), vgtSmokeWhite);
2587 AddVisualGear(hwRound(HHGear^.X) - 16 + Random(32), hwRound(HHGear^.Y) - 16 + Random(32), vgtSmokeWhite);
2588 end;
2589 HHGear^.Message:= HHGear^.Message or gmDestroy;
2590 HHGear^.Active:= true;
2591 AllInactive:= false;
2592 end;
2593 end;
2594 // can't dismiss more than one team
2595 break;
2596 end;
2597 end;
2598 lc_dismissteam:= 0;
2599 end;
2600
2601 function lc_getteamstats(L : Plua_State) : LongInt; Cdecl;
2602 var i: LongInt;
2603 begin
2604 if CheckLuaParamCount(L, 1, 'GetTeamStats', 'teamname') then
2605 begin
2606 if TeamsCount > 0 then
2607 for i:= 0 to Pred(TeamsCount) do
2608 begin
2609 // skip teams that don't have matching name
2610 if TeamsArray[i]^.TeamName <> lua_tostring(L, 1) then
2611 continue;
2612
2613 lua_newtable(L);
2614
2615 lua_pushstring(L, str2pchar('Kills'));
2616 lua_pushnumber(L, TeamsArray[i]^.stats.Kills);
2617 lua_settable(L, -3);
2618
2619 lua_pushstring(L, str2pchar('Suicides'));
2620 lua_pushnumber(L, TeamsArray[i]^.stats.Suicides);
2621 lua_settable(L, -3);
2622
2623 lua_pushstring(L, str2pchar('AIKills'));
2624 lua_pushnumber(L, TeamsArray[i]^.stats.AIKills);
2625 lua_settable(L, -3);
2626
2627 lua_pushstring(L, str2pchar('TeamKills'));
2628 lua_pushnumber(L, TeamsArray[i]^.stats.TeamKills);
2629 lua_settable(L, -3);
2630
2631 lua_pushstring(L, str2pchar('TurnSkips'));
2632 lua_pushnumber(L, TeamsArray[i]^.stats.TurnSkips);
2633 lua_settable(L, -3);
2634
2635 lua_pushstring(L, str2pchar('TeamDamage'));
2636 lua_pushnumber(L, TeamsArray[i]^.stats.TeamDamage);
2637 lua_settable(L, -3);
2638
2639 end;
2640 end
2641 else
2642 lua_pushnil(L);
2643 lc_getteamstats:= 1;
2644 end;
2645
2646
2647
lc_addhognull2648 function lc_addhog(L : Plua_State) : LongInt; Cdecl;
2649 var hatName: ShortString;
2650 begin
2651 if CheckLuaParamCount(L, 4, 'AddHog', 'hogname, botlevel, health, hat') then
2652 begin
2653 hatName:= lua_tostring(L, 4);
2654 ParseCommand('addhh ' + lua_tostring(L, 2) + ' ' + lua_tostring(L, 3) + ' ' + lua_tostring(L, 1), true, true);
2655 ParseCommand('hat ' + hatName, true, true);
2656 if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) then
2657 lua_pushnumber(L, CurrentHedgehog^.Gear^.uid)
2658 else
2659 OutError('Lua error: AddHog: Error adding hog. Maybe function was called outside of onGameInit.', true);
2660 end
2661 else
2662 lua_pushnil(L);
2663 lc_addhog:= 1;
2664 end;
2665
lc_addmissionhognull2666 function lc_addmissionhog(L : Plua_State) : LongInt; Cdecl;
2667 var hatName: ShortString;
2668 begin
2669 if CheckLuaParamCount(L, 1, 'AddMissionHog', 'health') then
2670 begin
2671 if(MissionTeam = nil) then
2672 begin
2673 OutError('Lua error: AddMissionHog: Could not add hog. Mission team is not set!', true);
2674 lua_pushnil(L);
2675 lc_addmissionhog:= 1;
2676 exit;
2677 end;
2678 with MissionTeam^.Hedgehogs[CurrentTeam^.HedgehogsNumber] do
2679 begin
2680 hatName:= Hat;
2681 ParseCommand('addhh ' + IntToStr(BotLevel) + ' ' + lua_tostring(L, 1) + ' ' + Name, true, true);
2682 ParseCommand('hat ' + hatName, true, true);
2683 end;
2684 if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) then
2685 lua_pushnumber(L, CurrentHedgehog^.Gear^.uid)
2686 else
2687 OutError('Lua error: AddMissionHog: Error adding hog. Maybe function was called outside of onGameInit.', true);
2688 end
2689 else
2690 lua_pushnil(L);
2691 lc_addmissionhog:= 1;
2692 end;
2693
lc_hogturnleftnull2694 function lc_hogturnleft(L : Plua_State) : LongInt; Cdecl;
2695 var gear: PGear;
2696 begin
2697 if CheckLuaParamCount(L, 2, 'HogTurnLeft', 'gearUid, boolean') then
2698 begin
2699 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
2700 if gear <> nil then
2701 gear^.dX.isNegative:= lua_toboolean(L, 2);
2702 end;
2703 lc_hogturnleft:= 0;
2704 end;
2705
lc_getgearpositionnull2706 function lc_getgearposition(L : Plua_State) : LongInt; Cdecl;
2707 var gear: PGear;
2708 begin
2709 if CheckLuaParamCount(L, 1, 'GetGearPosition', 'gearUid') then
2710 begin
2711 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
2712 if gear <> nil then
2713 begin
2714 lua_pushnumber(L, hwRound(gear^.X));
2715 lua_pushnumber(L, hwRound(gear^.Y))
2716 end
2717 else
2718 begin
2719 lua_pushnil(L);
2720 lua_pushnil(L)
2721 end;
2722 end
2723 else
2724 begin
2725 lua_pushnil(L);
2726 lua_pushnil(L)
2727 end;
2728 lc_getgearposition:= 2;
2729 end;
2730
lc_setgearpositionnull2731 function lc_setgearposition(L : Plua_State) : LongInt; Cdecl;
2732 var gear: PGear;
2733 col: boolean;
2734 x, y: LongInt;
2735 begin
2736 if CheckLuaParamCount(L, 3, 'SetGearPosition', 'gearUid, x, y') then
2737 begin
2738 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
2739 if gear <> nil then
2740 begin
2741 col:= gear^.CollisionIndex >= 0;
2742 x:= Trunc(lua_tonumber(L, 2));
2743 y:= Trunc(lua_tonumber(L, 3));
2744 if col then
2745 DeleteCI(gear);
2746 gear^.X:= int2hwfloat(x);
2747 gear^.Y:= int2hwfloat(y);
2748 if col then
2749 AddCI(gear);
2750 SetAllToActive
2751 end
2752 end;
2753 lc_setgearposition:= 0
2754 end;
2755
lc_getgeartargetnull2756 function lc_getgeartarget(L : Plua_State) : LongInt; Cdecl;
2757 var gear: PGear;
2758 begin
2759 if CheckLuaParamCount(L, 1, 'GetGearTarget', 'gearUid') then
2760 begin
2761 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
2762 if gear <> nil then
2763 begin
2764 lua_pushnumber(L, gear^.Target.X);
2765 lua_pushnumber(L, gear^.Target.Y)
2766 end
2767 else
2768 begin
2769 lua_pushnil(L);
2770 lua_pushnil(L)
2771 end
2772 end
2773 else
2774 begin
2775 lua_pushnil(L);
2776 lua_pushnil(L)
2777 end;
2778 lc_getgeartarget:= 2;
2779 end;
2780
lc_setgeartargetnull2781 function lc_setgeartarget(L : Plua_State) : LongInt; Cdecl;
2782 var gear: PGear;
2783 begin
2784 if CheckLuaParamCount(L, 3, 'SetGearTarget', 'gearUid, x, y') then
2785 begin
2786 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
2787 if gear <> nil then
2788 begin
2789 gear^.Target.X:= Trunc(lua_tonumber(L, 2));
2790 gear^.Target.Y:= Trunc(lua_tonumber(L, 3))
2791 end
2792 end;
2793 lc_setgeartarget:= 0
2794 end;
2795
lc_getgearvelocitynull2796 function lc_getgearvelocity(L : Plua_State) : LongInt; Cdecl;
2797 var gear: PGear;
2798 var t: LongInt;
2799 begin
2800 if CheckLuaParamCount(L, 1, 'GetGearVelocity', 'gearUid') then
2801 begin
2802 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
2803 if gear <> nil then
2804 begin
2805 t:= hwRound(gear^.dX * 1000000);
2806 // gear dX determines hog orientation
2807 if (gear^.dX.isNegative) and (t = 0) then t:= -1;
2808 lua_pushnumber(L, t);
2809 lua_pushnumber(L, hwRound(gear^.dY * 1000000))
2810 end
2811 end
2812 else
2813 begin
2814 lua_pushnil(L);
2815 lua_pushnil(L);
2816 end;
2817 lc_getgearvelocity:= 2;
2818 end;
2819
lc_setgearvelocitynull2820 function lc_setgearvelocity(L : Plua_State) : LongInt; Cdecl;
2821 var gear: PGear;
2822 begin
2823 if CheckLuaParamCount(L, 3, 'SetGearVelocity', 'gearUid, dx, dy') then
2824 begin
2825 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
2826 if gear <> nil then
2827 begin
2828 gear^.dX:= int2hwFloat(Trunc(lua_tonumber(L, 2))) / 1000000;
2829 gear^.dY:= int2hwFloat(Trunc(lua_tonumber(L, 3))) / 1000000;
2830 SetAllToActive;
2831 end
2832 end;
2833 lc_setgearvelocity:= 0
2834 end;
2835
lc_setzoomnull2836 function lc_setzoom(L : Plua_State) : LongInt; Cdecl;
2837 begin
2838 if CheckLuaParamCount(L, 1, 'SetZoom', 'zoomLevel') then
2839 begin
2840 ZoomValue:= lua_tonumber(L, 1);
2841 if ZoomValue < cMaxZoomLevel then
2842 ZoomValue:= cMaxZoomLevel;
2843 if ZoomValue > cMinZoomLevel then
2844 ZoomValue:= cMinZoomLevel;
2845 end;
2846 lc_setzoom:= 0
2847 end;
2848
lc_getzoomnull2849 function lc_getzoom(L : Plua_State) : LongInt; Cdecl;
2850 begin
2851 if CheckLuaParamCount(L, 0, 'GetZoom', '') then
2852 lua_pushnumber(L, ZoomValue)
2853 else
2854 lua_pushnil(L);
2855 lc_getzoom:= 1
2856 end;
2857
lc_setammonull2858 function lc_setammo(L : Plua_State) : LongInt; Cdecl;
2859 var np, at: LongInt;
2860 const
2861 call = 'SetAmmo';
2862 params = 'ammoType, count, probability, delay [, numberInCrate]';
2863 begin
2864 if CheckAndFetchParamCount(L, 4, 5, call, params, np) then
2865 begin
2866 at:= LuaToAmmoTypeOrd(L, 1, call, params);
2867 if at >= 0 then
2868 begin
2869 if np = 4 then
2870 ScriptSetAmmo(TAmmoType(at), Trunc(lua_tonumber(L, 2)), Trunc(lua_tonumber(L, 3)), Trunc(lua_tonumber(L, 4)), 1)
2871 else
2872 ScriptSetAmmo(TAmmoType(at), Trunc(lua_tonumber(L, 2)), Trunc(lua_tonumber(L, 3)), Trunc(lua_tonumber(L, 4)), Trunc(lua_tonumber(L, 5)));
2873 end;
2874 end;
2875 lc_setammo:= 0
2876 end;
2877
2878
lc_getammonull2879 function lc_getammo(L : Plua_State) : LongInt; Cdecl;
2880 var i, at, rawProb, probLevel: LongInt;
2881 const
2882 call = 'GetAmmo';
2883 params = 'ammoType';
2884 begin
2885 lc_getammo:= 0;
2886 if CheckLuaParamCount(L, 1, call, params) then
2887 begin
2888 at:= LuaToAmmoTypeOrd(L, 1, call, params);
2889 if at >= 0 then
2890 begin
2891 // Ammo count
2892 i:= InitialAmmoCounts[TAmmoType(at)];
2893 if i = AMMO_INFINITE then
2894 i:= 9;
2895 lua_pushnumber(L, i);
2896 // Probability
2897 rawProb:= Ammoz[TAmmoType(at)].Probability;
2898 probLevel:= -1;
2899 for i := 0 to High(probabilityLevels) do
2900 if rawProb = probabilityLevels[i] then
2901 probLevel:= i;
2902 lua_pushnumber(L, probLevel);
2903 // Delay in turns
2904 lua_pushnumber(L, Ammoz[TAmmoType(at)].SkipTurns);
2905 // Number in case
2906 lua_pushnumber(L, Ammoz[TAmmoType(at)].NumberInCase);
2907 lc_getammo:= 4
2908 end
2909 end;
2910 end;
2911
2912
lc_setammodelaynull2913 function lc_setammodelay(L : Plua_State) : LongInt; Cdecl;
2914 var at, delay: LongInt;
2915 const
2916 call = 'SetAmmoDelay';
2917 params = 'ammoType, delay';
2918 begin
2919 if CheckLuaParamCount(L, 2, call, params) then
2920 begin
2921 at:= LuaToAmmoTypeOrd(L, 1, call, params);
2922 delay:= Trunc(lua_tonumber(L, 2));
2923 if (at >= 0) and (TAmmoType(at) <> amNothing) then
2924 begin
2925 ScriptSetAmmoDelay(TAmmoType(at), delay);
2926 // Unselect weapon if neccessary
2927 if (delay > 0) and (CurrentHedgehog <> nil) and (CurrentHedgehog^.CurAmmoType = TAmmoType(at)) then
2928 ParseCommand('setweap ' + char(0), true, true);
2929 end;
2930 end;
2931 lc_setammodelay:= 0
2932 end;
2933
lc_setammoslotnull2934 function lc_setammoslot(L : Plua_State) : LongInt; Cdecl;
2935 var at, slot: LongInt;
2936 begin
2937 if CheckLuaParamCount(L, 2, 'SetAmmoSlot', 'ammoType, slot') then
2938 begin
2939 at:= Trunc(lua_tonumber(L, 1));
2940 slot:= Trunc(lua_tonumber(L, 2));
2941 Ammoz[TAmmoType(at)].Slot:= slot - 1;
2942 AmmoMenuInvalidated:= true;
2943 end;
2944 lc_setammoslot:= 0;
2945 end;
2946
lc_getrandomnull2947 function lc_getrandom(L : Plua_State) : LongInt; Cdecl;
2948 var m : LongInt;
2949 begin
2950 if CheckLuaParamCount(L, 1, 'GetRandom', 'number') then
2951 begin
2952 m:= Trunc(lua_tonumber(L, 1));
2953 if (m > 0) then
2954 lua_pushnumber(L, GetRandom(m))
2955 else
2956 begin
2957 LuaError('Lua: Tried to pass 0 to GetRandom!');
2958 lua_pushnil(L);
2959 end
2960 end
2961 else
2962 lua_pushnil(L); // return value on stack (nil)
2963 lc_getrandom:= 1
2964 end;
2965
lc_setwindnull2966 function lc_setwind(L : Plua_State) : LongInt; Cdecl;
2967 var vg: PVisualGear;
2968 begin
2969 if CheckLuaParamCount(L, 1, 'SetWind', 'windSpeed') then
2970 begin
2971 cWindSpeed:= int2hwfloat(Trunc(lua_tonumber(L, 1))) / 100 * cMaxWindSpeed;
2972 cWindSpeedf:= SignAs(cWindSpeed,cWindSpeed).QWordValue / SignAs(_1,_1).QWordValue;
2973 if cWindSpeed.isNegative then
2974 cWindSpeedf := -cWindSpeedf;
2975 vg:= AddVisualGear(0, 0, vgtSmoothWindBar);
2976 if vg <> nil then vg^.dAngle:= hwFloat2Float(cWindSpeed);
2977 AddFileLog('Script set wind = '+FloatToStr(cWindSpeed));
2978 end;
2979 lc_setwind:= 0
2980 end;
2981
lc_getwindnull2982 function lc_getwind(L : Plua_State) : LongInt; Cdecl;
2983 var wind: extended;
2984 begin
2985 if CheckLuaParamCount(L, 0, 'GetWind', '') then
2986 begin
2987 wind:= hwFloat2float((cWindSpeed / cMaxWindSpeed) * 100);
2988 if wind < -100 then
2989 wind:= -100
2990 else if wind > 100 then
2991 wind:= 100;
2992 lua_pushnumber(L, wind);
2993 end
2994 else
2995 lua_pushnil(L);
2996 lc_getwind:= 1
2997 end;
2998
lc_maphasbordernull2999 function lc_maphasborder(L : Plua_State) : LongInt; Cdecl;
3000 begin
3001 if CheckLuaParamCount(L, 0, 'MapHasBorder', '') then
3002 lua_pushboolean(L, hasBorder)
3003 else
3004 lua_pushnil(L);
3005 lc_maphasborder:= 1
3006 end;
3007
lc_getgearradiusnull3008 function lc_getgearradius(L : Plua_State) : LongInt; Cdecl;
3009 var gear : PGear;
3010 begin
3011 if CheckLuaParamCount(L, 1, 'GetGearRadius', 'gearUid') then
3012 begin
3013 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
3014 if gear <> nil then
3015 lua_pushnumber(L, gear^.Radius)
3016 else
3017 lua_pushnil(L);
3018 end
3019 else
3020 lua_pushnil(L); // return value on stack (nil)
3021 lc_getgearradius:= 1
3022 end;
3023
lc_gethoghatnull3024 function lc_gethoghat(L : Plua_State): LongInt; Cdecl;
3025 var gear : PGear;
3026 begin
3027 if CheckLuaParamCount(L, 1, 'GetHogHat', 'gearUid') then
3028 begin
3029 gear := GearByUID(Trunc(lua_tonumber(L, 1)));
3030 if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then
3031 lua_pushstring(L, str2pchar(gear^.Hedgehog^.Hat))
3032 else
3033 lua_pushnil(L);
3034 end
3035 else
3036 lua_pushnil(L);
3037 lc_gethoghat := 1;
3038 end;
3039
lc_sethoghatnull3040 function lc_sethoghat(L : Plua_State) : LongInt; Cdecl;
3041 var gear : PGear;
3042 hat: ShortString;
3043 begin
3044 if CheckLuaParamCount(L, 2, 'SetHogHat', 'gearUid, hat') then
3045 begin
3046 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
3047 if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
3048 begin
3049 hat:= lua_tostring(L, 2);
3050 gear^.Hedgehog^.Hat:= hat;
3051 AddFileLog('Changed hat to: '+hat);
3052 if (Length(hat) > 39) and (Copy(hat,1,8) = 'Reserved') and (Copy(hat,9,32) = gear^.Hedgehog^.Team^.PlayerHash) then
3053 LoadHedgehogHat(gear^.Hedgehog^, 'Reserved/' + Copy(hat,9,Length(hat)-8))
3054 else
3055 LoadHedgehogHat(gear^.Hedgehog^, hat)
3056 end
3057 end;
3058 lc_sethoghat:= 0;
3059 end;
3060
lc_placespritenull3061 function lc_placesprite(L : Plua_State) : LongInt; Cdecl;
3062 var spr : TSprite;
3063 lf : Word;
3064 tint : LongWord;
3065 i, n : LongInt;
3066 placed, behind, flipHoriz, flipVert : boolean;
3067 const
3068 call = 'PlaceSprite';
3069 params = 'x, y, sprite, frameIdx, tint, behind, flipHoriz, flipVert [, landFlag, ... ]';
3070 begin
3071 placed:= false;
3072 if CheckAndFetchLuaParamMinCount(L, 4, call, params, n) then
3073 begin
3074 if not lua_isnoneornil(L, 5) then
3075 tint := Trunc(lua_tonumber(L, 5))
3076 else tint := $FFFFFFFF;
3077 if not lua_isnoneornil(L, 6) then
3078 behind := lua_toboolean(L, 6)
3079 else behind := false;
3080 if not lua_isnoneornil(L, 7) then
3081 flipHoriz := lua_toboolean(L, 7)
3082 else flipHoriz := false;
3083 if not lua_isnoneornil(L, 8) then
3084 flipVert := lua_toboolean(L, 8)
3085 else flipVert := false;
3086 lf:= 0;
3087
3088 // accept any amount of landflags, loop is never executed if n<9
3089 for i:= 9 to n do
3090 lf:= lf or Trunc(lua_tonumber(L, i));
3091
3092 n:= LuaToSpriteOrd(L, 3, call, params);
3093 if n >= 0 then
3094 begin
3095 spr:= TSprite(n);
3096 if SpritesData[spr].Surface = nil then
3097 LuaError(call + ': ' + EnumToStr(spr) + ' cannot be placed! (required information not loaded)' )
3098 else
3099 placed:= ForcePlaceOnLand(
3100 Trunc(lua_tonumber(L, 1)) - SpritesData[spr].Width div 2,
3101 Trunc(lua_tonumber(L, 2)) - SpritesData[spr].Height div 2,
3102 spr, Trunc(lua_tonumber(L, 4)), lf, tint, behind, flipHoriz, flipVert);
3103 end;
3104 end;
3105
3106 lua_pushboolean(L, placed);
3107 lc_placesprite:= 1
3108 end;
3109
lc_erasespritenull3110 function lc_erasesprite(L : Plua_State) : LongInt; Cdecl;
3111 var spr : TSprite;
3112 lf : Word;
3113 i, n : LongInt;
3114 eraseOnLFMatch, onlyEraseLF, flipHoriz, flipVert : boolean;
3115 const
3116 call = 'EraseSprite';
3117 params = 'x, y, sprite, frameIdx, eraseOnLFMatch, onlyEraseLF, flipHoriz, flipVert [, landFlag, ... ]';
3118 begin
3119 if CheckAndFetchLuaParamMinCount(L, 4, call, params, n) then
3120 begin
3121 if not lua_isnoneornil(L, 5) then
3122 eraseOnLFMatch := lua_toboolean(L, 5)
3123 else eraseOnLFMatch := false;
3124 if not lua_isnoneornil(L, 6) then
3125 onlyEraseLF := lua_toboolean(L, 6)
3126 else onlyEraseLF := false;
3127 if not lua_isnoneornil(L, 7) then
3128 flipHoriz := lua_toboolean(L, 7)
3129 else flipHoriz := false;
3130 if not lua_isnoneornil(L, 8) then
3131 flipVert := lua_toboolean(L, 8)
3132 else flipVert := false;
3133 lf:= 0;
3134
3135 // accept any amount of landflags, loop is never executed if n<9
3136 for i:= 9 to n do
3137 lf:= lf or Trunc(lua_tonumber(L, i));
3138
3139 n:= LuaToSpriteOrd(L, 3, call, params);
3140 if n >= 0 then
3141 begin
3142 spr:= TSprite(n);
3143 if SpritesData[spr].Surface = nil then
3144 LuaError(call + ': ' + EnumToStr(spr) + ' cannot be placed! (required information not loaded)' )
3145 else
3146 EraseLand(
3147 Trunc(lua_tonumber(L, 1)) - SpritesData[spr].Width div 2,
3148 Trunc(lua_tonumber(L, 2)) - SpritesData[spr].Height div 2,
3149 spr, Trunc(lua_tonumber(L, 4)), lf, eraseOnLFMatch, onlyEraseLF, flipHoriz, flipVert);
3150 end;
3151 end;
3152 lc_erasesprite:= 0
3153 end;
3154
lc_placegirdernull3155 function lc_placegirder(L : Plua_State) : LongInt; Cdecl;
3156 var placed: boolean;
3157 begin
3158 placed:= false;
3159 if CheckLuaParamCount(L, 3, 'PlaceGirder', 'x, y, frameIdx') then
3160 placed:= TryPlaceOnLandSimple(
3161 Trunc(lua_tonumber(L, 1)) - SpritesData[sprAmGirder].Width div 2,
3162 Trunc(lua_tonumber(L, 2)) - SpritesData[sprAmGirder].Height div 2,
3163 sprAmGirder, Trunc(lua_tonumber(L, 3)), true, false);
3164
3165 lua_pushboolean(L, placed);
3166 lc_placegirder:= 1
3167 end;
3168
lc_placerubbernull3169 function lc_placerubber(L : Plua_State) : LongInt; Cdecl;
3170 var placed: boolean;
3171 begin
3172 placed:= false;
3173 if CheckLuaParamCount(L, 3, 'PlaceRubber', 'x, y, frameIdx') then
3174 placed:= TryPlaceOnLand(
3175 Trunc(lua_tonumber(L, 1)) - SpritesData[sprAmRubber].Width div 2,
3176 Trunc(lua_tonumber(L, 2)) - SpritesData[sprAmRubber].Height div 2,
3177 sprAmRubber, Trunc(lua_tonumber(L, 3)), true, lfBouncy);
3178
3179 lua_pushboolean(L, placed);
3180 lc_placerubber:= 1
3181 end;
3182
lc_getcurammotypenull3183 function lc_getcurammotype(L : Plua_State): LongInt; Cdecl;
3184 begin
3185 if (CurrentHedgehog <> nil) and (CheckLuaParamCount(L, 0, 'GetCurAmmoType', '')) then
3186 lua_pushnumber(L, ord(CurrentHedgehog^.CurAmmoType))
3187 else
3188 lua_pushnumber(L, ord(amNothing));
3189 lc_getcurammotype := 1;
3190 end;
3191
lc_savecampaignvarnull3192 function lc_savecampaignvar(L : Plua_State): LongInt; Cdecl;
3193 begin
3194 if CheckLuaParamCount(L, 2, 'SaveCampaignVar', 'varname, value') then
3195 SendIPC('V!' + lua_tostring(L, 1) + ' ' + lua_tostring(L, 2) + #0);
3196 lc_savecampaignvar := 0;
3197 end;
3198
lc_getcampaignvarnull3199 function lc_getcampaignvar(L : Plua_State): LongInt; Cdecl;
3200 begin
3201 if CheckLuaParamCount(L, 1, 'GetCampaignVar', 'varname') then
3202 SendIPCAndWaitReply('V?' + lua_tostring(L, 1) + #0);
3203 lua_pushstring(L, str2pchar(CampaignVariable));
3204 lc_getcampaignvar := 1;
3205 end;
3206
lc_savemissionvarnull3207 function lc_savemissionvar(L : Plua_State): LongInt; Cdecl;
3208 begin
3209 if CheckLuaParamCount(L, 2, 'SaveMissionVar', 'varname, value') then
3210 SendIPC('v!' + lua_tostring(L, 1) + ' ' + lua_tostring(L, 2) + #0);
3211 lc_savemissionvar := 0;
3212 end;
3213
lc_getmissionvarnull3214 function lc_getmissionvar(L : Plua_State): LongInt; Cdecl;
3215 begin
3216 if CheckLuaParamCount(L, 1, 'GetMissionVar', 'varname') then
3217 SendIPCAndWaitReply('v?' + lua_tostring(L, 1) + #0);
3218 lua_pushstring(L, str2pchar(MissionVariable));
3219 lc_getmissionvar := 1;
3220 end;
3221
lc_hidehognull3222 function lc_hidehog(L: Plua_State): LongInt; Cdecl;
3223 var gear: PGear;
3224 begin
3225 if CheckLuaParamCount(L, 1, 'HideHog', 'gearUid') then
3226 begin
3227 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
3228 if (gear <> nil) and (gear^.hedgehog <> nil) then
3229 begin
3230 HideHog(gear^.hedgehog);
3231 lua_pushboolean(L, true);
3232 end
3233 else
3234 lua_pushboolean(L, false);
3235 end;
3236 lc_hidehog := 1;
3237 end;
3238
lc_restorehognull3239 function lc_restorehog(L: Plua_State): LongInt; Cdecl;
3240 var i, h: LongInt;
3241 uid: LongWord;
3242 begin
3243 if CheckLuaParamCount(L, 1, 'RestoreHog', 'gearUid') then
3244 begin
3245 uid:= LongWord(Trunc(lua_tonumber(L, 1)));
3246 if TeamsCount > 0 then
3247 for i:= 0 to Pred(TeamsCount) do
3248 for h:= 0 to cMaxHHIndex do
3249 if (TeamsArray[i]^.Hedgehogs[h].GearHidden <> nil) and (TeamsArray[i]^.Hedgehogs[h].GearHidden^.uid = uid) then
3250 begin
3251 RestoreHog(@TeamsArray[i]^.Hedgehogs[h]);
3252 exit(0)
3253 end
3254 end;
3255 lc_restorehog := 0;
3256 end;
3257
lc_ishoghiddennull3258 function lc_ishoghidden(L: Plua_State): LongInt; Cdecl;
3259 var i, h: LongInt;
3260 uid: LongWord;
3261 gear: PGear;
3262 begin
3263 if CheckLuaParamCount(L, 1, 'IsHogHidden', 'gearUid') then
3264 begin
3265 uid:= LongWord(Trunc(lua_tonumber(L, 1)));
3266 gear:= GearByUID(uid);
3267 if (gear <> nil) and (gear^.hedgehog <> nil) then
3268 begin
3269 lua_pushboolean(L, false);
3270 lc_ishoghidden:= 1;
3271 exit;
3272 end
3273 else
3274 if TeamsCount > 0 then
3275 for i:= 0 to Pred(TeamsCount) do
3276 for h:= 0 to cMaxHHIndex do
3277 if (TeamsArray[i]^.Hedgehogs[h].GearHidden <> nil) and (TeamsArray[i]^.Hedgehogs[h].GearHidden^.uid = uid) then
3278 begin
3279 lua_pushboolean(L, true);
3280 lc_ishoghidden:= 1;
3281 exit;
3282 end
3283 end;
3284 lua_pushnil(L);
3285 lc_ishoghidden:= 1;
3286 end;
3287
3288 // boolean TestRectForObstacle(x1, y1, x2, y2, landOnly)
lc_testrectforobstaclenull3289 function lc_testrectforobstacle(L : Plua_State) : LongInt; Cdecl;
3290 var rtn: Boolean;
3291 begin
3292 if CheckLuaParamCount(L, 5, 'TestRectForObstacle', 'x1, y1, x2, y2, landOnly') then
3293 begin
3294 rtn:= TestRectangleForObstacle(
3295 Trunc(lua_tonumber(L, 1)),
3296 Trunc(lua_tonumber(L, 2)),
3297 Trunc(lua_tonumber(L, 3)),
3298 Trunc(lua_tonumber(L, 4)),
3299 lua_toboolean(L, 5)
3300 );
3301 lua_pushboolean(L, rtn);
3302 end
3303 else
3304 lua_pushnil(L); // return value on stack (nil)
3305 lc_testrectforobstacle:= 1
3306 end;
3307
3308
lc_getgravitynull3309 function lc_getgravity(L : Plua_State) : LongInt; Cdecl;
3310 begin
3311 if CheckLuaParamCount(L, 0, 'GetGravity', '') then
3312 lua_pushnumber(L, hwRound(SignAs(_0_5, cGravity) + (cGravity * 50 / cMaxWindSpeed)));
3313 lc_getgravity:= 1
3314 end;
3315
lc_setgravitynull3316 function lc_setgravity(L : Plua_State) : LongInt; Cdecl;
3317 begin
3318 if CheckLuaParamCount(L, 1, 'SetGravity', 'percent') then
3319 begin
3320 cGravity:= _0_02 * Trunc(lua_tonumber(L, 1)) * cMaxWindSpeed;
3321 cGravityf:= 0.00025 * Trunc(lua_tonumber(L, 1)) * 0.02
3322 end;
3323 lc_setgravity:= 0
3324 end;
3325
lc_setwaterlinenull3326 function lc_setwaterline(L : Plua_State) : LongInt; Cdecl;
3327 var iterator: PGear;
3328 begin
3329 if CheckLuaParamCount(L, 1, 'SetWaterLine', 'waterline') then
3330 begin
3331 cWaterLine:= Trunc(lua_tonumber(L,1));
3332 AllInactive:= false;
3333 iterator:= GearsList;
3334 while iterator <> nil do
3335 begin
3336 if not (iterator^.Kind in [gtPortal, gtAirAttack]) and (iterator^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0) then
3337 begin
3338 iterator^.Active:= true;
3339 if iterator^.dY.QWordValue = 0 then iterator^.dY.isNegative:= false;
3340 iterator^.State:= iterator^.State or gstMoving;
3341 DeleteCI(iterator)
3342 end;
3343 iterator:= iterator^.NextGear
3344 end
3345 end;
3346 lc_setwaterline:= 0
3347 end;
3348
lc_setgearaihintsnull3349 function lc_setgearaihints(L : Plua_State) : LongInt; Cdecl;
3350 var gear: PGear;
3351 begin
3352 if CheckLuaParamCount(L, 2, 'SetGearAIHints', 'gearUid, aiHints') then
3353 begin
3354 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
3355 if gear <> nil then
3356 gear^.aihints:= Trunc(lua_tonumber(L, 2));
3357 end;
3358 lc_setgearaihints:= 0
3359 end;
3360
3361
lc_hedgewarsscriptloadnull3362 function lc_hedgewarsscriptload(L : Plua_State) : LongInt; Cdecl;
3363 var success : boolean;
3364 n : LongInt;
3365 begin
3366 success:= false;
3367 if CheckAndFetchParamCount(L, 1, 2, 'HedgewarsScriptLoad', 'scriptPath [, mustExist]', n) then
3368 begin
3369 if n = 1 then
3370 success:= ScriptLoad(lua_tostring(L, 1), true)
3371 else
3372 success:= ScriptLoad(lua_tostring(L, 1), lua_toboolean(L, 2));
3373 end
3374 else
3375 success:= false;
3376 lua_pushboolean(L, success);
3377 lc_hedgewarsscriptload:= 1;
3378 end;
3379
3380
lc_declareachievementnull3381 function lc_declareachievement(L : Plua_State) : LongInt; Cdecl;
3382 begin
3383 if CheckLuaParamCount(L, 4, 'DeclareAchievement', 'achievementId, teamname, location, value') then
3384 declareAchievement(lua_tostring(L, 1), lua_tostring(L, 2), lua_tostring(L, 3), Trunc(lua_tonumber(L, 4)));
3385 lc_declareachievement:= 0
3386 end;
3387
lc_getammonamenull3388 function lc_getammoname(L : Plua_state) : LongInt; Cdecl;
3389 var np, at: LongInt;
3390 ignoreOverwrite: Boolean;
3391 const call = 'GetAmmoName';
3392 params = 'ammoType [, ignoreOverwrite ]';
3393 begin
3394 if CheckAndFetchParamCountRange(L, 1, 2, call, params, np) then
3395 begin
3396 at:= LuaToAmmoTypeOrd(L, 1, call, params);
3397 ignoreOverwrite := false;
3398 if np > 1 then
3399 ignoreOverwrite := lua_toboolean(L, 2);
3400 if at >= 0 then
3401 if (not ignoreOverwrite) and (length(trluaammo[Ammoz[TAmmoType(at)].NameId]) > 0) then
3402 lua_pushstring(L, PChar(trluaammo[Ammoz[TAmmoType(at)].NameId]))
3403 else
3404 lua_pushstring(L, PChar(trammo[Ammoz[TAmmoType(at)].NameId]));
3405 end
3406 else
3407 lua_pushnil(L);
3408 lc_getammoname:= 1;
3409 end;
3410
lc_getammotimernull3411 function lc_getammotimer(L : Plua_state) : LongInt; Cdecl;
3412 var at: LongInt;
3413 weapon: PAmmo;
3414 gear: PGear;
3415 const call = 'GetAmmoTimer';
3416 params = 'gearUid, ammoType';
3417 begin
3418 if CheckLuaParamCount(L, 2, call, params) then
3419 begin
3420 gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
3421 if (gear <> nil) and (gear^.Hedgehog <> nil) then
3422 begin
3423 at:= LuaToAmmoTypeOrd(L, 2, call, params);
3424 weapon:= GetAmmoEntry(gear^.Hedgehog^, TAmmoType(at));
3425 if (Ammoz[TAmmoType(at)].Ammo.Propz and ammoprop_Timerable) <> 0 then
3426 lua_pushnumber(L, weapon^.Timer)
3427 else
3428 lua_pushnil(L);
3429 end
3430 else
3431 lua_pushnil(L);
3432 end
3433 else
3434 lua_pushnil(L);
3435 lc_getammotimer:= 1;
3436 end;
3437
lc_setvampiricnull3438 function lc_setvampiric(L : Plua_state) : LongInt; Cdecl;
3439 begin
3440 if CheckLuaParamCount(L, 1, 'SetVampiric', 'bool') then
3441 cVampiric := lua_toboolean(L, 1);
3442 lc_setvampiric := 0;
3443 end;
3444
lc_getvampiricnull3445 function lc_getvampiric(L : Plua_state) : LongInt; Cdecl;
3446 begin
3447 lua_pushboolean(L, cVampiric);
3448 lc_getvampiric := 1;
3449 end;
3450
lc_setlasersightnull3451 function lc_setlasersight(L : Plua_state) : LongInt; Cdecl;
3452 begin
3453 if CheckLuaParamCount(L, 1, 'SetLaserSight', 'bool') then
3454 cLaserSighting:= lua_toboolean(L, 1);
3455 lc_setlasersight:= 0;
3456 end;
3457
lc_getlasersightnull3458 function lc_getlasersight(L : Plua_state) : LongInt; Cdecl;
3459 begin
3460 lua_pushboolean(L, cLaserSighting);
3461 lc_getlasersight:= 1;
3462 end;
3463
lc_explodenull3464 function lc_explode(L : Plua_state) : LongInt; Cdecl;
3465 var mask: LongWord;
3466 n: LongInt;
3467 begin
3468 if CheckAndFetchParamCount(L, 3, 4, 'Explode', 'x, y, radius[, options]', n) then
3469 if CurrentHedgehog <> nil then
3470 begin
3471 mask:= EXPLAutoSound;
3472 if (n = 4) then
3473 mask:= Trunc(lua_tonumber(L, 4));
3474 doMakeExplosion(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)), Trunc(lua_tonumber(L, 3)), CurrentHedgehog, mask);
3475 lua_pushboolean(L, true);
3476 end
3477 else
3478 lua_pushboolean(L, false)
3479 else
3480 lua_pushboolean(L, false);
3481 lc_explode:= 1;
3482 end;
3483
lc_setturntimeleftnull3484 function lc_setturntimeleft(L : Plua_State) : LongInt; Cdecl;
3485 var number: Int64;
3486 begin
3487 if CheckLuaParamCount(L, 1, 'SetTurnTimeLeft', 'newTurnTimeLeft') then
3488 begin
3489 number:= Trunc(lua_tonumber(L, 1));
3490 if number < 0 then
3491 number:= 0;
3492 if number > cMaxTurnTime then
3493 number:= cMaxTurnTime;
3494 // The real TurnTimeLeft will be set in SetGlobals
3495 PendingTurnTimeLeft:= number;
3496 isPendingTurnTimeLeft:= true;
3497 end;
3498 lc_setturntimeleft:= 0;
3499 end;
3500
lc_setreadytimeleftnull3501 function lc_setreadytimeleft(L : Plua_State) : LongInt; Cdecl;
3502 var number: Int64;
3503 begin
3504 if CheckLuaParamCount(L, 1, 'SetReadyTimeLeft', 'newReadyTimeLeft') then
3505 begin
3506 number:= Trunc(lua_tonumber(L, 1));
3507 if number < 0 then
3508 number:= 0;
3509 if number > cMaxTurnTime then
3510 number:= cMaxTurnTime;
3511 // The real ReadyTimeLeft will be set in SetGlobals
3512 PendingReadyTimeLeft:= number;
3513 isPendingReadyTimeLeft:= true;
3514 end;
3515 lc_setreadytimeleft:= 0;
3516 end;
3517
lc_setturntimepausednull3518 function lc_setturntimepaused(L : Plua_State) : LongInt; Cdecl;
3519 begin
3520 if CheckLuaParamCount(L, 1, 'SetTurnTimePaused', 'isPaused') then
3521 LuaClockPaused:= lua_toboolean(L, 1);
3522 lc_setturntimepaused:= 0;
3523 end;
3524
lc_getturntimepausednull3525 function lc_getturntimepaused(L : Plua_State) : LongInt; Cdecl;
3526 begin
3527 if CheckLuaParamCount(L, 0, 'GetTurnTimePaused', '') then
3528 lua_pushboolean(L, LuaClockPaused)
3529 else
3530 lua_pushnil(L);
3531 lc_getturntimepaused:= 1;
3532 end;
3533
lc_startghostpointsnull3534 function lc_startghostpoints(L : Plua_State) : LongInt; Cdecl;
3535 begin
3536 if CheckLuaParamCount(L, 1, 'StartGhostPoints', 'count') then
3537 startGhostPoints(Trunc(lua_tonumber(L, 1)));
3538 lc_startghostpoints:= 0
3539 end;
3540
lc_dumppointnull3541 function lc_dumppoint(L : Plua_State) : LongInt; Cdecl;
3542 begin
3543 if CheckLuaParamCount(L, 2, 'DumpPoint', 'x, y') then
3544 dumpPoint(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)));
3545 lc_dumppoint:= 0
3546 end;
3547
3548
3549 procedure ScriptFlushPoints();
3550 begin
3551 ParseCommand('draw ' + PointsBuffer, true, true);
3552 PointsBuffer:= '';
3553 end;
3554
3555
lc_addPointnull3556 function lc_addPoint(L : Plua_State) : LongInt; Cdecl;
3557 var np, param: LongInt;
3558 begin
3559 if CheckAndFetchParamCountRange(L, 2, 4, 'AddPoint', 'x, y [, width [, erase] ]', np) then
3560 begin
3561 // x
3562 param:= LongInt(Trunc(lua_tonumber(L,1)));
3563 PointsBuffer:= PointsBuffer + char((param shr 8) and $FF);
3564 PointsBuffer:= PointsBuffer + char((param and $FF));
3565 // y
3566 param:= LongInt(Trunc(lua_tonumber(L,2)));
3567 PointsBuffer:= PointsBuffer + char((param shr 8) and $FF);
3568 PointsBuffer:= PointsBuffer + char((param and $FF));
3569 // width
3570 if np > 2 then
3571 begin
3572 param:= Trunc(lua_tonumber(L,3));
3573 param:= (param or $80);
3574 // erase
3575 if (np > 3) and lua_toboolean(L, 4) then
3576 param:= (param or $40);
3577 PointsBuffer:= PointsBuffer + char(param);
3578 end
3579 // no width defined
3580 else
3581 PointsBuffer:= PointsBuffer + char(0);
3582
3583 // flush before shortstring limit length is reached
3584 if length(PointsBuffer) > 245 then
3585 ScriptFlushPoints();
3586 end;
3587 lc_addPoint:= 0
3588 end;
3589
3590
lc_flushPointsnull3591 function lc_flushPoints(L : Plua_State) : LongInt; Cdecl;
3592 begin
3593 if CheckLuaParamCount(L, 0, 'FlushPoints', '') then
3594 if length(PointsBuffer) > 0 then
3595 ScriptFlushPoints();
3596 lc_flushPoints:= 0
3597 end;
3598
3599 // stuff for lua tests
lc_endluatestnull3600 function lc_endluatest(L : Plua_State) : LongInt; Cdecl;
3601 var rstring: shortstring;
3602 const
3603 call = 'EndLuaTest';
3604 params = 'TEST_SUCCESSFUL or TEST_FAILED';
3605 begin
3606 if CheckLuaParamCount(L, 1, call, params) then
3607 begin
3608
3609 case Trunc(lua_tonumber(L, 1)) of
3610 HaltTestSuccess : rstring:= 'Success';
3611 HaltTestFailed: rstring:= 'FAILED';
3612 else
3613 begin
3614 LuaCallError('Parameter must be either ' + params, call, params);
3615 exit(0);
3616 end;
3617 end;
3618
3619 if cTestLua then
3620 begin
3621 WriteLnToConsole('Lua test finished, result: ' + rstring);
3622 halt(Trunc(lua_tonumber(L, 1)));
3623 end
3624 else LuaError('Not in lua test mode, engine will keep running. Reported test result: ' + rstring);
3625
3626 end;
3627
3628 lc_endluatest:= 0;
3629 end;
3630 ///////////////////
3631
3632 procedure ScriptPrintStack;
3633 var n, i : LongInt;
3634 begin
3635 n:= lua_gettop(luaState);
3636 WriteLnToConsole('Lua: Stack (' + inttostr(n) + ' elements):');
3637 for i:= 1 to n do
3638 if not lua_isboolean(luaState, i) then
3639 WriteLnToConsole('Lua: ' + inttostr(i) + ': ' + lua_tostring(luaState, i))
3640 else if lua_toboolean(luaState, i) then
3641 WriteLnToConsole('Lua: ' + inttostr(i) + ': true')
3642 else
3643 WriteLnToConsole('Lua: ' + inttostr(i) + ': false');
3644 end;
3645
3646 procedure ScriptClearStack;
3647 begin
3648 lua_settop(luaState, 0)
3649 end;
3650
3651 procedure ScriptSetNil(name : shortstring);
3652 begin
3653 lua_pushnil(luaState);
3654 lua_setglobal(luaState, Str2PChar(name));
3655 end;
3656
3657 procedure ScriptSetInteger(name : shortstring; value : LongInt);
3658 begin
3659 lua_pushnumber(luaState, value);
3660 lua_setglobal(luaState, Str2PChar(name));
3661 end;
3662
3663 procedure ScriptSetLongWord(name : shortstring; value : LongWord);
3664 begin
3665 lua_pushnumber(luaState, value);
3666 lua_setglobal(luaState, Str2PChar(name));
3667 end;
3668
3669 procedure ScriptSetString(name : shortstring; value : shortstring);
3670 begin
3671 lua_pushstring(luaState, Str2PChar(value));
3672 lua_setglobal(luaState, Str2PChar(name));
3673 end;
3674
ScriptGetIntegernull3675 function ScriptGetInteger(name : shortstring) : LongInt;
3676 begin
3677 lua_getglobal(luaState, Str2PChar(name));
3678 ScriptGetInteger:= Trunc(lua_tonumber(luaState, -1));
3679 lua_pop(luaState, 1);
3680 end;
3681
ScriptGetStringnull3682 function ScriptGetString(name : shortstring) : shortstring;
3683 begin
3684 lua_getglobal(luaState, Str2PChar(name));
3685 ScriptGetString:= lua_tostring(luaState, -1);
3686 lua_pop(luaState, 1);
3687 end;
3688
ScriptGetAnsiStringnull3689 function ScriptGetAnsiString(name : shortstring) : ansistring;
3690 begin
3691 lua_getglobal(luaState, Str2PChar(name));
3692 ScriptGetAnsiString:= lua_tostringa(luaState, -1);
3693 lua_pop(luaState, 1);
3694 end;
3695
3696 procedure ScriptOnPreviewInit;
3697 begin
3698 // not required if there is no script to run
3699 if not ScriptLoaded then
3700 exit;
3701
3702 ScriptSetString('Seed', cSeed);
3703 ScriptSetInteger('TemplateFilter', cTemplateFilter);
3704 ScriptSetInteger('TemplateNumber', LuaTemplateNumber);
3705 ScriptSetInteger('MapGen', ord(cMapGen));
3706 ScriptSetInteger('MapFeatureSize', cFeatureSize);
3707
3708 ScriptCall('onPreviewInit');
3709
3710 // pop game variables
3711 ParseCommand('seed ' + ScriptGetString('Seed'), true, true);
3712 cTemplateFilter := ScriptGetInteger('TemplateFilter');
3713 LuaTemplateNumber:= ScriptGetInteger('TemplateNumber');
3714 cMapGen := TMapGen(ScriptGetInteger('MapGen'));
3715 cFeatureSize := ScriptGetInteger('MapFeatureSize');
3716 end;
3717
3718 procedure ScriptOnGameInit;
3719 var i, j, k: LongInt;
3720 begin
3721 // not required if there is no script to run
3722 if not ScriptLoaded then
3723 exit;
3724
3725 // push game variables so they may be modified by the script
3726 ScriptSetInteger('CursorX', NoPointX);
3727 ScriptSetInteger('CursorY', NoPointX);
3728 ScriptSetInteger('GameFlags', GameFlags);
3729 ScriptSetInteger('WorldEdge', ord(WorldEdge));
3730 ScriptSetString('Seed', cSeed);
3731 ScriptSetInteger('TemplateFilter', cTemplateFilter);
3732 ScriptSetInteger('TemplateNumber', LuaTemplateNumber);
3733 ScriptSetInteger('MapGen', ord(cMapGen));
3734 ScriptSetInteger('MapFeatureSize', cFeatureSize);
3735 ScriptSetInteger('ScreenHeight', cScreenHeight);
3736 ScriptSetInteger('ScreenWidth', cScreenWidth);
3737 ScriptSetInteger('TurnTime', cHedgehogTurnTime);
3738 ScriptSetInteger('CaseFreq', cCaseFactor);
3739 ScriptSetInteger('MaxCaseDrops', cMaxCaseDrops);
3740 ScriptSetInteger('HealthCaseProb', cHealthCaseProb);
3741 ScriptSetInteger('HealthCaseAmount', cHealthCaseAmount);
3742 ScriptSetInteger('InitHealth', cInitHealth);
3743 ScriptSetInteger('DamagePercent', cDamagePercent);
3744 ScriptSetInteger('RopePercent', cRopePercent);
3745 ScriptSetInteger('MinesNum', cLandMines);
3746 ScriptSetInteger('MinesTime', cMinesTime);
3747 ScriptSetInteger('MineDudPercent', cMineDudPercent);
3748 ScriptSetInteger('AirMinesNum', cAirMines);
3749 ScriptSetInteger('Explosives', cExplosives);
3750 ScriptSetInteger('Delay', cInactDelay);
3751 ScriptSetInteger('Ready', cReadyDelay);
3752 ScriptSetInteger('SuddenDeathTurns', cSuddenDTurns);
3753 ScriptSetInteger('WaterRise', cWaterRise);
3754 ScriptSetInteger('HealthDecrease', cHealthDecrease);
3755 ScriptSetInteger('GetAwayTime', cGetAwayTime);
3756 ScriptSetInteger('AmmoTypeMax', Ord(High(TAmmoType)));
3757 ScriptSetString('Map', cMapName);
3758 ScriptSetString('Theme', Theme);
3759 ScriptSetString('Goals', '');
3760
3761 ScriptCall('onGameInit');
3762
3763 // pop game variables
3764 ParseCommand('seed ' + ScriptGetString('Seed'), true, true);
3765 cTemplateFilter := ScriptGetInteger('TemplateFilter');
3766 LuaTemplateNumber:= ScriptGetInteger('TemplateNumber');
3767 cMapGen := TMapGen(ScriptGetInteger('MapGen'));
3768 cFeatureSize := ScriptGetInteger('MapFeatureSize');
3769 GameFlags := ScriptGetInteger('GameFlags');
3770 WorldEdge := TWorldEdge(ScriptGetInteger('WorldEdge'));
3771 cHedgehogTurnTime:= ScriptGetInteger('TurnTime');
3772 cCaseFactor := ScriptGetInteger('CaseFreq');
3773 cMaxCaseDrops := ScriptGetInteger('MaxCaseDrops');
3774 cHealthCaseProb := ScriptGetInteger('HealthCaseProb');
3775 cHealthCaseAmount:= ScriptGetInteger('HealthCaseAmount');
3776 cInitHealth := ScriptGetInteger('InitHealth');
3777 cDamagePercent := ScriptGetInteger('DamagePercent');
3778 cRopePercent := ScriptGetInteger('RopePercent');
3779 cLandMines := ScriptGetInteger('MinesNum');
3780 cMinesTime := ScriptGetInteger('MinesTime');
3781 cMineDudPercent := ScriptGetInteger('MineDudPercent');
3782 cAirMines := ScriptGetInteger('AirMinesNum');
3783 cExplosives := ScriptGetInteger('Explosives');
3784 cInactDelay := ScriptGetInteger('Delay');
3785 cReadyDelay := ScriptGetInteger('Ready');
3786 cSuddenDTurns := ScriptGetInteger('SuddenDeathTurns');
3787 cWaterRise := ScriptGetInteger('WaterRise');
3788 cHealthDecrease := ScriptGetInteger('HealthDecrease');
3789 cGetAwayTime := ScriptGetInteger('GetAwayTime');
3790
3791 if cMapName <> ScriptGetString('Map') then
3792 ParseCommand('map ' + ScriptGetString('Map'), true, true);
3793 if ScriptGetString('Theme') <> '' then
3794 ParseCommand('theme ' + ScriptGetString('Theme'), true, true);
3795 LuaGoals:= ScriptGetAnsiString('Goals');
3796
3797 // Support lua changing the ammo layout - assume all hogs have same ammo, note this might leave a few ammo stores lying around.
3798 k:= 0;
3799 if (GameFlags and gfSharedAmmo) <> 0 then
3800 for i:= 0 to Pred(ClansCount) do
3801 for j:= 0 to Pred(ClansArray[i]^.TeamsNumber) do
3802 for k:= 0 to Pred(ClansArray[i]^.Teams[j]^.HedgehogsNumber) do
3803 ClansArray[i]^.Teams[j]^.Hedgehogs[k].AmmoStore:= i
3804 else if (GameFlags and gfPerHogAmmo) <> 0 then
3805 for i:= 0 to Pred(TeamsCount) do
3806 for j:= 0 to Pred(TeamsArray[i]^.HedgehogsNumber) do
3807 begin
3808 TeamsArray[i]^.Hedgehogs[j].AmmoStore:= k;
3809 if StoreCnt-1 < k then AddAmmoStore;
3810 inc(k)
3811 end
3812 else
3813 for i:= 0 to Pred(TeamsCount) do
3814 begin
3815 for j:= 0 to Pred(TeamsArray[i]^.HedgehogsNumber) do
3816 TeamsArray[i]^.Hedgehogs[j].AmmoStore:= k;
3817 if StoreCnt-1 < k then AddAmmoStore;
3818 inc(k)
3819 end;
3820 if ScriptExists('onAmmoStoreInit') or ScriptExists('onNewAmmoStore') then
3821 begin
3822 // reset ammostore (quite unclean, but works?)
3823 uAmmos.freeModule;
3824 uAmmos.initModule;
3825 if ScriptExists('onAmmoStoreInit') then
3826 begin
3827 ScriptPrepareAmmoStore;
3828 ScriptCall('onAmmoStoreInit');
3829 SetAmmoLoadout(ScriptAmmoLoadout);
3830 SetAmmoProbability(ScriptAmmoProbability);
3831 SetAmmoDelay(ScriptAmmoDelay);
3832 SetAmmoReinforcement(ScriptAmmoReinforcement)
3833 end;
3834 ScriptApplyAmmoStore
3835 end;
3836
3837 ScriptSetInteger('ClansCount', ClansCount);
3838 ScriptSetInteger('TeamsCount', TeamsCount);
3839 end;
3840
3841
3842 // Update values of screen dimensions and allow script to react to resolution change
3843 procedure ScriptOnScreenResize();
3844 begin
3845 ScriptSetInteger('ScreenHeight', cScreenHeight);
3846 ScriptSetInteger('ScreenWidth', cScreenWidth);
3847 ScriptCall('onScreenResize');
3848 end;
3849
3850 // custom script loader via physfs, passed to lua_load
3851 const BUFSIZE = 1024;
3852
3853 var inComment: boolean;
3854 var inQuote: boolean;
3855 var locSum: LongWord;
3856 var braceCount: LongWord;
3857 var wordCount: LongWord;
3858 var lastChar: char;
ScriptReadernull3859 function ScriptReader(L: Plua_State; f: PFSFile; sz: Psize_t) : PChar; Cdecl;
3860 var mybuf: PChar;
3861 i: LongInt;
3862 begin
3863 SetRandomSeed(cSeed,true);
3864 mybuf := physfsReader(L, f, sz);
3865 if (mybuf <> nil) and ((sz^) > 0) then
3866 begin
3867 for i:= 0 to sz^-1 do
3868 begin
3869 if (lastChar = '-') and (mybuf[i] = '-') then
3870 inComment := true
3871 else if not inComment and (byte(mybuf[i]) > $20) and (byte(mybuf[i]) < $7F) and (mybuf[i]<>'-') then
3872 begin
3873 AddRandomness(byte(mybuf[i])); // wish I had the seed...
3874 CheckSum := CheckSum xor GetRandom($FFFFFFFF);
3875 end;
3876 lastChar := mybuf[i];
3877 // lua apparently allows -- [===============[ as a valid block comment start.
3878 // I can't be bothered to check for that nonsense. Will allow limited single line without [
3879 if (byte(mybuf[i]) = $0D) or (byte(mybuf[i]) = $0A) or (mybuf[i] = '[') then
3880 inComment := false
3881 end;
3882 end;
3883 ScriptReader:= mybuf
3884 end;
3885 function ScriptLocaleReader(L: Plua_State; f: PFSFile; sz: Psize_t) : PChar; Cdecl;
3886 var mybuf: PChar;
3887 i: LongInt;
3888 begin
3889 mybuf := physfsReader(L, f, sz);
3890 if (mybuf <> nil) and ((sz^) > 0) then
3891 begin
3892 for i:= 0 to sz^-1 do
3893 begin
3894 if not inComment and (mybuf[i] = '"') and (lastChar <> '\') then
3895 inQuote := not inQuote;
3896 if not inQuote and (lastChar = '-') and (mybuf[i] = '-') then
3897 inComment := true;
3898 if not inComment and (not inQuote) then
3899 locSum := locSum xor (byte(mybuf[i]) shl (i mod 4));
3900 if not inComment and (not inQuote) and
3901 ((mybuf[i] = '(') or
3902 (mybuf[i] = ')') or
3903 (mybuf[i] = '+') or
3904 (mybuf[i] = '#') or
3905 (braceCount > 2) or
3906 (wordCount > 6)) then
3907 CheckSum := locSum;
3908 if not inComment and (not inQuote) and ((mybuf[i] = '{') or (mybuf[i] = '}')) then
3909 inc(braceCount);
3910 if not inComment and (not inQuote) and
3911 (((byte(mybuf[i]) > $40) and (byte(mybuf[i]) < $5B)) or
3912 ((byte(mybuf[i]) > $60) and (byte(mybuf[i]) < $7B)) or
3913 ((byte(mybuf[i]) >= $30) and (byte(mybuf[i]) < $3A))) then
3914 inc(wordCount);
3915 lastChar := mybuf[i];
3916 // this allows at least supporting the commented strings at end of line with lua script names
3917 if (byte(mybuf[i]) = $0D) or (byte(mybuf[i]) = $0A) or (mybuf[i] = '[') then
3918 inComment := false
3919 end;
3920 end;
3921 ScriptLocaleReader:= mybuf
3922 end;
3923
3924 function ScriptLoad(name : shortstring; mustExist : boolean): boolean;
3925 var ret : LongInt;
3926 s : shortstring;
3927 f : PFSFile;
3928 buf : array[0..Pred(BUFSIZE)] of byte;
3929 begin
3930 inComment:= false;
3931 inQuote:= false;
3932 lastChar:= 'X';
3933 braceCount:= 0;
3934 wordCount:= 0;
3935 locSum:= 0;
3936 s:= cPathz[ptData] + name;
3937 if not pfsExists(s) then
3938 begin
3939 if mustExist then
3940 OutError('Script not found: ' + name, true)
3941 else
3942 AddFileLog('[LUA] Script not found: ' + name);
3943 ScriptLoad:= false;
3944 exit;
3945 end;
3946
3947 f:= pfsOpenRead(s);
3948 if f = nil then
3949 OutError('Error reading script: ' + name, true);
3950
3951 hedgewarsMountPackage(Str2PChar(copy(s, 3, length(s)-6)+'.hwp'));
3952
3953 physfsReaderSetBuffer(@buf);
3954 if (Pos('Locale/',s) <> 0) or (s = 'Scripts/OfficialChallengeHashes.lua') then
3955 ret:= lua_load(luaState, @ScriptLocaleReader, f, Str2PChar(s))
3956 else
3957 begin
3958 SetRandomSeed(cSeed,true);
3959 ret:= lua_load(luaState, @ScriptReader, f, Str2PChar(s))
3960 end;
3961 pfsClose(f);
3962
3963 if ret <> 0 then
3964 begin
3965 LuaError('Failed to load ' + name + '(error ' + IntToStr(ret) + ')');
3966 LuaError(lua_tostring(luaState, -1));
3967 ScriptLoad:= false;
3968 end
3969 else
3970 begin
3971 WriteLnToConsole('Lua: ' + name + ' loaded');
3972 // call the script file
3973 lua_pcall(luaState, 0, 0, 0);
3974 ScriptLoaded:= true;
3975 ScriptLoad:= true;
3976 end;
3977 end;
3978
3979 procedure SetGlobals;
3980 var x, y: LongInt;
3981 begin
3982 ScriptSetInteger('TurnTimeLeft', TurnTimeLeft);
3983 ScriptSetInteger('ReadyTimeLeft', ReadyTimeLeft);
3984 ScriptSetInteger('GameTime', GameTicks);
3985 ScriptSetInteger('TotalRounds', TotalRoundsReal);
3986 ScriptSetInteger('WaterLine', cWaterLine);
3987 if isCursorVisible and (not bShowAmmoMenu) then
3988 begin
3989 x:= CursorPoint.X - WorldDx;
3990 y:= cScreenHeight - CursorPoint.Y - WorldDy;
3991 if (PrevCursorX <> x) or
3992 (PrevCursorY <> y) then
3993 begin
3994 ScriptSetInteger('CursorX', x);
3995 ScriptSetInteger('CursorY', y);
3996 PrevCursorX:= x;
3997 PrevCursorY:= y;
3998 end
3999 end
4000 else
4001 begin
4002 ScriptSetInteger('CursorX', NoPointX);
4003 ScriptSetInteger('CursorY', NoPointX);
4004 PrevCursorX:= NoPointX;
4005 PrevCursorY:= NoPointX
4006 end;
4007
4008 if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) then
4009 ScriptSetInteger('CurrentHedgehog', CurrentHedgehog^.Gear^.UID)
4010 else
4011 ScriptSetNil('CurrentHedgehog');
4012 end;
4013
4014 procedure ScriptSetMapGlobals;
4015 begin
4016 ScriptSetInteger('LAND_WIDTH', LAND_WIDTH);
4017 ScriptSetInteger('LAND_HEIGHT', LAND_HEIGHT);
4018 ScriptSetInteger('LeftX', leftX);
4019 ScriptSetInteger('RightX', rightX);
4020 ScriptSetInteger('TopY', topY);
4021 end;
4022
4023 procedure GetGlobals;
4024 var currentTTL, currentRTL, newTTL, newRTL: LongInt;
4025 begin
4026 // Setting TurnTimeLeft and ReadyTimeLeft should now be done in the setter functions.
4027 // SetTurnTimeLeft and SetReadTimeLeft.
4028 // GetGloals should be removed in a future release.
4029
4030 // DEPRECATED: Read TurnTimeLeft and ReadyTimeLeft from script directly.
4031 // TODO: Remove this behaviour in a future version.
4032 currentTTL:= TurnTimeLeft;
4033 currentRTL:= ReadyTimeLeft;
4034 newTTL:= ScriptGetInteger('TurnTimeLeft');
4035 newRTL:= ScriptGetInteger('ReadyTimeLeft');
4036 if (currentTTL <> newTTL) and (not isPendingTurnTimeLeft) then
4037 begin
4038 TurnTimeLeft:= newTTL;
4039 LuaWarning('Writing to TurnTimeLeft directly is deprecated! Use SetTurnTimeLeft instead!');
4040 end;
4041
4042 if (currentRTL <> newRTL) and (not isPendingReadyTimeLeft) then
4043 begin
4044 ReadyTimeLeft:= newRTL;
4045 LuaWarning('Writing to ReadyTimeLeft directly is deprecated! Use SetReadyTimeLeft instead!');
4046 end;
4047
4048 // Set TurnTimeLeft and ReadyTimeLeft if activated by SetTurnTimeLeft and SetReadyTimeLeft before
4049 if isPendingTurnTimeLeft then
4050 begin
4051 TurnTimeLeft:= PendingTurnTimeLeft;
4052 ScriptSetInteger('TurnTimeLeft', TurnTimeLeft);
4053 isPendingTurnTimeLeft:= false;
4054 end;
4055 if isPendingReadyTimeLeft then
4056 begin
4057 ReadyTimeLeft:= PendingReadyTimeLeft;
4058 ScriptSetInteger('ReadyTimeLeft', ReadyTimeLeft);
4059 isPendingReadyTimeLeft:= false;
4060 end;
4061 end;
4062
4063 procedure ScriptCall(fname : shortstring);
4064 begin
4065 if (not ScriptLoaded) or (not ScriptExists(fname)) then
4066 exit;
4067 SetGlobals;
4068 lua_getglobal(luaState, Str2PChar(fname));
4069 if lua_pcall(luaState, 0, 0, 0) <> 0 then
4070 begin
4071 LuaError('Error while calling ' + fname + ': ' + lua_tostring(luaState, -1));
4072 lua_pop(luaState, 1)
4073 end;
4074 GetGlobals;
4075 end;
4076
4077 (*
4078 function ParseCommandOverride(key, value : shortstring) : shortstring;
4079 begin
4080 ParseCommandOverride:= value;
4081 if not ScriptExists('ParseCommandOverride') then
4082 exit;
4083 lua_getglobal(luaState, Str2PChar('ParseCommandOverride'));
4084 lua_pushstring(luaState, Str2PChar(key));
4085 lua_pushstring(luaState, Str2PChar(value));
4086 if lua_pcall(luaState, 2, 1, 0) <> 0 then
4087 begin
4088 LuaError('Lua: Error while calling ParseCommandOverride: ' + lua_tostring(luaState, -1));
4089 lua_pop(luaState, 1)
4090 end
4091 else
4092 begin
4093 ParseCommandOverride:= lua_tostring(luaState, -1);
4094 lua_pop(luaState, 1)
4095 end;
4096 end;
4097 *)
4098
4099 function ScriptCall(fname : shortstring; par1: LongInt) : LongInt;
4100 begin
4101 ScriptCall:= ScriptCall(fname, par1, 0, 0, 0)
4102 end;
4103
4104 function ScriptCall(fname : shortstring; par1, par2: LongInt) : LongInt;
4105 begin
4106 ScriptCall:= ScriptCall(fname, par1, par2, 0, 0)
4107 end;
4108
4109 function ScriptCall(fname : shortstring; par1, par2, par3: LongInt) : LongInt;
4110 begin
4111 ScriptCall:= ScriptCall(fname, par1, par2, par3, 0)
4112 end;
4113
4114 function ScriptCall(fname : shortstring; par1, par2, par3, par4 : LongInt) : LongInt;
4115 begin
4116 if (not ScriptLoaded) or (not ScriptExists(fname)) then
4117 exit(0);
4118 SetGlobals;
4119 lua_getglobal(luaState, Str2PChar(fname));
4120 lua_pushnumber(luaState, par1);
4121 lua_pushnumber(luaState, par2);
4122 lua_pushnumber(luaState, par3);
4123 lua_pushnumber(luaState, par4);
4124 ScriptCall:= 0;
4125 if lua_pcall(luaState, 4, 1, 0) <> 0 then
4126 begin
4127 LuaError('Error while calling ' + fname + ': ' + lua_tostring(luaState, -1));
4128 lua_pop(luaState, 1)
4129 end
4130 else
4131 begin
4132 ScriptCall:= Trunc(lua_tonumber(luaState, -1));
4133 lua_pop(luaState, 1)
4134 end;
4135 GetGlobals;
4136 end;
4137
4138 function ScriptExists(fname : shortstring) : boolean;
4139 begin
4140 if not ScriptLoaded then
4141 begin
4142 ScriptExists:= false;
4143 exit
4144 end;
4145 lua_getglobal(luaState, Str2PChar(fname));
4146 ScriptExists:= not lua_isnoneornil(luaState, -1);
4147 lua_pop(luaState, 1)
4148 end;
4149
4150 procedure ScriptPrepareAmmoStore;
4151 var i: ShortInt;
4152 begin
4153 ScriptAmmoLoadout:= '';
4154 ScriptAmmoDelay:= '';
4155 ScriptAmmoProbability:= '';
4156 ScriptAmmoReinforcement:= '';
4157 for i:=1 to ord(High(TAmmoType)) do
4158 begin
4159 ScriptAmmoLoadout:= ScriptAmmoLoadout + '0';
4160 ScriptAmmoProbability:= ScriptAmmoProbability + '0';
4161 ScriptAmmoDelay:= ScriptAmmoDelay + '0';
4162 ScriptAmmoReinforcement:= ScriptAmmoReinforcement + '0';
4163 end;
4164 end;
4165
4166 procedure ScriptSetAmmo(ammo : TAmmoType; count, probability, delay, reinforcement: Byte);
4167 begin
4168 //if (ord(ammo) < 1) or (count > 9) or (count < 0) or (probability < 0) or (probability > 8) or (delay < 0) or (delay > 9) or (reinforcement < 0) or (reinforcement > 8) then
4169 if (ord(ammo) < 1) or (count > 9) or (probability > 8) or (delay > 9) or (reinforcement > 8) then
4170 exit;
4171 ScriptAmmoLoadout[ord(ammo)]:= inttostr(count)[1];
4172 ScriptAmmoProbability[ord(ammo)]:= inttostr(probability)[1];
4173 ScriptSetAmmoDelay(ammo, delay);
4174 ScriptAmmoReinforcement[ord(ammo)]:= inttostr(reinforcement)[1];
4175 end;
4176
4177 procedure ScriptSetAmmoDelay(ammo : TAmmoType; delay: LongWord);
4178 begin
4179 // change loadout string if ammo store has not been initialized yet
4180 if (StoreCnt = 0) then
4181 begin
4182 if (delay <= 9) then
4183 ScriptAmmoDelay[ord(ammo)]:= inttostr(delay)[1];
4184 end
4185 // change 'live' delay values
4186 else if (CurrentTeam <> nil) then
4187 begin
4188 ammoz[ammo].SkipTurns:= CurrentTeam^.Clan^.TurnNumber + delay;
4189 if ammoz[ammo].SkipTurns > 0 then
4190 dec(ammoz[ammo].SkipTurns);
4191 AmmoMenuInvalidated:= true;
4192 end;
4193 end;
4194
4195 procedure ScriptApplyAmmoStore;
4196 var i, j, k : LongInt;
4197 begin
4198 if (GameFlags and gfSharedAmmo) <> 0 then
4199 for i:= 0 to Pred(ClansCount) do
4200 begin
4201 if ScriptExists('onNewAmmoStore') then
4202 begin
4203 ScriptPrepareAmmoStore;
4204 ScriptCall('onNewAmmoStore',i,-1);
4205 SetAmmoLoadout(ScriptAmmoLoadout);
4206 SetAmmoProbability(ScriptAmmoProbability);
4207 SetAmmoDelay(ScriptAmmoDelay);
4208 SetAmmoReinforcement(ScriptAmmoReinforcement)
4209 end;
4210 AddAmmoStore;
4211 for j:= 0 to Pred(ClansArray[i]^.TeamsNumber) do
4212 for k:= 0 to Pred(ClansArray[i]^.Teams[j]^.HedgehogsNumber) do
4213 ClansArray[i]^.Teams[j]^.Hedgehogs[k].AmmoStore:= StoreCnt - 1
4214 end
4215 else if (GameFlags and gfPerHogAmmo) <> 0 then
4216 for i:= 0 to Pred(TeamsCount) do
4217 for j:= 0 to Pred(TeamsArray[i]^.HedgehogsNumber) do
4218 begin
4219 if ScriptExists('onNewAmmoStore') then
4220 begin
4221 ScriptPrepareAmmoStore;
4222 ScriptCall('onNewAmmoStore',i,j);
4223 SetAmmoLoadout(ScriptAmmoLoadout);
4224 SetAmmoProbability(ScriptAmmoProbability);
4225 SetAmmoDelay(ScriptAmmoDelay);
4226 SetAmmoReinforcement(ScriptAmmoReinforcement)
4227 end;
4228 AddAmmoStore;
4229 TeamsArray[i]^.Hedgehogs[j].AmmoStore:= StoreCnt - 1
4230 end
4231 else
4232 for i:= 0 to Pred(TeamsCount) do
4233 begin
4234 if ScriptExists('onNewAmmoStore') then
4235 begin
4236 ScriptPrepareAmmoStore;
4237 ScriptCall('onNewAmmoStore',i,-1);
4238 SetAmmoLoadout(ScriptAmmoLoadout);
4239 SetAmmoProbability(ScriptAmmoProbability);
4240 SetAmmoDelay(ScriptAmmoDelay);
4241 SetAmmoReinforcement(ScriptAmmoReinforcement)
4242 end;
4243 AddAmmoStore;
4244 for j:= 0 to Pred(TeamsArray[i]^.HedgehogsNumber) do
4245 TeamsArray[i]^.Hedgehogs[j].AmmoStore:= StoreCnt - 1
4246 end
4247 end;
4248
4249 procedure initModule;
4250 var at : TGearType;
4251 vgt: TVisualGearType;
4252 am : TAmmoType;
4253 si : TStatInfoType;
4254 st : TSound;
4255 he : THogEffect;
4256 cg : TCapGroup;
4257 spr: TSprite;
4258 mg : TMapGen;
4259 we : TWorldEdge;
4260 begin
4261 // initialize lua
4262 luaState:= lua_open;
4263 if checkFails(luaState <> nil, 'lua_open failed', true) then exit;
4264
4265 // open internal libraries
4266 luaopen_base(luaState);
4267 luaopen_string(luaState);
4268 luaopen_math(luaState);
4269 luaopen_table(luaState);
4270
4271 // import some variables
4272 ScriptSetString(_S'LOCALE', cLanguage);
4273
4274 {$IFDEF USE_TOUCH_INTERFACE}
4275 ScriptSetString(_S'INTERFACE', 'touch');
4276 {$ELSE}
4277 ScriptSetString(_S'INTERFACE', 'desktop');
4278 {$ENDIF}
4279
4280 // Add aliases for amDuck and gtDuck because rubber duck was removed.
4281 // amDuck and gtDuck are deprecated and should be removed later.
4282 // TODO: Remove these aliases in a later version.
4283 ScriptSetInteger('amDuck', Ord(amCreeper));
4284 ScriptSetInteger('gtDuck', Ord(gtCreeper));
4285
4286 // import game flags
4287 ScriptSetInteger('gfSwitchHog', gfSwitchHog);
4288 ScriptSetInteger('gfMultiWeapon', gfMultiWeapon);
4289 ScriptSetInteger('gfSolidLand', gfSolidLand);
4290 ScriptSetInteger('gfBorder', gfBorder);
4291 ScriptSetInteger('gfBottomBorder', gfBottomBorder);
4292 ScriptSetInteger('gfDivideTeams', gfDivideTeams);
4293 ScriptSetInteger('gfLowGravity', gfLowGravity);
4294 ScriptSetInteger('gfLaserSight', gfLaserSight);
4295 ScriptSetInteger('gfInvulnerable', gfInvulnerable);
4296 ScriptSetInteger('gfResetHealth', gfResetHealth);
4297 ScriptSetInteger('gfVampiric', gfVampiric);
4298 ScriptSetInteger('gfKarma', gfKarma);
4299 ScriptSetInteger('gfArtillery', gfArtillery);
4300 ScriptSetInteger('gfOneClanMode', gfOneClanMode);
4301 ScriptSetInteger('gfRandomOrder', gfRandomOrder);
4302 ScriptSetInteger('gfKing', gfKing);
4303 ScriptSetInteger('gfPlaceHog', gfPlaceHog);
4304 ScriptSetInteger('gfSharedAmmo', gfSharedAmmo);
4305 ScriptSetInteger('gfDisableGirders', gfDisableGirders);
4306 ScriptSetInteger('gfDisableLandObjects', gfDisableLandObjects);
4307 ScriptSetInteger('gfAISurvival', gfAISurvival);
4308 ScriptSetInteger('gfInfAttack', gfInfAttack);
4309 ScriptSetInteger('gfResetWeps', gfResetWeps);
4310 ScriptSetInteger('gfPerHogAmmo', gfPerHogAmmo);
4311 ScriptSetInteger('gfDisableWind', gfDisableWind);
4312 ScriptSetInteger('gfMoreWind', gfMoreWind);
4313 ScriptSetInteger('gfTagTeam', gfTagTeam);
4314 ScriptSetInteger('gfShoppaBorder', gfShoppaBorder);
4315
4316 ScriptSetInteger('gmLeft', gmLeft);
4317 ScriptSetInteger('gmRight', gmRight);
4318 ScriptSetInteger('gmUp', gmUp);
4319 ScriptSetInteger('gmDown', gmDown);
4320 ScriptSetInteger('gmSwitch', gmSwitch);
4321 ScriptSetInteger('gmAttack', gmAttack);
4322 ScriptSetInteger('gmLJump', gmLJump);
4323 ScriptSetInteger('gmHJump', gmHJump);
4324 ScriptSetInteger('gmDestroy', gmDestroy);
4325 ScriptSetInteger('gmSlot', gmSlot);
4326 ScriptSetInteger('gmWeapon', gmWeapon);
4327 ScriptSetInteger('gmTimer', gmTimer);
4328 ScriptSetInteger('gmAnimate', gmAnimate);
4329 ScriptSetInteger('gmPrecise', gmPrecise);
4330 ScriptSetInteger('gmAllStoppable', gmAllStoppable);
4331
4332 // speech bubbles
4333 ScriptSetInteger('SAY_SAY', 1);
4334 ScriptSetInteger('SAY_THINK', 2);
4335 ScriptSetInteger('SAY_SHOUT', 3);
4336
4337 // other
4338 ScriptSetInteger('AMMO_INFINITE', AMMO_INFINITE);
4339 ScriptSetInteger('JETPACK_FUEL_INFINITE', JETPACK_FUEL_INFINITE);
4340 ScriptSetInteger('BIRDY_ENERGY_INFINITE', BIRDY_ENERGY_INFINITE);
4341 ScriptSetInteger('NO_CURSOR', NoPointX);
4342 ScriptSetInteger('MAX_HOG_HEALTH', cMaxHogHealth);
4343 ScriptSetInteger('MAX_TURN_TIME', cMaxTurnTime);
4344
4345 // register gear types
4346 for at:= Low(TGearType) to High(TGearType) do
4347 ScriptSetInteger(EnumToStr(at), ord(at));
4348
4349 for vgt:= Low(TVisualGearType) to High(TVisualGearType) do
4350 ScriptSetInteger(EnumToStr(vgt), ord(vgt));
4351
4352 // register sounds
4353 for st:= Low(TSound) to High(TSound) do
4354 ScriptSetInteger(EnumToStr(st), ord(st));
4355
4356 // register ammo types
4357 for am:= Low(TAmmoType) to High(TAmmoType) do
4358 ScriptSetInteger(EnumToStr(am), ord(am));
4359
4360 for si:= Low(TStatInfoType) to High(TStatInfoType) do
4361 ScriptSetInteger(EnumToStr(si), ord(si));
4362
4363 for he:= Low(THogEffect) to High(THogEffect) do
4364 ScriptSetInteger(EnumToStr(he), ord(he));
4365
4366 for cg:= Low(TCapGroup) to High(TCapGroup) do
4367 ScriptSetInteger(EnumToStr(cg), ord(cg));
4368
4369 for spr:= Low(TSprite) to High(TSprite) do
4370 ScriptSetInteger(EnumToStr(spr), ord(spr));
4371
4372 for mg:= Low(TMapGen) to High(TMapGen) do
4373 ScriptSetInteger(EnumToStr(mg), ord(mg));
4374
4375 for we:= Low(TWorldEdge) to High(TWorldEdge) do
4376 ScriptSetInteger(EnumToStr(we), ord(we));
4377
4378 ScriptSetLongWord('capcolDefault' , capcolDefaultLua);
4379 ScriptSetLongWord('capcolSetting' , capcolSettingLua);
4380
4381 ScriptSetInteger('gstDrowning' , gstDrowning);
4382 ScriptSetInteger('gstHHDriven' , gstHHDriven);
4383 ScriptSetInteger('gstMoving' , gstMoving);
4384 ScriptSetInteger('gstAttacked' , gstAttacked);
4385 ScriptSetInteger('gstAttacking' , gstAttacking);
4386 ScriptSetInteger('gstCollision' , gstCollision);
4387 ScriptSetInteger('gstChooseTarget' , gstChooseTarget);
4388 ScriptSetInteger('gstHHJumping' , gstHHJumping);
4389 ScriptSetInteger('gsttmpFlag' , gsttmpFlag);
4390 ScriptSetInteger('gstHHThinking' , gstHHThinking);
4391 ScriptSetInteger('gstNoDamage' , gstNoDamage);
4392 ScriptSetInteger('gstHHHJump' , gstHHHJump);
4393 ScriptSetInteger('gstAnimation' , gstAnimation);
4394 ScriptSetInteger('gstHHDeath' , gstHHDeath);
4395 ScriptSetInteger('gstWinner' , gstWinner);
4396 ScriptSetInteger('gstWait' , gstWait);
4397 ScriptSetInteger('gstNotKickable' , gstNotKickable);
4398 ScriptSetInteger('gstLoser' , gstLoser);
4399 ScriptSetInteger('gstHHGone' , gstHHGone);
4400 ScriptSetInteger('gstInvisible' , gstInvisible);
4401 ScriptSetInteger('gstSubmersible' , gstSubmersible);
4402 ScriptSetInteger('gstFrozen' , gstFrozen);
4403 ScriptSetInteger('gstNoGravity' , gstNoGravity);
4404
4405 // ai hints
4406 ScriptSetInteger('aihUsualProcessing', aihUsualProcessing);
4407 ScriptSetInteger('aihDoesntMatter' , aihDoesntMatter);
4408
4409 // land flags (partial)
4410 ScriptSetInteger('lfIndestructible', lfIndestructible);
4411 ScriptSetInteger('lfIce' , lfIce);
4412 ScriptSetInteger('lfBouncy' , lfBouncy);
4413
4414 ScriptSetInteger('lfLandMask' , lfLandMask);
4415 ScriptSetInteger('lfCurHogCrate' , lfCurHogCrate);
4416 ScriptSetInteger('lfHHMask' , lfHHMask);
4417 ScriptSetInteger('lfNotHHObjMask' , lfNotHHObjMask);
4418 ScriptSetInteger('lfAllObjMask' , lfAllObjMask);
4419
4420 // explosion constants
4421 ScriptSetInteger('EXPLAutoSound' , EXPLAutoSound);
4422 ScriptSetInteger('EXPLNoDamage' , EXPLNoDamage);
4423 ScriptSetInteger('EXPLDoNotTouchHH' , EXPLDoNotTouchHH);
4424 ScriptSetInteger('EXPLDontDraw' , EXPLDontDraw);
4425 ScriptSetInteger('EXPLNoGfx' , EXPLNoGfx);
4426 ScriptSetInteger('EXPLPoisoned' , EXPLPoisoned);
4427 ScriptSetInteger('EXPLDoNotTouchAny', EXPLDoNotTouchAny);
4428 ScriptSetInteger('EXPLForceDraw' , EXPLForceDraw);
4429
4430 // register functions
4431 lua_register(luaState, _P'HideHog', @lc_hidehog);
4432 lua_register(luaState, _P'RestoreHog', @lc_restorehog);
4433 lua_register(luaState, _P'IsHogHidden', @lc_ishoghidden);
4434 lua_register(luaState, _P'SaveCampaignVar', @lc_savecampaignvar);
4435 lua_register(luaState, _P'GetCampaignVar', @lc_getcampaignvar);
4436 lua_register(luaState, _P'SaveMissionVar', @lc_savemissionvar);
4437 lua_register(luaState, _P'GetMissionVar', @lc_getmissionvar);
4438 lua_register(luaState, _P'band', @lc_band);
4439 lua_register(luaState, _P'bor', @lc_bor);
4440 lua_register(luaState, _P'bnot', @lc_bnot);
4441 lua_register(luaState, _P'div', @lc_div);
4442 lua_register(luaState, _P'GetInputMask', @lc_getinputmask);
4443 lua_register(luaState, _P'SetInputMask', @lc_setinputmask);
4444 lua_register(luaState, _P'AddGear', @lc_addgear);
4445 lua_register(luaState, _P'DismissTeam', @lc_dismissteam);
4446 lua_register(luaState, _P'EnableGameFlags', @lc_enablegameflags);
4447 lua_register(luaState, _P'DisableGameFlags', @lc_disablegameflags);
4448 lua_register(luaState, _P'ClearGameFlags', @lc_cleargameflags);
4449 lua_register(luaState, _P'GetGameFlag', @lc_getgameflag);
4450 lua_register(luaState, _P'DeleteGear', @lc_deletegear);
4451 lua_register(luaState, _P'AddVisualGear', @lc_addvisualgear);
4452 lua_register(luaState, _P'DeleteVisualGear', @lc_deletevisualgear);
4453 lua_register(luaState, _P'GetVisualGearType', @lc_getvisualgeartype);
4454 lua_register(luaState, _P'GetVisualGearValues', @lc_getvisualgearvalues);
4455 lua_register(luaState, _P'SetVisualGearValues', @lc_setvisualgearvalues);
4456 lua_register(luaState, _P'GetGearValues', @lc_getgearvalues);
4457 lua_register(luaState, _P'SetGearValues', @lc_setgearvalues);
4458 lua_register(luaState, _P'SpawnHealthCrate', @lc_spawnhealthcrate);
4459 lua_register(luaState, _P'SpawnAmmoCrate', @lc_spawnammocrate);
4460 lua_register(luaState, _P'SpawnUtilityCrate', @lc_spawnutilitycrate);
4461 lua_register(luaState, _P'SpawnSupplyCrate', @lc_spawnsupplycrate);
4462 lua_register(luaState, _P'SpawnFakeHealthCrate', @lc_spawnfakehealthcrate);
4463 lua_register(luaState, _P'SpawnFakeAmmoCrate', @lc_spawnfakeammocrate);
4464 lua_register(luaState, _P'SpawnFakeUtilityCrate', @lc_spawnfakeutilitycrate);
4465 lua_register(luaState, _P'WriteLnToConsole', @lc_writelntoconsole);
4466 lua_register(luaState, _P'WriteLnToChat', @lc_writelntochat);
4467 lua_register(luaState, _P'GetGearType', @lc_getgeartype);
4468 lua_register(luaState, _P'EndGame', @lc_endgame);
4469 lua_register(luaState, _P'EndTurn', @lc_endturn);
4470 lua_register(luaState, _P'Retreat', @lc_retreat);
4471 lua_register(luaState, _P'SkipTurn', @lc_skipturn);
4472 lua_register(luaState, _P'GetTeamStats', @lc_getteamstats);
4473 lua_register(luaState, _P'SendStat', @lc_sendstat);
4474 lua_register(luaState, _P'SendGameResultOff', @lc_sendgameresultoff);
4475 lua_register(luaState, _P'SendRankingStatsOff', @lc_sendrankingstatsoff);
4476 lua_register(luaState, _P'SendAchievementsStatsOff', @lc_sendachievementsstatsoff);
4477 lua_register(luaState, _P'SendHealthStatsOff', @lc_sendhealthstatsoff);
4478 lua_register(luaState, _P'FindPlace', @lc_findplace);
4479 lua_register(luaState, _P'SetGearPosition', @lc_setgearposition);
4480 lua_register(luaState, _P'GetGearPosition', @lc_getgearposition);
4481 lua_register(luaState, _P'SetGearTarget', @lc_setgeartarget);
4482 lua_register(luaState, _P'GetGearTarget', @lc_getgeartarget);
4483 lua_register(luaState, _P'SetGearVelocity', @lc_setgearvelocity);
4484 lua_register(luaState, _P'GetGearVelocity', @lc_getgearvelocity);
4485 lua_register(luaState, _P'ParseCommand', @lc_parsecommand);
4486 lua_register(luaState, _P'ShowMission', @lc_showmission);
4487 lua_register(luaState, _P'HideMission', @lc_hidemission);
4488 lua_register(luaState, _P'SetAmmoTexts', @lc_setammotexts);
4489 lua_register(luaState, _P'SetAmmoDescriptionAppendix', @lc_setammodescriptionappendix);
4490 lua_register(luaState, _P'AddCaption', @lc_addcaption);
4491 lua_register(luaState, _P'SetAmmo', @lc_setammo);
4492 lua_register(luaState, _P'GetAmmo', @lc_getammo);
4493 lua_register(luaState, _P'SetAmmoDelay', @lc_setammodelay);
4494 lua_register(luaState, _P'SetAmmoSlot', @lc_setammoslot);
4495 lua_register(luaState, _P'PlaySound', @lc_playsound);
4496 lua_register(luaState, _P'PlayMusicSound', @lc_playmusicsound);
4497 lua_register(luaState, _P'StopMusicSound', @lc_stopmusicsound);
4498 lua_register(luaState, _P'SetSoundMask', @lc_setsoundmask);
4499 lua_register(luaState, _P'GetTeamName', @lc_getteamname);
4500 lua_register(luaState, _P'GetTeamIndex', @lc_getteamindex);
4501 lua_register(luaState, _P'GetTeamClan', @lc_getteamclan);
4502 lua_register(luaState, _P'AddTeam', @lc_addteam);
4503 lua_register(luaState, _P'AddMissionTeam', @lc_addmissionteam);
4504 lua_register(luaState, _P'SetTeamLabel', @lc_setteamlabel);
4505 lua_register(luaState, _P'SetTeamPassive', @lc_setteampassive);
4506 lua_register(luaState, _P'AddHog', @lc_addhog);
4507 lua_register(luaState, _P'AddMissionHog', @lc_addmissionhog);
4508 lua_register(luaState, _P'AddAmmo', @lc_addammo);
4509 lua_register(luaState, _P'GetAmmoCount', @lc_getammocount);
4510 lua_register(luaState, _P'HealHog', @lc_healhog);
4511 lua_register(luaState, _P'SetHealth', @lc_sethealth);
4512 lua_register(luaState, _P'GetHealth', @lc_gethealth);
4513 lua_register(luaState, _P'SetEffect', @lc_seteffect);
4514 lua_register(luaState, _P'GetEffect', @lc_geteffect);
4515 lua_register(luaState, _P'GetHogClan', @lc_gethogclan);
4516 lua_register(luaState, _P'GetClanColor', @lc_getclancolor);
4517 lua_register(luaState, _P'SetClanColor', @lc_setclancolor);
4518 lua_register(luaState, _P'GetHogVoicepack', @lc_gethogvoicepack);
4519 lua_register(luaState, _P'GetHogFlag', @lc_gethogflag);
4520 lua_register(luaState, _P'GetHogFort', @lc_gethogfort);
4521 lua_register(luaState, _P'GetHogGrave', @lc_gethoggrave);
4522 lua_register(luaState, _P'IsHogAlive', @lc_ishogalive);
4523 lua_register(luaState, _P'IsHogLocal', @lc_ishoglocal);
4524 lua_register(luaState, _P'GetHogTeamName', @lc_gethogteamname);
4525 lua_register(luaState, _P'SetHogTeamName', @lc_sethogteamname);
4526 lua_register(luaState, _P'GetHogName', @lc_gethogname);
4527 lua_register(luaState, _P'SetHogName', @lc_sethogname);
4528 lua_register(luaState, _P'GetHogLevel', @lc_gethoglevel);
4529 lua_register(luaState, _P'SetHogLevel', @lc_sethoglevel);
4530 lua_register(luaState, _P'GetX', @lc_getx);
4531 lua_register(luaState, _P'GetY', @lc_gety);
4532 lua_register(luaState, _P'CopyPV', @lc_copypv);
4533 lua_register(luaState, _P'FollowGear', @lc_followgear);
4534 lua_register(luaState, _P'GetFollowGear', @lc_getfollowgear);
4535 lua_register(luaState, _P'SetState', @lc_setstate);
4536 lua_register(luaState, _P'GetState', @lc_getstate);
4537 lua_register(luaState, _P'GetTag', @lc_gettag);
4538 lua_register(luaState, _P'SetTag', @lc_settag);
4539 lua_register(luaState, _P'SetTimer', @lc_settimer);
4540 lua_register(luaState, _P'GetTimer', @lc_gettimer);
4541 lua_register(luaState, _P'SetFlightTime', @lc_setflighttime);
4542 lua_register(luaState, _P'GetFlightTime', @lc_getflighttime);
4543 lua_register(luaState, _P'SetZoom', @lc_setzoom);
4544 lua_register(luaState, _P'GetZoom', @lc_getzoom);
4545 lua_register(luaState, _P'HogSay', @lc_hogsay);
4546 lua_register(luaState, _P'SwitchHog', @lc_switchhog);
4547 lua_register(luaState, _P'EnableSwitchHog', @lc_enableswitchhog);
4548 lua_register(luaState, _P'HogTurnLeft', @lc_hogturnleft);
4549 lua_register(luaState, _P'GetGearElasticity', @lc_getgearelasticity);
4550 lua_register(luaState, _P'SetGearElasticity', @lc_setgearelasticity);
4551 lua_register(luaState, _P'GetGearFriction', @lc_getgearfriction);
4552 lua_register(luaState, _P'SetGearFriction', @lc_setgearfriction);
4553 lua_register(luaState, _P'GetGearRadius', @lc_getgearradius);
4554 lua_register(luaState, _P'GetGearMessage', @lc_getgearmessage);
4555 lua_register(luaState, _P'SetGearMessage', @lc_setgearmessage);
4556 lua_register(luaState, _P'GetGearPos', @lc_getgearpos);
4557 lua_register(luaState, _P'SetGearPos', @lc_setgearpos);
4558 lua_register(luaState, _P'GetGearCollisionMask', @lc_getgearcollisionmask);
4559 lua_register(luaState, _P'SetGearCollisionMask', @lc_setgearcollisionmask);
4560 lua_register(luaState, _P'GetRandom', @lc_getrandom);
4561 lua_register(luaState, _P'SetWind', @lc_setwind);
4562 lua_register(luaState, _P'GetWind', @lc_getwind);
4563 lua_register(luaState, _P'MapHasBorder', @lc_maphasborder);
4564 lua_register(luaState, _P'GetHogHat', @lc_gethoghat);
4565 lua_register(luaState, _P'SetHogHat', @lc_sethoghat);
4566 lua_register(luaState, _P'EraseSprite', @lc_erasesprite);
4567 lua_register(luaState, _P'PlaceSprite', @lc_placesprite);
4568 lua_register(luaState, _P'PlaceGirder', @lc_placegirder);
4569 lua_register(luaState, _P'PlaceRubber', @lc_placerubber);
4570 lua_register(luaState, _P'GetCurAmmoType', @lc_getcurammotype);
4571 lua_register(luaState, _P'TestRectForObstacle', @lc_testrectforobstacle);
4572 lua_register(luaState, _P'GetGravity', @lc_getgravity);
4573 lua_register(luaState, _P'SetGravity', @lc_setgravity);
4574 lua_register(luaState, _P'SetWaterLine', @lc_setwaterline);
4575 lua_register(luaState, _P'SetNextWeapon', @lc_setnextweapon);
4576 lua_register(luaState, _P'SetWeapon', @lc_setweapon);
4577 lua_register(luaState, _P'SetCinematicMode', @lc_setcinematicmode);
4578 lua_register(luaState, _P'SetMaxBuildDistance', @lc_setmaxbuilddistance);
4579 lua_register(luaState, _P'GetAmmoName', @lc_getammoname);
4580 lua_register(luaState, _P'GetAmmoTimer', @lc_getammotimer);
4581 lua_register(luaState, _P'SetVampiric', @lc_setvampiric);
4582 lua_register(luaState, _P'GetVampiric', @lc_getvampiric);
4583 lua_register(luaState, _P'SetLaserSight', @lc_setlasersight);
4584 lua_register(luaState, _P'GetLaserSight', @lc_getlasersight);
4585 lua_register(luaState, _P'Explode', @lc_explode);
4586 lua_register(luaState, _P'SetTurnTimeLeft', @lc_setturntimeleft);
4587 lua_register(luaState, _P'SetReadyTimeLeft', @lc_setreadytimeleft);
4588 lua_register(luaState, _P'SetTurnTimePaused', @lc_setturntimepaused);
4589 lua_register(luaState, _P'GetTurnTimePaused', @lc_getturntimepaused);
4590 // drawn map functions
4591 lua_register(luaState, _P'AddPoint', @lc_addPoint);
4592 lua_register(luaState, _P'FlushPoints', @lc_flushPoints);
4593
4594 lua_register(luaState, _P'SetGearAIHints', @lc_setgearaihints);
4595 lua_register(luaState, _P'HedgewarsScriptLoad', @lc_hedgewarsscriptload);
4596 lua_register(luaState, _P'DeclareAchievement', @lc_declareachievement);
4597 lua_register(luaState, _P'StartGhostPoints', @lc_startghostpoints);
4598 lua_register(luaState, _P'DumpPoint', @lc_dumppoint);
4599
4600 ScriptSetInteger('TEST_SUCCESSFUL' , HaltTestSuccess);
4601 ScriptSetInteger('TEST_FAILED' , HaltTestFailed);
4602 lua_register(luaState, _P'EndLuaTest', @lc_endluatest);
4603
4604 ScriptClearStack; // just to be sure stack is empty
4605 ScriptLoaded:= false;
4606 end;
4607
4608 procedure freeModule;
4609 begin
4610 lua_close(luaState);
4611 end;
4612
4613 {$ELSE}
4614 procedure ScriptPrintStack;
4615 begin
4616 end;
4617
4618 procedure ScriptClearStack;
4619 begin
4620 end;
4621
4622 procedure ScriptLoad(name : shortstring);
4623 begin
4624 name:= name; // avoid hint
4625 end;
4626
4627 procedure ScriptOnGameInit;
4628 begin
4629 end;
4630
4631 procedure ScriptCall(fname : shortstring);
4632 begin
4633 fname:= fname; // avoid hint
4634 end;
4635
4636 function ScriptCall(fname : shortstring; par1, par2, par3, par4 : LongInt) : LongInt;
4637 begin
4638 // avoid hints
4639 fname:= fname;
4640 par1:= par1;
4641 par2:= par2;
4642 par3:= par3;
4643 par4:= par4;
4644 ScriptCall:= 0
4645 end;
4646
4647 function ScriptCall(fname : shortstring; par1: LongInt) : LongInt;
4648 begin
4649 // avoid hints
4650 fname:= fname;
4651 par1:= par1;
4652 ScriptCall:= 0
4653 end;
4654
4655 function ScriptCall(fname : shortstring; par1, par2: LongInt) : LongInt;
4656 begin
4657 // avoid hints
4658 fname:= fname;
4659 par1:= par1;
4660 par2:= par2;
4661 ScriptCall:= 0
4662 end;
4663
4664 function ScriptCall(fname : shortstring; par1, par2, par3: LongInt) : LongInt;
4665 begin
4666 // avoid hints
4667 fname:= fname;
4668 par1:= par1;
4669 par2:= par2;
4670 par3:= par3;
4671 ScriptCall:= 0
4672 end;
4673
4674 function ScriptExists(fname : shortstring) : boolean;
4675 begin
4676 fname:= fname; // avoid hint
4677 ScriptExists:= false
4678 end;
4679 (*
4680 function ParseCommandOverride(key, value : shortstring) : shortstring;
4681 begin
4682 // avoid hints
4683 key:= key;
4684 value:= value;
4685 ParseCommandOverride:= ''
4686 end;
4687 *)
4688
4689 procedure ScriptOnScreenResize;
4690 begin
4691 end;
4692
4693 procedure ScriptOnPreviewInit;
4694 begin
4695 end;
4696
4697 procedure ScriptSetInteger(name : shortstring; value : LongInt);
4698 begin
4699 end;
4700
4701 procedure ScriptSetString(name : shortstring; value : shortstring);
4702 begin
4703 end;
4704
4705 procedure LuaParseString(s : ShortString);
4706 begin
4707 end;
4708
4709 procedure initModule;
4710 begin
4711 PointsBuffer:= '';
4712 PrevCursorX:= NoPointX;
4713 PrevCursorY:= NoPointX;
4714 isPendingTurnTimeLeft:= false;
4715 isPendingReadyTimeLeft:= false;
4716 end;
4717
4718 procedure freeModule;
4719 begin
4720 end;
4721
4722 {$ENDIF}
4723 end.
4724