diff -r 31570b766315 -r ed5a6478e710 hedgewars/uScript.pas --- a/hedgewars/uScript.pas Tue Nov 10 18:16:35 2015 +0100 +++ b/hedgewars/uScript.pas Tue Nov 10 20:43:13 2015 +0100 @@ -1,6 +1,6 @@ (* * Hedgewars, a free turn based strategy game - * Copyright (c) 2004-2013 Andrey Korotaev + * Copyright (c) 2004-2015 Andrey Korotaev * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -13,7 +13,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *) {$INCLUDE "options.inc"} @@ -35,9 +35,11 @@ procedure ScriptClearStack; procedure ScriptLoad(name : shortstring); +procedure ScriptOnPreviewInit; procedure ScriptOnGameInit; procedure ScriptOnScreenResize; procedure ScriptSetInteger(name : shortstring; value : LongInt); +procedure ScriptSetString(name : shortstring; value : shortstring); procedure ScriptCall(fname : shortstring); function ScriptCall(fname : shortstring; par1: LongInt) : LongInt; @@ -46,6 +48,7 @@ function ScriptCall(fname : shortstring; par1, par2, par3, par4 : LongInt) : LongInt; function ScriptExists(fname : shortstring) : boolean; +procedure LuaParseString(s: shortString); //function ParseCommandOverride(key, value : shortstring) : shortstring; This did not work out well @@ -85,7 +88,10 @@ uVisualGearsList, uGearsHandlersMess, uPhysFSLayer, - typinfo + SDLh +{$IFNDEF PAS2C} + , typinfo +{$ENDIF} ; var luaState : Plua_State; @@ -95,22 +101,241 @@ ScriptAmmoReinforcement : shortstring; ScriptLoaded : boolean; mapDims : boolean; + PointsBuffer: shortstring; + prevCursorPoint: TPoint; // why is tpoint still in sdlh... procedure ScriptPrepareAmmoStore; forward; procedure ScriptApplyAmmoStore; forward; procedure ScriptSetAmmo(ammo : TAmmoType; count, probability, delay, reinforcement: Byte); forward; procedure ScriptSetAmmoDelay(ammo : TAmmoType; delay: Byte); forward; +var LuaDebugInfo: lua_Debug; + +procedure SetGlobals; forward; +procedure LuaParseString(s: shortString); +begin + SetGlobals; + AddFileLog('[Lua] input string: ' + s); + AddChatString(#3 + '[Lua] > ' + s); + if luaL_dostring(luaState, Str2PChar(s)) <> 0 then + begin + AddFileLog('[Lua] input string parsing error!'); + AddChatString(#5 + '[Lua] Error while parsing!'); + end; +end; + +function LuaUpdateDebugInfo(): Boolean; +begin + FillChar(LuaDebugInfo, sizeof(LuaDebugInfo), 0); + + if lua_getstack(luaState, 1, @LuaDebugInfo) = 0 then + exit(false); // stack not deep enough + + // get source name and line count + lua_getinfo(luaState, PChar('Sl'), @LuaDebugInfo); + exit(true); +end; + procedure LuaError(s: shortstring); +var src: shortstring; +const + maxsrclen = 20; begin + if LuaUpdateDebugInfo() then + begin + src:= StrPas(LuaDebugInfo.source); + s:= 'LUA ERROR [ ... ' + + copy(src, Length(src) - maxsrclen, maxsrclen - 3) + ':' + + inttostr(LuaDebugInfo.currentLine) + ']: ' + s; + end + else + s:= 'LUA ERROR: ' + s; WriteLnToConsole(s); AddChatString(#5 + s); + if cTestLua then + halt(HaltTestLuaError); +end; + +procedure LuaCallError(error, call, paramsyntax: shortstring); +begin + LuaError(call + ': ' + error); + LuaError('-- SYNTAX: ' + call + ' ( ' + paramsyntax + ' )'); +end; + +procedure LuaParameterCountError(expected, call, paramsyntax: shortstring; wrongcount: LongInt); inline; +begin + // TODO: i18n? + LuaCallError('Wrong number of parameters! (is: ' + inttostr(wrongcount) + ', should be: '+ expected + ')', call, paramsyntax); +end; + +// compare with allowed count +function CheckLuaParamCount(L : Plua_State; count: LongInt; call, paramsyntax: shortstring): boolean; inline; +var c: LongInt; +begin + c:= lua_gettop(L); + if c <> count then + begin + LuaParameterCountError('exactly ' + inttostr(count), call, paramsyntax, c); + exit(false); + end; + + CheckLuaParamCount:= true; +end; + +// check if is either count1 or count2 +function CheckAndFetchParamCount(L : Plua_State; count1, count2: LongInt; call, paramsyntax: shortstring; out actual: LongInt): boolean; inline; +begin + actual:= lua_gettop(L); + if (actual <> count1) and (actual <> count2) then + begin + LuaParameterCountError('either ' + inttostr(count1) + ' or ' + inttostr(count2), call, paramsyntax, actual); + exit(false); + end; + + CheckAndFetchParamCount:= true; +end; + +// check if is in range of count1 and count2 +function CheckAndFetchParamCountRange(L : Plua_State; count1, count2: LongInt; call, paramsyntax: shortstring; out actual: LongInt): boolean; inline; +begin + actual:= lua_gettop(L); + if (actual < count1) or (actual > count2) then + begin + LuaParameterCountError('at least ' + inttostr(count1) + ', but at most ' + inttostr(count2), call, paramsyntax, actual); + exit(false); + end; + + CheckAndFetchParamCountRange:= true; +end; + +// check if is same or higher as minCount +function CheckAndFetchLuaParamMinCount(L : Plua_State; minCount: LongInt; call, paramsyntax: shortstring; out actual: LongInt): boolean; inline; +begin + actual:= lua_gettop(L); + if (actual < minCount) then + begin + LuaParameterCountError(inttostr(minCount) + ' or more', call, paramsyntax, actual); + exit(false); + end; + + CheckAndFetchLuaParamMinCount:= true; +end; + +function LuaToGearTypeOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline; +begin + if lua_isnoneornil(L, i) then i:= -1 + else i:= lua_tointeger(L, i); + if (i < ord(Low(TGearType))) or (i > ord(High(TGearType))) then + begin + LuaCallError('Invalid gearType!', call, paramsyntax); + LuaToGearTypeOrd:= -1; + end + else + LuaToGearTypeOrd:= i; end; -procedure LuaParameterCountError(call, paramsyntax: shortstring; wrongcount: LongInt); +function LuaToVisualGearTypeOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline; +begin + if lua_isnoneornil(L, i) then i:= -1 + else i:= lua_tointeger(L, i); + if (i < ord(Low(TVisualGearType))) or (i > ord(High(TVisualGearType))) then + begin + LuaCallError('Invalid visualGearType!', call, paramsyntax); + LuaToVisualGearTypeOrd:= -1; + end + else + LuaToVisualGearTypeOrd:= i; +end; + +function LuaToAmmoTypeOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline; +begin + if lua_isnoneornil(L, i) then i:= -1 + else i:= lua_tointeger(L, i); + if (i < ord(Low(TAmmoType))) or (i > ord(High(TAmmoType))) then + begin + LuaCallError('Invalid ammoType!', call, paramsyntax); + LuaToAmmoTypeOrd:= -1; + end + else + LuaToAmmoTypeOrd:= i; +end; + +function LuaToStatInfoTypeOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline; +begin + if lua_isnoneornil(L, i) then i:= -1 + else i:= lua_tointeger(L, i); + if (i < ord(Low(TStatInfoType))) or (i > ord(High(TStatInfoType))) then + begin + LuaCallError('Invalid statInfoType!', call, paramsyntax); + LuaToStatInfoTypeOrd:= -1; + end + else + LuaToStatInfoTypeOrd:= i; +end; + +function LuaToSoundOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline; begin - // TODO: i18n? - LuaError('Lua: Wrong number of parameters (' + inttostr(wrongcount) + ') passed to ' + call + '! syntax: ' + call + ' ( ' + paramsyntax + ' )'); + if lua_isnoneornil(L, i) then i:= -1 + else i:= lua_tointeger(L, i); + if (i < ord(Low(TSound))) or (i > ord(High(TSound))) then + begin + LuaCallError('Invalid soundId!', call, paramsyntax); + LuaToSoundOrd:= -1; + end + else + LuaToSoundOrd:= i; +end; + +function LuaToHogEffectOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline; +begin + if lua_isnoneornil(L, i) then i:= -1 + else i:= lua_tointeger(L, i); + if (i < ord(Low(THogEffect))) or (i > ord(High(THogEffect))) then + begin + LuaCallError('Invalid gear type!', call, paramsyntax); + LuaToHogEffectOrd:= -1; + end + else + LuaToHogEffectOrd:= i; +end; + +function LuaToCapGroupOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline; +begin + if lua_isnoneornil(L, i) then i:= -1 + else i:= lua_tointeger(L, i); + if (i < ord(Low(TCapGroup))) or (i > ord(High(TCapGroup))) then + begin + LuaCallError('Invalid capgroup type!', call, paramsyntax); + LuaToCapGroupOrd:= -1; + end + else + LuaToCapGroupOrd:= i; +end; + +function LuaToSpriteOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline; +begin + if lua_isnoneornil(L, i) then i:= -1 + else i:= lua_tointeger(L, i); + if (i < ord(Low(TSprite))) or (i > ord(High(TSprite))) then + begin + LuaCallError('Invalid sprite id!', call, paramsyntax); + LuaToSpriteOrd:= -1; + end + else + LuaToSpriteOrd:= i; +end; + +function LuaToMapGenOrd(L : Plua_State; i: LongInt; call, paramsyntax: shortstring): LongInt; inline; +begin + if lua_isnoneornil(L, i) then i:= -1 + else i:= lua_tointeger(L, i); + if (i < ord(Low(TMapGen))) or (i > ord(High(TMapGen))) then + begin + LuaCallError('Invalid mapgen id!', call, paramsyntax); + LuaToMapGenOrd:= -1; + end + else + LuaToMapGenOrd:= i; end; // wrapped calls // @@ -118,82 +343,65 @@ // functions called from Lua: // function(L : Plua_State) : LongInt; Cdecl; // where L contains the state, returns the number of return values on the stack -// call lua_gettop(L) to receive number of parameters passed +// call CheckLuaParamCount or CheckAndFetchParamCount +// to validate/get the number of passed arguments (see their call definitions) +// +// use as return value the number of variables pushed back to the lua script function lc_band(L: PLua_State): LongInt; Cdecl; begin - if lua_gettop(L) <> 2 then - begin - LuaParameterCountError('band', 'value1, value2', lua_gettop(L)); + if CheckLuaParamCount(L, 2, 'band', 'value1, value2') then + lua_pushinteger(L, lua_tointeger(L, 2) and lua_tointeger(L, 1)) + else lua_pushnil(L); - end - else - lua_pushinteger(L, lua_tointeger(L, 2) and lua_tointeger(L, 1)); lc_band := 1; end; function lc_bor(L: PLua_State): LongInt; Cdecl; begin - if lua_gettop(L) <> 2 then - begin - LuaParameterCountError('bor', 'value1, value2', lua_gettop(L)); + if CheckLuaParamCount(L, 2, 'bor', 'value1, value2') then + lua_pushinteger(L, lua_tointeger(L, 2) or lua_tointeger(L, 1)) + else lua_pushnil(L); - end - else - lua_pushinteger(L, lua_tointeger(L, 2) or lua_tointeger(L, 1)); lc_bor := 1; end; function lc_bnot(L: PLua_State): LongInt; Cdecl; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('bnot', 'value', lua_gettop(L)); + if CheckLuaParamCount(L, 1, 'bnot', 'value') then + lua_pushinteger(L, (not lua_tointeger(L, 1))) + else lua_pushnil(L); - end - else - lua_pushinteger(L, not lua_tointeger(L, 1)); lc_bnot := 1; end; function lc_div(L: PLua_State): LongInt; Cdecl; begin - if lua_gettop(L) <> 2 then - begin - LuaParameterCountError('div', 'dividend, divisor', lua_gettop(L)); + if CheckLuaParamCount(L, 2, 'div', 'dividend, divisor') then + lua_pushinteger(L, lua_tointeger(L, 1) div lua_tointeger(L, 2)) + else lua_pushnil(L); - end - else - lua_pushinteger(L, lua_tointeger(L, 1) div lua_tointeger(L, 2)); lc_div := 1; end; function lc_getinputmask(L : Plua_State) : LongInt; Cdecl; begin - if lua_gettop(L) <> 0 then - LuaParameterCountError('GetInputMask', '', lua_gettop(L)) - else + if CheckLuaParamCount(L, 0, 'GetInputMask', '') then lua_pushinteger(L, InputMask); lc_getinputmask:= 1 end; function lc_setinputmask(L : Plua_State) : LongInt; Cdecl; begin - if lua_gettop(L) <> 1 then - LuaParameterCountError('SetInputMask', 'mask', lua_gettop(L)) - else + if CheckLuaParamCount(L, 1, 'SetInputMask', 'mask') then InputMask:= lua_tointeger(L, 1); lc_setinputmask:= 0 end; function lc_writelntoconsole(L : Plua_State) : LongInt; Cdecl; begin - if lua_gettop(L) = 1 then - begin + if CheckLuaParamCount(L, 1, 'WriteLnToConsole', 'string') then WriteLnToConsole('Lua: ' + lua_tostring(L ,1)); - end - else - LuaParameterCountError('WriteLnToConsole', 'string', lua_gettop(L)); lc_writelntoconsole:= 0; end; @@ -202,29 +410,124 @@ i,c: LongWord; s: shortstring; begin - if lua_gettop(L) = 1 then + if CheckLuaParamCount(L, 1, 'ParseCommand', 'string') then begin - t:= lua_tolstring(L,1,@c); + t:= lua_tolstring(L, 1, Psize_t(@c)); for i:= 1 to c do s[i]:= t[i-1]; s[0]:= char(c); ParseCommand(s, true, true); - end - else - LuaParameterCountError('ParseCommand', 'string', lua_gettop(L)); + end; lc_parsecommand:= 0; end; +// sets weapon to the desired ammo type +function lc_setweapon(L : Plua_State) : LongInt; Cdecl; +var at: LongInt; +const + call = 'SetWeapon'; + params = 'ammoType'; +begin + // no point to run this without any CurrentHedgehog + if (CurrentHedgehog <> nil) and (CheckLuaParamCount(L, 1, call, params)) then + begin + at:= LuaToAmmoTypeOrd(L, 1, call, params); + if at >= 0 then + ParseCommand('setweap ' + char(at), true, true); + end; + lc_setweapon:= 0; +end; + +// no parameter means reset to default (and 0 means unlimited) +function lc_setmaxbuilddistance(L : Plua_State) : LongInt; Cdecl; +var np: LongInt; +const + call = 'SetMaxBuildDistance'; + params = '[ distInPx ]'; +begin + if CheckAndFetchParamCountRange(L, 0, 1, call, params, np) then + begin + if np = 0 then + begin + // no args? reset + cBuildMaxDist:= cDefaultBuildMaxDist; + end + else + CBuildMaxDist:= lua_tointeger(L, 1); + end; + lc_setmaxbuilddistance:= 0; +end; + +// sets weapon to whatever weapons is next (wraps around, amSkip is skipped) +function lc_setnextweapon(L : Plua_State) : LongInt; Cdecl; +var at : LongInt; + nextAmmo : TAmmo; + s, a, cs, fa: LongInt; +const + call = 'SetNextWeapon'; + params = ''; +begin + if (CurrentHedgehog <> nil) and (CheckLuaParamCount(L, 0, call, params)) then + begin + at:= -1; + with CurrentHedgehog^ do + begin + cs:= 0; // current slot + fa:= 0; // first ammo item to check + + // if something is selected, find it's successor + if curAmmoType <> amNothing then + begin + // get current slot index + cs:= Ammoz[CurAmmoType].Slot; + // find current ammo index + while (fa < cMaxSlotAmmoIndex) + and (Ammo^[cs, fa].AmmoType <> CurAmmoType) do + inc(fa); + // increase once more because we won't successor + inc(fa); + end; + + // find first available ammo + // revisit current slot too (current item might not be first) + for s:= cs to cs + cMaxSlotIndex + 1 do + begin + for a:= fa to cMaxSlotAmmoIndex do + begin + // check if we went full circle + if (a = fa) and (s = cs + cMaxSlotIndex + 1) then + exit(0); + + // get ammo + nextAmmo:= Ammo^[s mod (cMaxSlotIndex + 1), a]; + // only switch to ammos the hog actually has + if (nextAmmo.AmmoType <> amNothing) + and (nextAmmo.AmmoType <> amSkip) and (nextAmmo.Count > 0) then + begin + at:= ord(nextAmmo.AmmoType); + break; + end; + end; + // stop slot loop if something was found + if at >= 0 then + break; + // check following slots starting with first item + fa:= 0; + end; + end; + + if at >= 0 then + ParseCommand('setweap ' + char(at), true, true); + end; + lc_setnextweapon:= 0; +end; + function lc_showmission(L : Plua_State) : LongInt; Cdecl; begin - if lua_gettop(L) = 5 then - begin - ShowMission(lua_tostring(L, 1), lua_tostring(L, 2), lua_tostring(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5)); - end - else - LuaParameterCountError('ShowMission', 'caption, subcaption, text, icon, time', lua_gettop(L)); + if CheckLuaParamCount(L, 5, 'ShowMission', 'caption, subcaption, text, icon, time') then + ShowMission(lua_tostringA(L, 1), lua_tostringA(L, 2), lua_tostringA(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5)); lc_showmission:= 0; end; @@ -236,181 +539,189 @@ end; function lc_enablegameflags(L : Plua_State) : LongInt; Cdecl; -var i : integer; +var i, n : integer; begin - for i:= 1 to lua_gettop(L) do - GameFlags := GameFlags or LongWord(lua_tointeger(L, i)); - ScriptSetInteger('GameFlags', GameFlags); + // can have 1 or more arguments + if CheckAndFetchLuaParamMinCount(L, 1, 'EnableGameFlags', 'gameFlag, ... ', n) then + begin + for i:= 1 to n do + GameFlags := GameFlags or LongWord(lua_tointeger(L, i)); + ScriptSetInteger('GameFlags', GameFlags); + end; lc_enablegameflags:= 0; end; function lc_disablegameflags(L : Plua_State) : LongInt; Cdecl; -var i : integer; +var i , n: integer; begin - for i:= 1 to lua_gettop(L) do - GameFlags := GameFlags and not(LongWord(lua_tointeger(L, i))); - ScriptSetInteger('GameFlags', GameFlags); + // can have 1 or more arguments + if CheckAndFetchLuaParamMinCount(L, 1, 'DisableGameFlags', 'gameFlag, ... ', n) then + begin + for i:= 1 to n do + GameFlags := GameFlags and (not LongWord(lua_tointeger(L, i))); + ScriptSetInteger('GameFlags', GameFlags); + end; lc_disablegameflags:= 0; end; function lc_cleargameflags(L : Plua_State) : LongInt; Cdecl; begin - // Silence hint - L:= L; - GameFlags:= 0; - ScriptSetInteger('GameFlags', GameFlags); + if CheckLuaParamCount(L, 0, 'ClearGameFlags', '') then + begin + GameFlags:= 0; + ScriptSetInteger('GameFlags', GameFlags); + end; lc_cleargameflags:= 0; end; +function lc_getgameflag(L : Plua_State) : LongInt; Cdecl; +begin + if CheckLuaParamCount(L, 1, 'GetGameFlag', 'gameflag') then + lua_pushboolean(L, (GameFlags and LongWord(lua_tointeger(L, 1)) <> 0)) + else + lua_pushnil(L); + lc_getgameflag:= 1; +end; + function lc_addcaption(L : Plua_State) : LongInt; Cdecl; +var cg: LongInt; +const + call = 'AddCaption'; + params = 'text [, color, captiongroup]'; begin - if lua_gettop(L) = 1 then - AddCaption(lua_tostring(L, 1), cWhiteColor, capgrpMessage) - else if lua_gettop(L) = 3 then + if CheckAndFetchParamCount(L, 1, 3, call, params, cg) then begin - AddCaption(lua_tostring(L, 1), lua_tointeger(L, 2) shr 8, TCapGroup(lua_tointeger(L, 3))); - end - else - LuaParameterCountError('AddCaption', 'text[, color, captiongroup]', lua_gettop(L)); + if cg = 1 then + AddCaption(lua_tostringA(L, 1), cWhiteColor, capgrpMessage) + else + begin + cg:= LuaToCapGroupOrd(L, 3, call, params); + if cg >= 0 then + AddCaption(lua_tostringA(L, 1), lua_tointeger(L, 2) shr 8, TCapGroup(cg)); + end + end; lc_addcaption:= 0; end; function lc_campaignlock(L : Plua_State) : LongInt; Cdecl; begin - if lua_gettop(L) = 1 then + if CheckLuaParamCount(L, 1, 'CampaignLock', 'TODO') then begin - // to be done - end - else - LuaParameterCountError('CampaignLock', 'TODO', lua_gettop(L)); + // TODO + end; lc_campaignlock:= 0; end; function lc_campaignunlock(L : Plua_State) : LongInt; Cdecl; begin - if lua_gettop(L) = 1 then + if CheckLuaParamCount(L, 1, 'CampaignUnlock', 'TODO') then begin - // to be done - end - else - LuaParameterCountError('CampaignUnlock', 'TODO', lua_gettop(L)); + // TODO + end; lc_campaignunlock:= 0; end; function lc_spawnfakehealthcrate(L: Plua_State) : LongInt; Cdecl; var gear: PGear; begin - if lua_gettop(L) <> 4 then - begin - LuaParameterCountError('SpawnFakeHealthCrate', 'x, y, explode, poison', lua_gettop(L)); - lua_pushnil(L); - end - else + if CheckLuaParamCount(L, 4,'SpawnFakeHealthCrate', 'x, y, explode, poison') then begin gear := SpawnFakeCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), HealthCrate, lua_toboolean(L, 3), lua_toboolean(L, 4)); - lua_pushinteger(L, gear^.uid); - end; + if gear <> nil then + lua_pushinteger(L, gear^.uid) + else lua_pushnil(L) + end + else + lua_pushnil(L); lc_spawnfakehealthcrate := 1; end; function lc_spawnfakeammocrate(L: PLua_State): LongInt; Cdecl; var gear: PGear; begin - if lua_gettop(L) <> 4 then - begin - LuaParameterCountError('SpawnFakeAmmoCrate', 'x, y, explode, poison', lua_gettop(L)); - lua_pushnil(L); - end - else + if CheckLuaParamCount(L, 4,'SpawnFakeAmmoCrate', 'x, y, explode, poison') then begin gear := SpawnFakeCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), AmmoCrate, lua_toboolean(L, 3), lua_toboolean(L, 4)); - lua_pushinteger(L, gear^.uid); - end; + if gear <> nil then + lua_pushinteger(L, gear^.uid) + else lua_pushnil(L) + end + else + lua_pushnil(L); lc_spawnfakeammocrate := 1; end; function lc_spawnfakeutilitycrate(L: PLua_State): LongInt; Cdecl; var gear: PGear; begin - if lua_gettop(L) <> 4 then - begin - LuaParameterCountError('SpawnFakeUtilityCrate', 'x, y, explode, poison', lua_gettop(L)); - lua_pushnil(L); - end - else + if CheckLuaParamCount(L, 4,'SpawnFakeUtilityCrate', 'x, y, explode, poison') then begin gear := SpawnFakeCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), UtilityCrate, lua_toboolean(L, 3), lua_toboolean(L, 4)); - lua_pushinteger(L, gear^.uid); - end; + if gear <> nil then + lua_pushinteger(L, gear^.uid) + else lua_pushnil(L) + end + else + lua_pushnil(L); lc_spawnfakeutilitycrate := 1; end; function lc_spawnhealthcrate(L: Plua_State) : LongInt; Cdecl; var gear: PGear; -var health: LongInt; +var health, n: LongInt; begin - if (lua_gettop(L) < 2) or (lua_gettop(L) > 3) then + if CheckAndFetchParamCount(L, 2, 3, 'SpawnHealthCrate', 'x, y [, health]', n) then begin - LuaParameterCountError('SpawnHealthCrate', 'x, y[, health]', lua_gettop(L)); - lua_pushnil(L); - end - else - begin - if lua_gettop(L) = 3 then + if n = 3 then health:= lua_tointeger(L, 3) else health:= cHealthCaseAmount; gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), HealthCrate, health, 0); if gear <> nil then - lua_pushinteger(L, gear^.uid) - else - lua_pushnil(L); - end; + lua_pushinteger(L, gear^.uid) + else lua_pushnil(L); + end + else + lua_pushnil(L); lc_spawnhealthcrate := 1; end; function lc_spawnammocrate(L: PLua_State): LongInt; Cdecl; var gear: PGear; + n : LongInt; begin - if (lua_gettop(L) <> 3) and (lua_gettop(L) <> 4) then + if CheckAndFetchParamCount(L, 3, 4, 'SpawnAmmoCrate', 'x, y, content [, amount]', n) then begin - LuaParameterCountError('SpawnAmmoCrate', 'x, y, content[, amount]', lua_gettop(L)); - lua_pushnil(L); - end - else - begin - if (lua_gettop(L) = 3) then + if n = 3 then gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), AmmoCrate, lua_tointeger(L, 3), 0) else gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), AmmoCrate, lua_tointeger(L, 3), lua_tointeger(L, 4)); if gear <> nil then - lua_pushinteger(L, gear^.uid) - else - lua_pushnil(L); - end; + lua_pushinteger(L, gear^.uid) + else lua_pushnil(L); + end + else + lua_pushnil(L); lc_spawnammocrate := 1; end; function lc_spawnutilitycrate(L: PLua_State): LongInt; Cdecl; var gear: PGear; + n : LongInt; begin - if (lua_gettop(L) <> 3) and (lua_gettop(L) <> 4) then + if CheckAndFetchParamCount(L, 3, 4, 'SpawnUtilityCrate', 'x, y, content [, amount]', n) then begin - LuaParameterCountError('SpawnUtilityCrate', 'x, y, content[, amount]', lua_gettop(L)); - lua_pushnil(L); - end - else - begin - if (lua_gettop(L) = 3) then + if n = 3 then gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), UtilityCrate, lua_tointeger(L, 3), 0) else gear := SpawnCustomCrateAt(lua_tointeger(L, 1), lua_tointeger(L, 2), UtilityCrate, lua_tointeger(L, 3), lua_tointeger(L, 4)); if gear <> nil then - lua_pushinteger(L, gear^.uid) - else - lua_pushnil(L); - end; + lua_pushinteger(L, gear^.uid) + else lua_pushnil(L); + end + else + lua_pushnil(L); lc_spawnutilitycrate := 1; end; @@ -419,37 +730,39 @@ x, y, s, t: LongInt; dx, dy: hwFloat; gt: TGearType; +const + call = 'AddGear'; + params = 'x, y, gearType, state, dx, dy, timer'; begin - if lua_gettop(L) <> 7 then + if CheckLuaParamCount(L, 7, call, params) then begin - LuaParameterCountError('AddGear', 'x, y, gearType, state, dx, dy, timer', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) + t:= LuaToGearTypeOrd(L, 3, call, params); + if t >= 0 then + begin + gt:= TGearType(t); + x:= lua_tointeger(L, 1); + y:= lua_tointeger(L, 2); + s:= lua_tointeger(L, 4); + dx:= int2hwFloat(lua_tointeger(L, 5)) / 1000000; + dy:= int2hwFloat(lua_tointeger(L, 6)) / 1000000; + t:= lua_tointeger(L, 7); + + gear:= AddGear(x, y, gt, s, dx, dy, t); + lastGearByUID:= gear; + lua_pushinteger(L, gear^.uid) + end + else + lua_pushnil(L); end else - begin - x:= lua_tointeger(L, 1); - y:= lua_tointeger(L, 2); - gt:= TGearType(lua_tointeger(L, 3)); - s:= lua_tointeger(L, 4); - dx:= int2hwFloat(lua_tointeger(L, 5)) / 1000000; - dy:= int2hwFloat(lua_tointeger(L, 6)) / 1000000; - t:= lua_tointeger(L, 7); - - gear:= AddGear(x, y, gt, s, dx, dy, t); - lastGearByUID:= gear; - lua_pushinteger(L, gear^.uid) - end; + lua_pushnil(L); lc_addgear:= 1; // 1 return value end; function lc_deletegear(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('DeleteGear', 'gearUid', lua_gettop(L)); - end - else + if CheckLuaParamCount(L, 1, 'DeleteGear', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then @@ -460,61 +773,68 @@ function lc_addvisualgear(L : Plua_State) : LongInt; Cdecl; var vg : PVisualGear; - x, y, s: LongInt; + x, y, s, n, layer: LongInt; c: Boolean; vgt: TVisualGearType; + uid: Longword; +const + call = 'AddVisualGear'; + params = 'x, y, visualGearType, state, critical [, layer]'; begin - if lua_gettop(L) <> 5 then + uid:= 0; + if CheckAndFetchParamCount(L, 5, 6, call, params, n) then begin - LuaParameterCountError('AddVisualGear', 'x, y, visualGearType, state, critical', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) + s:= LuaToVisualGearTypeOrd(L, 3, call, params); + if s >= 0 then + begin + vgt:= TVisualGearType(s); + x:= lua_tointeger(L, 1); + y:= lua_tointeger(L, 2); + s:= lua_tointeger(L, 4); + c:= lua_toboolean(L, 5); + + if n = 6 then + begin + layer:= lua_tointeger(L, 6); + vg:= AddVisualGear(x, y, vgt, s, c, layer); + end + else + vg:= AddVisualGear(x, y, vgt, s, c); + + if vg <> nil then + begin + lastVisualGearByUID:= vg; + uid:= vg^.uid; + lua_pushinteger(L, uid); + end; + end + else + lua_pushnil(L); end else - begin - x:= lua_tointeger(L, 1); - y:= lua_tointeger(L, 2); - vgt:= TVisualGearType(lua_tointeger(L, 3)); - s:= lua_tointeger(L, 4); - c:= lua_toboolean(L, 5); - - vg:= AddVisualGear(x, y, vgt, s, c); - if vg <> nil then - begin - lastVisualGearByUID:= vg; - lua_pushinteger(L, vg^.uid) - end - else - lua_pushinteger(L, 0) - end; + lua_pushnil(L); // return value on stack (nil) lc_addvisualgear:= 1; // 1 return value end; function lc_deletevisualgear(L : Plua_State) : LongInt; Cdecl; var vg : PVisualGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('DeleteVisualGear', 'vgUid', lua_gettop(L)); - end - else + vg:= nil; + if CheckLuaParamCount(L, 1, 'DeleteVisualGear', 'vgUid') then begin vg:= VisualGearByUID(lua_tointeger(L, 1)); if vg <> nil then DeleteVisualGear(vg); end; - lc_deletevisualgear:= 0 + // allow caller to know whether there was something to delete + lua_pushboolean(L, vg <> nil); + lc_deletevisualgear:= 1 end; function lc_getvisualgearvalues(L : Plua_State) : LongInt; Cdecl; var vg: PVisualGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetVisualGearValues', 'vgUid', lua_gettop(L)); - lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); - lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L) - end - else + if CheckLuaParamCount(L, 1, 'GetVisualGearValues', 'vgUid') then begin vg:= VisualGearByUID(lua_tointeger(L, 1)); if vg <> nil then @@ -533,119 +853,238 @@ else begin lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); - lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L) + lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); end + end + else + begin + lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); + lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); end; - lc_getvisualgearvalues:= 10; + lc_getvisualgearvalues:= 10 end; function lc_setvisualgearvalues(L : Plua_State) : LongInt; Cdecl; var vg : PVisualGear; begin - if lua_gettop(L) <> 11 then - begin - LuaParameterCountError('SetVisualGearValues', 'vgUid, X, Y, dX, dY, Angle, Frame, FrameTicks, State, Timer, Tint', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else - begin +// Param count can be 1-11 at present +// if CheckLuaParamCount(L, 11, 'SetVisualGearValues', 'vgUid, X, Y, dX, dY, Angle, Frame, FrameTicks, State, Timer, Tint') then +// begin vg:= VisualGearByUID(lua_tointeger(L, 1)); if vg <> nil then begin - vg^.X:= lua_tointeger(L, 2); - vg^.Y:= lua_tointeger(L, 3); - vg^.dX:= lua_tonumber(L, 4); - vg^.dY:= lua_tonumber(L, 5); - vg^.Angle:= lua_tonumber(L, 6); - vg^.Frame:= lua_tointeger(L, 7); - if lua_tointeger(L, 8) <> 0 then - vg^.FrameTicks:= lua_tointeger(L, 8); // find a better way to do this. maybe need to break all these up. - vg^.State:= lua_tointeger(L, 9); - vg^.Timer:= lua_tointeger(L, 10); - vg^.Tint:= lua_tointeger(L, 11); + if not lua_isnoneornil(L, 2) then + vg^.X:= lua_tointeger(L, 2); + if not lua_isnoneornil(L, 3) then + vg^.Y:= lua_tointeger(L, 3); + if not lua_isnoneornil(L, 4) then + vg^.dX:= lua_tonumber(L, 4); + if not lua_isnoneornil(L, 5) then + vg^.dY:= lua_tonumber(L, 5); + if not lua_isnoneornil(L, 6) then + vg^.Angle:= lua_tonumber(L, 6); + if not lua_isnoneornil(L, 7) then + vg^.Frame:= lua_tointeger(L, 7); + if not lua_isnoneornil(L, 8) then + vg^.FrameTicks:= lua_tointeger(L, 8); + if not lua_isnoneornil(L, 9) then + vg^.State:= lua_tointeger(L, 9); + if not lua_isnoneornil(L, 10) then + vg^.Timer:= lua_tointeger(L, 10); + if not lua_isnoneornil(L, 11) then + vg^.Tint:= lua_tointeger(L, 11) + end; +// end +// else +// lua_pushnil(L); // return value on stack (nil) + lc_setvisualgearvalues:= 0 +end; + +// so. going to use this to get/set some of the more obscure gear values which weren't already exposed elsewhere +// can keep adding things in the future. isnoneornil makes it safe +function lc_getgearvalues(L : Plua_State) : LongInt; Cdecl; +var gear: PGear; +begin + if CheckLuaParamCount(L, 1, 'GetGearValues', 'gearUid') then + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if gear <> nil then + begin + lua_pushinteger(L, gear^.Angle); + lua_pushinteger(L, gear^.Power); + lua_pushinteger(L, gear^.WDTimer); + lua_pushinteger(L, gear^.Radius); + lua_pushinteger(L, hwRound(gear^.Density * _10000)); + lua_pushinteger(L, gear^.Karma); + lua_pushnumber(L, gear^.DirAngle); + lua_pushinteger(L, gear^.AdvBounce); + lua_pushinteger(L, Integer(gear^.ImpactSound)); + lua_pushinteger(L, gear^.nImpactSounds); + lua_pushinteger(L, gear^.Tint); + lua_pushinteger(L, gear^.Damage) end + else + begin + lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); + lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); + lua_pushnil(L); lua_pushnil(L) + end + end + else + begin + lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); + lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); lua_pushnil(L); + lua_pushnil(L); lua_pushnil(L) end; - lc_setvisualgearvalues:= 0; + lc_getgearvalues:= 12 +end; + +function lc_setgearvalues(L : Plua_State) : LongInt; Cdecl; +var gear : PGear; +begin +// Currently allows 1-13 params +// if CheckLuaParamCount(L, 13, 'SetGearValues', 'gearUid, Angle, Power, WDTimer, Radius, Density, Karma, DirAngle, AdvBounce, ImpactSound, # ImpactSounds, Tint, Damage') then +// begin + gear:= GearByUID(lua_tointeger(L, 1)); + if gear <> nil then + begin + if not lua_isnoneornil(L, 2) then + gear^.Angle := lua_tointeger(L, 2); + if not lua_isnoneornil(L, 3) then + gear^.Power := lua_tointeger(L, 3); + if not lua_isnoneornil(L, 4) then + gear^.WDTimer := lua_tointeger(L, 4); + if not lua_isnoneornil(L, 5) then + gear^.Radius := lua_tointeger(L, 5); + if not lua_isnoneornil(L, 6) then + gear^.Density:= int2hwFloat(lua_tointeger(L, 6)) / 10000; + if not lua_isnoneornil(L, 7) then + gear^.Karma := lua_tointeger(L, 7); + if not lua_isnoneornil(L, 8) then + gear^.DirAngle:= lua_tonumber(L, 8); + if not lua_isnoneornil(L, 9) then + gear^.AdvBounce := lua_tointeger(L, 9); + if not lua_isnoneornil(L, 10) then + gear^.ImpactSound := TSound(lua_tointeger(L, 10)); + if not lua_isnoneornil(L, 11) then + gear^.nImpactSounds := lua_tointeger(L, 11); + if not lua_isnoneornil(L, 12) then + gear^.Tint := lua_tointeger(L, 12); + if not lua_isnoneornil(L, 13) then + gear^.Damage := lua_tointeger(L, 13); + end; +// end +// else +// lua_pushnil(L); // return value on stack (nil) + lc_setgearvalues:= 0 end; function lc_getfollowgear(L : Plua_State) : LongInt; Cdecl; begin - if lua_gettop(L) <> 0 then + if CheckLuaParamCount(L, 0, 'GetFollowGear', '') then begin - LuaParameterCountError('GetFollowGear', '', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else if FollowGear = nil then lua_pushnil(L) else lua_pushinteger(L, FollowGear^.uid); + end + else + lua_pushnil(L); lc_getfollowgear:= 1; // 1 return value end; function lc_getgeartype(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetGearType', 'gearUid', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else + if CheckLuaParamCount(L, 1, 'GetGearType', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then lua_pushinteger(L, ord(gear^.Kind)) else lua_pushnil(L); - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_getgeartype:= 1 end; function lc_getgearmessage(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetGearMessage', 'gearUid', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else + if CheckLuaParamCount(L, 1, 'GetGearMessage', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then lua_pushinteger(L, gear^.message) else lua_pushnil(L); - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_getgearmessage:= 1 end; function lc_getgearelasticity(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetGearElasticity', 'gearUid', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else + if CheckLuaParamCount(L, 1, 'GetGearElasticity', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then lua_pushinteger(L, hwRound(gear^.elasticity * _10000)) else lua_pushnil(L); + end + else + lua_pushnil(L); // return value on stack (nil) + lc_getgearelasticity:= 1 +end; + +function lc_setgearelasticity(L : Plua_State) : LongInt; Cdecl; +var gear: PGear; +begin + if CheckLuaParamCount(L, 2, 'SetGearElasticity', 'gearUid, Elasticity') then + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if gear <> nil then + gear^.Elasticity:= int2hwFloat(lua_tointeger(L, 2)) / 10000 end; - lc_getgearelasticity:= 1 + lc_setgearelasticity:= 0 +end; + +function lc_getgearfriction(L : Plua_State) : LongInt; Cdecl; +var gear : PGear; +begin + if CheckLuaParamCount(L, 1, 'GetGearFriction', 'gearUid') then + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if gear <> nil then + lua_pushinteger(L, hwRound(gear^.friction * _10000)) + else + lua_pushnil(L); + end + else + lua_pushnil(L); // return value on stack (nil) + lc_getgearfriction:= 1 +end; + +function lc_setgearfriction(L : Plua_State) : LongInt; Cdecl; +var gear: PGear; +begin + if CheckLuaParamCount(L, 2, 'SetGearFriction', 'gearUid, Friction') then + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if gear <> nil then + gear^.Friction:= int2hwFloat(lua_tointeger(L, 2)) / 10000 + end; + lc_setgearfriction:= 0 end; function lc_setgearmessage(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 2 then - LuaParameterCountError('SetGearMessage', 'gearUid, message', lua_gettop(L)) - else + if CheckLuaParamCount(L, 2, 'SetGearMessage', 'gearUid, message') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then @@ -657,28 +1096,23 @@ function lc_getgearpos(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetGearPos', 'gearUid', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else + if CheckLuaParamCount(L, 1, 'GetGearPos', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then lua_pushinteger(L, gear^.Pos) else lua_pushnil(L); - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_getgearpos:= 1 end; function lc_setgearpos(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 2 then - LuaParameterCountError('SetGearPos', 'gearUid, value', lua_gettop(L)) - else + if CheckLuaParamCount(L, 2, 'SetGearPos', 'gearUid, value') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then @@ -690,28 +1124,23 @@ function lc_getgearcollisionmask(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetGearCollisionMask', 'gearUid', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else + if CheckLuaParamCount(L, 1, 'GetGearCollisionMask', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then lua_pushinteger(L, gear^.CollisionMask) else lua_pushnil(L); - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_getgearcollisionmask:= 1 end; function lc_setgearcollisionmask(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 2 then - LuaParameterCountError('SetGearCollisionMask', 'gearUid, mask', lua_gettop(L)) - else + if CheckLuaParamCount(L, 2, 'SetGearCollisionMask', 'gearUid, mask') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then @@ -723,9 +1152,7 @@ function lc_gethoglevel(L : Plua_State): LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - LuaParameterCountError('GetHogLevel', 'gearUid', lua_gettop(L)) - else + if CheckLuaParamCount(L, 1, 'GetHogLevel', 'gearUid') then begin gear := GearByUID(lua_tointeger(L, 1)); if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then @@ -739,9 +1166,7 @@ function lc_sethoglevel(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 2 then - LuaParameterCountError('SetHogLevel', 'gearUid, level', lua_gettop(L)) - else + if CheckLuaParamCount(L, 2, 'SetHogLevel', 'gearUid, level') then begin gear:= GearByUID(lua_tointeger(L, 1)); if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then @@ -753,12 +1178,7 @@ function lc_gethogclan(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetHogClan', 'gearUid', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else + if CheckLuaParamCount(L, 1, 'GetHogClan', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then @@ -767,18 +1187,18 @@ end else lua_pushnil(L); - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_gethogclan:= 1 end; function lc_getclancolor(L : Plua_State) : LongInt; Cdecl; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetClanColor', 'clan', lua_gettop(L)); + if CheckLuaParamCount(L, 1, 'GetClanColor', 'clan') then + lua_pushinteger(L, ClansArray[lua_tointeger(L, 1)]^.Color shl 8 or $FF) + else lua_pushnil(L); // return value on stack (nil) - end - else lua_pushinteger(L, ClansArray[lua_tointeger(L, 1)]^.Color shl 8 or $FF); lc_getclancolor:= 1 end; @@ -788,11 +1208,11 @@ hh : THedgehog; i, j : LongInt; begin - if lua_gettop(L) <> 2 then - LuaParameterCountError('SetClanColor', 'clan, color', lua_gettop(L)) - else + if CheckLuaParamCount(L, 2, 'SetClanColor', 'clan, color') then begin - clan := ClansArray[lua_tointeger(L, 1)]; + i:= lua_tointeger(L,1); + if i >= ClansCount then exit(0); + clan := ClansArray[i]; clan^.Color:= lua_tointeger(L, 2) shr 8; for i:= 0 to Pred(clan^.TeamsNumber) do @@ -803,75 +1223,111 @@ hh:= team^.Hedgehogs[j]; if (hh.Gear <> nil) or (hh.GearHidden <> nil) then begin - FreeTexture(hh.NameTagTex); - hh.NameTagTex:= RenderStringTex(hh.Name, clan^.Color, fnt16); + FreeAndNilTexture(hh.NameTagTex); + hh.NameTagTex:= RenderStringTex(ansistring(hh.Name), clan^.Color, fnt16); RenderHealth(hh); end; end; - FreeTexture(team^.NameTagTex); - team^.NameTagTex:= RenderStringTex(clan^.Teams[i]^.TeamName, clan^.Color, fnt16); + FreeAndNilTexture(team^.NameTagTex); + team^.NameTagTex:= RenderStringTex(ansistring(clan^.Teams[i]^.TeamName), clan^.Color, fnt16); end; + FreeAndNilTexture(clan^.HealthTex); clan^.HealthTex:= makeHealthBarTexture(cTeamHealthWidth + 5, clan^.Teams[0]^.NameTagTex^.h, clan^.Color); end; lc_setclancolor:= 0 end; +function lc_gethogvoicepack(L : Plua_State) : LongInt; Cdecl; +var gear : PGear; +begin + if CheckLuaParamCount(L, 1, 'GetHogVoicepack', 'gearUid') then + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then + lua_pushstring(L, str2pchar(gear^.Hedgehog^.Team^.Voicepack^.name)) + else + lua_pushnil(L); + end + else + lua_pushnil(L); // return value on stack (nil) + lc_gethogvoicepack:= 1 +end; + +function lc_gethoggrave(L : Plua_State) : LongInt; Cdecl; +var gear : PGear; +begin + if CheckLuaParamCount(L, 1, 'GetHogGrave', 'gearUid') then + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then + lua_pushstring(L, str2pchar(gear^.Hedgehog^.Team^.GraveName)) + else + lua_pushnil(L); + end + else + lua_pushnil(L); // return value on stack (nil) + lc_gethoggrave:= 1 +end; + +function lc_gethogflag(L : Plua_State) : LongInt; Cdecl; +var gear : PGear; +begin + if CheckLuaParamCount(L, 1, 'GetHogFlag', 'gearUid') then + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then + lua_pushstring(L, str2pchar(gear^.Hedgehog^.Team^.Flag)) + else + lua_pushnil(L); + end + else + lua_pushnil(L); // return value on stack (nil) + lc_gethogflag:= 1 +end; + function lc_gethogteamname(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetHogTeamName', 'gearUid', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else + if CheckLuaParamCount(L, 1, 'GetHogTeamName', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then - begin lua_pushstring(L, str2pchar(gear^.Hedgehog^.Team^.TeamName)) - end else lua_pushnil(L); - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_gethogteamname:= 1 end; function lc_sethogteamname(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 2 then - begin - LuaParameterCountError('SetHogTeamName', 'gearUid, name', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else + if CheckLuaParamCount(L, 2, 'SetHogTeamName', 'gearUid, name') then begin gear := GearByUID(lua_tointeger(L, 1)); if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then begin gear^.Hedgehog^.Team^.TeamName := lua_tostring(L, 2); - FreeTexture(gear^.Hedgehog^.Team^.NameTagTex); - gear^.Hedgehog^.Team^.NameTagTex:= RenderStringTex(gear^.Hedgehog^.Team^.TeamName, gear^.Hedgehog^.Team^.Clan^.Color, fnt16); + FreeAndNilTexture(gear^.Hedgehog^.Team^.NameTagTex); + gear^.Hedgehog^.Team^.NameTagTex:= RenderStringTex(ansistring(gear^.Hedgehog^.Team^.TeamName), gear^.Hedgehog^.Team^.Clan^.Color, fnt16); end else lua_pushnil(L); - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_sethogteamname:= 1 end; function lc_gethogname(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetHogName', 'gearUid', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else + if CheckLuaParamCount(L, 1, 'GetHogName', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then @@ -880,27 +1336,24 @@ end else lua_pushnil(L); - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_gethogname:= 1 end; function lc_sethogname(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 2 then - begin - LuaParameterCountError('SetHogName', 'gearUid, name', lua_gettop(L)); - lua_pushnil(L) - end - else + if CheckLuaParamCount(L, 2, 'SetHogName', 'gearUid, name') then begin gear:= GearByUID(lua_tointeger(L, 1)); if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then begin gear^.Hedgehog^.Name:= lua_tostring(L, 2); - FreeTexture(gear^.Hedgehog^.NameTagTex); - gear^.Hedgehog^.NameTagTex:= RenderStringTex(gear^.Hedgehog^.Name, gear^.Hedgehog^.Team^.Clan^.Color, fnt16) + FreeAndNilTexture(gear^.Hedgehog^.NameTagTex); + gear^.Hedgehog^.NameTagTex:= RenderStringTex(ansistring(gear^.Hedgehog^.Name), gear^.Hedgehog^.Team^.Clan^.Color, fnt16) end end; lc_sethogname:= 0; @@ -909,87 +1362,87 @@ function lc_gettimer(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetTimer', 'gearUid', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else + if CheckLuaParamCount(L, 1, 'GetTimer', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then lua_pushinteger(L, gear^.Timer) else lua_pushnil(L); - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_gettimer:= 1 end; +function lc_getflighttime(L : Plua_State) : LongInt; Cdecl; +var gear : PGear; +begin + if CheckLuaParamCount(L, 1, 'GetFlightTime', 'gearUid') then + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if gear <> nil then + lua_pushinteger(L, gear^.FlightTime) + else + lua_pushnil(L); + end + else + lua_pushnil(L); // return value on stack (nil) + lc_getflighttime:= 1 +end; + function lc_gethealth(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetHealth', 'gearUid', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else + if CheckLuaParamCount(L, 1, 'GetHealth', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then lua_pushinteger(L, gear^.Health) else lua_pushnil(L); - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_gethealth:= 1 end; function lc_getx(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetX', 'gearUid', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else + if CheckLuaParamCount(L, 1, 'GetX', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then lua_pushinteger(L, hwRound(gear^.X)) else lua_pushnil(L); - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_getx:= 1 end; function lc_gety(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetY', 'gearUid', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else + if CheckLuaParamCount(L, 1, 'GetY', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then lua_pushinteger(L, hwRound(gear^.Y)) else lua_pushnil(L); - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_gety:= 1 end; function lc_copypv(L : Plua_State) : LongInt; Cdecl; var gears, geard : PGear; begin - if lua_gettop(L) <> 2 then - begin - LuaParameterCountError('CopyPV', 'fromGearUid, toGearUid', lua_gettop(L)); - end - else + if CheckLuaParamCount(L, 2, 'CopyPV', 'fromGearUid, toGearUid') then begin gears:= GearByUID(lua_tointeger(L, 1)); geard:= GearByUID(lua_tointeger(L, 2)); @@ -1001,15 +1454,13 @@ geard^.dY:= gears^.dY; end end; - lc_copypv:= 1 + lc_copypv:= 0 end; function lc_followgear(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - LuaParameterCountError('FollowGear', 'gearUid', lua_gettop(L)) - else + if CheckLuaParamCount(L, 1, 'FollowGear', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then FollowGear:= gear @@ -1021,42 +1472,47 @@ var gear : PGear; vgear : PVisualGear; s : LongWord; + n : LongInt; begin - if lua_gettop(L) = 4 then - s:= lua_tointeger(L, 4) - else - s:= 0; - - if (lua_gettop(L) = 4) or (lua_gettop(L) = 3) then + if CheckAndFetchParamCount(L, 3, 4, 'HogSay', 'gearUid, text, manner [, vgState]', n) then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then begin + // state defaults to 0 if state param is given + if n = 4 then + s:= lua_tointeger(L, 4) + else + s:= 0; vgear:= AddVisualGear(0, 0, vgtSpeechBubble, s, true); if vgear <> nil then begin vgear^.Text:= lua_tostring(L, 2); - vgear^.Hedgehog:= gear^.Hedgehog; + if Gear^.Kind = gtHedgehog then + begin + AddChatString(#9+'[' + gear^.Hedgehog^.Name + '] '+vgear^.text); + vgear^.Hedgehog:= gear^.Hedgehog + end + else vgear^.Frame:= gear^.uid; + vgear^.FrameTicks:= lua_tointeger(L, 3); if (vgear^.FrameTicks < 1) or (vgear^.FrameTicks > 3) then vgear^.FrameTicks:= 1; lua_pushinteger(L, vgear^.Uid); - AddChatString(#1+'[' + gear^.Hedgehog^.Name + '] '+vgear^.text) end end - else - lua_pushnil(L) + else + lua_pushnil(L) end - else LuaParameterCountError('HogSay', 'gearUid, text, manner[, vgState]', lua_gettop(L)); + else + lua_pushnil(L); lc_hogsay:= 1 end; function lc_switchhog(L : Plua_State) : LongInt; Cdecl; var gear, prevgear : PGear; begin - if lua_gettop(L) <> 1 then - LuaParameterCountError('SwitchHog', 'gearUid', lua_gettop(L)) - else + if CheckLuaParamCount(L, 1, 'SwitchHog', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); // should we allow this when there is no current hedgehog? might do some odd(er) things to turn sequence. @@ -1083,93 +1539,78 @@ lc_switchhog:= 0 end; -{function lc_addammo(L : Plua_State) : LongInt; Cdecl; -var gear : PGear; -begin - - if lua_gettop(L) = 3 then - begin - gear:= GearByUID(lua_tointeger(L, 1)); - if (gear <> nil) and (gear^.Hedgehog <> nil) then - AddAmmoAmount(gear^.Hedgehog^, TAmmoType(lua_tointeger(L, 2)), lua_tointeger(L,3) ); - end else - - if lua_gettop(L) = 2 then - begin - gear:= GearByUID(lua_tointeger(L, 1)); - if (gear <> nil) and (gear^.Hedgehog <> nil) then - AddAmmo(gear^.Hedgehog^, TAmmoType(lua_tointeger(L, 2))); - end else - begin - LuaParameterCountError('AddAmmo', 'TODO', lua_gettop(L)); - end; - - lc_addammo:= 0; - -end;} - function lc_addammo(L : Plua_State) : LongInt; Cdecl; var gear : PGear; + at, n: LongInt; +const + call = 'AddAmmo'; + params = 'gearUid, ammoType [, ammoCount]'; begin - if (lua_gettop(L) = 3) or (lua_gettop(L) = 2) then + if CheckAndFetchParamCount(L, 2, 3, call, params, n) then begin - gear:= GearByUID(lua_tointeger(L, 1)); - if (gear <> nil) and (gear^.Hedgehog <> nil) then - if lua_gettop(L) = 2 then - AddAmmo(gear^.Hedgehog^, TAmmoType(lua_tointeger(L, 2))) - else - SetAmmo(gear^.Hedgehog^, TAmmoType(lua_tointeger(L, 2)), lua_tointeger(L, 3)) - end - else LuaParameterCountError('AddAmmo', 'gearUid, ammoType[, ammoCount]', lua_gettop(L)); + at:= LuaToAmmoTypeOrd(L, 2, call, params); + if at >= 0 then + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if (gear <> nil) and (gear^.Hedgehog <> nil) then + if n = 2 then + AddAmmo(gear^.Hedgehog^, TAmmoType(at)) + else + SetAmmo(gear^.Hedgehog^, TAmmoType(at), lua_tointeger(L, 3)) + end; + end; lc_addammo:= 0 end; function lc_getammocount(L : Plua_State) : LongInt; Cdecl; var gear : PGear; ammo : PAmmo; + at : LongInt; +const + call = 'GetAmmoCount'; + params = 'gearUid, ammoType'; begin - if (lua_gettop(L) = 2) then + if CheckLuaParamCount(L, 2, call, params) then begin gear:= GearByUID(lua_tointeger(L, 1)); if (gear <> nil) and (gear^.Hedgehog <> nil) then begin - ammo:= GetAmmoEntry(gear^.Hedgehog^, TAmmoType(lua_tointeger(L, 2))); - if ammo^.AmmoType = amNothing then - lua_pushinteger(L, 0) - else - lua_pushinteger(L, ammo^.Count) + at:= LuaToAmmoTypeOrd(L, 2, call, params); + if at >= 0 then + begin + ammo:= GetAmmoEntry(gear^.Hedgehog^, TAmmoType(at)); + if ammo^.AmmoType = amNothing then + lua_pushinteger(L, 0) + else + lua_pushinteger(L, ammo^.Count); + end; end - else lua_pushinteger(L, 0) + else lua_pushinteger(L, 0); end else - begin - LuaParameterCountError('GetAmmoCount', 'gearUid, ammoType', lua_gettop(L)); - lua_pushnil(L) - end; + lua_pushnil(L); lc_getammocount:= 1 end; function lc_sethealth(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 2 then - begin - LuaParameterCountError('SetHealth', 'gearUid, health', lua_gettop(L)); - end - else + if CheckLuaParamCount(L, 2, 'SetHealth', 'gearUid, health') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then begin gear^.Health:= lua_tointeger(L, 2); - if (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then - begin - RenderHealth(gear^.Hedgehog^); - RecountTeamHealth(gear^.Hedgehog^.Team) - end; - - SetAllToActive; + if (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then + begin + RenderHealth(gear^.Hedgehog^); + RecountTeamHealth(gear^.Hedgehog^.Team) + end; + // Why did this do a "setalltoactive" ? + //SetAllToActive; + Gear^.Active:= true; + AllInactive:= false end end; lc_sethealth:= 0 @@ -1178,11 +1619,7 @@ function lc_settimer(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 2 then - begin - LuaParameterCountError('SetTimer', 'gearUid, timer', lua_gettop(L)); - end - else + if CheckLuaParamCount(L, 2, 'SetTimer', 'gearUid, timer') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then gear^.Timer:= lua_tointeger(L, 2) @@ -1190,45 +1627,65 @@ lc_settimer:= 0 end; +function lc_setflighttime(L : Plua_State) : LongInt; Cdecl; +var gear : PGear; +begin + if CheckLuaParamCount(L, 2, 'SetFlightTime', 'gearUid, flighttime') then + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if gear <> nil then gear^.FlightTime:= lua_tointeger(L, 2) + end; + lc_setflighttime:= 0 +end; + function lc_seteffect(L : Plua_State) : LongInt; Cdecl; var gear: PGear; + t : LongInt; +const + call = 'SetEffect'; + params = 'gearUid, effect, effectState'; begin - if lua_gettop(L) <> 3 then - LuaParameterCountError('SetEffect', 'gearUid, effect, enabled', lua_gettop(L)) - else begin - gear := GearByUID(lua_tointeger(L, 1)); - if (gear <> nil) and (gear^.Hedgehog <> nil) then - gear^.Hedgehog^.Effects[THogEffect(lua_tointeger(L, 2))]:= lua_tointeger(L, 3); - end; + if CheckLuaParamCount(L, 3, call, params) then + begin + t:= LuaToHogEffectOrd(L, 2, call, params); + if t >= 0 then + begin + gear := GearByUID(lua_tointeger(L, 1)); + if (gear <> nil) and (gear^.Hedgehog <> nil) then + gear^.Hedgehog^.Effects[THogEffect(t)]:= lua_tointeger(L, 3); + end; + end; lc_seteffect := 0; end; function lc_geteffect(L : Plua_State) : LongInt; Cdecl; var gear : PGear; + t : LongInt; +const + call = 'GetEffect'; + params = 'gearUid, effect'; begin - if lua_gettop(L) <> 2 then + if CheckLuaParamCount(L, 2, call, params) then begin - LuaParameterCountError('GetEffect', 'gearUid, effect', lua_gettop(L)); + t:= LuaToHogEffectOrd(L, 2, call, params); + if t >= 0 then + begin + gear:= GearByUID(lua_tointeger(L, 1)); + if (gear <> nil) and (gear^.Hedgehog <> nil) then + lua_pushinteger(L, gear^.Hedgehog^.Effects[THogEffect(t)]) + else + lua_pushinteger(L, 0) + end; end else - begin - gear:= GearByUID(lua_tointeger(L, 1)); - if (gear <> nil) and (gear^.Hedgehog <> nil) then - lua_pushinteger(L, gear^.Hedgehog^.Effects[THogEffect(lua_tointeger(L, 2))]) - else - lua_pushinteger(L, 0) - end; + lua_pushinteger(L, 0); lc_geteffect:= 1 end; function lc_setstate(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 2 then - begin - LuaParameterCountError('SetState', 'gearUid, state', lua_gettop(L)); - end - else + if CheckLuaParamCount(L, 2, 'SetState', 'gearUid, state') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then @@ -1243,48 +1700,39 @@ function lc_getstate(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetState', 'gearUid', lua_gettop(L)); - end - else + if CheckLuaParamCount(L, 1, 'GetState', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then lua_pushinteger(L, gear^.State) else lua_pushnil(L) - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_getstate:= 1 end; function lc_gettag(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetTag', 'gearUid', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else + if CheckLuaParamCount(L, 1, 'GetTag', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then lua_pushinteger(L, gear^.Tag) else lua_pushnil(L); - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_gettag:= 1 end; function lc_settag(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 2 then - begin - LuaParameterCountError('SetTag', 'gearUid, tag', lua_gettop(L)); - end - else + if CheckLuaParamCount(L, 2, 'SetTag', 'gearUid, tag') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then @@ -1305,50 +1753,62 @@ function lc_sendstat(L : Plua_State) : LongInt; Cdecl; var statInfo : TStatInfoType; -var i : LongInt; -var color : shortstring; + i, n : LongInt; + color, tn: shortstring; + needsTn : boolean; +const + call = 'SendStat'; + params = 'statInfoType, color [, teamname]'; begin - statInfo := TStatInfoType(lua_tointeger(L, 1)); - if (lua_gettop(L) <> 2) and ((statInfo <> siPlayerKills) - and (statInfo <> siClanHealth)) then + if CheckAndFetchParamCount(L, 2, 3, call, params, n) then begin - LuaParameterCountError('SendStat', 'statInfoType, color', lua_gettop(L)); - end - else if (lua_gettop(L) <> 3) and ((statInfo = siPlayerKills) - or (statInfo = siClanHealth)) then - begin - LuaParameterCountError('SendStat', 'siClanHealth, color, teamname', lua_gettop(L)); - end - else - begin - if ((statInfo = siPlayerKills) or (statInfo = siClanHealth)) then + i:= LuaToStatInfoTypeOrd(L, 1, call, params); + if i >= 0 then begin - // 3: team name - for i:= 0 to Pred(TeamsCount) do + statInfo:= TStatInfoType(i); + needsTn:= ((statInfo = siPlayerKills) or (statInfo = siClanHealth)); + // check if param count is correct for the used statInfo + if (n = 3) <> needsTn then + begin + if n = 3 then + LuaCallError(EnumToStr(statInfo) + ' does not support the teamname parameter', call, params) + else + LuaCallError(EnumToStr(statInfo) + ' requires the teamname parameter', call, params); + end + else // count is correct! begin - with TeamsArray[i]^ do + if needsTn then begin - if TeamName = lua_tostring(L, 3) then + // 3: team name + for i:= 0 to Pred(TeamsCount) do + begin + color:= _S'0'; + tn:= lua_tostring(L, 3); + with TeamsArray[i]^ do begin - color := uUtils.IntToStr(Clan^.Color); - Break; + if TeamName = tn then + begin + color := uUtils.IntToStr(Clan^.Color); + Break; + end end + end; + if (statInfo = siPlayerKills) then + begin + SendStat(siPlayerKills, color + ' ' + + lua_tostring(L, 2) + ' ' + tn); + end + else if (statInfo = siClanHealth) then + begin + SendStat(siClanHealth, color + ' ' + + lua_tostring(L, 2)); + end end + else + begin + SendStat(statInfo,lua_tostring(L, 2)); + end; end; - if (statInfo = siPlayerKills) then - begin - SendStat(siPlayerKills, color + ' ' + - lua_tostring(L, 2) + ' ' + TeamsArray[i]^.TeamName); - end - else if (statInfo = siClanHealth) then - begin - SendStat(siClanHealth, color + ' ' + - lua_tostring(L, 2)); - end - end - else - begin - SendStat(statInfo,lua_tostring(L, 2)); end; end; lc_sendstat:= 0 @@ -1365,54 +1825,60 @@ var gear: PGear; fall: boolean; tryhard: boolean; - left, right: LongInt; + left, right, n: LongInt; begin - tryhard:= false; - if (lua_gettop(L) <> 4) and (lua_gettop(L) <> 5) then - LuaParameterCountError('FindPlace', 'gearUid, fall, left, right[, tryHarder]', lua_gettop(L)) - else + if CheckAndFetchParamCount(L, 4, 5, 'FindPlace', 'gearUid, fall, left, right [, tryHarder]', n) then begin gear:= GearByUID(lua_tointeger(L, 1)); fall:= lua_toboolean(L, 2); left:= lua_tointeger(L, 3); right:= lua_tointeger(L, 4); - if lua_gettop(L) = 5 then - tryhard:= lua_toboolean(L, 5); + if n = 5 then + tryhard:= lua_toboolean(L, 5) + else + tryhard:= false; if gear <> nil then FindPlace(gear, fall, left, right, tryhard); if gear <> nil then lua_pushinteger(L, gear^.uid) else lua_pushnil(L); - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_findplace:= 1 end; function lc_playsound(L : Plua_State) : LongInt; Cdecl; var gear: PGear; + n, s: LongInt; +const + call = 'PlaySound'; + params = 'soundId [, hhGearUid]'; begin - if lua_gettop(L) = 1 then - PlaySound(TSound(lua_tointeger(L, 1))) - else if lua_gettop(L) = 2 then + if CheckAndFetchParamCount(L, 1, 2, call, params, n) then begin - gear:= GearByUID(lua_tointeger(L, 2)); - if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then - AddVoice(TSound(lua_tointeger(L, 1)),gear^.Hedgehog^.Team^.Voicepack) - end - else LuaParameterCountError('PlaySound', 'soundId', lua_gettop(L)); + s:= LuaToSoundOrd(L, 1, call, params); + if s >= 0 then + begin + // no gear specified + if n = 1 then + PlaySound(TSound(s)) + else + begin + gear:= GearByUID(lua_tointeger(L, 2)); + if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then + AddVoice(TSound(s),gear^.Hedgehog^.Team^.Voicepack) + end; + end; + end; lc_playsound:= 0; end; function lc_addteam(L : Plua_State) : LongInt; Cdecl; var np: LongInt; begin - np:= lua_gettop(L); - if (np < 5) or (np > 6) then - begin - LuaParameterCountError('AddTeam', 'teamname, color, grave, fort, voicepack[, flag]', lua_gettop(L)); - //lua_pushnil(L) - end - else + if CheckAndFetchParamCount(L, 5, 6, 'AddTeam', 'teamname, color, grave, fort, voicepack [, flag]', np) then begin ParseCommand('addteam x ' + lua_tostring(L, 2) + ' ' + lua_tostring(L, 1), true, true); ParseCommand('grave ' + lua_tostring(L, 3), true, true); @@ -1423,35 +1889,73 @@ // fails on x64 //lua_pushinteger(L, LongInt(CurrentTeam)); end; + //else + //lua_pushnil(L) lc_addteam:= 0;//1; end; +function lc_dismissteam(L : Plua_State) : LongInt; Cdecl; +var HHGear: PGear; + i, h : LongInt; + hidden: boolean; +begin + if CheckLuaParamCount(L, 1, 'DismissTeam', 'teamname') then + begin + if TeamsCount > 0 then + for i:= 0 to Pred(TeamsCount) do + begin + // skip teams that don't have matching name + if TeamsArray[i]^.TeamName <> lua_tostring(L, 1) then + continue; + + // destroy all hogs of matching team, including the hidden ones + for h:= 0 to cMaxHHIndex do + begin + hidden:= (TeamsArray[i]^.Hedgehogs[h].GearHidden <> nil); + if hidden then + RestoreHog(@TeamsArray[i]^.Hedgehogs[h]); + // destroy hedgehog gear, if any + HHGear:= TeamsArray[i]^.Hedgehogs[h].Gear; + if HHGear <> nil then + begin + // smoke effect + if (not hidden) then + begin + AddVisualGear(hwRound(HHGear^.X), hwRound(HHGear^.Y), vgtSmokeWhite); + AddVisualGear(hwRound(HHGear^.X) - 16 + Random(32), hwRound(HHGear^.Y) - 16 + Random(32), vgtSmokeWhite); + AddVisualGear(hwRound(HHGear^.X) - 16 + Random(32), hwRound(HHGear^.Y) - 16 + Random(32), vgtSmokeWhite); + AddVisualGear(hwRound(HHGear^.X) - 16 + Random(32), hwRound(HHGear^.Y) - 16 + Random(32), vgtSmokeWhite); + AddVisualGear(hwRound(HHGear^.X) - 16 + Random(32), hwRound(HHGear^.Y) - 16 + Random(32), vgtSmokeWhite); + end; + HHGear^.Message:= HHGear^.Message or gmDestroy; + end; + end; + // can't dismiss more than one team + break; + end; + end; + lc_dismissteam:= 0; +end; + function lc_addhog(L : Plua_State) : LongInt; Cdecl; var temp: ShortString; begin - if lua_gettop(L) <> 4 then - begin - LuaParameterCountError('AddHog', 'hogname, botlevel, health, hat', lua_gettop(L)); - lua_pushnil(L) - end - else + if CheckLuaParamCount(L, 4, 'AddHog', 'hogname, botlevel, health, hat') then begin temp:= lua_tostring(L, 4); ParseCommand('addhh ' + lua_tostring(L, 2) + ' ' + lua_tostring(L, 3) + ' ' + lua_tostring(L, 1), true, true); ParseCommand('hat ' + temp, true, true); lua_pushinteger(L, CurrentHedgehog^.Gear^.uid); - end; + end + else + lua_pushnil(L); lc_addhog:= 1; end; function lc_hogturnleft(L : Plua_State) : LongInt; Cdecl; var gear: PGear; begin - if lua_gettop(L) <> 2 then - begin - LuaParameterCountError('HogTurnLeft', 'gearUid, boolean', lua_gettop(L)); - end - else + if CheckLuaParamCount(L, 2, 'HogTurnLeft', 'gearUid, boolean') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then @@ -1463,13 +1967,7 @@ function lc_getgearposition(L : Plua_State) : LongInt; Cdecl; var gear: PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetGearPosition', 'gearUid', lua_gettop(L)); - lua_pushnil(L); - lua_pushnil(L) - end - else + if CheckLuaParamCount(L, 1, 'GetGearPosition', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then @@ -1482,6 +1980,11 @@ lua_pushnil(L); lua_pushnil(L) end; + end + else + begin + lua_pushnil(L); + lua_pushnil(L) end; lc_getgearposition:= 2; end; @@ -1491,9 +1994,7 @@ col: boolean; x, y: LongInt; begin - if lua_gettop(L) <> 3 then - LuaParameterCountError('SetGearPosition', 'gearUid, x, y', lua_gettop(L)) - else + if CheckLuaParamCount(L, 3, 'SetGearPosition', 'gearUid, x, y') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then @@ -1516,13 +2017,7 @@ function lc_getgeartarget(L : Plua_State) : LongInt; Cdecl; var gear: PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetGearTarget', 'gearUid', lua_gettop(L)); - lua_pushnil(L); - lua_pushnil(L) - end - else + if CheckLuaParamCount(L, 1, 'GetGearTarget', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then @@ -1535,6 +2030,11 @@ lua_pushnil(L); lua_pushnil(L) end + end + else + begin + lua_pushnil(L); + lua_pushnil(L) end; lc_getgeartarget:= 2; end; @@ -1542,9 +2042,7 @@ function lc_setgeartarget(L : Plua_State) : LongInt; Cdecl; var gear: PGear; begin - if lua_gettop(L) <> 3 then - LuaParameterCountError('SetGearTarget', 'gearUid, x, y', lua_gettop(L)) - else + if CheckLuaParamCount(L, 3, 'SetGearTarget', 'gearUid, x, y') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then @@ -1560,13 +2058,7 @@ var gear: PGear; var t: LongInt; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetGearVelocity', 'gearUid', lua_gettop(L)); - lua_pushnil(L); - lua_pushnil(L) - end - else + if CheckLuaParamCount(L, 1, 'GetGearVelocity', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then @@ -1577,6 +2069,11 @@ lua_pushinteger(L, t); lua_pushinteger(L, hwRound(gear^.dY * 1000000)) end + end + else + begin + lua_pushnil(L); + lua_pushnil(L); end; lc_getgearvelocity:= 2; end; @@ -1584,9 +2081,7 @@ function lc_setgearvelocity(L : Plua_State) : LongInt; Cdecl; var gear: PGear; begin - if lua_gettop(L) <> 3 then - LuaParameterCountError('SetGearVelocity', 'gearUid, dx, dy', lua_gettop(L)) - else + if CheckLuaParamCount(L, 3, 'SetGearVelocity', 'gearUid, dx, dy') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then @@ -1601,9 +2096,7 @@ function lc_setzoom(L : Plua_State) : LongInt; Cdecl; begin - if lua_gettop(L) <> 1 then - LuaParameterCountError('SetZoom', 'zoomLevel', lua_gettop(L)) - else + if CheckLuaParamCount(L, 1, 'SetZoom', 'zoomLevel') then begin ZoomValue:= lua_tonumber(L, 1); if ZoomValue < cMaxZoomLevel then @@ -1616,47 +2109,51 @@ function lc_getzoom(L : Plua_State) : LongInt; Cdecl; begin - if lua_gettop(L) <> 0 then - begin - LuaParameterCountError('GetZoom', '', lua_gettop(L)); - lua_pushnil(L) - end + if CheckLuaParamCount(L, 0, 'GetZoom', '') then + lua_pushnumber(L, ZoomValue) else - lua_pushnumber(L, ZoomValue); + lua_pushnil(L); lc_getzoom:= 1 end; function lc_setammo(L : Plua_State) : LongInt; Cdecl; -var np: LongInt; +var np, at: LongInt; +const + call = 'SetAmmo'; + params = 'ammoType, count, probability, delay [, numberInCrate]'; begin - np:= lua_gettop(L); - if (np < 4) or (np > 5) then - LuaParameterCountError('SetAmmo', 'ammoType, count, probability, delay[, numberInCrate]', lua_gettop(L)) - else if np = 4 then - ScriptSetAmmo(TAmmoType(lua_tointeger(L, 1)), lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), 1) - else - ScriptSetAmmo(TAmmoType(lua_tointeger(L, 1)), lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5)); + if CheckAndFetchParamCount(L, 4, 5, call, params, np) then + begin + at:= LuaToAmmoTypeOrd(L, 1, call, params); + if at >= 0 then + begin + if np = 4 then + ScriptSetAmmo(TAmmoType(at), lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), 1) + else + ScriptSetAmmo(TAmmoType(at), lua_tointeger(L, 2), lua_tointeger(L, 3), lua_tointeger(L, 4), lua_tointeger(L, 5)); + end; + end; lc_setammo:= 0 end; function lc_setammodelay(L : Plua_State) : LongInt; Cdecl; -var np: LongInt; +var at: LongInt; +const + call = 'SetAmmoDelay'; + params = 'ammoType, delay'; begin - np:= lua_gettop(L); - if (np <> 2) then - LuaParameterCountError('SetAmmoDelay', 'ammoType, delay', lua_gettop(L)) - else - ScriptSetAmmoDelay(TAmmoType(lua_tointeger(L, 1)), lua_tointeger(L, 2)); + if CheckLuaParamCount(L, 2, call, params) then + begin + at:= LuaToAmmoTypeOrd(L, 1, call, params); + if at >= 0 then + ScriptSetAmmoDelay(TAmmoType(at), lua_tointeger(L, 2)); + end; lc_setammodelay:= 0 end; function lc_setammostore(L : Plua_State) : LongInt; Cdecl; -var np: LongInt; begin - np:= lua_gettop(L); - if (np <> 4) then - LuaParameterCountError('SetAmmoStore', 'loadouts, probabilities, delays, reinforments', lua_gettop(L)) - else + if CheckLuaParamCount(L, 4, 'SetAmmoStore', 'loadouts, probabilities, delays, reinforments') then begin ScriptAmmoLoadout:= lua_tostring(L, 1); ScriptAmmoProbability:= lua_tostring(L, 2); @@ -1669,12 +2166,7 @@ function lc_getrandom(L : Plua_State) : LongInt; Cdecl; var m : LongInt; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetRandom', 'number', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else + if CheckLuaParamCount(L, 1, 'GetRandom', 'number') then begin m:= lua_tointeger(L, 1); if (m > 0) then @@ -1684,15 +2176,15 @@ LuaError('Lua: Tried to pass 0 to GetRandom!'); lua_pushnil(L); end - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_getrandom:= 1 end; function lc_setwind(L : Plua_State) : LongInt; Cdecl; begin - if lua_gettop(L) <> 1 then - LuaParameterCountError('SetWind', 'windSpeed', lua_gettop(L)) - else + if CheckLuaParamCount(L, 1, 'SetWind', 'windSpeed') then begin cWindSpeed:= int2hwfloat(lua_tointeger(L, 1)) / 100 * cMaxWindSpeed; cWindSpeedf:= SignAs(cWindSpeed,cWindSpeed).QWordValue / SignAs(_1,_1).QWordValue; @@ -1705,71 +2197,60 @@ function lc_getdatapath(L : Plua_State) : LongInt; Cdecl; begin - if lua_gettop(L) <> 0 then - begin - LuaParameterCountError('GetDataPath', '', lua_gettop(L)); + if CheckLuaParamCount(L, 0, 'GetDataPath', '') then + lua_pushstring(L, str2pchar(cPathz[ptData])) + else lua_pushnil(L); - end - else - lua_pushstring(L, str2pchar(cPathz[ptData])); lc_getdatapath:= 1 end; function lc_getuserdatapath(L : Plua_State) : LongInt; Cdecl; begin - if lua_gettop(L) <> 0 then - begin - LuaParameterCountError('GetUserDataPath', '', lua_gettop(L)); + if CheckLuaParamCount(L, 0, 'GetUserDataPath', '') then + lua_pushstring(L, str2pchar(cPathz[ptData])) + else lua_pushnil(L); - end - else - lua_pushstring(L, str2pchar(cPathz[ptData])); lc_getuserdatapath:= 1 end; function lc_maphasborder(L : Plua_State) : LongInt; Cdecl; begin - if lua_gettop(L) <> 0 then - begin - LuaParameterCountError('MapHasBorder', '', lua_gettop(L)); + if CheckLuaParamCount(L, 0, 'MapHasBorder', '') then + lua_pushboolean(L, hasBorder) + else lua_pushnil(L); - end - else - lua_pushboolean(L, hasBorder); lc_maphasborder:= 1 end; function lc_getgearradius(L : Plua_State) : LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('GetGearRadius', 'gearUid', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else + if CheckLuaParamCount(L, 1, 'GetGearRadius', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then lua_pushinteger(L, gear^.Radius) else lua_pushnil(L); - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_getgearradius:= 1 end; function lc_gethoghat(L : Plua_State): LongInt; Cdecl; var gear : PGear; begin - if lua_gettop(L) <> 1 then - LuaParameterCountError('GetHogHat', 'gearUid', lua_gettop(L)) - else begin + if CheckLuaParamCount(L, 1, 'GetHogHat', 'gearUid') then + begin gear := GearByUID(lua_tointeger(L, 1)); if (gear <> nil) and ((gear^.Kind = gtHedgehog) or (gear^.Kind = gtGrave)) and (gear^.Hedgehog <> nil) then lua_pushstring(L, str2pchar(gear^.Hedgehog^.Hat)) else lua_pushnil(L); - end; + end + else + lua_pushnil(L); lc_gethoghat := 1; end; @@ -1777,12 +2258,7 @@ var gear : PGear; hat: ShortString; begin - if lua_gettop(L) <> 2 then - begin - LuaParameterCountError('SetHogHat', 'gearUid, hat', lua_gettop(L)); - lua_pushnil(L) - end - else + if CheckLuaParamCount(L, 2, 'SetHogHat', 'gearUid, hat') then begin gear:= GearByUID(lua_tointeger(L, 1)); if (gear <> nil) and (gear^.Kind = gtHedgehog) and (gear^.Hedgehog <> nil) then @@ -1799,42 +2275,133 @@ lc_sethoghat:= 0; end; -function lc_placegirder(L : Plua_State) : LongInt; Cdecl; +function lc_placesprite(L : Plua_State) : LongInt; Cdecl; +var spr : TSprite; + lf : Word; + tint : LongWord; + i, n : LongInt; + placed, behind, flipHoriz, flipVert : boolean; +const + call = 'PlaceSprite'; + params = 'x, y, sprite, frameIdx, tint, behind, flipHoriz, flipVert, [, landFlag, ... ]'; begin - if lua_gettop(L) <> 3 then - LuaParameterCountError('PlaceGirder', 'x, y, state', lua_gettop(L)) - else - TryPlaceOnLand( + placed:= false; + if CheckAndFetchLuaParamMinCount(L, 4, call, params, n) then + begin + if not lua_isnoneornil(L, 5) then + tint := lua_tointeger(L, 5) + else tint := $FFFFFFFF; + if not lua_isnoneornil(L, 6) then + behind := lua_toboolean(L, 6) + else behind := false; + if not lua_isnoneornil(L, 7) then + flipHoriz := lua_toboolean(L, 7) + else flipHoriz := false; + if not lua_isnoneornil(L, 8) then + flipVert := lua_toboolean(L, 8) + else flipVert := false; + lf:= 0; + + // accept any amount of landflags, loop is never executed if n<9 + for i:= 9 to n do + lf:= lf or lua_tointeger(L, i); + + n:= LuaToSpriteOrd(L, 3, call, params); + if n >= 0 then + begin + spr:= TSprite(n); + if SpritesData[spr].Surface = nil then + LuaError(call + ': ' + EnumToStr(spr) + ' cannot be placed! (required information not loaded)' ) + else + placed:= ForcePlaceOnLand( + lua_tointeger(L, 1) - SpritesData[spr].Width div 2, + lua_tointeger(L, 2) - SpritesData[spr].Height div 2, + spr, lua_tointeger(L, 4), lf, tint, behind, flipHoriz, flipVert); + end; + end; + + lua_pushboolean(L, placed); + lc_placesprite:= 1 +end; + +function lc_erasesprite(L : Plua_State) : LongInt; Cdecl; +var spr : TSprite; + lf : Word; + i, n : LongInt; + eraseOnLFMatch, onlyEraseLF, flipHoriz, flipVert : boolean; +const + call = 'EraseSprite'; + params = 'x, y, sprite, frameIdx, eraseOnLFMatch, onlyEraseLF, flipHoriz, flipVert, [, landFlag, ... ]'; +begin + if CheckAndFetchLuaParamMinCount(L, 4, call, params, n) then + begin + if not lua_isnoneornil(L, 5) then + eraseOnLFMatch := lua_toboolean(L, 5) + else eraseOnLFMatch := false; + if not lua_isnoneornil(L, 6) then + onlyEraseLF := lua_toboolean(L, 6) + else onlyEraseLF := false; + if not lua_isnoneornil(L, 7) then + flipHoriz := lua_toboolean(L, 7) + else flipHoriz := false; + if not lua_isnoneornil(L, 8) then + flipVert := lua_toboolean(L, 8) + else flipVert := false; + lf:= 0; + + // accept any amount of landflags, loop is never executed if n<9 + for i:= 9 to n do + lf:= lf or lua_tointeger(L, i); + + n:= LuaToSpriteOrd(L, 3, call, params); + if n >= 0 then + begin + spr:= TSprite(n); + if SpritesData[spr].Surface = nil then + LuaError(call + ': ' + EnumToStr(spr) + ' cannot be placed! (required information not loaded)' ) + else + EraseLand( + lua_tointeger(L, 1) - SpritesData[spr].Width div 2, + lua_tointeger(L, 2) - SpritesData[spr].Height div 2, + spr, lua_tointeger(L, 4), lf, eraseOnLFMatch, onlyEraseLF, flipHoriz, flipVert); + end; + end; + lc_erasesprite:= 0 +end; + +function lc_placegirder(L : Plua_State) : LongInt; Cdecl; +var placed: boolean; +begin + placed:= false; + if CheckLuaParamCount(L, 3, 'PlaceGirder', 'x, y, frameIdx') then + placed:= TryPlaceOnLandSimple( lua_tointeger(L, 1) - SpritesData[sprAmGirder].Width div 2, lua_tointeger(L, 2) - SpritesData[sprAmGirder].Height div 2, sprAmGirder, lua_tointeger(L, 3), true, false); - lc_placegirder:= 0 + + lua_pushboolean(L, placed); + lc_placegirder:= 1 end; function lc_getcurammotype(L : Plua_State): LongInt; Cdecl; begin - if lua_gettop(L) <> 0 then - LuaParameterCountError('GetCurAmmoType', '', lua_gettop(L)) + if (CurrentHedgehog <> nil) and (CheckLuaParamCount(L, 0, 'GetCurAmmoType', '')) then + lua_pushinteger(L, ord(CurrentHedgehog^.CurAmmoType)) else - lua_pushinteger(L, ord(CurrentHedgehog^.CurAmmoType)); + lua_pushinteger(L, ord(amNothing)); lc_getcurammotype := 1; end; function lc_savecampaignvar(L : Plua_State): LongInt; Cdecl; begin - if lua_gettop(L) <> 2 then - LuaParameterCountError('SaveCampaignVar', 'varname, value', lua_gettop(L)) - else begin + if CheckLuaParamCount(L, 2, 'SaveCampaignVar', 'varname, value') then SendIPC('V!' + lua_tostring(L, 1) + ' ' + lua_tostring(L, 2) + #0); - end; lc_savecampaignvar := 0; end; function lc_getcampaignvar(L : Plua_State): LongInt; Cdecl; begin - if (lua_gettop(L) <> 1) then - LuaParameterCountError('GetCampaignVar', 'varname', lua_gettop(L)) - else + if CheckLuaParamCount(L, 1, 'GetCampaignVar', 'varname') then SendIPCAndWaitReply('V?' + lua_tostring(L, 1) + #0); lua_pushstring(L, str2pchar(CampaignVariable)); lc_getcampaignvar := 1; @@ -1843,9 +2410,7 @@ function lc_hidehog(L: Plua_State): LongInt; Cdecl; var gear: PGear; begin - if lua_gettop(L) <> 1 then - LuaParameterCountError('HideHog', 'gearUid', lua_gettop(L)) - else + if CheckLuaParamCount(L, 1, 'HideHog', 'gearUid') then begin gear:= GearByUID(lua_tointeger(L, 1)); HideHog(gear^.hedgehog) @@ -1857,9 +2422,7 @@ var i, h: LongInt; uid: LongWord; begin - if lua_gettop(L) <> 1 then - LuaParameterCountError('RestoreHog', 'gearUid', lua_gettop(L)) - else + if CheckLuaParamCount(L, 1, 'RestoreHog', 'gearUid') then begin uid:= LongWord(lua_tointeger(L, 1)); if TeamsCount > 0 then @@ -1878,14 +2441,9 @@ function lc_testrectforobstacle(L : Plua_State) : LongInt; Cdecl; var rtn: Boolean; begin - if lua_gettop(L) <> 5 then + if CheckLuaParamCount(L, 5, 'TestRectForObstacle', 'x1, y1, x2, y2, landOnly') then begin - LuaParameterCountError('TestRectForObstacle', 'x1, y1, x2, y2, landOnly', lua_gettop(L)); - lua_pushnil(L); // return value on stack (nil) - end - else - begin - rtn:= TestRectancleForObstacle( + rtn:= TestRectangleForObstacle( lua_tointeger(L, 1), lua_tointeger(L, 2), lua_tointeger(L, 3), @@ -1893,47 +2451,165 @@ lua_toboolean(L, 5) ); lua_pushboolean(L, rtn); - end; + end + else + lua_pushnil(L); // return value on stack (nil) lc_testrectforobstacle:= 1 end; -function lc_setaihintsongear(L : Plua_State) : LongInt; Cdecl; +function lc_getgravity(L : Plua_State) : LongInt; Cdecl; +begin + if CheckLuaParamCount(L, 0, 'GetGravity', '') then + lua_pushinteger(L, hwRound(SignAs(_0_5, cGravity) + (cGravity * 50 / cMaxWindSpeed))); + lc_getgravity:= 1 +end; + +function lc_setgravity(L : Plua_State) : LongInt; Cdecl; +begin + if CheckLuaParamCount(L, 1, 'SetGravity', 'percent') then + begin + cGravity:= _0_02 * lua_tointeger(L, 1) * cMaxWindSpeed; + cGravityf:= 0.00025 * lua_tointeger(L, 1) * 0.02 + end; + lc_setgravity:= 0 +end; + +function lc_setwaterline(L : Plua_State) : LongInt; Cdecl; +var iterator: PGear; +begin + if CheckLuaParamCount(L, 1, 'SetWaterLine', 'waterline') then + begin + cWaterLine:= lua_tointeger(L,1); + AllInactive:= false; + iterator:= GearsList; + while iterator <> nil do + begin + if not (iterator^.Kind in [gtPortal, gtAirAttack]) and (iterator^.Message and (gmAllStoppable or gmLJump or gmHJump) = 0) then + begin + iterator^.Active:= true; + if iterator^.dY.QWordValue = 0 then iterator^.dY.isNegative:= false; + iterator^.State:= iterator^.State or gstMoving; + DeleteCI(iterator) + end; + iterator:= iterator^.NextGear + end + end; + lc_setwaterline:= 0 +end; + +function lc_setgearaihints(L : Plua_State) : LongInt; Cdecl; var gear: PGear; begin - if lua_gettop(L) <> 2 then - LuaParameterCountError('SetAIHintOnGear', 'gearUid, aiHints', lua_gettop(L)) - else + if CheckLuaParamCount(L, 2, 'SetAIHintOnGear', 'gearUid, aiHints') then begin gear:= GearByUID(lua_tointeger(L, 1)); if gear <> nil then gear^.aihints:= lua_tointeger(L, 2); end; - lc_setaihintsongear:= 0 + lc_setgearaihints:= 0 end; function lc_hedgewarsscriptload(L : Plua_State) : LongInt; Cdecl; begin - if lua_gettop(L) <> 1 then - begin - LuaParameterCountError('HedgewarsScriptLoad', 'scriptPath', lua_gettop(L)); - lua_pushnil(L) - end + if CheckLuaParamCount(L, 1, 'HedgewarsScriptLoad', 'scriptPath') then + ScriptLoad(lua_tostring(L, 1)) else - ScriptLoad(lua_tostring(L, 1)); + lua_pushnil(L); lc_hedgewarsscriptload:= 0; end; function lc_declareachievement(L : Plua_State) : LongInt; Cdecl; begin - if lua_gettop(L) <> 4 then - LuaParameterCountError('DeclareAchievement', 'achievementId, teamname, location, value', lua_gettop(L)) - else + if CheckLuaParamCount(L, 4, 'DeclareAchievement', 'achievementId, teamname, location, value') then declareAchievement(lua_tostring(L, 1), lua_tostring(L, 2), lua_tostring(L, 3), lua_tointeger(L, 4)); lc_declareachievement:= 0 end; + + +procedure ScriptFlushPoints(); +begin + ParseCommand('draw ' + PointsBuffer, true, true); + PointsBuffer:= ''; +end; + + +function lc_addPoint(L : Plua_State) : LongInt; Cdecl; +var np, param: LongInt; +begin + if CheckAndFetchParamCountRange(L, 2, 4, 'AddPoint', 'x, y [, width [, erase] ]', np) then + begin + // x + param:= LongInt(lua_tointeger(L,1)); + PointsBuffer:= PointsBuffer + char((param shr 8) and $FF); + PointsBuffer:= PointsBuffer + char((param and $FF)); + // y + param:= LongInt(lua_tointeger(L,2)); + PointsBuffer:= PointsBuffer + char((param shr 8) and $FF); + PointsBuffer:= PointsBuffer + char((param and $FF)); + // width + if np > 2 then + begin + param:= lua_tointeger(L,3); + param:= (param or $80); + // erase + if (np > 3) and lua_toboolean(L, 4) then + param:= (param or $40); + PointsBuffer:= PointsBuffer + char(param); + end + // no width defined + else + PointsBuffer:= PointsBuffer + char(0); + + // flush before shortstring limit length is reached + if length(PointsBuffer) > 245 then + ScriptFlushPoints(); + end; + lc_addPoint:= 0 +end; + + +function lc_flushPoints(L : Plua_State) : LongInt; Cdecl; +begin + if CheckLuaParamCount(L, 0, 'FlushPoints', '') then + if length(PointsBuffer) > 0 then + ScriptFlushPoints(); + lc_flushPoints:= 0 +end; + +// stuff for lua tests +function lc_endluatest(L : Plua_State) : LongInt; Cdecl; +var rstring: shortstring; +const + call = 'EndLuaTest'; + params = 'TEST_SUCCESSFUL or TEST_FAILED'; +begin + if CheckLuaParamCount(L, 1, call, params) then + begin + + case lua_tointeger(L, 1) of + HaltTestSuccess : rstring:= 'Success'; + HaltTestLuaError: rstring:= 'FAILED'; + else + begin + LuaCallError('Parameter must be either ' + params, call, params); + exit(0); + end; + end; + + if cTestLua then + begin + WriteLnToConsole('Lua test finished, result: ' + rstring); + halt(lua_tointeger(L, 1)); + end + else LuaError('Not in lua test mode, engine will keep running. Reported test result: ' + rstring); + + end; + + lc_endluatest:= 0; +end; /////////////////// procedure ScriptPrintStack; @@ -1987,6 +2663,28 @@ lua_pop(luaState, 1); end; +procedure ScriptOnPreviewInit; +begin +// not required if there is no script to run +if not ScriptLoaded then + exit; + +ScriptSetString('Seed', cSeed); +ScriptSetInteger('TemplateFilter', cTemplateFilter); +ScriptSetInteger('TemplateNumber', LuaTemplateNumber); +ScriptSetInteger('MapGen', ord(cMapGen)); +ScriptSetInteger('MapFeatureSize', cFeatureSize); + +ScriptCall('onPreviewInit'); + +// pop game variables +ParseCommand('seed ' + ScriptGetString('Seed'), true, true); +cTemplateFilter := ScriptGetInteger('TemplateFilter'); +LuaTemplateNumber:= ScriptGetInteger('TemplateNumber'); +cMapGen := TMapGen(ScriptGetInteger('MapGen')); +cFeatureSize := ScriptGetInteger('MapFeatureSize'); +end; + procedure ScriptOnGameInit; var i, j, k: LongInt; begin @@ -1995,12 +2693,15 @@ exit; // push game variables so they may be modified by the script +ScriptSetInteger('CursorX', CursorPoint.X); +ScriptSetInteger('CursorY', CursorPoint.Y); ScriptSetInteger('BorderColor', ExplosionBorderColor); ScriptSetInteger('GameFlags', GameFlags); ScriptSetString('Seed', cSeed); ScriptSetInteger('TemplateFilter', cTemplateFilter); ScriptSetInteger('TemplateNumber', LuaTemplateNumber); -ScriptSetInteger('MapGen', cMapGen); +ScriptSetInteger('MapGen', ord(cMapGen)); +ScriptSetInteger('MapFeatureSize', cFeatureSize); ScriptSetInteger('ScreenHeight', cScreenHeight); ScriptSetInteger('ScreenWidth', cScreenWidth); ScriptSetInteger('TurnTime', cHedgehogTurnTime); @@ -2018,8 +2719,8 @@ ScriptSetInteger('SuddenDeathTurns', cSuddenDTurns); ScriptSetInteger('WaterRise', cWaterRise); ScriptSetInteger('HealthDecrease', cHealthDecrease); +ScriptSetInteger('GetAwayTime', cGetAwayTime); ScriptSetString('Map', cMapName); - ScriptSetString('Theme', ''); ScriptSetString('Goals', ''); @@ -2029,7 +2730,8 @@ ParseCommand('seed ' + ScriptGetString('Seed'), true, true); cTemplateFilter := ScriptGetInteger('TemplateFilter'); LuaTemplateNumber:= ScriptGetInteger('TemplateNumber'); -cMapGen := ScriptGetInteger('MapGen'); +cMapGen := TMapGen(ScriptGetInteger('MapGen')); +cFeatureSize := ScriptGetInteger('MapFeatureSize'); GameFlags := ScriptGetInteger('GameFlags'); cHedgehogTurnTime:= ScriptGetInteger('TurnTime'); cCaseFactor := ScriptGetInteger('CaseFreq'); @@ -2046,6 +2748,7 @@ cSuddenDTurns := ScriptGetInteger('SuddenDeathTurns'); cWaterRise := ScriptGetInteger('WaterRise'); cHealthDecrease := ScriptGetInteger('HealthDecrease'); +cGetAwayTime := ScriptGetInteger('GetAwayTime'); if cMapName <> ScriptGetString('Map') then ParseCommand('map ' + ScriptGetString('Map'), true, true); @@ -2133,8 +2836,8 @@ if ret <> 0 then begin - LuaError('Lua: Failed to load ' + name + '(error ' + IntToStr(ret) + ')'); - LuaError('Lua: ' + lua_tostring(luaState, -1)); + LuaError('Failed to load ' + name + '(error ' + IntToStr(ret) + ')'); + LuaError(lua_tostring(luaState, -1)); end else begin @@ -2143,7 +2846,7 @@ lua_pcall(luaState, 0, 0, 0); ScriptLoaded:= true end; - hedgewarsMountPackage(Str2PChar(copy(s, 1, length(s)-4)+'.hwp')); +hedgewarsMountPackage(Str2PChar(copy(s, 1, length(s)-4)+'.hwp')); end; procedure SetGlobals; @@ -2152,6 +2855,25 @@ ScriptSetInteger('GameTime', GameTicks); ScriptSetInteger('TotalRounds', TotalRounds); ScriptSetInteger('WaterLine', cWaterLine); +if isCursorVisible and (not bShowAmmoMenu) then + begin + if (prevCursorPoint.X <> CursorPoint.X) or + (prevCursorPoint.Y <> CursorPoint.Y) then + begin + ScriptSetInteger('CursorX', CursorPoint.X - WorldDx); + ScriptSetInteger('CursorY', cScreenHeight - CursorPoint.Y- WorldDy); + prevCursorPoint.X:= CursorPoint.X; + prevCursorPoint.Y:= CursorPoint.Y; + end + end +else + begin + ScriptSetInteger('CursorX', NoPointX); + ScriptSetInteger('CursorY', NoPointX); + prevCursorPoint.X:= NoPointX; + prevCursorPoint.Y:= NoPointX + end; + if not mapDims then begin mapDims:= true; @@ -2169,18 +2891,24 @@ procedure GetGlobals; begin +// TODO +// Use setters instead, because globals should be read-only! +// Otherwise globals might be changed by Lua, but then unexpectatly overwritten by engine when a ScriptCall is triggered by whatever Lua is doing! +// 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. +// It is inconsistent anyway to have some globals be read-only and others not with no indication whatsoever. +// -- sheepluva TurnTimeLeft:= ScriptGetInteger('TurnTimeLeft'); end; procedure ScriptCall(fname : shortstring); begin -if not ScriptLoaded or (not ScriptExists(fname)) then +if (not ScriptLoaded) or (not ScriptExists(fname)) then exit; SetGlobals; lua_getglobal(luaState, Str2PChar(fname)); if lua_pcall(luaState, 0, 0, 0) <> 0 then begin - LuaError('Lua: Error while calling ' + fname + ': ' + lua_tostring(luaState, -1)); + LuaError('Error while calling ' + fname + ': ' + lua_tostring(luaState, -1)); lua_pop(luaState, 1) end; GetGlobals; @@ -2225,8 +2953,8 @@ function ScriptCall(fname : shortstring; par1, par2, par3, par4 : LongInt) : LongInt; begin -if not ScriptLoaded or (not ScriptExists(fname)) then - exit; +if (not ScriptLoaded) or (not ScriptExists(fname)) then + exit(0); SetGlobals; lua_getglobal(luaState, Str2PChar(fname)); lua_pushinteger(luaState, par1); @@ -2236,7 +2964,7 @@ ScriptCall:= 0; if lua_pcall(luaState, 4, 1, 0) <> 0 then begin - LuaError('Lua: Error while calling ' + fname + ': ' + lua_tostring(luaState, -1)); + LuaError('Error while calling ' + fname + ': ' + lua_tostring(luaState, -1)); lua_pop(luaState, 1) end else @@ -2361,6 +3089,8 @@ st : TSound; he : THogEffect; cg : TCapGroup; + spr: TSprite; + mg : TMapGen; begin // initialize lua luaState:= lua_open; @@ -2385,6 +3115,7 @@ ScriptSetInteger('gfLowGravity', gfLowGravity); ScriptSetInteger('gfLaserSight', gfLaserSight); ScriptSetInteger('gfInvulnerable', gfInvulnerable); +ScriptSetInteger('gfResetHealth', gfResetHealth); ScriptSetInteger('gfVampiric', gfVampiric); ScriptSetInteger('gfKarma', gfKarma); ScriptSetInteger('gfArtillery', gfArtillery); @@ -2420,7 +3151,6 @@ ScriptSetInteger('gmPrecise', gmPrecise); ScriptSetInteger('gmAllStoppable', gmAllStoppable); - // speech bubbles ScriptSetInteger('SAY_SAY', 1); ScriptSetInteger('SAY_THINK', 2); @@ -2450,30 +3180,44 @@ for cg:= Low(TCapGroup) to High(TCapGroup) do ScriptSetInteger(EnumToStr(cg), ord(cg)); -ScriptSetInteger('gstDrowning' ,$00000001); -ScriptSetInteger('gstHHDriven' ,$00000002); -ScriptSetInteger('gstMoving' ,$00000004); -ScriptSetInteger('gstAttacked' ,$00000008); -ScriptSetInteger('gstAttacking' ,$00000010); -ScriptSetInteger('gstCollision' ,$00000020); -ScriptSetInteger('gstHHChooseTarget' ,$00000040); -ScriptSetInteger('gstHHJumping' ,$00000100); -ScriptSetInteger('gsttmpFlag' ,$00000200); -ScriptSetInteger('gstHHThinking' ,$00000800); -ScriptSetInteger('gstNoDamage' ,$00001000); -ScriptSetInteger('gstHHHJump' ,$00002000); -ScriptSetInteger('gstAnimation' ,$00004000); -ScriptSetInteger('gstHHDeath' ,$00008000); -ScriptSetInteger('gstWinner' ,$00010000); -ScriptSetInteger('gstWait' ,$00020000); -ScriptSetInteger('gstNotKickable' ,$00040000); -ScriptSetInteger('gstLoser' ,$00080000); -ScriptSetInteger('gstHHGone' ,$00100000); -ScriptSetInteger('gstInvisible' ,$00200000); +for spr:= Low(TSprite) to High(TSprite) do + ScriptSetInteger(EnumToStr(spr), ord(spr)); + +for mg:= Low(TMapGen) to High(TMapGen) do + ScriptSetInteger(EnumToStr(mg), ord(mg)); + +ScriptSetInteger('gstDrowning' , gstDrowning); +ScriptSetInteger('gstHHDriven' , gstHHDriven); +ScriptSetInteger('gstMoving' , gstMoving); +ScriptSetInteger('gstAttacked' , gstAttacked); +ScriptSetInteger('gstAttacking' , gstAttacking); +ScriptSetInteger('gstCollision' , gstCollision); +ScriptSetInteger('gstChooseTarget' , gstChooseTarget); +ScriptSetInteger('gstHHJumping' , gstHHJumping); +ScriptSetInteger('gsttmpFlag' , gsttmpFlag); +ScriptSetInteger('gstHHThinking' , gstHHThinking); +ScriptSetInteger('gstNoDamage' , gstNoDamage); +ScriptSetInteger('gstHHHJump' , gstHHHJump); +ScriptSetInteger('gstAnimation' , gstAnimation); +ScriptSetInteger('gstHHDeath' , gstHHDeath); +ScriptSetInteger('gstWinner' , gstWinner); +ScriptSetInteger('gstWait' , gstWait); +ScriptSetInteger('gstNotKickable' , gstNotKickable); +ScriptSetInteger('gstLoser' , gstLoser); +ScriptSetInteger('gstHHGone' , gstHHGone); +ScriptSetInteger('gstInvisible' , gstInvisible); +ScriptSetInteger('gstSubmersible' , gstSubmersible); +ScriptSetInteger('gstFrozen' , gstFrozen); +ScriptSetInteger('gstNoGravity' , gstNoGravity); // ai hints -ScriptSetInteger('aihUsualProcessing' ,$00000000); -ScriptSetInteger('aihDoesntMatter' ,$00000001); +ScriptSetInteger('aihUsualProcessing', aihUsualProcessing); +ScriptSetInteger('aihDoesntMatter' , aihDoesntMatter); + +// land flags +ScriptSetInteger('lfIndestructible', lfIndestructible); +ScriptSetInteger('lfIce' , lfIce); +ScriptSetInteger('lfBouncy' , lfBouncy); // register functions lua_register(luaState, _P'HideHog', @lc_hidehog); @@ -2487,14 +3231,18 @@ lua_register(luaState, _P'GetInputMask', @lc_getinputmask); lua_register(luaState, _P'SetInputMask', @lc_setinputmask); lua_register(luaState, _P'AddGear', @lc_addgear); +lua_register(luaState, _P'DismissTeam', @lc_dismissteam); lua_register(luaState, _P'EnableGameFlags', @lc_enablegameflags); lua_register(luaState, _P'DisableGameFlags', @lc_disablegameflags); lua_register(luaState, _P'ClearGameFlags', @lc_cleargameflags); +lua_register(luaState, _P'GetGameFlag', @lc_getgameflag); lua_register(luaState, _P'DeleteGear', @lc_deletegear); lua_register(luaState, _P'AddVisualGear', @lc_addvisualgear); lua_register(luaState, _P'DeleteVisualGear', @lc_deletevisualgear); lua_register(luaState, _P'GetVisualGearValues', @lc_getvisualgearvalues); lua_register(luaState, _P'SetVisualGearValues', @lc_setvisualgearvalues); +lua_register(luaState, _P'GetGearValues', @lc_getgearvalues); +lua_register(luaState, _P'SetGearValues', @lc_setgearvalues); lua_register(luaState, _P'SpawnHealthCrate', @lc_spawnhealthcrate); lua_register(luaState, _P'SpawnAmmoCrate', @lc_spawnammocrate); lua_register(luaState, _P'SpawnUtilityCrate', @lc_spawnutilitycrate); @@ -2532,6 +3280,9 @@ lua_register(luaState, _P'GetHogClan', @lc_gethogclan); lua_register(luaState, _P'GetClanColor', @lc_getclancolor); lua_register(luaState, _P'SetClanColor', @lc_setclancolor); +lua_register(luaState, _P'GetHogVoicepack', @lc_gethogvoicepack); +lua_register(luaState, _P'GetHogFlag', @lc_gethogflag); +lua_register(luaState, _P'GetHogGrave', @lc_gethoggrave); lua_register(luaState, _P'GetHogTeamName', @lc_gethogteamname); lua_register(luaState, _P'SetHogTeamName', @lc_sethogteamname); lua_register(luaState, _P'GetHogName', @lc_gethogname); @@ -2549,6 +3300,8 @@ lua_register(luaState, _P'SetTag', @lc_settag); lua_register(luaState, _P'SetTimer', @lc_settimer); lua_register(luaState, _P'GetTimer', @lc_gettimer); +lua_register(luaState, _P'SetFlightTime', @lc_setflighttime); +lua_register(luaState, _P'GetFlightTime', @lc_getflighttime); lua_register(luaState, _P'SetZoom', @lc_setzoom); lua_register(luaState, _P'GetZoom', @lc_getzoom); lua_register(luaState, _P'HogSay', @lc_hogsay); @@ -2557,6 +3310,9 @@ lua_register(luaState, _P'CampaignLock', @lc_campaignlock); lua_register(luaState, _P'CampaignUnlock', @lc_campaignunlock); lua_register(luaState, _P'GetGearElasticity', @lc_getgearelasticity); +lua_register(luaState, _P'SetGearElasticity', @lc_setgearelasticity); +lua_register(luaState, _P'GetGearFriction', @lc_getgearfriction); +lua_register(luaState, _P'SetGearFriction', @lc_setgearfriction); lua_register(luaState, _P'GetGearRadius', @lc_getgearradius); lua_register(luaState, _P'GetGearMessage', @lc_getgearmessage); lua_register(luaState, _P'SetGearMessage', @lc_setgearmessage); @@ -2571,14 +3327,28 @@ lua_register(luaState, _P'MapHasBorder', @lc_maphasborder); lua_register(luaState, _P'GetHogHat', @lc_gethoghat); lua_register(luaState, _P'SetHogHat', @lc_sethoghat); +lua_register(luaState, _P'EraseSprite', @lc_erasesprite); +lua_register(luaState, _P'PlaceSprite', @lc_placesprite); lua_register(luaState, _P'PlaceGirder', @lc_placegirder); lua_register(luaState, _P'GetCurAmmoType', @lc_getcurammotype); lua_register(luaState, _P'TestRectForObstacle', @lc_testrectforobstacle); +lua_register(luaState, _P'GetGravity', @lc_getgravity); +lua_register(luaState, _P'SetGravity', @lc_setgravity); +lua_register(luaState, _P'SetWaterLine', @lc_setwaterline); +lua_register(luaState, _P'SetNextWeapon', @lc_setnextweapon); +lua_register(luaState, _P'SetWeapon', @lc_setweapon); +lua_register(luaState, _P'SetMaxBuildDistance', @lc_setmaxbuilddistance); +// drawn map functions +lua_register(luaState, _P'AddPoint', @lc_addPoint); +lua_register(luaState, _P'FlushPoints', @lc_flushPoints); -lua_register(luaState, _P'SetGearAIHints', @lc_setaihintsongear); +lua_register(luaState, _P'SetGearAIHints', @lc_setgearaihints); lua_register(luaState, _P'HedgewarsScriptLoad', @lc_hedgewarsscriptload); lua_register(luaState, _P'DeclareAchievement', @lc_declareachievement); +ScriptSetInteger('TEST_SUCCESSFUL' , HaltTestSuccess); +ScriptSetInteger('TEST_FAILED' , HaltTestFailed); +lua_register(luaState, _P'EndLuaTest', @lc_endluatest); ScriptClearStack; // just to be sure stack is empty ScriptLoaded:= false; @@ -2672,6 +3442,9 @@ procedure initModule; begin mapDims:= false; +PointsBuffer:= ''; +prevCursorPoint.X:= NoPointX; +prevCursorPoint.Y:= 0; end; procedure freeModule;