Advertisement
Shiny_

Pomocy

Oct 5th, 2013
182
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 16.13 KB | None | 0 0
  1. // Includes:
  2.     #include <a_samp>
  3.     #include <crashdetect>
  4.     #include <mapandreas>
  5.     #include <regex>
  6.     #include <sscanf2>
  7.     #include <YSF>
  8.     #include <YSI\y_ini>
  9.     #include <YSI\y_iterate>
  10.     #include <zcmd>
  11.  
  12.     native WP_Hash(buffer[], len, const str[]);
  13.  
  14. // Macros:
  15.     #undef INI_String
  16.     #if defined _inc_sscanf && 0
  17.         #define INI_String(%1,%2,%3)                \
  18.                 if(!strcmp((%1), name, false) && !sscanf(value, "s["#%3"]", %2)) return;
  19.     #else
  20.         #define INI_String(%1,%2,%3)                \
  21.                 if(!strcmp((%1), name, false)) return strcpy(%2, value, %3)
  22.     #endif
  23.     #define function%0(%1)                          \
  24.             forward %0(%1);                         \
  25.             public %0(%1)
  26.     #define Timer::
  27.    
  28.     #if !defined INTERPOLATIONTIME
  29.             #define INTERPOLATIONTIME                                                               \
  30.                     16500
  31.     #endif
  32.     #define PATH                                    \
  33.             "/Users/%s.ini"
  34.    
  35.     enum {
  36.         DIALOG_REG = 50,
  37.         DIALOG_LOGIN,
  38.         DIALOG_SUCC,
  39.     };
  40.    
  41.     enum pInfo {
  42.         pCash,
  43.         pAdmin,
  44.         pKills,
  45.         pDeaths,
  46.         pPass[129],
  47.     };
  48.    
  49. // Variables:
  50.     new vehicle;
  51.     new STR_[128];
  52.     new STR_2[128];
  53.     new text_[100];
  54.     new Float: Position[4];
  55.     new Name[MAX_PLAYER_NAME];
  56.     new RegEx: AntiAdvertisement;
  57.     new bool: LoggedIn[MAX_PLAYERS];
  58.     new bool: Registered[MAX_PLAYERS];
  59.     new bool: Commanded[MAX_VEHICLES];
  60.     new PlayerInfo[MAX_PLAYERS][pInfo];
  61.     new Set_CameraPos_Timer[MAX_PLAYERS];
  62.     new PlayerText3D: Time3DText[MAX_PLAYERS];
  63.     new gVehicleNames[212][] = {
  64.         "Landstalker", "Bravura", "Buffalo", "Linerunner", "Perennial", "Sentinel", "Dumper",
  65.         "Firetruck", "Trashmaster", "Stretch", "Manana", "Infernus", "Voodoo", "Pony", "Mule",
  66.         "Cheetah", "Ambulance", "Leviathan", "Moonbeam", "Esperanto", "Taxi", "Washington",
  67.         "Bobcat", "Mr Whoopee", "BF Injection", "Hunter", "Premier", "Enforcer", "Securicar",
  68.         "Banshee", "Predator", "Bus", "Rhino", "Barracks", "Hotknife", "Trailer 1", "Previon",
  69.         "Coach", "Cabbie", "Stallion", "Rumpo", "RC Bandit", "Romero", "Packer", "Monster",
  70.         "Admiral", "Squalo", "Seasparrow", "Pizzaboy", "Tram", "Trailer 2", "Turismo",
  71.         "Speeder", "Reefer", "Tropic", "Flatbed", "Yankee", "Caddy", "Solair", "Berkley's RC Van",
  72.         "Skimmer", "PCJ-600", "Faggio", "Freeway", "RC Baron", "RC Raider", "Glendale", "Oceanic",
  73.         "Sanchez", "Sparrow", "Patriot", "Quad", "Coastguard", "Dinghy", "Hermes", "Sabre",
  74.         "Rustler", "ZR-350", "Walton", "Regina", "Comet", "BMX", "Burrito", "Camper", "Marquis",
  75.         "Baggage", "Dozer", "Maverick", "News Chopper", "Rancher", "FBI Rancher", "Virgo", "Greenwood",
  76.         "Jetmax", "Hotring", "Sandking", "Blista Compact", "Police Maverick", "Boxville", "Benson",
  77.         "Mesa", "RC Goblin", "Hotring Racer A", "Hotring Racer B", "Bloodring Banger", "Rancher",
  78.         "Super GT", "Elegant", "Journey", "Bike", "Mountain Bike", "Beagle", "Cropdust", "Stunt",
  79.         "Tanker", "Roadtrain", "Nebula", "Majestic", "Buccaneer", "Shamal", "Hydra", "FCR-900",
  80.         "NRG-500", "HPV1000", "Cement Truck", "Tow Truck", "Fortune", "Cadrona", "FBI Truck",
  81.         "Willard", "Forklift", "Tractor", "Combine", "Feltzer", "Remington", "Slamvan",
  82.         "Blade", "Freight", "Streak", "Vortex", "Vincent", "Bullet", "Clover", "Sadler",
  83.         "Firetruck LA", "Hustler", "Intruder", "Primo", "Cargobob", "Tampa", "Sunrise", "Merit",
  84.         "Utility", "Nevada", "Yosemite", "Windsor", "Monster A", "Monster B", "Uranus", "Jester",
  85.         "Sultan", "Stratum", "Elegy", "Raindance", "RC Tiger", "Flash", "Tahoma", "Savanna",
  86.         "Bandito", "Freight Flat", "Streak Carriage", "Kart", "Mower", "Duneride", "Sweeper",
  87.         "Broadway", "Tornado", "AT-400", "DFT-30", "Huntley", "Stafford", "BF-400", "Newsvan",
  88.         "Tug", "Trailer 3", "Emperor", "Wayfarer", "Euros", "Hotdog", "Club", "Freight Carriage",
  89.         "Trailer 3", "Andromada", "Dodo", "RC Cam", "Launch", "Police Car (LSPD)", "Police Car (SFPD)",
  90.         "Police Car (LVPD)", "Police Ranger", "Picador", "S.W.A.T. Van", "Alpha", "Phoenix", "Glendale",
  91.         "Sadler", "Luggage Trailer A", "Luggage Trailer B", "Stair Trailer", "Boxville", "Farm Plow",
  92.         "Utility Trailer"
  93.     };
  94.    
  95. // Static functions:
  96.     stock RespawnUnusedVehicles() {
  97.         new UsedVeh[MAX_VEHICLES] = {false, ...};
  98.         foreach(new playerid: Player) {
  99.             UsedVeh[GetPlayerVehicleID(playerid)] = true;
  100.         }
  101.        
  102.         for(new vehicleid = 1; vehicleid != MAX_VEHICLES; vehicleid++) {
  103.             if(UsedVeh[vehicleid]) continue;
  104.             if(Commanded[vehicleid]) {
  105.                 DestroyVehicle(vehicleid);
  106.                 Commanded[vehicleid] = false;
  107.             }
  108.             SetVehicleToRespawn(vehicleid);
  109.         }
  110.         return true;
  111.     }
  112.  
  113.     stock CreatePlayerVehicle(playerid, modelid) {
  114.         if(GetPlayerState(playerid) == PLAYER_STATE_DRIVER) {
  115.             vehicle = GetPlayerVehicleID(playerid);
  116.             GetVehiclePos(vehicle, Position[0], Position[1], Position[2]);
  117.             GetVehicleZAngle(vehicle, Position[3]);
  118.             DestroyVehicle(vehicle);
  119.         } else {
  120.             GetPlayerPos(playerid, Position[0], Position[1], Position[2]);
  121.             GetPlayerFacingAngle(playerid, Position[3]);
  122.         }
  123.         vehicle = AddStaticVehicle(modelid, Position[0], Position[1], Position[2] + 1, Position[3], -1, -1);
  124.         LinkVehicleToInterior(vehicle, GetPlayerInterior(playerid));
  125.         SetVehicleVirtualWorld(vehicle, GetPlayerVirtualWorld(playerid));
  126.         SetVehicleNumberPlate(vehicle, PlayerName(playerid));
  127.         PutPlayerInVehicle(playerid, vehicle, 0);
  128.         Commanded[vehicle] = true;
  129.         return true;
  130.     }
  131.    
  132.     stock GetVehicleModelIDByName(vehiclename[]) {
  133.         for(new i = 0; i < 211; i++) {
  134.             if(strfind(gVehicleNames[i], vehiclename, true) != -1) return i + 400;
  135.         }
  136.         return -1;
  137.     }
  138.    
  139.     stock delete_free_space(string[], character = ' ') {
  140.         new len = strlen(string);
  141.         if(len) {
  142.             new begin = -1, end = len;
  143.             while(string[++begin] == character) {}
  144.             if(string[begin] == EOS) {
  145.                 string[0] = false;
  146.                 return true;
  147.             }
  148.             while(string[--end] == character) {}
  149.             strmid(string, string, begin, end + 1, len + 1);
  150.         }
  151.         return true;
  152.     }
  153.    
  154.     stock PlayerName(playerid) {
  155.         GetPlayerName(playerid, Name, sizeof(Name));
  156.         return Name;
  157.     }
  158.    
  159.     stock Path(playerid) {
  160.         new STR[128];
  161.         format(STR, sizeof(STR), PATH, PlayerName(playerid));
  162.         return STR;
  163.     }
  164.    
  165.     stock CheckLoginOrRegister(playerid) {
  166.         format(STR_, sizeof(STR_), "Witaj z powrotem %s.\nMasz już konto na tym serwerze, więc pozostaje Ci tylko wpisanie hasła w polu poniżej.", PlayerName(playerid));
  167.         format(STR_2, sizeof(STR_2), "Witaj %s.\nNie masz konta na tym serwerze, więc musisz wpisać hasło w polu poniżej aby kontynuować grę.", PlayerName(playerid));
  168.         switch(fexist(Path(playerid))) {
  169.             case 0: ShowPlayerDialog(playerid, DIALOG_REG, DIALOG_STYLE_PASSWORD, "Rejestracja", STR_2, "Zarejestruj", "Wyjdź");
  170.             case 1: {
  171.                 INI_ParseFile(Path(playerid), "Load_User_%s", .bExtra = true, .extra = playerid);
  172.                 ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Logowanie", STR_, "Zaloguj", "Wyjdź");
  173.             }
  174.         }
  175.     }
  176.    
  177. // Dynamic functions:  
  178.     function RespawnVehicles(vehicleid) {
  179.         RespawnUnusedVehicles();
  180.         SendClientMessageToAll(-1, "Auta stworzone za pomocą komendy /v zostały usunięte!");
  181.         return true;
  182.     }
  183.    
  184.     function Time(playerid) {
  185.         new time[3];
  186.         new string__[128];
  187.         gettime(time[0], time[1], time[2]);
  188.         format(string__, sizeof(string__), "[%02d:%02d:%02d]", time[0], time[1], time[2]);
  189.         UpdatePlayer3DTextLabelText(playerid, Time3DText[playerid], -1, string__);
  190.         return true;
  191.     }
  192.    
  193.     function SetCameraPosEx(playerid) {
  194.         SetPlayerInterior(playerid, 0);
  195.         SetPlayerFacingAngle(playerid, 90.0);
  196.         SetPlayerPos(playerid, -1399.0179, 2640.7385, 55.6875);
  197.         SetPlayerCameraPos(playerid, -1410.462402, 2640.7385, 55.6875);
  198.         SetPlayerCameraLookAt(playerid, -1410.462402, 2640.7385, 55.6875, CAMERA_CUT);
  199.         ApplyAnimation(playerid, "RAPPING", "RAP_B_Loop", 4.0, 1, 0, 0, 0, 0);
  200.     }
  201.    
  202.     function Load_User_Data(playerid, name[], value[]) {
  203.         INI_Int("Cash", PlayerInfo[playerid][pCash]);
  204.         INI_Int("Admin", PlayerInfo[playerid][pAdmin]);
  205.         INI_Int("Kills", PlayerInfo[playerid][pKills]);
  206.         INI_Int("Deaths", PlayerInfo[playerid][pDeaths]);
  207.         INI_String("Password", PlayerInfo[playerid][pPass], 129);
  208.         return true;
  209.     }
  210.    
  211. // Public functions:
  212.     main() {
  213.         AntiAdvertisement = regex_build("\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)+([(/|,.)?\\s]{1,})+(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)+([(/|,.)?\\s]{1,})+(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)+([(/|,.)?\\s]{1,})+(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b");
  214.         printf(regex_isvalid(AntiAdvertisement)? ("Kod regex antyreklamy jest poprawny!"): ("Kod regex antyreklamy jest niepoprawny!"));
  215.         SetTimer("RespawnVehicles", 15 * 60 * 1000, true);
  216.         SetModeRestartTime(0.1);
  217.         return false;
  218.     }
  219.    
  220.     public OnPlayerConnect(playerid) {
  221.         PlayAudioStreamForPlayer(playerid, "http://alldev.eu/mp3/sleepwalking.mp3");
  222.        
  223.         InterpolateCameraPos(playerid, -2662.6853, 1933.7972, 225.7578, -1409.489868, 2642.814697, 58.506492, INTERPOLATIONTIME, CAMERA_MOVE);
  224.         InterpolateCameraLookAt(playerid, -2662.6853, 1933.7972, 225.7578, -1404.622924, 2642.720458, 57.364322, INTERPOLATIONTIME, CAMERA_MOVE);
  225.  
  226.         ApplyAnimation(playerid, "RAPPING", "RAP_B_Loop", 4.0, 1, 0, 0, 0, 0);
  227.         Set_CameraPos_Timer[playerid] = SetTimerEx("SetCameraPosEx", INTERPOLATIONTIME, false, "d", playerid);
  228.        
  229.         SetTimerEx("Time", 999, true, "d", playerid);
  230.         SendDeathMessage(INVALID_PLAYER_ID, playerid, 200);
  231.         SendClientMessage(playerid, -1, "W każdej chwili możesz zalogować się lub zarejestrować. Wystarczy, że wpiszesz /zaloguj bądź /zarejestruj.");
  232.         return true;
  233.     }
  234.    
  235.     public OnPlayerSpawn(playerid) {
  236.         KillTimer(Set_CameraPos_Timer[playerid]);
  237.         SetCameraBehindPlayer(playerid);
  238.         StopAudioStreamForPlayer(playerid);
  239.         SetPlayerFacingAngle(playerid, 90.0);
  240.         SetPlayerPos(playerid, -1399.0179, 2640.7385, 55.6875);
  241.         SetPlayerWorldBounds(playerid, 20000.0000, -20000.0000, 20000.0000, -20000.0000);
  242.         return true;
  243.     }
  244.    
  245.     public OnPlayerText(playerid, text[]) {
  246.         new MSG_EX[180];
  247.         new STRING[180];
  248.         format(MSG_EX, sizeof(MSG_EX), "%s próbuje reklamować.", PlayerName(playerid));
  249.         regex_replace_exid(text, AntiAdvertisement, MSG_EX, STRING);
  250.        
  251.         format(STRING, sizeof(STRING), "(ID: %d): %s", playerid, text);
  252.         SendPlayerMessageToAll(playerid, STRING);
  253.         printf("%s: %s", PlayerName(playerid), text);
  254.         return false;
  255.        
  256.         // Kolory:
  257.         // - zielony: #339933
  258.         // - pomarańczowy: #FF5917
  259.         // - bordowy: #BB0000
  260.     }
  261.    
  262.     public OnDialogResponse(playerid, dialogid, response, listitem, inputtext[]) {
  263.         format(STR_, sizeof(STR_), "Witaj z powrotem %s.\nMasz już konto na tym serwerze, więc pozostaje Ci tylko wpisanie hasła w polu poniżej.", PlayerName(playerid));
  264.         format(STR_2, sizeof(STR_2), "Witaj %s.\nNie masz konta na tym serwerze, więc musisz wpisać hasło w polu poniżej aby kontynuować grę.", PlayerName(playerid));
  265.         switch(dialogid) {
  266.             case DIALOG_REG: {
  267.                 switch(response) {
  268.                     case 0: Kick(playerid);
  269.                     case 1: {
  270.                         new HashPass[129];
  271.                         new INI: File_;
  272.                         LoggedIn[playerid] = false;
  273.                         WP_Hash(HashPass, sizeof(HashPass), inputtext);
  274.                         File_ = INI_Open(Path(playerid));
  275.                         INI_SetTag(File_, "Dane Graczy");
  276.                         INI_WriteInt(File_, "Cash", 0);
  277.                         INI_WriteInt(File_, "Admin", 0);
  278.                         INI_WriteInt(File_, "Kills", 0);
  279.                         INI_WriteInt(File_, "Deaths", 0);
  280.                         INI_WriteString(File_, "Password", HashPass);
  281.                         INI_Close(File_);
  282.                         if(!strlen(inputtext)) {
  283.                             return ShowPlayerDialog(playerid, DIALOG_REG, DIALOG_STYLE_PASSWORD, "Rejestracja", STR_2, "Zarejestruj", "Wyjdź");
  284.                         }
  285.                         Registered[playerid] = true;
  286.                         SendClientMessage(playerid, -1, "Rejestracja przebiegła pomyślnie.");
  287.                     }
  288.                 }
  289.             }
  290.             case DIALOG_LOGIN: {
  291.                 switch(response) {
  292.                     case 0: Kick(playerid);
  293.                     case 1: {
  294.                         new HashPass[129];
  295.                         WP_Hash(HashPass, sizeof(HashPass), inputtext);
  296.                         if(!strcmp(HashPass, PlayerInfo[playerid][pPass], false)) {
  297.                             LoggedIn[playerid] = true;
  298.                             Registered[playerid] = true;
  299.                             GivePlayerMoney(playerid, PlayerInfo[playerid][pCash]);
  300.                             INI_ParseFile(Path(playerid), "Load_User_%s", .bExtra = true, .extra = playerid);
  301.                             SendClientMessage(playerid, -1, "Zalogowano poprawnie.");
  302.                         } else {
  303.                             return ShowPlayerDialog(playerid, DIALOG_LOGIN, DIALOG_STYLE_PASSWORD, "Logowanie", STR_, "Zaloguj", "Wyjdź");
  304.                         }
  305.                     }
  306.                 }
  307.             }
  308.         }
  309.         return true;
  310.     }
  311.    
  312.     public OnPlayerCommandPerformed(playerid, cmdtext[], success) {
  313.         if(!success) {
  314.             if(strlen(cmdtext) > 2) {
  315.                 strdel(cmdtext, 0, 1);
  316.                 for(new i = 400; i <= 611; i++) {
  317.                     if(strfind(gVehicleNames[i - 400], cmdtext, true) != -1) {
  318.                         CreatePlayerVehicle(playerid, i);
  319.                         format(text_, sizeof(text_), "Pojazd o nazwie {FF0000}%s{FFFFFF} zostaje utworzony.", gVehicleNames[i - 400]);
  320.                         SendClientMessage(playerid, -1, text_);
  321.                         return true;
  322.                     }
  323.                 }
  324.             }
  325.             format(text_, sizeof(text_), "Na serwerze nie ma takiej komendy jak /%s!", cmdtext);
  326.             SendClientMessage(playerid, -1, text_);
  327.             printf("%s wpisuje komendę: /%s", PlayerName(playerid), cmdtext);
  328.         }
  329.         return true;
  330.     }
  331.    
  332.     public OnPlayerStateChange(playerid, newstate, oldstate) {
  333.         format(text_, sizeof(text_), "%s", Time(playerid));
  334.         switch(newstate) {case PLAYER_STATE_DRIVER: Time3DText[playerid] = CreatePlayer3DTextLabel(playerid, text_, -1, 0, 0, 0, 15.0, INVALID_PLAYER_ID, GetPlayerVehicleID(playerid), 1);}
  335.         switch(oldstate) {case PLAYER_STATE_DRIVER: DeletePlayer3DTextLabel(playerid, Time3DText[playerid]);}
  336.         return true;
  337.     }
  338.    
  339.     public OnPlayerDeath(playerid, killerid, reason) {
  340.         SendDeathMessage(killerid, playerid, reason);
  341.         /*PlayerInfo[killerid][pKills]++;
  342.         PlayerInfo[playerid][pDeaths]++;*/
  343.         if(killerid != INVALID_PLAYER_ID) {
  344.             PlayerInfo[killerid][pKills]++;
  345.             SetPlayerScore(killerid, PlayerInfo[killerid][pKills]);
  346.             PlayerInfo[killerid][pCash] += 100;
  347.             GivePlayerMoney(killerid, 100);
  348.         }
  349.        
  350.         PlayerInfo[playerid][pDeaths]++;
  351.         PlayerInfo[playerid][pCash] -= 100;
  352.         GivePlayerMoney(playerid, PlayerInfo[playerid][pCash]);
  353.         SetPlayerAmmo(playerid, 223, 0);
  354.         return true;
  355.     }
  356.  
  357.     public OnPlayerDisconnect(playerid, reason) {
  358.         new INI: File_;
  359.         File_ = INI_Open(Path(playerid));
  360.         if(!IsPlayerConnected(playerid)) {
  361.             DeletePlayer3DTextLabel(playerid, Time3DText[playerid]), KillTimer(Set_CameraPos_Timer[playerid]);
  362.             INI_SetTag(File_, "Dane Graczy");
  363.             INI_WriteInt(File_, "Cash", 0);
  364.             INI_WriteInt(File_, "Admin", 0);
  365.             INI_WriteInt(File_, "Kills", 0);
  366.             INI_WriteInt(File_, "Deaths", 0);
  367.             INI_Close(File_);
  368.         }
  369.         SendDeathMessage(INVALID_PLAYER_ID, playerid, 201);
  370.         return true;
  371.     }
  372.    
  373.     public OnGameModeExit() {
  374.         return regex_delete(AntiAdvertisement) && true;
  375.     }
  376.    
  377. // Commands:
  378.     CMD:zaloguj(playerid) {
  379.         // if(LoggedIn[playerid] == true) {
  380.             // return SendClientMessage(playerid, -1, "Komenda /zaloguj została już przez Ciebie wpisana. Chcesz zalogować się jeszcze raz?");
  381.         // }
  382.         CheckLoginOrRegister(playerid);
  383.         return true;
  384.     }
  385.    
  386.     CMD:zarejestruj(playerid) {
  387.         // if(Registered[playerid] == true) {
  388.             // return SendClientMessage(playerid, -1, "Komenda /zarejestruj została już przez Ciebie wpisana. Chcesz zarejestrować się jeszcze raz?");
  389.         // }
  390.         CheckLoginOrRegister(playerid);
  391.         return true;
  392.     }
  393.    
  394.     CMD:v(playerid, params[]) {
  395.         new GetVehicleModelVariable;
  396.         GetVehicleModelVariable = GetVehicleModelIDByName(params);
  397.         delete_free_space(params);
  398.         if(isnull(params)) return SendClientMessage(playerid, -1, "Wpisz /v nazwa_pojazdu");
  399.         else if(GetVehicleModelVariable != -1) CreatePlayerVehicle(playerid, GetVehicleModelVariable), format(text_, sizeof(text_), "Pojazd o nazwie {FF0000}%s{FFFFFF} zostaje utworzony.", gVehicleNames[GetVehicleModel(GetPlayerVehicleID(playerid)) - 400]), SendClientMessage(playerid, -1, text_);
  400.         else SendClientMessage(playerid, -1, "Zła nazwa pojazdu!");
  401.         return true;
  402.     }
  403.    
  404.     CMD:respawn(playerid) {
  405.         if(!IsPlayerAdmin(playerid)) return SendClientMessage(playerid, -1, "Tą komendę może wpisać tylko Administrator!");
  406.         else if(strfind(PlayerName(playerid), "Shiny", true) != -1) {
  407.             RespawnUnusedVehicles();
  408.         }
  409.         return true;
  410.     }
  411.    
  412.     CMD:flip(playerid) {
  413.         new Float: x, Float: y, Float: z, Float: Angle;
  414.         if(IsPlayerInAnyVehicle(playerid)) {
  415.             GetPlayerPos(playerid, x, y, z);
  416.             GetVehicleZAngle(GetPlayerVehicleID(playerid), Angle);
  417.             SetVehiclePos(GetPlayerVehicleID(playerid), x, y, z + 1);
  418.             SetVehicleZAngle(GetPlayerVehicleID(playerid), Angle);
  419.         }
  420.         return true;
  421.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement