#include <amxmodx>
#include <amxmisc>
#include <hamsandwich>
#include <engine>
#include <fakemeta>
#include <cromchat>
#include <pubnite_mod>
#include <nvault>
#define PLUGIN "PUBNite: Knife Skins"
#define VERSION "1.0"
#define AUTHOR "EFFEX"
#define validEntity(%1) (g_iEntityID[%1] && pev_valid(g_iEntityID[%1]))
#define MAX_MODEL_LENGTH 64
#define m_pPlayer 41
#define XTRA_OFS_WEAPON 4
#define TASK_REMOVE_MODEL 73613711
#define MAX_KNIFE_SKINS 25
enum cModelsArray
{
cModelName[MAX_MODEL_LENGTH + MAX_PLAYERS],
cViewModel[MAX_MODEL_LENGTH],
cPlayerModel[MAX_MODEL_LENGTH],
cDeploySound[MAX_MODEL_LENGTH],
cHitWall1Sound[MAX_MODEL_LENGTH],
cSlash1Sound[MAX_MODEL_LENGTH],
cSlash2Sound[MAX_MODEL_LENGTH],
cStabSound[MAX_MODEL_LENGTH],
iKnifePrice
}
new const g_szBuySound[] = "pubg/effects/model_buy_sound.wav"
new Array:g_arModels
new g_nVaultBet, g_mMessageScreenFade
new bool:g_bHasModel[MAX_PLAYERS + 1][MAX_KNIFE_SKINS]
new g_iUserModel[MAX_PLAYERS + 1], g_iEntityID[MAX_PLAYERS + 1]
public plugin_init()
{
register_plugin(PLUGIN, VERSION, AUTHOR)
if(is_plugin_loaded("BattleRoyale Mod") == -1)
{
set_fail_state("MOD DISABLED")
}
register_dictionary("effxs_skinshop.txt")
register_dictionary("effxs_battleroyale.txt")
CC_SetPrefix("&x04[EFFx S]&x01:")
g_mMessageScreenFade = get_user_msgid("ScreenFade")
g_nVaultBet = nvault_open("AXES")
register_forward(FM_EmitSound, "EmitSound")
register_forward(FM_AddToFullPack, "forward_AddToFullPack", 1)
RegisterHam(Ham_Item_Deploy, "weapon_knife", "ham_KnifeDeploy_Post", 1)
new szKnifeShop[MAX_PLAYERS], szCommandFmt[35]
pubnite_get_command(cKnifeShop, szKnifeShop)
formatex(szCommandFmt, charsmax(szCommandFmt), "say %s", szKnifeShop)
register_clcmd(szCommandFmt, "cmdModels")
}
public plugin_end()
{
nvault_close(g_nVaultBet)
}
public plugin_precache()
{
g_arModels = ArrayCreate(cModelsArray)
precache_sound(g_szBuySound)
readIniData()
}
public client_connect(id)
{
if(!is_user_bot(id))
{
loadData(id)
}
}
public forward_AddToFullPack(es_handle, e, iEnt, iHost, hostflags, player, pSet)
{
if(is_user_alive(iEnt) || !pev_valid(iEnt))
return FMRES_IGNORED
if(is_user_alive(iHost) && validEntity(iHost))
{
static iOwner;iOwner = pev(iEnt, pev_owner)
if(is_user_connected(iOwner)
&& (iOwner == iHost)
&& (iEnt == g_iEntityID[iHost]))
{
set_es(es_handle, ES_RenderAmt, 255)
}
}
return FMRES_IGNORED
}
public EmitSound(id, channel, sample[])
{
if(!is_user_alive(id) || !user_has_weapon(id, CSW_KNIFE) || pubnite_is_knockedout(id))
return FMRES_IGNORED
if(containi(sample, "weapons/knife_") == -1)
return FMRES_IGNORED
new arrayData[cModelsArray]
ArrayGetArray(g_arModels, g_iUserModel[id], arrayData)
if(equal(sample, "weapons/knife_deploy1.wav"))
{
emit_sound(id, CHAN_ITEM, arrayData[cDeploySound], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
return FMRES_SUPERCEDE
}
else if(equal(sample, "weapons/knife_hitwall1.wav"))
{
emit_sound(id, CHAN_ITEM, arrayData[cHitWall1Sound], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
return FMRES_SUPERCEDE
}
else if(equal(sample, "weapons/knife_slash1.wav"))
{
emit_sound(id, CHAN_ITEM, arrayData[cSlash1Sound], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
return FMRES_SUPERCEDE
}
else if(equal(sample, "weapons/knife_slash2.wav"))
{
emit_sound(id, CHAN_ITEM, arrayData[cSlash2Sound], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
return FMRES_SUPERCEDE
}
else if((containi(sample, "weapons/knife_hit") != -1) || equal(sample, "weapons/knife_stab.wav"))
{
emit_sound(id, CHAN_ITEM, arrayData[cStabSound], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
return FMRES_SUPERCEDE
}
return FMRES_IGNORED
}
public ham_KnifeDeploy_Post(const iKnife)
{
static id; id = get_pdata_cbase(iKnife, m_pPlayer, XTRA_OFS_WEAPON)
if(is_user_connected(id))
{
new arrayData[cModelsArray]
ArrayGetArray(g_arModels, g_iUserModel[id], arrayData)
set_pev(id, pev_viewmodel2, arrayData[cViewModel])
set_pev(id, pev_weaponmodel2, arrayData[cPlayerModel])
}
}
public cmdModels(id)
{
static szTittle[60]
formatex(szTittle, charsmax(szTittle), "PUBNite - Modelos de cuchillos^n\dVBucks: %d", pubnite_get_user_vbucks(id))
new iMenu = menu_create(szTittle, "handler_models")
for(new i, szPrice[10], arrayData[cModelsArray], szItemFormat[55];i < ArraySize(g_arModels);i++)
{
ArrayGetArray(g_arModels, i, arrayData)
num_to_str(arrayData[iKnifePrice], szPrice, charsmax(szPrice))
formatex
(
szItemFormat, charsmax(szItemFormat),
"%s - [\r%s%s]",
arrayData[cModelName],
g_bHasModel[id][i] ? (g_iUserModel[id] == i) ? "\yEN USO\w" : "\rUSAR\w" : szPrice,
g_bHasModel[id][i] ? "" : " \rVBucks\w"
)
menu_additem(iMenu, szItemFormat)
}
menu_display(id, iMenu)
return PLUGIN_HANDLED
}
public handler_models(id, iMenu, iItem)
{
if((iItem == MENU_EXIT))
{
menu_destroy(iMenu)
return
}
new arrayData[cModelsArray]
ArrayGetArray(g_arModels, iItem, arrayData)
new iUserVBucks = pubnite_get_user_vbucks(id), iPrice = arrayData[iKnifePrice]
if(g_iUserModel[id] == iItem)
{
CC_SendMatched(id, CC_COLOR_RED, "%L", id, "SERVER_ALREADY_HAVE_SKIN", arrayData[cModelName])
menu_display(id, iMenu)
return
}
else if(!g_bHasModel[id][iItem] && (iUserVBucks < iPrice))
{
CC_SendMatched(id, CC_COLOR_RED, "%L", id, "SERVER_NOT_ENOUGH_VBUCKS", arrayData[cModelName])
menu_display(id, iMenu)
return
}
if(!g_bHasModel[id][iItem])
{
askMenu(id, iItem)
new Float:fOrigin[3], iEnt
originUnitsAhead(id, fOrigin, 110)
if(validEntity(id))
{
iEnt = g_iEntityID[id]
set_pev(iEnt, pev_origin, fOrigin)
engfunc(EngFunc_SetModel, iEnt, arrayData[cViewModel])
return
}
if(isInvalidPlace(fOrigin, id))
{
CC_SendMatched(id, CC_COLOR_RED, "%L", id, "SERVER_INVALID_PLACE_TO_USE")
client_cmd(id, "spk buttons/button11")
return
}
iEnt = create_entity("info_target")
if(pev_valid(iEnt))
{
g_iEntityID[id] = iEnt
fOrigin[2] += 15.0
set_pev(iEnt, pev_origin, fOrigin)
engfunc(EngFunc_SetModel, iEnt, arrayData[cViewModel])
set_pev(iEnt, pev_solid, SOLID_NOT)
set_pev(iEnt, pev_owner, id)
set_pev(iEnt, pev_movetype, MOVETYPE_NOCLIP)
set_pev(iEnt, pev_rendermode, kRenderTransAlpha)
set_pev(iEnt, pev_renderamt, 0.0)
static Float:fFloatvector[3]
fFloatvector[1] = 20.0
set_pev(iEnt, pev_avelocity, fFloatvector)
}
}
else
{
g_iUserModel[id] = iItem
if(get_user_weapon(id) == CSW_KNIFE && is_user_alive(id))
{
set_pev(id, pev_viewmodel2, arrayData[cViewModel])
set_pev(id, pev_weaponmodel2, arrayData[cPlayerModel])
}
cmdModels(id)
CC_SendMatched(id, CC_COLOR_RED, "%L", id, "SERVER_YOU_SELECTED", arrayData[cModelName])
}
}
askMenu(id, iItemID)
{
static szTittle[80]
formatex(szTittle, charsmax(szTittle), "PUBNite - Modelos de jugador^n\d%L^n\dVBucks: %d", id, "SERVER_QUESTION_MENU", pubnite_get_user_vbucks(id))
new iMenu = menu_create(szTittle, "askmenu_handler"), szItemID[10], szItemFmt[15]
num_to_str(iItemID, szItemID, charsmax(szItemID))
formatex(szItemFmt, charsmax(szItemFmt), "\y%L", id, "SERVER_YES")
menu_additem(iMenu, szItemFmt, szItemID)
formatex(szItemFmt, charsmax(szItemFmt), "\r%L", id, "SERVER_NO")
menu_additem(iMenu, szItemFmt)
menu_display(id, iMenu)
set_task(10.0, "removeKnifeModel", id + TASK_REMOVE_MODEL)
}
public askmenu_handler(id, iMenu, iItem)
{
removeModel(id)
remove_task(id + TASK_REMOVE_MODEL)
switch(iItem)
{
case MENU_EXIT:
{
menu_destroy(iMenu)
}
case 0:
{
new szData[10], szItemName[MAX_MODEL_LENGTH], _access, item_callback
menu_item_getinfo(iMenu, iItem, _access, szData,charsmax(szData), szItemName, charsmax(szItemName), item_callback)
new iItemID = str_to_num(szData), arrayData[cModelsArray], iPrice
ArrayGetArray(g_arModels, iItemID, arrayData)
CC_SendMatched(id, CC_COLOR_RED, "%L", id, "SERVER_YOU_BOUGHT", arrayData[cModelName], (iPrice = arrayData[iKnifePrice]))
g_iUserModel[id] = iItemID
g_bHasModel[id][iItemID] = true
message_begin(MSG_ONE, g_mMessageScreenFade, .player = id)
write_short(4300)
write_short(0)
write_short(0)
write_byte(255)
write_byte(255)
write_byte(255)
write_byte(65)
message_end()
client_cmd(id, "spk ^"%s^"", g_szBuySound)
pubnite_set_user_vbucks(id, (pubnite_get_user_vbucks(id) - iPrice))
saveData(id)
if(get_user_weapon(id) == CSW_KNIFE && is_user_alive(id))
{
set_pev(id, pev_viewmodel2, arrayData[cViewModel])
set_pev(id, pev_weaponmodel2, arrayData[cPlayerModel])
}
}
case 1: cmdModels(id)
}
}
public removeKnifeModel(id)
{
removeModel(id - TASK_REMOVE_MODEL)
}
removeModel(id)
{
if(validEntity(id))
{
remove_entity(g_iEntityID[id])
}
g_iEntityID[id] = 0
if(is_user_connected(id))
{
show_menu(id, 0, "^n")
}
}
readIniData()
{
new szConfig[MAX_PLAYERS], szIniFile[164]
get_configsdir(szConfig, charsmax(szConfig))
formatex(szIniFile, charsmax(szIniFile), "%s/pubnite_mod/pubnite_management/pubnite_knifemodels.ini", szConfig)
if(!file_exists(szIniFile))
{
log_to_file("pubnite_log.log", "[PUBNite Mod]: %L", LANG_SERVER, "SERVER_NO_CONFIG_FILE", szIniFile)
return
}
new szBuffer[MAX_MODEL_LENGTH + MAX_PLAYERS]
new szKey[MAX_PLAYERS], szValue[MAX_MODEL_LENGTH], arrayData[cModelsArray]
new iFile = fopen(szIniFile, "rt"), iModelsNum = 0
while(!feof(iFile) && (iModelsNum < MAX_KNIFE_SKINS))
{
fgets(iFile, szBuffer, charsmax(szBuffer))
trim(szBuffer)
if((szBuffer[0] == EOS) || (szBuffer[0] == ';') || ((szBuffer[0] == '/') && (szBuffer[1] == '/')))
continue
if(szBuffer[0] == '[')
{
if(szBuffer[strlen(szBuffer) - 1] == ']')
{
if(iModelsNum)
{
ArrayPushArray(g_arModels, arrayData)
}
iModelsNum++
replace(szBuffer, charsmax(szBuffer), "[", "")
replace(szBuffer, charsmax(szBuffer), "]", "")
arrayData[cModelName] = szBuffer
}
else continue
}
else
{
strtok(szBuffer, szKey, charsmax(szKey), szValue, charsmax(szValue), '=')
trim(szKey)
trim(szValue)
if(equal(szKey, "KNIFE_PRICE"))
{
arrayData[iKnifePrice] = str_to_num(szValue)
}
else if(equal(szKey, "KNIFE_VIEW_MODEL"))
{
if(precacheModel(szValue))
{
arrayData[cViewModel] = szValue
}
}
else if(equal(szKey, "KNIFE_PLAYER_MODEL"))
{
if(precacheModel(szValue))
{
arrayData[cPlayerModel] = szValue
}
}
else if(equal(szKey, "KNIFE_DEPLOY_SOUND"))
{
if(precacheSound(szValue))
{
arrayData[cDeploySound] = szValue
}
}
else if(equal(szKey, "KNIFE_HITWALL1_SOUND"))
{
if(precacheSound(szValue))
{
arrayData[cHitWall1Sound] = szValue
}
}
else if(equal(szKey, "KNIFE_SLASH1_SOUND"))
{
if(precacheSound(szValue))
{
arrayData[cSlash1Sound] = szValue
}
}
else if(equal(szKey, "KNIFE_SLASH2_SOUND"))
{
if(precacheSound(szValue))
{
arrayData[cSlash2Sound] = szValue
}
}
else if(equal(szKey, "KNIFE_STAB_SOUND"))
{
if(precacheSound(szValue))
{
arrayData[cStabSound] = szValue
}
}
}
}
if(iModelsNum)
{
ArrayPushArray(g_arModels, arrayData)
}
fclose(iFile)
}
precacheModel(szModel[])
{
if(file_exists(szModel))
{
precache_model(szModel)
// Quick&Dirty Fix
new temp[80]
copy(temp, (strlen(szModel) - 4), szModel)
formatex(temp, charsmax(temp), "%st.mdl", temp)
if(file_exists(temp))
{
precache_model(temp)
return true
}
copy(temp, (strlen(szModel) - 4), szModel)
formatex(temp, charsmax(temp), "%sT.mdl", temp)
if(file_exists(temp))
{
precache_model(temp)
return true
}
return true
}
return false
}
precacheSound(szSound[])
{
if(equal(szSound[strlen(szSound) - 4], ".mp3"))
{
if(file_exists(szSound))
{
precache_generic(szSound)
return true
}
}
else
{
return precache_sound(szSound)
}
return false
}
saveData(id)
{
new szSteam[35]
get_user_authid(id, szSteam, charsmax(szSteam))
new vaultkey[64], vaultdata[64]
format(vaultkey, charsmax(vaultkey), "%s-Save", szSteam)
format(vaultdata, charsmax(vaultdata), "%i", g_iUserModel[id])
for(new i;i < MAX_KNIFE_SKINS;i++)
{
formatex(vaultdata, charsmax(vaultdata), "%s %i", vaultdata, g_bHasModel[id][i])
}
nvault_set(g_nVaultBet, vaultkey, vaultdata)
}
loadData(id)
{
new szSteam[35]
get_user_authid(id, szSteam, charsmax(szSteam))
new vaultkey[64], vaultdata[64]
format(vaultkey, charsmax(vaultkey), "%s-Save", szSteam)
format(vaultdata, charsmax(vaultdata), "%i", g_iUserModel[id])
for(new i;i < MAX_KNIFE_SKINS;i++)
{
formatex(vaultdata, charsmax(vaultdata), "%s %i", vaultdata, g_bHasModel[id][i])
}
nvault_get(g_nVaultBet, vaultkey, vaultdata, charsmax(vaultdata))
new Data[MAX_KNIFE_SKINS][8]
// WTF
parse(vaultdata, Data[0], charsmax(Data), Data[1], charsmax(Data), Data[2], charsmax(Data), Data[3], charsmax(Data), Data[4], charsmax(Data), Data[5], charsmax(Data),
Data[6], charsmax(Data), Data[7], charsmax(Data), Data[8], charsmax(Data), Data[9], charsmax(Data), Data[10], charsmax(Data), Data[11], charsmax(Data), Data[12], charsmax(Data),
Data[13], charsmax(Data), Data[14], charsmax(Data), Data[15], charsmax(Data), Data[16], charsmax(Data), Data[17], charsmax(Data), Data[18], charsmax(Data), Data[19], charsmax(Data),
Data[20], charsmax(Data), Data[21], charsmax(Data), Data[22], charsmax(Data), Data[23], charsmax(Data), Data[24])
for(new i;i < sizeof Data;i++)
{
if(i > 0)
{
g_bHasModel[id][i - 1] = bool:str_to_num(Data[i])
}
else g_iUserModel[id] = str_to_num(Data[i])
}
}