Recoded weapon restrictions, and made new way of storing data. (Arrays)
* Removed ZMarket as an external plugin (to be integrated next commit) * Updated weapon configs, removed weapongroups.txt and moved weapons.txt to root zr config folder. * Moved offset finding to respective module, made new forward *OnOffsetsFound. * Updated weapons&hitgroups config file format to match playerclass.txt * Updated translations. * Recoded weapon restrict menu, commented out all zadmin options that don't quite work. * Added weaponammo module (not finished but existent) * Started zmarket module.
This commit is contained in:
@ -1,165 +0,0 @@
|
||||
/*
|
||||
* ============================================================================
|
||||
*
|
||||
* Zombie:Reloaded
|
||||
*
|
||||
* File: markethandler.inc
|
||||
* Type: Core
|
||||
* Description: Handles market (optional plugin) API, natives, and forwards.
|
||||
*
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Global variable set to true if market plugin is installed
|
||||
*/
|
||||
new bool:g_bMarket;
|
||||
|
||||
/**
|
||||
* Set global market flag variable
|
||||
*/
|
||||
MarketInit()
|
||||
{
|
||||
// Set market variable to true if market is installed.
|
||||
g_bMarket = LibraryExists("market");
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends market menu to client.
|
||||
*
|
||||
* @param client The client index.
|
||||
*/
|
||||
bool:ZMarketMenu(client)
|
||||
{
|
||||
// If market is disabled, then stop.
|
||||
if (!g_bMarket)
|
||||
{
|
||||
// Tell client market is disabled.
|
||||
TranslationPrintToChat(client, "Feature is disabled");
|
||||
return false;
|
||||
}
|
||||
|
||||
// If player is dead, then stop.
|
||||
if (!IsPlayerAlive(client))
|
||||
{
|
||||
// Tell player they must be alive.
|
||||
TranslationPrintToChat(client, "Must be alive");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check buyzone cvar to see if client has to be in a buyzone to use.
|
||||
new bool:buyzone = GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]);
|
||||
if (!ZMarketIsClientInBuyZone(client) && buyzone)
|
||||
{
|
||||
// Tell client they must be in a buyzone.
|
||||
TranslationPrintCenterText(client, "Market out of buyzone");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set translate target to client.
|
||||
SetGlobalTransTarget(client);
|
||||
|
||||
// Format title and rebuy lines.
|
||||
decl String:title[64];
|
||||
decl String:rebuy[64];
|
||||
|
||||
Format(title, sizeof(title), "%t\n ", "Market title");
|
||||
Format(rebuy, sizeof(rebuy), "%t\n ", "Market rebuy");
|
||||
|
||||
// Send market menu.
|
||||
Market_Send(client, title, rebuy);
|
||||
|
||||
// Successfully sent the market menu.
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a client is in a buyzone.
|
||||
*
|
||||
* @param client The client index.
|
||||
*/
|
||||
bool:ZMarketIsClientInBuyZone(client)
|
||||
{
|
||||
// Return if client is in buyzone.
|
||||
return bool:GetEntData(client, g_iToolsInBuyZone);
|
||||
}
|
||||
|
||||
/**
|
||||
* (Market) Forward called when a client selects a weapon from the market.
|
||||
*
|
||||
* @param client The client index.
|
||||
* @param weaponid The unique weapon ID used for market natives.
|
||||
* @return True to allow market to take over, false to block purchase.
|
||||
*/
|
||||
public bool:Market_OnWeaponSelected(client, String:weaponid[])
|
||||
{
|
||||
// If player is dead or weaponid is invalid, then stop.
|
||||
if (!weaponid[0] || !IsPlayerAlive(client))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// If player is a zombie, then stop.
|
||||
if (InfectIsClientInfected(client))
|
||||
{
|
||||
TranslationPrintToChat(client, "Zombie cant use weapon");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// If player is using the rebuy option then allow.
|
||||
if (StrEqual(weaponid, "rebuy"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
decl String:display[64];
|
||||
decl String:weapon[WEAPONS_MAX_LENGTH];
|
||||
new price;
|
||||
|
||||
// If the market plugin can't find info about the weapon, then stop.
|
||||
if (!Market_GetWeaponIDInfo(weaponid, display, weapon, price))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Strip "weapon_" from entity name.
|
||||
ReplaceString(weapon, sizeof(weapon), "weapon_", "");
|
||||
|
||||
// If the weapon is restricted, then stop.
|
||||
if (RestrictIsWeaponRestricted(weapon))
|
||||
{
|
||||
TranslationPrintToChat(client, "Weapon is restricted", weapon);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if buyzone cvar is enabled, and if the client is in a buyzone.
|
||||
new bool:buyzone = GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]);
|
||||
if (!ZMarketIsClientInBuyZone(client) && buyzone)
|
||||
{
|
||||
TranslationPrintCenterText(client, "Market out of buyzone");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Market) Forward called one frame after a client selects a weapon from the market.
|
||||
*
|
||||
* @param client The client index.
|
||||
* @param allowed True when the weapon was purchased successfully, false otherwise.
|
||||
*/
|
||||
public Market_PostOnWeaponSelected(client, &bool:allowed)
|
||||
{
|
||||
// If the purchase wasn't allowed, then stop.
|
||||
if (!allowed)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Resend market menu.
|
||||
ZMarketMenu(client);
|
||||
}
|
@ -11,28 +11,14 @@
|
||||
*/
|
||||
|
||||
/**
|
||||
* Weapons Menus
|
||||
* Array to store the client's current weapon type within menu.
|
||||
*/
|
||||
enum WeaponsMenu
|
||||
{
|
||||
Weapon,
|
||||
WeaponGroup,
|
||||
}
|
||||
|
||||
/**
|
||||
* Array to store the client's current weapon menu.
|
||||
*/
|
||||
new WeaponsMenu:curMenuWeapons[MAXPLAYERS + 1];
|
||||
|
||||
/**
|
||||
* Array to store the client's current weapon group menu.
|
||||
*/
|
||||
new String:curMenuGroup[WEAPONS_MAX_LENGTH][MAXPLAYERS + 1];
|
||||
new g_iCurWeaponType[MAXPLAYERS + 1];
|
||||
|
||||
/**
|
||||
* Sends main weapon menu to client.
|
||||
* @param client The client index.
|
||||
*/
|
||||
*/
|
||||
WeaponsMenuMain(client)
|
||||
{
|
||||
// Create menu handle.
|
||||
@ -42,17 +28,15 @@ WeaponsMenuMain(client)
|
||||
|
||||
SetMenuTitle(menu_weapons_main, "%t\n ", "Weapons menu main title");
|
||||
|
||||
decl String:toggleweaponrestriction[64];
|
||||
decl String:togglewgrouprestriction[64];
|
||||
decl String:restrict[64];
|
||||
decl String:zmarket[64];
|
||||
|
||||
Format(toggleweaponrestriction, sizeof(toggleweaponrestriction), "%t", "Weapons menu main toggle weapon restrict");
|
||||
Format(togglewgrouprestriction, sizeof(togglewgrouprestriction), "%t", "Weapons menu main toggle weapon group restrict");
|
||||
Format(restrict, sizeof(restrict), "%t", "Weapons menu main restrict");
|
||||
Format(zmarket, sizeof(zmarket), "%t", "Weapons menu main market");
|
||||
|
||||
AddMenuItem(menu_weapons_main, "toggleweaponrestriction", toggleweaponrestriction);
|
||||
AddMenuItem(menu_weapons_main, "togglewgrouprestriction", togglewgrouprestriction);
|
||||
AddMenuItem(menu_weapons_main, "zmarket", zmarket, MenuGetItemDraw(g_bMarket));
|
||||
// Draw items, make unselectable if module is disabled.
|
||||
AddMenuItem(menu_weapons_main, "restrict", restrict, MenuGetItemDraw(GetConVarBool(g_hCvarsList[CVAR_WEAPONS_RESTRICT])));
|
||||
AddMenuItem(menu_weapons_main, "zmarket", zmarket, MenuGetItemDraw(GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET])));
|
||||
|
||||
// Create a "Back" button to the weapons main menu.
|
||||
SetMenuExitBackButton(menu_weapons_main, true);
|
||||
@ -75,17 +59,15 @@ public WeaponsMenuMainHandle(Handle:menu_weapons_main, MenuAction:action, client
|
||||
{
|
||||
switch(slot)
|
||||
{
|
||||
// Weapons.
|
||||
case 0:
|
||||
{
|
||||
WeaponsMenuWeapons(client, Weapon);
|
||||
WeaponsMenuTypes(client);
|
||||
}
|
||||
// ZMarket.
|
||||
case 1:
|
||||
{
|
||||
WeaponsMenuWeapons(client, WeaponGroup);
|
||||
}
|
||||
case 2:
|
||||
{
|
||||
WeaponsMenuMarket(client);
|
||||
WeaponsMenuZMarket(client);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -95,7 +77,7 @@ public WeaponsMenuMainHandle(Handle:menu_weapons_main, MenuAction:action, client
|
||||
// Client hit "Back" button.
|
||||
if (slot == MenuCancel_ExitBack)
|
||||
{
|
||||
ZRAdminMenu(client);
|
||||
// Re-open admin menu.
|
||||
}
|
||||
}
|
||||
// Client hit "Exit" button.
|
||||
@ -106,159 +88,63 @@ public WeaponsMenuMainHandle(Handle:menu_weapons_main, MenuAction:action, client
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends weapon list menu to client.
|
||||
* Sends weapon type list to client.
|
||||
* @param client The client index.
|
||||
*/
|
||||
WeaponsMenuWeapons(client, WeaponsMenu:type)
|
||||
*/
|
||||
WeaponsMenuTypes(client)
|
||||
{
|
||||
// Set the current action client is performing on a weapon. (see enum WeaponsMenu)
|
||||
curMenuWeapons[client] = type;
|
||||
|
||||
// Create menu handle.
|
||||
new Handle:menu_weapons_weapons = CreateMenu(WeaponsMenuWeaponsHandle);
|
||||
new Handle:menu_weapons_types = CreateMenu(WeaponsMenuTypesHandle);
|
||||
|
||||
SetGlobalTransTarget(client);
|
||||
|
||||
// If client wants to perform an action on a single weapon, show weapon list.
|
||||
switch(curMenuWeapons[client])
|
||||
SetMenuTitle(menu_weapons_types, "%t\n ", "Weapons menu types title");
|
||||
|
||||
decl String:typename[WEAPONS_MAX_LENGTH];
|
||||
|
||||
// x = Array index.
|
||||
new size = GetArraySize(arrayWeaponTypes);
|
||||
for (new x = 0; x < size; x++)
|
||||
{
|
||||
case Weapon:
|
||||
{
|
||||
SetMenuTitle(menu_weapons_weapons, "%t\n ", "Weapons menu weapons weapon title");
|
||||
|
||||
decl String:weapon[WEAPONS_MAX_LENGTH];
|
||||
decl String:display[WEAPONS_MAX_LENGTH + 1];
|
||||
new Handle:arrayWeapons = INVALID_HANDLE;
|
||||
new size = WeaponsCreateWeaponArray(arrayWeapons);
|
||||
|
||||
// x = Array index.
|
||||
for (new x = 0; x < size; x++)
|
||||
{
|
||||
GetArrayString(arrayWeapons, x, weapon, sizeof(weapon));
|
||||
|
||||
strcopy(display, sizeof(display), weapon);
|
||||
|
||||
if (RestrictIsWeaponRestricted(weapon))
|
||||
{
|
||||
Format(display, sizeof(display), "%s*", weapon);
|
||||
}
|
||||
|
||||
// If weapon restriction is blocked for the menu, disable option.
|
||||
new bool:menu = WeaponsIsWeaponMenu(weapon);
|
||||
|
||||
if (menu)
|
||||
{
|
||||
AddMenuItem(menu_weapons_weapons, weapon, display);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddMenuItem(menu_weapons_weapons, weapon, display, ITEMDRAW_DISABLED);
|
||||
}
|
||||
}
|
||||
|
||||
// If there are no weapons, add an "(Empty)" line.
|
||||
if (size == 0)
|
||||
{
|
||||
decl String:empty[64];
|
||||
Format(empty, sizeof(empty), "%t", "Menu empty");
|
||||
|
||||
AddMenuItem(menu_weapons_weapons, "empty", empty, ITEMDRAW_DISABLED);
|
||||
}
|
||||
|
||||
// Kill the array handle.
|
||||
CloseHandle(arrayWeapons);
|
||||
}
|
||||
// If client wants to perform an action on a weapon group, show custom group list.
|
||||
case WeaponGroup:
|
||||
{
|
||||
SetMenuTitle(menu_weapons_weapons, "%t\n ", "Weapons menu weapons group title");
|
||||
|
||||
decl String:weapongroup[WEAPONS_MAX_LENGTH];
|
||||
decl String:display[WEAPONS_MAX_LENGTH + 2];
|
||||
new Handle:arrayWeaponGroups = INVALID_HANDLE;
|
||||
new size = RestrictCreateGroupArray(arrayWeaponGroups);
|
||||
|
||||
// x = Array index.
|
||||
for (new x = 0; x < size; x++)
|
||||
{
|
||||
GetArrayString(arrayWeaponGroups, x, weapongroup, sizeof(weapongroup));
|
||||
|
||||
strcopy(display, sizeof(display), weapongroup);
|
||||
|
||||
if (RestrictIsPartialRestricted(weapongroup))
|
||||
{
|
||||
Format(display, sizeof(display), "%s*", weapongroup);
|
||||
}
|
||||
else if (RestrictIsGroupRestricted(weapongroup))
|
||||
{
|
||||
Format(display, sizeof(display), "%s**", weapongroup);
|
||||
}
|
||||
|
||||
AddMenuItem(menu_weapons_weapons, weapongroup, display);
|
||||
}
|
||||
|
||||
// If there are no weapons, add an "(Empty)" line.
|
||||
if (size == 0)
|
||||
{
|
||||
decl String:empty[64];
|
||||
Format(empty, sizeof(empty), "%t", "Menu empty");
|
||||
|
||||
AddMenuItem(menu_weapons_weapons, "empty", empty, ITEMDRAW_DISABLED);
|
||||
}
|
||||
|
||||
// Kill the array handle
|
||||
CloseHandle(arrayWeaponGroups);
|
||||
}
|
||||
// Get name of type.
|
||||
RestrictWeaponTypeGetName(x, typename, sizeof(typename));
|
||||
|
||||
// Add item to menu.
|
||||
AddMenuItem(menu_weapons_types, typename, typename);
|
||||
}
|
||||
|
||||
SetMenuExitBackButton(menu_weapons_weapons, true);
|
||||
// If there are no weapons, add an "(Empty)" line.
|
||||
if (size == 0)
|
||||
{
|
||||
decl String:empty[64];
|
||||
Format(empty, sizeof(empty), "%t", "Menu empty");
|
||||
|
||||
DisplayMenu(menu_weapons_weapons, client, MENU_TIME_FOREVER);
|
||||
AddMenuItem(menu_weapons_types, "empty", empty, ITEMDRAW_DISABLED);
|
||||
}
|
||||
|
||||
// Set exit back button.
|
||||
SetMenuExitBackButton(menu_weapons_types, true);
|
||||
|
||||
DisplayMenu(menu_weapons_types, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when client selects option in the weapons list menu, and handles it.
|
||||
* @param menu_weapons_main Handle of the menu being used.
|
||||
* @param menu_weapons_types Handle of the menu being used.
|
||||
* @param action The action done on the menu (see menus.inc, enum MenuAction).
|
||||
* @param client The client index.
|
||||
* @param slot The slot index selected (starting from 0).
|
||||
*/
|
||||
public WeaponsMenuWeaponsHandle(Handle:menu_weapons_weapons, MenuAction:action, client, slot)
|
||||
public WeaponsMenuTypesHandle(Handle:menu_weapons_types, MenuAction:action, client, slot)
|
||||
{
|
||||
// Client selected an option.
|
||||
if (action == MenuAction_Select)
|
||||
{
|
||||
decl String:weapon[WEAPONS_MAX_LENGTH];
|
||||
GetMenuItem(menu_weapons_weapons, slot, weapon, sizeof(weapon));
|
||||
// Menu slot index is = weapon type index.
|
||||
g_iCurWeaponType[client] = slot;
|
||||
|
||||
switch(curMenuWeapons[client])
|
||||
{
|
||||
// Client is restricting a single weapon.
|
||||
case Weapon:
|
||||
{
|
||||
new WpnRestrictQuery:output;
|
||||
|
||||
if (!RestrictIsWeaponRestricted(weapon))
|
||||
{
|
||||
output = RestrictRestrict(weapon);
|
||||
RestrictPrintRestrictOutput(client, output, weapon, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
output = RestrictUnrestrict(weapon);
|
||||
RestrictPrintUnrestrictOutput(client, output, weapon, false);
|
||||
}
|
||||
|
||||
// Resend menu.
|
||||
WeaponsMenuWeapons(client, curMenuWeapons[client]);
|
||||
}
|
||||
// Client is accessing a weapon group.
|
||||
case WeaponGroup:
|
||||
{
|
||||
// Send weapon group menu.
|
||||
WeaponsMenuWeaponGroup(client, weapon);
|
||||
}
|
||||
}
|
||||
// Send weapons of the selected type in a menu to client.
|
||||
WeaponsMenuTypeWeapons(client);
|
||||
}
|
||||
// Client closed the menu.
|
||||
if (action == MenuAction_Cancel)
|
||||
@ -272,118 +158,141 @@ public WeaponsMenuWeaponsHandle(Handle:menu_weapons_weapons, MenuAction:action,
|
||||
// Client hit "Exit" button.
|
||||
else if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu_weapons_weapons);
|
||||
CloseHandle(menu_weapons_types);
|
||||
}
|
||||
}
|
||||
|
||||
WeaponsMenuWeaponGroup(client, const String:weapongroup[])
|
||||
/**
|
||||
* Sends a list of weapons of a certain type in a menu to the client.
|
||||
* @param client The client index.
|
||||
*/
|
||||
WeaponsMenuTypeWeapons(client)
|
||||
{
|
||||
strcopy(curMenuGroup[client], WEAPONS_MAX_LENGTH, weapongroup);
|
||||
|
||||
// Create menu handle.
|
||||
new Handle:menu_weapons_groupweapon = CreateMenu(WeaponsMenuWeaponGroupHandle);
|
||||
new Handle:menu_weapons_typeweapons = CreateMenu(WeaponsMenuTypeWeaponsHandle);
|
||||
|
||||
SetMenuTitle(menu_weapons_groupweapon, "%t\n ", "Weapons menu weapon group title", weapongroup);
|
||||
decl String:typename[WEAPONS_MAX_LENGTH];
|
||||
RestrictWeaponTypeGetName(g_iCurWeaponType[client], typename, sizeof(typename));
|
||||
|
||||
SetMenuTitle(menu_weapons_typeweapons, "%t\n ", "Weapons menu types type title", typename);
|
||||
|
||||
decl String:restrictall[64];
|
||||
decl String:unrestrictall[64];
|
||||
|
||||
Format(restrictall, sizeof(restrictall), "%t", "Weapons menu weapon group restrict all");
|
||||
Format(unrestrictall, sizeof(unrestrictall), "%t", "Weapons menu weapon group unrestrict all");
|
||||
Format(restrictall, sizeof(restrictall), "%t", "Weapons menu types restrict all", typename);
|
||||
Format(unrestrictall, sizeof(unrestrictall), "%t", "Weapons menu types unrestrict all", typename);
|
||||
|
||||
if (RestrictIsGroupRestricted(weapongroup))
|
||||
{
|
||||
AddMenuItem(menu_weapons_groupweapon, "restrictall", restrictall, ITEMDRAW_DISABLED);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddMenuItem(menu_weapons_groupweapon, "restrictall", restrictall);
|
||||
}
|
||||
// Draw items as selectable only if not all weapons within the type are restricted or unrestricted.
|
||||
AddMenuItem(menu_weapons_typeweapons, "restrictall", restrictall, MenuGetItemDraw(!RestrictIsTypeUniform(true, g_iCurWeaponType[client])));
|
||||
AddMenuItem(menu_weapons_typeweapons, "unrestrictall", unrestrictall, MenuGetItemDraw(!RestrictIsTypeUniform(false, g_iCurWeaponType[client])));
|
||||
|
||||
if (RestrictIsGroupUnrestricted(weapongroup))
|
||||
{
|
||||
AddMenuItem(menu_weapons_groupweapon, "unrestrictall", unrestrictall, ITEMDRAW_DISABLED);
|
||||
}
|
||||
else
|
||||
{
|
||||
AddMenuItem(menu_weapons_groupweapon, "unrestrictall", unrestrictall);
|
||||
}
|
||||
decl String:typeweapon[WEAPONS_MAX_LENGTH];
|
||||
decl String:display[WEAPONS_MAX_LENGTH];
|
||||
|
||||
decl String:groupweapon[WEAPONS_MAX_LENGTH];
|
||||
decl String:display[WEAPONS_MAX_LENGTH + 1];
|
||||
new Handle:arrayGroupWeapons = INVALID_HANDLE;
|
||||
new size = RestrictCreateGroupWeaponsArray(arrayGroupWeapons, weapongroup);
|
||||
// Get an array populated with all weapons of the given type.
|
||||
new Handle:arrayTypeWeapons;
|
||||
new count = RestrictGetTypeWeapons(g_iCurWeaponType[client], arrayTypeWeapons);
|
||||
|
||||
// x = Array index.
|
||||
for (new x = 0; x < size; x++)
|
||||
for (new x = 0; x < count; x++)
|
||||
{
|
||||
GetArrayString(arrayGroupWeapons, x, groupweapon, sizeof(groupweapon));
|
||||
// Get weapon index to check restricted status of.
|
||||
new weaponindex = GetArrayCell(arrayTypeWeapons, x);
|
||||
|
||||
strcopy(display, sizeof(display), groupweapon);
|
||||
// Get name of weapon.
|
||||
WeaponsGetName(weaponindex, typeweapon, sizeof(typeweapon));
|
||||
strcopy(display, sizeof(display), typeweapon);
|
||||
|
||||
if (RestrictIsWeaponRestricted(groupweapon))
|
||||
if (RestrictIsWeaponRestricted(weaponindex))
|
||||
{
|
||||
Format(display, sizeof(display), "%s*", groupweapon);
|
||||
Format(display, sizeof(display), "[%s]", typeweapon);
|
||||
}
|
||||
|
||||
AddMenuItem(menu_weapons_groupweapon, groupweapon, display);
|
||||
// Disable option if it isn't toggleable.
|
||||
AddMenuItem(menu_weapons_typeweapons, typeweapon, display, MenuGetItemDraw(WeaponsGetToggleable(weaponindex)));
|
||||
}
|
||||
|
||||
// Kill the array handle.
|
||||
CloseHandle(arrayGroupWeapons);
|
||||
// Destroy the array handle.
|
||||
CloseHandle(arrayTypeWeapons);
|
||||
|
||||
SetMenuExitBackButton(menu_weapons_groupweapon, true);
|
||||
|
||||
DisplayMenu(menu_weapons_groupweapon, client, MENU_TIME_FOREVER);
|
||||
// Set menu back button.
|
||||
SetMenuExitBackButton(menu_weapons_typeweapons, true);
|
||||
|
||||
// Display menu to client.
|
||||
DisplayMenu(menu_weapons_typeweapons, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when client selects option in the weapon group menu, and handles it.
|
||||
* @param menu_weapons_main Handle of the menu being used.
|
||||
* @param action The action done on the menu (see menus.inc, enum MenuAction).
|
||||
* @param client The client index.
|
||||
* @param slot The slot index selected (starting from 0).
|
||||
* @param menu_weapons_typeweapons Handle of the menu being used.
|
||||
* @param action The action done on the menu (see menus.inc, enum MenuAction).
|
||||
* @param client The client index.
|
||||
* @param slot The slot index selected (starting from 0).
|
||||
*/
|
||||
public WeaponsMenuWeaponGroupHandle(Handle:menu_weapons_groupweapon, MenuAction:action, client, slot)
|
||||
public WeaponsMenuTypeWeaponsHandle(Handle:menu_weapons_typeweapons, MenuAction:action, client, slot)
|
||||
{
|
||||
// Client selected an option.
|
||||
if (action == MenuAction_Select)
|
||||
{
|
||||
// Get name of current weapon type.
|
||||
decl String:typename[WEAPONS_MAX_LENGTH];
|
||||
RestrictWeaponTypeGetName(g_iCurWeaponType[client], typename, sizeof(typename));
|
||||
|
||||
new RestrictQuery:query;
|
||||
new bool:single;
|
||||
new bool:restrict;
|
||||
decl String:returntarget[WEAPONS_MAX_LENGTH];
|
||||
|
||||
switch(slot)
|
||||
{
|
||||
case 0:
|
||||
{
|
||||
new WpnRestrictQuery:output = RestrictRestrict(curMenuGroup[client]);
|
||||
RestrictPrintRestrictOutput(client, output, curMenuGroup[client], false);
|
||||
// Restrict all weapons of this type.
|
||||
restrict = true;
|
||||
query = RestrictWeapon(true, typename, single, returntarget, sizeof(returntarget));
|
||||
}
|
||||
case 1:
|
||||
{
|
||||
new WpnRestrictQuery:output = RestrictUnrestrict(curMenuGroup[client]);
|
||||
RestrictPrintUnrestrictOutput(client, output, curMenuGroup[client], false);
|
||||
// Unrestrict all weapons of this type.
|
||||
restrict = false;
|
||||
query = RestrictWeapon(false, typename, single, returntarget, sizeof(returntarget));
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
new WpnRestrictQuery:output;
|
||||
// Get weappon name.
|
||||
decl String:typeweapon[WEAPONS_MAX_LENGTH];
|
||||
GetMenuItem(menu_weapons_typeweapons, slot, typeweapon, sizeof(typeweapon));
|
||||
|
||||
decl String:groupweapon[WEAPONS_MAX_LENGTH];
|
||||
GetMenuItem(menu_weapons_groupweapon, slot, groupweapon, sizeof(groupweapon));
|
||||
// Get weapon index.
|
||||
new weaponindex = WeaponsNameToIndex(typeweapon);
|
||||
|
||||
if (!RestrictIsWeaponRestricted(groupweapon))
|
||||
// If weapon index is -1, then something went very wrong.
|
||||
if (weaponindex == -1)
|
||||
{
|
||||
output = RestrictRestrict(groupweapon);
|
||||
RestrictPrintRestrictOutput(client, output, groupweapon, false);
|
||||
CloseHandle(menu_weapons_typeweapons);
|
||||
}
|
||||
|
||||
// If weapon isn't restricted, then restrict it.
|
||||
if (!RestrictIsWeaponRestricted(weaponindex))
|
||||
{
|
||||
// Restrict this weapon.
|
||||
restrict = true;
|
||||
query = RestrictWeapon(true, typeweapon, single, returntarget, sizeof(returntarget));
|
||||
}
|
||||
else
|
||||
{
|
||||
output = RestrictUnrestrict(groupweapon);
|
||||
RestrictPrintUnrestrictOutput(client, output, groupweapon, false);
|
||||
// Unrestrict this weapon.
|
||||
restrict = false;
|
||||
query = RestrictWeapon(false, typeweapon, single, returntarget, sizeof(returntarget));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Print query response.
|
||||
RestrictPrintQueryResponse(client, query, single, restrict, returntarget);
|
||||
|
||||
// Resend menu.
|
||||
WeaponsMenuWeaponGroup(client, curMenuGroup[client]);
|
||||
WeaponsMenuTypeWeapons(client);
|
||||
}
|
||||
// Client closed the menu.
|
||||
if (action == MenuAction_Cancel)
|
||||
@ -391,37 +300,38 @@ public WeaponsMenuWeaponGroupHandle(Handle:menu_weapons_groupweapon, MenuAction:
|
||||
// Client hit "Back" button.
|
||||
if (slot == MenuCancel_ExitBack)
|
||||
{
|
||||
WeaponsMenuWeapons(client, curMenuWeapons[client]);
|
||||
WeaponsMenuTypes(client);
|
||||
}
|
||||
}
|
||||
// Client hit "Exit" button.
|
||||
else if (action == MenuAction_End)
|
||||
{
|
||||
CloseHandle(menu_weapons_groupweapon);
|
||||
CloseHandle(menu_weapons_typeweapons);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends market options menu to client.
|
||||
* Sends ZMarket options menu to client.
|
||||
* @param client The client index.
|
||||
*/
|
||||
WeaponsMenuMarket(client)
|
||||
*/
|
||||
WeaponsMenuZMarket(client)
|
||||
{
|
||||
// Create menu handle.
|
||||
new Handle:menu_weapons_market = CreateMenu(WeaponsMenuMarketHandle);
|
||||
new Handle:menu_weapons_market = CreateMenu(WeaponsMenuZMarketHandle);
|
||||
|
||||
SetGlobalTransTarget(client);
|
||||
|
||||
SetMenuTitle(menu_weapons_market, "%t\n ", "Weapons menu market title");
|
||||
SetMenuTitle(menu_weapons_market, "%t\n ", "Weapons menu zmarket title");
|
||||
|
||||
decl String:togglebuyzone[64];
|
||||
decl String:buyzone[64];
|
||||
decl String:buyzonesetting[8];
|
||||
|
||||
decl String:curSetting[8];
|
||||
ConfigBoolToSetting(GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]), curSetting, sizeof(curSetting));
|
||||
// Get "yes" or "no" settings from respective cvar.
|
||||
ConfigBoolToSetting(GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]), buyzonesetting, sizeof(buyzonesetting));
|
||||
|
||||
Format(togglebuyzone, sizeof(togglebuyzone), "%t", "Weapons menu market toggle buyzone", curSetting);
|
||||
|
||||
AddMenuItem(menu_weapons_market, "togglebuyzone", togglebuyzone);
|
||||
// Add options to menu.
|
||||
Format(buyzone, sizeof(buyzone), "%t", "Weapons menu zmarket buyzone", buyzonesetting);
|
||||
AddMenuItem(menu_weapons_market, "buyzone", buyzone);
|
||||
|
||||
// Create a "Back" button to the weapons main menu.
|
||||
SetMenuExitBackButton(menu_weapons_market, true);
|
||||
@ -432,33 +342,29 @@ WeaponsMenuMarket(client)
|
||||
|
||||
/**
|
||||
* Called when client selects option in the weapons main menu, and handles it.
|
||||
* @param menu_weapons_main Handle of the menu being used.
|
||||
* @param menu_weapons_market Handle of the menu being used.
|
||||
* @param action The action done on the menu (see menus.inc, enum MenuAction).
|
||||
* @param client The client index.
|
||||
* @param slot The slot index selected (starting from 0).
|
||||
*/
|
||||
public WeaponsMenuMarketHandle(Handle:menu_weapons_market, MenuAction:action, client, slot)
|
||||
public WeaponsMenuZMarketHandle(Handle:menu_weapons_market, MenuAction:action, client, slot)
|
||||
{
|
||||
// Client selected an option.
|
||||
if (action == MenuAction_Select)
|
||||
{
|
||||
switch(slot)
|
||||
{
|
||||
// Buyzone.
|
||||
case 0:
|
||||
{
|
||||
if (GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]))
|
||||
{
|
||||
SetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE], false);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE], true);
|
||||
}
|
||||
// Toggle cvar.
|
||||
new bool:zmarketbuyzone = GetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE]);
|
||||
SetConVarBool(g_hCvarsList[CVAR_WEAPONS_ZMARKET_BUYZONE], !zmarketbuyzone);
|
||||
}
|
||||
}
|
||||
|
||||
// Resend menu.
|
||||
WeaponsMenuMarket(client);
|
||||
WeaponsMenuZMarket(client);
|
||||
}
|
||||
// Client closed the menu.
|
||||
if (action == MenuAction_Cancel)
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -150,7 +150,7 @@ WeaponAlphaApplyWeaponAlpha(entity, alpha)
|
||||
}
|
||||
|
||||
// Get client's list of weapons.
|
||||
new weapons[WeaponsType];
|
||||
new weapons[WeaponsSlot];
|
||||
WeaponsGetClientWeapons(entity, weapons);
|
||||
|
||||
// Loop through array slots and set alpha.
|
||||
|
81
src/zr/weapons/weaponammo.inc
Normal file
81
src/zr/weapons/weaponammo.inc
Normal file
@ -0,0 +1,81 @@
|
||||
/*
|
||||
* ============================================================================
|
||||
*
|
||||
* Zombie:Reloaded
|
||||
*
|
||||
* File: weaponammo.inc
|
||||
* Type: Core
|
||||
* Description: API for all weaponammo-related functions.
|
||||
*
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* @section Variables to store ammo offset values.
|
||||
*/
|
||||
new g_iToolsClip1;
|
||||
new g_iToolsClip2;
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* Find ammo-reserve-specific offsets here.
|
||||
*/
|
||||
WeaponAmmoOnOffsetsFound()
|
||||
{
|
||||
// If offset "m_iClip1" can't be found, then stop the plugin.
|
||||
g_iToolsClip1 = FindSendPropInfo("CBaseCombatWeapon", "m_iClip1");
|
||||
if (g_iToolsClip1 == -1)
|
||||
{
|
||||
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CBaseCombatWeapon::m_iClip1\" was not found.");
|
||||
}
|
||||
|
||||
// If offset "m_iClip2" can't be found, then stop the plugin.
|
||||
g_iToolsClip2 = FindSendPropInfo("CBaseCombatWeapon", "m_iClip2");
|
||||
if (g_iToolsClip2 == -1)
|
||||
{
|
||||
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CBaseCombatWeapon::m_iClip2\" was not found.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set clip/reserve ammo on a weapon.
|
||||
*
|
||||
* @param weapon The weapon index.
|
||||
* @param clip True sets clip ammo, false sets reserve.
|
||||
* @param value The amount of ammo to set to.
|
||||
* @param add (Optional) If true, the value is added to the weapon's current ammo count.
|
||||
*/
|
||||
stock WeaponAmmoSetClientAmmo(weapon, bool:clip, value, bool:add = false)
|
||||
{
|
||||
// Set variable to offset we are changing.
|
||||
new ammooffset = clip ? g_iToolsClip1 : g_iToolsClip2;
|
||||
|
||||
// Initialize variable (value is 0)
|
||||
new ammovalue;
|
||||
|
||||
// If we are adding, then update variable with current ammo value.
|
||||
if (add)
|
||||
{
|
||||
ammovalue = WeaponAmmoGetClientAmmo(weapon, clip);
|
||||
}
|
||||
|
||||
// Return ammo offset value.
|
||||
SetEntData(weapon, ammooffset, ammovalue + value, _, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get clip/reserve ammo on a weapon.
|
||||
*
|
||||
* @param weapon The weapon index.
|
||||
* @param clip True gets clip ammo, false gets reserve.
|
||||
*/
|
||||
stock WeaponAmmoGetClientAmmo(weapon, bool:clip)
|
||||
{
|
||||
// Set variable to offset we are changing.
|
||||
new ammooffset = clip ? g_iToolsClip1 : g_iToolsClip2;
|
||||
|
||||
// Return ammo offset value.
|
||||
return GetEntData(weapon, ammooffset);
|
||||
}
|
@ -14,9 +14,6 @@
|
||||
* Maximum length of a weapon name string
|
||||
*/
|
||||
#define WEAPONS_MAX_LENGTH 32
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* Number of weapon slots (For CS:S)
|
||||
@ -24,27 +21,52 @@
|
||||
#define WEAPONS_SLOTS_MAX 5
|
||||
|
||||
/**
|
||||
* Weapon types.
|
||||
* Weapon config data indexes.
|
||||
*/
|
||||
enum WeaponsType
|
||||
enum WeaponsData
|
||||
{
|
||||
Type_Invalid = -1, /** Invalid weapon (slot). */
|
||||
Type_Primary = 0, /** Primary weapon slot. */
|
||||
Type_Secondary = 1, /** Secondary weapon slot. */
|
||||
Type_Melee = 2, /** Melee (knife) weapon slot. */
|
||||
Type_Projectile = 3, /** Projectile (grenades, flashbangs, etc) weapon slot. */
|
||||
Type_Explosive = 4, /** Explosive (c4) weapon slot. */
|
||||
WEAPONS_DATA_NAME = 0,
|
||||
WEAPONS_DATA_TYPE,
|
||||
WEAPONS_DATA_RESTRICTDEFAULT,
|
||||
WEAPONS_DATA_TOGGLEABLE,
|
||||
WEAPONS_DATA_AMMOTYPE,
|
||||
WEAPONS_DATA_AMMOPRICE,
|
||||
WEAPONS_DATA_KNOCKBACK,
|
||||
WEAPONS_DATA_ZMARKETPRICE,
|
||||
WEAPONS_DATA_RESTRICTED,
|
||||
}
|
||||
|
||||
/**
|
||||
* Keyvalue handle to store weapon data.
|
||||
*
|
||||
* @redir config.inc
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* Variable to store active weapon offset value.
|
||||
*/
|
||||
new g_iToolsActiveWeapon;
|
||||
|
||||
/**
|
||||
* Weapon slots.
|
||||
*/
|
||||
enum WeaponsSlot
|
||||
{
|
||||
Slot_Invalid = -1, /** Invalid weapon (slot). */
|
||||
Slot_Primary = 0, /** Primary weapon slot. */
|
||||
Slot_Secondary = 1, /** Secondary weapon slot. */
|
||||
Slot_Melee = 2, /** Melee (knife) weapon slot. */
|
||||
Slot_Projectile = 3, /** Projectile (grenades, flashbangs, etc) weapon slot. */
|
||||
Slot_Explosive = 4, /** Explosive (c4) weapon slot. */
|
||||
}
|
||||
|
||||
/**
|
||||
* Array handle to store weapon config data.
|
||||
*/
|
||||
new Handle:arrayWeapons = INVALID_HANDLE;
|
||||
|
||||
#include "zr/weapons/restrict"
|
||||
#include "zr/weapons/weaponammo"
|
||||
#include "zr/weapons/weaponalpha"
|
||||
#include "zr/weapons/markethandler"
|
||||
#include "zr/weapons/zmarket"
|
||||
#include "zr/weapons/menu_weapons"
|
||||
|
||||
/**
|
||||
@ -52,10 +74,26 @@ enum WeaponsType
|
||||
*/
|
||||
WeaponsInit()
|
||||
{
|
||||
// Forward event to sub-module
|
||||
// Forward event to sub-modules.
|
||||
RestrictInit();
|
||||
}
|
||||
|
||||
/**
|
||||
* Find active weapon-specific offsets here.
|
||||
*/
|
||||
WeaponsOnOffsetsFound()
|
||||
{
|
||||
// If offset "m_hActiveWeapon" can't be found, then stop the plugin.
|
||||
g_iToolsActiveWeapon = FindSendPropInfo("CBasePlayer", "m_hActiveWeapon");
|
||||
if (g_iToolsActiveWeapon == -1)
|
||||
{
|
||||
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CBasePlayer::m_hActiveWeapon\" was not found.");
|
||||
}
|
||||
|
||||
// Forward event to sub-modules
|
||||
WeaponAmmoOnOffsetsFound();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create commands related to weapons here.
|
||||
*/
|
||||
@ -65,34 +103,13 @@ WeaponsOnCommandsCreate()
|
||||
RestrictOnCommandsCreate();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears weapon data.
|
||||
*/
|
||||
WeaponsClearData()
|
||||
{
|
||||
// Load weapon data
|
||||
if (kvWeapons != INVALID_HANDLE)
|
||||
{
|
||||
CloseHandle(kvWeapons);
|
||||
}
|
||||
|
||||
kvWeapons = CreateKeyValues("weapons");
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads weapon data from file.
|
||||
*/
|
||||
WeaponsLoad()
|
||||
{
|
||||
// Clear weapon data.
|
||||
WeaponsClearData();
|
||||
|
||||
// Get weapons config path.
|
||||
decl String:pathweapons[PLATFORM_MAX_PATH];
|
||||
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_WEAPONS, pathweapons);
|
||||
|
||||
// Register config info.
|
||||
ConfigRegisterConfig(ConfigWeapons, false, GetFunctionByName(GetMyHandle(), "WeaponsOnConfigReload"), _, pathweapons, CONFIG_FILE_ALIAS_WEAPONS);
|
||||
// Register config file.
|
||||
ConfigRegisterConfig(File_Weapons, Structure_Keyvalue, CONFIG_FILE_ALIAS_WEAPONS);
|
||||
|
||||
// If module is disabled, then stop.
|
||||
new bool:weapons = GetConVarBool(g_hCvarsList[CVAR_WEAPONS]);
|
||||
@ -101,6 +118,10 @@ WeaponsLoad()
|
||||
return;
|
||||
}
|
||||
|
||||
// Get weapons config path.
|
||||
decl String:pathweapons[PLATFORM_MAX_PATH];
|
||||
new bool:exists = ConfigGetCvarFilePath(CVAR_CONFIG_PATH_WEAPONS, pathweapons);
|
||||
|
||||
// If file doesn't exist, then log and stop.
|
||||
if (!exists)
|
||||
{
|
||||
@ -110,46 +131,121 @@ WeaponsLoad()
|
||||
return;
|
||||
}
|
||||
|
||||
// Put file data into memory.
|
||||
FileToKeyValues(kvWeapons, pathweapons);
|
||||
// Set the path to the config file.
|
||||
ConfigSetConfigPath(File_Weapons, pathweapons);
|
||||
|
||||
// Load config from file and create array structure.
|
||||
new bool:success = ConfigLoadConfig(File_Weapons, arrayWeapons);
|
||||
|
||||
// Unexpected error, stop plugin.
|
||||
if (!success)
|
||||
{
|
||||
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Weapons", "Config Validation", "Unexpected error encountered loading: %s", pathweapons);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Validate weapons config.
|
||||
WeaponsValidateConfig();
|
||||
new size = GetArraySize(arrayWeapons);
|
||||
if (!size)
|
||||
{
|
||||
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Weapons", "Config Validation", "No usable data found in weapons config file: %s", pathweapons);
|
||||
}
|
||||
|
||||
// Now copy data to array structure.
|
||||
WeaponsCacheData();
|
||||
|
||||
// Set config data.
|
||||
ConfigSetConfigLoaded(ConfigWeapons, true);
|
||||
ConfigSetConfigHandle(ConfigWeapons, kvWeapons);
|
||||
ConfigSetConfigLoaded(File_Weapons, true);
|
||||
ConfigSetConfigReloadFunc(File_Weapons, GetFunctionByName(GetMyHandle(), "WeaponsOnConfigReload"));
|
||||
ConfigSetConfigHandle(File_Weapons, arrayWeapons);
|
||||
|
||||
// Forward event to sub-module.
|
||||
// Forward event to sub-modules
|
||||
RestrictLoad();
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when configs are being reloaded.
|
||||
*
|
||||
* @param config The config being reloaded. (only if 'all' is false)
|
||||
* Caches weapon data from file into arrays.
|
||||
* Make sure the file is loaded before (ConfigLoadConfig) to prep array structure.
|
||||
*/
|
||||
public WeaponsOnConfigReload(ConfigFile:config)
|
||||
WeaponsCacheData()
|
||||
{
|
||||
// Reload weapons config.
|
||||
if (config == ConfigWeapons)
|
||||
// Get config's file path.
|
||||
decl String:pathweapons[PLATFORM_MAX_PATH];
|
||||
ConfigGetConfigPath(File_Weapons, pathweapons, sizeof(pathweapons));
|
||||
|
||||
new Handle:kvWeapons;
|
||||
new bool:success = ConfigOpenConfigFile(File_Weapons, kvWeapons);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
WeaponsLoad();
|
||||
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Weapons", "Config Validation", "Unexpected error caching data from weapons config file: %s", pathweapons);
|
||||
}
|
||||
|
||||
decl String:weaponname[WEAPONS_MAX_LENGTH];
|
||||
|
||||
// x = array index
|
||||
new size = GetArraySize(arrayWeapons);
|
||||
for (new x = 0; x < size; x++)
|
||||
{
|
||||
WeaponsGetName(x, weaponname, sizeof(weaponname));
|
||||
KvRewind(kvWeapons);
|
||||
if (!KvJumpToKey(kvWeapons, weaponname))
|
||||
{
|
||||
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Weapons", "Config Validation", "Couldn't cache weapon data for: %s (check weapons config)", weaponname);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Get config data.
|
||||
|
||||
decl String:weapontype[CONFIG_MAX_LENGTH];
|
||||
decl String:ammotype[CONFIG_MAX_LENGTH];
|
||||
|
||||
// General
|
||||
KvGetString(kvWeapons, "weapontype", weapontype, sizeof(weapontype));
|
||||
|
||||
// Restrict (core)
|
||||
new bool:restrictdefault = ConfigKvGetStringBool(kvWeapons, "restrictdefault", "no");
|
||||
new bool:toggleable = ConfigKvGetStringBool(kvWeapons, "toggleable", "yes");
|
||||
|
||||
// Weapon Ammo (core)
|
||||
KvGetString(kvWeapons, "ammotype", ammotype, sizeof(ammotype));
|
||||
new ammoprice = KvGetNum(kvWeapons, "ammoprice");
|
||||
|
||||
// Knockback (module)
|
||||
new Float:knockback = KvGetFloat(kvWeapons, "knockback", 1.0);
|
||||
|
||||
// ZMarket (module)
|
||||
new zmarketprice = KvGetNum(kvWeapons, "zmarketprice", -1);
|
||||
|
||||
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, x);
|
||||
|
||||
// Push data into array.
|
||||
PushArrayString(arrayWeapon, weapontype); // Index: 1
|
||||
PushArrayCell(arrayWeapon, restrictdefault); // Index: 2
|
||||
PushArrayCell(arrayWeapon, toggleable); // Index: 3
|
||||
PushArrayString(arrayWeapon, ammotype); // Index: 4
|
||||
PushArrayCell(arrayWeapon, ammoprice); // Index: 5
|
||||
PushArrayCell(arrayWeapon, knockback); // Index: 6
|
||||
PushArrayCell(arrayWeapon, zmarketprice); // Index: 7
|
||||
|
||||
// Initialize other stored weapon info here.
|
||||
PushArrayCell(arrayWeapon, restrictdefault); // Index: 8
|
||||
}
|
||||
|
||||
// We're done with this file now, so we can close it.
|
||||
CloseHandle(kvWeapons);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate weapon config file and settings.
|
||||
* Called when config is being reloaded.
|
||||
*/
|
||||
WeaponsValidateConfig()
|
||||
public WeaponsOnConfigReload()
|
||||
{
|
||||
KvRewind(kvWeapons);
|
||||
if (!KvGotoFirstSubKey(kvWeapons))
|
||||
{
|
||||
LogPrintToLog(LOG_FORMAT_TYPE_ERROR, "Weapons", "Config Validation", "No weapons listed in weapons.txt.");
|
||||
}
|
||||
// Reload weapons config.
|
||||
WeaponsLoad();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Client is joining the server.
|
||||
*
|
||||
@ -195,154 +291,173 @@ WeaponsOnRoundEnd()
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an array of all listed weapons in weapons.txt.
|
||||
* @param arrayWeapons The handle of the array, don't forget to call CloseHandle
|
||||
* on it when finished!
|
||||
* @return The size of the array.
|
||||
* Weapon data reading API.
|
||||
*/
|
||||
stock WeaponsCreateWeaponArray(&Handle:arrayWeapons, maxlen = WEAPONS_MAX_LENGTH)
|
||||
|
||||
/**
|
||||
* Clear cache for a given weapon.
|
||||
*
|
||||
* @param index The weapon index.
|
||||
*/
|
||||
WeaponsClearCache(index)
|
||||
{
|
||||
// Initialize array handle.
|
||||
arrayWeapons = CreateArray(maxlen);
|
||||
new count = 0;
|
||||
// Get array handle of weapon at given index.
|
||||
new Handle:hWeapon = GetArrayCell(arrayWeapons, index);
|
||||
|
||||
// Reset keyvalue's traveral stack.
|
||||
KvRewind(kvWeapons);
|
||||
if (KvGotoFirstSubKey(kvWeapons))
|
||||
{
|
||||
decl String:weapon[maxlen];
|
||||
|
||||
do
|
||||
{
|
||||
KvGetSectionName(kvWeapons, weapon, maxlen);
|
||||
|
||||
// Push weapon name into the array.
|
||||
PushArrayString(arrayWeapons, weapon);
|
||||
|
||||
// Increment count.
|
||||
count++;
|
||||
} while (KvGotoNextKey(kvWeapons));
|
||||
}
|
||||
|
||||
// Return the count
|
||||
return count;
|
||||
// Clear array.
|
||||
ClearArray(hWeapon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a weapon is valid. (aka listed in weapons.txt)
|
||||
* Find the index at which the weapon's name is at.
|
||||
*
|
||||
* @param weapon The weapon name.
|
||||
* @return The array index containing the given weapon name.
|
||||
*/
|
||||
stock WeaponsNameToIndex(const String:weapon[])
|
||||
{
|
||||
decl String:weaponname[WEAPONS_MAX_LENGTH];
|
||||
|
||||
// x = Array index.
|
||||
new size = GetArraySize(arrayWeapons);
|
||||
for (new x = 0; x < size; x++)
|
||||
{
|
||||
WeaponsGetName(x, weaponname, sizeof(weaponname));
|
||||
|
||||
// If names match, then return index.
|
||||
if (StrEqual(weapon, weaponname, false))
|
||||
{
|
||||
return x;
|
||||
}
|
||||
}
|
||||
|
||||
// Name doesn't exist.
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a weapon is valid. (E.G. listed in weapons.txt)
|
||||
* @param weapon The weapon name.
|
||||
* @return Returns true if valid, false it not.
|
||||
*/
|
||||
stock bool:WeaponsIsValidWeapon(const String:weapon[])
|
||||
stock bool:WeaponsIsWeaponValid(const String:weapon[])
|
||||
{
|
||||
// Reset keyvalue's traversal stack.
|
||||
KvRewind(kvWeapons);
|
||||
if (KvGotoFirstSubKey(kvWeapons))
|
||||
{
|
||||
decl String:validweapon[WEAPONS_MAX_LENGTH];
|
||||
|
||||
do
|
||||
{
|
||||
KvGetSectionName(kvWeapons, validweapon, sizeof(validweapon));
|
||||
|
||||
// If weaponname matches a valid weapon, then return true.
|
||||
if (StrEqual(validweapon, weapon, false))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
} while (KvGotoNextKey(kvWeapons));
|
||||
}
|
||||
|
||||
// Weapon is invalid.
|
||||
return false;
|
||||
return (WeaponsNameToIndex(weapon) != -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks up a weapon in weapons.txt and returns exact display name.
|
||||
* @param weapon The weapon name.
|
||||
* @param display Returns with the display name, is not changed if weapon is invalid.
|
||||
* Gets the name of a weapon at a given index.
|
||||
* @param index The weapon index.
|
||||
* @param weapon The string to return name in.
|
||||
* @param maxlen The max length of the string.
|
||||
*/
|
||||
stock WeaponsGetDisplayName(const String:weapon[], String:display[])
|
||||
stock WeaponsGetName(index, String:weapon[], maxlen)
|
||||
{
|
||||
// Reset keyvalue's traversal stack.
|
||||
KvRewind(kvWeapons);
|
||||
if (KvGotoFirstSubKey(kvWeapons))
|
||||
{
|
||||
decl String:validweapon[WEAPONS_MAX_LENGTH];
|
||||
|
||||
do
|
||||
{
|
||||
KvGetSectionName(kvWeapons, validweapon, sizeof(validweapon));
|
||||
|
||||
// If weapon matches a valid weapon (case-insensitive), then return display name.
|
||||
if (StrEqual(validweapon, weapon, false))
|
||||
{
|
||||
strcopy(display, WEAPONS_MAX_LENGTH, validweapon);
|
||||
}
|
||||
|
||||
} while (KvGotoNextKey(kvWeapons));
|
||||
}
|
||||
// Get array handle of weapon at given index.
|
||||
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
|
||||
|
||||
// Get weapon name.
|
||||
GetArrayString(arrayWeapon, _:WEAPONS_DATA_NAME, weapon, maxlen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a weapon restriction can be toggled by the admin menu.
|
||||
* @param weapon The weapon name.
|
||||
* @return Returns true if restricted, false it not.
|
||||
* Gets the type of a weapon at a given index.
|
||||
* @param index The weapon index.
|
||||
* @param type The string to return type in.
|
||||
* @param maxlen The max length of the string.
|
||||
*/
|
||||
stock bool:WeaponsIsWeaponMenu(const String:weapon[])
|
||||
stock WeaponsGetType(index, String:type[], maxlen)
|
||||
{
|
||||
// Reset keyvalue's traversal stack.
|
||||
KvRewind(kvWeapons);
|
||||
if (KvGotoFirstSubKey(kvWeapons))
|
||||
{
|
||||
decl String:validweapon[WEAPONS_MAX_LENGTH];
|
||||
decl String:menu[8];
|
||||
|
||||
do
|
||||
{
|
||||
KvGetSectionName(kvWeapons, validweapon, sizeof(validweapon));
|
||||
|
||||
// If this is the right weapon, then return setting for it.
|
||||
if (StrEqual(validweapon, weapon, false))
|
||||
{
|
||||
KvGetString(kvWeapons, "menu", menu, sizeof(menu), "yes");
|
||||
|
||||
// Return weapon's setting.
|
||||
return ConfigSettingToBool(menu);
|
||||
}
|
||||
} while (KvGotoNextKey(kvWeapons));
|
||||
}
|
||||
// Get array handle of weapon at given index.
|
||||
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
|
||||
|
||||
return false;
|
||||
// Get weapon type.
|
||||
GetArrayString(arrayWeapon, _:WEAPONS_DATA_TYPE, type, maxlen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns knockback multiplier of the weapon.
|
||||
* @param weapon The weapon name.
|
||||
* @return The float value of the knockback multiplier, 1.0 if not found.
|
||||
* Gets if a weapon is restricted by default.
|
||||
* @param index The weapon index.
|
||||
* @return True if the weapon is restricted by default, false if not.
|
||||
*/
|
||||
stock Float:WeaponGetWeaponKnockback(const String:weapon[])
|
||||
stock bool:WeaponsGetRestrictDefault(index)
|
||||
{
|
||||
// Reset keyvalue's traversal stack.
|
||||
KvRewind(kvWeapons);
|
||||
if (KvGotoFirstSubKey(kvWeapons))
|
||||
{
|
||||
decl String:validweapon[WEAPONS_MAX_LENGTH];
|
||||
|
||||
do
|
||||
{
|
||||
KvGetSectionName(kvWeapons, validweapon, sizeof(validweapon));
|
||||
|
||||
// If this is the right weapon, then return setting for it.
|
||||
if (StrEqual(validweapon, weapon, false))
|
||||
{
|
||||
return KvGetFloat(kvWeapons, "knockback", 1.0);
|
||||
}
|
||||
} while (KvGotoNextKey(kvWeapons));
|
||||
}
|
||||
// Get array handle of weapon at given index.
|
||||
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
|
||||
|
||||
return 1.0;
|
||||
// Return default restriction status.
|
||||
return bool:GetArrayCell(arrayWeapon, _:WEAPONS_DATA_RESTRICTDEFAULT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets if a weapon's restriction status is toggleable.
|
||||
* @param index The weapon index.
|
||||
* @return True if the weapon restriction can be toggled, false if not.
|
||||
*/
|
||||
stock bool:WeaponsGetToggleable(index)
|
||||
{
|
||||
// Get array handle of weapon at given index.
|
||||
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
|
||||
|
||||
// Return if weapon is toggleable.
|
||||
return bool:GetArrayCell(arrayWeapon, _:WEAPONS_DATA_TOGGLEABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ammo type of a weapon at a given index.
|
||||
* @param index The weapon index.
|
||||
* @param ammotype The string to return ammotype in.
|
||||
* @param maxlen The max length of the string.
|
||||
*/
|
||||
stock WeaponsGetAmmoType(index, String:ammotype[], maxlen)
|
||||
{
|
||||
// Get array handle of weapon at given index.
|
||||
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
|
||||
|
||||
// Get ammo type of the weapon.
|
||||
GetArrayString(arrayWeapon, _:WEAPONS_DATA_AMMOTYPE, type, maxlen);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the price of ammo for the weapon.
|
||||
* @param index The weapon index.
|
||||
* @return The ammo price.
|
||||
*/
|
||||
stock WeaponsGetAmmoPrice(index)
|
||||
{
|
||||
// Get array handle of weapon at given index.
|
||||
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
|
||||
|
||||
// Return ammo price of the weapon.
|
||||
return GetArrayCell(arrayWeapon, _:WEAPONS_DATA_AMMOPRICE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the knockback multiplier for the weapon.
|
||||
* @param index The weapon index.
|
||||
* @return The weapon knockback multiplier.
|
||||
*/
|
||||
stock Float:WeaponsGetKnockback(index)
|
||||
{
|
||||
// Get array handle of weapon at given index.
|
||||
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
|
||||
|
||||
// Return knockback multiplier of the weapon.
|
||||
return Float:GetArrayCell(arrayWeapon, _:WEAPONS_DATA_KNOCKBACK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the ZMarket price for the weapon.
|
||||
* @param index The weapon index.
|
||||
* @return The ZMarket price.
|
||||
*/
|
||||
stock WeaponsGetZMarketPrice(index)
|
||||
{
|
||||
// Get array handle of weapon at given index.
|
||||
new Handle:arrayWeapon = GetArrayCell(arrayWeapons, index);
|
||||
|
||||
// Return the ZMarket price of the weapon.
|
||||
return GetArrayCell(arrayWeapon, _:WEAPONS_DATA_ZMARKETPRICE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -356,7 +471,7 @@ stock Float:WeaponGetWeaponKnockback(const String:weapon[])
|
||||
* @param weapons The weapon index array.
|
||||
* -1 if no weapon in slot.
|
||||
*/
|
||||
stock WeaponsGetClientWeapons(client, weapons[WeaponsType])
|
||||
stock WeaponsGetClientWeapons(client, weapons[WeaponsSlot])
|
||||
{
|
||||
// x = weapon slot.
|
||||
for (new x = 0; x < WEAPONS_SLOTS_MAX; x++)
|
||||
@ -384,10 +499,10 @@ stock WeaponsGetDeployedWeaponIndex(client)
|
||||
* @param client The client index.
|
||||
* @return The slot number of deployed weapon.
|
||||
*/
|
||||
stock WeaponsType:WeaponsGetDeployedWeaponSlot(client)
|
||||
stock WeaponsSlot:WeaponsGetDeployedWeaponSlot(client)
|
||||
{
|
||||
// Get all client's weapon indexes.
|
||||
new weapons[WeaponsType];
|
||||
new weapons[WeaponsSlot];
|
||||
WeaponsGetClientWeapons(client, weapons);
|
||||
|
||||
// Get client's deployed weapon.
|
||||
@ -404,7 +519,7 @@ stock WeaponsType:WeaponsGetDeployedWeaponSlot(client)
|
||||
{
|
||||
if (weapons[x] == deployedweapon)
|
||||
{
|
||||
return x;
|
||||
return WeaponsSlot:x;
|
||||
}
|
||||
}
|
||||
|
||||
|
47
src/zr/weapons/zmarket.inc
Normal file
47
src/zr/weapons/zmarket.inc
Normal file
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* ============================================================================
|
||||
*
|
||||
* Zombie:Reloaded
|
||||
*
|
||||
* File:
|
||||
* Type: Module
|
||||
* Description:
|
||||
*
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Variable to store buyzone offset value.
|
||||
*/
|
||||
new g_iToolsInBuyZone;
|
||||
|
||||
/**
|
||||
* Initialize market data.
|
||||
*/
|
||||
ZMarketInit()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Find ZMarket-specific offsets here.
|
||||
*/
|
||||
ZMarketOnOffsetsFound()
|
||||
{
|
||||
// If offset "m_bInBuyZone" can't be found, then stop the plugin.
|
||||
g_iToolsInBuyZone = FindSendPropInfo("CCSPlayer", "m_bInBuyZone");
|
||||
if (g_iToolsInBuyZone == -1)
|
||||
{
|
||||
LogPrintToLog(LOG_FORMAT_TYPE_FATALERROR, "Tools", "Offsets", "Offset \"CCSPlayer::m_bInBuyZone\" was not found.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a client is in a buyzone.
|
||||
*
|
||||
* @param client The client index.
|
||||
*/
|
||||
stock bool:ZMarketIsClientInBuyZone(client)
|
||||
{
|
||||
// Return if client is in buyzone.
|
||||
return bool:GetEntData(client, g_iToolsInBuyZone);
|
||||
}
|
Reference in New Issue
Block a user