diff --git a/.github/ISSUE_TEMPLATE/function_request.md b/.github/ISSUE_TEMPLATE/function_request.md index 802b557..98de5ac 100644 --- a/.github/ISSUE_TEMPLATE/function_request.md +++ b/.github/ISSUE_TEMPLATE/function_request.md @@ -18,4 +18,4 @@ labels: function **Additional information** - + diff --git a/README.md b/README.md index db60cef..25e4c64 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ *amx* is a software package that allows the execution of unmodified San Andreas: Multiplayer 0.3.7 gamemodes, filterscripts and plugins on Multi -Theft Auto: San Andreas 1.5.8 and higher servers. It is open source, and [**a prebuilt +Theft Auto: San Andreas 1.6 and higher servers. It is open source, and [**a prebuilt binary for Windows is available for testing purposes right now**](https://github.com/multitheftauto/amx/releases). - [License](#license) @@ -86,12 +86,19 @@ features: ## Installation *amx* consists of a binary server module (.dll/.so) and a Lua resource. -It will only run on MTA:SA 1.0 and later. Installation steps are lined +It will only run on MTA:SA 1.6 and later. Installation steps are lined out below. ### Extracting -Extract the "mods" folder into your MTA "server" directory. +- All needed binary files are in the archive provided on Releases + page. Unpack amx.zip and extract the `mods` folder into your MTA + `server` directory. + +- `amx` folder located in mods/deathmatch/resources is a place for the + mentioned Lua resources. It will be empty at this point, so you need + to copy all the latest files of `amx` folder from this repository + into your `amx` folder. ### Configuration @@ -125,13 +132,16 @@ Extract the "mods" folder into your MTA "server" directory. The following rights are used for the following purposes: - - `general.ModifyOtherObjects`: to access files of `amx-*` - resources + - `general.ModifyOtherObjects`: + - to access files of `amx-*` resources - `function.startResource` \ `function.stopResource` \ `function.restartResource`: - to automatically (re)start filterscripts when `amx` starts - for rcon + - `function.getServerPassword` \ + `function.setServerPassword`: + - for rcon ### Migrating gamemodes, filterscripts, plugins from an SA-MP server @@ -179,7 +189,7 @@ Information about this is lined out below. - In SA-MP, there is one folder that contains all gamemodes and another that contains all filterscripts. In MTA, it is the - convention to create a separate resource (i.e. folder) for each + convention to create a separate resource (i.e. folder) for each gamemode. *amx* follows the MTA convention for better integration, which means that a resource needs to be created for each gamemode and filterscript. The naming convention for these is amx-*name* for @@ -250,7 +260,7 @@ Information about this is lined out below. ## Running gamemodes and filterscripts -Before you can run sa-mp modes or filterscripts, you need to start the +Before you can run SA-MP modes or filterscripts, you need to start the *amx* resource. Type this command in the server console or as admin in the ingame console: @@ -378,7 +388,7 @@ amxRegisterPawnPrototypes(prototypes); native amxVersion ( &Float:ver ); ``` -Retrieves the *amx* version as a floating point number, e.g. `1.3`. +Retrieves the *amx* version as a floating point number, e.g. `1.3`. ### amxVersionString @@ -523,7 +533,7 @@ with [amxRegisterLuaPrototypes](#amxRegisterLuaPrototypes). Both functions associate a number of function names with their argument types and (optionally) return type. To specify a return type, prepend the function name with the type letter followed by a colon (:), for example: -`f:testfn`. If you do not specify a return type (i.e. only specify the +`f:testfn`. If you do not specify a return type (i.e. only specify the name, `testfn`), "i" will be assumed. See the syntax sections of the two registration functions for the @@ -666,16 +676,11 @@ is perfect. Below is a list of limitations that may or may not be addressed in later versions of *amx* and Multi Theft Auto. - The following scripting functions are currently not implemented and - will have no effect when called: AllowAdminTeleport, - AllowInteriorWeapons, AllowPlayerTeleport, - DisableInteriorEnterExits, EnableStuntBonusForAll, - EnableStuntBonusForPlayer, EnableTirePopping (tire popping is always - on), EnableZoneNames, LimitGlobalChatRadius, PlayerPlaySound, - SendDeathMessage (use the "killmessages" resource on your server - instead for graphical death messages), SetDeathDropAmount, - SetDisabledWeapons, SetEchoDestination, SetNameTagDrawDistance, - SetPlayerDisabledWeapons, SetTeamCount, SetVehicleNumberPlate, - ShowPlayerNameTagForPlayer, TextDrawSetProportional, + will have no effect when called: DisableInteriorEnterExits, + EnableStuntBonusForAll, EnableStuntBonusForPlayer, EnableTirePopping + (tire popping is always on), PlayerPlaySound, SendDeathMessage (use + the "killmessages" resource on your server instead for graphical + death messages), SetNameTagDrawDistance, TextDrawSetProportional, UsePlayerPedAnims. ## Credits diff --git a/amx-deps/a_amx.inc b/amx-deps/a_amx.inc deleted file mode 100644 index f45a97d..0000000 --- a/amx-deps/a_amx.inc +++ /dev/null @@ -1,175 +0,0 @@ -/* MTA AMX compatibility layer - * - * Extension functions - */ - -#if defined _amx_included - #endinput -#endif -#define _amx_included - -// MTA -native lua(const fn[], {Float,_}:...); -native amxRegisterPawnPrototypes(const prototype[][]); -native amxVersion(&Float:ver); -native amxVersionString(buffer[], maxsize); -native md5hash(str[], const buf[], bufsize); - -// Events -forward OnBotConnect(botid, name[]); -forward OnBotEnterVehicle(botid, vehicleid, seatid); -forward OnBotExitVehicle(botid, vehicleid); -forward OnBotDeath(botid, killerid, weaponid, bodypart); -forward OnBotStateChange(botid, newstate, oldstate); -forward OnVehicleDamage(vehicleid, Float:loss); -forward OnPlayerShootingPlayer(playerid, attackerid, bodypart, Float:loss); -forward OnPlayerWeaponSwitch(playerid, previousWeaponID, currentWeaponID); -forward OnPlayerShoot(playerid, weapon, ammo, ammoInClip, Float:hitX, Float:hitY, Float:hitZ); -forward OnMarkerCreate(markerid); -forward OnMarkerHit(markerid, elemtype[], elemid, matchingDimension); -forward OnMarkerLeave(markerid, elemtype[], elemid, matchingDimension); - -// World -native SetSkyGradient(topRed = 0, topGreen = 0, topBlue = 0, bottomRed = 0, bottomGreen = 0, bottomBlue = 0); -native ResetSkyGradient(); -native GetCloudsEnabled(); -native SetCloudsEnabled(stateid); -native IsGarageOpen(garageid); -native SetGarageOpen(garageid, stateid); -native IsGlitchEnabled(name[]); -native SetGlitchEnabled(name[], stateid); -native SetFPSLimit(fps); -native GetPlayerCount(); -native GetRandomPlayer(); -native GetDistanceBetweenPoints2D(Float:X1, Float:Y1, Float:X2, Float:Y2); -native GetDistanceBetweenPoints3D(Float:X1, Float:Y1, Float:Z1, Float:X2, Float:Y2, Float:Z2); - -// Water -native GetWaveHeight(); -native SetWaveHeight(Float:height); -native SetWaterLevel(Float:level); - -// Pickups -native GetPickupType(pickupid); -native SetPickupType(pickupid, typeid, amount, ammo = 500); -native GetPickupWeapon(pickupid); -native GetPickupAmount(pickupid); -native GetPickupAmmo(pickupid); - -// Native Markers -native CreateMarker(Float:X, Float:Y, Float:Z, type[], Float:size, red, green, blue, alpha); -native DestroyMarker(markerid); -native GetMarkerColor(markerid, colorid); // Color IDs: 0 = Red, 1 = Green, 2 = Blue, 3 = Alpha -native GetMarkerIcon(markerid); // 0 = No icon, 1 = Arrow, 2 = Race finish -native GetMarkerSize(markerid, &Float:size); -native GetMarkerTarget(markerid, &Float:X, &Float:Y, &Float:Z); -native GetMarkerType(markerid); // 0 = Checkpoint, 1 = Ring, 2 = Cylinder, 3 = Arrow, 4 = Corona -native SetMarkerColor(markerid, red, green, blue, alpha); -native SetMarkerIcon(markerid, iconid); // 0 = No icon, 1 = Arrow, 2 = Race finish -native SetMarkerSize(markerid, Float:size); -native SetMarkerTarget(markerid, Float:X, Float:Y, Float:Z); -native SetMarkerType(markerid, typeid); // 0 = Checkpoint, 1 = Ring, 2 = Cylinder, 3 = Arrow, 4 = Corona -native IsPlayerInMarker(markerid, playerid); -native IsBotInMarker(markerid, botid); -native IsVehicleInMarker(markerid, vehicleid); - -// Rules -native GetRuleValue(rule[], const buf[], bufsize); -native SetRuleValue(rule[], value[]); -native RemoveRuleValue(rule[]); - -// Objects -native GetObjectAlpha(objectid); -native SetObjectAlpha(objectid, alpha); - -// Players -native AddPlayerClothes(playerid, type, index); -native GetPlayerClothes(playerid, type); -native RemovePlayerClothes(playerid, type); -native ShowPlayerMarker(playerid, show); -native IsPlayerInWater(playerid); -native IsPlayerOnFire(playerid); -native IsPlayerDucked(playerid); -native IsPlayerOnGround(playerid); -native SetPlayerOnFire(playerid, fire); -native GetPlayerStat(playerid, statid); -native SetPlayerStat(playerid, statid, Float:value); -native GetPlayerCanBeKnockedOffBike(playerid); -native SetPlayerCanBeKnockedOffBike(playerid, stateid); -native GetPlayerDoingDriveBy(playerid); -native SetPlayerDoingDriveBy(playerid, stateid); -native SetPlayerWeaponSlot(playerid, slotid); -native SetPlayerHeadless(playerid, stateid); -native GetPlayerBlurLevel(playerid); -native SetPlayerBlurLevel(playerid, level); -native GetPlayerAlpha(playerid); -native SetPlayerAlpha(playerid, alpha); -native FadePlayerCamera(playerid, fadeIn, Float:timeToFade = 1.0, red = 0, green = 0, blue = 0); -native SetPlayerControlState(playerid, control[], stateid); - -// Vehicles -native GetVehicleMaxPassengers(vehicleid); -native SetVehicleModel(vehicleid, model); -native GetVehicleEngineState(vehicleid); -native SetVehicleEngineState(vehicleid, stateid); -native GetVehicleDoorState(vehicleid, door); -native SetVehicleDoorState(vehicleid, door, stateid); -native GetVehicleLightState(vehicleid, lightid); -native SetVehicleLightState(vehicleid, lightid, stateid); -native GetVehicleOverrideLights(vehicleid); -native SetVehicleOverrideLights(vehicleid, stateid); -native GetVehicleWheelState(vehicleid, wheelid); -native SetVehicleWheelState(vehicleid, frontLeft = -1, rearLeft = -1, frontRight = -1, rearRight = -1); -native GetVehiclePanelState(vehicleid, panelid); -native SetVehiclePanelState(vehicleid, panelid, stateid); -native GetVehicleAlpha(vehicleid); -native SetVehicleAlpha(vehicleid, alpha); -native GetVehiclePaintjob(vehicleid); -native GetVehicleSirensOn(vehicleid); -native SetVehicleSirensOn(vehicleid, stateid); -native IsTrainDerailable(vehicleid); -native IsTrainDerailed(vehicleid); -native SetTrainDerailable(vehicleid, stateid); -native SetTrainDerailed(vehicleid, stateid); -native GetTrainDirection(vehicleid); -native SetTrainDirection(vehicleid, direction); -native GetTrainSpeed(vehicleid, &Float:speed); -native SetTrainSpeed(vehicleid, &Float:speed); - -// Bots -native CreateBot(modelid, Float:x, Float:y, Float:z, name[] = "Bot"); -native SetBotHealth(botid, Float:health); -native GetBotHealth(botid, &Float:health); -native SetBotArmour(botid, Float:armour); -native GetBotArmour(botid, &Float:armour); -native SetBotPos(botid, Float:X, Float:Y, Float:Z); -native GetBotPos(botid, &Float:X, &Float:Y, &Float:Z); -native SetBotRot(botid, Float:RotX, Float:RotY, Float:RotZ); -native GetBotRot(botid, &Float:RotX, &Float:RotY, &Float:RotZ); -native IsBotInWater(botid); -native IsBotOnFire(botid); -native IsBotDucked(botid); -native IsBotOnGround(botid); -native GetBotFightingStyle(botid); -native SetBotFightingStyle(botid, styleid); -native SetBotOnFire(botid, fire); -native GetBotStat(botid, statid); -native SetBotStat(botid, statid, Float:value); -native GetBotState(botid); -native PutBotInVehicle(botid, vehicleid, seatid); -native RemoveBotFromVehicle(botid); -native SetBotControlState(botid, control[], stateid); -native SetBotAimTarget(botid, &Float:X, &Float:Y, &Float:Z); -native GetBotDoingDriveBy(botid); -native SetBotDoingDriveBy(botid, stateid); -native GetBotCanBeKnockedOffBike(botid); -native SetBotCanBeKnockedOffBike(botid, stateid); -native SetBotWeaponSlot(botid, slotid); -native SetBotHeadless(botid, stateid); -native BotKill(botid); -native GetBotAlpha(botid); -native SetBotAlpha(botid, alpha); -native GetBotName(botid, const buf[], bufsize); -native GetBotVehicleSeat(botid); -native GetBotVelocity(botid, &Float:X, &Float:Y, &Float:Z); -native SetBotVelocity(botid, Float:X, Float:Y, Float:Z); diff --git a/amx-deps/amxdeploy.pl b/amx-deps/amxdeploy.pl index a087af9..d0bddb1 100644 --- a/amx-deps/amxdeploy.pl +++ b/amx-deps/amxdeploy.pl @@ -231,7 +231,7 @@ sub copySelection { print "> Configuring\n"; -# Read sa-mp config +# Read SA-MP config my %sampcfg; open SAMPCFG, $oldsrvpath . "/server.cfg"; while() { @@ -279,7 +279,7 @@ sub copySelection { # Get filterscripts already in amx meta.xml my %usedFilterscripts = %{{ map {$_ => 1 if(!/^$/)} split(/\s+/, $filterscriptsNode->att("value")) }}; - # Add filterscripts that are in samp's server.cfg and also exist in MTA + # Add filterscripts that are in SA-MP's server.cfg and also exist in MTA if($sampcfg{filterscripts}) { for(split /\s+/, $sampcfg{filterscripts}) { next if(!-e $newsrvpath . "/mods/deathmatch/resources/amx-fs-$_"); @@ -289,7 +289,7 @@ sub copySelection { # Get plugins already in amx meta.xml my %usedPlugins = %{{ map {$_ => 1 if(!/^$/)} split(/\s+/, $pluginsNode->att("value")) }}; - # Add plugins that are in samp's server.cfg and also exist in MTA + # Add plugins that are in SA-MP's server.cfg and also exist in MTA if($sampcfg{plugins}) { for(split /\s+/, $sampcfg{plugins}) { next if(!-e $newsrvpath . "/mods/deathmatch/resources/amx/plugins/$_.dll" && !-e $newsrvpath . "/mods/deathmatch/resources/amx/plugins/$_.so"); diff --git a/amx-deps/meta.xml b/amx-deps/meta.xml index 26699b6..ec5105f 100644 --- a/amx-deps/meta.xml +++ b/amx-deps/meta.xml @@ -1,5 +1,4 @@ - diff --git a/amx-deps/src/CFunctions.cpp b/amx-deps/src/CFunctions.cpp index c4690fe..5ca11dc 100644 --- a/amx-deps/src/CFunctions.cpp +++ b/amx-deps/src/CFunctions.cpp @@ -176,7 +176,7 @@ int CFunctions::amxLoad(lua_State *luaVM) { return 1; } - // Register sa-mp and plugin natives + // Register SA-MP and plugin natives amx_CoreInit(amx); amx_ConsoleInit(amx); amx_FloatInit(amx); diff --git a/amx-test/pawno/include/a_amx.inc b/amx-test/pawno/include/a_amx.inc index f45a97d..bdbcdbd 100644 --- a/amx-test/pawno/include/a_amx.inc +++ b/amx-test/pawno/include/a_amx.inc @@ -11,49 +11,61 @@ // MTA native lua(const fn[], {Float,_}:...); native amxRegisterPawnPrototypes(const prototype[][]); +native amxVersionString(buffer[], maxsize = sizeof(buffer)); native amxVersion(&Float:ver); -native amxVersionString(buffer[], maxsize); -native md5hash(str[], const buf[], bufsize); // Events forward OnBotConnect(botid, name[]); -forward OnBotEnterVehicle(botid, vehicleid, seatid); +forward OnBotEnterVehicle(botid, vehicleid, ispassenger); forward OnBotExitVehicle(botid, vehicleid); forward OnBotDeath(botid, killerid, weaponid, bodypart); forward OnBotStateChange(botid, newstate, oldstate); -forward OnVehicleDamage(vehicleid, Float:loss); -forward OnPlayerShootingPlayer(playerid, attackerid, bodypart, Float:loss); -forward OnPlayerWeaponSwitch(playerid, previousWeaponID, currentWeaponID); -forward OnPlayerShoot(playerid, weapon, ammo, ammoInClip, Float:hitX, Float:hitY, Float:hitZ); forward OnMarkerCreate(markerid); -forward OnMarkerHit(markerid, elemtype[], elemid, matchingDimension); -forward OnMarkerLeave(markerid, elemtype[], elemid, matchingDimension); +forward OnMarkerHit(markerid, type[], id, worldid); +forward OnMarkerLeave(markerid, type[], id, worldid); +forward OnPlayerClickWorld(playerid, button, updown, worldX, worldY, worldZ); +forward OnPlayerClickWorldPlayer(playerid, button, updown, clickedid, worldX, worldY, worldZ); +forward OnPlayerClickWorldObject(playerid, button, updown, clickedid, worldX, worldY, worldZ); +forward OnPlayerClickWorldVehicle(playerid, button, updown, clickedid, worldX, worldY, worldZ); +forward OnPlayerWeaponSwitch(playerid, oldweaponid, newweaponid); +forward OnPlayerKeyDown(playerid, key); +forward OnPlayerKeyUp(playerid, key); // World +native Float:GetGameSpeed(); +native SetGameSpeed(Float:speed); +native GetSkyGradient(&topRed, &topGreen, &topBlue, &bottomRed, &bottomGreen, &bottomBlue); native SetSkyGradient(topRed = 0, topGreen = 0, topBlue = 0, bottomRed = 0, bottomGreen = 0, bottomBlue = 0); native ResetSkyGradient(); native GetCloudsEnabled(); -native SetCloudsEnabled(stateid); +native SetCloudsEnabled(bool:enable); +native GetInteriorSoundsEnabled(); +native SetInteriorSoundsEnabled(bool:enable); native IsGarageOpen(garageid); -native SetGarageOpen(garageid, stateid); +native SetGarageOpen(garageid, bool:open); native IsGlitchEnabled(name[]); -native SetGlitchEnabled(name[], stateid); +native SetGlitchEnabled(name[], bool:enable); +native Float:GetAircraftMaxVelocity(); +native SetAircraftMaxVelocity(Float:velocity); +native Float:GetAircraftMaxHeight(); +native SetAircraftMaxHeight(Float:height); +native Float:GetJetpackMaxHeight(); +native SetJetpackMaxHeight(Float:height); +native GetFPSLimit(); native SetFPSLimit(fps); -native GetPlayerCount(); native GetRandomPlayer(); -native GetDistanceBetweenPoints2D(Float:X1, Float:Y1, Float:X2, Float:Y2); -native GetDistanceBetweenPoints3D(Float:X1, Float:Y1, Float:Z1, Float:X2, Float:Y2, Float:Z2); +native GetPlayerCount(); // Water -native GetWaveHeight(); +native Float:GetWaveHeight(); native SetWaveHeight(Float:height); native SetWaterLevel(Float:level); // Pickups native GetPickupType(pickupid); -native SetPickupType(pickupid, typeid, amount, ammo = 500); -native GetPickupWeapon(pickupid); +native SetPickupType(pickupid, type, model, ammo = 500); native GetPickupAmount(pickupid); +native GetPickupWeapon(pickupid); native GetPickupAmmo(pickupid); // Native Markers @@ -68,17 +80,22 @@ native SetMarkerColor(markerid, red, green, blue, alpha); native SetMarkerIcon(markerid, iconid); // 0 = No icon, 1 = Arrow, 2 = Race finish native SetMarkerSize(markerid, Float:size); native SetMarkerTarget(markerid, Float:X, Float:Y, Float:Z); -native SetMarkerType(markerid, typeid); // 0 = Checkpoint, 1 = Ring, 2 = Cylinder, 3 = Arrow, 4 = Corona +native SetMarkerType(markerid, type); // 0 = Checkpoint, 1 = Ring, 2 = Cylinder, 3 = Arrow, 4 = Corona native IsPlayerInMarker(markerid, playerid); native IsBotInMarker(markerid, botid); native IsVehicleInMarker(markerid, vehicleid); // Rules -native GetRuleValue(rule[], const buf[], bufsize); -native SetRuleValue(rule[], value[]); -native RemoveRuleValue(rule[]); +native IsValidServerRule(name[]); +native GetServerRule(name[], buf[], bufsize = sizeof(buf)); +native SetServerRule(name[], value[]); +native RemoveServerRule(name[]); // Objects +native IsObjectBreakable(objectid); +native SetObjectBreakable(objectid, bool:breakable); +native GetObjectScale(objectid, &Float:X, &Float:Y, &Float:Z); +native SetObjectScale(objectid, Float:X, Float:Y, Float:Z); native GetObjectAlpha(objectid); native SetObjectAlpha(objectid, alpha); @@ -86,90 +103,158 @@ native SetObjectAlpha(objectid, alpha); native AddPlayerClothes(playerid, type, index); native GetPlayerClothes(playerid, type); native RemovePlayerClothes(playerid, type); -native ShowPlayerMarker(playerid, show); +native ShowPlayerMarker(playerid, mode); native IsPlayerInWater(playerid); native IsPlayerOnFire(playerid); +native SetPlayerOnFire(playerid, bool:fire); native IsPlayerDucked(playerid); native IsPlayerOnGround(playerid); -native SetPlayerOnFire(playerid, fire); +native IsPlayerChoking(playerid); +native SetPlayerChoking(playerid, bool:choking); +native GetPlayerWalkingStyle(playerid); +native SetPlayerWalkingStyle(playerid, style); native GetPlayerStat(playerid, statid); native SetPlayerStat(playerid, statid, Float:value); -native GetPlayerCanBeKnockedOffBike(playerid); -native SetPlayerCanBeKnockedOffBike(playerid, stateid); native GetPlayerDoingDriveBy(playerid); -native SetPlayerDoingDriveBy(playerid, stateid); +native SetPlayerDoingDriveBy(playerid, bool:driveBy); +native GetPlayerCanBeKnockedOffBike(playerid); +native SetPlayerCanBeKnockedOffBike(playerid, bool:knockOff); +native GetPlayerWeaponSlot(playerid); native SetPlayerWeaponSlot(playerid, slotid); -native SetPlayerHeadless(playerid, stateid); +native GetPlayerAmmoInClip(playerid); +native IsPlayerHeadless(playerid); +native SetPlayerHeadless(playerid, bool:headless); native GetPlayerBlurLevel(playerid); native SetPlayerBlurLevel(playerid, level); +native FadePlayerCamera(playerid, bool:fadeIn, Float:timeToFade = 1.0, red = 0, green = 0, blue = 0); +native SetPlayerControlState(playerid, control[], bool:controlState); +native IsPlayerCursorShowing(playerid); +native ShowPlayerCursor(playerid, bool:show, bool:controls); native GetPlayerAlpha(playerid); native SetPlayerAlpha(playerid, alpha); -native FadePlayerCamera(playerid, fadeIn, Float:timeToFade = 1.0, red = 0, green = 0, blue = 0); -native SetPlayerControlState(playerid, control[], stateid); +native RemovePlayerWeapon(playerid, weaponid); +native Float:GetPlayerGravity(playerid); +native SetPlayerGravity(playerid, Float:gravity); +native GetPlayerSkillLevel(playerid, skill); // Vehicles -native GetVehicleMaxPassengers(vehicleid); +native IsVehicleInWater(vehicleid); +native IsVehicleOnGround(vehicleid); native SetVehicleModel(vehicleid, model); +native GetVehicleMaxPassengers(vehicleid); native GetVehicleEngineState(vehicleid); -native SetVehicleEngineState(vehicleid, stateid); +native SetVehicleEngineState(vehicleid, bool:engine); +native GetVehicleSirenState(vehicleid); +native SetVehicleSirenState(vehicleid, bool:siren); native GetVehicleDoorState(vehicleid, door); -native SetVehicleDoorState(vehicleid, door, stateid); -native GetVehicleLightState(vehicleid, lightid); -native SetVehicleLightState(vehicleid, lightid, stateid); +native SetVehicleDoorState(vehicleid, door, doorState); +native GetVehicleLightState(vehicleid, light); +native SetVehicleLightState(vehicleid, light, lightState); native GetVehicleOverrideLights(vehicleid); -native SetVehicleOverrideLights(vehicleid, stateid); -native GetVehicleWheelState(vehicleid, wheelid); +native SetVehicleOverrideLights(vehicleid, override); +native GetVehicleWheelState(vehicleid, wheel); native SetVehicleWheelState(vehicleid, frontLeft = -1, rearLeft = -1, frontRight = -1, rearRight = -1); -native GetVehiclePanelState(vehicleid, panelid); -native SetVehiclePanelState(vehicleid, panelid, stateid); +native GetVehiclePanelState(vehicleid, panel); +native SetVehiclePanelState(vehicleid, panel, panelState); +native GetVehicleVariant(vehicleid, &var1, &var2); +native SetVehicleVariant(vehicleid, var1, var2); native GetVehicleAlpha(vehicleid); native SetVehicleAlpha(vehicleid, alpha); -native GetVehiclePaintjob(vehicleid); -native GetVehicleSirensOn(vehicleid); -native SetVehicleSirensOn(vehicleid, stateid); native IsTrainDerailable(vehicleid); +native SetTrainDerailable(vehicleid, bool:derailable); native IsTrainDerailed(vehicleid); -native SetTrainDerailable(vehicleid, stateid); -native SetTrainDerailed(vehicleid, stateid); +native SetTrainDerailed(vehicleid, bool:derailed); native GetTrainDirection(vehicleid); -native SetTrainDirection(vehicleid, direction); +native SetTrainDirection(vehicleid, bool:clockwise); native GetTrainSpeed(vehicleid, &Float:speed); -native SetTrainSpeed(vehicleid, &Float:speed); +native SetTrainSpeed(vehicleid, Float:speed); +native GetVehicleDriver(vehicleid); +native GetVehicleNumberPlate(vehicleid, plate[], len = sizeof(plate)); +native GetVehicleColor(vehicleid, &color1, &color2); +native GetVehiclePaintjob(vehicleid); +native GetVehicleInterior(vehicleid); // Bots native CreateBot(modelid, Float:x, Float:y, Float:z, name[] = "Bot"); -native SetBotHealth(botid, Float:health); -native GetBotHealth(botid, &Float:health); -native SetBotArmour(botid, Float:armour); -native GetBotArmour(botid, &Float:armour); -native SetBotPos(botid, Float:X, Float:Y, Float:Z); -native GetBotPos(botid, &Float:X, &Float:Y, &Float:Z); -native SetBotRot(botid, Float:RotX, Float:RotY, Float:RotZ); -native GetBotRot(botid, &Float:RotX, &Float:RotY, &Float:RotZ); +native DestroyBot(botid); +native AddBotClothes(botid, type, index); +native GetBotClothes(botid, type); +native RemoveBotClothes(botid, type); native IsBotInWater(botid); native IsBotOnFire(botid); +native SetBotOnFire(botid, bool:fire); native IsBotDucked(botid); native IsBotOnGround(botid); +native IsBotChoking(botid); +native SetBotChoking(botid, bool:choking); +native GetBotHealth(botid, &Float:health); +native SetBotHealth(botid, Float:health); +native GetBotArmour(botid, &Float:armour); +native SetBotArmour(botid, Float:armour); +native GetBotPos(botid, &Float:X, &Float:Y, &Float:Z); +native SetBotPos(botid, Float:X, Float:Y, Float:Z); +native GetBotRot(botid, &Float:rX, &Float:rY, &Float:rZ); +native SetBotRot(botid, Float:rX, Float:rY, Float:rZ); +native GetBotVelocity(botid, &Float:X, &Float:Y, &Float:Z); +native SetBotVelocity(botid, Float:X, Float:Y, Float:Z); +native GetBotInterior(botid); +native SetBotInterior(botid, interiorid); +native GetBotVirtualWorld(botid); +native SetBotVirtualWorld(botid, worldid); native GetBotFightingStyle(botid); -native SetBotFightingStyle(botid, styleid); -native SetBotOnFire(botid, fire); +native SetBotFightingStyle(botid, style); +native GetBotWalkingStyle(botid); +native SetBotWalkingStyle(botid, style); +native GetBotSkin(botid); +native SetBotSkin(botid, skinid); +native GetBotSkillLevel(botid, skill); +native SetBotSkillLevel(botid, skill, level); native GetBotStat(botid, statid); native SetBotStat(botid, statid, Float:value); native GetBotState(botid); native PutBotInVehicle(botid, vehicleid, seatid); native RemoveBotFromVehicle(botid); -native SetBotControlState(botid, control[], stateid); -native SetBotAimTarget(botid, &Float:X, &Float:Y, &Float:Z); +native GetBotVehicleID(botid); +native GetBotVehicleSeat(botid); +native IsBotInVehicle(botid, vehicleid); +native IsBotInAnyVehicle(botid); +native SetBotControlState(botid, control[], bool:controlState); +native SetBotAimTarget(botid, Float:X, Float:Y, Float:Z); native GetBotDoingDriveBy(botid); -native SetBotDoingDriveBy(botid, stateid); +native SetBotDoingDriveBy(botid, bool:driveBy); native GetBotCanBeKnockedOffBike(botid); -native SetBotCanBeKnockedOffBike(botid, stateid); +native SetBotCanBeKnockedOffBike(botid, bool:knockOff); +native GetBotAmmo(botid); +native GetBotWeaponState(botid); +native GetBotWeapon(botid); +native GetBotWeaponSlot(botid); native SetBotWeaponSlot(botid, slotid); -native SetBotHeadless(botid, stateid); -native BotKill(botid); +native GetBotAmmoInClip(botid); +native IsBotHeadless(botid); +native SetBotHeadless(botid, bool:headless); +native IsBotDead(botid); +native KillBot(botid); +native GetBotName(botid, buf[], bufsize = sizeof(buf)); native GetBotAlpha(botid); native SetBotAlpha(botid, alpha); -native GetBotName(botid, const buf[], bufsize); -native GetBotVehicleSeat(botid); -native GetBotVelocity(botid, &Float:X, &Float:Y, &Float:Z); -native SetBotVelocity(botid, Float:X, Float:Y, Float:Z); + +// Scoreboard +native AddScoreBoardColumn(column[]); +native SetPlayerScoreBoardData(playerid, column[], data[]); +native RemoveScoreBoardColumn(column[]); + +// Player Data +native SetPlayerIntData(playerid, key[], value); +native GetPlayerIntData(playerid, key[]); +native SetPlayerFloatData(playerid, key[], Float:value); +native Float:GetPlayerFloatData(playerid, key[]); +native SetPlayerBoolData(playerid, key[], bool:value); +native GetPlayerBoolData(playerid, key[]); +native SetPlayerStringData(playerid, key[], value[]); +native GetPlayerStringData(playerid, key[], buf[], bufsize = sizeof(buf)); +native ResetPlayerData(playerid, key[]); + +// Misc +native AddEventHandler(event[], func[]); +native RemoveEventHandler(func[]); +native IsPluginLoaded(plugin[]); diff --git a/amx-test/testgm.amx b/amx-test/testgm.amx index c1e4259..6c537df 100644 Binary files a/amx-test/testgm.amx and b/amx-test/testgm.amx differ diff --git a/amx-test/testgm.pwn b/amx-test/testgm.pwn index 793817b..40a53d5 100644 --- a/amx-test/testgm.pwn +++ b/amx-test/testgm.pwn @@ -34,8 +34,8 @@ public OnGameModeInit() AddPlayerClass(0, 1958.3783, 1343.1572, 15.3746, 269.1425, 0, 0, 0, 0, 0, 0); new buf[64]; - SetRuleValue("nya", "test"); - GetRuleValue("nya", buf, sizeof(buf)); + SetServerRule("nya", "test"); + GetServerRule("nya", buf, sizeof(buf)); printf("val: %s", buf); bot = CreateBot(0, 0.5, 0.5, 0.5, "Nyashk"); @@ -83,11 +83,10 @@ public OnPlayerConnect(playerid) new listitems[] = "1\tDeagle\n2\tSawnoff\n3\tPistol\n4\tGrenade\n5\tParachute\n6\tLorikeet"; ShowPlayerDialog(playerid, 2, DIALOG_STYLE_LIST, "List of weapons:", listitems, "Select", "Cancel"); - //ShowPlayerDialog(playerid, 1, DIALOG_STYLE_LIST, "testcapt", "info", "Okay", "Canceled"); + //ShowPlayerDialog(playerid, 1, DIALOG_STYLE_LIST, "testcapt", "info", "Okay", "Cancel"); return 1; } -forward OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]); public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) { if(dialogid == 0) { // Our example msgbox @@ -164,13 +163,13 @@ public OnBotConnect(botid, name[]) return 1; } -public OnMarkerHit(markerid, elemtype[], elemid, matchingDimension) +public OnMarkerHit(markerid, type[], id, worldid) { - printf("OnMarkerHit(%d, %s, %d)", markerid, elemtype, elemid); + printf("OnMarkerHit(%d, %s, %d)", markerid, type, id); return 1; } -public OnBotEnterVehicle(botid, vehicleid, seatid) +public OnBotEnterVehicle(botid, vehicleid, ispassenger) { return 1; } @@ -186,21 +185,21 @@ public OnBotDeath(botid, killerid, weaponid, bodypart) return 1; } -public OnPlayerWeaponSwitch(playerid, previousWeaponID, currentWeaponID) +public OnPlayerWeaponSwitch(playerid, oldweaponid, newweaponid) { - printf("OnPlayerWeaponSwitch(%d, %d, %d)", playerid, previousWeaponID, currentWeaponID); + printf("OnPlayerWeaponSwitch(%d, %d, %d)", playerid, oldweaponid, newweaponid); return 1; } -public OnPlayerShoot(playerid, weapon, ammo, ammoInClip, Float:hitX, Float:hitY, Float:hitZ) +public OnPlayerWeaponShot(playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ) { - printf("OnPlayerShoot(%d, %d, %d, %d, %f, %f, %f)", playerid, weapon, ammo, ammoInClip, hitX, hitY, hitZ); + printf("OnPlayerWeaponShot(%d, %d, %d, %d, %f, %f, %f)", playerid, weaponid, hittype, hitid, Float:fX, Float:fY, Float:fZ); return 1; } -public OnVehicleDamage(vehicleid, Float:loss) +public OnVehicleDamageStatusUpdate(vehicleid, playerid) { - printf("OnVehicleDamage(%d, %f)", vehicleid, loss); + printf("OnVehicleDamageStatusUpdate(%d, %d)", vehicleid, playerid); return 1; } diff --git a/amx/client/anim.lua b/amx/client/anim.lua index adbdd07..71fcb0b 100644 --- a/amx/client/anim.lua +++ b/amx/client/anim.lua @@ -235,7 +235,7 @@ end function Phase:_setup(parent) self.parent = parent if self[1] then - for i,phase in ipairs(self) do + for i, phase in ipairs(self) do if type(phase) == 'function' then phase = { fn = phase } self[i] = phase @@ -255,7 +255,7 @@ end function Phase:addPhase(phase) setmetatable(phase, Phase) - self[#self+1] = phase + self[#self + 1] = phase if #self == 1 then self.curphase = 1 end @@ -263,7 +263,7 @@ function Phase:addPhase(phase) end function Phase:addPhases(...) - for i,phase in ipairs({ ... }) do + for i, phase in ipairs({ ... }) do self:addPhase(phase) end end @@ -274,7 +274,7 @@ function updateAnim() local curTick = getTickCount() local phaseEnded - for i,anim in ipairs(Animation.collection) do + for i, anim in ipairs(Animation.collection) do if anim.playing then phase = anim while phase.curphase do @@ -331,7 +331,7 @@ function updateAnim() end end if anim and phase.fn then - phase.value = phase.from + phase.speed*phase.passed + phase.value = phase.from + phase.speed * phase.passed if elem then phase.fn(elem, phase.transform and phase.transform(phase.value) or phase.value, phase) else @@ -345,7 +345,7 @@ end function table.find(t, ...) local args = { ... } if #args == 0 then - for k,v in pairs(t) do + for k, v in pairs(t) do if v then return k, v end @@ -357,8 +357,8 @@ function table.find(t, ...) if value == '[nil]' then value = nil end - for k,v in pairs(t) do - for i,index in ipairs(args) do + for k, v in pairs(t) do + for i, index in ipairs(args) do if type(index) == 'function' then v = index(v) else @@ -376,7 +376,7 @@ function table.find(t, ...) end function table.removevalue(t, val) - for i,v in ipairs(t) do + for i, v in ipairs(t) do if v == val then table.remove(t, i) return i @@ -385,8 +385,6 @@ function table.removevalue(t, val) return false end - - --[[ The preset functions return phases for commonly used animation effects. @@ -398,20 +396,20 @@ function Animation.presets.guiPulse(time, value, phase) -- guiPulse(time) -- Pulses an image (scale down/up). time = ms for a complete pulsation cycle if type(time) ~= 'userdata' then - return { from = 0, to = 2*math.pi, transform = math.sin, time = time, repeats = 0, fn = Animation.presets.pulse } + return { from = 0, to = 2 * math.pi, transform = math.sin, time = time, repeats = 0, fn = Animation.presets.pulse } else local elem = time if not phase.width then phase.width, phase.height = guiGetSize(elem, false) phase.centerX, phase.centerY = guiGetPosition(elem, false) - phase.centerX = phase.centerX + math.floor(phase.width/2) - phase.centerY = phase.centerY + math.floor(phase.height/2) + phase.centerX = phase.centerX + math.floor(phase.width / 2) + phase.centerY = phase.centerY + math.floor(phase.height / 2) end - local pct = 1 - (value+1)*0.1 - local width = pct*phase.width - local height = pct*phase.height - local x = phase.centerX - math.floor(width/2) - local y = phase.centerY - math.floor(height/2) + local pct = 1 - (value + 1) * 0.1 + local width = pct * phase.width + local height = pct * phase.height + local x = phase.centerX - math.floor(width / 2) + local y = phase.centerY - math.floor(height / 2) guiSetPosition(elem, x, y, false) guiSetSize(elem, width, height, false) end @@ -428,18 +426,18 @@ end function Animation.presets.guiMove(endX, endY, time, loop, startX, startY, speedUpSlowDown) -- guiMove(endX, endY, [ time = 1000, loop = false, startX = current X, startY = current Y, speedUpSlowDown = false ]) if type(endX) ~= 'userdata' then - return { from = speedUpSlowDown and -math.pi/2 or 0, to = speedUpSlowDown and math.pi/2 or 1, + return { from = speedUpSlowDown and -math.pi / 2 or 0, to = speedUpSlowDown and math.pi / 2 or 1, time = time or 1000, repeats = loop and 0 or 1, fn = Animation.presets.guiMove, startX = startX, startY = startY, endX = endX, endY = endY, speedUpSlowDown = speedUpSlowDown } else local elem, value, phase = endX, endY, time if phase.speedUpSlowDown then - value = (value + 1)/2 + value = (value + 1) / 2 end if not phase.startX then phase.startX, phase.startY = guiGetPosition(elem, false) end - guiSetPosition(elem, phase.startX + (phase.endX - phase.startX)*value, phase.startY + (phase.endY - phase.startY)*value, false) + guiSetPosition(elem, phase.startX + (phase.endX - phase.startX) * value, phase.startY + (phase.endY - phase.startY) * value, false) end end @@ -447,20 +445,20 @@ function Animation.presets.guiMoveResize(endX, endY, endWidth, endHeight, time, -- guiMoveResize(endX, endY, endWidth, endHeight, [ time = 1000, loop = false, startX = current X, startY = current Y, -- startWidth = current width, startHeiht = current height, speedUpSlowDown = false ]) if type(endX) ~= 'userdata' then - return { from = speedUpSlowDown and -math.pi/2 or 0, to = speedUpSlowDown and math.pi/2 or 1, + return { from = speedUpSlowDown and -math.pi / 2 or 0, to = speedUpSlowDown and math.pi / 2 or 1, time = time or 1000, repeats = loop and 0 or 1, transform = math.sin, fn = Animation.presets.guiMoveResize, startX = startX, startY = startY, startWidth = startWidth, startHeight = startHeight, endX = endX, endY = endY, endWidth = endWidth, endHeight = endHeight, speedUpSlowDown = speedUpSlowDown } else local elem, value, phase = endX, endY, endWidth if phase.speedUpSlowDown then - value = (value + 1)/2 + value = (value + 1) / 2 end if not phase.startX then phase.startX, phase.startY = guiGetPosition(elem, false) phase.startWidth, phase.startHeight = guiGetSize(elem, false) end - guiSetPosition(elem, math.floor(phase.startX + value*(phase.endX - phase.startX)), math.floor(phase.startY + value*(phase.endY - phase.startY)), false) - guiSetSize(elem, math.floor(phase.startWidth + value*(phase.endWidth - phase.startWidth)), math.floor(phase.startHeight + value*(phase.endHeight - phase.startHeight)), false) + guiSetPosition(elem, math.floor(phase.startX + value * (phase.endX - phase.startX)), math.floor(phase.startY + value * (phase.endY - phase.startY)), false) + guiSetSize(elem, math.floor(phase.startWidth + value * (phase.endWidth - phase.startWidth)), math.floor(phase.startHeight + value * (phase.endHeight - phase.startHeight)), false) end end diff --git a/amx/client/arrowmarkers.lua b/amx/client/arrowmarkers.lua index 03911b9..5383943 100644 --- a/amx/client/arrowmarkers.lua +++ b/amx/client/arrowmarkers.lua @@ -32,7 +32,7 @@ addEventHandler('onClientElementStreamIn', root, else streamedMarkers[source] = { getElementPosition(source) } end - streamedMarkers[source].anim = Animation.createAndPlay(source, { from = 0, to = 2*math.pi, time = 2000, repeats = 0, fn = setMarkerZ }) + streamedMarkers[source].anim = Animation.createAndPlay(source, { from = 0, to = 2 * math.pi, time = 2000, repeats = 0, fn = setMarkerZ }) end ) diff --git a/amx/client/bone_attach_c.lua b/amx/client/bone_attach_c.lua index 3e5e79e..81c04d4 100644 --- a/amx/client/bone_attach_c.lua +++ b/amx/client/bone_attach_c.lua @@ -1,11 +1,11 @@ function sendReadyMessage() - triggerServerEvent("boneAttach_requestAttachmentData",root) + triggerServerEvent('boneAttach_requestAttachmentData', root) end -addEventHandler("onClientResourceStart",resourceRoot,sendReadyMessage) +addEventHandler('onClientResourceStart', resourceRoot, sendReadyMessage) -function getAttachmentData(ped,bone,x,y,z,rx,ry,rz) - for element,att_ped in pairs(ped) do - setElementCollisionsEnabled(element,false) +function getAttachmentData(ped, bone, x, y, z, rx, ry, rz) + for element, att_ped in pairs(ped) do + setElementCollisionsEnabled(element, false) attached_ped[element] = att_ped attached_bone[element] = bone[element] attached_x[element] = x[element] @@ -16,75 +16,75 @@ function getAttachmentData(ped,bone,x,y,z,rx,ry,rz) attached_rz[element] = rz[element] end end -addEvent("boneAttach_sendAttachmentData",true) -addEventHandler("boneAttach_sendAttachmentData",root,getAttachmentData) +addEvent('boneAttach_sendAttachmentData', true) +addEventHandler('boneAttach_sendAttachmentData', root, getAttachmentData) function initAttach() - addEvent("boneAttach_attach",true) - addEvent("boneAttach_detach",true) - addEventHandler("boneAttach_attach",root,attachElementToBone) - addEventHandler("boneAttach_detach",root,detachElementFromBone) + addEvent('boneAttach_attach', true) + addEvent('boneAttach_detach', true) + addEventHandler('boneAttach_attach', root, attachElementToBone) + addEventHandler('boneAttach_detach', root, detachElementFromBone) end -addEventHandler("onClientResourceStart",resourceRoot,initAttach) +addEventHandler('onClientResourceStart', resourceRoot, initAttach) -bone_0,bone_t,bone_f = {},{},{} -bone_0[1],bone_t[1],bone_f[1] = 5,nil,6 --head -bone_0[2],bone_t[2],bone_f[2] = 4,5,8 --neck -bone_0[3],bone_t[3],bone_f[3] = 3,nil,31 --spine -bone_0[4],bone_t[4],bone_f[4] = 1,2,3 --pelvis -bone_0[5],bone_t[5],bone_f[5] = 4,32,5 --left clavicle -bone_0[6],bone_t[6],bone_f[6] = 4,22,5 --right clavicle -bone_0[7],bone_t[7],bone_f[7] = 32,33,34 --left shoulder -bone_0[8],bone_t[8],bone_f[8] = 22,23,24 --right shoulder -bone_0[9],bone_t[9],bone_f[9] = 33,34,32 --left elbow -bone_0[10],bone_t[10],bone_f[10] = 23,24,22 --right elbow -bone_0[11],bone_t[11],bone_f[11] = 34,35,36 --left hand -bone_0[12],bone_t[12],bone_f[12] = 24,25,26 --right hand -bone_0[13],bone_t[13],bone_f[13] = 41,42,43 --left hip -bone_0[14],bone_t[14],bone_f[14] = 51,52,53 --right hip -bone_0[15],bone_t[15],bone_f[15] = 42,43,44 --left knee -bone_0[16],bone_t[16],bone_f[16] = 52,53,54 --right knee -bone_0[17],bone_t[17],bone_f[17] = 43,42,44 --left ankle -bone_0[18],bone_t[18],bone_f[18] = 53,52,54 --right angle -bone_0[19],bone_t[19],bone_f[19] = 44,43,42 --left foot -bone_0[20],bone_t[20],bone_f[20] = 54,53,52 --right foot +bone_0, bone_t, bone_f = {}, {}, {} +bone_0[1], bone_t[1], bone_f[1] = 5, nil, 6 -- head +bone_0[2], bone_t[2], bone_f[2] = 4, 5, 8 -- neck +bone_0[3], bone_t[3], bone_f[3] = 3, nil, 31 -- spine +bone_0[4], bone_t[4], bone_f[4] = 1, 2, 3 -- pelvis +bone_0[5], bone_t[5], bone_f[5] = 4, 32, 5 -- left clavicle +bone_0[6], bone_t[6], bone_f[6] = 4, 22, 5 -- right clavicle +bone_0[7], bone_t[7], bone_f[7] = 32, 33, 34 -- left shoulder +bone_0[8], bone_t[8], bone_f[8] = 22, 23, 24 -- right shoulder +bone_0[9], bone_t[9], bone_f[9] = 33, 34, 32 -- left elbow +bone_0[10], bone_t[10], bone_f[10] = 23, 24, 22 -- right elbow +bone_0[11], bone_t[11], bone_f[11] = 34, 35, 36 -- left hand +bone_0[12], bone_t[12], bone_f[12] = 24, 25, 26 -- right hand +bone_0[13], bone_t[13], bone_f[13] = 41, 42, 43 -- left hip +bone_0[14], bone_t[14], bone_f[14] = 51, 52, 53 -- right hip +bone_0[15], bone_t[15], bone_f[15] = 42, 43, 44 -- left knee +bone_0[16], bone_t[16], bone_f[16] = 52, 53, 54 -- right knee +bone_0[17], bone_t[17], bone_f[17] = 43, 42, 44 -- left ankle +bone_0[18], bone_t[18], bone_f[18] = 53, 52, 54 -- right angle +bone_0[19], bone_t[19], bone_f[19] = 44, 43, 42 -- left foot +bone_0[20], bone_t[20], bone_f[20] = 54, 53, 52 -- right foot function putAttachedElementsOnBones() - for element,ped in pairs(attached_ped) do + for element, ped in pairs(attached_ped) do if not isElement(element) then clearAttachmentData(element) elseif isElementStreamedIn(ped) then local bone = attached_bone[element] - local x,y,z = getPedBonePosition(ped,bone_0[bone]) - local xx,xy,xz,yx,yy,yz,zx,zy,zz = getBoneMatrix(ped,bone) - local offx,offy,offz = attached_x[element],attached_y[element],attached_z[element] - local offrx,offry,offrz = attached_rx[element],attached_ry[element],attached_rz[element] - local objx = x+offx*xx+offy*yx+offz*zx - local objy = y+offx*xy+offy*yy+offz*zy - local objz = z+offx*xz+offy*yz+offz*zz - local rxx,rxy,rxz,ryx,ryy,ryz,rzx,rzy,rzz = getMatrixFromEulerAngles(offrx,offry,offrz) + local x, y, z = getPedBonePosition(ped, bone_0[bone]) + local xx, xy, xz, yx, yy, yz, zx, zy, zz = getBoneMatrix(ped,bone) + local offx, offy, offz = attached_x[element], attached_y[element], attached_z[element] + local offrx, offry, offrz = attached_rx[element], attached_ry[element], attached_rz[element] + local objx = x + offx * xx + offy * yx + offz * zx + local objy = y + offx * xy + offy * yy + offz * zy + local objz = z + offx * xz + offy * yz + offz * zz + local rxx, rxy, rxz, ryx, ryy, ryz, rzx, rzy, rzz = getMatrixFromEulerAngles(offrx, offry, offrz) - local txx = rxx*xx+rxy*yx+rxz*zx - local txy = rxx*xy+rxy*yy+rxz*zy - local txz = rxx*xz+rxy*yz+rxz*zz - local tyx = ryx*xx+ryy*yx+ryz*zx - local tyy = ryx*xy+ryy*yy+ryz*zy - local tyz = ryx*xz+ryy*yz+ryz*zz - local tzx = rzx*xx+rzy*yx+rzz*zx - local tzy = rzx*xy+rzy*yy+rzz*zy - local tzz = rzx*xz+rzy*yz+rzz*zz - offrx,offry,offrz = getEulerAnglesFromMatrix(txx,txy,txz,tyx,tyy,tyz,tzx,tzy,tzz) - if (string.find(objx..objy..objz, "a")) then - setElementPosition(element, x, y, z) + local txx = rxx * xx + rxy * yx + rxz * zx + local txy = rxx * xy + rxy * yy + rxz * zy + local txz = rxx * xz + rxy * yz + rxz * zz + local tyx = ryx * xx + ryy * yx + ryz * zx + local tyy = ryx * xy + ryy * yy + ryz * zy + local tyz = ryx * xz + ryy * yz + ryz * zz + local tzx = rzx * xx + rzy * yx + rzz * zx + local tzy = rzx * xy + rzy * yy + rzz * zy + local tzz = rzx * xz + rzy * yz + rzz * zz + offrx, offry, offrz = getEulerAnglesFromMatrix(txx, txy, txz, tyx, tyy, tyz, tzx, tzy, tzz) + if (string.find(objx .. objy .. objz, 'a')) then + setElementPosition(element, x, y, z) else - setElementPosition(element, objx, objy, objz) + setElementPosition(element, objx, objy, objz) end - if (not string.find(offrx..offry..offrz, "a")) then - setElementRotation(element, offrx, offry, offrz, "ZXY") - else - setElementPosition(element,getElementPosition(ped)) + if (not string.find(offrx .. offry .. offrz, 'a')) then + setElementRotation(element, offrx, offry, offrz, 'ZXY') + else + setElementPosition(element, getElementPosition(ped)) end end end end -addEventHandler("onClientPreRender",root,putAttachedElementsOnBones) \ No newline at end of file +addEventHandler('onClientPreRender', root, putAttachedElementsOnBones) \ No newline at end of file diff --git a/amx/client/bone_pos_rot.lua b/amx/client/bone_pos_rot.lua index deb90fe..8e32395 100644 --- a/amx/client/bone_pos_rot.lua +++ b/amx/client/bone_pos_rot.lua @@ -1,66 +1,66 @@ -sx,sy,sz = 0,0,3 -tx,ty,tz = 0,0,4 -fx,fy,fz = 0,1,3 +sx, sy, sz = 0, 0, 3 +tx, ty, tz = 0, 0, 4 +fx, fy, fz = 0, 1, 3 -function getMatrixFromPoints(x,y,z,x3,y3,z3,x2,y2,z2) - x3 = x3-x - y3 = y3-y - z3 = z3-z - x2 = x2-x - y2 = y2-y - z2 = z2-z - local x1 = y2*z3-z2*y3 - local y1 = z2*x3-x2*z3 - local z1 = x2*y3-y2*x3 - x2 = y3*z1-z3*y1 - y2 = z3*x1-x3*z1 - z2 = x3*y1-y3*x1 - local len1 = 1/math.sqrt(x1*x1+y1*y1+z1*z1) - local len2 = 1/math.sqrt(x2*x2+y2*y2+z2*z2) - local len3 = 1/math.sqrt(x3*x3+y3*y3+z3*z3) - x1 = x1*len1 y1 = y1*len1 z1 = z1*len1 - x2 = x2*len2 y2 = y2*len2 z2 = z2*len2 - x3 = x3*len3 y3 = y3*len3 z3 = z3*len3 - return x1,y1,z1,x2,y2,z2,x3,y3,z3 +function getMatrixFromPoints(x, y, z, x3, y3, z3, x2, y2, z2) + x3 = x3 - x + y3 = y3 - y + z3 = z3 - z + x2 = x2 - x + y2 = y2 - y + z2 = z2 - z + local x1 = y2 * z3 - z2 * y3 + local y1 = z2 * x3 - x2 * z3 + local z1 = x2 * y3 - y2 * x3 + x2 = y3 * z1 - z3 * y1 + y2 = z3 * x1 - x3 * z1 + z2 = x3 * y1 - y3 * x1 + local len1 = 1 / math.sqrt(x1 * x1 + y1 * y1 + z1 * z1) + local len2 = 1 / math.sqrt(x2 * x2 + y2 * y2 + z2 * z2) + local len3 = 1 / math.sqrt(x3 * x3 + y3 * y3 + z3 * z3) + x1 = x1 * len1 y1 = y1 * len1 z1 = z1 * len1 + x2 = x2 * len2 y2 = y2 * len2 z2 = z2 * len2 + x3 = x3 * len3 y3 = y3 * len3 z3 = z3 * len3 + return x1, y1, z1, x2, y2, z2, x3, y3, z3 end -function getEulerAnglesFromMatrix(x1,y1,z1,x2,y2,z2,x3,y3,z3) - local nz1,nz2,nz3 - nz3 = math.sqrt(x2*x2+y2*y2) - nz1 = -x2*z2/nz3 - nz2 = -y2*z2/nz3 - local vx = nz1*x1+nz2*y1+nz3*z1 - local vz = nz1*x3+nz2*y3+nz3*z3 - return math.deg(math.asin(z2)),-math.deg(math.atan2(vx,vz)),-math.deg(math.atan2(x2,y2)) +function getEulerAnglesFromMatrix(x1, y1, z1, x2, y2, z2, x3, y3, z3) + local nz1, nz2, nz3 + nz3 = math.sqrt(x2 * x2 + y2 * y2) + nz1 = -x2 * z2 / nz3 + nz2 = -y2 * z2 / nz3 + local vx = nz1 * x1 + nz2 * y1 + nz3 * z1 + local vz = nz1 * x3 + nz2 * y3 + nz3 * z3 + return math.deg(math.asin(z2)), -math.deg(math.atan2(vx, vz)), -math.deg(math.atan2(x2, y2)) end -function getMatrixFromEulerAngles(x,y,z) - x,y,z = math.rad(x),math.rad(y),math.rad(z) - local sinx,cosx,siny,cosy,sinz,cosz = math.sin(x),math.cos(x),math.sin(y),math.cos(y),math.sin(z),math.cos(z) +function getMatrixFromEulerAngles(x, y, z) + x, y, z = math.rad(x), math.rad(y), math.rad(z) + local sinx, cosx, siny, cosy, sinz, cosz = math.sin(x), math.cos(x), math.sin(y), math.cos(y), math.sin(z), math.cos(z) return - cosy*cosz-siny*sinx*sinz,cosy*sinz+siny*sinx*cosz,-siny*cosx, - -cosx*sinz,cosx*cosz,sinx, - siny*cosz+cosy*sinx*sinz,siny*sinz-cosy*sinx*cosz,cosy*cosx + cosy * cosz - siny * sinx * sinz, cosy * sinz + siny * sinx * cosz, -siny * cosx, + -cosx * sinz, cosx * cosz, sinx, + siny * cosz + cosy * sinx * sinz, siny * sinz - cosy * sinx * cosz, cosy * cosx end if not script_serverside then - function getBoneMatrix(ped,bone) - local x,y,z,tx,ty,tz,fx,fy,fz - x,y,z = getPedBonePosition(ped,bone_0[bone]) + function getBoneMatrix(ped, bone) + local x, y, z, tx, ty, tz, fx, fy, fz + x, y, z = getPedBonePosition(ped, bone_0[bone]) if bone == 1 then - local x6,y6,z6 = getPedBonePosition(ped,6) - local x7,y7,z7 = getPedBonePosition(ped,7) - tx,ty,tz = (x6+x7)*0.5,(y6+y7)*0.5,(z6+z7)*0.5 + local x6, y6, z6 = getPedBonePosition(ped, 6) + local x7, y7, z7 = getPedBonePosition(ped, 7) + tx, ty, tz = (x6 + x7) * 0.5, (y6 + y7) * 0.5, (z6 + z7) * 0.5 elseif bone == 3 then - local x21,y21,z21 = getPedBonePosition(ped,21) - local x31,y31,z31 = getPedBonePosition(ped,31) - tx,ty,tz = (x21+x31)*0.5,(y21+y31)*0.5,(z21+z31)*0.5 + local x21, y21, z21 = getPedBonePosition(ped, 21) + local x31, y31, z31 = getPedBonePosition(ped, 31) + tx, ty, tz = (x21 + x31) * 0.5, (y21 + y31) * 0.5, (z21 + z31) * 0.5 else - tx,ty,tz = getPedBonePosition(ped,bone_t[bone]) + tx, ty, tz = getPedBonePosition(ped, bone_t[bone]) end - fx,fy,fz = getPedBonePosition(ped,bone_f[bone]) - local xx,xy,xz,yx,yy,yz,zx,zy,zz = getMatrixFromPoints(x,y,z,tx,ty,tz,fx,fy,fz) - if bone == 1 or bone == 3 then xx,xy,xz,yx,yy,yz = -yx,-yy,-yz,xx,xy,xz end - return xx,xy,xz,yx,yy,yz,zx,zy,zz + fx, fy, fz = getPedBonePosition(ped, bone_f[bone]) + local xx, xy, xz, yx, yy, yz, zx, zy, zz = getMatrixFromPoints(x, y, z, tx, ty, tz, fx, fy, fz) + if bone == 1 or bone == 3 then xx, xy, xz, yx, yy, yz = -yx, -yy, -yz, xx, xy, xz end + return xx, xy, xz, yx, yy, yz, zx, zy, zz end end \ No newline at end of file diff --git a/amx/client/client.lua b/amx/client/client.lua index 8f9c190..f14c99e 100644 --- a/amx/client/client.lua +++ b/amx/client/client.lua @@ -1,11 +1,11 @@ local dxDrawText = dxDrawText local tocolor = tocolor -local SPEED_EPSILON = 0.005 + local VEHICLE_DROP_TRY_INTERVAL = 100 local VEHICLE_DROP_MAX_TRIES = 50 local MENU_ITEM_HEIGHT = 25 -local MENU_TOP_PADDING = MENU_ITEM_HEIGHT*2 +local MENU_TOP_PADDING = MENU_ITEM_HEIGHT * 2 local MENU_BOTTOM_PADDING = 10 local MENU_SIDE_PADDING = 20 @@ -45,6 +45,7 @@ addEventHandler('onClientResourceStart', resourceRoot, function() triggerServerEvent('onLoadedAtClient', resourceRoot, localPlayer) setTimer(checkTextLabels, 500, 0) + setAmbientSoundEnabled('gunfire', false) setDebugViewActive(true) end, false @@ -61,7 +62,7 @@ function enableDebug() local state = not isDebugViewActive() setDebugViewActive(state) end -addCommandHandler("debug", enableDebug) +addCommandHandler('debug', enableDebug) function setAMXVersion(ver) g_AMXVersion = ver @@ -115,11 +116,6 @@ function setPlayerID(id) g_PlayerID = id end ----------------------------- --- MTA Key Handling -function HandleMTAKey( key, keyState ) - outputServerLog("handlemtakey: " .. key) -end ------------------------------ -- Class selection screen function startClassSelection(classInfo) @@ -134,7 +130,7 @@ function startClassSelection(classInfo) setWeather(g_StartWeather) g_StartWeather = nil end - setGravity(0) + setElementCollisionsEnabled(localPlayer, false) -- interaction @@ -144,26 +140,26 @@ function startClassSelection(classInfo) end g_ClassSelectionInfo.gui = { img = guiCreateStaticImage(35, screenHeight - 410, 205, 236, 'client/logo_small.png', false), - btnLeft = guiCreateButton(screenWidth/2-145-70,screenHeight-100,140,20,"<<<",false), - btnRight = guiCreateButton(screenWidth/2-70,screenHeight-100,140,20,">>>",false), - btnSpawn = guiCreateButton(screenWidth/2+145-70,screenHeight-100,140,20,"Spawn",false) + btnLeft = guiCreateButton(screenWidth / 2 - 145 - 70, screenHeight - 100, 140, 20, '<<<', false), + btnRight = guiCreateButton(screenWidth / 2 - 70, screenHeight - 100, 140, 20, '>>>', false), + btnSpawn = guiCreateButton(screenWidth / 2 + 145 - 70, screenHeight - 100, 140, 20, 'Spawn', false) } - addEventHandler ( "onClientGUIClick", g_ClassSelectionInfo.gui.btnLeft, ClassSelLeft ) - addEventHandler ( "onClientGUIClick", g_ClassSelectionInfo.gui.btnRight, ClassSelRight ) - addEventHandler ( "onClientGUIClick", g_ClassSelectionInfo.gui.btnSpawn, ClassSelSpawn ) + addEventHandler('onClientGUIClick', g_ClassSelectionInfo.gui.btnLeft, ClassSelLeft) + addEventHandler('onClientGUIClick', g_ClassSelectionInfo.gui.btnRight, ClassSelRight) + addEventHandler('onClientGUIClick', g_ClassSelectionInfo.gui.btnSpawn, ClassSelSpawn) showCursor(true) addEventHandler('onClientRender', root, renderClassSelText) end -function ClassSelLeft () +function ClassSelLeft() server.requestClass(localPlayer, false, false, -1) end -function ClassSelRight () +function ClassSelRight() server.requestClass(localPlayer, false, false, 1) end -function ClassSelSpawn () +function ClassSelSpawn() server.requestSpawn(localPlayer, false, false) end @@ -178,7 +174,7 @@ function renderClassSelText() drawShadowText('Class ' .. g_ClassSelectionInfo.selectedclass .. ' weapons:', 20, screenHeight - 110, tocolor(240, 240, 240)) local weapon, ammo, linenum, line linenum = 0 - for i,weapondata in ipairs(g_ClassSelectionInfo[g_ClassSelectionInfo.selectedclass].weapons) do + for i, weapondata in ipairs(g_ClassSelectionInfo[g_ClassSelectionInfo.selectedclass].weapons) do weapon, ammo = weapondata[1], weapondata[2] if weapon ~= 0 and weapon ~= -1 and ammo ~= -1 then linenum = linenum + 1 @@ -188,7 +184,7 @@ function renderClassSelText() line = '' end line = line .. (getWeaponNameFromID(weapon) or weapon) - drawShadowText(line, 25, screenHeight - 110 + 14*linenum, tocolor(240, 240, 240)) + drawShadowText(line, 25, screenHeight - 110 + 14 * linenum, tocolor(240, 240, 240)) end end end @@ -200,7 +196,7 @@ end function destroyClassSelGUI() if g_ClassSelectionInfo and g_ClassSelectionInfo.gui then - for i,elem in pairs(g_ClassSelectionInfo.gui) do + for i, elem in pairs(g_ClassSelectionInfo.gui) do destroyElement(elem) end g_ClassSelectionInfo.gui = nil @@ -208,13 +204,12 @@ function destroyClassSelGUI() end setPlayerHudComponentVisible('radar', true) setCameraTarget(localPlayer) - setGravity(0.008) setElementCollisionsEnabled(localPlayer, true) showCursor(false) if g_ClassSelectionInfo and g_ClassSelectionInfo.gui then - removeEventHandler ( "onClientGUIClick", g_ClassSelectionInfo.gui.btnLeft, ClassSelLeft ) - removeEventHandler ( "onClientGUIClick", g_ClassSelectionInfo.gui.btnRight, ClassSelRight ) - removeEventHandler ( "onClientGUIClick", g_ClassSelectionInfo.gui.btnSpawn, ClassSelSpawn ) + removeEventHandler('onClientGUIClick', g_ClassSelectionInfo.gui.btnLeft, ClassSelLeft) + removeEventHandler('onClientGUIClick', g_ClassSelectionInfo.gui.btnRight, ClassSelRight) + removeEventHandler('onClientGUIClick', g_ClassSelectionInfo.gui.btnSpawn, ClassSelSpawn) end end @@ -229,15 +224,6 @@ addEventHandler('onClientResourceStop', resourceRoot, function requestSpawn() triggerServerEvent('onRequestSpawn', localPlayer, g_ClassSelectionInfo.selectedclass) end - -addEventHandler('onClientPlayerWeaponFire', resourceRoot, - function(weapon, ammo, ammoInClip, hitX, hitY, hitZ) - --if localPlayer ~= source then return end - serverAMXEvent('OnPlayerShoot', getElemID(source), weapon, ammo, ammoInClip, hitX, hitY, hitZ) - end, - false -) - ----------------------------- -- Camera @@ -276,10 +262,11 @@ function showIntroScene() end ----------------------------- -- Pickup related -function pickupOnInteriorChangeLoop() + +function pickupOnInteriorChangeLoop() local vw = getElementDimension(localPlayer) local interior = getElementInterior(localPlayer) - for i, v in ipairs(getElementsByType("pickup", root)) do --Only for those that are streamed in + for i, v in ipairs(getElementsByType('pickup', root)) do -- Only for those that are streamed in if isElement(v) then setElementInterior(v, interior) setElementDimension(v, vw) @@ -288,41 +275,43 @@ function pickupOnInteriorChangeLoop() end local function clientPlayerPickupHit(thePickup, matchingDimension) - triggerServerEvent('OnPlayerPickUpPickup_Ev', resourceRoot, thePickup) + if source ~= localPlayer then return end + triggerServerEvent('OnPlayerPickUpPickup_Ev', localPlayer, thePickup) end -addEventHandler("onClientPlayerPickupHit", root, clientPlayerPickupHit) +addEventHandler('onClientPlayerPickupHit', root, clientPlayerPickupHit) ----------------------------- -- Interior related + local interiorTimerPtr = false function AMX_OnPlayerInteriorChange(interior, oldInt) if not interiorTimerPtr then - interiorTimerPtr = setTimer ( pickupOnInteriorChangeLoop, 1000, 0 ) --Every second check for pickups + interiorTimerPtr = setTimer(pickupOnInteriorChangeLoop, 1000, 0) -- Every second check for pickups end end - ----------------------------- -- Camera related + function removeCamHandlers() removeInterpCamHandler() removeCamAttachHandler() end -- Camera attachments ---Based on https://forum.mtasa.com/topic/36692-move-camera-by-mouse-like-normal/?do=findComment&comment=368670 +-- Based on https://forum.multitheftauto.com/topic/36692-move-camera-by-mouse-like-normal/#comment-368670 local ca = {} ca.active = 0 ca.objCamPos = nil ca.dist = 0.025 -ca.speed = 5 -ca.x = math.rad(60) -ca.y = math.rad(60) -ca.z = math.rad(15) -ca.maxZ = math.rad(89) -ca.minZ = math.rad(-45) +ca.speed = 5 +ca.x = math.rad(60) +ca.y = math.rad(60) +ca.z = math.rad(15) +ca.maxZ = math.rad(89) +ca.minZ = math.rad(-45) function removeCamAttachHandler() outputConsole('removeCamAttachHandler was called') - if(ca.active == 1) then + if (ca.active == 1) then outputConsole('Destroying cam attach handler...') ca.active = 0 end @@ -330,146 +319,182 @@ end function camAttachRender() if (ca.active == 1) then - local x1,y1,z1 = 0.0, 0.0, 0.0 + if isCursorShowing() then return end + + local x1, y1, z1 = 0.0, 0.0, 0.0 if ca.objCamPos ~= nil then - x1,y1,z1 = getElementPosition(ca.objCamPos) + x1, y1, z1 = getElementPosition(ca.objCamPos) if not x1 then x1 = 0.0 end if not y1 then y1 = 0.0 end if not z1 then z1 = 0.0 end end - local camDist = ca.dist - local cosZ = math.cos(ca.z) - local camX = x1 + math.cos(ca.x)*camDist*cosZ - local camY = y1 + math.sin(ca.y)*camDist*cosZ - local camZ = z1 + math.sin(ca.z)*camDist - setCameraMatrix(camX, camY, camZ, x1, y1, z1) - - --If aiming, set the target (does nothing, todo fix) - if getPedTask(localPlayer, "secondary", 0) == "TASK_SIMPLE_USE_GUN" or isPedDoingGangDriveby(localPlayer) then - setPedAimTarget ( localPlayer, camX, camY, camZ ) - setPlayerHudComponentVisible ( localPlayer, "crosshair", true ) + local camDist = ca.dist + local cosZ = math.cos(ca.z) + local camX = x1 + math.cos(ca.x) * camDist * cosZ + local camY = y1 + math.sin(ca.y) * camDist * cosZ + local camZ = z1 + math.sin(ca.z) * camDist + setCameraMatrix(camX, camY, camZ, x1, y1, z1) + + -- If aiming, set the target (does nothing, todo fix) + if getPedTask(localPlayer, 'secondary', 0) == 'TASK_SIMPLE_USE_GUN' or isPedDoingGangDriveby(localPlayer) then + setPedAimTarget(localPlayer, camX, camY, camZ) + setPlayerHudComponentVisible(localPlayer, 'crosshair', true) outputConsole('ped is aiming') end - - --outputConsole(string.format("camAttachRender - Camera Matrix is: CamPos: %f %f %f CamLookAt: %f %f %f", camX, camY, camZ, x1,y1,z1)) + + --outputConsole(string.format("camAttachRender - Camera Matrix is: CamPos: %f %f %f CamLookAt: %f %f %f", camX, camY, camZ, x1, y1, z1)) else - removeEventHandler("onClientPreRender", root, camAttachRender) + removeEventHandler('onClientPreRender', root, camAttachRender) end end function cursorMouseMoveHandler(curX, curY, absX, absY) if (ca.active == 1) then - local diffX = curX - 0.5 - local diffY = curY - 0.5 - local camX = ca.x - diffX*ca.speed - local camY = ca.y - diffX*ca.speed - local camZ = ca.z + (diffY*ca.speed)/math.pi - if(camZ > ca.maxZ) then - camZ = ca.maxZ - end - if(camZ < ca.minZ) then - camZ = ca.minZ - end - ca.x = camX - ca.y = camY - ca.z = camZ + if isCursorShowing() then return end + + local diffX = curX - 0.5 + local diffY = curY - 0.5 + local camX = ca.x - diffX * ca.speed + local camY = ca.y - diffX * ca.speed + local camZ = ca.z + (diffY * ca.speed) / math.pi + if (camZ > ca.maxZ) then + camZ = ca.maxZ + end + if (camZ < ca.minZ) then + camZ = ca.minZ + end + ca.x = camX + ca.y = camY + ca.z = camZ else - removeEventHandler("onClientCursorMove", root, cursorMouseMoveHandler) + removeEventHandler('onClientCursorMove', root, cursorMouseMoveHandler) end end function AttachCameraToObject(camObj) outputConsole('AttachCameraToObject was called') + + if not isElement(camObj) then + return + end + ca.active = 1 ca.objCamPos = camObj - addEventHandler("onClientPreRender", root, camAttachRender) - addEventHandler("onClientCursorMove", root, cursorMouseMoveHandler) + + addEventHandler('onClientPreRender', root, camAttachRender) + addEventHandler('onClientCursorMove', root, cursorMouseMoveHandler) +end + +function AttachCameraToPlayerObject(camobjID) + outputConsole('AttachCameraToPlayerObject was called') + + if not isElement(g_PlayerObjects[camobjID]) then + return + end + + ca.active = 1 + ca.objCamPos = g_PlayerObjects[camobjID] + + addEventHandler('onClientPreRender', root, camAttachRender) + addEventHandler('onClientCursorMove', root, cursorMouseMoveHandler) end -- Camera Interpolation ---Originally from https://wiki.multitheftauto.com/wiki/SmoothMoveCamera +-- Originally from https://wiki.multitheftauto.com/wiki/SmoothMoveCamera local sm = {} sm.moov = 0 -sm.objCamPos,sm.objLookAt = nil,nil - +sm.objCamPos, sm.objLookAt = nil, nil + function removeInterpCamHandler() outputConsole('removeInterpCamHandler was called') - if(sm.moov == 1) then + if (sm.moov == 1) then outputConsole('Destroying cam handler...') sm.moov = 0 end end - + function camRender() if (sm.moov == 1) then - local x1,y1,z1,x2,y2,z2 = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 + local x1, y1, z1, x2, y2, z2 = 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 if sm.objCamPos ~= nil then - x1,y1,z1 = getElementPosition(sm.objCamPos) + x1, y1, z1 = getElementPosition(sm.objCamPos) if not x1 then x1 = 0.0 end if not y1 then y1 = 0.0 end if not z1 then z1 = 0.0 end end if sm.objLookAt ~= nil then - x2,y2,z2 = getElementPosition(sm.objLookAt) + x2, y2, z2 = getElementPosition(sm.objLookAt) if not x2 then x2 = 0.0 end if not y2 then y2 = 0.0 end if not z2 then z2 = 0.0 end end - --outputConsole(string.format("Current Camera Matrix is: CamPos: %f %f %f CamLookAt: %f %f %f", x1,y1,z1,x2,y2,z2)) - setCameraMatrix(x1,y1,z1,x2,y2,z2) + --outputConsole(string.format("Current Camera Matrix is: CamPos: %f %f %f CamLookAt: %f %f %f", x1, y1, z1, x2, y2, z2)) + setCameraMatrix(x1, y1, z1, x2, y2, z2) else - removeEventHandler("onClientPreRender", root, camRender) + removeEventHandler('onClientPreRender', root, camRender) end end -function setupCameraObject(camObj, FromX, FromY, FromZ, ToX, ToY, ToZ, time, cut) +function setupCameraObject(FromX, FromY, FromZ, ToX, ToY, ToZ, time, cut) sm.moov = 1 - camObj = createObject(1337, FromX, FromY, FromZ) - setElementCollisionsEnabled (camObj, false) + local camObj = createObject(1337, FromX, FromY, FromZ) + setElementCollisionsEnabled(camObj, false) setElementAlpha(camObj, 0) setObjectScale(camObj, 0.01) - moveObject(camObj, time, ToX, ToY, ToZ, ToX, ToY, ToZ, "InOutQuad") - setTimer(removeInterpCamHandler,time,1) - setTimer(destroyElement,time,1,camObj) + moveObject(camObj, time, ToX, ToY, ToZ, ToX, ToY, ToZ, 'InOutQuad') + setTimer(removeInterpCamHandler, time, 1) + setTimer(destroyElement, time, 1, camObj) return camObj end function InterpolateCameraPos(FromX, FromY, FromZ, ToX, ToY, ToZ, time, cut) outputConsole(string.format("InterpolateCameraPos called with args %f %f %f %f %f %f %d %d", FromX, FromY, FromZ, ToX, ToY, ToZ, time, cut)) - sm.objCamPos = setupCameraObject(sm.objCamPos, FromX, FromY, FromZ, ToX, ToY, ToZ, time, cut) - addEventHandler("onClientPreRender", root, camRender) - return true + sm.objCamPos = setupCameraObject(FromX, FromY, FromZ, ToX, ToY, ToZ, time, cut) + addEventHandler('onClientPreRender', root, camRender) end + function InterpolateCameraLookAt(FromX, FromY, FromZ, ToX, ToY, ToZ, time, cut) outputConsole(string.format("InterpolateCameraLookAt called with args %f %f %f %f %f %f %d %d", FromX, FromY, FromZ, ToX, ToY, ToZ, time, cut)) - sm.objLookAt = setupCameraObject(sm.objLookAt, FromX, FromY, FromZ, ToX, ToY, ToZ, time, cut) - addEventHandler("onClientPreRender", root, camRender) - return true + sm.objLookAt = setupCameraObject(FromX, FromY, FromZ, ToX, ToY, ToZ, time, cut) + addEventHandler('onClientPreRender', root, camRender) end ----------------------------- -- Player objects + function RemoveBuildingForPlayer(model, x, y, z, radius) if model == -1 then - for i=550,20000 do --Remove all world models around radius if they sent -1 + for i = 550, 20000 do -- Remove all world models around radius if they sent -1 removeWorldModel(i, radius, x, y, z) end - return true --Don't run the rest of the code + return -- Don't run the rest of the code end removeWorldModel(model, radius, x, y, z) - return true + return end function AttachPlayerObjectToPlayer(objID, attachPlayer, offsetX, offsetY, offsetZ, rX, rY, rZ) local obj = g_PlayerObjects[objID] if not obj then - return false + return end attachElements(obj, attachPlayer, offsetX, offsetY, offsetZ, rX, rY, rZ) - return true +end + +function AttachPlayerObjectToVehicle(objID, attachVehicle, offsetX, offsetY, offsetZ, rX, rY, rZ) + local obj = g_PlayerObjects[objID] + if not obj then + return + end + attachElements(obj, attachVehicle, offsetX, offsetY, offsetZ, rX, rY, rZ) end function CreatePlayerObject(objID, model, x, y, z, rX, rY, rZ) g_PlayerObjects[objID] = createObject(model, x, y, z, rX, rY, rZ) + if g_PlayerObjects[objID] == false then + g_PlayerObjects[objID] = createObject(1337, x, y, z, rX, rY, rZ) -- Create a dummy object anyway since createobject can also be used to make camera attachments + setElementAlpha(g_PlayerObjects[objID], 0) + setElementCollisionsEnabled(g_PlayerObjects[objID], false) + end end function DestroyPlayerObject(objID) @@ -481,51 +506,60 @@ function DestroyPlayerObject(objID) g_PlayerObjects[objID] = nil end -function MovePlayerObject(objID, x, y, z, speed) +function MovePlayerObject(objID, x, y, z, speed, rX, rY, rZ) local obj = g_PlayerObjects[objID] - local rX, rY, rZ = getElementRotation(obj) local distance = getDistanceBetweenPoints3D(x, y, z, getElementPosition(obj)) - local time = distance/speed*1000 - moveObject(obj, time, x, y, z) - setElementRotation(obj, rX, rY, rZ) + local time = distance / speed * 1000 + + -- We need relative rotation + local cRotX, cRotY, cRotZ = getElementRotation(obj) + cRotX = cRotX - rX + cRotY = cRotY - rY + cRotZ = cRotZ - rZ + + -- -1000 or less means no rotation change, so set it to 0.0 + if rX <= -1000.0 then cRotX = 0.0 end + if rY <= -1000.0 then cRotY = 0.0 end + if rZ <= -1000.0 then cRotZ = 0.0 end + + moveObject(obj, time, x, y, z, cRotX, cRotY, cRotZ) + return math.floor(time) end function SetPlayerObjectPos(objID, x, y, z) local obj = g_PlayerObjects[objID] if not obj then - return false + return end setElementPosition(obj, x, y, z) - return true end function SetPlayerObjectRot(objID, rX, rY, rZ) local obj = g_PlayerObjects[objID] if not obj then - return false + return end setElementRotation(obj, rX, rY, rZ) - return true end function StopPlayerObject(objID) local obj = g_PlayerObjects[objID] if not obj then - return false + return end stopObject(obj) - return true end +----------------------------- +-- Audio ---- Audio -local pAudioStreamSound = nil --samp can only do one stream at a time anyway +local pAudioStreamSound = nil -- SA-MP can only do one stream at a time anyway function PlayAudioStreamForPlayer(url, posX, posY, posZ, distance, usepos) --outputConsole(string.format("PlayAudioStreamForPlayer called with args %s %f %f %f %f %d", url, posX, posY, posZ, distance, usepos)) - if pAudioStreamSound ~= nil then --If there's one already playing, stop it + if pAudioStreamSound ~= nil then -- If there's one already playing, stop it --outputConsole("PlayAudioStreamForPlayer is stopping an audio stream") StopAudioStreamForPlayer() end - if usepos == nil or usepos == 0 then + if not usepos then --outputConsole(string.format("PlayAudioStreamForPlayer now playing non-3d sound %s", url)) pAudioStreamSound = playSound(url) else @@ -536,10 +570,11 @@ function PlayAudioStreamForPlayer(url, posX, posY, posZ, distance, usepos) if pAudioStreamSound ~= nil then setSoundVolume(pAudioStreamSound, 1.0) end - return true end + function StopAudioStreamForPlayer() - stopSound(pAudioStreamSound) + if pAudioStreamSound == nil then return end + stopSound(pAudioStreamSound) end ----------------------------- -- Checkpoints @@ -564,7 +599,7 @@ function DisablePlayerCheckpoint() end removeEventHandler('onClientColShapeHit', g_PlayerCheckpoint.colshape, OnPlayerEnterCheckpoint) removeEventHandler('onClientColShapeLeave', g_PlayerCheckpoint.colshape, OnPlayerLeaveCheckpoint) - for k,elem in pairs(g_PlayerCheckpoint) do + for k, elem in pairs(g_PlayerCheckpoint) do destroyElement(elem) end g_PlayerCheckpoint = nil @@ -605,7 +640,7 @@ function DisablePlayerRaceCheckpoint() end removeEventHandler('onClientColShapeHit', g_PlayerRaceCheckpoint.colshape, OnPlayerEnterRaceCheckpoint) removeEventHandler('onClientColShapeLeave', g_PlayerRaceCheckpoint.colshape, OnPlayerLeaveRaceCheckpoint) - for k,elem in pairs(g_PlayerRaceCheckpoint) do + for k, elem in pairs(g_PlayerRaceCheckpoint) do destroyElement(elem) end g_PlayerRaceCheckpoint = nil @@ -617,7 +652,7 @@ function SetPlayerRaceCheckpoint(type, x, y, z, nextX, nextY, nextZ, size) end g_PlayerRaceCheckpoint = { marker = createMarker(x, y, z, type < 2 and 'checkpoint' or 'ring', size, 255, 0, 0), - colshape = type < 2 and createColCircle(x, y, size) or createColSphere(x, y, z, size*1.5), + colshape = type < 2 and createColCircle(x, y, size) or createColSphere(x, y, z, size * 1.5), blip = createBlip(x, y, z, 0, 2, 255, 0, 0), nextblip = createBlip(nextX, nextY, nextZ, 0, 1, 255, 0, 0) } @@ -631,16 +666,9 @@ function SetPlayerRaceCheckpoint(type, x, y, z, nextX, nextY, nextZ, size) addEventHandler('onClientColShapeHit', g_PlayerRaceCheckpoint.colshape, OnPlayerEnterRaceCheckpoint) addEventHandler('onClientColShapeLeave', g_PlayerRaceCheckpoint.colshape, OnPlayerLeaveRaceCheckpoint) end - - ----------------------------- -- Vehicles -function SetPlayerPosFindZ(x, y, z) - setElementPosition(localPlayer, x, y, getGroundPosition(x, y, z) + 1) - return true -end - function SetVehicleParamsForPlayer(vehicle, isObjective, doorsLocked) local vehID = getElemID(vehicle) if not vehID then @@ -667,7 +695,6 @@ function SetVehicleParamsForPlayer(vehicle, isObjective, doorsLocked) setVehicleLocked(vehicle, doorsLocked) end - local vehicleDrops = {} -- { [vehicle] = { timer = timer, tries = tries } } function dropVehicle(vehicle) @@ -687,7 +714,7 @@ function dropVehicle(vehicle) return end - local left, back, bottom, right, front, top = getElementBoundingBox(vehicle) + local _, _, bottom, _, _, top = getElementBoundingBox(vehicle) if not bottom then top = getElementDistanceFromCentreOfMassToBaseOfModel(vehicle) if not top then @@ -696,14 +723,15 @@ function dropVehicle(vehicle) bottom = -top end local x, y, z = getElementPosition(vehicle) - local rx, ry, rz = getElementRotation(vehicle) - local hit, hitX, hitY, hitZ = processLineOfSight(x, y, z + top, x, y, z - 10, true, false) + local _, _, _, hitZ = processLineOfSight(x, y, z + top, x, y, z - 10, true, false) + hitZ = hitZ or getGroundPosition(x, y, z + top) if hitZ then setElementCollisionsEnabled(vehicle, true) if z < hitZ - bottom - 0.5 or top > 2 then - setElementPosition(vehicle, x, y, hitZ + 2*math.abs(bottom)) - setElementRotation(vehicle, 0, ry, rz) + local _, _, rz = getElementRotation(vehicle) + setElementPosition(vehicle, x, y, hitZ + 2 * math.abs(bottom)) + setElementRotation(vehicle, 0, 0, rz) setElementVelocity(vehicle, 0, 0, -0.05) end if dropdata.tries < VEHICLE_DROP_MAX_TRIES then @@ -734,7 +762,7 @@ addEventHandler('onClientElementStreamIn', root, triggerServerEvent('onAmxClientVehicleStream', localPlayer, getElemID(source), true) elseif getElementType(source) == 'player' then triggerServerEvent('onAmxClientPlayerStream', localPlayer, getElemID(source), true) - elseif getElementType(source) == 'ped' and getElementData(source, 'amx.actorped') then + elseif getElementType(source) == 'ped' and getElementData(source, 'ActorPed') then triggerServerEvent('onAmxClientActorStream', localPlayer, getElemID(source), true) end end @@ -754,12 +782,26 @@ addEventHandler('onClientElementStreamOut', root, triggerServerEvent('onAmxClientVehicleStream', localPlayer, getElemID(source), false) elseif getElementType(source) == 'player' then triggerServerEvent('onAmxClientPlayerStream', localPlayer, getElemID(source), false) - elseif getElementType(source) == 'ped' and getElementData(source, 'amx.actorped') then + elseif getElementType(source) == 'ped' and getElementData(source, 'ActorPed') then triggerServerEvent('onAmxClientActorStream', localPlayer, getElemID(source), false) end end ) +local function clientVehicleDamage(attacker, weapon, loss, x, y, z, tire) + if not isElement(source) then return end + + local driver = getVehicleOccupant(source) + if not driver then + -- Block any damage for unoccupied vehicles like SA-MP does + return cancelEvent() + end + + if driver ~= localPlayer then return end + triggerServerEvent('OnVehicleDamageStatusUpdate_Ev', localPlayer, source) +end +addEventHandler('onClientVehicleDamage', root, clientVehicleDamage) + -- emulate SA-MP behaviour: block enter attempts as driver to locked vehicles addEventHandler('onClientVehicleStartEnter', root, function(player, seat, door) @@ -772,7 +814,6 @@ addEventHandler('onClientVehicleStartEnter', root, function DestroyVehicle(vehID) g_Vehicles[vehID] = nil end - ----------------------------- -- Text @@ -832,12 +873,12 @@ end local textDrawColorMapping = { r = {180, 25, 29}, - g = {53, 101, 43}, + g = {54, 104, 44}, b = {50, 60, 127}, - o = {239, 141, 27}, - w = {255, 255, 255}, - y = {222, 188, 97}, - p = {180, 25, 180}, + o = {215, 146, 24}, + w = {225, 225, 225}, + y = {226, 192, 99}, + p = {168, 110, 252}, l = {10, 10, 10} } @@ -886,20 +927,20 @@ function initTextDraw(textdraw) local scale = (textdraw.lwidth or 0.5) local tWidth, tHeight = dxGetTextSize(textdraw.text, scale) - local lineHeight = (tHeight or 0.25) / 2 --space between lines (vertical) also used to calculate size of the box if any - local lineWidth = (textdraw.lwidth or 0.25) --space between words (horizontal) + local lineHeight = (tHeight or 0.25) / 2 -- space between lines (vertical) also used to calculate size of the box if any + local lineWidth = (textdraw.lwidth or 0.25) -- space between words (horizontal) - --Set the height based on the text size + -- Set the height based on the text size textdraw.theight = tHeight textdraw.twidth = tWidth - + local text = textdraw.text:gsub('~k~~(.-)~', getSAMPBoundKey) local lines = {} local pos, stop, c stop = 0 while true do pos, stop, c = text:find('~(%a)~', stop + 1) - if c == 'n' then --If we found a new line + if c == 'n' then -- If we found a new line lines[#lines + 1] = text:sub(1, pos - 1) text = text:sub(stop + 1) stop = 0 @@ -917,11 +958,11 @@ function initTextDraw(textdraw) local font = textDrawFonts[textdraw.font and textdraw.font >= 0 and textdraw.font <= #textDrawFonts and textdraw.font or 0] font = font.font - local TDXPos = textdraw.x or 640 - #lines*lineWidth - local TDYPos = textdraw.y or 448 - #lines*lineHeight + local TDXPos = textdraw.x or 640 - #lines * lineWidth + local TDYPos = textdraw.y or 448 - #lines * lineHeight - --Process the lines we previously found - for i,line in ipairs(lines) do + -- Process the lines we previously found + for _, line in ipairs(lines) do local colorpos = 1 local color @@ -949,11 +990,11 @@ function initTextDraw(textdraw) if color or extrabright > 0 then if extrabright > 0 then color = color and table.shallowcopy(color) or { 255, 255, 255 } - for i=1,3 do - color[i] = math.min(color[i] + extrabright*40, 255) + for i = 1, 3 do + color[i] = math.min(color[i] + extrabright * 40, 255) end end - line = line:sub(1, start-1) .. ('#%02X%02X%02X'):format(unpack(color)) .. line:sub(colorpos) + line = line:sub(1, start - 1) .. ('#%02X%02X%02X'):format(unpack(color)) .. line:sub(colorpos) end end @@ -973,8 +1014,8 @@ function initTextDraw(textdraw) color = textdraw.color or tocolor(255, 255, 255) colorpos = 1 local nextcolorpos - while colorpos < line:len()+1 do - local r, g, b = line:sub(colorpos, colorpos+6):match('#(%x%x)(%x%x)(%x%x)') + while colorpos < line:len() + 1 do + local r, g, b = line:sub(colorpos, colorpos + 6):match('#(%x%x)(%x%x)(%x%x)') if r then color = tocolor(tonumber(r, 16), tonumber(g, 16), tonumber(b, 16)) colorpos = colorpos + 7 @@ -987,11 +1028,11 @@ function initTextDraw(textdraw) end TDYPos = TDYPos + lineHeight end - textdraw.absheight = tHeight*#lines + textdraw.absheight = tHeight * #lines end function renderTextDraws() - for id,textdraw in pairs(g_TextDraws) do + for id, textdraw in pairs(g_TextDraws) do if textdraw.visible and textdraw.parts and not (textdraw.text:match('^%s*$')) then-- and not textdraw.usebox) then local font = textDrawFonts[textdraw.font and textdraw.font >= 0 and textdraw.font <= #textDrawFonts and textdraw.font or 0] @@ -1007,34 +1048,34 @@ function renderTextDraws() local vertHudScale = hudGetVerticalScale() local horHudScale = hudGetHorizontalScale() - local scalex = screenWidth * horHudScale * letterWidth; - local scaley = screenHeight * vertHudScale * letterHeight * 0.5; - + local scalex = screenWidth * horHudScale * letterWidth + local scaley = screenHeight * vertHudScale * letterHeight * 0.5 + local sourceY = screenHeight - ((DEFAULT_SCREEN_HEIGHT - textdraw.y) * (screenHeight * vertHudScale)) local sourceX = screenWidth - ((DEFAULT_SCREEN_WIDTH - textdraw.x) * (screenWidth * horHudScale)) font = font.font - --Process box alignments + -- Process box alignments if textdraw.usebox ~= nil and textdraw.usebox ~= 0 then --outputConsole('textdraw uses box: ' .. textdraw.text) - local boxcolor = textdraw.boxcolor or tocolor(0, 0, 0, 120*(textdraw.alpha or 1)) + local boxcolor = textdraw.boxcolor or tocolor(0, 0, 0, 120 * (textdraw.alpha or 1)) local x, y, w, h w = textdraw.width - if textdraw.align == 1 then --left + if textdraw.align == 1 then -- left x = sourceX if textdraw.boxsize then w = textdraw.boxsize[1]-- - x else w = textdraw.width end - elseif textdraw.align == 2 then --centered + elseif textdraw.align == 2 then -- centered x = sourceX-- / 2 if textdraw.boxsize then w = textdraw.boxsize[1] else w = textdraw.width end - elseif textdraw.align == 3 then --right + elseif textdraw.align == 3 then -- right x = sourceX - w if textdraw.boxsize then w = sourceX - textdraw.boxsize[1] @@ -1043,8 +1084,8 @@ function renderTextDraws() end end y = sourceY - - --Calculates box height + + -- Calculates box height if textdraw.boxsize and textdraw.text:match('^%s*$') then h = textdraw.boxsize[2] else @@ -1054,21 +1095,21 @@ function renderTextDraws() dxDrawRectangle(x, y, w * getAspectRatio(), h * getAspectRatio(), boxcolor) --outputConsole(string.format("Drawing textdraw box: sourceX: %f, sourceY: %f %s", sourceX, sourceY, textdraw.text)) end - - for i,part in pairs(textdraw.parts) do + + for i, part in pairs(textdraw.parts) do sourceY = screenHeight - ((DEFAULT_SCREEN_HEIGHT - part.y) * (screenHeight * vertHudScale)) sourceX = screenWidth - ((DEFAULT_SCREEN_WIDTH - part.x) * (screenWidth * horHudScale)) --outputConsole(string.format("text: %s partx: %f, party: %f sourceX: %f, sourceY: %f", part.text, part.x, part.y, sourceX, sourceY)) - if textdraw.shade and textdraw.shade > 0 then --Draw the shadow - dxDrawText(part.text, sourceX + 5, sourceY + 5, sourceX + 5, sourceY + 5, tocolor(0, 0, 0, 100*(textdraw.alpha or 1)), scalex, scaley, font) + if textdraw.shade and textdraw.shade > 0 then -- Draw the shadow + dxDrawText(part.text, sourceX + 5, sourceY + 5, sourceX + 5, sourceY + 5, tocolor(0, 0, 0, 100 * (textdraw.alpha or 1)), scalex, scaley, font) end - --Draw the actual text + -- Draw the actual text drawBorderText( part.text, sourceX, sourceY, - textdraw.alpha and setcoloralpha(part.color, math.floor(textdraw.alpha*255)) or part.color, + textdraw.alpha and setcoloralpha(part.color, math.floor(textdraw.alpha * 255)) or part.color, scalex, scaley, font, textdraw.outlinesize, textdraw.outlinecolor ) @@ -1102,10 +1143,10 @@ function GameTextForPlayer(text, time, style) destroyGameText(gIndex) end - destroyAllGameTextsWithStyle(style) --So same styles don't overlap + destroyAllGameTextsWithStyle(style) -- So same styles don't overlap --[[ - alignments + alignments 1 = left 2 = center 3 = right @@ -1119,13 +1160,13 @@ function GameTextForPlayer(text, time, style) gameText[gIndex].align = 3 gameText[gIndex].upscaley = 3.0 gameText[gIndex].upscalex = 1.0 - time = 8000 --Fades out after 8 seconds regardless of time set according to the wiki + time = 8000 -- Fades out after 8 seconds regardless of time set according to the wiki elseif style == 2 then gameText[gIndex].x = 0.9 * 640 gameText[gIndex].y = 0.7 * 448 gameText[gIndex].align = 3 elseif style >= 3 then - --★ + -- ★ -- GTA replaces these with stars gameText[gIndex].text = text:gsub("]", "★") gameText[gIndex].x = 0.5 * 640 @@ -1139,23 +1180,23 @@ function GameTextForPlayer(text, time, style) initTextDraw(gameText[gIndex]) showTextDraw(gameText[gIndex]) gameText[gIndex].timer = setTimer(destroyGameText, time, 1, gIndex) - gIndex = gIndex > 100 and 1 or gIndex + 1 --Limit to 100 + gIndex = gIndex > 100 and 1 or gIndex + 1 -- Limit to 100 end -function destroyGameText(gIndex) - if gameText[gIndex] == nil then +function destroyGameText(index) + if gameText[index] == nil then return end - destroyTextDraw(gameText[gIndex]) - if gameText[gIndex].timer then - killTimer(gameText[gIndex].timer) - gameText[gIndex].timer = nil + destroyTextDraw(gameText[index]) + if gameText[index].timer then + killTimer(gameText[index].timer) + gameText[index].timer = nil end - gameText[gIndex] = nil + gameText[index] = nil end function renderTextLabels() - for id,textlabel in pairs(g_TextLabels) do + for id, textlabel in pairs(g_TextLabels) do if textlabel.enabled then if textlabel.attached then local oX, oY, oZ = getElementPosition(textlabel.attachedTo) @@ -1168,25 +1209,25 @@ function renderTextLabels() end local screenX, screenY = getScreenFromWorldPosition(textlabel.X, textlabel.Y, textlabel.Z, textlabel.dist, false) - local pX, pY, pZ, _, _, _ = getCameraMatrix()--getElementPosition(localPlayer) + local pX, pY, pZ, _, _, _ = getCameraMatrix() --getElementPosition(localPlayer) local dist = getDistanceBetweenPoints3D(pX, pY, pZ, textlabel.X, textlabel.Y, textlabel.Z) local vw = getElementDimension(localPlayer) local LOS = isLineOfSightClear(pX, pY, pZ, textlabel.X, textlabel.Y, textlabel.Z, true, false, false) - - if screenX and dist <= textlabel.dist and (vw == textlabel.vw or textlabel.vw == -1) then --Because player textlabels don't have VW's, since we're processing both here + + if screenX and dist <= textlabel.dist and (vw == textlabel.vw or textlabel.vw == -1) then -- Because player textlabels don't have VW's, since we're processing both here if not textlabel.los then - dxDrawText(textlabel.text, screenX, screenY, screenX, screenY, tocolor(textlabel.color.r, textlabel.color.g, textlabel.color.b, textlabel.color.a), 1.0, "default-bold", "center", "top", false, false, false, true) + dxDrawText(textlabel.text, screenX, screenY, screenX, screenY, tocolor(textlabel.color.r, textlabel.color.g, textlabel.color.b, textlabel.color.a), 1.0, 'default-bold', 'center', 'top', false, false, false, true) elseif LOS then - dxDrawText(textlabel.text, screenX, screenY, screenX, screenY, tocolor(textlabel.color.r, textlabel.color.g, textlabel.color.b, textlabel.color.a), 1.0, "default-bold", "center", "top", false, false, false, true) + dxDrawText(textlabel.text, screenX, screenY, screenX, screenY, tocolor(textlabel.color.r, textlabel.color.g, textlabel.color.b, textlabel.color.a), 1.0, 'default-bold', 'center', 'top', false, false, false, true) end end end end end -addEventHandler("onClientRender", root, renderTextLabels) +addEventHandler('onClientRender', root, renderTextLabels) function checkTextLabels() - for id,textlabel in pairs(g_TextLabels) do + for id, textlabel in pairs(g_TextLabels) do local pX, pY, pZ = getElementPosition(localPlayer) local dist = getDistanceBetweenPoints3D(pX, pY, pZ, textlabel.X, textlabel.Y, textlabel.Z) @@ -1200,7 +1241,6 @@ function checkTextLabels() end end - function Create3DTextLabel(id, textlabel) textlabel.id = id textlabel.enabled = false @@ -1230,14 +1270,14 @@ function TextDrawCreate(id, textdraw) textdraw.x = textdraw.x textdraw.y = textdraw.y end - for prop,val in pairs(textdraw) do + for prop, val in pairs(textdraw) do TextDrawPropertyChanged(id, prop, val, true) end initTextDraw(textdraw) end function findTextDrawHandleByID(id) - for _,textdraw in pairs(g_TextDraws) do + for _, textdraw in pairs(g_TextDraws) do if textdraw.clientTDId == id then return textdraw.clientTDId end @@ -1278,8 +1318,8 @@ function TextDrawPropertyChanged(id, prop, newval, skipInit) local textdraw = g_TextDraws[clientTDIdx] - --outputConsole('[TextDrawPropertyChanged]: Received new property ' .. prop .. ' - ' .. newval .. ' for ' .. textdraw.text) - + --outputConsole('[TextDrawPropertyChanged]: Received new property ' .. prop .. ' - ' .. newval .. ' for ' .. textdraw.text) + textdraw[prop] = newval if prop == 'boxsize' then textdraw.boxsize[1] = textdraw.boxsize[1] @@ -1305,7 +1345,7 @@ function displayFadingMessage(text, r, g, b, fadeInTime, stayTime, fadeOutTime) local lineHeight = 40 local label = guiCreateLabel(screenWidth, screenHeight, 500, lineHeight, text, false) local width = guiLabelGetTextExtent(label) - guiSetPosition(label, screenWidth/2 - width/2, 3*screenHeight/4, false) + guiSetPosition(label, screenWidth / 2 - width / 2, 3 * screenHeight / 4, false) guiSetSize(label, width, lineHeight, false) guiSetAlpha(label, 0) if r and g and b then @@ -1322,13 +1362,12 @@ function displayFadingMessage(text, r, g, b, fadeInTime, stayTime, fadeOutTime) ) anim:play() end - ----------------------------- -- Menus local function updateMenuSize(menu) - menu.width = (#menu.items[1] > 0 and (menu.leftColumnWidth + menu.rightColumnWidth) or (menu.leftColumnWidth)) + 2*MENU_SIDE_PADDING - menu.height = MENU_ITEM_HEIGHT*math.max(#menu.items[0], #menu.items[1]) + MENU_TOP_PADDING + MENU_BOTTOM_PADDING + menu.width = (#menu.items[1] > 0 and (menu.leftColumnWidth + menu.rightColumnWidth) or (menu.leftColumnWidth)) + 2 * MENU_SIDE_PADDING + menu.height = MENU_ITEM_HEIGHT * math.max(#menu.items[0], #menu.items[1]) + MENU_TOP_PADDING + MENU_BOTTOM_PADDING end function AddMenuItem(id, column, caption) @@ -1346,7 +1385,7 @@ function CreateMenu(id, menu) while g_TextDraws['m' .. id] do id = id + 1 end - menu.titletextdraw = { text = menu.title, id = 'm' .. id, x = menu.x + MENU_SIDE_PADDING, y = menu.y - 0.5*MENU_ITEM_HEIGHT, align = 1, font = 2 } + menu.titletextdraw = { text = menu.title, id = 'm' .. id, x = menu.x + MENU_SIDE_PADDING, y = menu.y - 0.5 * MENU_ITEM_HEIGHT, align = 1, font = 2 } initTextDraw(menu.titletextdraw) hideTextDraw(menu.titletextdraw) updateMenuSize(menu) @@ -1371,7 +1410,7 @@ function ShowMenuForPlayer(menuID) local prevMenu = g_CurrentMenu g_CurrentMenu = g_Menus[menuID] - local closebtnSide = screenWidth*(30/1024) + local closebtnSide = screenWidth * (30 / 1024) if not prevMenu then g_CurrentMenu.alpha = 0 g_CurrentMenu.titletextdraw.alpha = 0 @@ -1454,8 +1493,8 @@ end function setMenuAlpha(menu, alpha) menu.alpha = alpha menu.titletextdraw.alpha = alpha - guiSetAlpha(menu.closebtn, .75*alpha) - guiSetAlpha(menu.closebtnhover, .75*alpha) + guiSetAlpha(menu.closebtn, .75 * alpha) + guiSetAlpha(menu.closebtnhover, .75 * alpha) end function closeMenu() @@ -1485,36 +1524,36 @@ function renderMenu() end -- background - dxDrawRectangle(menu.x, menu.y, menu.width, menu.height, tocolor(0, 0, 0, 128*menu.alpha)) + dxDrawRectangle(menu.x, menu.y, menu.width, menu.height, tocolor(0, 0, 0, 128 * menu.alpha)) local cursorX, cursorY = getCursorPosition() - cursorY = screenHeight*cursorY + cursorY = screenHeight * cursorY -- selected row local selectedRow if cursorY >= menu.y + MENU_TOP_PADDING and cursorY < menu.y + menu.height - MENU_BOTTOM_PADDING then selectedRow = math.floor((cursorY - menu.y - MENU_TOP_PADDING) / MENU_ITEM_HEIGHT) - dxDrawRectangle(menu.x, menu.y + MENU_TOP_PADDING + selectedRow*MENU_ITEM_HEIGHT, menu.width, MENU_ITEM_HEIGHT, tocolor(98, 152, 219, 192*menu.alpha)) + dxDrawRectangle(menu.x, menu.y + MENU_TOP_PADDING + selectedRow * MENU_ITEM_HEIGHT, menu.width, MENU_ITEM_HEIGHT, tocolor(98, 152, 219, 192 * menu.alpha)) end -- menu items - for column=0,1 do - for i,text in pairs(menu.items[column]) do - local x = menu.x + MENU_SIDE_PADDING + column*menu.leftColumnWidth + for column = 0, 1 do + for i, text in pairs(menu.items[column]) do + local x = menu.x + MENU_SIDE_PADDING + column * menu.leftColumnWidth local y local color, scale if i < 13 then -- regular item - y = menu.y + MENU_TOP_PADDING + (i-1)*MENU_ITEM_HEIGHT - if menu.disabledrows and table.find(menu.disabledrows, i-1) then - color = tocolor(100, 100, 100, 255*menu.alpha) + y = menu.y + MENU_TOP_PADDING + (i - 1) * MENU_ITEM_HEIGHT + if menu.disabledrows and table.find(menu.disabledrows, i - 1) then + color = tocolor(100, 100, 100, 255 * menu.alpha) else - color = (i-1) == selectedRow and tocolor(255, 255, 255, 255*menu.alpha) or tocolor(180, 180, 180, 255*menu.alpha) + color = (i - 1) == selectedRow and tocolor(255, 255, 255, 255 * menu.alpha) or tocolor(180, 180, 180, 255 * menu.alpha) end scale = 0.7 else -- column header y = menu.y + MENU_TOP_PADDING - MENU_ITEM_HEIGHT - color = tocolor(228, 190, 57, 255*menu.alpha) + color = tocolor(228, 190, 57, 255 * menu.alpha) scale = 0.8 end drawShadowText(text, x, y + 5, color, scale, 'pricedown') @@ -1530,8 +1569,8 @@ function menuClickHandler(button, state, clickX, clickY) return end local cursorX, cursorY = getCursorPosition() - cursorY = screenHeight*cursorY - if cursorY < g_CurrentMenu.y + MENU_TOP_PADDING or cursorY > g_CurrentMenu.y + MENU_TOP_PADDING + math.max(#g_CurrentMenu.items[0], #g_CurrentMenu.items[1])*MENU_ITEM_HEIGHT then + cursorY = screenHeight * cursorY + if cursorY < g_CurrentMenu.y + MENU_TOP_PADDING or cursorY > g_CurrentMenu.y + MENU_TOP_PADDING + math.max(#g_CurrentMenu.items[0], #g_CurrentMenu.items[1]) * MENU_ITEM_HEIGHT then return end local selectedRow = math.floor((clickY - g_CurrentMenu.y - MENU_TOP_PADDING) / MENU_ITEM_HEIGHT) @@ -1542,17 +1581,75 @@ function menuClickHandler(button, state, clickX, clickY) end function OnKeyPress(key, keyState) - if ( keyState == "down" ) then + if (keyState == 'down') then exitMenu() end end - ----------------------------- -- Others +function SetPlayerPosFindZ(x, y, z) + setElementPosition(localPlayer, x, y, getGroundPosition(x, y, z) + 1) +end + +local function clientPlayerWeaponFire(weapon, ammo, ammoInClip, hitX, hitY, hitZ, hitElement, startX, startY, startZ) + if weapon < 22 or (weapon > 34 and weapon ~= 38) then return end + if source ~= localPlayer then return end + + local hitId, hitType = 65535, 0 + local offsetX, offsetY, offsetZ = hitX, hitY, hitZ + + if hitElement and isElement(hitElement) then + local elemType = getElementType(hitElement) + + hitType = ({ + player = 1, + vehicle = 2, + object = 3 + })[elemType] or 0 + + if hitType > 0 then + hitId = getElemID(hitElement) + + for k, elem in pairs(g_PlayerObjects) do + if elem == hitElement then + hitId = k + hitType = 4 + break + end + end + + offsetX, offsetY, offsetZ = getElementPosition(hitElement) + offsetX = hitX - offsetX + offsetY = hitY - offsetY + offsetZ = hitZ - offsetZ + end + end + + triggerServerEvent('OnPlayerWeaponShot_Ev', localPlayer, weapon, hitType, hitId, startX, startY, startZ, hitX, hitY, hitZ, offsetX, offsetY, offsetZ) +end +addEventHandler('onClientPlayerWeaponFire', root, clientPlayerWeaponFire) + +local function clientPedDamage(attacker, weapon, bodypart, loss) + if getElementType(source) == 'ped' and getElementData(source, 'ActorPed') then + local issuer = attacker + if issuer and getElementType(issuer) == 'vehicle' then + issuer = getVehicleOccupant(issuer) + end + + if issuer == localPlayer and not getElementData(source, 'Invulnerable') then + triggerServerEvent('OnPlayerGiveDamageActor_Ev', localPlayer, source, loss, weapon, bodypart) + end + + -- Actor damage controlled by the server in any case + return cancelEvent() + end +end +addEventHandler('onClientPedDamage', root, clientPedDamage) + function enableWeaponSyncing(enable) if enable and not g_WeaponSyncTimer then - g_WeaponSyncTimer = setTimer(sendWeapons, 5000, 0) + g_WeaponSyncTimer = setTimer(sendWeapons, 1000, 0) elseif not enable and g_WeaponSyncTimer then killTimer(g_WeaponSyncTimer) g_WeaponSyncTimer = nil @@ -1563,7 +1660,7 @@ local prevWeapons function sendWeapons() local weapons = {} local needResync = false - for slot=0,12 do + for slot = 0, 12 do weapons[slot] = { id = getPedWeapon(localPlayer, slot), ammo = getPedTotalAmmo(localPlayer, slot) } if not needResync and (not prevWeapons or prevWeapons[slot].ammo ~= weapons[slot].ammo or prevWeapons[slot].id ~= weapons[slot].id) then needResync = true @@ -1584,12 +1681,16 @@ function RemovePlayerMapIcon(blipID) return false end -function SetPlayerMapIcon(blipID, x, y, z, type, r, g, b, a) +function SetPlayerMapIcon(blipID, x, y, z, type, r, g, b, a, style) if g_Blips[blipID] then destroyElement(g_Blips[blipID]) g_Blips[blipID] = nil end g_Blips[blipID] = createBlip(x, y, z, type, 2, r, g, b, a) + -- TODO: Implement checkpoint styles + if style == 0 or style == 2 then -- Local / local checkpoint + setBlipVisibleDistance(g_Blips[blipID], 250.0) + end return true end @@ -1680,28 +1781,28 @@ end function createListDialog(titleText, message, button1txt, button2txt) if listWindow ~= nil then - removeEventHandler("onClientGUIClick", getRootElement(), OnListDialogButton1Click) --Remove handlers so they are not registered more than once - removeEventHandler("onClientGUIClick", getRootElement(), OnListDialogButton2Click) - destroyElement(listWindow) --Assuming inputWindow is the parent of everything, it should remove the whole hierarchy + removeEventHandler('onClientGUIClick', getRootElement(), OnListDialogButton1Click) -- Remove handlers so they are not registered more than once + removeEventHandler('onClientGUIClick', getRootElement(), OnListDialogButton2Click) + destroyElement(listWindow) -- Assuming inputWindow is the parent of everything, it should remove the whole hierarchy end listDialog = nil - listWindow = guiCreateWindow(screenWidth/2 - 541/2,screenHeight/2 - 352/2,541,352, titleText, false) - guiWindowSetMovable(listWindow,false) - guiWindowSetSizable(listWindow,false) - listGrid = guiCreateGridList(0.0, 0.1, 1.0, 0.8,true,listWindow) - guiGridListSetSelectionMode(listGrid,2) + listWindow = guiCreateWindow(screenWidth / 2 - 541 / 2, screenHeight / 2 - 352 / 2, 541, 352, titleText, false) + guiWindowSetMovable(listWindow, false) + guiWindowSetSizable(listWindow, false) + listGrid = guiCreateGridList(0.0, 0.1, 1.0, 0.8, true, listWindow) + guiGridListSetSelectionMode(listGrid, 2) guiGridListSetScrollBars(listGrid, true, true) - guiGridListSetSortingEnabled (listGrid, false) - --listColumn = guiGridListAddColumn(listGrid, "List", 0.85) + guiGridListSetSortingEnabled(listGrid, false) + --listColumn = guiGridListAddColumn(listGrid, 'List', 0.85) local xpos = 0.0 if #button1txt == 0 or #button2txt == 0 then - xpos = 0.40 --Center + xpos = 0.40 -- Center end - - listButton1 = guiCreateButton(xpos ~= 0.0 and xpos or 0.3, 0.9, 0.15, 0.1, button1txt,true,listWindow) - listButton2 = guiCreateButton(xpos ~= 0.0 and xpos or 0.5, 0.9, 0.15, 0.1, button2txt,true,listWindow) + + listButton1 = guiCreateButton(xpos ~= 0.0 and xpos or 0.3, 0.9, 0.15, 0.1, button1txt, true, listWindow) + listButton2 = guiCreateButton(xpos ~= 0.0 and xpos or 0.5, 0.9, 0.15, 0.1, button2txt, true, listWindow) if #button1txt == 0 then guiSetVisible(listButton1, false) @@ -1711,31 +1812,31 @@ function createListDialog(titleText, message, button1txt, button2txt) end guiSetVisible(listWindow, false) - addEventHandler("onClientGUIClick", listButton1, OnListDialogButton1Click, false) - addEventHandler("onClientGUIClick", listButton2, OnListDialogButton2Click, false) + addEventHandler('onClientGUIClick', listButton1, OnListDialogButton1Click, false) + addEventHandler('onClientGUIClick', listButton2, OnListDialogButton2Click, false) return listGrid end function createInputDialog(titleText, message, button1txt, button2txt) if inputWindow ~= nil then - removeEventHandler("onClientGUIClick", getRootElement(), OnInputDialogButton1Click) --Remove handlers so they are not registered more than once - removeEventHandler("onClientGUIClick", getRootElement(), OnInputDialogButton2Click) - destroyElement(inputWindow) --Assuming inputWindow is the parent of everything, it should remove the whole hierarchy + removeEventHandler('onClientGUIClick', getRootElement(), OnInputDialogButton1Click) -- Remove handlers so they are not registered more than once + removeEventHandler('onClientGUIClick', getRootElement(), OnInputDialogButton2Click) + destroyElement(inputWindow) -- Assuming inputWindow is the parent of everything, it should remove the whole hierarchy end inputDialog = nil - inputWindow = guiCreateWindow(screenWidth/2 - 541/2,screenHeight/2 - 352/2,541,352, titleText, false) - guiWindowSetMovable(inputWindow,false) - guiWindowSetSizable(inputWindow,false) + inputWindow = guiCreateWindow(screenWidth / 2 - 541 / 2, screenHeight / 2 - 352 / 2, 541, 352, titleText, false) + guiWindowSetMovable(inputWindow, false) + guiWindowSetSizable(inputWindow, false) inputLabel = guiCreateColoredLabel(0.1, 0.1, 1.0, 0.8, message, inputWindow, true) - inputEdit = guiCreateEdit(0.0, 0.7, 1.0, 0.1, "", true, inputWindow) + inputEdit = guiCreateEdit(0.0, 0.7, 1.0, 0.1, '', true, inputWindow) local xpos = 0.0 if #button1txt == 0 or #button2txt == 0 then - xpos = 0.40 --Center + xpos = 0.40 -- Center end - inputButton1 = guiCreateButton(xpos ~= 0.0 and xpos or 0.3, 0.9, 0.15, 0.1, button1txt, true,inputWindow) --x, y, width, height - inputButton2 = guiCreateButton(xpos ~= 0.0 and xpos or 0.5, 0.9, 0.15, 0.1, button2txt, true,inputWindow) + inputButton1 = guiCreateButton(xpos ~= 0.0 and xpos or 0.3, 0.9, 0.15, 0.1, button1txt, true, inputWindow) -- x, y, width, height + inputButton2 = guiCreateButton(xpos ~= 0.0 and xpos or 0.5, 0.9, 0.15, 0.1, button2txt, true, inputWindow) if #button1txt == 0 then guiSetVisible(inputButton1, false) @@ -1743,32 +1844,32 @@ function createInputDialog(titleText, message, button1txt, button2txt) if #button2txt == 0 then guiSetVisible(inputButton2, false) end - + guiSetVisible(inputWindow, false) - addEventHandler("onClientGUIClick", inputButton1, OnInputDialogButton1Click, false) - addEventHandler("onClientGUIClick", inputButton2, OnInputDialogButton2Click, false) + addEventHandler('onClientGUIClick', inputButton1, OnInputDialogButton1Click, false) + addEventHandler('onClientGUIClick', inputButton2, OnInputDialogButton2Click, false) end -function createMessageDialog(titleText, message, button1txt, button2txt ) +function createMessageDialog(titleText, message, button1txt, button2txt) if msgWindow ~= nil then - removeEventHandler("onClientGUIClick", getRootElement(), OnMessageDialogButton1Click) --Remove handlers so they are not registered more than once - removeEventHandler("onClientGUIClick", getRootElement(), OnMessageDialogButton2Click) - destroyElement(msgWindow) --Assuming msgWindow is the parent of everything, it should remove the whole hierarchy + removeEventHandler('onClientGUIClick', getRootElement(), OnMessageDialogButton1Click) -- Remove handlers so they are not registered more than once + removeEventHandler('onClientGUIClick', getRootElement(), OnMessageDialogButton2Click) + destroyElement(msgWindow) -- Assuming msgWindow is the parent of everything, it should remove the whole hierarchy end msgDialog = nil - msgWindow = guiCreateWindow(screenWidth/2 - 541/2,screenHeight/2 - 352/2,541,352, titleText, false) - guiWindowSetMovable(msgWindow,false) - guiWindowSetSizable(msgWindow,false) + msgWindow = guiCreateWindow(screenWidth / 2 - 541 / 2, screenHeight / 2 - 352 / 2, 541, 352, titleText, false) + guiWindowSetMovable(msgWindow, false) + guiWindowSetSizable(msgWindow, false) msgLabel = guiCreateColoredLabel(0.1, 0.1, 1.0, 0.7, message, msgWindow, true) local xpos = 0.0 if #button1txt == 0 or #button2txt == 0 then - xpos = 0.40 --Center + xpos = 0.40 -- Center end - msgButton1 = guiCreateButton(xpos ~= 0.0 and xpos or 0.3, 0.9, 0.15, 0.1, button1txt,true,msgWindow) --x, y, width, height - msgButton2 = guiCreateButton(xpos ~= 0.0 and xpos or 0.5, 0.9, 0.15, 0.1, button2txt,true,msgWindow) + msgButton1 = guiCreateButton(xpos ~= 0.0 and xpos or 0.3, 0.9, 0.15, 0.1, button1txt, true, msgWindow) -- x, y, width, height + msgButton2 = guiCreateButton(xpos ~= 0.0 and xpos or 0.5, 0.9, 0.15, 0.1, button2txt, true, msgWindow) if #button1txt == 0 then guiSetVisible(msgButton1, false) @@ -1778,27 +1879,27 @@ function createMessageDialog(titleText, message, button1txt, button2txt ) end guiSetVisible(msgWindow, false) - addEventHandler("onClientGUIClick", msgButton1, OnMessageDialogButton1Click, false) - addEventHandler("onClientGUIClick", msgButton2, OnMessageDialogButton2Click, false) + addEventHandler('onClientGUIClick', msgButton1, OnMessageDialogButton1Click, false) + addEventHandler('onClientGUIClick', msgButton2, OnMessageDialogButton2Click, false) end function clearListItem() - guiGridListRemoveColumn(listGrid, listColumn) --First remove the default column + guiGridListRemoveColumn(listGrid, listColumn) -- First remove the default column local colAmount = guiGridListGetColumnCount(listGrid) - for i=1, colAmount do --Column indexes appear to start from 1 - if not guiGridListRemoveColumn(listGrid, i) then --Always clean up all columns - outputConsole('[AMX:ShowPlayerDialog] Error: Couldn\'t remove column: ' .. 'idx: ' .. i) + for i = 1, colAmount do -- Column indexes appear to start from 1 + if not guiGridListRemoveColumn(listGrid, i) then -- Always clean up all columns + outputConsole('[ShowPlayerDialog] Error: Couldn\'t remove column: ' .. 'idx: ' .. i) end outputConsole('vals: ' .. 'idx: ' .. i) end guiGridListClear(listGrid) end -function OnListDialogButton1Click( button, state ) - if button == "left" then +function OnListDialogButton1Click(button, state) + if button == 'left' then local row, column = guiGridListGetSelectedItem(listGrid) local text = guiGridListGetItemText(listGrid, row, column) - serverAMXEvent("OnDialogResponse", getElemID(localPlayer), listDialog, 1, row, text); + serverAMXEvent('OnDialogResponse', getElemID(localPlayer), listDialog, 1, row, text) guiSetVisible(listWindow, false) showCursor(false) listDialog = nil @@ -1806,11 +1907,11 @@ function OnListDialogButton1Click( button, state ) end end -function OnListDialogButton2Click( button, state ) - if button == "left" then +function OnListDialogButton2Click(button, state) + if button == 'left' then local row, column = guiGridListGetSelectedItem(listGrid) local text = guiGridListGetItemText(listGrid, row, column) - serverAMXEvent("OnDialogResponse", getElemID(localPlayer), listDialog, 0, row, text); + serverAMXEvent('OnDialogResponse', getElemID(localPlayer), listDialog, 0, row, text) guiSetVisible(listWindow, false) showCursor(false) listDialog = nil @@ -1818,119 +1919,139 @@ function OnListDialogButton2Click( button, state ) end end -function OnInputDialogButton1Click( button, state ) - if button == "left" then - serverAMXEvent("OnDialogResponse", getElemID(localPlayer), inputDialog, 1, 0, guiGetText(inputEdit)); +function OnInputDialogButton1Click(button, state) + if button == 'left' then + serverAMXEvent('OnDialogResponse', getElemID(localPlayer), inputDialog, 1, 0, guiGetText(inputEdit)) guiSetVisible(inputWindow, false) showCursor(false) inputDialog = nil end end -function OnInputDialogButton2Click( button, state ) - if button == "left" then - serverAMXEvent("OnDialogResponse", getElemID(localPlayer), inputDialog, 0, 0, guiGetText(inputEdit)); +function OnInputDialogButton2Click(button, state) + if button == 'left' then + serverAMXEvent('OnDialogResponse', getElemID(localPlayer), inputDialog, 0, 0, guiGetText(inputEdit)) guiSetVisible(inputWindow, false) showCursor(false) inputDialog = nil end end -function OnMessageDialogButton1Click( button, state ) - if button == "left" then - serverAMXEvent("OnDialogResponse", getElemID(localPlayer), msgDialog, 1, 0, ""); +function OnMessageDialogButton1Click(button, state) + if button == 'left' then + serverAMXEvent('OnDialogResponse', getElemID(localPlayer), msgDialog, 1, 0, '') guiSetVisible(msgWindow, false) showCursor(false) msgDialog = nil end end -function OnMessageDialogButton2Click( button, state ) - if button == "left" then - serverAMXEvent("OnDialogResponse", getElemID(localPlayer), msgDialog, 0, 0, ""); +function OnMessageDialogButton2Click(button, state) + if button == 'left' then + serverAMXEvent('OnDialogResponse', getElemID(localPlayer), msgDialog, 0, 0, '') guiSetVisible(msgWindow, false) - msgDialog = nil showCursor(false) + msgDialog = nil end end --- Originally by UAEpro from here: https://forum.mtasa.com/topic/33149-colorcodes-in-labels/?tab=comments#comment-335358 -function guiCreateColoredLabel(ax, ay, bx, by,str, parent, relative) --x, y, width, height +-- Originally by UAEpro from here: https://forum.multitheftauto.com/topic/33149-colorcodes-in-labels/#comment-335358 +function guiCreateColoredLabel(ax, ay, bx, by,str, parent, relative) -- x, y, width, height if not relative then relative = true end - local scrollpane = guiCreateScrollPane(ax,ay,bx,by,relative,parent) + local scrollpane = guiCreateScrollPane(ax, ay, bx, by, relative, parent) --outputConsole('main string:' .. str) - local pat = "(.-)#(%x%x%x%x%x%x)" - local s, e, cap, col = str:find(pat, 1) - local last = 1 - local labels = {} + local pat = "(.-)#(%x%x%x%x%x%x)" + local s, e, cap, col = str:find(pat, 1) + local last = 1 + local labels = {} local incy = 0 local incx = 0 - while s do - - if cap == "" and col then r,g,b = tonumber("0x"..col:sub(1, 2)), tonumber("0x"..col:sub(3, 4)), tonumber("0x"..col:sub(5, 6)) end - if (s ~= 1) or cap ~= "" then + while s do + if cap == '' and col then + r, g, b = tonumber('0x' .. col:sub(1, 2)), tonumber('0x' .. col:sub(3, 4)), tonumber('0x' .. col:sub(5, 6)) + end + if (s ~= 1) or cap ~= '' then --outputConsole('guiCreateColoredLabel: ' .. cap) - lbl = guiCreateLabel(ax + incx, ay + incy, 1.0, by, cap, relative, scrollpane) - guiLabelSetHorizontalAlign(lbl, "left") - table.insert(labels, lbl) - if (r == nil) then r = 255 end - if (g == nil) then g = 255 end - if (b == nil) then b = 255 end - guiLabelSetColor(lbl,r,g,b) - r,g,b = tonumber("0x"..col:sub(1, 2)), tonumber("0x"..col:sub(3, 4)), tonumber("0x"..col:sub(5, 6)) + lbl = guiCreateLabel(ax + incx, ay + incy, 1.0, by, cap, relative, scrollpane) + guiLabelSetHorizontalAlign(lbl, 'left') + table.insert(labels, lbl) + if (r == nil) then r = 255 end + if (g == nil) then g = 255 end + if (b == nil) then b = 255 end + guiLabelSetColor(lbl, r, g, b) + r, g, b = tonumber('0x' .. col:sub(1, 2)), tonumber('0x' .. col:sub(3, 4)), tonumber('0x' .. col:sub(5, 6)) - local match = cap:find("\n") + local match = cap:find('\n') if match ~= nil then - local xtxtsize, ytxtsize = guiGetSize(lbl, true) --not relative - incy = incy + (ytxtsize / 8) --We found a /n so send it further down on the next line - incx = 0 --Don't add spaces on new lines + local xtxtsize, ytxtsize = guiGetSize(lbl, true) -- not relative + incy = incy + (ytxtsize / 8) -- We found a /n so send it further down on the next line + incx = 0 -- Don't add spaces on new lines --outputConsole('found a new line') else - if r ~= 255 or g ~= 255 or b ~= 255 then --It's colored so separate it + if r ~= 255 or g ~= 255 or b ~= 255 then -- It's colored so separate it incy = 0 - local xsize, ysize = guiGetSize(scrollpane, false) --not relative - incx = incx + (guiLabelGetTextExtent ( lbl ) / xsize) --Make space for the next word, relative to the parent width + local xsize, ysize = guiGetSize(scrollpane, false) -- not relative + incx = incx + (guiLabelGetTextExtent(lbl) / xsize) -- Make space for the next word, relative to the parent width --outputConsole('Separating string') else incy = 0 incx = 0 end end - end - last = e + 1 - s, e, cap, col = str:find(pat, last) - end - if (last <= #str) then - cap = str:sub(last) - lbl2 = guiCreateLabel(ax + incx, ay + incy, 1.0, by, cap, relative, scrollpane) - table.insert(labels, lbl2) - if (r == nil) then r = 255 end - if (g == nil) then g = 255 end - if (b == nil) then b = 255 end - guiLabelSetColor(lbl2,r,g,b) - end - return labels -end - ---replace colors -function colorizeString(string) + end + last = e + 1 + s, e, cap, col = str:find(pat, last) + end + if (last <= #str) then + cap = str:sub(last) + lbl2 = guiCreateLabel(ax + incx, ay + incy, 1.0, by, cap, relative, scrollpane) + table.insert(labels, lbl2) + if (r == nil) then r = 255 end + if (g == nil) then g = 255 end + if (b == nil) then b = 255 end + guiLabelSetColor(lbl2, r, g, b) + end + return labels +end + +-- replace colors +function colorizeString(string) return string:gsub("(=?{[0-9A-Fa-f]*})", function(colorMatches) - colorMatches = colorMatches:gsub("[{}]+", "") --replace the curly brackets with nothing - colorMatches = '#' .. colorMatches --Append to the beginning - return colorMatches + colorMatches = colorMatches:gsub("[{}]+", "") -- replace the curly brackets with nothing + colorMatches = '#' .. colorMatches -- Append to the beginning + return colorMatches end) end function ShowPlayerDialog(dialogid, dialogtype, caption, info, button1, button2) + if dialogid < -1 then + return true + elseif dialogid == -1 then + if msgDialog then + guiSetVisible(msgWindow, false) + msgDialog = nil + end + if inputDialog then + guiSetVisible(inputWindow, false) + inputDialog = nil + end + if listDialog then + guiSetVisible(listWindow, false) + listDialog = nil + clearListItem() + end + showCursor(false) + return true + end showCursor(true) if dialogtype == 0 then - createMessageDialog(caption, colorizeString(info), button1, button2 ) + createMessageDialog(caption, colorizeString(info), button1, button2) guiSetVisible(msgWindow, true) msgDialog = dialogid elseif dialogtype == 1 or dialogtype == 3 then @@ -1938,61 +2059,62 @@ function ShowPlayerDialog(dialogid, dialogtype, caption, info, button1, button2) guiEditSetMasked(inputEdit, dialogtype == 3) guiSetVisible(inputWindow, true) inputDialog = dialogid - elseif dialogtype == 2 or dialogtype == 4 or dialogtype == 5 then --DIALOG_STYLE_LIST, DIALOG_STYLE_TABLIST, DIALOG_STYLE_TABLIST_HEADER - --Setup the UI + elseif dialogtype == 2 or dialogtype == 4 or dialogtype == 5 then -- DIALOG_STYLE_LIST, DIALOG_STYLE_TABLIST, DIALOG_STYLE_TABLIST_HEADER + -- Setup the UI createListDialog(caption, colorizeString(info), button1, button2) guiSetVisible(listWindow, true) listDialog = dialogid -- Done - --Process each - --DIALOG_STYLE_LIST + -- Process each + -- DIALOG_STYLE_LIST if dialogtype == 2 then local items = info:gsub("\t", " ") - items = items:split("\n") - listColumn = guiGridListAddColumn(listGrid, "List", 0.85) - for k,v in ipairs(items) do - local row = guiGridListAddRow ( listGrid ) - guiGridListSetItemText ( listGrid, row, listColumn, v, false, true) + items = items:split('\n') + listColumn = guiGridListAddColumn(listGrid, 'List', 0.85) + for k, v in ipairs(items) do + local row = guiGridListAddRow(listGrid) + guiGridListSetItemText(listGrid, row, listColumn, v, false, true) end return true end - --DIALOG_STYLE_TABLIST, DIALOG_STYLE_TABLIST_HEADER - --Add the columns - local items = info:split("\n") -- Get the first one which is the header + -- DIALOG_STYLE_TABLIST, DIALOG_STYLE_TABLIST_HEADER + -- Add the columns + local items = info:split('\n') -- Get the first one which is the header if #items < 1 then outputConsole('Error, your dialog either has no items, its format is wrong or you\'re missing a newline character in the string') outputConsole('The raw string was: ' .. info) - return false --Abort if there's no items + return false -- Abort if there's no items end - --Create the header - local headerCols = items[1]:split("\t") - for k,v in ipairs(headerCols) do - local colIdx = guiGridListAddColumn( listGrid, (dialogtype == 5 and v or ''), 0.5 ) --If it's the DIALOG_STYLE_TABLIST_HEADER add the name, otherwise leave it blank + -- Create the header + local headerCols = items[1]:split('\t') + for k, v in ipairs(headerCols) do + local colIdx = guiGridListAddColumn(listGrid, (dialogtype == 5 and v or ''), 0.5) -- If it's the DIALOG_STYLE_TABLIST_HEADER add the name, otherwise leave it blank --outputConsole('headerCols - colidx: ' .. colIdx .. 'k: ' .. k .. 'v: ' .. v) end - if dialogtype == 5 then --Only remove if it's a DIALOG_STYLE_TABLIST_HEADER - table.remove(items, 1) --remove the first item which is the header + if dialogtype == 5 then -- Only remove if it's a DIALOG_STYLE_TABLIST_HEADER + table.remove(items, 1) -- remove the first item which is the header end - --Add the rows ordered under each column - for k,v in ipairs(items) do --rows - local row = guiGridListAddRow ( listGrid ) --add the row - --Now process every individual column (columns are tabulated) - for hk,hv in ipairs(v:split("\t")) do --header key, header value + -- Add the rows ordered under each column + for k, v in ipairs(items) do -- rows + local row = guiGridListAddRow(listGrid) -- add the row + -- Now process every individual column (columns are tabulated) + for hk, hv in ipairs(v:split('\t')) do -- header key, header value --outputConsole('hk: ' .. hk .. 'hv: ' .. hv) - guiGridListSetItemText ( listGrid, row, hk, hv, false, true) + guiGridListSetItemText(listGrid, row, hk, hv, false, true) end end end return true end -addEvent("onPlayerClickPlayer") -function OnPlayerClickPlayer(element) - serverAMXEvent('OnPlayerClickPlayer', getElemID(localPlayer), getElemID(element), 0) +-- depends on scoreboard resource +local function clientPlayerScoreboardClick(selected, cX, cY, clickedColumn) + if getElementType(source) ~= 'player' then return end + serverAMXEvent('OnPlayerClickPlayer', getElemID(localPlayer), getElemID(source), 0) end -addEventHandler("onPlayerClickPlayer", root, OnPlayerClickPlayer) +addEventHandler('onClientPlayerScoreboardClick', root, clientPlayerScoreboardClick) diff --git a/amx/client/garages.lua b/amx/client/garages.lua index f888c1b..ed60220 100644 --- a/amx/client/garages.lua +++ b/amx/client/garages.lua @@ -1,15 +1,15 @@ -addEventHandler( "onClientRender", root, - function( ) - for i=0,49 do - local gx, gy, gz = getGaragePosition( i ) +addEventHandler('onClientRender', root, + function() + for i = 0, 49 do + local gx, gy, gz = getGaragePosition(i) local px, py, pz = getElementPosition(localPlayer) local dist = getDistanceBetweenPoints3D(gx, gy, gz, px, py, pz) - if(dist < 20) then - if(isGarageOpen(i) == false) then + if (dist < 20) then + if (isGarageOpen(i) == false) then server.setGarageOpen(i, true) end else - if(isGarageOpen(i) == true) then + if (isGarageOpen(i) == true) then server.setGarageOpen(i, false) end end diff --git a/amx/client/mouselook.lua b/amx/client/mouselook.lua index d8ce6bc..a0c4fd3 100644 --- a/amx/client/mouselook.lua +++ b/amx/client/mouselook.lua @@ -13,7 +13,7 @@ local pi = math.pi local _setCameraMatrix = setCameraMatrix local function scale(factor, baseX, baseY, baseZ, x, y, z) - return baseX + factor*(x-baseX), baseY + factor*(y-baseY), baseZ + factor*(z-baseZ) + return baseX + factor * (x - baseX), baseY + factor * (y - baseY), baseZ + factor * (z - baseZ) end local function onRender() @@ -21,10 +21,10 @@ local function onRender() return end local x, y, z = getElementPosition(target) - local camX = x + 3*distance*cos(phi)*cos(theta) - local camY = y + 3*distance*sin(phi)*cos(theta) - local camZ = z + 0.4*distance + 2*distance*sin(theta) - local camLookZ = z + 0.5*distance + local camX = x + 3 * distance * cos(phi) * cos(theta) + local camY = y + 3 * distance * sin(phi) * cos(theta) + local camZ = z + 0.4 * distance + 2 * distance * sin(theta) + local camLookZ = z + 0.5 * distance local hit, hitX, hitY, hitZ = processLineOfSight(x, y, camLookZ, camX, camY, camZ, true, false, false) if hit then camX, camY, camZ = scale(0.9, x, y, camLookZ, hitX, hitY, hitZ) @@ -36,14 +36,14 @@ local function onMouseMove(relX, relY, absX, absY) if isMTAWindowActive() then return end - absX = absX - screenWidth/2 - absY = absY - screenHeight/2 - phi = (phi - 0.005*absX) % (2*pi) - theta = theta + 0.005*absY - if theta > 0.4*pi then - theta = 0.4*pi - elseif theta < -0.4*pi then - theta = -0.4*pi + absX = absX - screenWidth / 2 + absY = absY - screenHeight / 2 + phi = (phi - 0.005 * absX) % (2 * pi) + theta = theta + 0.005 * absY + if theta > 0.4 * pi then + theta = 0.4 * pi + elseif theta < -0.4 * pi then + theta = -0.4 * pi end end @@ -72,5 +72,3 @@ function setCameraTarget(_target) registerHandlers() end end - - diff --git a/amx/client/samp_nametags.lua b/amx/client/samp_nametags.lua index 66341fd..1ebbd93 100644 --- a/amx/client/samp_nametags.lua +++ b/amx/client/samp_nametags.lua @@ -1,38 +1,37 @@ - local font = 'arial' -- default font HealthBarBorderVertices = { - {x=0, y=0, z=0, c=tocolor(0, 0, 0, 255)}, - {x=0, y=0, z=0, c=tocolor(0, 0, 0, 255)}, - {x=0, y=0, z=0, c=tocolor(0, 0, 0, 255)}, - {x=0, y=0, z=0, c=tocolor(0, 0, 0, 255)} + { x = 0, y = 0, z = 0, c = tocolor(0, 0, 0, 255) }, + { x = 0, y = 0, z = 0, c = tocolor(0, 0, 0, 255) }, + { x = 0, y = 0, z = 0, c = tocolor(0, 0, 0, 255) }, + { x = 0, y = 0, z = 0, c = tocolor(0, 0, 0, 255) } } HealthBarBackgroundVertices = { - {x=0, y=0, z=0, c=tocolor(75, 11, 20, 255)}, - {x=0, y=0, z=0, c=tocolor(75, 11, 20, 255)}, - {x=0, y=0, z=0, c=tocolor(75, 11, 20, 255)}, - {x=0, y=0, z=0, c=tocolor(75, 11, 20, 255)} + { x = 0, y = 0, z = 0, c = tocolor(75, 11, 20, 255) }, + { x = 0, y = 0, z = 0, c = tocolor(75, 11, 20, 255) }, + { x = 0, y = 0, z = 0, c = tocolor(75, 11, 20, 255) }, + { x = 0, y = 0, z = 0, c = tocolor(75, 11, 20, 255) } } HealthBarInnerVertices = { - {x=0, y=0, z=0, c=tocolor(185, 34, 40, 255)}, - {x=0, y=0, z=0, c=tocolor(185, 34, 40, 255)}, - {x=0, y=0, z=0, c=tocolor(185, 34, 40, 255)}, - {x=0, y=0, z=0, c=tocolor(185, 34, 40, 255)} + { x = 0, y = 0, z = 0, c = tocolor(185, 34, 40, 255) }, + { x = 0, y = 0, z = 0, c = tocolor(185, 34, 40, 255) }, + { x = 0, y = 0, z = 0, c = tocolor(185, 34, 40, 255) }, + { x = 0, y = 0, z = 0, c = tocolor(185, 34, 40, 255) } } -function applyColorAlpha(color,alpha) +function applyColorAlpha(color, alpha) if color < 0 then - color = 0x100000000+color + color = 0x100000000 + color end - local rgb = color%0x1000000 - local a = (color-rgb)/0x1000000*alpha - a = a-a%1 - return rgb+a*0x1000000 + local rgb = color % 0x1000000 + local a = (color - rgb) / 0x1000000 * alpha + a = a - a % 1 + return rgb + a * 0x1000000 end function drawNameTag(position, nameText, health, armor, distance) @@ -44,53 +43,53 @@ function drawNameTag(position, nameText, health, armor, distance) return end - local rect = {left = screenCoordsX, top = screenCoordsY, right = screenCoordsX+1, bottom = screenCoordsY+1} + local rect = {left = screenCoordsX, top = screenCoordsY, right = screenCoordsX + 1, bottom = screenCoordsY + 1} local textSizeX, textSizeY = dxGetTextSize(nameText, 0, 1, 1, font) - rect.left = rect.left - (textSizeX/2) + rect.left = rect.left - (textSizeX / 2) --doOutline(nameText, 1, 1, rect.left, rect.top) dxDrawText( nameText, rect.left + 1, rect.top, rect.right, rect.bottom, - tocolor( 0, 0, 0, 255 ), 1, 1, + tocolor(0, 0, 0, 255), 1, 1, - font, "left", "top", false, false, + font, 'left', 'top', false, false, false, false, false, 0, 0, 0 ) dxDrawText( nameText, rect.left - 1, rect.top, rect.right, rect.bottom, - tocolor( 0, 0, 0, 255 ), 1, 1, + tocolor(0, 0, 0, 255), 1, 1, - font, "left", "top", false, false, + font, 'left', 'top', false, false, false, false, false, 0, 0, 0 ) dxDrawText( nameText, rect.left, rect.top - 1, rect.right, rect.bottom, - tocolor( 0, 0, 0, 255 ), 1, 1, + tocolor(0, 0, 0, 255), 1, 1, - font, "left", "top", false, false, + font, 'left', 'top', false, false, false, false, false, 0, 0, 0 ) dxDrawText( - nameText, rect.left, rect.top +1, rect.right, rect.bottom, - tocolor( 0, 0, 0, 255 ), 1, 1, + nameText, rect.left, rect.top + 1, rect.right, rect.bottom, + tocolor(0, 0, 0, 255), 1, 1, - font, "left", "top", false, false, + font, 'left', 'top', false, false, false, false, false, 0, 0, 0 ) dxDrawText( nameText, rect.left, rect.top, rect.right, rect.bottom, - tocolor( 255, 255, 255, 255 ), 1, 1, + tocolor(255, 255, 255, 255), 1, 1, - font, "left", "top", false, false, + font, 'left', 'top', false, false, false, false, false, 0, 0, 0 ) @@ -132,7 +131,7 @@ function drawNameTag(position, nameText, health, armor, distance) HealthBarInnerVertices[4].x = screenCoordsX + health -- Top Right if armor > 0 then - for i = 1,4 do + for i = 1, 4 do HealthBarBorderVertices[i].y = HealthBarBorderVertices[i].y + 8 HealthBarBackgroundVertices[i].y = HealthBarBackgroundVertices[i].y + 8 HealthBarInnerVertices[i].y = HealthBarInnerVertices[i].y + 8 @@ -142,70 +141,70 @@ function drawNameTag(position, nameText, health, armor, distance) local healthBarBordersDxVertices = {} local healthBarBackgroundDxVertices = {} local healthBarInnerDxVertices = {} - for i = 1,4 do + for i = 1, 4 do table.insert(healthBarBordersDxVertices, {HealthBarBorderVertices[i].x, HealthBarBorderVertices[i].y, HealthBarBorderVertices[i].c}) table.insert(healthBarBackgroundDxVertices, {HealthBarBackgroundVertices[i].x, HealthBarBackgroundVertices[i].y, HealthBarBackgroundVertices[i].c}) table.insert(healthBarInnerDxVertices, {HealthBarInnerVertices[i].x, HealthBarInnerVertices[i].y, HealthBarInnerVertices[i].c}) end - dxDrawPrimitive("trianglefan", false, unpack(healthBarBordersDxVertices)) - dxDrawPrimitive("trianglefan", false, unpack(healthBarBackgroundDxVertices)) - dxDrawPrimitive("trianglefan", false, unpack(healthBarInnerDxVertices)) - - -- Armor Bar + dxDrawPrimitive('trianglefan', false, unpack(healthBarBordersDxVertices)) + dxDrawPrimitive('trianglefan', false, unpack(healthBarBackgroundDxVertices)) + dxDrawPrimitive('trianglefan', false, unpack(healthBarInnerDxVertices)) + + -- Armor Bar if armor > 0 then - for i = 1,4 do + for i = 1, 4 do HealthBarBorderVertices[i].y = HealthBarBorderVertices[i].y - 8 HealthBarBackgroundVertices[i].y = HealthBarBackgroundVertices[i].y - 8 HealthBarInnerVertices[i].y = HealthBarInnerVertices[i].y - 8 - end + end - for i = 1,4 do + for i = 1, 4 do HealthBarInnerVertices[i].c = tocolor(200, 200, 200, 255) HealthBarBackgroundVertices[i].c = tocolor(40, 40, 40, 255) end if armor > 100 then - armor = 100 - end + armor = 100 + end armor = armor / 2.6 armor = armor - 19 HealthBarInnerVertices[3].x = screenCoordsX + armor -- Bottom right - HealthBarInnerVertices[4].x = screenCoordsX + armor -- Top Right + HealthBarInnerVertices[4].x = screenCoordsX + armor -- Top Right local armorBarBordersDxVertices = {} local armorBarBackgroundDxVertices = {} local armorBarInnerDxVertices = {} - for i = 1,4 do + for i = 1, 4 do table.insert(armorBarBordersDxVertices, {HealthBarBorderVertices[i].x, HealthBarBorderVertices[i].y, HealthBarBorderVertices[i].c}) table.insert(armorBarBackgroundDxVertices, {HealthBarBackgroundVertices[i].x, HealthBarBackgroundVertices[i].y, HealthBarBackgroundVertices[i].c}) table.insert(armorBarInnerDxVertices, {HealthBarInnerVertices[i].x, HealthBarInnerVertices[i].y, HealthBarInnerVertices[i].c}) end - dxDrawPrimitive("trianglefan", false, unpack(armorBarBordersDxVertices)) - dxDrawPrimitive("trianglefan", false, unpack(armorBarBackgroundDxVertices)) - dxDrawPrimitive("trianglefan", false, unpack(armorBarInnerDxVertices)) + dxDrawPrimitive('trianglefan', false, unpack(armorBarBordersDxVertices)) + dxDrawPrimitive('trianglefan', false, unpack(armorBarBackgroundDxVertices)) + dxDrawPrimitive('trianglefan', false, unpack(armorBarInnerDxVertices)) - for i = 1,4 do + for i = 1, 4 do HealthBarInnerVertices[i].c = tocolor(185, 34, 40, 255) HealthBarBackgroundVertices[i].c = tocolor(75, 11, 20, 255) end end end -addEventHandler( "onClientRender", root, +addEventHandler('onClientRender', root, function() local playerPosX, playerPosY, playerPosZ = getElementPosition(localPlayer) - for k, player in pairs( getElementsByType("player") ) do - if player ~= localPlayer and isElementOnScreen( player ) then + for k, player in pairs(getElementsByType('player')) do + if player ~= localPlayer and isElementOnScreen(player) then --local fPosX, fPosY, fPosZ = getElementPosition(player) local fPosX, fPosY, fPosZ = getPedBonePosition(player, 8) local distance = getDistanceBetweenPoints3D(playerPosX, playerPosY, playerPosZ, fPosX, fPosY, fPosZ) if distance < 45 then - local cx,cy,cz = getCameraMatrix(localPlayer) - if isLineOfSightClear(cx,cy,cz, fPosX, fPosY, fPosZ, true, true, false, true, true, false, false) then - drawNameTag({x = fPosX, y = fPosY, z = fPosZ}, getPlayerName(player) .. " (" .. getElemID(player) .. ")", getElementHealth(player), getPedArmor(player), distance) + local cx, cy, cz = getCameraMatrix(localPlayer) + if isLineOfSightClear(cx, cy, cz, fPosX, fPosY, fPosZ, true, true, false, true, true, false, false) then + drawNameTag({x = fPosX, y = fPosY, z = fPosZ}, getPlayerName(player) .. ' (' .. getElemID(player) .. ')', getElementHealth(player), getPedArmor(player), distance) end end end diff --git a/amx/client/util.lua b/amx/client/util.lua index a02d16c..1f421d8 100644 --- a/amx/client/util.lua +++ b/amx/client/util.lua @@ -1,14 +1,14 @@ --[[ local function fndebug(...) local args = { ... } - for i,name in ipairs(args) do + for i, name in ipairs(args) do local fn = _G[name] _G[name] = function(...) local args = { ... } local result = fn(...) local logstr = 'Client: ' .. name .. '(' - for i,a in ipairs(args) do + for i, a in ipairs(args) do if i > 1 then logstr = logstr .. ', ' end @@ -70,8 +70,8 @@ function drawBorderText(text, x, y, color, scalex, scaley, font, outlinesize, ou local alpha = math.floor(color / 16777216) outlinesize = outlinesize or 2 if outlinesize > 0 then - for offsetX=-outlinesize,outlinesize,outlinesize do - for offsetY=-outlinesize,outlinesize,outlinesize do + for offsetX = -outlinesize, outlinesize, outlinesize do + for offsetY = -outlinesize, outlinesize, outlinesize do if not (offsetX == 0 and offsetY == 0) then dxDrawText(text, x + offsetX, y + offsetY, x + offsetX, y + offsetY, outlinecolor or tocolor(0, 0, 0, alpha), scalex, scaley, font) end @@ -98,7 +98,7 @@ function bindKey(key, ...) return _bindKey(key, ...) elseif type(key) == 'table' then local result = true - for i,k in ipairs(key) do + for i, k in ipairs(key) do result = result and _bindKey(k, ...) end return result @@ -119,7 +119,7 @@ function isVehicleEmpty(vehicle) if not numPassengers then return true end - for seat=0,numPassengers do + for seat = 0, numPassengers do if getVehicleOccupant(vehicle, seat) then return false end @@ -147,7 +147,7 @@ end function table.find(t, ...) local args = { ... } if #args == 0 then - for k,v in pairs(t) do + for k, v in pairs(t) do if v then return k, v end @@ -159,8 +159,8 @@ function table.find(t, ...) if value == '[nil]' then value = nil end - for k,v in pairs(t) do - for i,index in ipairs(args) do + for k, v in pairs(t) do + for i, index in ipairs(args) do if type(index) == 'function' then v = index(v) else @@ -178,7 +178,7 @@ function table.find(t, ...) end function table.removevalue(t, val) - for i,v in ipairs(t) do + for i, v in ipairs(t) do if v == val then table.remove(t, i) return i @@ -197,7 +197,7 @@ function table.each(t, index, callback, ...) callback = index index = false end - for k,v in pairs(t) do + for k, v in pairs(t) do callback(index and v[index] or v, unpack(arg)) end return t @@ -207,7 +207,7 @@ function table.filter(t, callback, cmpval) if cmpval == nil then cmpval = true end - for k,v in pairs(t) do + for k, v in pairs(t) do if callback(v) ~= cmpval then t[k] = nil end @@ -217,7 +217,7 @@ end function table.shallowcopy(t) local result = {} - for k,v in pairs(t) do + for k, v in pairs(t) do result[k] = v end return result @@ -239,13 +239,13 @@ function table.dump(t, caption, depth) outputConsole(str) end else - local braceIndent = string.rep(' ', depth-1) + local braceIndent = string.rep(' ', depth - 1) local fieldIndent = braceIndent .. ' ' outputConsole(braceIndent .. '{') - for k,v in pairs(t) do + for k, v in pairs(t) do if type(v) == 'table' and k ~= 'siblings' and k ~= 'parent' then outputConsole(fieldIndent .. tostring(k) .. ' = ') - table.dump(v, nil, depth+1) + table.dump(v, nil, depth + 1) else outputConsole(fieldIndent .. tostring(k) .. ' = ' .. tostring(v)) end @@ -264,7 +264,7 @@ function string:split(sep, plain) local to, nextfrom repeat to, nextfrom = self:find(sep, from, plain) - result[#result+1] = self:sub(from, to and to - 1) + result[#result + 1] = self:sub(from, to and to - 1) from = nextfrom and nextfrom + 1 until not to return result @@ -279,46 +279,56 @@ function fromcolor(color) return math.floor(color / 65536) % 255, math.floor(color / 255) % 255, color % 255, math.floor(color / 16777216) end ---From: https://github.com/GTAmodding/re3/blob/408f47fc9d85e930f2dc1a4cc9f50b3c0d4c60b8/src/core/common.h +-- From: https://github.com/halpz/re3/blob/408f47fc9d85e930f2dc1a4cc9f50b3c0d4c60b8/src/core/common.h DEFAULT_SCREEN_WIDTH = 640.0 DEFAULT_SCREEN_HEIGHT = 448.0 -DEFAULT_ASPECT_RATIO = 4.0/3.0 +DEFAULT_ASPECT_RATIO = 4.0 / 3.0 DEFAULT_VIEWWINDOW = 0.7 -local USCREEN_WIDTH, USCREEN_HEIGHT = guiGetScreenSize( ) +local USCREEN_WIDTH, USCREEN_HEIGHT = guiGetScreenSize() -function SCREEN_ASPECT_RATIO(a) +function SCREEN_ASPECT_RATIO(a) return ((a) * USCREEN_WIDTH / DEFAULT_SCREEN_WIDTH) end ---This scales from PS2 pixel coordinates to the real resolution -function SCREEN_STRETCH_X(a) + +-- This scales from PS2 pixel coordinates to the real resolution +function SCREEN_STRETCH_X(a) return ((a) * USCREEN_WIDTH / DEFAULT_SCREEN_WIDTH) end -function SCREEN_STRETCH_Y(a) + +function SCREEN_STRETCH_Y(a) return ((a) * USCREEN_HEIGHT / DEFAULT_SCREEN_HEIGHT) end -function SCREEN_STRETCH_FROM_RIGHT(a) + +function SCREEN_STRETCH_FROM_RIGHT(a) return (USCREEN_WIDTH - SCREEN_STRETCH_X(a)) end -function SCREEN_STRETCH_FROM_BOTTOM(a) + +function SCREEN_STRETCH_FROM_BOTTOM(a) return (USCREEN_HEIGHT - SCREEN_STRETCH_Y(a)) end ---This scales from PS2 pixel coordinates while optionally maintaining the aspect ratio -function SCREEN_SCALE_X(a) + +-- This scales from PS2 pixel coordinates while optionally maintaining the aspect ratio +function SCREEN_SCALE_X(a) return SCREEN_SCALE_AR(SCREEN_STRETCH_X(a)) end -function SCREEN_SCALE_Y(a) + +function SCREEN_SCALE_Y(a) return SCREEN_STRETCH_Y(a) end -function SCREEN_SCALE_FROM_RIGHT(a) + +function SCREEN_SCALE_FROM_RIGHT(a) return USCREEN_WIDTH - SCREEN_SCALE_X(a) end -function SCREEN_SCALE_FROM_BOTTOM(a) + +function SCREEN_SCALE_FROM_BOTTOM(a) return USCREEN_HEIGHT - SCREEN_SCALE_Y(a) end + function getAspectRatio() - return USCREEN_WIDTH/USCREEN_HEIGHT + return USCREEN_WIDTH / USCREEN_HEIGHT end + function SCREEN_SCALE_AR(a) return ((a) * DEFAULT_ASPECT_RATIO / getAspectRatio()) end diff --git a/amx/meta.xml b/amx/meta.xml index d16f645..6d91c00 100644 --- a/amx/meta.xml +++ b/amx/meta.xml @@ -1,9 +1,10 @@ - +