hedgewars/uScript.pas
branchui-scaling
changeset 15283 c4fd2813b127
parent 15177 a22013a817e4
child 15582 6a38a30e772a
child 15907 1becf4a0e907
equal deleted inserted replaced
13390:0135e64c6c66 15283:c4fd2813b127
    32 interface
    32 interface
    33 
    33 
    34 procedure ScriptPrintStack;
    34 procedure ScriptPrintStack;
    35 procedure ScriptClearStack;
    35 procedure ScriptClearStack;
    36 
    36 
    37 procedure ScriptLoad(name : shortstring);
    37 function ScriptLoad(name : shortstring; mustExist : boolean): boolean;
    38 procedure ScriptOnPreviewInit;
    38 procedure ScriptOnPreviewInit;
    39 procedure ScriptOnGameInit;
    39 procedure ScriptOnGameInit;
    40 procedure ScriptOnScreenResize;
    40 procedure ScriptOnScreenResize;
    41 procedure ScriptSetInteger(name : shortstring; value : LongInt);
    41 procedure ScriptSetInteger(name : shortstring; value : LongInt);
    42 procedure ScriptSetString(name : shortstring; value : shortstring);
    42 procedure ScriptSetString(name : shortstring; value : shortstring);
       
    43 procedure ScriptSetMapGlobals;
    43 
    44 
    44 procedure ScriptCall(fname : shortstring);
    45 procedure ScriptCall(fname : shortstring);
    45 function ScriptCall(fname : shortstring; par1: LongInt) : LongInt;
    46 function ScriptCall(fname : shortstring; par1: LongInt) : LongInt;
    46 function ScriptCall(fname : shortstring; par1, par2: LongInt) : LongInt;
    47 function ScriptCall(fname : shortstring; par1, par2: LongInt) : LongInt;
    47 function ScriptCall(fname : shortstring; par1, par2, par3: LongInt) : LongInt;
    48 function ScriptCall(fname : shortstring; par1, par2, par3: LongInt) : LongInt;
    84     uUtils,
    85     uUtils,
    85     uIO,
    86     uIO,
    86     uVisualGearsList,
    87     uVisualGearsList,
    87     uGearsHandlersMess,
    88     uGearsHandlersMess,
    88     uPhysFSLayer,
    89     uPhysFSLayer,
       
    90     uLocale,
    89     SDLh
    91     SDLh
    90 {$IFNDEF PAS2C}
    92 {$IFNDEF PAS2C}
    91     , typinfo
    93     , typinfo
    92 {$ENDIF}
    94 {$ENDIF}
    93     ;
    95     ;
    96     ScriptAmmoLoadout : shortstring;
    98     ScriptAmmoLoadout : shortstring;
    97     ScriptAmmoProbability : shortstring;
    99     ScriptAmmoProbability : shortstring;
    98     ScriptAmmoDelay : shortstring;
   100     ScriptAmmoDelay : shortstring;
    99     ScriptAmmoReinforcement : shortstring;
   101     ScriptAmmoReinforcement : shortstring;
   100     ScriptLoaded : boolean;
   102     ScriptLoaded : boolean;
   101     mapDims : boolean;
       
   102     PointsBuffer: shortstring;
   103     PointsBuffer: shortstring;
   103     PrevCursorX, PrevCursorY: LongInt;
   104     PrevCursorX, PrevCursorY: LongInt;
       
   105     PendingTurnTimeLeft, PendingReadyTimeLeft: LongWord;
       
   106     isPendingTurnTimeLeft, isPendingReadyTimeLeft: boolean;
   104 
   107 
   105 {$IFDEF USE_LUA_SCRIPT}
   108 {$IFDEF USE_LUA_SCRIPT}
   106 procedure ScriptPrepareAmmoStore; forward;
   109 procedure ScriptPrepareAmmoStore; forward;
   107 procedure ScriptApplyAmmoStore; forward;
   110 procedure ScriptApplyAmmoStore; forward;
   108 procedure ScriptSetAmmo(ammo : TAmmoType; count, probability, delay, reinforcement: Byte); forward;
   111 procedure ScriptSetAmmo(ammo : TAmmoType; count, probability, delay, reinforcement: Byte); forward;
   109 procedure ScriptSetAmmoDelay(ammo : TAmmoType; delay: Byte); forward;
   112 procedure ScriptSetAmmoDelay(ammo : TAmmoType; delay: LongWord); forward;
   110 
   113 
   111 var LuaDebugInfo: lua_Debug;
   114 var LuaDebugInfo: lua_Debug;
   112 
   115 
   113 procedure SetGlobals; forward;
   116 procedure SetGlobals; forward;
       
   117 procedure GetGlobals; forward;
   114 procedure LuaParseString(s: shortString);
   118 procedure LuaParseString(s: shortString);
   115 begin
   119 begin
   116     SetGlobals;
   120     SetGlobals;
   117     AddFileLog('[Lua] input string: ' + s);
   121     AddFileLog('[Lua] input string: ' + s);
   118     AddChatString(#3 + '[Lua] > ' + s);
   122     AddChatString(#3 + '[Lua] > ' + s);
   119     if luaL_dostring(luaState, Str2PChar(s)) <> 0 then
   123     if luaL_dostring(luaState, Str2PChar(s)) <> 0 then
   120         begin
   124         begin
   121         AddFileLog('[Lua] input string parsing error!');
   125         AddFileLog('[Lua] input string parsing error!');
   122         AddChatString(#5 + '[Lua] Error while parsing!');
   126         AddChatString(#5 + '[Lua] Error while parsing!');
   123         end;
   127         end
       
   128     else
       
   129         GetGlobals();
   124 end;
   130 end;
   125 
   131 
   126 function LuaUpdateDebugInfo(): Boolean;
   132 function LuaUpdateDebugInfo(): Boolean;
   127 begin
   133 begin
   128     FillChar(LuaDebugInfo, sizeof(LuaDebugInfo), 0);
   134     FillChar(LuaDebugInfo, sizeof(LuaDebugInfo), 0);
   133     // get source name and line count
   139     // get source name and line count
   134     lua_getinfo(luaState, PChar('Sl'), @LuaDebugInfo);
   140     lua_getinfo(luaState, PChar('Sl'), @LuaDebugInfo);
   135     exit(true);
   141     exit(true);
   136 end;
   142 end;
   137 
   143 
   138 procedure LuaError(s: shortstring);
   144 procedure LuaErrorOrWarning(s: shortstring; isWarning: boolean);
   139 var src: shortstring;
   145 var src, intro: shortstring;
   140 const
   146 const
   141     maxsrclen = 20;
   147     maxsrclen = 20;
   142 begin
   148 begin
       
   149     if isWarning then
       
   150         intro:= 'LUA WARNING'
       
   151     else
       
   152         intro:= 'LUA ERROR';
   143     if LuaUpdateDebugInfo() then
   153     if LuaUpdateDebugInfo() then
   144         begin
   154         begin
   145         src:= StrPas(LuaDebugInfo.source);
   155         src:= StrPas(LuaDebugInfo.source);
   146         s:= 'LUA ERROR [ ... '
   156         s:= intro + ': [ ... '
   147             + copy(src, Length(src) - maxsrclen, maxsrclen - 3) + ':'
   157             + copy(src, Length(src) - maxsrclen, maxsrclen - 3) + ':'
   148             + inttostr(LuaDebugInfo.currentLine) + ']: ' + s;
   158             + inttostr(LuaDebugInfo.currentLine) + ']: ' + s;
   149         end
   159         end
   150     else
   160     else
   151         s:= 'LUA ERROR: ' + s;
   161         s:= intro + ': ' + s;
   152     WriteLnToConsole(s);
   162     WriteLnToConsole(s);
   153     AddChatString(#5 + s);
   163     if isWarning then
   154     if cTestLua then
   164         AddChatString(#0 + s)
       
   165     else
       
   166         AddChatString(#5 + s);
       
   167     if cTestLua and (not isWarning) then
   155         halt(HaltTestLuaError);
   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);
   156 end;
   179 end;
   157 
   180 
   158 procedure LuaCallError(error, call, paramsyntax: shortstring);
   181 procedure LuaCallError(error, call, paramsyntax: shortstring);
   159 begin
   182 begin
   160     LuaError(call + ': ' + error);
   183     LuaError(call + ': ' + error);
   542         end;
   565         end;
   543     lc_setnextweapon:= 0;
   566     lc_setnextweapon:= 0;
   544 end;
   567 end;
   545 
   568 
   546 function lc_showmission(L : Plua_State) : LongInt; Cdecl;
   569 function lc_showmission(L : Plua_State) : LongInt; Cdecl;
   547 begin
   570 var n: LongInt;
   548     if CheckLuaParamCount(L, 5, 'ShowMission', 'caption, subcaption, text, icon, time') then
   571 begin
   549         ShowMission(lua_tostringA(L, 1), lua_tostringA(L, 2), lua_tostringA(L, 3), Trunc(lua_tonumber(L, 4)), Trunc(lua_tonumber(L, 5)));
   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));
   550     lc_showmission:= 0;
   577     lc_showmission:= 0;
   551 end;
   578 end;
   552 
   579 
   553 function lc_hidemission(L : Plua_State) : LongInt; Cdecl;
   580 function lc_hidemission(L : Plua_State) : LongInt; Cdecl;
   554 begin
   581 begin
   558 end;
   585 end;
   559 
   586 
   560 function lc_setammotexts(L : Plua_State) : LongInt; Cdecl;
   587 function lc_setammotexts(L : Plua_State) : LongInt; Cdecl;
   561 const
   588 const
   562     call = 'SetAmmoTexts';
   589     call = 'SetAmmoTexts';
   563     params = 'ammoType, name, caption, description';
   590     params = 'ammoType, name, caption, description [, showExtra]';
   564 begin
   591 var n: integer;
   565     if CheckLuaParamCount(L, 4, call, params) then
   592     showExtra: boolean;
   566         SetAmmoTexts(TAmmoType(LuaToAmmoTypeOrd(L, 1, call, params)), lua_tostringA(L, 2), lua_tostringA(L, 3), lua_tostringA(L, 4));
   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;
   567     lc_setammotexts:= 0;
   602     lc_setammotexts:= 0;
   568 end;
   603 end;
   569 
   604 
   570 function lc_setammodescriptionappendix(L : Plua_State) : LongInt; Cdecl;
   605 function lc_setammodescriptionappendix(L : Plua_State) : LongInt; Cdecl;
   571 const
   606 const
   636     params = 'text [, color, captiongroup]';
   671     params = 'text [, color, captiongroup]';
   637 begin
   672 begin
   638     if CheckAndFetchParamCount(L, 1, 3, call, params, cg) then
   673     if CheckAndFetchParamCount(L, 1, 3, call, params, cg) then
   639         begin
   674         begin
   640         if cg = 1 then
   675         if cg = 1 then
   641             AddCaption(lua_tostringA(L, 1), cWhiteColor, capgrpMessage)
   676             AddCaption(lua_tostringA(L, 1), capcolDefault, capgrpMessage)
   642         else
   677         else
   643             begin
   678             begin
   644             cg:= LuaToCapGroupOrd(L, 3, call, params);
   679             cg:= LuaToCapGroupOrd(L, 3, call, params);
   645             if cg >= 0 then
   680             if cg >= 0 then
   646                 AddCaption(lua_tostringA(L, 1), Trunc(lua_tonumber(L, 2)) shr 8, TCapGroup(cg));
   681                 AddCaption(lua_tostringA(L, 1), Trunc(lua_tonumber(L, 2)) shr 8, TCapGroup(cg));
   649     lc_addcaption:= 0;
   684     lc_addcaption:= 0;
   650 end;
   685 end;
   651 
   686 
   652 function lc_spawnfakehealthcrate(L: Plua_State) : LongInt; Cdecl;
   687 function lc_spawnfakehealthcrate(L: Plua_State) : LongInt; Cdecl;
   653 var gear: PGear;
   688 var gear: PGear;
   654 begin
   689     explode, poison: boolean;
   655     if CheckLuaParamCount(L, 4,'SpawnFakeHealthCrate', 'x, y, explode, poison') then
   690     n: LongInt;
   656         begin
   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 
   657         gear := SpawnFakeCrateAt(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)),
   701         gear := SpawnFakeCrateAt(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)),
   658         HealthCrate, lua_toboolean(L, 3), lua_toboolean(L, 4));
   702         HealthCrate, explode, poison);
   659         if gear <> nil then
   703         if gear <> nil then
   660              lua_pushnumber(L, gear^.uid)
   704              lua_pushnumber(L, gear^.uid)
   661         else lua_pushnil(L)
   705         else lua_pushnil(L)
   662         end
   706         end
   663     else
   707     else
   665     lc_spawnfakehealthcrate := 1;
   709     lc_spawnfakehealthcrate := 1;
   666 end;
   710 end;
   667 
   711 
   668 function lc_spawnfakeammocrate(L: PLua_State): LongInt; Cdecl;
   712 function lc_spawnfakeammocrate(L: PLua_State): LongInt; Cdecl;
   669 var gear: PGear;
   713 var gear: PGear;
   670 begin
   714     explode, poison: boolean;
   671     if CheckLuaParamCount(L, 4,'SpawnFakeAmmoCrate', 'x, y, explode, poison') then
   715     n: LongInt;
   672         begin
   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 
   673         gear := SpawnFakeCrateAt(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)),
   726         gear := SpawnFakeCrateAt(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)),
   674         AmmoCrate, lua_toboolean(L, 3), lua_toboolean(L, 4));
   727         AmmoCrate, explode, poison);
   675         if gear <> nil then
   728         if gear <> nil then
   676              lua_pushnumber(L, gear^.uid)
   729              lua_pushnumber(L, gear^.uid)
   677         else lua_pushnil(L)
   730         else lua_pushnil(L)
   678         end
   731         end
   679     else
   732     else
   681     lc_spawnfakeammocrate := 1;
   734     lc_spawnfakeammocrate := 1;
   682 end;
   735 end;
   683 
   736 
   684 function lc_spawnfakeutilitycrate(L: PLua_State): LongInt; Cdecl;
   737 function lc_spawnfakeutilitycrate(L: PLua_State): LongInt; Cdecl;
   685 var gear: PGear;
   738 var gear: PGear;
   686 begin
   739     explode, poison: boolean;
   687     if CheckLuaParamCount(L, 4,'SpawnFakeUtilityCrate', 'x, y, explode, poison') then
   740     n: LongInt;
   688         begin
   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 
   689         gear := SpawnFakeCrateAt(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)),
   751         gear := SpawnFakeCrateAt(Trunc(lua_tonumber(L, 1)), Trunc(lua_tonumber(L, 2)),
   690         UtilityCrate, lua_toboolean(L, 3), lua_toboolean(L, 4));
   752         UtilityCrate, explode, poison);
   691         if gear <> nil then
   753         if gear <> nil then
   692              lua_pushnumber(L, gear^.uid)
   754              lua_pushnumber(L, gear^.uid)
   693         else lua_pushnil(L)
   755         else lua_pushnil(L)
   694         end
   756         end
   695     else
   757     else
   917             lua_pushnumber(L, vg^.Frame);
   979             lua_pushnumber(L, vg^.Frame);
   918             lua_pushnumber(L, vg^.FrameTicks);
   980             lua_pushnumber(L, vg^.FrameTicks);
   919             lua_pushnumber(L, vg^.State);
   981             lua_pushnumber(L, vg^.State);
   920             lua_pushnumber(L, vg^.Timer);
   982             lua_pushnumber(L, vg^.Timer);
   921             lua_pushnumber(L, vg^.Tint);
   983             lua_pushnumber(L, vg^.Tint);
       
   984             lua_pushnumber(L, vg^.Scale);
   922             end
   985             end
   923         else
   986         else
   924             begin
   987             begin
   925             lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
   988             lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
   926             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);
   927             end
   990             end
   928         end
   991         end
   929     else
   992     else
   930         begin
   993         begin
   931         lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
   994         lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L);
   932         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);
   933         end;
   996         end;
   934     lc_getvisualgearvalues:= 10
   997     lc_getvisualgearvalues:= 10
   935 end;
   998 end;
   936 
   999 
   937 function lc_setvisualgearvalues(L : Plua_State) : LongInt; Cdecl;
  1000 function lc_setvisualgearvalues(L : Plua_State) : LongInt; Cdecl;
   938 var vg : PVisualGear;
  1001 var vg : PVisualGear;
   939 begin
  1002 begin
   940 // Param count can be 1-11 at present
  1003 // Param count can be 1-11 at present
   941 //    if CheckLuaParamCount(L, 11, 'SetVisualGearValues', 'vgUid, X, Y, dX, dY, Angle, Frame, FrameTicks, State, Timer, Tint') then
  1004 //    if CheckLuaParamCount(L, 11, 'SetVisualGearValues', 'vgUid, X, Y, dX, dY, Angle, Frame, FrameTicks, State, Timer, Tint, Scale') then
   942 //        begin
  1005 //        begin
   943         vg:= VisualGearByUID(Trunc(lua_tonumber(L, 1)));
  1006         vg:= VisualGearByUID(Trunc(lua_tonumber(L, 1)));
   944         if vg <> nil then
  1007         if vg <> nil then
   945             begin
  1008             begin
   946             if not lua_isnoneornil(L, 2) then
  1009             if not lua_isnoneornil(L, 2) then
   960             if not lua_isnoneornil(L, 9) then
  1023             if not lua_isnoneornil(L, 9) then
   961                 vg^.State:= Trunc(lua_tonumber(L, 9));
  1024                 vg^.State:= Trunc(lua_tonumber(L, 9));
   962             if not lua_isnoneornil(L, 10) then
  1025             if not lua_isnoneornil(L, 10) then
   963                 vg^.Timer:= Trunc(lua_tonumber(L, 10));
  1026                 vg^.Timer:= Trunc(lua_tonumber(L, 10));
   964             if not lua_isnoneornil(L, 11) then
  1027             if not lua_isnoneornil(L, 11) then
   965                 vg^.Tint:= Trunc(lua_tonumber(L, 11))
  1028                 vg^.Tint:= Trunc(lua_tonumber(L, 11));
       
  1029             if not lua_isnoneornil(L, 12) then
       
  1030                 vg^.Scale:= Trunc(lua_tonumber(L, 12))
   966             end;
  1031             end;
   967 //        end
  1032 //        end
   968 //    else
  1033 //    else
   969 //        lua_pushnil(L); // return value on stack (nil)
  1034 //        lua_pushnil(L); // return value on stack (nil)
   970     lc_setvisualgearvalues:= 0
  1035     lc_setvisualgearvalues:= 0
  1291 end;
  1356 end;
  1292 
  1357 
  1293 function lc_setclancolor(L : Plua_State) : LongInt; Cdecl;
  1358 function lc_setclancolor(L : Plua_State) : LongInt; Cdecl;
  1294 var clan : PClan;
  1359 var clan : PClan;
  1295     team : PTeam;
  1360     team : PTeam;
  1296     hh   : THedgehog;
  1361     hh  : THedgehog;
  1297     i, j : LongInt;
  1362     i, j : LongInt;
       
  1363     colorArg: Int64;
       
  1364     color: LongWord;
  1298 begin
  1365 begin
  1299     if CheckLuaParamCount(L, 2, 'SetClanColor', 'clan, color') then
  1366     if CheckLuaParamCount(L, 2, 'SetClanColor', 'clan, color') then
  1300         begin
  1367         begin
  1301         i:= Trunc(lua_tonumber(L,1));
  1368         i:= Trunc(lua_tonumber(L,1));
  1302         if i >= ClansCount then exit(0);
  1369         if i >= ClansCount then exit(0);
  1303         clan := ClansArray[i];
  1370         clan := ClansArray[i];
  1304         clan^.Color:= Trunc(lua_tonumber(L, 2)) shr 8;
  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;
  1305 
  1386 
  1306         for i:= 0 to Pred(clan^.TeamsNumber) do
  1387         for i:= 0 to Pred(clan^.TeamsNumber) do
  1307             begin
  1388             begin
  1308             team:= clan^.Teams[i];
  1389             team:= clan^.Teams[i];
  1309             for j:= 0 to 7 do
  1390             for j:= 0 to cMaxHHIndex do
  1310                 begin
  1391                 begin
  1311                 hh:= team^.Hedgehogs[j];
  1392                 hh:= team^.Hedgehogs[j];
  1312                 if (hh.Gear <> nil) or (hh.GearHidden <> nil) then
  1393                 if (hh.Gear <> nil) or (hh.GearHidden <> nil) then
  1313                     begin
  1394                     begin
  1314                     FreeAndNilTexture(hh.NameTagTex);
  1395                     FreeAndNilTexture(hh.NameTagTex);
  1315                     hh.NameTagTex:= RenderStringTex(ansistring(hh.Name), clan^.Color, fnt16);
  1396                     hh.NameTagTex:= RenderStringTex(ansistring(hh.Name), clan^.Color, fnt16);
  1316                     RenderHealth(hh);
  1397                     RenderHealth(hh);
       
  1398                     team^.Hedgehogs[j]:= hh;
  1317                     end;
  1399                     end;
  1318                 end;
  1400                 end;
  1319             FreeAndNilTexture(team^.NameTagTex);
  1401             FreeAndNilTexture(team^.NameTagTex);
  1320             team^.NameTagTex:= RenderStringTex(ansistring(clan^.Teams[i]^.TeamName), clan^.Color, fnt16);
  1402             team^.NameTagTex:= RenderStringTex(ansistring(clan^.Teams[i]^.TeamName), clan^.Color, fnt16);
  1321             end;
  1403             end;
  1389             lua_pushnil(L);
  1471             lua_pushnil(L);
  1390         end
  1472         end
  1391     else
  1473     else
  1392         lua_pushnil(L); // return value on stack (nil)
  1474         lua_pushnil(L); // return value on stack (nil)
  1393     lc_gethogfort:= 1
  1475     lc_gethogfort:= 1
       
  1476 end;
       
  1477 
       
  1478 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
  1394 end;
  1498 end;
  1395 
  1499 
  1396 function lc_ishoglocal(L : Plua_State) : LongInt; Cdecl;
  1500 function lc_ishoglocal(L : Plua_State) : LongInt; Cdecl;
  1397 var gear : PGear;
  1501 var gear : PGear;
  1398 begin
  1502 begin
  1612             if vgear <> nil then
  1716             if vgear <> nil then
  1613                begin
  1717                begin
  1614                vgear^.Text:= lua_tostring(L, 2);
  1718                vgear^.Text:= lua_tostring(L, 2);
  1615                if Gear^.Kind = gtHedgehog then
  1719                if Gear^.Kind = gtHedgehog then
  1616                    begin
  1720                    begin
  1617                    AddChatString(#9+'[' + gear^.Hedgehog^.Name + '] '+vgear^.text);
  1721                    AddChatString(#9+Format(shortstring(trmsg[sidChatHog]), gear^.Hedgehog^.Name, vgear^.text));
  1618                    vgear^.Hedgehog:= gear^.Hedgehog
  1722                    vgear^.Hedgehog:= gear^.Hedgehog
  1619                    end
  1723                    end
  1620                else vgear^.Frame:= gear^.uid;
  1724                else vgear^.Frame:= gear^.uid;
  1621 
  1725 
  1622                vgear^.FrameTicks:= Trunc(lua_tonumber(L, 3));
  1726                vgear^.FrameTicks:= Trunc(lua_tonumber(L, 3));
  1640         begin
  1744         begin
  1641         gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
  1745         gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
  1642 // should we allow this when there is no current hedgehog? might do some odd(er) things to turn sequence.
  1746 // should we allow this when there is no current hedgehog? might do some odd(er) things to turn sequence.
  1643         if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) and (CurrentHedgehog <> nil) then
  1747         if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) and (CurrentHedgehog <> nil) then
  1644             begin
  1748             begin
       
  1749             CurrentHedgehog^.MultiShootAttacks:= 0;
  1645             prevgear := CurrentHedgehog^.Gear;
  1750             prevgear := CurrentHedgehog^.Gear;
  1646             if prevgear <> nil then
  1751             if prevgear <> nil then
  1647                 begin
  1752                 begin
  1648                 prevgear^.Active := false;
  1753                 prevgear^.Active := false;
  1649                 prevgear^.State:= prevgear^.State and (not gstHHDriven);
  1754                 prevgear^.State:= prevgear^.State and (not gstHHDriven);
  1665             gear^.Z := cCurrHHZ;
  1770             gear^.Z := cCurrHHZ;
  1666             gear^.Message:= gear^.Message or gmRemoveFromList or gmAddToList;
  1771             gear^.Message:= gear^.Message or gmRemoveFromList or gmAddToList;
  1667             end
  1772             end
  1668         end;
  1773         end;
  1669     lc_switchhog:= 0
  1774     lc_switchhog:= 0
       
  1775 end;
       
  1776 
       
  1777 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;
  1670 end;
  1813 end;
  1671 
  1814 
  1672 function lc_addammo(L : Plua_State) : LongInt; Cdecl;
  1815 function lc_addammo(L : Plua_State) : LongInt; Cdecl;
  1673 var gear : PGear;
  1816 var gear : PGear;
  1674     at, n, c: LongInt;
  1817     at, n, c: LongInt;
  1737             begin
  1880             begin
  1738             gear^.Health:= Trunc(lua_tonumber(L, 2));
  1881             gear^.Health:= Trunc(lua_tonumber(L, 2));
  1739 
  1882 
  1740             if (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
  1883             if (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then
  1741                 begin
  1884                 begin
       
  1885                 if gear^.Health > cMaxHogHealth then
       
  1886                     gear^.Health:= cMaxHogHealth;
       
  1887                 if gear^.Health < 0 then
       
  1888                     gear^.Health:= 0;
  1742                 RenderHealth(gear^.Hedgehog^);
  1889                 RenderHealth(gear^.Hedgehog^);
  1743                 RecountTeamHealth(gear^.Hedgehog^.Team)
  1890                 RecountTeamHealth(gear^.Hedgehog^.Team)
  1744                 end;
  1891                 end
  1745             // Why did this do a "setalltoactive" ?
  1892             else if (gear^.RenderHealth) and (gear^.Tex <> nil) then
  1746             //SetAllToActive;
  1893                 FreeAndNilTexture(gear^.Tex);
  1747             Gear^.Active:= true;
  1894             Gear^.Active:= true;
  1748             AllInactive:= false
  1895             AllInactive:= false
  1749             end
  1896             end
  1750         end;
  1897         end;
  1751     lc_sethealth:= 0
  1898     lc_sethealth:= 0
  1759         begin
  1906         begin
  1760         gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
  1907         gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
  1761         healthBoost:= Trunc(lua_tonumber(L, 2));
  1908         healthBoost:= Trunc(lua_tonumber(L, 2));
  1762         if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) and (healthBoost >= 1) then
  1909         if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) and (healthBoost >= 1) then
  1763             begin
  1910             begin
  1764             gear^.Health:= gear^.Health + healthBoost;
  1911             healthBoost:= IncHogHealth(gear^.Hedgehog, healthBoost);
  1765 
       
  1766             RenderHealth(gear^.Hedgehog^);
  1912             RenderHealth(gear^.Hedgehog^);
  1767             RecountTeamHealth(gear^.Hedgehog^.Team);
  1913             RecountTeamHealth(gear^.Hedgehog^.Team);
  1768             if n = 4 then
  1914             if n = 4 then
  1769                 HHHeal(gear^.Hedgehog, healthBoost, lua_toboolean(L, 3), Trunc(lua_tonumber(L, 4)))
  1915                 HHHeal(gear^.Hedgehog, healthBoost, lua_toboolean(L, 3), Trunc(lua_tonumber(L, 4)))
  1770             else if n = 3 then
  1916             else if n = 3 then
  1782 var gear : PGear;
  1928 var gear : PGear;
  1783 begin
  1929 begin
  1784     if CheckLuaParamCount(L, 2, 'SetTimer', 'gearUid, timer') then
  1930     if CheckLuaParamCount(L, 2, 'SetTimer', 'gearUid, timer') then
  1785         begin
  1931         begin
  1786         gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
  1932         gear:= GearByUID(Trunc(lua_tonumber(L, 1)));
  1787         if gear <> nil then gear^.Timer:= Trunc(lua_tonumber(L, 2))
  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;
  1788         end;
  1939         end;
  1789     lc_settimer:= 0
  1940     lc_settimer:= 0
  1790 end;
  1941 end;
  1791 
  1942 
  1792 function lc_setflighttime(L : Plua_State) : LongInt; Cdecl;
  1943 function lc_setflighttime(L : Plua_State) : LongInt; Cdecl;
  1907 end;
  2058 end;
  1908 
  2059 
  1909 function lc_endgame(L : Plua_State) : LongInt; Cdecl;
  2060 function lc_endgame(L : Plua_State) : LongInt; Cdecl;
  1910 begin
  2061 begin
  1911     L:= L; // avoid compiler hint
  2062     L:= L; // avoid compiler hint
       
  2063     GameOver:= true;
  1912     AddGear(0, 0, gtATFinishGame, 0, _0, _0, 3000);
  2064     AddGear(0, 0, gtATFinishGame, 0, _0, _0, 3000);
  1913     lc_endgame:= 0
  2065     lc_endgame:= 0
  1914 end;
  2066 end;
  1915 
  2067 
  1916 function lc_endturn(L : Plua_State) : LongInt; Cdecl;
  2068 function lc_endturn(L : Plua_State) : LongInt; Cdecl;
  1941         if n = 2 then
  2093         if n = 2 then
  1942             respectFactor:= lua_toboolean(L, 2)
  2094             respectFactor:= lua_toboolean(L, 2)
  1943         else
  2095         else
  1944             respectFactor:= True;
  2096             respectFactor:= True;
  1945         if respectFactor then
  2097         if respectFactor then
  1946             TurnTimeLeft:= (time * cGetAwayTime) div 100
  2098             PendingTurnTimeLeft:= (time * cGetAwayTime) div 100
  1947         else
  2099         else
  1948             TurnTimeLeft:= time;
  2100             PendingTurnTimeLeft:= time;
       
  2101         isPendingTurnTimeLeft:= true;
  1949         if ((CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil)) then
  2102         if ((CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil)) then
  1950             begin
  2103             begin
  1951             CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State or gstAttacked;
  2104             CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State or gstAttacked;
  1952             CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State and (not gstAttacking);
  2105             CurrentHedgehog^.Gear^.State:= CurrentHedgehog^.Gear^.State and (not gstAttacking);
  1953             end;
  2106             end;
  2106                     if n = 3 then
  2259                     if n = 3 then
  2107                         instaVoice:= lua_toboolean(L, 3);
  2260                         instaVoice:= lua_toboolean(L, 3);
  2108                     if instaVoice then
  2261                     if instaVoice then
  2109                         PlaySoundV(TSound(s), gear^.Hedgehog^.Team^.Voicepack, false, true)
  2262                         PlaySoundV(TSound(s), gear^.Hedgehog^.Team^.Voicepack, false, true)
  2110                     else
  2263                     else
  2111                         AddVoice(TSound(s), gear^.Hedgehog^.Team^.Voicepack, true);
  2264                         AddVoice(TSound(s), gear^.Hedgehog^.Team^.Voicepack, true, false);
  2112                     end;
  2265                     end;
  2113                 end;
  2266                 end;
  2114             end;
  2267             end;
  2115         end;
  2268         end;
  2116     lc_playsound:= 0;
  2269     lc_playsound:= 0;
  2117 end;
  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 
  2118 
  2302 
  2119 function lc_setsoundmask(L : Plua_State) : LongInt; Cdecl;
  2303 function lc_setsoundmask(L : Plua_State) : LongInt; Cdecl;
  2120 var s: LongInt;
  2304 var s: LongInt;
  2121     soundState: boolean;
  2305     soundState: boolean;
  2122 const
  2306 const
  2123     call = 'SetSoundMasked';
  2307     call = 'SetSoundMask';
  2124     params = 'soundId, isMasked]';
  2308     params = 'soundId, isMasked';
  2125 begin
  2309 begin
  2126     if CheckLuaParamCount(L, 2, call, params) then
  2310     if CheckLuaParamCount(L, 2, call, params) then
  2127         begin
  2311         begin
  2128         s:= LuaToSoundOrd(L, 1, call, params);
  2312         s:= LuaToSoundOrd(L, 1, call, params);
  2129         if s <> Ord(sndNone) then
  2313         if s <> Ord(sndNone) then
  2135     lc_setsoundmask:= 0;
  2319     lc_setsoundmask:= 0;
  2136 end;
  2320 end;
  2137 
  2321 
  2138 function lc_addteam(L : Plua_State) : LongInt; Cdecl;
  2322 function lc_addteam(L : Plua_State) : LongInt; Cdecl;
  2139 var np: LongInt;
  2323 var np: LongInt;
       
  2324     colorArg: Int64;
       
  2325     colorStr: shortstring;
  2140 begin
  2326 begin
  2141     if CheckAndFetchParamCount(L, 5, 6, 'AddTeam', 'teamname, color, grave, fort, voicepack [, flag]', np) then
  2327     if CheckAndFetchParamCount(L, 5, 6, 'AddTeam', 'teamname, color, grave, fort, voicepack [, flag]', np) then
  2142         begin
  2328         begin
  2143         ParseCommand('addteam x ' + lua_tostring(L, 2) + ' ' + lua_tostring(L, 1), true, true);
  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);
  2144         ParseCommand('grave ' + lua_tostring(L, 3), true, true);
  2345         ParseCommand('grave ' + lua_tostring(L, 3), true, true);
  2145         ParseCommand('fort ' + lua_tostring(L, 4), true, true);
  2346         ParseCommand('fort ' + lua_tostring(L, 4), true, true);
  2146         ParseCommand('voicepack ' + lua_tostring(L, 5), true, true);
  2347         ParseCommand('voicepack ' + lua_tostring(L, 5), true, true);
  2147         if (np = 6) then ParseCommand('flag ' + lua_tostring(L, 6), true, true);
  2348         if (np = 6) then ParseCommand('flag ' + lua_tostring(L, 6), true, true);
  2148         CurrentTeam^.Binds:= DefaultBinds
  2349         // If there's a mission team, copy it's control scheme.
  2149         // fails on x64
  2350         // So in singleplayer missions, all teams use the player team's controls.
  2150         //lua_pushnumber(L, LongInt(CurrentTeam));
  2351         if MissionTeam <> nil then
  2151         end;
  2352             CurrentTeam^.Binds:= MissionTeam^.Binds
  2152     //else
  2353         // Default keys otherwise
  2153         //lua_pushnil(L)
  2354         else
  2154     lc_addteam:= 0;//1;
  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 
       
  2368 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;
  2155 end;
  2413 end;
  2156 
  2414 
  2157 function lc_setteamlabel(L : Plua_State) : LongInt; Cdecl;
  2415 function lc_setteamlabel(L : Plua_State) : LongInt; Cdecl;
  2158 var teamValue: ansistring;
  2416 var teamValue: ansistring;
  2159     i, n: LongInt;
  2417     i, n: LongInt;
  2160     success: boolean;
  2418     success: boolean;
  2161 begin
  2419 begin
       
  2420 	success:= false;
  2162     if CheckAndFetchParamCount(L, 1, 2, 'SetTeamLabel', 'teamname[, label]', n) then
  2421     if CheckAndFetchParamCount(L, 1, 2, 'SetTeamLabel', 'teamname[, label]', n) then
  2163         begin
  2422         begin
  2164         success:= false;
  2423         success:= false;
  2165         // fetch team
  2424         // fetch team
  2166         if TeamsCount > 0 then
  2425         if TeamsCount > 0 then
  2194     // return true if operation was successful, false otherwise
  2453     // return true if operation was successful, false otherwise
  2195     lua_pushboolean(L, success);
  2454     lua_pushboolean(L, success);
  2196     lc_setteamlabel:= 1;
  2455     lc_setteamlabel:= 1;
  2197 end;
  2456 end;
  2198 
  2457 
       
  2458 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 
  2199 function lc_getteamname(L : Plua_State) : LongInt; Cdecl;
  2498 function lc_getteamname(L : Plua_State) : LongInt; Cdecl;
  2200 var t: LongInt;
  2499 var t: LongInt;
  2201 begin
  2500 begin
  2202     if CheckLuaParamCount(L, 1, 'GetTeamName', 'teamIdx') then
  2501     if CheckLuaParamCount(L, 1, 'GetTeamName', 'teamIdx') then
  2203         begin
  2502         begin
  2286                             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);
  2287                             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);
  2288                             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);
  2289                             end;
  2588                             end;
  2290                         HHGear^.Message:= HHGear^.Message or gmDestroy;
  2589                         HHGear^.Message:= HHGear^.Message or gmDestroy;
       
  2590                         HHGear^.Active:= true;
       
  2591                         AllInactive:= false;
  2291                         end;
  2592                         end;
  2292                     end;
  2593                     end;
  2293                 // can't dismiss more than one team
  2594                 // can't dismiss more than one team
  2294                 break;
  2595                 break;
  2295                 end;
  2596                 end;
  2343 end;
  2644 end;
  2344 
  2645 
  2345 
  2646 
  2346 
  2647 
  2347 function lc_addhog(L : Plua_State) : LongInt; Cdecl;
  2648 function lc_addhog(L : Plua_State) : LongInt; Cdecl;
  2348 var temp: ShortString;
  2649 var hatName: ShortString;
  2349 begin
  2650 begin
  2350     if CheckLuaParamCount(L, 4, 'AddHog', 'hogname, botlevel, health, hat') then
  2651     if CheckLuaParamCount(L, 4, 'AddHog', 'hogname, botlevel, health, hat') then
  2351         begin
  2652         begin
  2352         temp:= lua_tostring(L, 4);
  2653         hatName:= lua_tostring(L, 4);
  2353         ParseCommand('addhh ' + lua_tostring(L, 2) + ' ' + lua_tostring(L, 3) + ' ' + lua_tostring(L, 1), true, true);
  2654         ParseCommand('addhh ' + lua_tostring(L, 2) + ' ' + lua_tostring(L, 3) + ' ' + lua_tostring(L, 1), true, true);
  2354         ParseCommand('hat ' + temp, true, true);
  2655         ParseCommand('hat ' + hatName, true, true);
  2355         lua_pushnumber(L, CurrentHedgehog^.Gear^.uid);
  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);
  2356         end
  2660         end
  2357     else
  2661     else
  2358         lua_pushnil(L);
  2662         lua_pushnil(L);
  2359     lc_addhog:= 1;
  2663     lc_addhog:= 1;
       
  2664 end;
       
  2665 
       
  2666 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;
  2360 end;
  2692 end;
  2361 
  2693 
  2362 function lc_hogturnleft(L : Plua_State) : LongInt; Cdecl;
  2694 function lc_hogturnleft(L : Plua_State) : LongInt; Cdecl;
  2363 var gear: PGear;
  2695 var gear: PGear;
  2364 begin
  2696 begin
  2541             end;
  2873             end;
  2542         end;
  2874         end;
  2543     lc_setammo:= 0
  2875     lc_setammo:= 0
  2544 end;
  2876 end;
  2545 
  2877 
       
  2878 
       
  2879 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 
  2546 function lc_setammodelay(L : Plua_State) : LongInt; Cdecl;
  2913 function lc_setammodelay(L : Plua_State) : LongInt; Cdecl;
  2547 var at: LongInt;
  2914 var at, delay: LongInt;
  2548 const
  2915 const
  2549     call = 'SetAmmoDelay';
  2916     call = 'SetAmmoDelay';
  2550     params = 'ammoType, delay';
  2917     params = 'ammoType, delay';
  2551 begin
  2918 begin
  2552     if CheckLuaParamCount(L, 2, call, params) then
  2919     if CheckLuaParamCount(L, 2, call, params) then
  2553         begin
  2920         begin
  2554         at:= LuaToAmmoTypeOrd(L, 1, call, params);
  2921         at:= LuaToAmmoTypeOrd(L, 1, call, params);
  2555         if at >= 0 then
  2922         delay:= Trunc(lua_tonumber(L, 2));
  2556             ScriptSetAmmoDelay(TAmmoType(at), 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;
  2557         end;
  2930         end;
  2558     lc_setammodelay:= 0
  2931     lc_setammodelay:= 0
       
  2932 end;
       
  2933 
       
  2934 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;
  2559 end;
  2945 end;
  2560 
  2946 
  2561 function lc_getrandom(L : Plua_State) : LongInt; Cdecl;
  2947 function lc_getrandom(L : Plua_State) : LongInt; Cdecl;
  2562 var m : LongInt;
  2948 var m : LongInt;
  2563 begin
  2949 begin
  2586         cWindSpeedf:= SignAs(cWindSpeed,cWindSpeed).QWordValue / SignAs(_1,_1).QWordValue;
  2972         cWindSpeedf:= SignAs(cWindSpeed,cWindSpeed).QWordValue / SignAs(_1,_1).QWordValue;
  2587         if cWindSpeed.isNegative then
  2973         if cWindSpeed.isNegative then
  2588             cWindSpeedf := -cWindSpeedf;
  2974             cWindSpeedf := -cWindSpeedf;
  2589         vg:= AddVisualGear(0, 0, vgtSmoothWindBar);
  2975         vg:= AddVisualGear(0, 0, vgtSmoothWindBar);
  2590         if vg <> nil then vg^.dAngle:= hwFloat2Float(cWindSpeed);
  2976         if vg <> nil then vg^.dAngle:= hwFloat2Float(cWindSpeed);
  2591             AddFileLog('Wind = '+FloatToStr(cWindSpeed));
  2977             AddFileLog('Script set wind = '+FloatToStr(cWindSpeed));
  2592         end;
  2978         end;
  2593     lc_setwind:= 0
  2979     lc_setwind:= 0
  2594 end;
  2980 end;
  2595 
  2981 
  2596 function lc_getwind(L : Plua_State) : LongInt; Cdecl;
  2982 function lc_getwind(L : Plua_State) : LongInt; Cdecl;
  2678     tint  : LongWord;
  3064     tint  : LongWord;
  2679     i, n : LongInt;
  3065     i, n : LongInt;
  2680     placed, behind, flipHoriz, flipVert : boolean;
  3066     placed, behind, flipHoriz, flipVert : boolean;
  2681 const
  3067 const
  2682     call = 'PlaceSprite';
  3068     call = 'PlaceSprite';
  2683     params = 'x, y, sprite, frameIdx, tint, behind, flipHoriz, flipVert, [, landFlag, ... ]';
  3069     params = 'x, y, sprite, frameIdx, tint, behind, flipHoriz, flipVert [, landFlag, ... ]';
  2684 begin
  3070 begin
  2685     placed:= false;
  3071     placed:= false;
  2686     if CheckAndFetchLuaParamMinCount(L, 4, call, params, n) then
  3072     if CheckAndFetchLuaParamMinCount(L, 4, call, params, n) then
  2687         begin
  3073         begin
  2688         if not lua_isnoneornil(L, 5) then
  3074         if not lua_isnoneornil(L, 5) then
  2726     lf    : Word;
  3112     lf    : Word;
  2727     i, n : LongInt;
  3113     i, n : LongInt;
  2728     eraseOnLFMatch, onlyEraseLF, flipHoriz, flipVert : boolean;
  3114     eraseOnLFMatch, onlyEraseLF, flipHoriz, flipVert : boolean;
  2729 const
  3115 const
  2730     call = 'EraseSprite';
  3116     call = 'EraseSprite';
  2731     params = 'x, y, sprite, frameIdx, eraseOnLFMatch, onlyEraseLF, flipHoriz, flipVert, [, landFlag, ... ]';
  3117     params = 'x, y, sprite, frameIdx, eraseOnLFMatch, onlyEraseLF, flipHoriz, flipVert [, landFlag, ... ]';
  2732 begin
  3118 begin
  2733     if CheckAndFetchLuaParamMinCount(L, 4, call, params, n) then
  3119     if CheckAndFetchLuaParamMinCount(L, 4, call, params, n) then
  2734         begin
  3120         begin
  2735         if not lua_isnoneornil(L, 5) then
  3121         if not lua_isnoneornil(L, 5) then
  2736             eraseOnLFMatch := lua_toboolean(L, 5)
  3122             eraseOnLFMatch := lua_toboolean(L, 5)
  2816         SendIPCAndWaitReply('V?' + lua_tostring(L, 1) + #0);
  3202         SendIPCAndWaitReply('V?' + lua_tostring(L, 1) + #0);
  2817     lua_pushstring(L, str2pchar(CampaignVariable));
  3203     lua_pushstring(L, str2pchar(CampaignVariable));
  2818     lc_getcampaignvar := 1;
  3204     lc_getcampaignvar := 1;
  2819 end;
  3205 end;
  2820 
  3206 
       
  3207 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 
       
  3214 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 
  2821 function lc_hidehog(L: Plua_State): LongInt; Cdecl;
  3222 function lc_hidehog(L: Plua_State): LongInt; Cdecl;
  2822 var gear: PGear;
  3223 var gear: PGear;
  2823 begin
  3224 begin
  2824     if CheckLuaParamCount(L, 1, 'HideHog', 'gearUid') then
  3225     if CheckLuaParamCount(L, 1, 'HideHog', 'gearUid') then
  2825         begin
  3226         begin
  2852                         end
  3253                         end
  2853         end;
  3254         end;
  2854     lc_restorehog := 0;
  3255     lc_restorehog := 0;
  2855 end;
  3256 end;
  2856 
  3257 
       
  3258 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 
  2857 // boolean TestRectForObstacle(x1, y1, x2, y2, landOnly)
  3288 // boolean TestRectForObstacle(x1, y1, x2, y2, landOnly)
  2858 function lc_testrectforobstacle(L : Plua_State) : LongInt; Cdecl;
  3289 function lc_testrectforobstacle(L : Plua_State) : LongInt; Cdecl;
  2859 var rtn: Boolean;
  3290 var rtn: Boolean;
  2860 begin
  3291 begin
  2861     if CheckLuaParamCount(L, 5, 'TestRectForObstacle', 'x1, y1, x2, y2, landOnly') then
  3292     if CheckLuaParamCount(L, 5, 'TestRectForObstacle', 'x1, y1, x2, y2, landOnly') then
  2927     lc_setgearaihints:= 0
  3358     lc_setgearaihints:= 0
  2928 end;
  3359 end;
  2929 
  3360 
  2930 
  3361 
  2931 function lc_hedgewarsscriptload(L : Plua_State) : LongInt; Cdecl;
  3362 function lc_hedgewarsscriptload(L : Plua_State) : LongInt; Cdecl;
  2932 begin
  3363 var success : boolean;
  2933     if CheckLuaParamCount(L, 1, 'HedgewarsScriptLoad', 'scriptPath') then
  3364     n : LongInt;
  2934         ScriptLoad(lua_tostring(L, 1))
  3365 begin
  2935     else
  3366 	success:= false;
  2936         lua_pushnil(L);
  3367     if CheckAndFetchParamCount(L, 1, 2, 'HedgewarsScriptLoad', 'scriptPath [, mustExist]', n) then
  2937     lc_hedgewarsscriptload:= 0;
  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;
  2938 end;
  3378 end;
  2939 
  3379 
  2940 
  3380 
  2941 function lc_declareachievement(L : Plua_State) : LongInt; Cdecl;
  3381 function lc_declareachievement(L : Plua_State) : LongInt; Cdecl;
  2942 begin
  3382 begin
  2966     else
  3406     else
  2967         lua_pushnil(L);
  3407         lua_pushnil(L);
  2968     lc_getammoname:= 1;
  3408     lc_getammoname:= 1;
  2969 end;
  3409 end;
  2970 
  3410 
       
  3411 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 
  2971 function lc_setvampiric(L : Plua_state) : LongInt; Cdecl;
  3438 function lc_setvampiric(L : Plua_state) : LongInt; Cdecl;
  2972 begin
  3439 begin
  2973     if CheckLuaParamCount(L, 1, 'SetVampiric', 'bool') then
  3440     if CheckLuaParamCount(L, 1, 'SetVampiric', 'bool') then
  2974         cVampiric := lua_toboolean(L, 1);
  3441         cVampiric := lua_toboolean(L, 1);
  2975     lc_setvampiric := 0;
  3442     lc_setvampiric := 0;
  2976 end;
  3443 end;
  2977 
  3444 
       
  3445 function lc_getvampiric(L : Plua_state) : LongInt; Cdecl;
       
  3446 begin
       
  3447     lua_pushboolean(L, cVampiric);
       
  3448     lc_getvampiric := 1;
       
  3449 end;
       
  3450 
  2978 function lc_setlasersight(L : Plua_state) : LongInt; Cdecl;
  3451 function lc_setlasersight(L : Plua_state) : LongInt; Cdecl;
  2979 begin
  3452 begin
  2980     if CheckLuaParamCount(L, 1, 'SetLaserSight', 'bool') then
  3453     if CheckLuaParamCount(L, 1, 'SetLaserSight', 'bool') then
  2981         cLaserSighting:= lua_toboolean(L, 1);
  3454         cLaserSighting:= lua_toboolean(L, 1);
  2982     lc_setlasersight:= 0;
  3455     lc_setlasersight:= 0;
       
  3456 end;
       
  3457 
       
  3458 function lc_getlasersight(L : Plua_state) : LongInt; Cdecl;
       
  3459 begin
       
  3460     lua_pushboolean(L, cLaserSighting);
       
  3461     lc_getlasersight:= 1;
  2983 end;
  3462 end;
  2984 
  3463 
  2985 function lc_explode(L : Plua_state) : LongInt; Cdecl;
  3464 function lc_explode(L : Plua_state) : LongInt; Cdecl;
  2986 var mask: LongWord;
  3465 var mask: LongWord;
  2987     n: LongInt;
  3466     n: LongInt;
  2998         else
  3477         else
  2999             lua_pushboolean(L, false)
  3478             lua_pushboolean(L, false)
  3000     else
  3479     else
  3001         lua_pushboolean(L, false);
  3480         lua_pushboolean(L, false);
  3002     lc_explode:= 1;
  3481     lc_explode:= 1;
       
  3482 end;
       
  3483 
       
  3484 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 
       
  3501 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 
       
  3518 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 
       
  3525 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;
  3003 end;
  3532 end;
  3004 
  3533 
  3005 function lc_startghostpoints(L : Plua_State) : LongInt; Cdecl;
  3534 function lc_startghostpoints(L : Plua_State) : LongInt; Cdecl;
  3006 begin
  3535 begin
  3007     if CheckLuaParamCount(L, 1, 'StartGhostPoints', 'count') then
  3536     if CheckLuaParamCount(L, 1, 'StartGhostPoints', 'count') then
  3124     lua_pushnil(luaState);
  3653     lua_pushnil(luaState);
  3125     lua_setglobal(luaState, Str2PChar(name));
  3654     lua_setglobal(luaState, Str2PChar(name));
  3126 end;
  3655 end;
  3127 
  3656 
  3128 procedure ScriptSetInteger(name : shortstring; value : LongInt);
  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);
  3129 begin
  3664 begin
  3130     lua_pushnumber(luaState, value);
  3665     lua_pushnumber(luaState, value);
  3131     lua_setglobal(luaState, Str2PChar(name));
  3666     lua_setglobal(luaState, Str2PChar(name));
  3132 end;
  3667 end;
  3133 
  3668 
  3199 ScriptSetInteger('MapFeatureSize', cFeatureSize);
  3734 ScriptSetInteger('MapFeatureSize', cFeatureSize);
  3200 ScriptSetInteger('ScreenHeight', cScreenHeight);
  3735 ScriptSetInteger('ScreenHeight', cScreenHeight);
  3201 ScriptSetInteger('ScreenWidth', cScreenWidth);
  3736 ScriptSetInteger('ScreenWidth', cScreenWidth);
  3202 ScriptSetInteger('TurnTime', cHedgehogTurnTime);
  3737 ScriptSetInteger('TurnTime', cHedgehogTurnTime);
  3203 ScriptSetInteger('CaseFreq', cCaseFactor);
  3738 ScriptSetInteger('CaseFreq', cCaseFactor);
       
  3739 ScriptSetInteger('MaxCaseDrops', cMaxCaseDrops);
  3204 ScriptSetInteger('HealthCaseProb', cHealthCaseProb);
  3740 ScriptSetInteger('HealthCaseProb', cHealthCaseProb);
  3205 ScriptSetInteger('HealthCaseAmount', cHealthCaseAmount);
  3741 ScriptSetInteger('HealthCaseAmount', cHealthCaseAmount);
       
  3742 ScriptSetInteger('InitHealth', cInitHealth);
  3206 ScriptSetInteger('DamagePercent', cDamagePercent);
  3743 ScriptSetInteger('DamagePercent', cDamagePercent);
  3207 ScriptSetInteger('RopePercent', cRopePercent);
  3744 ScriptSetInteger('RopePercent', cRopePercent);
  3208 ScriptSetInteger('MinesNum', cLandMines);
  3745 ScriptSetInteger('MinesNum', cLandMines);
  3209 ScriptSetInteger('MinesTime', cMinesTime);
  3746 ScriptSetInteger('MinesTime', cMinesTime);
  3210 ScriptSetInteger('MineDudPercent', cMineDudPercent);
  3747 ScriptSetInteger('MineDudPercent', cMineDudPercent);
  3231 cFeatureSize     := ScriptGetInteger('MapFeatureSize');
  3768 cFeatureSize     := ScriptGetInteger('MapFeatureSize');
  3232 GameFlags        := ScriptGetInteger('GameFlags');
  3769 GameFlags        := ScriptGetInteger('GameFlags');
  3233 WorldEdge        := TWorldEdge(ScriptGetInteger('WorldEdge'));
  3770 WorldEdge        := TWorldEdge(ScriptGetInteger('WorldEdge'));
  3234 cHedgehogTurnTime:= ScriptGetInteger('TurnTime');
  3771 cHedgehogTurnTime:= ScriptGetInteger('TurnTime');
  3235 cCaseFactor      := ScriptGetInteger('CaseFreq');
  3772 cCaseFactor      := ScriptGetInteger('CaseFreq');
       
  3773 cMaxCaseDrops    := ScriptGetInteger('MaxCaseDrops');
  3236 cHealthCaseProb  := ScriptGetInteger('HealthCaseProb');
  3774 cHealthCaseProb  := ScriptGetInteger('HealthCaseProb');
  3237 cHealthCaseAmount:= ScriptGetInteger('HealthCaseAmount');
  3775 cHealthCaseAmount:= ScriptGetInteger('HealthCaseAmount');
       
  3776 cInitHealth      := ScriptGetInteger('InitHealth');
  3238 cDamagePercent   := ScriptGetInteger('DamagePercent');
  3777 cDamagePercent   := ScriptGetInteger('DamagePercent');
  3239 cRopePercent     := ScriptGetInteger('RopePercent');
  3778 cRopePercent     := ScriptGetInteger('RopePercent');
  3240 cLandMines       := ScriptGetInteger('MinesNum');
  3779 cLandMines       := ScriptGetInteger('MinesNum');
  3241 cMinesTime       := ScriptGetInteger('MinesTime');
  3780 cMinesTime       := ScriptGetInteger('MinesTime');
  3242 cMineDudPercent  := ScriptGetInteger('MineDudPercent');
  3781 cMineDudPercent  := ScriptGetInteger('MineDudPercent');
  3295     ScriptApplyAmmoStore
  3834     ScriptApplyAmmoStore
  3296     end;
  3835     end;
  3297 
  3836 
  3298 ScriptSetInteger('ClansCount', ClansCount);
  3837 ScriptSetInteger('ClansCount', ClansCount);
  3299 ScriptSetInteger('TeamsCount', TeamsCount);
  3838 ScriptSetInteger('TeamsCount', TeamsCount);
  3300 mapDims:= false
       
  3301 end;
  3839 end;
  3302 
  3840 
  3303 
  3841 
  3304 // Update values of screen dimensions and allow script to react to resolution change
  3842 // Update values of screen dimensions and allow script to react to resolution change
  3305 procedure ScriptOnScreenResize();
  3843 procedure ScriptOnScreenResize();
  3316 var inQuote: boolean;
  3854 var inQuote: boolean;
  3317 var locSum: LongWord;
  3855 var locSum: LongWord;
  3318 var braceCount: LongWord;
  3856 var braceCount: LongWord;
  3319 var wordCount: LongWord;
  3857 var wordCount: LongWord;
  3320 var lastChar: char;
  3858 var lastChar: char;
  3321 // ⭒⭐⭒✨⭐⭒✨⭐☆✨⭐✨✧✨☆✨✧✨☆⭒✨☆⭐⭒☆✧✨⭒✨⭐✧⭒☆⭒✧☆✨✧⭐☆✨☆✧⭒✨✧⭒☆⭐☆✧
       
  3322 function  ScriptReader(L: Plua_State; f: PFSFile; sz: Psize_t) : PChar; Cdecl;
  3859 function  ScriptReader(L: Plua_State; f: PFSFile; sz: Psize_t) : PChar; Cdecl;
  3323 var mybuf: PChar;
  3860 var mybuf: PChar;
  3324     i: LongInt;
  3861     i: LongInt;
  3325 begin
  3862 begin
  3326     SetRandomSeed(cSeed,true);
  3863     SetRandomSeed(cSeed,true);
  3329         begin
  3866         begin
  3330             for i:= 0 to sz^-1 do
  3867             for i:= 0 to sz^-1 do
  3331                 begin
  3868                 begin
  3332                     if (lastChar = '-') and (mybuf[i] = '-') then
  3869                     if (lastChar = '-') and (mybuf[i] = '-') then
  3333                         inComment := true
  3870                         inComment := true
  3334                     // gonna add any non-magic whitespace and skip - just to make comment avoidance easier
       
  3335                     else if not inComment and (byte(mybuf[i]) > $20) and (byte(mybuf[i]) < $7F) and (mybuf[i]<>'-') then
  3871                     else if not inComment and (byte(mybuf[i]) > $20) and (byte(mybuf[i]) < $7F) and (mybuf[i]<>'-') then
  3336                         begin
  3872                         begin
  3337                         AddRandomness(byte(mybuf[i]));  // wish I had the seed...
  3873                         AddRandomness(byte(mybuf[i]));  // wish I had the seed...
  3338                         CheckSum := CheckSum xor GetRandom($FFFFFFFF);
  3874                         CheckSum := CheckSum xor GetRandom($FFFFFFFF);
  3339                         end;
  3875                         end;
  3340                     lastChar := mybuf[i];
  3876                     lastChar := mybuf[i];
  3341                     if (byte(mybuf[i]) = $0D) or (byte(mybuf[i]) = $0A) then
  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
  3342                         inComment := false
  3880                         inComment := false
  3343                 end;
  3881                 end;
  3344         end;
  3882         end;
  3345     ScriptReader:= mybuf
  3883     ScriptReader:= mybuf
  3346 end;
  3884 end;
  3373                         (((byte(mybuf[i]) > $40) and (byte(mybuf[i]) < $5B)) or
  3911                         (((byte(mybuf[i]) > $40) and (byte(mybuf[i]) < $5B)) or
  3374                         ((byte(mybuf[i]) > $60) and (byte(mybuf[i]) < $7B)) or
  3912                         ((byte(mybuf[i]) > $60) and (byte(mybuf[i]) < $7B)) or
  3375                         ((byte(mybuf[i]) >= $30) and (byte(mybuf[i]) < $3A))) then
  3913                         ((byte(mybuf[i]) >= $30) and (byte(mybuf[i]) < $3A))) then
  3376                         inc(wordCount);
  3914                         inc(wordCount);
  3377                     lastChar := mybuf[i];
  3915                     lastChar := mybuf[i];
  3378                     if (byte(mybuf[i]) = $0D) or (byte(mybuf[i]) = $0A) then
  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
  3379                         inComment := false
  3918                         inComment := false
  3380                 end;
  3919                 end;
  3381         end;
  3920         end;
  3382     ScriptLocaleReader:= mybuf
  3921     ScriptLocaleReader:= mybuf
  3383 end;
  3922 end;
  3384 // ⭒⭐⭒✨⭐⭒✨⭐☆✨⭐✨✧✨☆✨✧✨☆⭒✨☆⭐⭒☆✧✨⭒✨⭐✧⭒☆⭒✧☆✨✧⭐☆✨☆✧⭒✨✧⭒☆⭐☆✧
  3923 
  3385 
  3924 function ScriptLoad(name : shortstring; mustExist : boolean): boolean;
  3386 procedure ScriptLoad(name : shortstring);
       
  3387 var ret : LongInt;
  3925 var ret : LongInt;
  3388       s : shortstring;
  3926       s : shortstring;
  3389       f : PFSFile;
  3927       f : PFSFile;
  3390     buf : array[0..Pred(BUFSIZE)] of byte;
  3928     buf : array[0..Pred(BUFSIZE)] of byte;
  3391 begin
  3929 begin
  3396 wordCount:= 0;
  3934 wordCount:= 0;
  3397 locSum:= 0;
  3935 locSum:= 0;
  3398 s:= cPathz[ptData] + name;
  3936 s:= cPathz[ptData] + name;
  3399 if not pfsExists(s) then
  3937 if not pfsExists(s) then
  3400     begin
  3938     begin
  3401     AddFileLog('[LUA] Script not found: ' + name);
  3939     if mustExist then
       
  3940         OutError('Script not found: ' + name, true)
       
  3941     else
       
  3942         AddFileLog('[LUA] Script not found: ' + name);
       
  3943     ScriptLoad:= false;
  3402     exit;
  3944     exit;
  3403     end;
  3945     end;
  3404 
  3946 
  3405 f:= pfsOpenRead(s);
  3947 f:= pfsOpenRead(s);
  3406 if f = nil then
  3948 if f = nil then
  3407     exit;
  3949     OutError('Error reading script: ' + name, true);
  3408 
  3950 
  3409 hedgewarsMountPackage(Str2PChar(copy(s, 1, length(s)-4)+'.hwp'));
  3951 hedgewarsMountPackage(Str2PChar(copy(s, 3, length(s)-6)+'.hwp'));
  3410 
  3952 
  3411 physfsReaderSetBuffer(@buf);
  3953 physfsReaderSetBuffer(@buf);
  3412 if Pos('Locale/',s) <> 0 then
  3954 if (Pos('Locale/',s) <> 0) or (s = 'Scripts/OfficialChallengeHashes.lua') then
  3413      ret:= lua_load(luaState, @ScriptLocaleReader, f, Str2PChar(s))
  3955      ret:= lua_load(luaState, @ScriptLocaleReader, f, Str2PChar(s))
  3414 else ret:= lua_load(luaState, @ScriptReader, f, Str2PChar(s));
  3956 else
       
  3957     begin
       
  3958     SetRandomSeed(cSeed,true);
       
  3959     ret:= lua_load(luaState, @ScriptReader, f, Str2PChar(s))
       
  3960     end;
  3415 pfsClose(f);
  3961 pfsClose(f);
  3416 
  3962 
  3417 if ret <> 0 then
  3963 if ret <> 0 then
  3418     begin
  3964     begin
  3419     LuaError('Failed to load ' + name + '(error ' + IntToStr(ret) + ')');
  3965     LuaError('Failed to load ' + name + '(error ' + IntToStr(ret) + ')');
  3420     LuaError(lua_tostring(luaState, -1));
  3966     LuaError(lua_tostring(luaState, -1));
       
  3967     ScriptLoad:= false;
  3421     end
  3968     end
  3422 else
  3969 else
  3423     begin
  3970     begin
  3424     WriteLnToConsole('Lua: ' + name + ' loaded');
  3971     WriteLnToConsole('Lua: ' + name + ' loaded');
  3425     // call the script file
  3972     // call the script file
  3426     lua_pcall(luaState, 0, 0, 0);
  3973     lua_pcall(luaState, 0, 0, 0);
  3427     ScriptLoaded:= true
  3974     ScriptLoaded:= true;
       
  3975     ScriptLoad:= true;
  3428     end;
  3976     end;
  3429 end;
  3977 end;
  3430 
  3978 
  3431 procedure SetGlobals;
  3979 procedure SetGlobals;
  3432 var x, y: LongInt;
  3980 var x, y: LongInt;
  3433 begin
  3981 begin
  3434 ScriptSetInteger('TurnTimeLeft', TurnTimeLeft);
  3982 ScriptSetInteger('TurnTimeLeft', TurnTimeLeft);
  3435 ScriptSetInteger('ReadyTimeLeft', ReadyTimeLeft);
  3983 ScriptSetInteger('ReadyTimeLeft', ReadyTimeLeft);
  3436 ScriptSetInteger('GameTime', GameTicks);
  3984 ScriptSetInteger('GameTime', GameTicks);
  3437 ScriptSetInteger('TotalRounds', TotalRounds);
  3985 ScriptSetInteger('TotalRounds', TotalRoundsReal);
  3438 ScriptSetInteger('WaterLine', cWaterLine);
  3986 ScriptSetInteger('WaterLine', cWaterLine);
  3439 if isCursorVisible and (not bShowAmmoMenu) then
  3987 if isCursorVisible and (not bShowAmmoMenu) then
  3440     begin
  3988     begin
  3441     x:= CursorPoint.X - WorldDx;
  3989     x:= CursorPoint.X - WorldDx;
  3442     y:= cScreenHeight - CursorPoint.Y - WorldDy;
  3990     y:= cScreenHeight - CursorPoint.Y - WorldDy;
  3455     ScriptSetInteger('CursorY', NoPointX);
  4003     ScriptSetInteger('CursorY', NoPointX);
  3456     PrevCursorX:= NoPointX;
  4004     PrevCursorX:= NoPointX;
  3457     PrevCursorY:= NoPointX
  4005     PrevCursorY:= NoPointX
  3458     end;
  4006     end;
  3459 
  4007 
  3460 if not mapDims then
       
  3461     begin
       
  3462     mapDims:= true;
       
  3463     ScriptSetInteger('LAND_WIDTH', LAND_WIDTH);
       
  3464     ScriptSetInteger('LAND_HEIGHT', LAND_HEIGHT);
       
  3465     ScriptSetInteger('LeftX', leftX);
       
  3466     ScriptSetInteger('RightX', rightX);
       
  3467     ScriptSetInteger('TopY', topY)
       
  3468     end;
       
  3469 if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) then
  4008 if (CurrentHedgehog <> nil) and (CurrentHedgehog^.Gear <> nil) then
  3470     ScriptSetInteger('CurrentHedgehog', CurrentHedgehog^.Gear^.UID)
  4009     ScriptSetInteger('CurrentHedgehog', CurrentHedgehog^.Gear^.UID)
  3471 else
  4010 else
  3472     ScriptSetNil('CurrentHedgehog');
  4011     ScriptSetNil('CurrentHedgehog');
  3473 end;
  4012 end;
  3474 
  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 
  3475 procedure GetGlobals;
  4023 procedure GetGlobals;
  3476 begin
  4024 var currentTTL, currentRTL, newTTL, newRTL: LongInt;
  3477 // TODO
  4025 begin
  3478 // Use setters instead, because globals should be read-only!
  4026 // Setting TurnTimeLeft and ReadyTimeLeft should now be done in the setter functions.
  3479 // Otherwise globals might be changed by Lua, but then unexpectatly overwritten by engine when a ScriptCall is triggered by whatever Lua is doing!
  4027 // SetTurnTimeLeft and SetReadTimeLeft.
  3480 // Sure, one could work around that in engine (e.g. by setting writable globals in SetGlobals only when their engine-side value has actually changed since SetGlobals was called the last time...), but things just get messier and messier then.
  4028 // GetGloals should be removed in a future release.
  3481 // It is inconsistent anyway to have some globals be read-only and others not with no indication whatsoever.
  4029 
  3482 // -- sheepluva
  4030 // DEPRECATED: Read TurnTimeLeft and ReadyTimeLeft from script directly.
  3483 TurnTimeLeft:= ScriptGetInteger('TurnTimeLeft');
  4031 // TODO: Remove this behaviour in a future version.
  3484 ReadyTimeLeft:= ScriptGetInteger('ReadyTimeLeft');
  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;
  3485 end;
  4061 end;
  3486 
  4062 
  3487 procedure ScriptCall(fname : shortstring);
  4063 procedure ScriptCall(fname : shortstring);
  3488 begin
  4064 begin
  3489 if (not ScriptLoaded) or (not ScriptExists(fname)) then
  4065 if (not ScriptLoaded) or (not ScriptExists(fname)) then
  3596 ScriptAmmoProbability[ord(ammo)]:= inttostr(probability)[1];
  4172 ScriptAmmoProbability[ord(ammo)]:= inttostr(probability)[1];
  3597 ScriptSetAmmoDelay(ammo, delay);
  4173 ScriptSetAmmoDelay(ammo, delay);
  3598 ScriptAmmoReinforcement[ord(ammo)]:= inttostr(reinforcement)[1];
  4174 ScriptAmmoReinforcement[ord(ammo)]:= inttostr(reinforcement)[1];
  3599 end;
  4175 end;
  3600 
  4176 
  3601 procedure ScriptSetAmmoDelay(ammo : TAmmoType; delay: Byte);
  4177 procedure ScriptSetAmmoDelay(ammo : TAmmoType; delay: LongWord);
  3602 begin
  4178 begin
  3603 // change loadout string if ammo store has not been initialized yet
  4179 // change loadout string if ammo store has not been initialized yet
  3604 if (StoreCnt = 0) then
  4180 if (StoreCnt = 0) then
  3605 begin
  4181     begin
  3606     if (delay <= 9) then
  4182     if (delay <= 9) then
  3607         ScriptAmmoDelay[ord(ammo)]:= inttostr(delay)[1];
  4183         ScriptAmmoDelay[ord(ammo)]:= inttostr(delay)[1];
  3608 end
  4184     end
  3609 // change 'live' delay values
  4185 // change 'live' delay values
  3610 else if (CurrentTeam <> nil) then
  4186 else if (CurrentTeam <> nil) then
  3611         ammoz[ammo].SkipTurns:= CurrentTeam^.Clan^.TurnNumber + delay;
  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;
  3612 end;
  4193 end;
  3613 
  4194 
  3614 procedure ScriptApplyAmmoStore;
  4195 procedure ScriptApplyAmmoStore;
  3615 var i, j, k : LongInt;
  4196 var i, j, k : LongInt;
  3616 begin
  4197 begin
  3686 luaopen_string(luaState);
  4267 luaopen_string(luaState);
  3687 luaopen_math(luaState);
  4268 luaopen_math(luaState);
  3688 luaopen_table(luaState);
  4269 luaopen_table(luaState);
  3689 
  4270 
  3690 // import some variables
  4271 // import some variables
  3691 ScriptSetString(_S'LOCALE', cLocale);
  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));
  3692 
  4285 
  3693 // import game flags
  4286 // import game flags
  3694 ScriptSetInteger('gfSwitchHog', gfSwitchHog);
  4287 ScriptSetInteger('gfSwitchHog', gfSwitchHog);
  3695 ScriptSetInteger('gfMultiWeapon', gfMultiWeapon);
  4288 ScriptSetInteger('gfMultiWeapon', gfMultiWeapon);
  3696 ScriptSetInteger('gfSolidLand', gfSolidLand);
  4289 ScriptSetInteger('gfSolidLand', gfSolidLand);
  3739 // speech bubbles
  4332 // speech bubbles
  3740 ScriptSetInteger('SAY_SAY', 1);
  4333 ScriptSetInteger('SAY_SAY', 1);
  3741 ScriptSetInteger('SAY_THINK', 2);
  4334 ScriptSetInteger('SAY_THINK', 2);
  3742 ScriptSetInteger('SAY_SHOUT', 3);
  4335 ScriptSetInteger('SAY_SHOUT', 3);
  3743 
  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 
  3744 // register gear types
  4345 // register gear types
  3745 for at:= Low(TGearType) to High(TGearType) do
  4346 for at:= Low(TGearType) to High(TGearType) do
  3746     ScriptSetInteger(EnumToStr(at), ord(at));
  4347     ScriptSetInteger(EnumToStr(at), ord(at));
  3747 
  4348 
  3748 for vgt:= Low(TVisualGearType) to High(TVisualGearType) do
  4349 for vgt:= Low(TVisualGearType) to High(TVisualGearType) do
  3771 for mg:= Low(TMapGen) to High(TMapGen) do
  4372 for mg:= Low(TMapGen) to High(TMapGen) do
  3772     ScriptSetInteger(EnumToStr(mg), ord(mg));
  4373     ScriptSetInteger(EnumToStr(mg), ord(mg));
  3773 
  4374 
  3774 for we:= Low(TWorldEdge) to High(TWorldEdge) do
  4375 for we:= Low(TWorldEdge) to High(TWorldEdge) do
  3775     ScriptSetInteger(EnumToStr(we), ord(we));
  4376     ScriptSetInteger(EnumToStr(we), ord(we));
       
  4377 
       
  4378 ScriptSetLongWord('capcolDefault'   , capcolDefaultLua);
       
  4379 ScriptSetLongWord('capcolSetting'   , capcolSettingLua);
  3776 
  4380 
  3777 ScriptSetInteger('gstDrowning'      , gstDrowning);
  4381 ScriptSetInteger('gstDrowning'      , gstDrowning);
  3778 ScriptSetInteger('gstHHDriven'      , gstHHDriven);
  4382 ScriptSetInteger('gstHHDriven'      , gstHHDriven);
  3779 ScriptSetInteger('gstMoving'        , gstMoving);
  4383 ScriptSetInteger('gstMoving'        , gstMoving);
  3780 ScriptSetInteger('gstAttacked'      , gstAttacked);
  4384 ScriptSetInteger('gstAttacked'      , gstAttacked);
  3806 ScriptSetInteger('lfIndestructible', lfIndestructible);
  4410 ScriptSetInteger('lfIndestructible', lfIndestructible);
  3807 ScriptSetInteger('lfIce'           , lfIce);
  4411 ScriptSetInteger('lfIce'           , lfIce);
  3808 ScriptSetInteger('lfBouncy'        , lfBouncy);
  4412 ScriptSetInteger('lfBouncy'        , lfBouncy);
  3809 
  4413 
  3810 ScriptSetInteger('lfLandMask'      , lfLandMask);
  4414 ScriptSetInteger('lfLandMask'      , lfLandMask);
  3811 ScriptSetInteger('lfCurrentHog'    , lfCurrentHog);
  4415 ScriptSetInteger('lfCurHogCrate'   , lfCurHogCrate);
  3812 ScriptSetInteger('lfHHMask'        , lfHHMask);
  4416 ScriptSetInteger('lfHHMask'        , lfHHMask);
  3813 ScriptSetInteger('lfNotHHObjMask'  , lfNotHHObjMask);
  4417 ScriptSetInteger('lfNotHHObjMask'  , lfNotHHObjMask);
  3814 ScriptSetInteger('lfAllObjMask'    , lfAllObjMask);
  4418 ScriptSetInteger('lfAllObjMask'    , lfAllObjMask);
  3815 
  4419 
  3816 // explosion constants
  4420 // explosion constants
  3819 ScriptSetInteger('EXPLDoNotTouchHH' , EXPLDoNotTouchHH);
  4423 ScriptSetInteger('EXPLDoNotTouchHH' , EXPLDoNotTouchHH);
  3820 ScriptSetInteger('EXPLDontDraw'     , EXPLDontDraw);
  4424 ScriptSetInteger('EXPLDontDraw'     , EXPLDontDraw);
  3821 ScriptSetInteger('EXPLNoGfx'        , EXPLNoGfx);
  4425 ScriptSetInteger('EXPLNoGfx'        , EXPLNoGfx);
  3822 ScriptSetInteger('EXPLPoisoned'     , EXPLPoisoned);
  4426 ScriptSetInteger('EXPLPoisoned'     , EXPLPoisoned);
  3823 ScriptSetInteger('EXPLDoNotTouchAny', EXPLDoNotTouchAny);
  4427 ScriptSetInteger('EXPLDoNotTouchAny', EXPLDoNotTouchAny);
       
  4428 ScriptSetInteger('EXPLForceDraw'    , EXPLForceDraw);
  3824 
  4429 
  3825 // register functions
  4430 // register functions
  3826 lua_register(luaState, _P'HideHog', @lc_hidehog);
  4431 lua_register(luaState, _P'HideHog', @lc_hidehog);
  3827 lua_register(luaState, _P'RestoreHog', @lc_restorehog);
  4432 lua_register(luaState, _P'RestoreHog', @lc_restorehog);
       
  4433 lua_register(luaState, _P'IsHogHidden', @lc_ishoghidden);
  3828 lua_register(luaState, _P'SaveCampaignVar', @lc_savecampaignvar);
  4434 lua_register(luaState, _P'SaveCampaignVar', @lc_savecampaignvar);
  3829 lua_register(luaState, _P'GetCampaignVar', @lc_getcampaignvar);
  4435 lua_register(luaState, _P'GetCampaignVar', @lc_getcampaignvar);
       
  4436 lua_register(luaState, _P'SaveMissionVar', @lc_savemissionvar);
       
  4437 lua_register(luaState, _P'GetMissionVar', @lc_getmissionvar);
  3830 lua_register(luaState, _P'band', @lc_band);
  4438 lua_register(luaState, _P'band', @lc_band);
  3831 lua_register(luaState, _P'bor', @lc_bor);
  4439 lua_register(luaState, _P'bor', @lc_bor);
  3832 lua_register(luaState, _P'bnot', @lc_bnot);
  4440 lua_register(luaState, _P'bnot', @lc_bnot);
  3833 lua_register(luaState, _P'div', @lc_div);
  4441 lua_register(luaState, _P'div', @lc_div);
  3834 lua_register(luaState, _P'GetInputMask', @lc_getinputmask);
  4442 lua_register(luaState, _P'GetInputMask', @lc_getinputmask);
  3879 lua_register(luaState, _P'HideMission', @lc_hidemission);
  4487 lua_register(luaState, _P'HideMission', @lc_hidemission);
  3880 lua_register(luaState, _P'SetAmmoTexts', @lc_setammotexts);
  4488 lua_register(luaState, _P'SetAmmoTexts', @lc_setammotexts);
  3881 lua_register(luaState, _P'SetAmmoDescriptionAppendix', @lc_setammodescriptionappendix);
  4489 lua_register(luaState, _P'SetAmmoDescriptionAppendix', @lc_setammodescriptionappendix);
  3882 lua_register(luaState, _P'AddCaption', @lc_addcaption);
  4490 lua_register(luaState, _P'AddCaption', @lc_addcaption);
  3883 lua_register(luaState, _P'SetAmmo', @lc_setammo);
  4491 lua_register(luaState, _P'SetAmmo', @lc_setammo);
       
  4492 lua_register(luaState, _P'GetAmmo', @lc_getammo);
  3884 lua_register(luaState, _P'SetAmmoDelay', @lc_setammodelay);
  4493 lua_register(luaState, _P'SetAmmoDelay', @lc_setammodelay);
       
  4494 lua_register(luaState, _P'SetAmmoSlot', @lc_setammoslot);
  3885 lua_register(luaState, _P'PlaySound', @lc_playsound);
  4495 lua_register(luaState, _P'PlaySound', @lc_playsound);
       
  4496 lua_register(luaState, _P'PlayMusicSound', @lc_playmusicsound);
       
  4497 lua_register(luaState, _P'StopMusicSound', @lc_stopmusicsound);
  3886 lua_register(luaState, _P'SetSoundMask', @lc_setsoundmask);
  4498 lua_register(luaState, _P'SetSoundMask', @lc_setsoundmask);
  3887 lua_register(luaState, _P'GetTeamName', @lc_getteamname);
  4499 lua_register(luaState, _P'GetTeamName', @lc_getteamname);
  3888 lua_register(luaState, _P'GetTeamIndex', @lc_getteamindex);
  4500 lua_register(luaState, _P'GetTeamIndex', @lc_getteamindex);
  3889 lua_register(luaState, _P'GetTeamClan', @lc_getteamclan);
  4501 lua_register(luaState, _P'GetTeamClan', @lc_getteamclan);
  3890 lua_register(luaState, _P'AddTeam', @lc_addteam);
  4502 lua_register(luaState, _P'AddTeam', @lc_addteam);
       
  4503 lua_register(luaState, _P'AddMissionTeam', @lc_addmissionteam);
  3891 lua_register(luaState, _P'SetTeamLabel', @lc_setteamlabel);
  4504 lua_register(luaState, _P'SetTeamLabel', @lc_setteamlabel);
       
  4505 lua_register(luaState, _P'SetTeamPassive', @lc_setteampassive);
  3892 lua_register(luaState, _P'AddHog', @lc_addhog);
  4506 lua_register(luaState, _P'AddHog', @lc_addhog);
       
  4507 lua_register(luaState, _P'AddMissionHog', @lc_addmissionhog);
  3893 lua_register(luaState, _P'AddAmmo', @lc_addammo);
  4508 lua_register(luaState, _P'AddAmmo', @lc_addammo);
  3894 lua_register(luaState, _P'GetAmmoCount', @lc_getammocount);
  4509 lua_register(luaState, _P'GetAmmoCount', @lc_getammocount);
  3895 lua_register(luaState, _P'HealHog', @lc_healhog);
  4510 lua_register(luaState, _P'HealHog', @lc_healhog);
  3896 lua_register(luaState, _P'SetHealth', @lc_sethealth);
  4511 lua_register(luaState, _P'SetHealth', @lc_sethealth);
  3897 lua_register(luaState, _P'GetHealth', @lc_gethealth);
  4512 lua_register(luaState, _P'GetHealth', @lc_gethealth);
  3902 lua_register(luaState, _P'SetClanColor', @lc_setclancolor);
  4517 lua_register(luaState, _P'SetClanColor', @lc_setclancolor);
  3903 lua_register(luaState, _P'GetHogVoicepack', @lc_gethogvoicepack);
  4518 lua_register(luaState, _P'GetHogVoicepack', @lc_gethogvoicepack);
  3904 lua_register(luaState, _P'GetHogFlag', @lc_gethogflag);
  4519 lua_register(luaState, _P'GetHogFlag', @lc_gethogflag);
  3905 lua_register(luaState, _P'GetHogFort', @lc_gethogfort);
  4520 lua_register(luaState, _P'GetHogFort', @lc_gethogfort);
  3906 lua_register(luaState, _P'GetHogGrave', @lc_gethoggrave);
  4521 lua_register(luaState, _P'GetHogGrave', @lc_gethoggrave);
       
  4522 lua_register(luaState, _P'IsHogAlive', @lc_ishogalive);
  3907 lua_register(luaState, _P'IsHogLocal', @lc_ishoglocal);
  4523 lua_register(luaState, _P'IsHogLocal', @lc_ishoglocal);
  3908 lua_register(luaState, _P'GetHogTeamName', @lc_gethogteamname);
  4524 lua_register(luaState, _P'GetHogTeamName', @lc_gethogteamname);
  3909 lua_register(luaState, _P'SetHogTeamName', @lc_sethogteamname);
  4525 lua_register(luaState, _P'SetHogTeamName', @lc_sethogteamname);
  3910 lua_register(luaState, _P'GetHogName', @lc_gethogname);
  4526 lua_register(luaState, _P'GetHogName', @lc_gethogname);
  3911 lua_register(luaState, _P'SetHogName', @lc_sethogname);
  4527 lua_register(luaState, _P'SetHogName', @lc_sethogname);
  3926 lua_register(luaState, _P'GetFlightTime', @lc_getflighttime);
  4542 lua_register(luaState, _P'GetFlightTime', @lc_getflighttime);
  3927 lua_register(luaState, _P'SetZoom', @lc_setzoom);
  4543 lua_register(luaState, _P'SetZoom', @lc_setzoom);
  3928 lua_register(luaState, _P'GetZoom', @lc_getzoom);
  4544 lua_register(luaState, _P'GetZoom', @lc_getzoom);
  3929 lua_register(luaState, _P'HogSay', @lc_hogsay);
  4545 lua_register(luaState, _P'HogSay', @lc_hogsay);
  3930 lua_register(luaState, _P'SwitchHog', @lc_switchhog);
  4546 lua_register(luaState, _P'SwitchHog', @lc_switchhog);
       
  4547 lua_register(luaState, _P'EnableSwitchHog', @lc_enableswitchhog);
  3931 lua_register(luaState, _P'HogTurnLeft', @lc_hogturnleft);
  4548 lua_register(luaState, _P'HogTurnLeft', @lc_hogturnleft);
  3932 lua_register(luaState, _P'GetGearElasticity', @lc_getgearelasticity);
  4549 lua_register(luaState, _P'GetGearElasticity', @lc_getgearelasticity);
  3933 lua_register(luaState, _P'SetGearElasticity', @lc_setgearelasticity);
  4550 lua_register(luaState, _P'SetGearElasticity', @lc_setgearelasticity);
  3934 lua_register(luaState, _P'GetGearFriction', @lc_getgearfriction);
  4551 lua_register(luaState, _P'GetGearFriction', @lc_getgearfriction);
  3935 lua_register(luaState, _P'SetGearFriction', @lc_setgearfriction);
  4552 lua_register(luaState, _P'SetGearFriction', @lc_setgearfriction);
  3958 lua_register(luaState, _P'SetNextWeapon', @lc_setnextweapon);
  4575 lua_register(luaState, _P'SetNextWeapon', @lc_setnextweapon);
  3959 lua_register(luaState, _P'SetWeapon', @lc_setweapon);
  4576 lua_register(luaState, _P'SetWeapon', @lc_setweapon);
  3960 lua_register(luaState, _P'SetCinematicMode', @lc_setcinematicmode);
  4577 lua_register(luaState, _P'SetCinematicMode', @lc_setcinematicmode);
  3961 lua_register(luaState, _P'SetMaxBuildDistance', @lc_setmaxbuilddistance);
  4578 lua_register(luaState, _P'SetMaxBuildDistance', @lc_setmaxbuilddistance);
  3962 lua_register(luaState, _P'GetAmmoName', @lc_getammoname);
  4579 lua_register(luaState, _P'GetAmmoName', @lc_getammoname);
       
  4580 lua_register(luaState, _P'GetAmmoTimer', @lc_getammotimer);
  3963 lua_register(luaState, _P'SetVampiric', @lc_setvampiric);
  4581 lua_register(luaState, _P'SetVampiric', @lc_setvampiric);
       
  4582 lua_register(luaState, _P'GetVampiric', @lc_getvampiric);
  3964 lua_register(luaState, _P'SetLaserSight', @lc_setlasersight);
  4583 lua_register(luaState, _P'SetLaserSight', @lc_setlasersight);
       
  4584 lua_register(luaState, _P'GetLaserSight', @lc_getlasersight);
  3965 lua_register(luaState, _P'Explode', @lc_explode);
  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);
  3966 // drawn map functions
  4590 // drawn map functions
  3967 lua_register(luaState, _P'AddPoint', @lc_addPoint);
  4591 lua_register(luaState, _P'AddPoint', @lc_addPoint);
  3968 lua_register(luaState, _P'FlushPoints', @lc_flushPoints);
  4592 lua_register(luaState, _P'FlushPoints', @lc_flushPoints);
  3969 
  4593 
  3970 lua_register(luaState, _P'SetGearAIHints', @lc_setgearaihints);
  4594 lua_register(luaState, _P'SetGearAIHints', @lc_setgearaihints);
  4082 begin
  4706 begin
  4083 end;
  4707 end;
  4084 
  4708 
  4085 procedure initModule;
  4709 procedure initModule;
  4086 begin
  4710 begin
  4087 mapDims:= false;
       
  4088 PointsBuffer:= '';
  4711 PointsBuffer:= '';
  4089 PrevCursorX:= NoPointX;
  4712 PrevCursorX:= NoPointX;
  4090 PrevCursorY:= NoPointX;
  4713 PrevCursorY:= NoPointX;
       
  4714 isPendingTurnTimeLeft:= false;
       
  4715 isPendingReadyTimeLeft:= false;
  4091 end;
  4716 end;
  4092 
  4717 
  4093 procedure freeModule;
  4718 procedure freeModule;
  4094 begin
  4719 begin
  4095 end;
  4720 end;