Try this: ( I left some comments too where you done wrong )
PHP Code:
/* Issuse:
1. Knife precache
2. Player Model
3. Edit data from ini file
4. Replace g_szTeams name into eData[Team]
*/
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>
#include <engine>
#include <hamsandwich>
#define PLUGIN "New Plug-In"
#define VERSION "1.0"
#define AUTHOR "Supremache"
#if !defined client_disconnected
#define client_disconnected client_disconnect
#endif
#define SetUserModeled(%1) g_bModeled |= ( 1<<(%1 & 31) ) //flag_set
#define SetUserNotModeled(%1) g_bModeled &= ~( 1<<(%1 & 31) )//unset
#define IsUserModeled(%1) ( g_bModeled & ( 1<<(%1 & 31) ) ) //flag_get
#define m_pPlayer 41
#define m_pTeam 114
#define iUserTeam(%1) get_pdata_int(%1, m_pTeam)
#define m_afButtonPressed 246
#define MAX_MENU_LENGTH 512
#define MAX_PLAYERS 32
enum _:Data
{
Name[MAX_PLAYERS],
Info[MAX_PLAYERS],
Model[MAX_PLAYERS],
Knife[MAX_PLAYERS * 2],
Flag[MAX_PLAYERS],
Health,
Armor,
Speed,
Gravity,
KnockBack,
MultiJump,
Team
}
enum _:TotalForwards
{
g_MenuOpened = 0,
g_SelectModel,
g_SetModel
}
new g_iForwards[TotalForwards],
iReturnForward
new Array:Models,
g_iTotalModels,
eData[Data],
g_szAdditionalText[MAX_PLAYERS * 2],
Float:g_iKnockBack[MAX_PLAYERS],
Float:g_iSpeed[MAX_PLAYERS],
g_iJump[MAX_PLAYERS],
g_szCurrentModel[MAX_PLAYERS][MAX_PLAYERS * 2],
g_szFile[MAX_PLAYERS * 8],
g_szTeams[4][MAX_PLAYERS],
g_bModeled,
g_iJumpCount[MAX_PLAYERS + 1],
bool:g_bGiveMultiJump[MAX_PLAYERS + 1],
g_iNextClass[MAX_PLAYERS + 1],
g_iClass[MAX_PLAYERS + 1]
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
register_dictionary("CustomModels.txt");
if( g_iTotalModels )
console_print(0, "* Total Registered Models: %d", g_iTotalModels)
else console_print(0, "* No Models found in the configuration file.")
RegisterHam(Ham_Spawn, "player", "OnPlayerSpawn", 1)
RegisterHam(Ham_Item_Deploy, "weapon_knife", "OnSelectKnife", 1)
RegisterHam(Ham_Player_Jump, "player", "OnCBasePlayer_Jump", false)
g_iForwards[g_MenuOpened] = CreateMultiForward("open_menu", ET_IGNORE, FP_CELL)
g_iForwards[g_SelectModel] = CreateMultiForward("model_selected", ET_IGNORE, FP_CELL, FP_CELL)
g_iForwards[g_SetModel] = CreateMultiForward("set_model", ET_IGNORE, FP_CELL, FP_CELL)
register_forward( FM_SetClientKeyValue, "fw_SetClientKeyValue" );
register_forward( FM_PlayerPreThink, "fw_PlayerPreThink" )
ReadFile()
}
public plugin_precache()
{
Models = ArrayCreate(Data)
// The array should be created before precache.
//Models = ArrayCreate(Data)
get_configsdir(g_szFile, charsmax(g_szFile))
add(g_szFile, charsmax(g_szFile), "/ModelMenu.ini")
}
public client_putinserver( id )
{
g_iClass[id] = 0
g_iNextClass[id] = g_iClass[id]
g_bGiveMultiJump[id] = true
}
public client_disconnected(id)
{
g_iClass[id] = 0
g_iNextClass[id] = 0
g_bGiveMultiJump[id] = false
}
public plugin_natives()
{
register_native("register_model", "_RegisterModels")
register_native("add_text", "_MenuText")
register_native("get_next_class", "_NextClass")
register_native("get_class", "_Class")
}
public _MenuText(iPlugin, iParams)
{
get_string(1, g_szAdditionalText, charsmax(g_szAdditionalText))
}
public _NextClass(iPlugin, iParams)
{
return g_iNextClass[get_param(1)];
}
public _Class(iPlugin, iParams)
{
return g_iClass[get_param(1)];
}
/*Example of native:
//native register_model(
const szName[],
const szInfo[],
const szModel[],
const szKnife[],
const szFlag[],
iHealth,
iArmor,
iSpeed,
Float:iGravity,
Float:iKnockBack,
iMultiJump,
iTeam
);
*/
public _RegisterModels(iPlugin, iParams)
{
get_string(1, eData[Name], charsmax(eData[Name]))
get_string(2, eData[Info], charsmax(eData[Info]))
get_string(3, eData[Model], charsmax(eData[Model]))
get_string(4, eData[Knife], charsmax(eData[Knife]))
get_string(5, eData[Flag], charsmax(eData[Flag]))
eData[Health] = get_param(6)
eData[Armor] = get_param(7)
eData[Speed] = get_param(8)
eData[Gravity] = get_param(9)
eData[KnockBack] = get_param(10)
eData[MultiJump] = get_param(11)
eData[Team] = get_param(12)
new szModel[64];
if(eData[Model] != EOS)
{
formatex( szModel, charsmax( szModel ), "models/player/%s/%s.mdl", eData[Model], eData[Model] );
precache_model( szModel );
}
if(eData[Knife] != EOS)
{
formatex( szModel, charsmax( szModel ), "models/%s.mdl", eData[Knife] );
precache_model( szModel );
}
ArrayPushArray(Models, eData)
g_iTotalModels++
// Why do you wanna return every time the total models num - 1 ??
//return g_iTotalModels - 1
}
public plugin_end()
{
// Why do you loop through array's items if the server is deactivating or map changes?
/*for(new i ; i < g_iTotalModels; i++)
{
ArrayGetArray(Models, i, eData)
}*/
ArrayDestroy(Models)
DestroyForward(g_iForwards[g_MenuOpened])
DestroyForward(g_iForwards[g_SelectModel])
DestroyForward(g_iForwards[g_SetModel])
}
public OnTakeDamage(iVictim, iInflictor, iAttacker)
{
for(new i = 0; i < g_iTotalModels; i++)
{
ArrayGetArray(Models, i, eData)
if( eData[Team] && eData[Team] != iUserTeam(iVictim) )
continue;
if(eData[KnockBack])
{
if(!is_user_connected(iAttacker) || iVictim == iAttacker || iInflictor != iAttacker)
return HAM_IGNORED;
if(iUserTeam(iAttacker) == iUserTeam(iVictim))
return HAM_SUPERCEDE;
new Float:fVelocity[3]
velocity_by_aim(iAttacker, 64, fVelocity)
fVelocity[2] = g_iKnockBack[iAttacker]
set_pev(iVictim, pev_velocity, fVelocity)
}
}
return HAM_SUPERCEDE;
}
public OnCBasePlayer_Jump(id)
{
if ( !g_bGiveMultiJump[id] || !is_user_alive(id))
return HAM_HANDLED
new iFlags = pev(id, pev_flags)
if( iFlags & FL_WATERJUMP || pev(id, pev_waterlevel) >= 2 || !(get_pdata_int(id, m_afButtonPressed) & IN_JUMP))
{
return HAM_IGNORED
}
if (iFlags & FL_ONGROUND)
{
g_iJumpCount[id] = 0
return HAM_IGNORED
}
for(new i = 0; i < g_iTotalModels; i++)
{
ArrayGetArray(Models, i, eData)
if( eData[Team] && eData[Team] != iUserTeam(id) )
continue;
if( g_iJump[id] )
{
if (++g_iJumpCount[id] < g_iJump[id])
{
new Float:fVelocity[3]
pev(id, pev_velocity, fVelocity)
fVelocity[2] = 268.328157
set_pev(id, pev_velocity, fVelocity)
return HAM_HANDLED
}
}
}
return HAM_IGNORED
}
public OnSelectKnife(iEnt)
{
new id = get_pdata_cbase(iEnt, m_pPlayer, 4)
RefreshModel(id)
}
RefreshModel(const id)
{
set_pev(id, pev_viewmodel2, eData[Knife])
}
public fw_SetClientKeyValue( id, const szBuffer[], const szKey[], const szValue[] )
{
if( !equal( szKey, "model" ) )
return FMRES_IGNORED;
for(new i = 0; i < g_iTotalModels; i++)
{
ArrayGetArray(Models, i, eData)
if( eData[Team] && eData[Team] != iUserTeam(id) )
continue;
if(eData[Model])
{
get_user_info(id, "model", g_szCurrentModel[id], charsmax(g_szCurrentModel[]))
if( !IsUserModeled( id ) || !equal( g_szCurrentModel[ id ], eData[Model] ) || !equal( szValue, eData[Model] ) )
{
copy( g_szCurrentModel[ id ], charsmax( g_szCurrentModel[] ),eData[Model] );
SetUserModeled( id );
set_user_info( id, "model", eData[Model] );
return FMRES_SUPERCEDE;
}
if( IsUserModeled( id ) )
{
SetUserNotModeled( id );
g_szCurrentModel[ id ][ 0 ] = 0;
}
}
}
return FMRES_IGNORED;
}
public fw_PlayerPreThink(id)
{
for(new i = 0; i < g_iTotalModels; i++)
{
ArrayGetArray(Models, i, eData)
if( eData[Team] && eData[Team] != iUserTeam(id) )
continue;
if( eData[Speed] )
set_pev(id, pev_maxspeed, g_iSpeed[id])
}
}
public OnPlayerSpawn(id)
{
if(is_user_alive(id))
{
for(new i = 0; i < g_iTotalModels; i++)
{
ArrayGetArray(Models, i, eData)
if( eData[Team] && eData[Team] != iUserTeam(id) )
continue;
if (g_iNextClass[id] != g_iClass[id])
g_iClass[id] = g_iNextClass[id]
if( eData[Knife] )
{
if(get_user_weapon(id) == CSW_KNIFE)
{
RefreshModel(id)
}
}
if( eData[Health] )
set_pev(id, pev_health, float(eData[Health]))
if( eData[Armor] )
set_pev(id, pev_armorvalue, float(eData[Armor]))
if( eData[Gravity] )
set_pev(id, pev_gravity, float(eData[Gravity]))
if( eData[KnockBack] )
g_iKnockBack[id] = float(eData[KnockBack])
if( eData[Speed] )
g_iSpeed[id] = float(eData[Speed])
if( eData[MultiJump] )
g_iJump[id] = eData[MultiJump]
ExecuteForward(g_iForwards[g_SetModel], iReturnForward, id, g_iClass[id])
}
}
}
public CustomMenu(id)
{
new szData[MAX_MENU_LENGTH], szInfo[128], iPages
formatex(szInfo, charsmax(szInfo), "%L %s", id, "MENU_TITLE", g_szTeams[iUserTeam(id)])
new iMenu = menu_create(szInfo, "Handler")
for(new i = 0; i < g_iTotalModels; i++)
{
ArrayGetArray(Models, i, eData)
// wanna reset an array, use this kind of reset
g_szAdditionalText[0] = 0;
if( eData[Team] && eData[Team] != iUserTeam(id) )
continue;
if ( eData[Flag] )
formatex(szData, charsmax(szData), "%s%s \y%s \r[Flag: %s] %s %s",
access(id, eData[Flag]) ? "\w" : "\d", eData[Name], eData[Info], eData[Flag], g_szAdditionalText, ( i == g_iClass[id] ) ? "\r-=\wSELECTED\r=-" : "")
else
formatex(szData, charsmax(szData), "%s%s \y%s %s %s",
access(id, eData[Flag]) ? "\w" : "\d", eData[Name], eData[Info], g_szAdditionalText, ( i == g_iClass[id] ) ? "\r-=\wSELECTED\r=-" : "")
menu_additem(iMenu, szData)
// Don't call forwards in loops.
//ExecuteForward(g_iForwards[g_MenuOpened], iReturnForward, id)
}
formatex(szInfo, charsmax(szInfo), "%L", id, "PREV_PAGE")
menu_setprop(iMenu, MPROP_BACKNAME, szInfo)
formatex(szInfo, charsmax(szInfo), "%L", id, "NEXT_PAGE")
menu_setprop(iMenu, MPROP_NEXTNAME, szInfo)
formatex(szInfo, charsmax(szInfo), "%L", id, "EXIT_MENU")
menu_setprop(iMenu, MPROP_EXITNAME, szInfo)
iPages = menu_pages(iMenu)
if ( !iPages )
{
client_print(id, print_chat, "%L", id, "NOT_MODELS")
return PLUGIN_HANDLED;
}
/*else if(iPages > 1)
{
formatex(szInfo, charsmax(szInfo), "%L %s ^n\wPage:\d", id, "MENU_TITLE", g_szTeams[iUserTeam(id)])
menu_setprop(iMenu, MPROP_TITLE, szInfo)
}*/
menu_display(id, iMenu)
ExecuteForward(g_iForwards[g_MenuOpened], iReturnForward, id)
return PLUGIN_HANDLED;
}
public Handler(id, iMenu, iItem)
{
if(iItem != MENU_EXIT)
{
if(!is_user_alive(id))
{
client_print(id, print_chat, "%L", id, "NOT_ALIVE")
return PLUGIN_HANDLED;
}
ArrayGetArray(Models, iItem, eData)
if( eData[Flag] && !access(id, eData[Flag]) )
{
client_print(id, print_chat, "%L", id, "NOT_ACCESS")
return PLUGIN_HANDLED;
}
g_iClass[id] = iItem
//ExecuteForward(g_iForwards[g_MenuOpened], iReturnForward, id, g_iClass[id])
ExecuteForward(g_iForwards[g_SelectModel], iReturnForward, id, g_iClass[id])
client_print(id, print_chat, "%L", id, "INFO_SELECT",
eData[Name], eData[Health], eData[Armor], eData[Speed], floatround(Float:eData[Gravity] * 800.0), floatround(Float:eData[KnockBack] * 100.0), eData[MultiJump])
}
menu_destroy(iMenu)
return PLUGIN_HANDLED;
}
ReadFile()
{
if( file_exists(g_szFile) )
{
new iFile = fopen( g_szFile, "rt" );
new szData[264], szKey[32], szValue[128]
while(fgets(iFile, szData, charsmax(szData)))
{
trim(szData);
remove_quotes(szData);
switch( szData[ 0 ] )
{
case EOS, '#', ';', '/', '[': continue;
//case '[':
//{
// szData[strlen(szData) - 1] = 0;
// copy(szData, charsmax(szData), szData[1])
// continue;
//}
default:
{
strtok( szData, szKey, charsmax(szKey), szValue, charsmax(szValue), '=' );
trim(szKey); trim(szValue);
if( ! szValue[ 0 ] || ! szKey[ 0 ] )
continue;
if(equal(szKey, "MENU_COMMANDS"))
{
while(szValue[0] != 0 && strtok(szValue, szKey, charsmax(szKey), szValue, charsmax(szValue), ','))
{
trim(szKey); trim(szValue)
register_clcmd(szKey, "CustomMenu")
}
}
else if(equal(szKey, "TEAM_NAMES"))
{
for(new i = 0; i < 4; i++)
{
strtok(szValue, szKey, charsmax(szKey), szValue, charsmax(szValue), ',')
trim(szKey); trim(szValue)
copy(g_szTeams[i], charsmax(g_szTeams[]), szKey)
}
}
else if(equal(szKey, "NAME"))
copy(eData[Name], charsmax(eData[Name]), szValue)
else if(equal(szKey, "INFO"))
copy(eData[Info], charsmax(eData[Info]), szValue)
else if(equal(szKey, "MODEL"))
{
while(szValue[0] != 0 && strtok(szValue, szKey, charsmax(szKey), szValue, charsmax(szValue), ','))
{
trim(szKey); trim(szValue)
copy(eData[Model], charsmax(eData[Model]), szValue)
}
}
else if(equal(szKey, "KNIFE"))
copy(eData[Knife], charsmax(eData[Knife]), szValue)
else if(equal(szKey, "FLAG"))
copy(eData[Flag], charsmax(eData[Flag]), szValue)
else if(equal(szKey, "HP"))
eData[Health] = str_to_num(szValue)
else if(equal(szKey, "ARMOR"))
eData[Armor] = str_to_num(szValue)
else if(equal(szKey, "SPEED"))
eData[Speed] = str_to_num(szValue)
else if(equal(szKey, "GRAVITY"))
eData[Gravity] = _:str_to_float(szValue)
else if(equal(szKey, "KB"))
eData[KnockBack] = _:str_to_float(szValue)
else if(equal(szKey, "MJ"))
eData[MultiJump] = str_to_num(szValue)
//else if(equal(szKey, "LEVEL"))
// eData[Level] = str_to_num(szValue)
else if(equal(szKey, "TEAM"))
eData[Team] = str_to_num(szValue)
}
}
}
fclose( iFile );
}
else
{
delete_file(g_szFile)
new iFile = fopen(g_szFile, "at")
if(iFile)
{
fputs(iFile, "[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]^n")
fputs(iFile, "[] Model Menu API: Configuration file []^n")
fputs(iFile, "[] AUTHOR: Supremache []^n")
fputs(iFile, "[] Any changes you make here will be automatically loaded at map start. []^n")
fputs(iFile, "[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]^n^n")
fputs(iFile, "MENU_COMMANDS = say /skin, say_team /skin, say /model, say_team /model, custommodel^n")
fputs(iFile, "TEAM_NAMES = Unassigned, Terrorist, Counter-Terrorist, Spectator^n")
fputs(iFile, "ENABLE_RANK = ^n")
for(new i = 0; i < g_iTotalModels; i++)
{
ArrayGetArray(Models, i, eData)
fprintf(iFile, "^n[%s]", eData[Name])
fprintf(iFile, "^nNAME = %s", eData[Name])
fprintf(iFile, "^nINFO = %s", eData[Info])
fprintf(iFile, "^nMODEL = %s", eData[Model])
fprintf(iFile, "^nKNIFE = %s", eData[Knife])
fprintf(iFile, "^nFLAG = %s", eData[Flag])
fprintf(iFile, "^nHP = %d", eData[Health])
fprintf(iFile, "^nARMOR = %d", eData[Armor])
fprintf(iFile, "^nSPEED = %d", eData[Speed])
// dont use "%.2f" if you don't know what is does, use standard "%f" and it should be fine
fprintf(iFile, "^nGRAVITY = %f", Float:eData[Gravity])
fprintf(iFile, "^nKB = %f", Float:eData[KnockBack])
fprintf(iFile, "^nMJ = %d", eData[MultiJump])
fprintf(iFile, "^nTEAM = %s^n", g_szTeams[eData[Team]])
}
fclose( iFile );
}
}
}
/*
ReadFile()
{
if( file_exists(g_szFile) )
{
new iFile = fopen( g_szFile, "rt" );
new szData[264], szKey[32], szValue[128], iSection = SECTION_NONE
while(fgets(iFile, szData, charsmax(szData)))
{
trim(szData);
remove_quotes(szData);
switch( szData[ 0 ] )
{
case EOS, '#', ';', '/', '[': continue;
default:
{
if(iSection == SECTION_NONE)
{
continue
}
strtok( szData, szKey, charsmax(szKey), szValue, charsmax(szValue), '=' );
trim(szKey); trim(szValue);
if( ! szValue[ 0 ] || ! szKey[ 0 ] )
continue;
switch(iSection)
{
case SECTION_SETTINGS:
{
if(equal(szKey, "MENU_COMMANDS"))
{
while(szValue[0] != 0 && strtok(szValue, szKey, charsmax(szKey), szValue, charsmax(szValue), ','))
{
trim(szKey); trim(szValue)
register_clcmd(szKey, "CustomMenu")
}
}
else if(equal(szKey, "TEAM_NAMES"))
{
for(new i = 0; i < 2; i++)
{
strtok(szValue, szKey, charsmax(szKey), szValue, charsmax(szValue), ',')
trim(szKey); trim(szValue)
copy(g_szTeams[i], charsmax(g_szTeams[]), szKey)
}
}
}
case SECTION_OPTIONS:
{
if(equal(szKey, "NAME"))
copy(eData[Name], charsmax(eData[Name]), szValue)
else if(equal(szKey, "INFO"))
copy(eData[Info], charsmax(eData[Info]), szValue)
else if(equal(szKey, "MODEL"))
copy(eData[Model], charsmax(eData[Model]), szValue)
else if(equal(szKey, "KNIFE"))
copy(eData[Knife], charsmax(eData[Knife]), szValue)
else if(equal(szKey, "FLAG"))
copy(eData[Flag], charsmax(eData[Flag]), szValue)
else if(equal(szKey, "HP"))
eData[Health] = str_to_num(szValue)
else if(equal(szKey, "SPEED"))
eData[Speed] = str_to_num(szValue)
else if(equal(szKey, "GRAVITY"))
eData[Gravity] = _:str_to_float(szValue)
else if(equal(szKey, "KB"))
eData[KnockBack] = _:str_to_float(szValue)
else if(equal(szKey, "TEAM"))
eData[Team] = str_to_num(szValue)
//ArraySetArray(Models, iModel, eData)
}
}
}
}
}
fclose( iFile );
}
}
LoadFile()
{
new iFile = fopen(g_szFile, "wt")
if(iFile)
{
fputs(iFile, "[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]^n")
fputs(iFile, "[] Model Menu API: Configuration file []^n")
fputs(iFile, "[] AUTHOR: Supremache []^n")
fputs(iFile, "[] Any changes you make here will be automatically loaded at map start. []^n")
fputs(iFile, "[][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][][]^n^n")
fputs(iFile, "MENU_COMMANDS = say /skin, say_team /skin, say /model, say_team /model, custommodel^n")
fputs(iFile, "TEAM_NAMES = Terrorist, Counter-Terrorist^n")
for(new i = 0; i < g_iTotalModels; i++)
{
ArrayGetArray(Models, i, eData)
fprintf(iFile, "^n[%s]", eData[Name])
fprintf(iFile, "^nNAME = %s", eData[Name])
fprintf(iFile, "^nINFO = %s", eData[Info])
fprintf(iFile, "^nMODEL = %s", eData[Model])
fprintf(iFile, "^nKNIFE = %s", eData[Knife])
fprintf(iFile, "^nFLAG = %s", eData[Flag])
fprintf(iFile, "^nHP = %d", eData[Health])
fprintf(iFile, "^nARMOR = %d", eData[Armor])
fprintf(iFile, "^nSPEED = %d", eData[Speed])
fprintf(iFile, "^nGRAVITY = %.2f", Float:eData[Gravity])
fprintf(iFile, "^nKB = %.2f", Float:eData[KnockBack])
fprintf(iFile, "^nMJ = %d", eData[MultiJump])
//fprintf(iFile, "^nTEAM = %s", g_szTeams[eData[Team]])
}
fclose( iFile );
}
}
*/