bonus plugin error

Coding Help/Re-API Supported
Post Reply
czirimbolo
Veteran Member
Veteran Member
Poland
Posts: 598
Joined: 7 years ago
Contact:

bonus plugin error

#1

Post by czirimbolo » 2 years ago

can someone help me to fix?

L 11/28/2021 - 19:08:11: Invalid index -4 (count: 15)
L 11/28/2021 - 19:08:11: [AMXX] Displaying debug trace (plugin "ze_bonus_manager.amxx", version "1.2")
L 11/28/2021 - 19:08:11: [AMXX] Run time error 10: native error (native "ArrayGetCell")
L 11/28/2021 - 19:08:11: [AMXX] [0] ze_bonus_manager.sma::Handler_Bonus (line 289)

Code: Select all

#include <zombie_escape>
#include <ze_levels>

// Settings file.
new const g_szSettingsFile[] = "ze_bonus.ini"

// Enums.
enum
{
	ENABLE_DISABLE = 0,
	ENABLE_ALWAYS,
	ENABLE_COOLDOWN,
	ENABLE_MAXTIMES,
	ENABLE_ONCEROUND,
	ENABLE_ONCEMAP
}

// Dynamic Arrays.
new Array:g_szBonusName,
		Array:g_szBonusHandler,
		Array:g_szBonusPlugin,
		Array:g_iBonusReqLevel,
		Array:g_szPlayerAuthID
		
// Cvars Variables.
new g_pCvarEnableType,
		g_pCvarCooldown,
		g_pCvarMaxTimes
	
// Global Variables.
new g_iBonusCount,
		g_iMaxTimes[MAX_CLIENTS+1],
		Float:g_flCooldownTime[MAX_CLIENTS+1],
		g_iBounsType[MAX_CLIENTS+1]

// Forward called after server activation.
public plugin_init()
{
	// Load plugin.
	register_plugin("[ZE] Bonus Manager", "1.2", "z0h1r-LK")

	// Events.
	register_event("HLTV", "Event_NewRound", "a", "1=0", "2=0")

	// Cvars.
	g_pCvarEnableType = register_cvar("ze_bonus_enable", "5")
	g_pCvarCooldown = register_cvar("ze_bonus_cooldown", "60")
	g_pCvarMaxTimes = register_cvar("ze_bonus_maxtimes", "1")

	// Client command(s).
	register_clcmd("say", "clcmd_SayText")
	register_clcmd("say_team", "clcmd_SayText")
	
	// Initialize dynamic arrays
	g_szBonusPlugin = ArrayCreate(128) // File name.
	g_szPlayerAuthID = ArrayCreate(35)
	g_szBonusHandler = ArrayCreate(32)
	g_szBonusName = ArrayCreate(32)
	g_iBonusReqLevel = ArrayCreate(1)
	
	// Default Values.
	arrayset(g_iMaxTimes, 1, sizeof(g_iMaxTimes))
}

// Forward allows registering natives.
public plugin_natives()
{
	register_native("ze_bonus_register", "_native_ze_bonus_register", 0)
	register_native("ze_bonus_get_name", "_native_ze_bonus_get_name", 0)
	register_native("ze_bonus_get_id", "_native_ze_bonus_get_id", 0)
	register_native("ze_bonus_get_reqlevel", "_native_ze_bonus_get_reqlevel", 0)
	register_native("ze_open_bonus_menu", "_native_ze_open_bonus_menu", 1)
}

// Forward called before server deactivation or plugin fail.
public plugin_end()
{
	// Destroy (remove) all dynamic arrays.
	ArrayDestroy(g_szPlayerAuthID)
}

// Forward called after player join server.
public client_putinserver(iPlayer)
{
	// Bonus Menu is once time in map (Fix enable menu after player reconnect or retry).
	if (get_pcvar_num(g_pCvarEnableType) == ENABLE_ONCEMAP)
	{
		// Variables.
		new szDynArr[35], szAuthID[35], iNum
		
		// Get Auth ID of player (Valve ID or Steam ID).
		get_user_authid(iPlayer, szAuthID, charsmax(szAuthID))
		
		// Check from authid player is already in dynamic array.
		for (iNum = 0; iNum < ArraySize(g_szPlayerAuthID); iNum++)
		{
			// Get Auth ID's from dynamic array.
			ArrayGetString(g_szPlayerAuthID, iNum, szDynArr, charsmax(szDynArr))
			
			// We find Auth ID of player, So, Him is already use a bonus menu.
			if (equali(szAuthID, szDynArr))
			{
				g_iMaxTimes[iPlayer] = 0 // Suspende the menu on player.
				break; // Stop finding for Auth ID in dynamic array.
			}
		}
	}
	
	if (g_iMaxTimes[iPlayer])
	{
		g_iBounsType[iPlayer] = -1;
	}
}

// Hook called every new round.
public Event_NewRound()
{
	// Re-enable getting bonus.
	if ((get_pcvar_num(g_pCvarEnableType) == ENABLE_ONCEROUND))
	{
		// Re-enable the bonus menu for all players.
		arrayset(g_iMaxTimes, 1, sizeof(g_iMaxTimes))
	}
	else if (get_pcvar_num(g_pCvarEnableType) == ENABLE_MAXTIMES) // Reset maximum times for all players.
	{
		// Re-enable the bonus menu for all players.
		arrayset(g_iMaxTimes, get_pcvar_num(g_pCvarMaxTimes), sizeof(g_iMaxTimes))
	}
}

public ze_user_humanized(id)
{
	if (g_iBounsType[id] >= 0)
	{
		set_task(1.0, "DelayReset", id)
	}
}

public DelayReset(id)
{
	ReGive(id, g_iBounsType[id])
}

// Hook called when sent any message in say/say_team.
public clcmd_SayText(iPlayer)
{
	// Bonus menu is disabled.
	if (!get_pcvar_num(g_pCvarEnableType))
		return;
	
	// Read arguments from say and say_team commands (Message). 
	static szArgs[32]
	read_args(szArgs, charsmax(szArgs))
	remove_quotes(szArgs) // Remove quotes from message "Hi!".
	
	// Check the player is trying open the bonus menu.
	if (equali(szArgs, ".bonus") || equali(szArgs, "/bonus") || equali(szArgs, "!bonus"))
	{
		// Player is a zombie.
		if (ze_is_user_zombie(iPlayer))
		{
			// Alert a player!
			ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_ISZOMBIE")
			return;
		}
		
		// Player is not a alive.
		if (!is_user_alive(iPlayer))
		{
			// Alert a player!
			ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_NOTALIVE")
			return;		
		}
		
		// Enable type is once round, So, Player is already use bonus menu. 
		if (get_pcvar_num(g_pCvarEnableType) == ENABLE_ALWAYS)
		{
			// Menu without limit.
			if (!g_iMaxTimes[iPlayer])
				g_iMaxTimes[iPlayer] = 1
		}
		else if ((get_pcvar_num(g_pCvarEnableType) == ENABLE_ONCEROUND) && !g_iMaxTimes[iPlayer])
		{
			// Alert a player!
			ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_NEXTROUND")
			return;
		} 
		else if (get_pcvar_num(g_pCvarEnableType) == ENABLE_COOLDOWN) // Enable type is cooldown
		{
			// Get a game (halflife) time.
			new Float:flGameTime = get_gametime()
		
			// Alert a player, Cooldown time is not over.
			if (flGameTime < g_flCooldownTime[iPlayer])
			{
				ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_COOLDOWN", floatround(g_flCooldownTime[iPlayer] - flGameTime))
				return;
			}
			
			// Re-enable bonus menu for player.
			g_iMaxTimes[iPlayer] = 1
		} 
		else if (get_pcvar_num(g_pCvarEnableType) == ENABLE_ONCEMAP) // Enable type is once time in map.
		{
			// Player is open bonus menu.
			if (!g_iMaxTimes[iPlayer])
			{
				ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_ONCETIME")
				return;
			}
		} 
		else if (get_pcvar_num(g_pCvarEnableType) == ENABLE_MAXTIMES) // Enable type is maximum times.
		{
			// Player can't open bonus menu, Because is reached maximum times.
			if (!g_iMaxTimes[iPlayer])
			{
				ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_MAXTIME")
				return;
			}		
		}
		
		// Open the bonus menu for player.
		Menu_Bonus(iPlayer)
	}
}

public Menu_Bonus(iPlayer)
{
	new szLang[64], szName[32], iLevelPlr, iLevelReq, iNum, iMenu
	
	// Get current Level of the player.
	iLevelPlr = ze_get_user_level(iPlayer)
	
	// Create a new menu with title.
	formatex(szLang, charsmax(szLang), "\r%L:", LANG_PLAYER, "MENU_TITLE_BONUS", iLevelPlr)
	iMenu = menu_create(szLang, "Handler_Bonus")

	// Add all bonus name to menu.
	for (iNum = 0; iNum < g_iBonusCount; iNum++)
	{
		// Get name of bonus from dynamic array.
		ArrayGetString(g_szBonusName, iNum, szName, charsmax(szName))

		// Get a required level to get the bonus.
		iLevelReq = ArrayGetCell(g_iBonusReqLevel, iNum)
		
		// Sort names in menu.
		if (iLevelReq == 0)
			formatex(szLang, charsmax(szLang), "\w%s - \r%L", szName, LANG_PLAYER, "FREE")
		else if (iLevelPlr < iLevelReq)
			formatex(szLang, charsmax(szLang), "\d%s - \r[%d %L]", szName, iLevelReq, LANG_PLAYER, "LVL")
		else
			formatex(szLang, charsmax(szLang), "\y%s - \r%L", szName, LANG_PLAYER, "UNLOCKED")
			
		// Add bonus name to menu.
		menu_additem(iMenu, szLang, "", 0)
	}
	
	// Set menu property (exit, back, next).
	formatex(szLang, charsmax(szLang), "\y%L", LANG_PLAYER, "NEXT")
	menu_setprop(iMenu, MPROP_NEXTNAME, szLang)
	formatex(szLang, charsmax(szLang), "\y%L", LANG_PLAYER, "BACK")	
	menu_setprop(iMenu, MPROP_BACKNAME, szLang)
	formatex(szLang, charsmax(szLang), "\y%L", LANG_PLAYER, "EXIT")	
	menu_setprop(iMenu, MPROP_EXITNAME, szLang)
	
	// Display menu for player and close menu after 30s.
	menu_display(iPlayer, iMenu, 0, 30)
}

// Hook handle command from bonus menu.
public Handler_Bonus(iPlayer, iMenu, iKey)
{
	// Close and destroy menu.
	if (iKey == MENU_EXIT)
	{
		// Destroy (remove) menu.
		menu_destroy(iMenu)
		return PLUGIN_HANDLED;
	}
	
	// Variables.
	new szName[32], szHandler[32], szPlugin[128], iLevelPlr, iLevelReq
		
	// Get current Level of player.	
	iLevelPlr = ze_get_user_level(iPlayer)
	
	// Get a required Level to get the bonus.
	iLevelReq = ArrayGetCell(g_iBonusReqLevel, iKey)
		
	// Check the player is not getting a bonus yet.
	if (g_iMaxTimes[iPlayer])
	{
		// The player's level is greater than the required level (Getting a bonus).
		if (iLevelPlr >= iLevelReq)
		{
			// Get bonus name from dynamic array.
			ArrayGetString(g_szBonusName, iKey, szName, charsmax(szName))
			
			// Get bonus handler function from dynamic array.
			ArrayGetString(g_szBonusHandler, iKey, szHandler, charsmax(szHandler))
			
			// Get bonus plugin filename from dynamic array.
			ArrayGetString(g_szBonusPlugin, iKey, szPlugin, charsmax(szPlugin))
			
			// Call a function in plugin of the bonus
			new iRet = callfunc_begin(szHandler, szPlugin)
			
			// Handler function is not found in plugin of bonus.
			if (iRet == -1)
			{
				log_error(AMX_ERR_NOTFOUND, "[AMX] Function (%s) not found in plugin (%s)", szHandler, szPlugin)
				return PLUGIN_HANDLED;
			}
			
			// Plugin file is not found.
			if (iRet == -2)
			{
				log_error(AMX_ERR_NOTFOUND, "[AMX] Plugin (%s) is not found.", szPlugin)
				return PLUGIN_HANDLED;
			}
			
			callfunc_push_int(iPlayer) // Add Player ID to handler function.
			callfunc_push_int(iKey) // Add Bonus ID to handler function.
			callfunc_end()
			
			g_iBounsType[iPlayer] = iKey
			
			// Sent colored message in chat, (claiming bonus msg).
			ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_DONE", szName)
			
			// Player has taken the bonus.
			if (get_pcvar_num(g_pCvarEnableType) == ENABLE_ONCEROUND)
			{
				// Player has claim some bonus from menu.
				--g_iMaxTimes[iPlayer]
			}
			else if (get_pcvar_num(g_pCvarEnableType) == ENABLE_COOLDOWN)
			{
				// Make a cooldown time for bonus menu on player.
				g_flCooldownTime[iPlayer] = get_gametime() + get_pcvar_float(g_pCvarCooldown)
			}
			else if (get_pcvar_num(g_pCvarEnableType) == ENABLE_ONCEMAP) // That for Fix problem enable menu when player reconnect or retry.
			{
				// Get auth ID of player.
				new szAuthID[35]
				get_user_authid(iPlayer, szAuthID, charsmax(szAuthID))
				
				// Push AuthID of player in dynamic array.
				ArrayPushString(g_szPlayerAuthID, szAuthID)
				
				// Bonus has claimed.
				--g_iMaxTimes[iPlayer]
			}
			else if (get_pcvar_num(g_pCvarEnableType) == ENABLE_MAXTIMES) // Max times in every round.
			{
				--g_iMaxTimes[iPlayer]
				ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_REMTIMES", g_iMaxTimes[iPlayer])
			}
		}
		else // Player haven't Level enough.
		{
			Menu_Bonus(iPlayer)
			ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_LEVEL_ENOUGH")
		}
	}
	
	// Destroy (remove) menu.
	menu_destroy(iMenu)
	return PLUGIN_HANDLED;
}

public ReGive(iPlayer, iKey)
{
	new szName[32], szHandler[32], szPlugin[128]
	
	// Get bonus name from dynamic array.
	ArrayGetString(g_szBonusName, iKey, szName, charsmax(szName))
	
	// Get bonus handler function from dynamic array.
	ArrayGetString(g_szBonusHandler, iKey, szHandler, charsmax(szHandler))
	
	// Get bonus plugin filename from dynamic array.
	ArrayGetString(g_szBonusPlugin, iKey, szPlugin, charsmax(szPlugin))
	
	if (equal(szHandler, "Handler_PlusTenArmor") || equal(szHandler, "Handler_PlusTenSpeed") || equal(szHandler, "Handler_PlusDamage") || equal(szHandler, "Handler_PlusTenHealth200") || equal(szHandler, "Handler_PlusTenHealth10k") || equal(szHandler, "Handler_PlusTenSpeed30") || equal(szHandler, "Handler_PlusTenArmor100"))
	{
		// Call a function in plugin of the bonus
		new iRet = callfunc_begin(szHandler, szPlugin)
		
		// Handler function is not found in plugin of bonus.
		if (iRet == -1)
		{
			log_error(AMX_ERR_NOTFOUND, "[AMX] Function (%s) not found in plugin (%s)", szHandler, szPlugin)
			return PLUGIN_HANDLED;
		}
		
		// Plugin file is not found.
		if (iRet == -2)
		{
			log_error(AMX_ERR_NOTFOUND, "[AMX] Plugin (%s) is not found.", szPlugin)
			return PLUGIN_HANDLED;
		}
		
		callfunc_push_int(iPlayer) // Add Player ID to handler function.
		callfunc_push_int(iKey) // Add Bonus ID to handler function.
		callfunc_end()
	}
	
	return PLUGIN_HANDLED;
}

// Functions of natives.
public _native_ze_bonus_register(iPlugin_iIndex, iParam_iNum)
{
	new szName[32], szHandler[32], szPlugin[128],  iReqLevel
	get_string(1, szName, charsmax(szName)) // Get name of bonus.
	get_string(2, szHandler, charsmax(szHandler)) // Get handler function of bonus.
	iReqLevel = get_param(3) // Get require level.
	
	// Bonus without name.
	if (strlen(szName) < 0)
	{
		log_error(AMX_ERR_NATIVE, "[AMX] Bonus without name.")
		return INVALID_HANDLE;
	}
	
	// Bonus without handler.
	if (strlen(szHandler) < 0)
	{
		log_error(AMX_ERR_NATIVE, "[AMX] Bonus without handler.")
		return INVALID_HANDLE;
	}
	
	// Get plugin name.
	get_plugin(iPlugin_iIndex, szPlugin, charsmax(szPlugin))
	
	// Bonus name is already registered
	new szDynArr[32], iIndex
	for (iIndex = 0; iIndex < g_iBonusCount; iIndex++)
	{
		// Get bonus name from dynamic array.
		ArrayGetString(g_szBonusName, iIndex, szDynArr, charsmax(szDynArr))
		
		if (equali(szDynArr, szName))
		{
			log_error(AMX_ERR_NATIVE, "[AMX] Bonus name already is registered.")
			return INVALID_HANDLE;
		}
	}
	
	// Load bonus data's from external file.
	if (!amx_load_setting_string(g_szSettingsFile, szName, "NAME", szName, charsmax(szName)))
	{
		amx_save_setting_string(g_szSettingsFile, szName, "NAME", szName)
	}
	
	if (!amx_load_setting_int(g_szSettingsFile, szName, "LEVEL", iReqLevel))
	{
		amx_save_setting_int(g_szSettingsFile, szName, "LEVEL", iReqLevel)
	}
	
	// Register new bonus.
	g_iBonusCount++
	ArrayPushString(g_szBonusName, szName)
	ArrayPushString(g_szBonusHandler, szHandler)
	ArrayPushString(g_szBonusPlugin, szPlugin)
	ArrayPushCell(g_iBonusReqLevel, iReqLevel)
	return g_iBonusCount - 1
}

public _native_ze_bonus_get_name(iPlugin_iIndex, iParam_iNum)
{
	// Get a bonus ID.
	new iBonus = get_param(1)
	
	// Invalid bonus.
	if (iBonus > g_iBonusCount)
	{
		log_error(AMX_ERR_NATIVE, "[AMX] Bonus id is not found (%d)", iBonus)
		return 0;
	}
	
	new szName[32]
	
	// Get name of bonus.
	ArrayGetString(g_szBonusName, iBonus, szName, charsmax(szName))
	
	// Store name in array.
	set_string(2, szName, get_param(3))
	return 1;
}

public _native_ze_bonus_get_id(iPlugin_iIndex, iParam_iNum)
{
	// Get a bonus name
	new szName[32]
	get_string(1, szName, charsmax(szName))
	
	// Find for bonus id by name.
	new szCheck[32], iIndex
	for (iIndex = 0; iIndex < g_iBonusCount; iIndex++)
	{
		// Get bonus name from dynamic array.
		ArrayGetString(g_szBonusName, iIndex, szCheck, charsmax(szCheck))
		
		// Return bonus ID
		if (equal(szName, szCheck))
		{
			return iIndex
		}
	}
	
	// Doesn't find bonus, Invalid bonus.
	return INVALID_HANDLE
}

public _native_ze_bonus_get_reqlevel(iPlugin_iIndex, iParam_iNum)
{
	// Get a bonus name
	new szName[32]
	get_string(2, szName, charsmax(szName))
	
	// Get required level by bonus name.
	if (strlen(szName) < 1)
	{
		// Find for bonus id by name.
		new szDynArr[32], iNum
		for (iNum = 0; iNum < g_iBonusCount; iNum++)
		{
			// Get bonus name from dynamic array.
			ArrayGetString(g_szBonusName, iNum, szDynArr, charsmax(szDynArr))
			
			// Return bonus Level required.
			if (equal(szDynArr, szName))
			{
				return ArrayGetCell(g_iBonusReqLevel, iNum)
			}
		}	
	}	
	
	// Get bonus ID.
	new iBonus = get_param(1)
	
	// Get required level by bonus id.
	if (iBonus > g_iBonusCount)
	{
		log_error(AMX_ERR_NATIVE, "[AMX] Bonus id is not found (%d)", iBonus)
		return INVALID_HANDLE;
	}
	
	// Return bonus ID.
	return ArrayGetCell(g_iBonusReqLevel, iBonus)
}

public _native_ze_open_bonus_menu(const iPlayer)
{
	// Player is not found.
	if (!is_user_connected(iPlayer))
	{
		log_error(AMX_ERR_NATIVE, "[AMX] Invalid player (%d)", iPlayer)
		return 0;
	}
	
	// Open menu for player.
	Menu_Bonus(iPlayer)
	return 1;
} 
Image

User avatar
z0h1r-LK
Mod Developer
Mod Developer
Morocco
Posts: 476
Joined: 5 years ago
Location: The Red City ❤
Contact:

#2

Post by z0h1r-LK » 2 years ago

give me ze_bonus.ini from your server!

User avatar
z0h1r-LK
Mod Developer
Mod Developer
Morocco
Posts: 476
Joined: 5 years ago
Location: The Red City ❤
Contact:

#3

Post by z0h1r-LK » 2 years ago

I told you this plugin is not stable, I will create another version

czirimbolo
Veteran Member
Veteran Member
Poland
Posts: 598
Joined: 7 years ago
Contact:

#4

Post by czirimbolo » 2 years ago

Its edited by Raheem and its looking good but sometimes it gives error:

Code: Select all

#include <zombie_escape>
#include <ze_levels>

// Settings file.
new const g_szSettingsFile[] = "ze_bonus.ini"

// Enums.
enum
{
	ENABLE_DISABLE = 0,
	ENABLE_ALWAYS,
	ENABLE_COOLDOWN,
	ENABLE_MAXTIMES,
	ENABLE_ONCEROUND,
	ENABLE_ONCEMAP
}

// Dynamic Arrays.
new Array:g_szBonusName,
		Array:g_szBonusHandler,
		Array:g_szBonusPlugin,
		Array:g_iBonusReqLevel,
		Array:g_szPlayerAuthID
		
// Cvars Variables.
new g_pCvarEnableType,
		g_pCvarCooldown,
		g_pCvarMaxTimes
	
// Global Variables.
new g_iBonusCount,
		g_iMaxTimes[MAX_CLIENTS+1],
		Float:g_flCooldownTime[MAX_CLIENTS+1],
		g_iBounsType[MAX_CLIENTS+1]

// Forward called after server activation.
public plugin_init()
{
	// Load plugin.
	register_plugin("[ZE] Bonus Manager", "1.2", "z0h1r-LK")

	// Events.
	register_event("HLTV", "Event_NewRound", "a", "1=0", "2=0")

	// Cvars.
	g_pCvarEnableType = register_cvar("ze_bonus_enable", "5")
	g_pCvarCooldown = register_cvar("ze_bonus_cooldown", "60")
	g_pCvarMaxTimes = register_cvar("ze_bonus_maxtimes", "1")

	// Client command(s).
	register_clcmd("say", "clcmd_SayText")
	register_clcmd("say_team", "clcmd_SayText")
	
	// Initialize dynamic arrays
	g_szBonusPlugin = ArrayCreate(128) // File name.
	g_szPlayerAuthID = ArrayCreate(35)
	g_szBonusHandler = ArrayCreate(32)
	g_szBonusName = ArrayCreate(32)
	g_iBonusReqLevel = ArrayCreate(1)
	
	// Default Values.
	arrayset(g_iMaxTimes, 1, sizeof(g_iMaxTimes))
}

// Forward allows registering natives.
public plugin_natives()
{
	register_native("ze_bonus_register", "_native_ze_bonus_register", 0)
	register_native("ze_bonus_get_name", "_native_ze_bonus_get_name", 0)
	register_native("ze_bonus_get_id", "_native_ze_bonus_get_id", 0)
	register_native("ze_bonus_get_reqlevel", "_native_ze_bonus_get_reqlevel", 0)
	register_native("ze_open_bonus_menu", "_native_ze_open_bonus_menu", 1)
}

// Forward called before server deactivation or plugin fail.
public plugin_end()
{
	// Destroy (remove) all dynamic arrays.
	ArrayDestroy(g_szPlayerAuthID)
}

// Forward called after player join server.
public client_putinserver(iPlayer)
{
	// Bonus Menu is once time in map (Fix enable menu after player reconnect or retry).
	if (get_pcvar_num(g_pCvarEnableType) == ENABLE_ONCEMAP)
	{
		// Variables.
		new szDynArr[35], szAuthID[35], iNum
		
		// Get Auth ID of player (Valve ID or Steam ID).
		get_user_authid(iPlayer, szAuthID, charsmax(szAuthID))
		
		// Check from authid player is already in dynamic array.
		for (iNum = 0; iNum < ArraySize(g_szPlayerAuthID); iNum++)
		{
			// Get Auth ID's from dynamic array.
			ArrayGetString(g_szPlayerAuthID, iNum, szDynArr, charsmax(szDynArr))
			
			// We find Auth ID of player, So, Him is already use a bonus menu.
			if (equali(szAuthID, szDynArr))
			{
				g_iMaxTimes[iPlayer] = 0 // Suspende the menu on player.
				break; // Stop finding for Auth ID in dynamic array.
			}
		}
	}
	
	if (g_iMaxTimes[iPlayer])
	{
		g_iBounsType[iPlayer] = -1;
	}
}

// Hook called every new round.
public Event_NewRound()
{
	// Re-enable getting bonus.
	if ((get_pcvar_num(g_pCvarEnableType) == ENABLE_ONCEROUND))
	{
		// Re-enable the bonus menu for all players.
		arrayset(g_iMaxTimes, 1, sizeof(g_iMaxTimes))
	}
	else if (get_pcvar_num(g_pCvarEnableType) == ENABLE_MAXTIMES) // Reset maximum times for all players.
	{
		// Re-enable the bonus menu for all players.
		arrayset(g_iMaxTimes, get_pcvar_num(g_pCvarMaxTimes), sizeof(g_iMaxTimes))
	}
}

public ze_user_humanized(id)
{
	if (g_iBounsType[id] >= 0)
	{
		set_task(1.0, "DelayReset", id)
	}
}

public DelayReset(id)
{
	ReGive(id, g_iBounsType[id])
}

// Hook called when sent any message in say/say_team.
public clcmd_SayText(iPlayer)
{
	// Bonus menu is disabled.
	if (!get_pcvar_num(g_pCvarEnableType))
		return;
	
	// Read arguments from say and say_team commands (Message). 
	static szArgs[32]
	read_args(szArgs, charsmax(szArgs))
	remove_quotes(szArgs) // Remove quotes from message "Hi!".
	
	// Check the player is trying open the bonus menu.
	if (equali(szArgs, ".bonus") || equali(szArgs, "/bonus") || equali(szArgs, "!bonus"))
	{
		// Player is a zombie.
		if (ze_is_user_zombie(iPlayer))
		{
			// Alert a player!
			ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_ISZOMBIE")
			return;
		}
		
		// Player is not a alive.
		if (!is_user_alive(iPlayer))
		{
			// Alert a player!
			ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_NOTALIVE")
			return;		
		}
		
		// Enable type is once round, So, Player is already use bonus menu. 
		if (get_pcvar_num(g_pCvarEnableType) == ENABLE_ALWAYS)
		{
			// Menu without limit.
			if (!g_iMaxTimes[iPlayer])
				g_iMaxTimes[iPlayer] = 1
		}
		else if ((get_pcvar_num(g_pCvarEnableType) == ENABLE_ONCEROUND) && !g_iMaxTimes[iPlayer])
		{
			// Alert a player!
			ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_NEXTROUND")
			return;
		} 
		else if (get_pcvar_num(g_pCvarEnableType) == ENABLE_COOLDOWN) // Enable type is cooldown
		{
			// Get a game (halflife) time.
			new Float:flGameTime = get_gametime()
		
			// Alert a player, Cooldown time is not over.
			if (flGameTime < g_flCooldownTime[iPlayer])
			{
				ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_COOLDOWN", floatround(g_flCooldownTime[iPlayer] - flGameTime))
				return;
			}
			
			// Re-enable bonus menu for player.
			g_iMaxTimes[iPlayer] = 1
		} 
		else if (get_pcvar_num(g_pCvarEnableType) == ENABLE_ONCEMAP) // Enable type is once time in map.
		{
			// Player is open bonus menu.
			if (!g_iMaxTimes[iPlayer])
			{
				ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_ONCETIME")
				return;
			}
		} 
		else if (get_pcvar_num(g_pCvarEnableType) == ENABLE_MAXTIMES) // Enable type is maximum times.
		{
			// Player can't open bonus menu, Because is reached maximum times.
			if (!g_iMaxTimes[iPlayer])
			{
				ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_MAXTIME")
				return;
			}		
		}
		
		// Open the bonus menu for player.
		Menu_Bonus(iPlayer)
	}
}

public Menu_Bonus(iPlayer)
{
	new szLang[64], szName[32], iLevelPlr, iLevelReq, iNum, iMenu
	
	// Get current Level of the player.
	iLevelPlr = ze_get_user_level(iPlayer)
	
	// Create a new menu with title.
	formatex(szLang, charsmax(szLang), "\r%L:", LANG_PLAYER, "MENU_TITLE_BONUS", iLevelPlr)
	iMenu = menu_create(szLang, "Handler_Bonus")

	// Add all bonus name to menu.
	for (iNum = 0; iNum < g_iBonusCount; iNum++)
	{
		// Get name of bonus from dynamic array.
		ArrayGetString(g_szBonusName, iNum, szName, charsmax(szName))

		// Get a required level to get the bonus.
		iLevelReq = ArrayGetCell(g_iBonusReqLevel, iNum)
		
		// Sort names in menu.
		if (iLevelReq == 0)
			formatex(szLang, charsmax(szLang), "\w%s - \r%L", szName, LANG_PLAYER, "FREE")
		else if (iLevelPlr < iLevelReq)
			formatex(szLang, charsmax(szLang), "\d%s - \r[%d %L]", szName, iLevelReq, LANG_PLAYER, "LVL")
		else
			formatex(szLang, charsmax(szLang), "\y%s - \r%L", szName, LANG_PLAYER, "UNLOCKED")
			
		// Add bonus name to menu.
		menu_additem(iMenu, szLang, "", 0)
	}
	
	// Set menu property (exit, back, next).
	formatex(szLang, charsmax(szLang), "\y%L", LANG_PLAYER, "NEXT")
	menu_setprop(iMenu, MPROP_NEXTNAME, szLang)
	formatex(szLang, charsmax(szLang), "\y%L", LANG_PLAYER, "BACK")	
	menu_setprop(iMenu, MPROP_BACKNAME, szLang)
	formatex(szLang, charsmax(szLang), "\y%L", LANG_PLAYER, "EXIT")	
	menu_setprop(iMenu, MPROP_EXITNAME, szLang)
	
	// Display menu for player and close menu after 30s.
	menu_display(iPlayer, iMenu, 0, 30)
}

// Hook handle command from bonus menu.
public Handler_Bonus(iPlayer, iMenu, iKey)
{
	// Close and destroy menu.
	if (iKey == MENU_EXIT)
	{
		// Destroy (remove) menu.
		menu_destroy(iMenu)
		return PLUGIN_HANDLED;
	}
	
	// Variables.
	new szName[32], szHandler[32], szPlugin[128], iLevelPlr, iLevelReq
		
	// Get current Level of player.	
	iLevelPlr = ze_get_user_level(iPlayer)
	
	// Get a required Level to get the bonus.
	iLevelReq = ArrayGetCell(g_iBonusReqLevel, iKey)
		
	// Check the player is not getting a bonus yet.
	if (g_iMaxTimes[iPlayer])
	{
		// The player's level is greater than the required level (Getting a bonus).
		if (iLevelPlr >= iLevelReq)
		{
			// Get bonus name from dynamic array.
			ArrayGetString(g_szBonusName, iKey, szName, charsmax(szName))
			
			// Get bonus handler function from dynamic array.
			ArrayGetString(g_szBonusHandler, iKey, szHandler, charsmax(szHandler))
			
			// Get bonus plugin filename from dynamic array.
			ArrayGetString(g_szBonusPlugin, iKey, szPlugin, charsmax(szPlugin))
			
			// Call a function in plugin of the bonus
			new iRet = callfunc_begin(szHandler, szPlugin)
			
			// Handler function is not found in plugin of bonus.
			if (iRet == -1)
			{
				log_error(AMX_ERR_NOTFOUND, "[AMX] Function (%s) not found in plugin (%s)", szHandler, szPlugin)
				return PLUGIN_HANDLED;
			}
			
			// Plugin file is not found.
			if (iRet == -2)
			{
				log_error(AMX_ERR_NOTFOUND, "[AMX] Plugin (%s) is not found.", szPlugin)
				return PLUGIN_HANDLED;
			}
			
			callfunc_push_int(iPlayer) // Add Player ID to handler function.
			callfunc_push_int(iKey) // Add Bonus ID to handler function.
			callfunc_end()
			
			g_iBounsType[iPlayer] = iKey
			
			// Sent colored message in chat, (claiming bonus msg).
			ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_DONE", szName)
			
			// Player has taken the bonus.
			if (get_pcvar_num(g_pCvarEnableType) == ENABLE_ONCEROUND)
			{
				// Player has claim some bonus from menu.
				--g_iMaxTimes[iPlayer]
			}
			else if (get_pcvar_num(g_pCvarEnableType) == ENABLE_COOLDOWN)
			{
				// Make a cooldown time for bonus menu on player.
				g_flCooldownTime[iPlayer] = get_gametime() + get_pcvar_float(g_pCvarCooldown)
			}
			else if (get_pcvar_num(g_pCvarEnableType) == ENABLE_ONCEMAP) // That for Fix problem enable menu when player reconnect or retry.
			{
				// Get auth ID of player.
				new szAuthID[35]
				get_user_authid(iPlayer, szAuthID, charsmax(szAuthID))
				
				// Push AuthID of player in dynamic array.
				ArrayPushString(g_szPlayerAuthID, szAuthID)
				
				// Bonus has claimed.
				--g_iMaxTimes[iPlayer]
			}
			else if (get_pcvar_num(g_pCvarEnableType) == ENABLE_MAXTIMES) // Max times in every round.
			{
				--g_iMaxTimes[iPlayer]
				ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_REMTIMES", g_iMaxTimes[iPlayer])
			}
		}
		else // Player haven't Level enough.
		{
			Menu_Bonus(iPlayer)
			ze_colored_print(iPlayer, "%L", LANG_PLAYER, "BONUS_LEVEL_ENOUGH")
		}
	}
	
	// Destroy (remove) menu.
	menu_destroy(iMenu)
	return PLUGIN_HANDLED;
}

public ReGive(iPlayer, iKey)
{
	new szName[32], szHandler[32], szPlugin[128]
	
	// Get bonus name from dynamic array.
	ArrayGetString(g_szBonusName, iKey, szName, charsmax(szName))
	
	// Get bonus handler function from dynamic array.
	ArrayGetString(g_szBonusHandler, iKey, szHandler, charsmax(szHandler))
	
	// Get bonus plugin filename from dynamic array.
	ArrayGetString(g_szBonusPlugin, iKey, szPlugin, charsmax(szPlugin))
	
	if (equal(szHandler, "Handler_PlusTenArmor") || equal(szHandler, "Handler_PlusTenSpeed") || equal(szHandler, "Handler_PlusDamage") || equal(szHandler, "Handler_PlusTenHealth200") || equal(szHandler, "Handler_PlusTenHealth10k") || equal(szHandler, "Handler_PlusTenSpeed30") || equal(szHandler, "Handler_PlusTenArmor100"))
	{
		// Call a function in plugin of the bonus
		new iRet = callfunc_begin(szHandler, szPlugin)
		
		// Handler function is not found in plugin of bonus.
		if (iRet == -1)
		{
			log_error(AMX_ERR_NOTFOUND, "[AMX] Function (%s) not found in plugin (%s)", szHandler, szPlugin)
			return PLUGIN_HANDLED;
		}
		
		// Plugin file is not found.
		if (iRet == -2)
		{
			log_error(AMX_ERR_NOTFOUND, "[AMX] Plugin (%s) is not found.", szPlugin)
			return PLUGIN_HANDLED;
		}
		
		callfunc_push_int(iPlayer) // Add Player ID to handler function.
		callfunc_push_int(iKey) // Add Bonus ID to handler function.
		callfunc_end()
	}
	
	return PLUGIN_HANDLED;
}

// Functions of natives.
public _native_ze_bonus_register(iPlugin_iIndex, iParam_iNum)
{
	new szName[32], szHandler[32], szPlugin[128],  iReqLevel
	get_string(1, szName, charsmax(szName)) // Get name of bonus.
	get_string(2, szHandler, charsmax(szHandler)) // Get handler function of bonus.
	iReqLevel = get_param(3) // Get require level.
	
	// Bonus without name.
	if (strlen(szName) < 0)
	{
		log_error(AMX_ERR_NATIVE, "[AMX] Bonus without name.")
		return INVALID_HANDLE;
	}
	
	// Bonus without handler.
	if (strlen(szHandler) < 0)
	{
		log_error(AMX_ERR_NATIVE, "[AMX] Bonus without handler.")
		return INVALID_HANDLE;
	}
	
	// Get plugin name.
	get_plugin(iPlugin_iIndex, szPlugin, charsmax(szPlugin))
	
	// Bonus name is already registered
	new szDynArr[32], iIndex
	for (iIndex = 0; iIndex < g_iBonusCount; iIndex++)
	{
		// Get bonus name from dynamic array.
		ArrayGetString(g_szBonusName, iIndex, szDynArr, charsmax(szDynArr))
		
		if (equali(szDynArr, szName))
		{
			log_error(AMX_ERR_NATIVE, "[AMX] Bonus name already is registered.")
			return INVALID_HANDLE;
		}
	}
	
	// Load bonus data's from external file.
	if (!amx_load_setting_string(g_szSettingsFile, szName, "NAME", szName, charsmax(szName)))
	{
		amx_save_setting_string(g_szSettingsFile, szName, "NAME", szName)
	}
	
	if (!amx_load_setting_int(g_szSettingsFile, szName, "LEVEL", iReqLevel))
	{
		amx_save_setting_int(g_szSettingsFile, szName, "LEVEL", iReqLevel)
	}
	
	// Register new bonus.
	g_iBonusCount++
	ArrayPushString(g_szBonusName, szName)
	ArrayPushString(g_szBonusHandler, szHandler)
	ArrayPushString(g_szBonusPlugin, szPlugin)
	ArrayPushCell(g_iBonusReqLevel, iReqLevel)
	return g_iBonusCount - 1
}

public _native_ze_bonus_get_name(iPlugin_iIndex, iParam_iNum)
{
	// Get a bonus ID.
	new iBonus = get_param(1)
	
	// Invalid bonus.
	if (iBonus > g_iBonusCount)
	{
		log_error(AMX_ERR_NATIVE, "[AMX] Bonus id is not found (%d)", iBonus)
		return 0;
	}
	
	new szName[32]
	
	// Get name of bonus.
	ArrayGetString(g_szBonusName, iBonus, szName, charsmax(szName))
	
	// Store name in array.
	set_string(2, szName, get_param(3))
	return 1;
}

public _native_ze_bonus_get_id(iPlugin_iIndex, iParam_iNum)
{
	// Get a bonus name
	new szName[32]
	get_string(1, szName, charsmax(szName))
	
	// Find for bonus id by name.
	new szCheck[32], iIndex
	for (iIndex = 0; iIndex < g_iBonusCount; iIndex++)
	{
		// Get bonus name from dynamic array.
		ArrayGetString(g_szBonusName, iIndex, szCheck, charsmax(szCheck))
		
		// Return bonus ID
		if (equal(szName, szCheck))
		{
			return iIndex
		}
	}
	
	// Doesn't find bonus, Invalid bonus.
	return INVALID_HANDLE
}

public _native_ze_bonus_get_reqlevel(iPlugin_iIndex, iParam_iNum)
{
	// Get a bonus name
	new szName[32]
	get_string(2, szName, charsmax(szName))
	
	// Get required level by bonus name.
	if (strlen(szName) < 1)
	{
		// Find for bonus id by name.
		new szDynArr[32], iNum
		for (iNum = 0; iNum < g_iBonusCount; iNum++)
		{
			// Get bonus name from dynamic array.
			ArrayGetString(g_szBonusName, iNum, szDynArr, charsmax(szDynArr))
			
			// Return bonus Level required.
			if (equal(szDynArr, szName))
			{
				return ArrayGetCell(g_iBonusReqLevel, iNum)
			}
		}	
	}	
	
	// Get bonus ID.
	new iBonus = get_param(1)
	
	// Get required level by bonus id.
	if (iBonus > g_iBonusCount)
	{
		log_error(AMX_ERR_NATIVE, "[AMX] Bonus id is not found (%d)", iBonus)
		return INVALID_HANDLE;
	}
	
	// Return bonus ID.
	return ArrayGetCell(g_iBonusReqLevel, iBonus)
}

public _native_ze_open_bonus_menu(const iPlayer)
{
	// Player is not found.
	if (!is_user_connected(iPlayer))
	{
		log_error(AMX_ERR_NATIVE, "[AMX] Invalid player (%d)", iPlayer)
		return 0;
	}
	
	// Open menu for player.
	Menu_Bonus(iPlayer)
	return 1;
} 

Code: Select all

[+3000 coins]
NAME = +3000 coins
LEVEL = 5

[+200 HP]
NAME = +200 HP
LEVEL = 8

[+10 armor]
NAME = +10 armor
LEVEL = 10

[+70k EXP]
NAME = +70k EXP
LEVEL = 14

[+8000 coins]
NAME = +8000 coins
LEVEL = 16

[+200k EXP]
NAME = +200k EXP
LEVEL = 21

[Damage x1.2]
NAME = Damage x1.2
LEVEL = 26

[+20k coins]
NAME = +20k coins
LEVEL = 27

[+10 Speed]
NAME = +10 Speed
LEVEL = 29

[+1mln EXP]
NAME = +1mln EXP
LEVEL = 31

[+30 Speed]
NAME = +30 Speed
LEVEL = 33

[+50k coins]
NAME = +50k coins
LEVEL = 34

[+100 armor]
NAME = +100 armor
LEVEL = 35

[Damage x2]
NAME = Damage x2
LEVEL = 36
L 12/05/2021 - 18:01:01: Invalid index -4 (count: 14)
L 12/05/2021 - 18:01:01: [AMXX] Displaying debug trace (plugin "ze_bonus_manager.amxx", version "1.2")
L 12/05/2021 - 18:01:01: [AMXX] Run time error 10: native error (native "ArrayGetCell")
L 12/05/2021 - 18:01:01: [AMXX] [0] ze_bonus_manager.sma::Handler_Bonus (line 289)
Image

User avatar
z0h1r-LK
Mod Developer
Mod Developer
Morocco
Posts: 476
Joined: 5 years ago
Location: The Red City ❤
Contact:

#5

Post by z0h1r-LK » 2 years ago

I will try create version later

Post Reply

Create an account or sign in to join the discussion

You need to be a member in order to post a reply

Create an account

Not a member? register to join our community
Members can start their own topics & subscribe to topics
It’s free and only takes a minute

Register

Sign in

Who is online

Users browsing this forum: No registered users and 4 guests