OciXCrom Knife Models не сохраняет модели

Статус
В этой теме нельзя размещать новые ответы.
Сообщения
3,582
Реакции
1,570
Помог
137 раз(а)
Ошибка
OciXCrom Knife Models не сохраняет выбранную модель ножа.
В логах ошибок нет.
ОС
Linux
Amx Mod X
AMX Mod X 1.10.0.5252
Билд
ReHLDS version: 3.4.0.669-dev
ReGamedll
ReGameDLL version: 5.7.0.328-dev
Версия Metamod
Metamod-r v1.3.0.128, API (5:13)
Список метамодулей
Currently loaded plugins:
description stat pend file vers src load unload
[ 1] Reunion RUN - reunion_mm_i386.so v0.1.0.133 ini Start Never
[ 2] ReAuthCheck RUN - reauthcheck_mm_i386.so v0.1.6 ini Start Never
[ 3] Rechecker RUN - rechecker_mm_i386.so v2.5 ini Chlvl ANY
[ 4] Revoice RUN - revoice_mm_i386.so v0.1.0.32 ini Start Never
[ 5] AMX Mod X RUN - amxmodx_mm_i386.so v1.10.0.5252 ini Start ANY
[ 6] MySQL RUN - mysql_amxx_i386.so v1.10.0.5252 pl5 ANY ANY
[ 7] SQLite RUN - sqlite_amxx_i386.so v1.10.0.5252 pl5 ANY ANY
[ 8] Fun RUN - fun_amxx_i386.so v1.10.0.5252 pl5 ANY ANY
[ 9] Engine RUN - engine_amxx_i386.so v1.10.0.5252 pl5 ANY ANY
[10] FakeMeta RUN - fakemeta_amxx_i386.so v1.10.0.5252 pl5 ANY ANY
[11] CStrike RUN - cstrike_amxx_i386.so v1.10.0.5252 pl5 ANY ANY
[12] Ham Sandwich RUN - hamsandwich_amxx_i386.so v1.10.0.5252 pl5 ANY ANY
[13] ReAPI RUN - reapi_amxx_i386.so v5.8.0.166-dev pl5 ANY Never
[14] GeoIP RUN - geoip_amxx_i386.so v1.10.0.5252 pl5 ANY ANY

[15] whois RUN - whois_amxx_i386.so v0.2.270 pl5 ANY ANY
[16] CURL AMXX RUN - curl_amxx_i386.so v1.1.0 pl5 ANY ANY
16 plugins, 16 running
Список плагинов
Currently loaded plugins:
name version author file status
[ 1] fb_forwards 0.1.4 Kanagava & Realu fb_forwards.amx running
[ 2] WebHS 0.1 kanagava fb_web_online.a running
[ 3] FreshBans 1.4.0b kanagava fresh_bans_140_ running
[ 4] SF Warn Menu 0.1.4g_edi serfreeman1337/N sf_admin_warns. running
[ 5] CSStatsX SQL 0.7.4+1 serfreeman1337 csstatsx_sql.am running
[ 6] Rank Menu 1.1 h1k3 rankmenu.amxx running
[ 7] AES: StatsX 0.5 Vega serfreeman1337 statsx_cstrike. running
[ 8] Multi-Rendering System [ReAPI] 0. Subb98/Nordic Wa multirendering. running
[ 9] Admin Load 3.10.0 F@nt0M adminload.amxx running
[ 10] Admin Commands 1.10.0.525 AMXX Dev Team admincmd.amxx running
[ 11] Admin Help 1.10.0.525 AMXX Dev Team adminhelp.amxx running
[ 12] Menus Front-End 1.10.0.525 AMXX Dev Team menufront.amxx running
[ 13] Commands Menu 1.10.0.525 AMXX Dev Team cmdmenu.amxx running
[ 14] Players Menu 1.10.0.525 AMXX Dev Team plmenu.amxx running

[ 15] Teleport Menu 1.10.0.525 AMXX Dev Team telemenu.amxx running
[ 16] Maps Menu 1.10.0.525 AMXX Dev Team mapsmenu.amxx running
[ 17] Admin Chat 1.10.0.525 AMXX Dev Team adminchat.amxx running
[ 18] Anti Flood 1.10.0.525 AMXX Dev Team antiflood.amxx running
[ 19] Admin Votes 1.10.0.525 AMXX Dev Team adminvote.amxx running
[ 20] Pause Plugins 1.10.0.525 AMXX Dev Team pausecfg.amxx running
[ 21] Stats Configuration 1.10.0.525 AMXX Dev Team statscfg.amxx running
[ 22] unknown unknown unknown 35hp_16.amxx stopped
[ 23] AdminMenu 1.1 Nordic Warrior adminmenu.amxx running
[ 24] Admin menu central 0.2 Nordic Warrior adminmenu_centr running
[ 25] Advanced Lottery 0.5.1 Nordic Warrior advanced_lotter running
[ 26] [ReAPI] Advanced Team 0.1.0 Vaqtincha AdvancedTeamCho running
[ 27] Advert Messages 1.22 neygomon adverts.amxx running
[ 28] AFK Protection 2.3.3 rapara13/Nordic afk.amxx running
[ 29] AimInfo 2.1 xPaw/Nordic Warr aim_info.amxx running

[ 30] Ball 1.2.1 xPaw/Nordic Warr ball.amxx running
[ 31] BhopHack Detector 0.1 Mistrick bhophack_detect running
[ 32] [Reapi] Block Advert 1.4 neygomon block_advert.am running
[ 33] Bypass Guard 24.05.2019 mx?! bypass_guard_ip running
[ 34] CameraChanger Lite 0.1 Nordic Warrior camera_changer. running
[ 35] Advanced Client Checke 0.3.7e Mistrick cmdchecker.amxx running
[ 36] Connect Exec 1.1 AleX/Nordic Warr connect_exec.am running
[ 37] Chat Manager 4.4 OciXCrom crx_chatmanager running
[ 38] CM: Toggle Chat 4.1 OciXCrom crx_chatmanager running
[ 39] OciXCrom's Rank System 3.4 OciXCrom crx_ranksystem. running
[ 40] Knife Models 3.1 OciXCrom crx_knife_model running
[ 41] [ReAPI] Custom Models 1.6.1 neugomon custom_models.a running
[ 42] Demo Recorder 2.4.0 F@nt0M demo_recorder.a running
[ 43] Fix for sky 1.0 Nordic Warrior fix_maps.amxx running
[ 44] Gag System 1.1 TheRedShoko @ AM gag_system.amxx running

[ 45] GameName Changer 1.0 neugomon gamename.amxx running
[ 46] High Ping Kicker 1.0 OLO/shadow/Nordi high_ping_kicke running
[ 47] iFLY 1.0 arttty7 iFLY.amxx debug
[ 48] iHOOK 1.0 arttty7 iHOOK.amxx running
[ 49] Invisible Spectator 1.0 ReHLDS Team invisible_spect running
[ 50] Kill Distance 0.4 Nightscream/Nord kill_distance.a running
[ 51] Knife Duel Arena 1.32 bionext knife_duel_aren debug
[ 52] Knife Duel Arena Edito 1.0 bionext knife_duel_aren paused
[ 53] Knife Duel Arena Edito 0.2 Nordic Warrior knife_duel_aren running
[ 54] Knife Duel Arena Block 0.2 bionext/Nordic W knife_duel_aren running
[ 55] Language Menu 1.0 F@nt0M langmenu.amxx running
[ 56] Light Menu 0.3 Nordic Warrior light_menu.amxx running
[ 57] Mind Games 1.1 fifayer/Nordic W MindGames.amxx running
[ 58] Money System Best t3rkecorejz MoneySystem.amx running
[ 59] Mute Menu 12.02.2019 w0w/Nordic Warri mute_menu.amxx running

[ 60] New Grab 1.0 Nordic Warrior/N new_grab.amxx running
[ 61] KillStreakAnnouncer 0.3 Nordic Warrior nkillstreak.amx running
[ 62] Knife Menu 1.3 Nordic Warrior nknifemenu.amxx running
[ 63] Knife shop 0.2.1 Nordic Warrior nknifeshop.amxx running
[ 64] Online Helper 2.1.3 Nordic Warrior online_helper.a running
[ 65] Paint Marker 1.1 w0w paint_marker.am running
[ 66] [ReAPI] Parachute 1.1 ReHLDS Team parachute.amxx running
[ 67] Pingwinowa bombka 0.1 diablix pingwin.amxx running
[ 68] Poll 1.1 Nunfy poll.amxx debug
[ 69] Random Skies 1.1 rmk by N.W. randomskies.amx running
[ 70] ReChecker Logging 1.0 custom rc_logging.amxx running
[ 71] Reset Score 1.0 Nordic Warrior reset_score.amx running
[ 72] Spectator Bots 2.1 SISA spectator_bots. running
[ 73] SteamID Limiter 0.4 Mistrick steamid_limiter running
[ 74] Money Transfer 1.2 x3/Nordic Warrio tm.amxx debug

[ 75] Train Killer 1.2 Pastout!/Nordic trainkiller.amx running
[ 76] VipMenu 1.0 Nordic Warrior vipmenu.amxx running
[ 77] Yet Another Voteban 1.8 AndrewZ/voed yet_another_vot running
[ 78] Map Manager: Core 3.0.1 Mistrick map_manager_cor running
[ 79] Map Manager: Scheduler 0.1.0 Mistrick map_manager_sch running
[ 80] Map Manager: Rtv 0.0.4 Mistrick map_manager_rtv running
[ 81] Map Manager: Nominatio 0.0.8 Mistrick map_manager_nom running
[ 82] Map Manager: Online so 0.0.2 Mistrick map_manager_onl running
[ 83] Map Manager: Effects 0.0.8 Mistrick map_manager_eff running
[ 84] Map Manager: Informer 0.0.5 Mistrick map_manager_inf running
[ 85] Map Manager: Advanced 0.0.4 Mistrick map_manager_adv running
85 plugins, 83 running
Автор плагина
OciXCrom
Версия плагина
3.1
Исходный код
#include <amxmodx>
#include <amxmisc>
#include <crxknives_const>
#include <cromchat>
#include <fakemeta>
#include <hamsandwich>
#include <nvault>

native crxranks_get_max_levels()
native crxranks_get_rank_by_level(level, buffer[], len)
native crxranks_get_user_level(id)
native crxranks_get_user_xp(id)

new const g_szNatives[][] =
{
"crxranks_get_max_levels",
"crxranks_get_rank_by_level",
"crxranks_get_user_level",
"crxranks_get_user_xp"
}

#if !defined m_pPlayer
const m_pPlayer = 41
#endif

#if !defined client_disconnected
#define client_disconnected client_disconnect
#endif

new const PLUGIN_VERSION[] = "3.1"
const Float:DELAY_ON_CONNECT = 3.0

#if !defined MAX_AUTHID_LENGTH
const MAX_AUTHID_LENGTH = 35
#endif

#if !defined MAX_NAME_LENGTH
const MAX_NAME_LENGTH = 32
#endif

#if !defined MAX_PLAYERS
const MAX_PLAYERS = 32
#endif

enum
{
SOUND_NONE = 0,
SOUND_DEPLOY,
SOUND_HIT,
SOUND_HITWALL,
SOUND_SLASH,
SOUND_STAB
}

enum _:Knives
{
NAME[MAX_NAME_LENGTH],
V_MODEL[CRXKNIVES_MAX_SOUND_LENGTH],
P_MODEL[CRXKNIVES_MAX_SOUND_LENGTH],
DEPLOY_SOUND[CRXKNIVES_MAX_SOUND_LENGTH],
HIT_SOUND[CRXKNIVES_MAX_SOUND_LENGTH],
HITWALL_SOUND[CRXKNIVES_MAX_SOUND_LENGTH],
SLASH_SOUND[CRXKNIVES_MAX_SOUND_LENGTH],
STAB_SOUND[CRXKNIVES_MAX_SOUND_LENGTH],
SELECT_SOUND[CRXKNIVES_MAX_SOUND_LENGTH],
FLAG,
LEVEL,
XP,
SELECT_MESSAGES_NUM,
bool:SHOW_RANK,
bool:HAS_CUSTOM_SOUND,
Array:SELECT_MESSAGES,
Trie:ATTRIBUTES
}

enum _:CvarsReg
{
cvar_km_open_at_spawn,
cvar_km_save_choice,
cvar_km_only_dead,
cvar_km_select_message,
cvar_km_knife_only_skills,
cvar_km_admin_bypass
}

enum _:Cvars
{
km_open_at_spawn,
km_save_choice,
km_only_dead,
km_select_message,
km_knife_only_skills,
km_admin_bypass
}

new Array:g_aKnives,
bool:g_bFirstTime[MAX_PLAYERS + 1],
bool:g_bRankSystem,
bool:g_bGetLevel,
bool:g_bGetXP,
g_eCvars[Cvars],
g_eCvarsReg[CvarsReg],
g_eKnife[MAX_PLAYERS + 1][Knives],
g_szAuth[MAX_PLAYERS + 1][MAX_AUTHID_LENGTH],
g_iKnife[MAX_PLAYERS + 1],
g_fwdKnifeUpdated,
g_fwdAttemptChange,
g_iMenuFlags,
g_iKnivesNum,
g_iCallback,
g_iVault

public plugin_init()
{
register_plugin("Knife Models", PLUGIN_VERSION, "OciXCrom")
register_cvar("CRXKnifeModels", PLUGIN_VERSION, FCVAR_SERVER|FCVAR_SPONLY|FCVAR_UNLOGGED)

if(!g_iKnivesNum)
{
set_fail_state("No knives found in the configuration file.")
}

register_dictionary("KnifeModels.txt")

RegisterHam(Ham_Spawn, "player", "OnPlayerSpawn", 1)
register_forward(FM_EmitSound, "OnEmitSound")
RegisterHam(Ham_Item_Deploy, "weapon_knife", "OnSelectKnife", 1)

register_clcmd("say /knife", "Cmd_Knife")
register_clcmd("say_team /knife", "Cmd_Knife")
register_clcmd("say /skins", "Cmd_Knife")
register_clcmd("say_team /skins", "Cmd_Knife")
register_clcmd("crxknives_select", "Cmd_Select", _, "<knife id>")

g_fwdKnifeUpdated = CreateMultiForward("crxknives_knife_updated", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL)
g_fwdAttemptChange = CreateMultiForward("crxknives_attempt_change", ET_STOP, FP_CELL, FP_CELL)

g_iCallback = menu_makecallback("CheckKnifeAccess")

g_eCvarsReg[cvar_km_open_at_spawn] = register_cvar("km_open_at_spawn", "0")
g_eCvarsReg[cvar_km_save_choice] = register_cvar("km_save_choice", "1")
g_eCvarsReg[cvar_km_only_dead] = register_cvar("km_only_dead", "0")
g_eCvarsReg[cvar_km_select_message] = register_cvar("km_select_message", "1")
g_eCvarsReg[cvar_km_knife_only_skills] = register_cvar("km_knife_only_skills", "1")
g_eCvarsReg[cvar_km_admin_bypass] = register_cvar("km_admin_bypass", "0")
}

public plugin_precache()
{
if(LibraryExists("crxranks", LibType_Library))
{
g_bRankSystem = true
}

g_aKnives = ArrayCreate(Knives)
ReadFile()
}

public plugin_cfg()
{
g_eCvars[km_save_choice] = get_pcvar_num(g_eCvarsReg[cvar_km_save_choice])
g_eCvars[km_open_at_spawn] = get_pcvar_num(g_eCvarsReg[cvar_km_open_at_spawn])
g_eCvars[km_only_dead] = get_pcvar_num(g_eCvarsReg[cvar_km_only_dead])
g_eCvars[km_select_message] = get_pcvar_num(g_eCvarsReg[cvar_km_select_message])
g_eCvars[km_knife_only_skills] = get_pcvar_num(g_eCvarsReg[cvar_km_knife_only_skills])
g_eCvars[km_admin_bypass] = get_pcvar_num(g_eCvarsReg[cvar_km_admin_bypass])

if(g_eCvars[km_save_choice])
{
g_iVault = nvault_open("KnifeModels")
}
}

public plugin_end()
{
for(new eKnife[Knives], i; i < g_iKnivesNum; i++)
{
ArrayGetArray(g_aKnives, i, eKnife)
ArrayDestroy(eKnife[SELECT_MESSAGES])
TrieDestroy(eKnife[ATTRIBUTES])
}

ArrayDestroy(g_aKnives)

if(g_eCvars[km_save_choice])
{
nvault_close(g_iVault)
}
}

ReadFile()
{
new szFilename[256]
get_configsdir(szFilename, charsmax(szFilename))
add(szFilename, charsmax(szFilename), "/KnifeModels.ini")
new iFilePointer = fopen(szFilename, "rt")

if(iFilePointer)
{
new szData[160], szKey[32], szValue[128], szSound[128], iMaxLevels
new eKnife[Knives], bool:bCustom

if(g_bRankSystem)
{
iMaxLevels = crxranks_get_max_levels()
}

while(!feof(iFilePointer))
{
fgets(iFilePointer, szData, charsmax(szData))
trim(szData)

switch(szData[0])
{
case EOS, '#', ';': continue
case '[':
{
if(szData[strlen(szData) - 1] == ']')
{
if(g_iKnivesNum)
{
push_knife(eKnife)
}

g_iKnivesNum++
replace(szData, charsmax(szData), "[", "")
replace(szData, charsmax(szData), "]", "")
copy(eKnife[NAME], charsmax(eKnife[NAME]), szData)

eKnife[V_MODEL][0] = EOS
eKnife[P_MODEL][0] = EOS
eKnife[DEPLOY_SOUND][0] = EOS
eKnife[HIT_SOUND][0] = EOS
eKnife[HITWALL_SOUND][0] = EOS
eKnife[SLASH_SOUND][0] = EOS
eKnife[STAB_SOUND][0] = EOS
eKnife[SELECT_SOUND][0] = EOS
eKnife[FLAG] = ADMIN_ALL
eKnife[HAS_CUSTOM_SOUND] = false
eKnife[SELECT_MESSAGES_NUM] = 0
eKnife[SELECT_MESSAGES] = _:ArrayCreate(CRXKNIVES_MAX_MESSAGE_LENGTH)
eKnife[ATTRIBUTES] = _:TrieCreate()

if(g_bRankSystem)
{
eKnife[LEVEL] = 0
eKnife[SHOW_RANK] = false
eKnife[XP] = 0
}

static const ATTRIBUTE_NAME[] = "NAME"
TrieSetString(eKnife[ATTRIBUTES], ATTRIBUTE_NAME, szData)
}
else continue
}
default:
{
strtok(szData, szKey, charsmax(szKey), szValue, charsmax(szValue), '=')
trim(szKey); trim(szValue)
bCustom = true

TrieSetString(eKnife[ATTRIBUTES], szKey, szValue)

if(equal(szKey, "FLAG"))
{
eKnife[FLAG] = read_flags(szValue)
g_iMenuFlags |= eKnife[FLAG]
}
else if(equal(szKey, "LEVEL") && g_bRankSystem)
{
eKnife[LEVEL] = clamp(str_to_num(szValue), 0, iMaxLevels)

if(!g_bGetLevel)
{
g_bGetLevel = true
}
}
else if(equal(szKey, "SHOW_RANK") && g_bRankSystem)
{
eKnife[SHOW_RANK] = _:clamp(str_to_num(szValue), false, true)
}
else if(equal(szKey, "XP") && g_bRankSystem)
{
eKnife[XP] = _:clamp(str_to_num(szValue), 0)

if(!g_bGetXP)
{
g_bGetXP = true
}
}
else if(equal(szKey, "V_MODEL"))
{
copy(eKnife[V_MODEL], charsmax(eKnife[V_MODEL]), szValue)
}
else if(equal(szKey, "P_MODEL"))
{
copy(eKnife[P_MODEL], charsmax(eKnife[P_MODEL]), szValue)
}
else if(equal(szKey, "DEPLOY_SOUND"))
{
copy(eKnife[DEPLOY_SOUND], charsmax(eKnife[DEPLOY_SOUND]), szValue)
}
else if(equal(szKey, "HIT_SOUND"))
{
copy(eKnife[HIT_SOUND], charsmax(eKnife[HIT_SOUND]), szValue)
}
else if(equal(szKey, "HITWALL_SOUND"))
{
copy(eKnife[HITWALL_SOUND], charsmax(eKnife[HITWALL_SOUND]), szValue)
}
else if(equal(szKey, "SLASH_SOUND"))
{
copy(eKnife[SLASH_SOUND], charsmax(eKnife[SLASH_SOUND]), szValue)
}
else if(equal(szKey, "STAB_SOUND"))
{
copy(eKnife[STAB_SOUND], charsmax(eKnife[STAB_SOUND]), szValue)
}
else if(equal(szKey, "SELECT_SOUND"))
{
bCustom = false
copy(eKnife[SELECT_SOUND], charsmax(eKnife[SELECT_SOUND]), szValue)
}
else if(equal(szKey, "SELECT_MESSAGE"))
{
ArrayPushString(eKnife[SELECT_MESSAGES], szValue)
eKnife[SELECT_MESSAGES_NUM]++
}
else continue

static const szModelArg[] = "_MODEL"
static const szSoundArg[] = "_SOUND"

if(contain(szKey, szModelArg) != -1)
{
if(!file_exists(szValue))
{
log_amx("ERROR: model ^"%s^" not found!", szValue)
}
else
{
precache_model(szValue)
}
}
else if(contain(szKey, szSoundArg) != -1)
{
formatex(szSound, charsmax(szSound), "sound/%s", szValue)

if(!file_exists(szSound))
{
log_amx("ERROR: sound ^"%s^" not found!", szSound)
}
else
{
precache_sound(szValue)
}

if(bCustom)
{
eKnife[HAS_CUSTOM_SOUND] = true
}
}
}
}
}

if(g_iKnivesNum)
{
push_knife(eKnife)
}

fclose(iFilePointer)
}
}

public client_connect(id)
{
g_bFirstTime[id] = true
ArrayGetArray(g_aKnives, 0, g_eKnife[id])
g_iKnife[id] = 0

new iReturn
ExecuteForward(g_fwdKnifeUpdated, iReturn, id, g_iKnife[id], true)

if(g_eCvars[km_save_choice])
{
get_user_authid(id, g_szAuth[id], charsmax(g_szAuth[]))
set_task(DELAY_ON_CONNECT, "load_data", id)
}
}

public client_disconnected(id)
{
if(g_eCvars[km_save_choice])
{
use_vault(id, true)
}
}

public OnEmitSound(id, iChannel, const szSample[])
{
if(!is_user_connected(id) || !g_eKnife[id][HAS_CUSTOM_SOUND] || !is_knife_sound(szSample))
{
return FMRES_IGNORED
}

switch(detect_knife_sound(szSample))
{
case SOUND_DEPLOY: if(g_eKnife[id][DEPLOY_SOUND][0]) { play_knife_sound(id, g_eKnife[id][DEPLOY_SOUND][0]); return FMRES_SUPERCEDE; }
case SOUND_HIT: if(g_eKnife[id][HIT_SOUND][0]) { play_knife_sound(id, g_eKnife[id][HIT_SOUND][0]); return FMRES_SUPERCEDE; }
case SOUND_HITWALL: if(g_eKnife[id][HITWALL_SOUND][0]) { play_knife_sound(id, g_eKnife[id][HITWALL_SOUND][0]); return FMRES_SUPERCEDE; }
case SOUND_SLASH: if(g_eKnife[id][SLASH_SOUND][0]) { play_knife_sound(id, g_eKnife[id][SLASH_SOUND][0]); return FMRES_SUPERCEDE; }
case SOUND_STAB: if(g_eKnife[id][STAB_SOUND][0]) { play_knife_sound(id, g_eKnife[id][STAB_SOUND][0]); return FMRES_SUPERCEDE; }
}

return FMRES_IGNORED
}

public Cmd_Knife(id)
{
if(g_eCvars[km_only_dead] && is_user_alive(id))
{
CC_SendMessage(id, "%l %l", "KM_CHAT_PREFIX", "KM_ONLY_DEAD")
return PLUGIN_HANDLED
}

static eKnife[Knives]
new szTitle[128], szItem[128], iLevel, iXP
formatex(szTitle, charsmax(szTitle), "%L", id, "KM_MENU_TITLE")

if(g_bGetLevel)
{
iLevel = crxranks_get_user_level(id)
}

if(g_bGetXP)
{
iXP = crxranks_get_user_xp(id)
}

new iMenu = menu_create(szTitle, "MenuHandler")

for(new iFlags = get_user_flags(id), i; i < g_iKnivesNum; i++)
{
ArrayGetArray(g_aKnives, i, eKnife)
copy(szItem, charsmax(szItem), eKnife[NAME])

if(g_bRankSystem)
{
if(eKnife[LEVEL] && iLevel < eKnife[LEVEL])
{
if(eKnife[SHOW_RANK])
{
static szRank[32]
crxranks_get_rank_by_level(eKnife[LEVEL], szRank, charsmax(szRank))
format(szItem, charsmax(szItem), "%s %L", szItem, id, "KM_MENU_RANK", szRank)
}
else
{
format(szItem, charsmax(szItem), "%s %L", szItem, id, "KM_MENU_LEVEL", eKnife[LEVEL])
}
}

if(eKnife[XP] && iXP < eKnife[XP])
{
format(szItem, charsmax(szItem), "%s %L", szItem, id, "KM_MENU_XP", eKnife[XP])
}
}

if(eKnife[FLAG] != ADMIN_ALL && !(iFlags & eKnife[FLAG]))
{
format(szItem, charsmax(szItem), "%s %L", szItem, id, "KM_MENU_VIP_ONLY")
}

if(g_iKnife[id] == i)
{
format(szItem, charsmax(szItem), "%s %L", szItem, id, "KM_MENU_SELECTED")
}

menu_additem(iMenu, szItem, eKnife[NAME], eKnife[FLAG], g_iCallback)
}

if(menu_pages(iMenu) > 1)
{
formatex(szItem, charsmax(szItem), "%s%L", szTitle, id, "KM_MENU_TITLE_PAGE")
menu_setprop(iMenu, MPROP_TITLE, szItem)
}

menu_display(id, iMenu)
return PLUGIN_HANDLED
}

public Cmd_Select(id, iLevel, iCid)
{
if(!cmd_access(id, iLevel, iCid, 2))
{
return PLUGIN_HANDLED
}

if(g_eCvars[km_only_dead] && is_user_alive(id))
{
CC_SendMessage(id, "%l %l", "KM_CHAT_PREFIX", "KM_ONLY_DEAD")
return PLUGIN_HANDLED
}

new szKnife[4]
read_argv(1, szKnife, charsmax(szKnife))

new iKnife = str_to_num(szKnife)

if(!is_knife_valid(iKnife))
{
console_print(id, "%l", "KM_INVALID_KNIFE", g_iKnivesNum - 1)
return PLUGIN_HANDLED
}

if(!has_knife_access(id, iKnife))
{
console_print(id, "%l", "KM_NO_ACCESS")
return PLUGIN_HANDLED
}

select_knife(id, iKnife)
return PLUGIN_HANDLED
}

public MenuHandler(id, iMenu, iItem)
{
if(g_eCvars[km_only_dead] && is_user_alive(id))
{
CC_SendMessage(id, "%l %l", "KM_CHAT_PREFIX", "KM_ONLY_DEAD")
goto @MENU_DESTROY
}

if(!is_user_connected(id))
{
goto @MENU_DESTROY
}

if(iItem != MENU_EXIT)
{
select_knife(id, iItem)
}

@MENU_DESTROY:
menu_destroy(iMenu)
return PLUGIN_HANDLED
}

select_knife(id, iKnife)
{
new iReturn
ExecuteForward(g_fwdAttemptChange, iReturn, id, iKnife)

if(iReturn == PLUGIN_HANDLED)
{
return
}

g_iKnife[id] = iKnife
ArrayGetArray(g_aKnives, iKnife, g_eKnife[id])
ExecuteForward(g_fwdKnifeUpdated, iReturn, id, iKnife, false)

if(is_user_alive(id) && get_user_weapon(id) == CSW_KNIFE)
{
refresh_knife_model(id)
}

if(g_eCvars[km_select_message])
{
CC_SendMessage(id, "%l %l", "KM_CHAT_PREFIX", "KM_CHAT_SELECTED", g_eKnife[id][NAME])
}

if(g_eKnife[id][SELECT_MESSAGES_NUM])
{
for(new i; i < g_eKnife[id][SELECT_MESSAGES_NUM]; i++)
{
CC_SendMessage(id, "%a", ArrayGetStringHandle(g_eKnife[id][SELECT_MESSAGES], i))
}
}

if(g_eKnife[id][SELECT_SOUND][0])
{
play_knife_sound(id, g_eKnife[id][SELECT_SOUND])
}
}

public load_data(id)
{
if(is_user_connected(id))
{
use_vault(id, false)
}
}

public CheckKnifeAccess(id, iMenu, iItem)
{
return ((g_iKnife[id] == iItem) || !has_knife_access(id, iItem)) ? ITEM_DISABLED : ITEM_ENABLED
}

public OnPlayerSpawn(id)
{
if(is_user_alive(id) && g_eCvars[km_open_at_spawn] && !g_iKnife[id] && g_bFirstTime[id] && (g_iMenuFlags & ADMIN_USER || get_user_flags(id) & g_iMenuFlags))
{
g_bFirstTime[id] = false
Cmd_Knife(id)
}
}

public OnSelectKnife(iEnt)
{
new id = get_pdata_cbase(iEnt, m_pPlayer, 4)

if(is_user_connected(id))
{
refresh_knife_model(id)
}
}

refresh_knife_model(const id)
{
set_pev(id, pev_viewmodel2, g_eKnife[id][V_MODEL])
set_pev(id, pev_weaponmodel2, g_eKnife[id][P_MODEL])
}

push_knife(eKnife[Knives])
{
if(!eKnife[V_MODEL][0])
{
copy(eKnife[V_MODEL], charsmax(eKnife[V_MODEL]), CRXKNIVES_DEFAULT_V)
}

if(!eKnife[P_MODEL][0])
{
copy(eKnife[P_MODEL], charsmax(eKnife[P_MODEL]), CRXKNIVES_DEFAULT_P)
}

if(!eKnife[FLAG])
{
g_iMenuFlags |= ADMIN_USER
}

ArrayPushArray(g_aKnives, eKnife)
}

bool:has_knife_access(const id, const iKnife)
{
static eKnife[Knives]
ArrayGetArray(g_aKnives, iKnife, eKnife)

if(eKnife[FLAG] != ADMIN_ALL)
{
if(get_user_flags(id) & eKnife[FLAG])
{
if(g_eCvars[km_admin_bypass])
{
return true
}
}
else
{
return false
}
}

if(g_bRankSystem)
{
if(eKnife[LEVEL] && crxranks_get_user_level(id) < eKnife[LEVEL])
{
return false
}

if(eKnife[XP] && crxranks_get_user_xp(id) < eKnife[XP])
{
return false
}
}

return true
}

bool:is_knife_sound(const szSample[])
{
return bool:equal(szSample[8], "kni", 3)
}

detect_knife_sound(const szSample[])
{
static iSound
iSound = SOUND_NONE

if(equal(szSample, "weapons/knife_deploy1.wav"))
{
iSound = SOUND_DEPLOY
}
else if(equal(szSample[14], "hit", 3))
{
iSound = szSample[17] == 'w' ? SOUND_HITWALL : SOUND_HIT
}
else if(equal(szSample[14], "sla", 3))
{
iSound = SOUND_SLASH
}
else if(equal(szSample[14], "sta", 3))
{
iSound = SOUND_STAB
}

return iSound
}

use_vault(const id, const bool:bSave)
{
if(bSave)
{
new szData[4]
num_to_str(g_iKnife[id], szData, charsmax(szData))
nvault_set(g_iVault, g_szAuth[id], szData)
}
else
{
new iKnife
iKnife = nvault_get(g_iVault, g_szAuth[id])

if(!is_knife_valid(iKnife))
{
iKnife = 0
}
else if(has_knife_access(id, iKnife))
{
g_iKnife[id] = iKnife

new iReturn
ArrayGetArray(g_aKnives, iKnife, g_eKnife[id])
ExecuteForward(g_fwdKnifeUpdated, iReturn, id, iKnife, false)

if(is_user_alive(id) && get_user_weapon(id) == CSW_KNIFE)
{
refresh_knife_model(id)
}
}
}
}

play_knife_sound(const id, const szSound[])
{
engfunc(EngFunc_EmitSound, id, CHAN_AUTO, szSound, 1.0, ATTN_NORM, 0, PITCH_NORM)
}

bool:is_knife_valid(const iKnife)
{
return 0 <= iKnife < g_iKnivesNum
}

public plugin_natives()
{
register_library("crxknives")
register_native("crxknives_can_use_skill", "_crxknives_can_use_skill")
register_native("crxknives_get_attribute_int", "_crxknives_get_attribute_int")
register_native("crxknives_get_attribute_float", "_crxknives_get_attribute_float")
register_native("crxknives_get_attribute_str", "_crxknives_get_attribute_str")
register_native("crxknives_get_knives_num", "_crxknives_get_knives_num")
register_native("crxknives_get_user_knife", "_crxknives_get_user_knife")
register_native("crxknives_has_knife_access", "_crxknives_has_knife_access")
register_native("crxknives_is_knife_valid", "_crxknives_is_knife_valid")
set_native_filter("native_filter")
}

public native_filter(const szNative[], id, iTrap)
{
if(!iTrap)
{
static i

for(i = 0; i < sizeof(g_szNatives); i++)
{
if(equal(szNative, g_szNatives[i]))
{
return PLUGIN_HANDLED
}
}
}

return PLUGIN_CONTINUE
}

public bool:_crxknives_can_use_skill(iPlugin, iParams)
{
return !g_eCvars[km_knife_only_skills] || (get_user_weapon(get_param(1)) == CSW_KNIFE)
}

public bool:_crxknives_get_attribute_int(iPlugin, iParams)
{
static szAttribute[MAX_NAME_LENGTH], szValue[CRXKNIVES_MAX_ATTRIBUTE_LENGTH], id
get_string(2, szAttribute, charsmax(szAttribute))
id = get_param(1)

if(!get_param(4))
{
if(!is_knife_valid(id))
{
return false
}

static eKnife[Knives]
ArrayGetArray(g_aKnives, id, eKnife)

if(!TrieKeyExists(eKnife[ATTRIBUTES], szAttribute))
{
return false
}

TrieGetString(eKnife[ATTRIBUTES], szAttribute, szValue, charsmax(szValue))
goto @SET_ATTRIBUTE
}

if(!TrieKeyExists(g_eKnife[id][ATTRIBUTES], szAttribute))
{
return false
}

TrieGetString(g_eKnife[id][ATTRIBUTES], szAttribute, szValue, charsmax(szValue))

@SET_ATTRIBUTE:
set_param_byref(3, str_to_num(szValue))
return true
}

public bool:_crxknives_get_attribute_float(iPlugin, iParams)
{
static szAttribute[MAX_NAME_LENGTH], szValue[CRXKNIVES_MAX_ATTRIBUTE_LENGTH], id
get_string(2, szAttribute, charsmax(szAttribute))
id = get_param(1)

if(!get_param(4))
{
if(!is_knife_valid(id))
{
return false
}

static eKnife[Knives]
ArrayGetArray(g_aKnives, id, eKnife)

if(!TrieKeyExists(eKnife[ATTRIBUTES], szAttribute))
{
return false
}

TrieGetString(eKnife[ATTRIBUTES], szAttribute, szValue, charsmax(szValue))
goto @SET_ATTRIBUTE
}

if(!TrieKeyExists(g_eKnife[id][ATTRIBUTES], szAttribute))
{
return false
}

TrieGetString(g_eKnife[id][ATTRIBUTES], szAttribute, szValue, charsmax(szValue))

@SET_ATTRIBUTE:
set_float_byref(3, str_to_float(szValue))
return true
}

public bool:_crxknives_get_attribute_str(iPlugin, iParams)
{
static szAttribute[MAX_NAME_LENGTH], szValue[CRXKNIVES_MAX_ATTRIBUTE_LENGTH], id
get_string(2, szAttribute, charsmax(szAttribute))
id = get_param(1)

if(!get_param(5))
{
if(!is_knife_valid(id))
{
return false
}

static eKnife[Knives]
ArrayGetArray(g_aKnives, id, eKnife)

if(!TrieKeyExists(eKnife[ATTRIBUTES], szAttribute))
{
return false
}

TrieGetString(eKnife[ATTRIBUTES], szAttribute, szValue, charsmax(szValue))
goto @SET_ATTRIBUTE
}

if(!TrieKeyExists(g_eKnife[id][ATTRIBUTES], szAttribute))
{
return false
}

TrieGetString(g_eKnife[id][ATTRIBUTES], szAttribute, szValue, charsmax(szValue))

@SET_ATTRIBUTE:
set_string(3, szValue, get_param(4))
return true
}

public _crxknives_get_knives_num(iPlugin, iParams)
{
return g_iKnivesNum
}

public _crxknives_get_user_knife(iPlugin, iParams)
{
return g_iKnife[get_param(1)]
}

public bool:_crxknives_has_knife_access(iPlugin, iParams)
{
return has_knife_access(get_param(1), get_param(2))
}

public bool:_crxknives_is_knife_valid(iPlugin, iParams)
{
return is_knife_valid(get_param(1))
}
OciXCrom Knife Models не сохраняет выбранную модель ножа.
В логах ошибок нет.
12 Июн 2019
OciXCrom
 
В этой теме было размещено решение! Перейти к решению.
Сообщения
3,582
Реакции
1,570
Помог
137 раз(а)
Откатился на версию 3.0 — сохраняет нормально. Однако хочется все же использовать новейшую версию.
OciXCrom
 
Сообщения
594
Реакции
350
Предупреждения
1
Помог
9 раз(а)
Сообщения
3,582
Реакции
1,570
Помог
137 раз(а)
steelzzz, что за бред? Я бы писал сюда, если б мог исправить? Головой думай прежде чем писать
 
Сообщения
3,582
Реакции
1,570
Помог
137 раз(а)
Проблема решена следующим способом:


Diff:
#include <amxmodx>
#include <amxmisc>
#include <crxknives_const>
#include <cromchat>
#include <fakemeta>
#include <hamsandwich>
#include <nvault>

native crxranks_get_max_levels()
native crxranks_get_rank_by_level(level, buffer[], len)
native crxranks_get_user_level(id)
native crxranks_get_user_xp(id)

new const g_szNatives[][] =
{
    "crxranks_get_max_levels",
    "crxranks_get_rank_by_level",
    "crxranks_get_user_level",
    "crxranks_get_user_xp"
}

#if !defined m_pPlayer
const m_pPlayer = 41
#endif

#if !defined client_disconnected
    #define client_disconnected client_disconnect
#endif

new const PLUGIN_VERSION[] = "3.1"
-const Float:DELAY_ON_CONNECT = 3.0

#if !defined MAX_AUTHID_LENGTH
const MAX_AUTHID_LENGTH = 35
#endif

#if !defined MAX_NAME_LENGTH
const MAX_NAME_LENGTH = 32
#endif

#if !defined MAX_PLAYERS
const MAX_PLAYERS = 32
#endif

enum
{
    SOUND_NONE = 0,
    SOUND_DEPLOY,
    SOUND_HIT,
    SOUND_HITWALL,
    SOUND_SLASH,
    SOUND_STAB
}

enum _:Knives
{
    NAME[MAX_NAME_LENGTH],
    V_MODEL[CRXKNIVES_MAX_SOUND_LENGTH],
    P_MODEL[CRXKNIVES_MAX_SOUND_LENGTH],
    DEPLOY_SOUND[CRXKNIVES_MAX_SOUND_LENGTH],
    HIT_SOUND[CRXKNIVES_MAX_SOUND_LENGTH],
    HITWALL_SOUND[CRXKNIVES_MAX_SOUND_LENGTH],
    SLASH_SOUND[CRXKNIVES_MAX_SOUND_LENGTH],
    STAB_SOUND[CRXKNIVES_MAX_SOUND_LENGTH],
    SELECT_SOUND[CRXKNIVES_MAX_SOUND_LENGTH],
    FLAG,
    LEVEL,
    XP,
    SELECT_MESSAGES_NUM,
    bool:SHOW_RANK,
    bool:HAS_CUSTOM_SOUND,
    Array:SELECT_MESSAGES,
    Trie:ATTRIBUTES
}

enum _:CvarsReg
{
    cvar_km_open_at_spawn,
    cvar_km_save_choice,
    cvar_km_only_dead,
    cvar_km_select_message,
    cvar_km_knife_only_skills,
    cvar_km_admin_bypass
}

enum _:Cvars
{
    km_open_at_spawn,
    km_save_choice,
    km_only_dead,
    km_select_message,
    km_knife_only_skills,
    km_admin_bypass
}

new Array:g_aKnives,
    bool:g_bFirstTime[MAX_PLAYERS + 1],
    bool:g_bRankSystem,
    bool:g_bGetLevel,
    bool:g_bGetXP,
    g_eCvars[Cvars],
    g_eCvarsReg[CvarsReg],
    g_eKnife[MAX_PLAYERS + 1][Knives],
    g_szAuth[MAX_PLAYERS + 1][MAX_AUTHID_LENGTH],
    g_iKnife[MAX_PLAYERS + 1],
    g_fwdKnifeUpdated,
    g_fwdAttemptChange,
    g_iMenuFlags,
    g_iKnivesNum,
    g_iCallback,
    g_iVault

public plugin_init()
{
    register_plugin("Knife Models", PLUGIN_VERSION, "OciXCrom")
    register_cvar("CRXKnifeModels", PLUGIN_VERSION, FCVAR_SERVER|FCVAR_SPONLY|FCVAR_UNLOGGED)

    if(!g_iKnivesNum)
    {
        set_fail_state("No knives found in the configuration file.")
    }

    register_dictionary("KnifeModels.txt")

    RegisterHam(Ham_Spawn, "player", "OnPlayerSpawn", 1)
    register_forward(FM_EmitSound,    "OnEmitSound")
    RegisterHam(Ham_Item_Deploy, "weapon_knife", "OnSelectKnife", 1)

    register_clcmd("say /knife",       "Cmd_Knife")
    register_clcmd("say_team /knife",  "Cmd_Knife")
    register_clcmd("say /skins",       "Cmd_Knife")
    register_clcmd("say_team /skins",  "Cmd_Knife")
    register_clcmd("crxknives_select", "Cmd_Select", _, "<knife id>")

    g_fwdKnifeUpdated  = CreateMultiForward("crxknives_knife_updated",  ET_IGNORE, FP_CELL, FP_CELL, FP_CELL)
    g_fwdAttemptChange = CreateMultiForward("crxknives_attempt_change", ET_STOP,   FP_CELL, FP_CELL)

    g_iCallback = menu_makecallback("CheckKnifeAccess")

    g_eCvarsReg[cvar_km_open_at_spawn]     = register_cvar("km_open_at_spawn",     "0")
    g_eCvarsReg[cvar_km_save_choice]       = register_cvar("km_save_choice",       "1")
    g_eCvarsReg[cvar_km_only_dead]         = register_cvar("km_only_dead",         "0")
    g_eCvarsReg[cvar_km_select_message]    = register_cvar("km_select_message",    "1")
    g_eCvarsReg[cvar_km_knife_only_skills] = register_cvar("km_knife_only_skills", "1")
    g_eCvarsReg[cvar_km_admin_bypass]      = register_cvar("km_admin_bypass",      "0")
}

public plugin_precache()
{
    if(LibraryExists("crxranks", LibType_Library))
    {
        g_bRankSystem = true
    }

    g_aKnives = ArrayCreate(Knives)
    ReadFile()
}

public plugin_cfg()
{
    g_eCvars[km_save_choice]       = get_pcvar_num(g_eCvarsReg[cvar_km_save_choice])
    g_eCvars[km_open_at_spawn]     = get_pcvar_num(g_eCvarsReg[cvar_km_open_at_spawn])
    g_eCvars[km_only_dead]         = get_pcvar_num(g_eCvarsReg[cvar_km_only_dead])
    g_eCvars[km_select_message]    = get_pcvar_num(g_eCvarsReg[cvar_km_select_message])
    g_eCvars[km_knife_only_skills] = get_pcvar_num(g_eCvarsReg[cvar_km_knife_only_skills])
    g_eCvars[km_admin_bypass]      = get_pcvar_num(g_eCvarsReg[cvar_km_admin_bypass])

    if(g_eCvars[km_save_choice])
    {
        g_iVault = nvault_open("KnifeModels")
    }
}

public plugin_end()
{
    for(new eKnife[Knives], i; i < g_iKnivesNum; i++)
    {
        ArrayGetArray(g_aKnives, i, eKnife)
        ArrayDestroy(eKnife[SELECT_MESSAGES])
        TrieDestroy(eKnife[ATTRIBUTES])
    }

    ArrayDestroy(g_aKnives)

    if(g_eCvars[km_save_choice])
    {
        nvault_close(g_iVault)
    }
}

ReadFile()
{
    new szFilename[256]
    get_configsdir(szFilename, charsmax(szFilename))
    add(szFilename, charsmax(szFilename), "/KnifeModels.ini")
    new iFilePointer = fopen(szFilename, "rt")

    if(iFilePointer)
    {
        new szData[160], szKey[32], szValue[128], szSound[128], iMaxLevels
        new eKnife[Knives], bool:bCustom

        if(g_bRankSystem)
        {
            iMaxLevels = crxranks_get_max_levels()
        }

        while(!feof(iFilePointer))
        {
            fgets(iFilePointer, szData, charsmax(szData))
            trim(szData)

            switch(szData[0])
            {
                case EOS, '#', ';': continue
                case '[':
                {
                    if(szData[strlen(szData) - 1] == ']')
                    {
                        if(g_iKnivesNum)
                        {
                            push_knife(eKnife)
                        }

                        g_iKnivesNum++
                        replace(szData, charsmax(szData), "[", "")
                        replace(szData, charsmax(szData), "]", "")
                        copy(eKnife[NAME], charsmax(eKnife[NAME]), szData)

                        eKnife[V_MODEL][0] = EOS
                        eKnife[P_MODEL][0] = EOS
                        eKnife[DEPLOY_SOUND][0] = EOS
                        eKnife[HIT_SOUND][0] = EOS
                        eKnife[HITWALL_SOUND][0] = EOS
                        eKnife[SLASH_SOUND][0] = EOS
                        eKnife[STAB_SOUND][0] = EOS
                        eKnife[SELECT_SOUND][0] = EOS
                        eKnife[FLAG] = ADMIN_ALL
                        eKnife[HAS_CUSTOM_SOUND] = false
                        eKnife[SELECT_MESSAGES_NUM] = 0
                        eKnife[SELECT_MESSAGES] = _:ArrayCreate(CRXKNIVES_MAX_MESSAGE_LENGTH)
                        eKnife[ATTRIBUTES] = _:TrieCreate()

                        if(g_bRankSystem)
                        {
                            eKnife[LEVEL] = 0
                            eKnife[SHOW_RANK] = false
                            eKnife[XP] = 0
                        }

                        static const ATTRIBUTE_NAME[] = "NAME"
                        TrieSetString(eKnife[ATTRIBUTES], ATTRIBUTE_NAME, szData)
                    }
                    else continue
                }
                default:
                {
                    strtok(szData, szKey, charsmax(szKey), szValue, charsmax(szValue), '=')
                    trim(szKey); trim(szValue)
                    bCustom = true

                    TrieSetString(eKnife[ATTRIBUTES], szKey, szValue)

                    if(equal(szKey, "FLAG"))
                    {
                        eKnife[FLAG] = read_flags(szValue)
                        g_iMenuFlags |= eKnife[FLAG]
                    }
                    else if(equal(szKey, "LEVEL") && g_bRankSystem)
                    {
                        eKnife[LEVEL] = clamp(str_to_num(szValue), 0, iMaxLevels)

                        if(!g_bGetLevel)
                        {
                            g_bGetLevel = true
                        }
                    }
                    else if(equal(szKey, "SHOW_RANK") && g_bRankSystem)
                    {
                        eKnife[SHOW_RANK] = _:clamp(str_to_num(szValue), false, true)
                    }
                    else if(equal(szKey, "XP") && g_bRankSystem)
                    {
                        eKnife[XP] = _:clamp(str_to_num(szValue), 0)

                        if(!g_bGetXP)
                        {
                            g_bGetXP = true
                        }
                    }
                    else if(equal(szKey, "V_MODEL"))
                    {
                        copy(eKnife[V_MODEL], charsmax(eKnife[V_MODEL]), szValue)
                    }
                    else if(equal(szKey, "P_MODEL"))
                    {
                        copy(eKnife[P_MODEL], charsmax(eKnife[P_MODEL]), szValue)
                    }
                    else if(equal(szKey, "DEPLOY_SOUND"))
                    {
                        copy(eKnife[DEPLOY_SOUND], charsmax(eKnife[DEPLOY_SOUND]), szValue)
                    }
                    else if(equal(szKey, "HIT_SOUND"))
                    {
                        copy(eKnife[HIT_SOUND], charsmax(eKnife[HIT_SOUND]), szValue)
                    }
                    else if(equal(szKey, "HITWALL_SOUND"))
                    {
                        copy(eKnife[HITWALL_SOUND], charsmax(eKnife[HITWALL_SOUND]), szValue)
                    }
                    else if(equal(szKey, "SLASH_SOUND"))
                    {
                        copy(eKnife[SLASH_SOUND], charsmax(eKnife[SLASH_SOUND]), szValue)
                    }
                    else if(equal(szKey, "STAB_SOUND"))
                    {
                        copy(eKnife[STAB_SOUND], charsmax(eKnife[STAB_SOUND]), szValue)
                    }
                    else if(equal(szKey, "SELECT_SOUND"))
                    {
                        bCustom = false
                        copy(eKnife[SELECT_SOUND], charsmax(eKnife[SELECT_SOUND]), szValue)
                    }
                    else if(equal(szKey, "SELECT_MESSAGE"))
                    {
                        ArrayPushString(eKnife[SELECT_MESSAGES], szValue)
                        eKnife[SELECT_MESSAGES_NUM]++
                    }
                    else continue

                    static const szModelArg[] = "_MODEL"
                    static const szSoundArg[] = "_SOUND"

                    if(contain(szKey, szModelArg) != -1)
                    {
                        if(!file_exists(szValue))
                        {
                            log_amx("ERROR: model ^"%s^" not found!", szValue)
                        }
                        else
                        {
                            precache_model(szValue)
                        }
                    }
                    else if(contain(szKey, szSoundArg) != -1)
                    {
                        formatex(szSound, charsmax(szSound), "sound/%s", szValue)

                        if(!file_exists(szSound))
                        {
                            log_amx("ERROR: sound ^"%s^" not found!", szSound)
                        }
                        else
                        {
                            precache_sound(szValue)
                        }

                        if(bCustom)
                        {
                            eKnife[HAS_CUSTOM_SOUND] = true
                        }
                    }
                }
            }
        }

        if(g_iKnivesNum)
        {
            push_knife(eKnife)
        }

        fclose(iFilePointer)
    }
}

public client_connect(id)
{
    g_bFirstTime[id] = true
    ArrayGetArray(g_aKnives, 0, g_eKnife[id])
    g_iKnife[id] = 0

    new iReturn
    ExecuteForward(g_fwdKnifeUpdated, iReturn, id, g_iKnife[id], true)

    if(g_eCvars[km_save_choice])
    {
        get_user_authid(id, g_szAuth[id], charsmax(g_szAuth[]))
+        use_vault(id, false)
-        set_task(DELAY_ON_CONNECT, "load_data", id)
    }
}

public client_disconnected(id)
{
    if(g_eCvars[km_save_choice])
    {
        use_vault(id, true)
    }
}

public OnEmitSound(id, iChannel, const szSample[])
{
    if(!is_user_connected(id) || !g_eKnife[id][HAS_CUSTOM_SOUND] || !is_knife_sound(szSample))
    {
        return FMRES_IGNORED
    }

    switch(detect_knife_sound(szSample))
    {
        case SOUND_DEPLOY:         if(g_eKnife[id][DEPLOY_SOUND][0])         { play_knife_sound(id, g_eKnife[id][DEPLOY_SOUND][0]);      return FMRES_SUPERCEDE; }
        case SOUND_HIT:         if(g_eKnife[id][HIT_SOUND][0])             { play_knife_sound(id, g_eKnife[id][HIT_SOUND][0]);         return FMRES_SUPERCEDE; }
        case SOUND_HITWALL:        if(g_eKnife[id][HITWALL_SOUND][0])         { play_knife_sound(id, g_eKnife[id][HITWALL_SOUND][0]);     return FMRES_SUPERCEDE; }
        case SOUND_SLASH:         if(g_eKnife[id][SLASH_SOUND][0])         { play_knife_sound(id, g_eKnife[id][SLASH_SOUND][0]);       return FMRES_SUPERCEDE; }
        case SOUND_STAB:         if(g_eKnife[id][STAB_SOUND][0])         { play_knife_sound(id, g_eKnife[id][STAB_SOUND][0]);        return FMRES_SUPERCEDE; }
    }

    return FMRES_IGNORED
}

public Cmd_Knife(id)
{
    if(g_eCvars[km_only_dead] && is_user_alive(id))
    {
        CC_SendMessage(id, "%l %l", "KM_CHAT_PREFIX", "KM_ONLY_DEAD")
        return PLUGIN_HANDLED
    }

    static eKnife[Knives]
    new szTitle[128], szItem[128], iLevel, iXP
    formatex(szTitle, charsmax(szTitle), "%L", id, "KM_MENU_TITLE")

    if(g_bGetLevel)
    {
        iLevel = crxranks_get_user_level(id)
    }

    if(g_bGetXP)
    {
        iXP = crxranks_get_user_xp(id)
    }

    new iMenu = menu_create(szTitle, "MenuHandler")

    for(new iFlags = get_user_flags(id), i; i < g_iKnivesNum; i++)
    {
        ArrayGetArray(g_aKnives, i, eKnife)
        copy(szItem, charsmax(szItem), eKnife[NAME])

        if(g_bRankSystem)
        {
            if(eKnife[LEVEL] && iLevel < eKnife[LEVEL])
            {
                if(eKnife[SHOW_RANK])
                {
                    static szRank[32]
                    crxranks_get_rank_by_level(eKnife[LEVEL], szRank, charsmax(szRank))
                    format(szItem, charsmax(szItem), "%s %L", szItem, id, "KM_MENU_RANK", szRank)
                }
                else
                {
                    format(szItem, charsmax(szItem), "%s %L", szItem, id, "KM_MENU_LEVEL", eKnife[LEVEL])
                }
            }

            if(eKnife[XP] && iXP < eKnife[XP])
            {
                format(szItem, charsmax(szItem), "%s %L", szItem, id, "KM_MENU_XP", eKnife[XP])
            }
        }

        if(eKnife[FLAG] != ADMIN_ALL && !(iFlags & eKnife[FLAG]))
        {
            format(szItem, charsmax(szItem), "%s %L", szItem, id, "KM_MENU_VIP_ONLY")
        }

        if(g_iKnife[id] == i)
        {
            format(szItem, charsmax(szItem), "%s %L", szItem, id, "KM_MENU_SELECTED")
        }

        menu_additem(iMenu, szItem, eKnife[NAME], eKnife[FLAG], g_iCallback)
    }

    if(menu_pages(iMenu) > 1)
    {
        formatex(szItem, charsmax(szItem), "%s%L", szTitle, id, "KM_MENU_TITLE_PAGE")
        menu_setprop(iMenu, MPROP_TITLE, szItem)
    }

    menu_display(id, iMenu)
    return PLUGIN_HANDLED
}

public Cmd_Select(id, iLevel, iCid)
{
    if(!cmd_access(id, iLevel, iCid, 2))
    {
        return PLUGIN_HANDLED
    }

    if(g_eCvars[km_only_dead] && is_user_alive(id))
    {
        CC_SendMessage(id, "%l %l", "KM_CHAT_PREFIX", "KM_ONLY_DEAD")
        return PLUGIN_HANDLED
    }

    new szKnife[4]
    read_argv(1, szKnife, charsmax(szKnife))

    new iKnife = str_to_num(szKnife)

    if(!is_knife_valid(iKnife))
    {
        console_print(id, "%l", "KM_INVALID_KNIFE", g_iKnivesNum - 1)
        return PLUGIN_HANDLED
    }

    if(!has_knife_access(id, iKnife))
    {
        console_print(id, "%l", "KM_NO_ACCESS")
        return PLUGIN_HANDLED
    }

    select_knife(id, iKnife)
    return PLUGIN_HANDLED
}

public MenuHandler(id, iMenu, iItem)
{
    if(g_eCvars[km_only_dead] && is_user_alive(id))
    {
        CC_SendMessage(id, "%l %l", "KM_CHAT_PREFIX", "KM_ONLY_DEAD")
        goto @MENU_DESTROY
    }

    if(!is_user_connected(id))
    {
        goto @MENU_DESTROY
    }

    if(iItem != MENU_EXIT)
    {
        select_knife(id, iItem)
    }

    @MENU_DESTROY:
    menu_destroy(iMenu)
    return PLUGIN_HANDLED
}

select_knife(id, iKnife)
{
    new iReturn
    ExecuteForward(g_fwdAttemptChange, iReturn, id, iKnife)

    if(iReturn == PLUGIN_HANDLED)
    {
        return
    }

    g_iKnife[id] = iKnife
    ArrayGetArray(g_aKnives, iKnife, g_eKnife[id])
    ExecuteForward(g_fwdKnifeUpdated, iReturn, id, iKnife, false)

    if(is_user_alive(id) && get_user_weapon(id) == CSW_KNIFE)
    {
        refresh_knife_model(id)
    }

    if(g_eCvars[km_select_message])
    {
        CC_SendMessage(id, "%l %l", "KM_CHAT_PREFIX", "KM_CHAT_SELECTED", g_eKnife[id][NAME])
    }

    if(g_eKnife[id][SELECT_MESSAGES_NUM])
    {
        for(new i; i < g_eKnife[id][SELECT_MESSAGES_NUM]; i++)
        {
            CC_SendMessage(id, "%a", ArrayGetStringHandle(g_eKnife[id][SELECT_MESSAGES], i))
        }
    }

    if(g_eKnife[id][SELECT_SOUND][0])
    {
        play_knife_sound(id, g_eKnife[id][SELECT_SOUND])
    }
}
-
-public load_data(id)
-{
-    if(is_user_connected(id))
-    {
-        use_vault(id, false)
-    }
-}

public CheckKnifeAccess(id, iMenu, iItem)
{
    return ((g_iKnife[id] == iItem) || !has_knife_access(id, iItem)) ? ITEM_DISABLED : ITEM_ENABLED
}

public OnPlayerSpawn(id)
{
    if(is_user_alive(id) && g_eCvars[km_open_at_spawn] && !g_iKnife[id] && g_bFirstTime[id] && (g_iMenuFlags & ADMIN_USER || get_user_flags(id) & g_iMenuFlags))
    {
        g_bFirstTime[id] = false
        Cmd_Knife(id)
    }
}

public OnSelectKnife(iEnt)
{
    new id = get_pdata_cbase(iEnt, m_pPlayer, 4)

    if(is_user_connected(id))
    {
        refresh_knife_model(id)
    }
}

refresh_knife_model(const id)
{
    set_pev(id, pev_viewmodel2, g_eKnife[id][V_MODEL])
    set_pev(id, pev_weaponmodel2, g_eKnife[id][P_MODEL])
}

push_knife(eKnife[Knives])
{
    if(!eKnife[V_MODEL][0])
    {
        copy(eKnife[V_MODEL], charsmax(eKnife[V_MODEL]), CRXKNIVES_DEFAULT_V)
    }

    if(!eKnife[P_MODEL][0])
    {
        copy(eKnife[P_MODEL], charsmax(eKnife[P_MODEL]), CRXKNIVES_DEFAULT_P)
    }

    if(!eKnife[FLAG])
    {
        g_iMenuFlags |= ADMIN_USER
    }

    ArrayPushArray(g_aKnives, eKnife)
}

bool:has_knife_access(const id, const iKnife)
{
    static eKnife[Knives]
    ArrayGetArray(g_aKnives, iKnife, eKnife)

    if(eKnife[FLAG] != ADMIN_ALL)
    {
        if(get_user_flags(id) & eKnife[FLAG])
        {
            if(g_eCvars[km_admin_bypass])
            {
                return true
            }
        }
        else
        {
            return false
        }
    }

    if(g_bRankSystem)
    {
        if(eKnife[LEVEL] && crxranks_get_user_level(id) < eKnife[LEVEL])
        {
            return false
        }

        if(eKnife[XP] && crxranks_get_user_xp(id) < eKnife[XP])
        {
            return false
        }
    }

    return true
}

bool:is_knife_sound(const szSample[])
{
    return bool:equal(szSample[8], "kni", 3)
}

detect_knife_sound(const szSample[])
{
    static iSound
    iSound = SOUND_NONE

    if(equal(szSample, "weapons/knife_deploy1.wav"))
    {
        iSound = SOUND_DEPLOY
    }
    else if(equal(szSample[14], "hit", 3))
    {
        iSound = szSample[17] == 'w' ? SOUND_HITWALL : SOUND_HIT
    }
    else if(equal(szSample[14], "sla", 3))
    {
        iSound = SOUND_SLASH
    }
    else if(equal(szSample[14], "sta", 3))
    {
        iSound = SOUND_STAB
    }

    return iSound
}

use_vault(const id, const bool:bSave)
{
    if(bSave)
    {
        new szData[4]
        num_to_str(g_iKnife[id], szData, charsmax(szData))
        nvault_set(g_iVault, g_szAuth[id], szData)
    }
    else
    {
        new iKnife
        iKnife = nvault_get(g_iVault, g_szAuth[id])

        if(!is_knife_valid(iKnife))
        {
            iKnife = 0
        }
        else if(has_knife_access(id, iKnife))
        {
            g_iKnife[id] = iKnife

            new iReturn
            ArrayGetArray(g_aKnives, iKnife, g_eKnife[id])
            ExecuteForward(g_fwdKnifeUpdated, iReturn, id, iKnife, false)

            if(is_user_alive(id) && get_user_weapon(id) == CSW_KNIFE)
            {
                refresh_knife_model(id)
            }
        }
    }
}

play_knife_sound(const id, const szSound[])
{
    engfunc(EngFunc_EmitSound, id, CHAN_AUTO, szSound, 1.0, ATTN_NORM, 0, PITCH_NORM)
}

bool:is_knife_valid(const iKnife)
{
    return 0 <= iKnife < g_iKnivesNum
}

public plugin_natives()
{
    register_library("crxknives")
    register_native("crxknives_can_use_skill",       "_crxknives_can_use_skill")
    register_native("crxknives_get_attribute_int",   "_crxknives_get_attribute_int")
    register_native("crxknives_get_attribute_float", "_crxknives_get_attribute_float")
    register_native("crxknives_get_attribute_str",   "_crxknives_get_attribute_str")
    register_native("crxknives_get_knives_num",      "_crxknives_get_knives_num")
    register_native("crxknives_get_user_knife",      "_crxknives_get_user_knife")
    register_native("crxknives_has_knife_access",    "_crxknives_has_knife_access")
    register_native("crxknives_is_knife_valid",      "_crxknives_is_knife_valid")
    set_native_filter("native_filter")
}

public native_filter(const szNative[], id, iTrap)
{
    if(!iTrap)
    {
        static i

        for(i = 0; i < sizeof(g_szNatives); i++)
        {
            if(equal(szNative, g_szNatives[i]))
            {
                return PLUGIN_HANDLED
            }
        }
    }

    return PLUGIN_CONTINUE
}

public bool:_crxknives_can_use_skill(iPlugin, iParams)
{
    return !g_eCvars[km_knife_only_skills] || (get_user_weapon(get_param(1)) == CSW_KNIFE)
}

public bool:_crxknives_get_attribute_int(iPlugin, iParams)
{
    static szAttribute[MAX_NAME_LENGTH], szValue[CRXKNIVES_MAX_ATTRIBUTE_LENGTH], id
    get_string(2, szAttribute, charsmax(szAttribute))
    id = get_param(1)

    if(!get_param(4))
    {
        if(!is_knife_valid(id))
        {
            return false
        }

        static eKnife[Knives]
        ArrayGetArray(g_aKnives, id, eKnife)

        if(!TrieKeyExists(eKnife[ATTRIBUTES], szAttribute))
        {
            return false
        }

        TrieGetString(eKnife[ATTRIBUTES], szAttribute, szValue, charsmax(szValue))
        goto @SET_ATTRIBUTE
    }

    if(!TrieKeyExists(g_eKnife[id][ATTRIBUTES], szAttribute))
    {
        return false
    }

    TrieGetString(g_eKnife[id][ATTRIBUTES], szAttribute, szValue, charsmax(szValue))

    @SET_ATTRIBUTE:
    set_param_byref(3, str_to_num(szValue))
    return true
}

public bool:_crxknives_get_attribute_float(iPlugin, iParams)
{
    static szAttribute[MAX_NAME_LENGTH], szValue[CRXKNIVES_MAX_ATTRIBUTE_LENGTH], id
    get_string(2, szAttribute, charsmax(szAttribute))
    id = get_param(1)

    if(!get_param(4))
    {
        if(!is_knife_valid(id))
        {
            return false
        }

        static eKnife[Knives]
        ArrayGetArray(g_aKnives, id, eKnife)

        if(!TrieKeyExists(eKnife[ATTRIBUTES], szAttribute))
        {
            return false
        }

        TrieGetString(eKnife[ATTRIBUTES], szAttribute, szValue, charsmax(szValue))
        goto @SET_ATTRIBUTE
    }

    if(!TrieKeyExists(g_eKnife[id][ATTRIBUTES], szAttribute))
    {
        return false
    }

    TrieGetString(g_eKnife[id][ATTRIBUTES], szAttribute, szValue, charsmax(szValue))

    @SET_ATTRIBUTE:
    set_float_byref(3, str_to_float(szValue))
    return true
}

public bool:_crxknives_get_attribute_str(iPlugin, iParams)
{
    static szAttribute[MAX_NAME_LENGTH], szValue[CRXKNIVES_MAX_ATTRIBUTE_LENGTH], id
    get_string(2, szAttribute, charsmax(szAttribute))
    id = get_param(1)

    if(!get_param(5))
    {
        if(!is_knife_valid(id))
        {
            return false
        }

        static eKnife[Knives]
        ArrayGetArray(g_aKnives, id, eKnife)

        if(!TrieKeyExists(eKnife[ATTRIBUTES], szAttribute))
        {
            return false
        }

        TrieGetString(eKnife[ATTRIBUTES], szAttribute, szValue, charsmax(szValue))
        goto @SET_ATTRIBUTE
    }

    if(!TrieKeyExists(g_eKnife[id][ATTRIBUTES], szAttribute))
    {
        return false
    }

    TrieGetString(g_eKnife[id][ATTRIBUTES], szAttribute, szValue, charsmax(szValue))

    @SET_ATTRIBUTE:
    set_string(3, szValue, get_param(4))
    return true
}

public _crxknives_get_knives_num(iPlugin, iParams)
{
    return g_iKnivesNum
}

public _crxknives_get_user_knife(iPlugin, iParams)
{
    return g_iKnife[get_param(1)]
}

public bool:_crxknives_has_knife_access(iPlugin, iParams)
{
    return has_knife_access(get_param(1), get_param(2))
}

public bool:_crxknives_is_knife_valid(iPlugin, iParams)
{
    return is_knife_valid(get_param(1))
}
 
Статус
В этой теме нельзя размещать новые ответы.

Пользователи, просматривающие эту тему

Сейчас на форуме нет ни одного пользователя.
Сверху Снизу