/*----------------------------------------------------------------------------*- ============================= Y Sever Includes - Class Core =============================Description: Allows greater control over classes so not everyone has every class. Uses a form of compression for locations.Legal: Copyright (C) 2007 Alex "Y_Less" Cole This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.Version: 0.1Changelog: 02/01/08: First '08 edit - Fixed minus numbers in spawn points. 18/11/07: Improved location compression to allow larger areas. Moved position code to Class_OnPlayerSpawn to reduce overhead. 10/10/07: Fixed spawn data problem. 31/08/07: Added cheap master system - YSI_SLAVE_CLASSs can't be master. 05/08/07: Fixed a few bugs with repeated selection. 04/08/07: First version.Functions: Public: Class_AddRemote - Adds a class to the remote master. Class_Remote - Updates settings remotely. Core: Class_Class - Sets up the system. Class_OnPlayerRequestSpawn - Called when a player requests a spawn. Class_OnPlayerRequestClass - Called when a player requests a class. Class_OnPlayerConnect - Called when a player connects. Stock: Class_Delete - Removes a class. Class_SetPlayer - Sets whether or not a player can use a class. Class_Disable - Disables a class. Class_Enable - Enables a disabled class. Class_AddForGroup - Adds a class to the system for only one group. Class_Add - Adds a class to the system. Class_AddEx - Adds a class to the system with group selection and setting. Class_AddWithGroupSet - Adds a class and sets their group on selection. Class_AllowReselection - Allows or disallows people to return to reselect a class. Class_RequireSpawnLogin - Require people to login before spawning. Class_RequireSelectionLogin - Require people to login before selecting. Class_RequireSelectionReg - Require people to register before selecting. Class_RequireSpawnReg - Require people to register before spawning. Static: Class_AddClass - Adds a class, wrapped by API and remote functions. Inline: Class_IsActive - Checks a class is active. Class_Enabled - Checks a class is enabled. Class_IsValid - Checks a class is valid. Class_X - Gets a classes x position. Class_Y - Gets a classes y position. Class_Z - Gets a classes z position. Class_A - Gets a classes angle. Class_Skin - Gets a classes skin. API: -Callbacks: -Definitions: MAX_CLASSES - Maximum number of classes storeable by the system. CLASS_LEFT - Flag for last internal class viewed. CLASS_MIDDLE - Flag for last internal class viewed. CLASS_RIGHT - Flag for last internal class viewed.Enums: e_CLASS_FLAGS - Small data for individual classes. E_CLASS - Class data structure.Macros: -Tags: -Variables: Global: - Static: YSI_g_sClasses - Data for classes. YSI_g_sPlayerClass - Player's current classes. YSI_g_sLeft - Handle for the first internal class. YSI_g_sMiddle - Handle for the second internal class. YSI_g_sRight - Handle for the third internal class. YSI_g_sClassCount - Number of classes stored.Commands: -Compile options: -Operators: --*----------------------------------------------------------------------------*/#if !defined MAX_CLASSES #define MAX_CLASSES 256#endif#if !defined MAX_CLASS_SPAWN_WEAPONS #define MAX_CLASS_SPAWN_WEAPONS (13)#endif#if !defined WEAPON_ARMOUR #define WEAPON_ARMOUR (100)#endifenum e_CLASS_FLAGS (<<= 1){ e_CLASS_FLAGS_SKIN = 0x0000FFFF, e_CLASS_FLAGS_ACTIVE = 0x01000000, e_CLASS_FLAGS_ENABLED, e_CLASS_FLAGS_DEFAULT}enum e_CLASS_PLAYER{ e_CLASS_PLAYER_CLASS = 0x00FFFFFF, e_CLASS_PLAYER_SPAWN = 0x01000000, e_CLASS_PLAYER_REFUSE = 0x02000000, e_CLASS_PLAYER_RIGHT = 0x10000000, e_CLASS_PLAYER_MIDDLE = 0x20000000, e_CLASS_PLAYER_LEFT = 0x40000000, e_CLASS_PLAYER_MASK = 0x70000000}enum E_CLASS{ e_CLASS_FLAGS:E_CLASS_FLAGS, Float:E_CLASS_X, Float:E_CLASS_Y, Float:E_CLASS_Z, Float:E_CLASS_A, E_CLASS_WEAPONS[13], #if defined _YSI_SYSTEM_GROUPS E_CLASS_GROUP, #endif Bit:E_CLASS_PLAYERS[PLAYER_BIT_ARRAY]}enum e_CLASS_OPTION (<<= 1){ e_CLASS_OPTION_NORE = 1, e_CLASS_OPTION_LOGIN_SELECT, e_CLASS_OPTION_LOGIN_SPAWN, e_CLASS_OPTION_REG_SELECT, e_CLASS_OPTION_REG_SPAWN, e_CLASS_OPTION_HAS_RC_CALLBACK, e_CLASS_OPTION_HAS_RS_CALLBACK}enum{ E_CLASS_INS_UNSET_FLAG, E_CLASS_INS_SET_FLAG, E_CLASS_INS_DELETE, E_CLASS_INS_ADD_PLAYER, E_CLASS_INS_REMOVE_PLAYER, E_CLASS_INS_ALLOW_RESELECT, E_CLASS_INS_LSE, E_CLASS_INS_LSP, E_CLASS_INS_RSE, E_CLASS_INS_RSP, E_CLASS_INT_SET_CLASS}#if defined FILTERSCRIPT #if !defined YSI_SLAVE_CLASS #define YSI_SLAVE_CLASS #endif#else #if defined YSI_SLAVE_CLASS #undef YSI_SLAVE_CLASS #endif#endif#if !defined YSI_SLAVE_CLASS static YSI_g_sClasses[MAX_CLASSES][E_CLASS], e_CLASS_PLAYER:YSI_g_sPlayerClass[MAX_PLAYERS], YSI_g_sLeft, YSI_g_sMiddle, YSI_g_sRight, YSI_g_sClassCount, e_CLASS_OPTION:YSI_g_sClassOptions; forward Class_AddRemote(skin, Float:x, Float:y, Float:z, Float:a, weapons[], count, forgroup, asgroup); forward Class_Remote(ident, info, instruction); forward Class_DelaySpawn(playerid);#endif/*----------------------------------------------------------------------------*-Function: Class_IsActiveParams: classid - Class to check.Return: -Notes: Checks if a class is currently in use.-*----------------------------------------------------------------------------*/#define Class_IsActive(%1) \ (YSI_g_sClasses[(%1)][E_CLASS_FLAGS] & e_CLASS_FLAGS_ACTIVE)/*----------------------------------------------------------------------------*-Function: Class_EnabledParams: classid - Class to check.Return: -Notes: Checks if a class is currently available for viewing.-*----------------------------------------------------------------------------*/#define Class_Enabled(%1) \ (YSI_g_sClasses[(%1)][E_CLASS_FLAGS] & e_CLASS_FLAGS_ENABLED)/*----------------------------------------------------------------------------*-Function: Class_IsValidParams: classid - Class to check.Return: -Notes: Checks if a number is a valid classid and active.-*----------------------------------------------------------------------------*/#define Class_IsValid(%1) \ ((%1) >= 0 && (%1) < MAX_CLASSES && Class_IsActive((%1)))/*----------------------------------------------------------------------------*-Function: Class_XParams: classid - Class to get X location for.Return: -Notes: --*----------------------------------------------------------------------------*/#define Class_X(%1) \ YSI_g_sClasses[(%1)][E_CLASS_X] //(float(YSI_g_sClasses[(%1)][E_CLASS_XY] >> 16) / 10.0)/*----------------------------------------------------------------------------*-Function: Class_YParams: classid - Class to get Y location for.Return: -Notes: --*----------------------------------------------------------------------------*/#define Class_Y(%1) \ YSI_g_sClasses[(%1)][E_CLASS_Y] //(float((YSI_g_sClasses[(%1)][E_CLASS_XY] & 0x7FFF) | ((YSI_g_sClasses[(%1)][E_CLASS_XY] & 0x8000) ? (0xFFFF8000) : (0))) / 10.0)/*----------------------------------------------------------------------------*-Function: Class_ZParams: classid - Class to get Z location for.Return: -Notes: --*----------------------------------------------------------------------------*/#define Class_Z(%1) \ YSI_g_sClasses[(%1)][E_CLASS_Z] //(float(YSI_g_sClasses[(%1)][E_CLASS_ZA] >> 16) / 10.0)/*----------------------------------------------------------------------------*-Function: Class_AParams: classid - Class to get angle for.Return: -Notes: --*----------------------------------------------------------------------------*/#define Class_A(%1) \ YSI_g_sClasses[(%1)][E_CLASS_A] //(float((YSI_g_sClasses[(%1)][E_CLASS_ZA] & 0x7FFF) | (YSI_g_sClasses[(%1)][E_CLASS_ZA] & 0x8000) ? (0xFFFF8000) : (0)) / 10.0)/*----------------------------------------------------------------------------*-Function: Class_SkinParams: classid - Class to get skin for.Return: -Notes: --*----------------------------------------------------------------------------*/#define Class_Skin(%1) \ (YSI_g_sClasses[(%1)][E_CLASS_FLAGS] & e_CLASS_FLAGS_SKIN)/*----------------------------------------------------------------------------*-Function: Class_ClassParams: -Return: -Notes: Creates three real player classes so you can scroll correctly with the direction being detected.-*----------------------------------------------------------------------------*/#if !defined YSI_SLAVE_CLASS Class_Class() { YSI_g_sLeft = AddPlayerClass(0, 1958.0, 1343.0, 15.0, 269.0, 0, 0, 0, 0, 0, 0); YSI_g_sMiddle = AddPlayerClass(0, 1958.0, 1343.0, 15.0, 269.0, 0, 0, 0, 0, 0, 0); YSI_g_sRight = AddPlayerClass(0, 1958.0, 1343.0, 15.0, 269.0, 0, 0, 0, 0, 0, 0); YSI_g_sClassOptions = ((funcidx("OnPlayerRequestClassExGM") == -1) ? (e_CLASS_OPTION:0) : (e_CLASS_OPTION_HAS_RC_CALLBACK)) | ((funcidx("OnPlayerRequestSpawnExGM") == -1) ? (e_CLASS_OPTION:0) : (e_CLASS_OPTION_HAS_RS_CALLBACK)); return 1; }#endif/*----------------------------------------------------------------------------*-Function: Class_OnPlayerLoginParams: playerid - Player who requested a class. yid - Their YSI id.Return: -Notes: --*----------------------------------------------------------------------------*/#if !defined YSI_SLAVE_CLASS Class_OnPlayerLogin(playerid, yid) { if (YSI_g_sPlayerClass[playerid] & e_CLASS_PLAYER_REFUSE) { YSI_g_sPlayerClass[playerid] = e_CLASS_PLAYER_CLASS; TogglePlayerControllable(playerid, 1); ForceClassSelection(playerid); SetPlayerHealth(playerid, 0.0); } return 1; #pragma unused yid }#endif/*----------------------------------------------------------------------------*-Function: Class_OnPlayerRequestClassParams: playerid - Player who requested a class. class - Class they requested.Return: -Notes: The input is one of the three real classes used to detect selected direction of alteration. Scans for a class the player is allowed to use and hot swaps it out. Uses SetPlayerSkin AND SetSpawnInfo to combat bugs with calling this from OnPlayerRequestSpawn (e.g. the example team script). Calls OnPlayerRequestClassEx with the current internal class not the real one.-*----------------------------------------------------------------------------*/#if !defined YSI_SLAVE_CLASS Class_OnPlayerRequestClass(playerid, class) { DBGP2("Class_OnPlayerRequestClass() start"); new playerclass = YSI_g_sPlayerClass[playerid], dir = 1; if ((YSI_g_sClassOptions & e_CLASS_OPTION_NORE) && (playerclass & _:e_CLASS_PLAYER_SPAWN)) { SpawnPlayer(playerid); return 0; } if ((YSI_g_sClassOptions & e_CLASS_OPTION_LOGIN_SELECT) && (!Player_IsLoggedIn(playerid))) { DBGP3("Class_OnPlayerRequestClass refuse"); //SpawnPlayer(playerid); //TogglePlayerControllable(playerid, 0); SetTimerEx("Class_DelaySpawn", 1, 0, "i", playerid); YSI_g_sPlayerClass[playerid] |= e_CLASS_PLAYER_REFUSE; return 1; } switch (playerclass & _:e_CLASS_PLAYER_MASK) { case e_CLASS_PLAYER_RIGHT: { if (class == YSI_g_sMiddle) { dir = -1; } } case e_CLASS_PLAYER_MIDDLE: { if (class == YSI_g_sLeft) { dir = -1; } } default: { if (class == YSI_g_sRight) { dir = -1; } } } if (playerclass & _:e_CLASS_PLAYER_SPAWN) { playerclass = _:e_CLASS_PLAYER_CLASS; } else { playerclass &= _:e_CLASS_PLAYER_CLASS; } if (!YSI_g_sClassCount) { SetSpawnInfo(playerid, NO_TEAM, 0, 1958.0, 1343.0, 15.0, 269.0, 0, 0, 0, 0, 0, 0); SetPlayerSkin(playerid, 0); DBGP1("*** Internal Error! No YSI classes found"); } else { new old = playerclass; do { playerclass += dir; DBGP4("Class_OnPlayerRequestClass() playerclass: %d", playerclass); if (playerclass < 0) playerclass = YSI_g_sClassCount - 1; if (playerclass >= YSI_g_sClassCount) playerclass = 0; } while (playerclass != old && (!Class_Enabled(playerclass) || !Bit_Get(YSI_g_sClasses[playerclass][E_CLASS_PLAYERS], playerid))); DBGP4("Class_OnPlayerRequestClass() selected: %d", playerclass); new weapon1 = YSI_g_sClasses[playerclass][E_CLASS_WEAPONS][0], weapon2 = YSI_g_sClasses[playerclass][E_CLASS_WEAPONS][1], weapon3 = YSI_g_sClasses[playerclass][E_CLASS_WEAPONS][2]; SetSpawnInfo(playerid, NO_TEAM, 0, 1958.0, 1343.0, 15.0, 269.0, weapon1 & 0xFF, weapon1 >> 8, weapon2 & 0xFF, weapon2 >> 8, weapon3 & 0xFF, weapon3 >> 8); SetPlayerSkin(playerid, Class_Skin(playerclass)); YSI_g_sPlayerClass[playerid] = e_CLASS_PLAYER:playerclass; if (class == YSI_g_sMiddle) YSI_g_sPlayerClass[playerid] |= e_CLASS_PLAYER_MIDDLE; else if (class == YSI_g_sLeft) YSI_g_sPlayerClass[playerid] |= e_CLASS_PLAYER_LEFT; else if (class == YSI_g_sRight) YSI_g_sPlayerClass[playerid] |= e_CLASS_PLAYER_RIGHT; } DBGP2("Class_OnPlayerRequestClass() end"); CallRemoteFunction("OnPlayerRequestClassExFS", "ii", playerid, playerclass); if (YSI_g_sClassOptions & e_CLASS_OPTION_HAS_RC_CALLBACK) { return CallRemoteFunction("OnPlayerRequestClassExGM", "ii", playerid, playerclass); } else { return 1; } } /*----------------------------------------------------------------------------*- Function: Class_DelaySpawn Params: playerid - Player who joined. Return: - Notes: Spawns a player after first class selection to avoid problems. -*----------------------------------------------------------------------------*/ public Class_DelaySpawn(playerid) { TogglePlayerControllable(playerid, 0); SpawnPlayer(playerid); CallRemoteFunction("OnPlayerSelectRefusal", "i", playerid); }#endif/*----------------------------------------------------------------------------*-Function: Class_OnPlayerConnectParams: playerid - Player who joined.Return: -Notes: Resets the player's current class.-*----------------------------------------------------------------------------*/#if !defined YSI_SLAVE_CLASS Class_OnPlayerConnect(playerid) { YSI_g_sPlayerClass[playerid] = e_CLASS_PLAYER_CLASS; return 1; }#endif/*----------------------------------------------------------------------------*-Function: Class_OnPlayerRequestSpawnParams: playerid - Player who selected a spawn.Return: -Notes: Has inbuilt protection for a bug where selections aren't correctly debounced so you can press shift twice at once which can mess up some scripts (e.g. the example team selection script). Calls OnPlayerRequestSpawnEx with an additional class parameter.-*----------------------------------------------------------------------------*/#if !defined YSI_SLAVE_CLASS Class_OnPlayerRequestSpawn(playerid) { if (YSI_g_sClassCount) { static sLastRefuse[MAX_PLAYERS]; new playerclass = _:(YSI_g_sPlayerClass[playerid] & e_CLASS_PLAYER_CLASS); if (!Class_Enabled(playerclass) || !Bit_Get(YSI_g_sClasses[playerclass][E_CLASS_PLAYERS], playerid)) return 0; SetSpawnInfo(playerid, NO_TEAM, Class_Skin(playerclass), Class_X(playerclass), Class_Y(playerclass), Class_Z(playerclass), Class_A(playerclass), 0, 0, 0, 0, 0, 0); new time = GetTickCount(), ret; if ((time - sLastRefuse[playerid]) >= 1000) { CallRemoteFunction("OnPlayerRequestSpawnExFS", "ii", playerid, playerclass); if (YSI_g_sClassOptions & e_CLASS_OPTION_HAS_RS_CALLBACK) { ret = CallLocalFunction("OnPlayerRequestSpawnExGM", "ii", playerid, playerclass); } else { ret = 1; } } DBGP4("Class_OnPlayerRequestSpawn() return: %d", ret); if (ret) { #if defined _YSI_SYSTEM_GROUPS new newgroup = YSI_g_sClasses[playerclass][E_CLASS_GROUP]; DBGP4("Class_OnPlayerRequestSpawn() newgroup: %d", newgroup); if (newgroup != -1) Group_AddPlayer(newgroup, playerid); #endif if (ret == 1) { if (YSI_g_sClassOptions & e_CLASS_OPTION_LOGIN_SPAWN && !Player_IsLoggedIn(playerid)) { CallRemoteFunction("OnPlayerSpawnRefusal", "i", playerid); return 0; } else { return 1; } } else if(ret == -1) { YSI_g_sPlayerClass[playerid] |= e_CLASS_PLAYER_CLASS; Class_OnPlayerRequestClass(playerid, YSI_g_sLeft); } } sLastRefuse[playerid] = time; return 0; } return 1; }#endif/*----------------------------------------------------------------------------*-Function: Class_OnPlayerSpawnParams: playerid - Player who spawned.Return: -Notes: Sets a player's position based on skin.-*----------------------------------------------------------------------------*/#if !defined YSI_SLAVE_CLASS Class_OnPlayerSpawn(playerid) { YSI_g_sPlayerClass[playerid] |= e_CLASS_PLAYER_SPAWN; new playerclass = _:(YSI_g_sPlayerClass[playerid] & e_CLASS_PLAYER_CLASS); for (new i = 12; i >= 0; i--) { new weapon = YSI_g_sClasses[playerclass][E_CLASS_WEAPONS][i]; if ((weapon & 0xFF) == WEAPON_ARMOUR) SetPlayerArmour(playerid, 100.0); else if (weapon) GivePlayerWeapon(playerid, weapon & 0xFF, weapon >> 8); } return 0; }#endif/*----------------------------------------------------------------------------*-Function: Class_AddParams: skin - Skin of the class. Float:x - X spawn location. Float:y - Y spawn location. Float:z - Z spawn location. Float:a - A spawn location. ... - Spawn weapons and ammo (weapon then ammo)Return: -Notes: Pretty much AddPlayerClass but allows greater control over the classes. Now has infinate (13) spawn weapons.-*----------------------------------------------------------------------------*/stock Class_Add(skin, Float:x, Float:y, Float:z, Float:a, ...){ new num = numargs(), weap = 5, slot, weapons[13]; if (!(num & 0x01)) num--; while (weap < num && slot < 13) { weapons[slot++] = (getarg(weap++) & 0xFF) | (getarg(weap++) << 8); } #if !defined YSI_SLAVE_CLASS return Class_AddClass(skin, x, y, z, a, weapons, slot, -1, -1); #else CallRemoteFunction("Class_AddRemote", "iffffaiii", skin, x, y, z, a, weapons, slot, -1, -1); return getproperty(0, "LReqClass"); #endif}/*----------------------------------------------------------------------------*-Function: Class_AddExParams: forgroup - Group that can use the skin. setgroup - Group to add the player to on selection. skin - Skin of the class. Float:x - X spawn location. Float:y - Y spawn location. Float:z - Z spawn location. Float:a - A spawn location. ... - Spawn weapons and ammo (weapon then ammo)Return: -Notes: Pretty much AddPlayerClass but allows greater control over the classes. Now has infinate (13) spawn weapons.-*----------------------------------------------------------------------------*/stock Class_AddEx(forgroup, setgroup, skin, Float:x, Float:y, Float:z, Float:a, ...){ new num = numargs(), weap = 7, slot, weapons[13]; if (!(num & 0x01)) num--; while (weap < num && slot < 13) { weapons[slot++] = (getarg(weap++) & 0xFF) | (getarg(weap++) << 8); } #if !defined YSI_SLAVE_CLASS return Class_AddClass(skin, x, y, z, a, weapons, slot, forgroup, setgroup); #else CallRemoteFunction("Class_AddRemote", "iffffaiii", skin, x, y, z, a, weapons, slot, forgroup, setgroup); return getproperty(0, "LReqClass"); #endif}/*----------------------------------------------------------------------------*-Function: Class_AddClassParams: skin - Skin of the class. Float:x - X spawn location. Float:y - Y spawn location. Float:z - Z spawn location. Float:a - A spawn location. weapons[] - Array of spawn weapon data. count - Number of weapons added. forgroup - Group that can use the class. asgroup - Group to assign people to with this class.Return: -Notes: Does the hard work.-*----------------------------------------------------------------------------*/#if !defined YSI_SLAVE_CLASS stock Class_AddClass(skin, Float:x, Float:y, Float:z, Float:a, weapons[], count, forgroup, asgroup) { new i; while (i < MAX_CLASSES) { if (!Class_IsActive(i)) break; i++; } if (i == MAX_CLASSES) return -1; YSI_g_sClasses[i][E_CLASS_FLAGS] = e_CLASS_FLAGS_ACTIVE | e_CLASS_FLAGS:skin | e_CLASS_FLAGS_ENABLED; YSI_g_sClasses[i][E_CLASS_X] = x; YSI_g_sClasses[i][E_CLASS_Y] = y; YSI_g_sClasses[i][E_CLASS_Z] = z; YSI_g_sClasses[i][E_CLASS_A] = a; new j; while (j < count) { YSI_g_sClasses[i][E_CLASS_WEAPONS][j] = weapons[j]; j++; } while (j < 13) { YSI_g_sClasses[i][E_CLASS_WEAPONS][j] = 0; j++; } #if defined _YSI_SYSTEM_GROUPS YSI_g_sClasses[i][E_CLASS_GROUP] = asgroup; if (forgroup == -1) { Group_SetDefaultClass(i, 1); } else { Group_SetDefaultClass(i, 0); Group_SetClass(forgroup, i, 1); } #else #pragma unused forgroup, asgroup #endif YSI_g_sClassCount++; setproperty(0, "LReqClass", i); return i; }#endif/*----------------------------------------------------------------------------*-Function: Class_AddRemoteParams: skin - Skin of the class. Float:x - X spawn location. Float:y - Y spawn location. Float:z - Z spawn location. Float:a - A spawn location. weapons - Weapon and ammo data. count - Number of weapons. forgroup - Group that can use the class. asgroup - Group to assign people to with this class.Return: -Notes: Remote wrapper for all class add systems.-*----------------------------------------------------------------------------*/#if !defined YSI_SLAVE_CLASS public Class_AddRemote(skin, Float:x, Float:y, Float:z, Float:a, weapons[], count, forgroup, asgroup) { return Class_AddClass(skin, x, y, z, a, weapons, count, forgroup, asgroup); }#endif/*----------------------------------------------------------------------------*-Function: Class_AddForGroupParams: group - Group to allow to use the class. skin - Skin of the class. Float:x - X spawn location. Float:y - Y spawn location. Float:z - Z spawn location. Float:a - A spawn location. ... - Weapon data.Return: -Notes: Adds a class only people in the specified group can use.-*----------------------------------------------------------------------------*/#if defined _YSI_SYSTEM_GROUPS stock Class_AddForGroup(group, skin, Float:x, Float:y, Float:z, Float:a, ...) { new num = numargs(), weap = 6, slot, weapons[13]; if (num & 0x01) num--; while (weap < num && slot < 13) { weapons[slot++] = (getarg(weap++) & 0xFF) | (getarg(weap++) << 8); } #if !defined YSI_SLAVE_CLASS return Class_AddClass(skin, x, y, z, a, weapons, slot, group, -1); #else CallRemoteFunction("Class_AddRemote", "iffffaiii", skin, x, y, z, a, weapons, slot, group, -1); return getproperty(0, "LReqClass"); #endif }#else #define Class_AddForGroup(%1,%2) \ Class_Add(%2)#endif/*----------------------------------------------------------------------------*-Function: Class_AddWithGroupSetParams: group - Group to make players who use this group. skin - Skin of the class. Float:x - X spawn location. Float:y - Y spawn location. Float:z - Z spawn location. Float:a - A spawn location. ... - Spawn weapons.Return: -Notes: Adds a class which puts you in the specified group when selected.-*----------------------------------------------------------------------------*/#if defined _YSI_SYSTEM_GROUPS stock Class_AddWithGroupSet(group, skin, Float:x, Float:y, Float:z, Float:a, ...) { new num = numargs(), weap = 6, slot, weapons[13]; if (num & 0x01) num--; while (weap < num && slot < 13) { weapons[slot++] = (getarg(weap++) & 0xFF) | (getarg(weap++) << 8); } #if !defined YSI_SLAVE_CLASS return Class_AddClass(skin, x, y, z, a, weapons, slot, -1, group); #else CallRemoteFunction("Class_AddRemote", "iffffaiii", skin, x, y, z, a, weapons, slot, -1, group); return getproperty(0, "LReqClass"); #endif }#else #define Class_AddWithGroupSet(%1,%2) \ Class_Add(%2)#endif/*----------------------------------------------------------------------------*-Function: Class_EnableParams: classid - Class to re-enable.Return: -Notes: Reallow use of this class.-*----------------------------------------------------------------------------*/stock Class_Enable(classid){ #if !defined YSI_SLAVE_CLASS if (Class_IsValid(classid)) YSI_g_sClasses[classid][E_CLASS_FLAGS] |= e_CLASS_FLAGS_ENABLED; #else CallRemoteFunction("Class_Remote", "iii", classid, _:e_CLASS_FLAGS_ENABLED, E_CLASS_INS_SET_FLAG); #endif}/*----------------------------------------------------------------------------*-Function: Class_DisableParams: classid - Class to disable.Return: -Notes: Stop people being able to use this class.-*----------------------------------------------------------------------------*/stock Class_Disable(classid){ #if !defined YSI_SLAVE_CLASS if (Class_IsValid(classid)) YSI_g_sClasses[classid][E_CLASS_FLAGS] &= ~e_CLASS_FLAGS_ENABLED; #else CallRemoteFunction("Class_Remote", "iii", classid, _:e_CLASS_FLAGS_ENABLED, E_CLASS_INS_UNSET_FLAG); #endif}/*----------------------------------------------------------------------------*-Function: Class_RemoteParams: allow - Wether or not to allow changing class.Return: -Notes: Sets wether or not people can change class after first spawning.-*----------------------------------------------------------------------------*/stock Class_AllowReselection(allow){ #if !defined YSI_SLAVE_CLASS if (allow) YSI_g_sClassOptions &= ~e_CLASS_OPTION_NORE; else YSI_g_sClassOptions |= e_CLASS_OPTION_NORE; #else CallRemoteFunction("Class_Remote", "iii", allow, 0, E_CLASS_INS_ALLOW_RESELECT); #endif}/*----------------------------------------------------------------------------*-Function: Class_RemoteParams: ident - Item to perform action on. info - Data for action. instruction - Action to perform.Return: -Notes: Provides remote interaction to the script.-*----------------------------------------------------------------------------*/#if !defined YSI_SLAVE_CLASS public Class_Remote(ident, info, instruction) { switch (instruction) { case E_CLASS_INS_UNSET_FLAG: { if (Class_IsValid(ident)) YSI_g_sClasses[ident][E_CLASS_FLAGS] |= e_CLASS_FLAGS:info; } case E_CLASS_INS_SET_FLAG: { if (Class_IsValid(ident)) YSI_g_sClasses[ident][E_CLASS_FLAGS] &= ~e_CLASS_FLAGS:info; } case E_CLASS_INS_DELETE: { if (Class_IsValid(ident)) YSI_g_sClasses[ident][E_CLASS_FLAGS] = e_CLASS_FLAGS:0; } case E_CLASS_INS_ADD_PLAYER: { if (Class_IsValid(ident) && info >= 0 && info < MAX_PLAYERS) Bit_Set(YSI_g_sClasses[ident][E_CLASS_PLAYERS], info, 1, PLAYER_BIT_ARRAY); } case E_CLASS_INS_REMOVE_PLAYER: { if (Class_IsValid(ident) && info >= 0 && info < MAX_PLAYERS) Bit_Set(YSI_g_sClasses[ident][E_CLASS_PLAYERS], info, 0, PLAYER_BIT_ARRAY); } case E_CLASS_INS_ALLOW_RESELECT: { if (ident) YSI_g_sClassOptions &= ~e_CLASS_OPTION_NORE; else YSI_g_sClassOptions |= e_CLASS_OPTION_NORE; } case E_CLASS_INS_LSE: { if (ident) YSI_g_sClassOptions |= e_CLASS_OPTION_LOGIN_SELECT; else YSI_g_sClassOptions &= ~e_CLASS_OPTION_LOGIN_SELECT; } case E_CLASS_INS_LSP: { if (ident) YSI_g_sClassOptions |= e_CLASS_OPTION_LOGIN_SPAWN; else YSI_g_sClassOptions &= ~e_CLASS_OPTION_LOGIN_SPAWN; } case E_CLASS_INS_RSE: { if (ident) YSI_g_sClassOptions |= e_CLASS_OPTION_REG_SELECT; else YSI_g_sClassOptions &= ~e_CLASS_OPTION_REG_SELECT; } case E_CLASS_INS_RSP: { if (ident) YSI_g_sClassOptions |= e_CLASS_OPTION_REG_SPAWN; else YSI_g_sClassOptions &= ~e_CLASS_OPTION_REG_SPAWN; } } }#endif/*----------------------------------------------------------------------------*-Function: Class_DeleteParams: classid - Class to delete.Return: -Notes: Completely removes a class from the system.-*----------------------------------------------------------------------------*/stock Class_Delete(classid){ #if !defined YSI_SLAVE_CLASS if (Class_IsValid(classid)) YSI_g_sClasses[classid][E_CLASS_FLAGS] = e_CLASS_FLAGS:0; #else CallRemoteFunction("Class_Remote", "iii", classid, 0, E_CLASS_INS_DELETE); #endif}/*----------------------------------------------------------------------------*-Function: Class_SetPlayerParams: classid - Class to set permissions for. playerid - Player to set for. set - Whether or not they can use this class.Return: -Notes: --*----------------------------------------------------------------------------*/stock Class_SetPlayer(classid, playerid, set){ #if !defined YSI_SLAVE_CLASS if (Class_IsValid(classid) && playerid >= 0 && playerid < MAX_PLAYERS) Bit_Set(YSI_g_sClasses[classid][E_CLASS_PLAYERS], playerid, set, PLAYER_BIT_ARRAY); #else if (set) CallRemoteFunction("Class_Remote", "iii", classid, playerid, E_CLASS_INS_ADD_PLAYER); else CallRemoteFunction("Class_Remote", "iii", classid, playerid, E_CLASS_INS_REMOVE_PLAYER); #endif}/*----------------------------------------------------------------------------*-Function: Class_RequireSelectionLoginParams: allow - Wether or not people must login.Return: -Notes: Don't let registered people select a class till they log in.-*----------------------------------------------------------------------------*/stock Class_RequireSelectionLogin(allow){ #if !defined YSI_SLAVE_CLASS if (allow) YSI_g_sClassOptions |= e_CLASS_OPTION_LOGIN_SELECT; else YSI_g_sClassOptions &= ~e_CLASS_OPTION_LOGIN_SELECT; #else CallRemoteFunction("Class_Remote", "iii", allow, 0, E_CLASS_INS_LSE); #endif}/*----------------------------------------------------------------------------*-Function: Class_RequireSpawnLoginParams: allow - Wether or not people must login.Return: -Notes: Don't let registered people spawn till they log in.-*----------------------------------------------------------------------------*/stock Class_RequireSpawnLogin(allow){ #if !defined YSI_SLAVE_CLASS if (allow) YSI_g_sClassOptions |= e_CLASS_OPTION_LOGIN_SPAWN; else YSI_g_sClassOptions &= ~e_CLASS_OPTION_LOGIN_SPAWN; #else CallRemoteFunction("Class_Remote", "iii", allow, 0, E_CLASS_INS_LSP); #endif}/*----------------------------------------------------------------------------*-Function: Class_RequireSelectionRegParams: allow - Wether or not people must register.Return: -Notes: Don't let people select a class till they register.-*----------------------------------------------------------------------------*/stock Class_RequireSelectionReg(allow){ #if !defined YSI_SLAVE_CLASS if (allow) YSI_g_sClassOptions |= e_CLASS_OPTION_REG_SELECT; else YSI_g_sClassOptions &= ~e_CLASS_OPTION_REG_SELECT; #else CallRemoteFunction("Class_Remote", "iii", allow, 0, E_CLASS_INS_RSE); #endif}/*----------------------------------------------------------------------------*-Function: Class_RequireSpawnRegParams: allow - Wether or not people must register.Return: -Notes: Don't let people spawn till they register.-*----------------------------------------------------------------------------*/stock Class_RequireSpawnReg(allow){ #if !defined YSI_SLAVE_CLASS if (allow) YSI_g_sClassOptions |= e_CLASS_OPTION_REG_SPAWN; else YSI_g_sClassOptions &= ~e_CLASS_OPTION_REG_SPAWN; #else CallRemoteFunction("Class_Remote", "iii", allow, 0, E_CLASS_INS_RSP); #endif}