Próbowałem zrobić zapis <nvault> do pluginu knife api ale coś mi się nie udało.
1error = error 088 ber of arguments does not match definition
Spoiler
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PLUGIN_VERSION "2.1.1"
// comment this if you want CS knife as the default weapon
#define DEFAULT_HANDS
// because I think it looks cooler. And also, I'm cool, you're cool
// and this plugin is cool.
#define pev_pickable pev_renderamt
#define pev_knifevalue pev_iuser1
new g_name[33][48]
new plik_vault
new g_Knife[33];
#define KNIFE_CLASSNAME "tossed_knife"
const MAXPLAYERS = 32
const MAX_KNIVES = 32
new const DEFAULT_WMODEL[] = "models/knife_api/w_knifepack.mdl"
#if defined DEFAULT_HANDS
new const HANDS_VMODEL[] = "models/knife_api/v_default.mdl"
new const HANDS_SOUND[] = "knife_api/default.wav"
#else
new const KNIFE_VMODEL[] = "models/v_knife.mdl"
new const KNIFE_PMODEL[] = "models/p_knife.mdl"
#endif
new g_MaxPlayers
new g_MsgIndexWeaponList
new g_MsgIndexWeapPickup
new g_sModelIndexBloodSpray, g_sModelIndexBloodDrop
#define IsPlayer(%1) (1 <= %1 <= g_MaxPlayers)
#define IsKnife(%1) (0 <= %1 <= g_TotalKnives)
enum _:ForwardIds
{
Forward_ProcessAttackPre,
Forward_ProcessAttackPost,
Forward_DealDamage,
Forward_Deploy,
Forward_SoundPlay
}
new g_ForwardIds[ForwardIds]
/* that's a lot of stuff, fortunately, all of these
* values are easily changeable using the Knife_SetProperty() native.
* See the .inc file to see the usage
*/
enum _:KnifeAttackType
{
Primary,
Secondary
}
enum _:KnifeDataStructure
{
_WeaponName[32],
_VModel[64],
_PModel[64],
_WModel[64],
_DeploySound[64],
_SlashSound[64],
_StabSound[64],
_WhiffSound[64],
_WallSound[64],
_SpriteName[32],
bool:_Droppable,
Float:_Damage[KnifeAttackType],
Float:_NextAttack[KnifeAttackType],
Float:_Range[KnifeAttackType],
Float:_DamageDelay[KnifeAttackType],
_DmgBits[KnifeAttackType],
_TeamLock,
bool:_NextAttackDependency,
bool:_IgnoreFriendlyFire,
// internal variables, do not change these!
__BitKnifeOwners__,
__CommandIndex__
}
new g_Knives[MAX_KNIVES][KnifeDataStructure], g_TotalKnives
#define BitFunc_SetKnife(%1,%2) (g_Knives[%2][__BitKnifeOwners__] |= (1<<%1-1))
#define BitFunc_RemoveKnife(%1,%2) (g_Knives[%2][__BitKnifeOwners__] &= ~(1<<%1-1))
#define BitFunc_HasKnife(%1,%2) (g_Knives[%2][__BitKnifeOwners__] & (1<<%1-1))
new g_CurrentKnife[MAXPLAYERS+1], bool:g_LockedKnife[MAXPLAYERS+1]
new g_CvarDropOnDeath, g_CvarLossOnDeath, g_CvarSwitchMenu, g_CvarRoundRemoval
new g_CvarPointerFF
// CSTRIKE PRIVATE DATA
const XO_CBASEPLAYERITEM = 4
const m_pPlayer = 41
const m_flNextPrimaryAttack = 46
const m_flNextSecondaryAttack = 47
new const m_rgpPlayerItems_CBasePlayer[6] = {367, 368, ...}
const m_LastHitGroup = 75
// CSTRIKE HITZONE/SOUND DATA
// the damage (1.0 by default) of your knife will multiply this
// resulting in the total damage (*3 if backstab)
new const Float:g_HitgroupDamage[KnifeAttackType][] =
{
{ // slash
15.0, /* Generic */
60.0, /* Head */
15.0, /* Chest */
18.75, /* Stomach */
15.0, /* Left Arm */
15.0, /* Right Arm */
11.25, /* Left Leg */
11.25 /* Right Leg */
},
{ // stab
65.0, /* Generic */
260.0, /* Head */
65.0, /* Chest */
81.25, /* Stomach */
65.0, /* Left Arm */
65.0, /* Right Arm */
48.75, /* Left Leg */
48.75 /* Right Leg */
}
}
// default flesh sound
new const g_HitFleshSound[2][][] =
{
{ // HIT_*
"player/bhit_flesh-1.wav",
"player/bhit_flesh-2.wav",
"player/bhit_flesh-3.wav"
},
{ // HIT_HEAD
"player/headshot1.wav",
"player/headshot2.wav",
"player/headshot3.wav"
}
}
// blood decals
new g_BloodDecals[6]
public plugin_precache()
{
precache_model(DEFAULT_WMODEL)
#if defined DEFAULT_HANDS
precache_model(HANDS_VMODEL)
precache_sound(HANDS_SOUND)
#endif
g_sModelIndexBloodSpray = precache_model("sprites/bloodspray.spr")
g_sModelIndexBloodDrop = precache_model("sprites/blood.spr")
// must be executed here, if any subplugin adds a knife earlier it would be the default knife
__addDefaultKnife()
}
__addDefaultKnife()
{
/* FEEL FREE TO CHANGE WHATEVER YOU WANT HERE.
* UNDER NO CIRCUMSTANCES MAKE THE DEFAULT KNIFE DROPPABLE!*/
#if defined DEFAULT_HANDS
g_Knives[0][_WeaponName] = "Hands"
g_Knives[0][_VModel] = HANDS_VMODEL
g_Knives[0][_SlashSound] = HANDS_SOUND
g_Knives[0][_StabSound] = HANDS_SOUND
g_Knives[0][_WallSound] = HANDS_SOUND
g_Knives[0][_DeploySound] = "weapons/knife_slash1.wav"
g_Knives[0][_WhiffSound] = "weapons/knife_slash1.wav"
g_Knives[0][_Damage] = {_:0.5, _:0.5}
g_Knives[0][_Range] = {_:35.0, _:35.0}
g_Knives[0][_NextAttack] = {_:0.3, _:0.6}
#else
g_Knives[0][_WeaponName] = "Hunting Knife"
g_Knives[0][_VModel] = KNIFE_VMODEL
g_Knives[0][_PModel] = KNIFE_PMODEL
g_Knives[0][_DeploySound] = "weapons/knife_deploy1.wav"
g_Knives[0][_SlashSound] = "weapons/knife_hit1.wav"
g_Knives[0][_StabSound] = "weapons/knife_stab.wav"
g_Knives[0][_WallSound] = "weapons/knife_hitwall1.wav"
g_Knives[0][_WhiffSound] = "weapons/knife_slash1.wav"
g_Knives[0][_Damage] = {_:1.0, _:1.0}
g_Knives[0][_Range] = {_:48.0, _:32.0}
#endif
g_Knives[0][__BitKnifeOwners__] = -1
}
public plugin_natives()
{
register_library("knifeapi")
register_native("Knife_Register", "_Knife_Register")
register_native("Knife_GetTotal", "_Knife_GetTotal")
register_native("Knife_GetProperty", "_Knife_GetProperty")
register_native("Knife_SetProperty", "_Knife_SetProperty")
register_native("Knife_PlayerGive", "_Knife_PlayerGive")
register_native("Knife_PlayerGetCurrent", "_Knife_PlayerGetCurrent")
register_native("Knife_PlayerSetCurrent", "_Knife_PlayerSetCurrent")
register_native("Knife_PlayerHas", "_Knife_PlayerHas")
register_native("Knife_PlayerSetLock", "_Knife_PlayerSetLock")
register_native("Knife_PlayerGetLock", "_Knife_PlayerGetLock")
register_native("Knife_PlayerRemoveAll", "_Knife_PlayerRemoveAll")
}
public _Knife_Register(Plugin, Params)
{
if(g_TotalKnives++ >= MAX_KNIVES)
{
log_error(AMX_ERR_NATIVE, "Knife limit has been reached. Increase MAX_KNIVES in the source code to continue.")
return 0
}
get_string(1, g_Knives[g_TotalKnives][_WeaponName], charsmax(g_Knives[][_WeaponName]))
get_string(2, g_Knives[g_TotalKnives][_VModel], charsmax(g_Knives[][_VModel]))
get_string(3, g_Knives[g_TotalKnives][_PModel], charsmax(g_Knives[][_PModel]))
get_string(4, g_Knives[g_TotalKnives][_WModel], charsmax(g_Knives[][_WModel]))
get_string(5, g_Knives[g_TotalKnives][_DeploySound], charsmax(g_Knives[][_DeploySound]))
get_string(6, g_Knives[g_TotalKnives][_SlashSound], charsmax(g_Knives[][_SlashSound]))
get_string(7, g_Knives[g_TotalKnives][_StabSound], charsmax(g_Knives[][_StabSound]))
get_string(8, g_Knives[g_TotalKnives][_WhiffSound], charsmax(g_Knives[][_WhiffSound]))
get_string(9, g_Knives[g_TotalKnives][_WallSound], charsmax(g_Knives[][_WallSound]))
g_Knives[g_TotalKnives][_Damage][Primary] = get_param(10)
g_Knives[g_TotalKnives][_Damage][Secondary] = get_param(11)
//DEFAULT SETTINGS
g_Knives[g_TotalKnives][_Range] = {_:48.0, _:32.0}
g_Knives[g_TotalKnives][_NextAttackDependency] = true
return g_TotalKnives
}
public _Knife_GetTotal(Plugin, Params)
{
if(Params != 0)
{
log_error(AMX_ERR_NATIVE, "Invalid amount of parameters. Expected: 0, Found: %d", Params)
return -1
}
return g_TotalKnives
}
public _Knife_GetProperty(Plugin, Params)
{
new Knife = get_param(1)
if(!IsKnife(Knife))
{
log_error(AMX_ERR_NATIVE, "Invalid knife (%d)", Knife)
return 0
}
new KnifeProperties:Value = KnifeProperties:get_param(2)
switch(Value)
{
case KN_STR_WeaponName: set_string(3, g_Knives[Knife][_WeaponName], get_param(4))
case KN_STR_VModel: set_string(3, g_Knives[Knife][_VModel], get_param(4))
case KN_STR_PModel: set_string(3, g_Knives[Knife][_PModel], get_param(4))
case KN_STR_WModel: set_string(3, g_Knives[Knife][_WModel], get_param(4))
case KN_STR_DeploySound: set_string(3, g_Knives[Knife][_DeploySound], get_param(4))
case KN_STR_SlashSound: set_string(3, g_Knives[Knife][_SlashSound], get_param(4))
case KN_STR_StabSound: set_string(3, g_Knives[Knife][_StabSound], get_param(4))
case KN_STR_WhiffSound: set_string(3, g_Knives[Knife][_WhiffSound], get_param(4))
case KN_STR_WallSound: set_string(3, g_Knives[Knife][_WallSound], get_param(4))
case KN_STR_SpriteName: set_string(3, g_Knives[Knife][_SpriteName], get_param(4))
case KN_CLL_Droppable: set_param_byref(3, _:g_Knives[Knife][_Droppable])
case KN_CLL_PrimaryDamage: set_param_byref(3, _:g_Knives[Knife][_Damage][Primary])
case KN_CLL_SecondaryDamage: set_param_byref(3, _:g_Knives[Knife][_Damage][Secondary])
case KN_CLL_PrimaryNextAttack: set_param_byref(3, _:g_Knives[Knife][_NextAttack][Primary])
case KN_CLL_SecondaryNextAttack: set_param_byref(3, _:g_Knives[Knife][_NextAttack][Secondary])
case KN_CLL_PrimaryRange: set_param_byref(3, _:g_Knives[Knife][_Range][Primary])
case KN_CLL_SecondaryRange: set_param_byref(3, _:g_Knives[Knife][_Range][Secondary])
case KN_CLL_PrimaryDamageDelay: set_param_byref(3, _:g_Knives[Knife][_DamageDelay][Primary])
case KN_CLL_SecondaryDamageDelay: set_param_byref(3, _:g_Knives[Knife][_DamageDelay][Secondary])
case KN_CLL_PrimaryDmgBits: set_param_byref(3, g_Knives[Knife][_DmgBits][Primary])
case KN_CLL_SecondaryDmgBits: set_param_byref(3, g_Knives[Knife][_DmgBits][Secondary])
case KN_CLL_TeamLock: set_param_byref(3, g_Knives[Knife][_TeamLock])
case KN_CLL_NextAttackDependency: set_param_byref(3, g_Knives[Knife][_NextAttackDependency])
case KN_CLL_IgnoreFriendlyFire: set_param_byref(3, g_Knives[Knife][_IgnoreFriendlyFire])
default: {
log_error(AMX_ERR_NATIVE, "Value is not a member of the KnifeProperties enum: %d", Value)
return 0
}
}
return 1
}
public _Knife_SetProperty(Plugin, Params)
{
new Knife = get_param(1)
if(!IsKnife(Knife))
{
log_error(AMX_ERR_NATIVE, "Invalid knife (%d)Version 2.2 released on 21st of July, 2014", Knife)
return 0
}
new KnifeProperties:Value = KnifeProperties:get_param(2)
// gotta use get_param_byref since we're passing the params with any:...
switch(Value)
{
case KN_STR_WeaponName: get_string(3, g_Knives[Knife][_WeaponName], charsmax(g_Knives[][_WeaponName]))
case KN_STR_VModel: get_string(3, g_Knives[Knife][_VModel], charsmax(g_Knives[][_VModel]))
case KN_STR_PModel: get_string(3, g_Knives[Knife][_PModel], charsmax(g_Knives[][_PModel]))
case KN_STR_WModel: get_string(3, g_Knives[Knife][_WModel], charsmax(g_Knives[][_WModel]))
case KN_STR_DeploySound: get_string(3, g_Knives[Knife][_DeploySound], charsmax(g_Knives[][_DeploySound]))
case KN_STR_SlashSound: get_string(3, g_Knives[Knife][_SlashSound], charsmax(g_Knives[][_SlashSound]))
case KN_STR_StabSound: get_string(3, g_Knives[Knife][_StabSound], charsmax(g_Knives[][_StabSound]))
case KN_STR_WhiffSound: get_string(3, g_Knives[Knife][_WhiffSound], charsmax(g_Knives[][_WhiffSound]))
case KN_STR_WallSound: get_string(3, g_Knives[Knife][_WallSound], charsmax(g_Knives[][_WallSound]))
case KN_STR_SpriteName: get_string(3, g_Knives[Knife][_SpriteName], charsmax(g_Knives[][_SpriteName]))
case KN_CLL_Droppable: g_Knives[Knife][_Droppable] = bool:get_param_byref(3)
case KN_CLL_PrimaryDamage: g_Knives[Knife][_Damage][Primary] = get_param_byref(3)
case KN_CLL_SecondaryDamage: g_Knives[Knife][_Damage][Secondary] = get_param_byref(3)
case KN_CLL_PrimaryNextAttack: g_Knives[Knife][_NextAttack][Primary] = get_param_byref(3)
case KN_CLL_SecondaryNextAttack: g_Knives[Knife][_NextAttack][Secondary] = get_param_byref(3)
case KN_CLL_PrimaryRange: g_Knives[Knife][_Range][Primary] = get_param_byref(3)
case KN_CLL_SecondaryRange: g_Knives[Knife][_Range][Secondary] = get_param_byref(3)
case KN_CLL_PrimaryDamageDelay: g_Knives[Knife][_DamageDelay][Primary] = get_param_byref(3)
case KN_CLL_SecondaryDamageDelay: g_Knives[Knife][_DamageDelay][Secondary] = get_param_byref(3)
case KN_CLL_PrimaryDmgBits: g_Knives[Knife][_DmgBits][Primary] = get_param_byref(3)
case KN_CLL_SecondaryDmgBits: g_Knives[Knife][_DmgBits][Secondary] = get_param_byref(3)
case KN_CLL_TeamLock: g_Knives[Knife][_TeamLock] = get_param_byref(3)
case KN_CLL_NextAttackDependency: g_Knives[Knife][_NextAttackDependency] = get_param_byref(3)
case KN_CLL_IgnoreFriendlyFire: g_Knives[Knife][_IgnoreFriendlyFire] = get_param_byref(3)
default: {
log_error(AMX_ERR_NATIVE, "Value is not a member of the KnifeProperties enum: %d", Value)
return 0
}
}
return 1
}
public _Knife_PlayerGive(Plugin, Params)
{
if(Params != 3)
{
log_error(AMX_ERR_NATIVE, "Invalid amount of parameters. Expected: 3, Found: %d", Params)
return 0
}
new Player = get_param(1)
new Knife = get_param(2)
if(!IsPlayer(Player) || !IsKnife(Knife))
{
log_error(AMX_ERR_NATIVE, "Invalid player (%d) or knife (%d)", Player, Knife)
return 0
}
if(BitFunc_HasKnife(Player, Knife))
{
return 0
}
return giveKnife(Player, Knife, bool:get_param(3))
}
public _Knife_PlayerGetCurrent(Plugin, Params)
{
if(Params != 1)
{
log_error(AMX_ERR_NATIVE, "Invalid amount of parameters. Expected: 1, Found: %d", Params)
return -1
}
new Player = get_param(1)
if(!IsPlayer(Player))
{
log_error(AMX_ERR_NATIVE, "Invalid player (%d)", Player)
return -1
}
return g_CurrentKnife[Player]
}
public _Knife_PlayerSetCurrent(Plugin, Params)
{
if(Params != 2)
{
log_error(AMX_ERR_NATIVE, "Invalid amount of parameters. Expected: 2, Found: %d", Params)
return 0
}
new Player = get_param(1)
new Knife = get_param(2)
if(!IsPlayer(Player) || !IsKnife(Knife))
{
log_error(AMX_ERR_NATIVE, "Invalid player (%d) or knife (%d)", Player, Knife)
return 0
}
if(!BitFunc_HasKnife(Player, Knife))
{
return 0
}
g_CurrentKnife[Player] = Knife
redeployKnife(Player)
return 1
}
public _Knife_PlayerHas(Plugin, Params)
{
if(Params != 2)
{
log_error(AMX_ERR_NATIVE, "Invalid amount of parameters. Expected: 2, Found: %d", Params)
return 0
}
new Player = get_param(1)
new Knife = get_param(2)
if(!IsPlayer(Player) || !IsKnife(Knife))
{
log_error(AMX_ERR_NATIVE, "Invalid player (%d) or knife (%d)", Player, Knife)
return 0
}
return BitFunc_HasKnife(Player, Knife)
}
public _Knife_PlayerSetLock(Plugin, Params)
{
if(Params != 2)
{
log_error(AMX_ERR_NATIVE, "Invalid amount of parameters. Expected: 2, Found: %d", Params)
return
}
new Player = get_param(1)
if(!IsPlayer(Player))
{
log_error(AMX_ERR_NATIVE, "Invalid player (%d)", Player)
return
}
g_LockedKnife[Player] = bool:get_param(2)
}
public bool:_Knife_PlayerGetLock(Plugin, Params)
{
if(Params != 1)
{
log_error(AMX_ERR_NATIVE, "Invalid amount of parameters. Expected: 1, Found: %d", Params)
return false
}
new Player = get_param(1)
if(!IsPlayer(Player))
{
log_error(AMX_ERR_NATIVE, "Invalid player (%d)", Player)
return false
}
return g_LockedKnife[Player]
}
public _Knife_PlayerRemoveAll(Plugin, Params)
{
if(Params != 1)
{
log_error(AMX_ERR_NATIVE, "Invalid amount of parameters. Expected: 1, Found: %d", Params)
return
}
new Player = get_param(1)
if(!IsPlayer(Player))
{
log_error(AMX_ERR_NATIVE, "Invalid player (%d)", Player)
return
}
for(new i = 1; i <= g_TotalKnives; i++)
{
BitFunc_RemoveKnife(Player, i)
}
g_CurrentKnife[Player] = 0
}
public plugin_init()
{
register_plugin("Knife API", PLUGIN_VERSION, "idiotstrike")
g_MaxPlayers = get_maxplayers()
g_MsgIndexWeaponList = get_user_msgid("WeaponList")
g_MsgIndexWeapPickup = get_user_msgid("WeapPickup")
RegisterHam(Ham_TraceAttack, "player", "_fwTraceAttack")
RegisterHam(Ham_Item_Deploy, "weapon_knife", "_fwDeploy", true)
RegisterHam(Ham_Weapon_PrimaryAttack, "weapon_knife", "_fwPrimaryAttack", false)
RegisterHam(Ham_Weapon_SecondaryAttack, "weapon_knife", "_fwSecondaryAttack", false)
// the purpose of hooking post is solely to set the m_flNextPrimary/SecondaryAttack values.
RegisterHam(Ham_Weapon_PrimaryAttack, "weapon_knife", "_fwPrimaryAttack_Post", true)
RegisterHam(Ham_Weapon_SecondaryAttack, "weapon_knife", "_fwSecondaryAttack_Post", true)
RegisterHam(Ham_Killed, "player", "_fwKilled", true)
// register the weapon touch for pickup
register_touch(KNIFE_CLASSNAME, "player", "_fwTouch")
register_forward(FM_EmitSound, "_fwEmitSound")
register_forward(FM_CmdStart, "_fwCmdStart", true)
register_event("HLTV", "_eNewRound", "a", "1=0", "2=0")
g_CvarDropOnDeath = register_cvar("knifeapi_dropondeath", "1")
g_CvarLossOnDeath = register_cvar("knifeapi_lossondeath", "1")
g_CvarSwitchMenu = register_cvar("knifeapi_switchmenu", "1")
g_CvarRoundRemoval = register_cvar("knifeapi_roundremoval", "1")
g_CvarPointerFF = get_cvar_pointer("mp_friendlyfire")
register_clcmd("drop", "_cDrop")
register_concmd("knifeapi_list", "_cKnivesList", ADMIN_ALL)
// our Five(5) forwards
g_ForwardIds[Forward_ProcessAttackPre] = CreateMultiForward("KnifeAction_ProcessAttack_Pre", ET_STOP, FP_CELL, FP_CELL, FP_CELL)
g_ForwardIds[Forward_ProcessAttackPost] = CreateMultiForward("KnifeAction_ProcessAttack_Post", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_ARRAY, FP_ARRAY)
g_ForwardIds[Forward_DealDamage] = CreateMultiForward("KnifeAction_DealDamage", ET_STOP, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_ARRAY, FP_ARRAY, FP_CELL)
g_ForwardIds[Forward_Deploy] = CreateMultiForward("KnifeAction_Deploy", ET_IGNORE, FP_CELL, FP_CELL)
g_ForwardIds[Forward_SoundPlay] = CreateMultiForward("KnifeAction_SoundPlay", ET_STOP, FP_CELL, FP_CELL, FP_STRING)
g_BloodDecals[0] = engfunc(EngFunc_DecalIndex, "{blood1")
g_BloodDecals[1] = engfunc(EngFunc_DecalIndex, "{blood2")
g_BloodDecals[2] = engfunc(EngFunc_DecalIndex, "{blood3")
g_BloodDecals[3] = engfunc(EngFunc_DecalIndex, "{blood4")
g_BloodDecals[4] = engfunc(EngFunc_DecalIndex, "{blood5")
g_BloodDecals[5] = engfunc(EngFunc_DecalIndex, "{blood6")
plik_vault = nvault_open("noze")
if(plik_vault == INVALID_HANDLE)
set_fail_state("Nie moge otworzyc pliku ");
}
public client_authorized(id)
load_g_Knife(id);
public client_disconnect(id) {
save_g_Knife(id)
g_Knife[id]=0 // zeby ktos kto wejdzie po nas nie mial naszych fragow zapisanych w tablicy
copy(g_name[id], 47, "");
// mozna by wyswietlic komunikat ale tylko gdy uzywamy komendy bo inaczej nie dosc ze nic sie nie wyswietli
// to w logach zobaczymy "index out of bound"
}
public plugin_cfg()
{
// we register the commands in plugin_cfg, since plugins registering knives post plugin_init would not work correctly
for(new i = 0; i <= g_TotalKnives; i++)
{
if(g_Knives[i][_SpriteName][0])
{
g_Knives[i][__CommandIndex__] = register_clcmd(g_Knives[i][_SpriteName], "_cKnifeUsage")
}
}
}
// remove the knives lying on the ground here
public _eNewRound()
{
if(!get_pcvar_num(g_CvarRoundRemoval))
{
return
}
new Ent = -1
while((Ent = find_ent_by_class(Ent, KNIFE_CLASSNAME)))
{
remove_entity(Ent)
}
}
// first I wanted to hook Ham_Weapon_Reload, but I guessed it wouldn't work with knife
public _fwCmdStart(id, UcHandle, Seed)
{
if(!is_user_alive(id) || get_user_weapon(id) != CSW_KNIFE)
{
return
}
if(get_uc(UcHandle, UC_Buttons) & IN_RELOAD && !(pev(id, pev_oldbuttons) & IN_RELOAD))
{
if(g_LockedKnife[id])
{
client_print(id, print_center, "You cannot change your knife right now.")
return
}
if(get_pcvar_num(g_CvarSwitchMenu))
{
showKnivesMenu(id)
}
else
{
setNextWeapon(id)
}
}
}
public _fwKilled(Victim)
{
remove_task(Victim)
if(get_pcvar_num(g_CvarDropOnDeath))
{
for(new i = 1; i <= g_TotalKnives; i++)
{
if(BitFunc_HasKnife(Victim, i))
{
if(g_Knives[i][_Droppable])
{
spawnKnifeFromPlayer(Victim, i, false, true)
}
}
}
}
if(get_pcvar_num(g_CvarLossOnDeath))
{
for(new i = 1; i <= g_TotalKnives; i++)
{
BitFunc_RemoveKnife(Victim, i)
}
g_CurrentKnife[Victim] = 0
updateWeaponHud(Victim)
g_LockedKnife[Victim] = false
}
}
public client_connect(id)
{
for(new i = 1; i <= g_TotalKnives; i++)
{
BitFunc_RemoveKnife(id, i)
}
g_CurrentKnife[id] = 0
g_LockedKnife[id] = false
}
public _fwEmitSound(id, Channel, Sample[])
{
if(!is_user_alive(id) || (Channel != CHAN_WEAPON && Channel != CHAN_ITEM))
{
return FMRES_IGNORED
}
if(equal(Sample, "weapons/knife_", 14))
{
if(equal(Sample[14], "deploy", 6))
{
new Knife = g_CurrentKnife[id]
if(g_Knives[Knife][_DeploySound][0])
{
new ReturnVal
ExecuteForward(g_ForwardIds[Forward_SoundPlay], ReturnVal, id, Knife, g_Knives[Knife][_DeploySound])
if(ReturnVal == KnifeAction_Block)
{
return FMRES_SUPERCEDE
}
emit_sound(id, Channel, g_Knives[Knife][_DeploySound], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
}
return FMRES_SUPERCEDE
}
return FMRES_SUPERCEDE
}
return FMRES_IGNORED
}
public _fwTraceAttack(Victim, Attacker, Float:Damage, Float:VecDir[3], Ptr, DamageBitsum)
{
static const DMG_KNIFE = (DMG_BULLET | DMG_NEVERGIB)
if(IsPlayer(Attacker) && get_user_weapon(Attacker) == CSW_KNIFE && DamageBitsum & DMG_KNIFE)
{
return HAM_SUPERCEDE
}
return HAM_IGNORED
}
public _fwDeploy(Entity)
{
new PlayerId = get_pdata_cbase(Entity, m_pPlayer, XO_CBASEPLAYERITEM)
new CurrentKnife = g_CurrentKnife[PlayerId]
set_pev(PlayerId, pev_viewmodel2, g_Knives[CurrentKnife][_VModel])
set_pev(PlayerId, pev_weaponmodel2, g_Knives[CurrentKnife][_PModel])
set_pev(Entity, pev_knifevalue, CurrentKnife)
new ReturnVal
ExecuteForward(g_ForwardIds[Forward_Deploy], ReturnVal, PlayerId, CurrentKnife)
}
public _fwPrimaryAttack(Entity)
{
return ProcessAttack(Entity, Primary)
}
public _fwSecondaryAttack(Entity)
{
return ProcessAttack(Entity, Secondary)
}
public _fwPrimaryAttack_Post(Entity)
{
new Player = get_pdata_cbase(Entity, m_pPlayer, XO_CBASEPLAYERITEM)
new Knife = g_CurrentKnife[Player]
new Float:PrimaryNextAttack = Float:g_Knives[Knife][_NextAttack][Primary]
if(PrimaryNextAttack)
{
set_pdata_float(Entity, m_flNextPrimaryAttack, PrimaryNextAttack, XO_CBASEPLAYERITEM)
if(g_Knives[Knife][_NextAttackDependency])
{
set_pdata_float(Entity, m_flNextSecondaryAttack, PrimaryNextAttack, XO_CBASEPLAYERITEM)
}
}
}
public _fwSecondaryAttack_Post(Entity)
{
new Player = get_pdata_cbase(Entity, m_pPlayer, XO_CBASEPLAYERITEM)
new Knife = g_CurrentKnife[Player]
new Float:SecondaryNextAttack = Float:g_Knives[Knife][_NextAttack][Secondary]
if(SecondaryNextAttack)
{
set_pdata_float(Entity, m_flNextSecondaryAttack, SecondaryNextAttack, XO_CBASEPLAYERITEM)
if(g_Knives[Knife][_NextAttackDependency])
{
set_pdata_float(Entity, m_flNextPrimaryAttack, SecondaryNextAttack, XO_CBASEPLAYERITEM)
}
}
}
ProcessAttack(Entity, AttackType)
{
new Player = get_pdata_cbase(Entity, m_pPlayer, XO_CBASEPLAYERITEM)
new Knife = g_CurrentKnife[Player]
new ReturnVal
ExecuteForward(g_ForwardIds[Forward_ProcessAttackPre], ReturnVal, Player, Knife, !AttackType)
if(ReturnVal == KnifeAction_Block)
{
return HAM_SUPERCEDE
}
new TaskData[4]
TaskData[0] = Player
TaskData[1] = Knife
TaskData[2] = AttackType
TaskData[3] = Entity
if(g_Knives[Knife][_DamageDelay][AttackType])
{
set_task(g_Knives[Knife][_DamageDelay][AttackType], "DelayAttack", Player, TaskData, sizeof TaskData)
}
else
{
DelayAttack(TaskData)
}
return HAM_IGNORED
}
public DelayAttack(TaskData[])
{
new Player = TaskData[0]
new Knife = TaskData[1]
new AttackType = TaskData[2]
new Entity = TaskData[3]
if(!is_user_connected(Player))
{
return
}
new Float:ViewOfs[3], Float:Start[3], Float:End[3], Float:Aim[3]
pev(Player, pev_origin, Start)
pev(Player, pev_view_ofs, ViewOfs)
xs_vec_add(Start, ViewOfs, Start)
velocity_by_aim(Player, 1, Aim)
xs_vec_mul_scalar(Aim, g_Knives[Knife][_Range][AttackType], End)
xs_vec_add(Start, End, End)
new Trace, Float:Fraction
engfunc(EngFunc_TraceLine, Start, End, DONT_IGNORE_MONSTERS, Player, Trace)
get_tr2(Trace, TR_flFraction, Fraction)
if(Fraction >= 1.0)
{
engfunc(EngFunc_TraceHull, Start, End, DONT_IGNORE_MONSTERS, HULL_HEAD, Player, Trace)
get_tr2(Trace, TR_flFraction, Fraction)
}
new ReturnVal
new PreparedEndVector = PrepareArray(_:End, 3)
new PreparedAimVector = PrepareArray(_:Aim, 3)
if(Fraction >= 1.0)
{
ExecuteForward(g_ForwardIds[Forward_ProcessAttackPost], ReturnVal, Player, 0, Knife,
!AttackType, PreparedEndVector, PreparedAimVector
)
if(g_Knives[Knife][_WhiffSound][0])
{
new ReturnVal
ExecuteForward(g_ForwardIds[Forward_SoundPlay], ReturnVal, Player, Knife, g_Knives[Knife][_WhiffSound])
if(ReturnVal != KnifeAction_Block)
{
emit_sound(Player, CHAN_WEAPON, g_Knives[Knife][_WhiffSound], VOL_NORM, ATTN_NORM, 0, 94)
}
}
}
else
{
new HitPlayer = get_tr2(Trace, TR_pHit)
if(IsPlayer(HitPlayer))
{
ExecuteForward(g_ForwardIds[Forward_ProcessAttackPost], ReturnVal, Player, HitPlayer, Knife,
!AttackType, PreparedEndVector, PreparedAimVector
)
// to ignore friendly fire
new Previous = get_pcvar_num(g_CvarPointerFF)
if(!Previous)
{
if(g_Knives[Knife][_IgnoreFriendlyFire]) set_pcvar_num(g_CvarPointerFF, 1)
else return
}
new Hitgroup = get_tr2(Trace, TR_iHitgroup)
new bool:Backstab = isBackstab(Player, HitPlayer)
new Float:Damage = g_HitgroupDamage[AttackType][Hitgroup] * Float:g_Knives[Knife][_Damage][Primary]
if(AttackType == Primary && Backstab)
{
Damage *= 3.0
}
new DmgBits = g_Knives[Knife][_DmgBits][AttackType] ? g_Knives[Knife][_DmgBits][AttackType] : DMG_BULLET|DMG_NEVERGIB
ExecuteForward(g_ForwardIds[Forward_DealDamage], ReturnVal, Player, HitPlayer, Knife, Damage,
!AttackType, DmgBits, Backstab, PreparedEndVector, PreparedAimVector, Hitgroup
)
if(ReturnVal == KnifeAction_Block)
{
return
}
UTIL_BloodDrips(End, 248, _:Damage)
new Float:HitOrigin[3]
pev(HitPlayer, pev_origin, HitOrigin)
if(pev(HitPlayer, pev_bInDuck))
{
HitOrigin[2] -= 18.0
}
else
{
HitOrigin[2] -= 36.0
}
UTIL_BloodDecal(HitOrigin, g_BloodDecals[random(sizeof g_BloodDecals)])
set_pdata_int(HitPlayer, m_LastHitGroup, Hitgroup)
emit_sound(HitPlayer, CHAN_VOICE,
g_HitFleshSound[Hitgroup == HIT_HEAD ? 1:0][random(sizeof g_HitFleshSound[])],
VOL_NORM, ATTN_NORM, 0, PITCH_NORM
)
if(AttackType == Primary)
{
if(g_Knives[Knife][_SlashSound][0])
{
new ReturnVal
ExecuteForward(g_ForwardIds[Forward_SoundPlay], ReturnVal, Player, Knife, g_Knives[Knife][_SlashSound])
if(ReturnVal != KnifeAction_Block)
{
emit_sound(Player, CHAN_WEAPON, g_Knives[Knife][_SlashSound], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
}
}
ExecuteHam(Ham_TakeDamage, HitPlayer, Entity, Player, Damage, DmgBits)
}
else
{
if(g_Knives[Knife][_StabSound][0])
{
new ReturnVal
ExecuteForward(g_ForwardIds[Forward_SoundPlay], ReturnVal, Player, Knife, g_Knives[Knife][_StabSound])
if(ReturnVal != KnifeAction_Block)
{
emit_sound(Player, CHAN_WEAPON, g_Knives[Knife][_StabSound], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
}
}
ExecuteHam(Ham_TakeDamage, HitPlayer, Entity, Player, Damage, DmgBits)
}
if(Previous && g_Knives[Knife][_IgnoreFriendlyFire])
{
set_pcvar_num(g_CvarPointerFF, 1)
}
}
else if(g_Knives[Knife][_WallSound][0])
{
new ReturnVal
ExecuteForward(g_ForwardIds[Forward_ProcessAttackPost], ReturnVal, Player, 0, Knife,
!AttackType, PreparedEndVector, PreparedAimVector
)
ExecuteForward(g_ForwardIds[Forward_SoundPlay], ReturnVal, Player, Knife, g_Knives[Knife][_WallSound])
if(ReturnVal != KnifeAction_Block)
{
emit_sound(Player, CHAN_ITEM, g_Knives[Knife][_WallSound], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
}
}
}
free_tr2(Trace)
}
public _cDrop(id)
{
if(!is_user_alive(id) || get_user_weapon(id) != CSW_KNIFE)
{
return PLUGIN_CONTINUE
}
if(g_LockedKnife[id])
{
client_print(id, print_center, "Nie mozna upuscic noz.")
return PLUGIN_HANDLED
}
new CurrentKnife = g_CurrentKnife[id]
if(g_Knives[CurrentKnife][_Droppable])
{
spawnKnifeFromPlayer(id, CurrentKnife, true)
removeKnife(id, CurrentKnife)
return PLUGIN_HANDLED
}
return PLUGIN_CONTINUE
}
public _cKnifeUsage(id, level, cid)
{
engclient_cmd(id, "weapon_knife")
if(g_LockedKnife[id])
{
client_print(id, print_center, "Nie mozna zmienic noza.")
return PLUGIN_HANDLED
}
for(new i = 0; i <= g_TotalKnives; i++)
{
if(BitFunc_HasKnife(id, i) && g_Knives[i][__CommandIndex__] == cid && i != g_CurrentKnife[id])
{
g_CurrentKnife[id] = i
redeployKnife(id)
}
}
return PLUGIN_HANDLED
}
public _cKnivesList(id, Level)
{
if(~get_user_flags(id) & Level)
{
return PLUGIN_CONTINUE
}
new Len, Buffer[2048]
for(new i = 1; i <= g_TotalKnives; i++)
{
Len = formatex(Buffer, charsmax(Buffer), "^nKnife Index: #%d^nName: %s^nVModel: %s^nPModel: %s^nWModel: %s^n", i,
g_Knives[i][_WeaponName],
g_Knives[i][_VModel],
g_Knives[i][_PModel],
g_Knives[i][_WModel]
)
Len += formatex(Buffer[Len], charsmax(Buffer) - Len, "Deploy Sound: %s^nSlash Sound: %s^n", g_Knives[i][_DeploySound], g_Knives[i][_SlashSound])
Len += formatex(Buffer[Len], charsmax(Buffer) - Len, "Stab Sound: %s^nWhiff Sound: %s^nWall Sound: %s^n",
g_Knives[i][_StabSound],
g_Knives[i][_WhiffSound],
g_Knives[i][_WallSound]
)
Len += formatex(Buffer[Len], charsmax(Buffer) - Len,
"Droppable: %s^nCustom Sprite: %s^nPrimary Damage: %.1f^nSecondary Damage: %.1f^nPrimary NextAttack: %.1f^nSecondary NextAttack %.1f^n",
g_Knives[i][_Droppable] ? "Yes" : "No",
g_Knives[i][_SpriteName][0] ? "Yes" : "No",
g_Knives[i][_Damage][Primary],
g_Knives[i][_Damage][Secondary],
g_Knives[i][_NextAttack][Primary],
g_Knives[i][_NextAttack][Secondary]
)
Len += formatex(Buffer[Len], charsmax(Buffer) - Len,
"Primary Range: %.1f^nSecondary Range: %.1f^nPrimary Damage Delay: %.1f^nSecondary Damage Delay: %.1f^n",
g_Knives[i][_Range][Primary],
g_Knives[i][_Range][Secondary],
g_Knives[i][_DamageDelay][Primary],
g_Knives[i][_DamageDelay][Secondary]
)
if(IsPlayer(id))
{
engclient_print(id, engprint_console, Buffer)
}
else
{
server_print(Buffer)
}
}
return PLUGIN_HANDLED
}
public _fwTouch(Entity, Player)
{
if(!IsPlayer(Player) || !pev_valid(Entity))
{
return
}
new KnifeType = pev(Entity, pev_knifevalue)
if(!KnifeType)
{
return
}
if(pev(Entity, pev_pickable) > get_gametime())
{
return
}
if(!BitFunc_HasKnife(Player, KnifeType))
{
if(giveKnife(Player, KnifeType))
{
set_pev(Entity, pev_flags, FL_KILLME)
}
}
}
showKnivesMenu(id)
{
new Knife[4], Menu = menu_create("Choose your knife", "_mKnivesHandler")
new MenuItem[45]
new Team = get_user_team(id)
for(new i = 0; i <= g_TotalKnives; i++)
{
if(BitFunc_HasKnife(id, i))
{
if(g_Knives[i][_TeamLock] && Team != g_Knives[i][_TeamLock])
{
continue
}
num_to_str(i, Knife, charsmax(Knife))
formatex(MenuItem, charsmax(MenuItem), "%s%s",
g_Knives[i][_WeaponName],
i == g_CurrentKnife[id] ? "\y - Selected" : ""
)
menu_additem(Menu, MenuItem, Knife)
}
}
menu_display(id, Menu)
}
public _mKnivesHandler(id, Menu, Item)
{
if (Item != MENU_EXIT)
{
if(g_LockedKnife[id])
{
client_print(id, print_center, "You cannot change your knife right now.")
menu_destroy(Menu)
return PLUGIN_HANDLED
}
new Junk, Knife[4]
menu_item_getinfo(Menu, Item, Junk, Knife, charsmax(Knife), .callback = Junk)
new KnifeIndex = str_to_num(Knife)
if(BitFunc_HasKnife(id, KnifeIndex))
{
g_CurrentKnife[id] = KnifeIndex
redeployKnife(id)
}
}
menu_destroy(Menu)
return PLUGIN_HANDLED
}
updateWeaponHud(id)
{
new CurrentKnife = g_CurrentKnife[id]
message_begin(MSG_ONE, g_MsgIndexWeaponList, _, id)
if(!g_Knives[CurrentKnife][_SpriteName][0])
{
write_string("weapon_knife")
}
else
{
write_string(g_Knives[CurrentKnife][_SpriteName])
}
write_byte(-1)
write_byte(-1)
write_byte(-1)
write_byte(-1)
write_byte(2)
write_byte(1)
write_byte(CSW_KNIFE)
write_byte(0)
message_end()
}
giveKnife(Player, Knife, bool:Set = true)
{
if(g_Knives[Knife][_TeamLock] && get_user_team(Player) != g_Knives[Knife][_TeamLock])
{
return 0
}
BitFunc_SetKnife(Player, Knife)
if(Set) g_CurrentKnife[Player] = Knife
if(is_user_alive(Player))
{
emit_sound(Player, CHAN_AUTO, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
if(Set) redeployKnife(Player)
set_dhudmessage( 0, 160, 0, -1.0, 0.25, 2, 6.0, 3.0, 0.1, 1.5 );
show_dhudmessage( 0, "Wygrales %s. Nacisnij klawisz R (przeladowanie) aby zmienic noz.",
g_Knives[Knife][_WeaponName]
)
message_begin(MSG_ONE, g_MsgIndexWeapPickup, _, Player)
write_byte(CSW_KNIFE)
message_end()
}
return 1
}
removeKnife(Player, Knife)
{
if(g_CurrentKnife[Player] == Knife)
{
setNextWeapon(Player)
}
BitFunc_RemoveKnife(Player, Knife)
redeployKnife(Player)
}
setNextWeapon(Player)
{
new NextKnifeIndex, Team = get_user_team(Player)
for(new i = g_CurrentKnife[Player] + 1; i <= g_TotalKnives; i++)
{
if(BitFunc_HasKnife(Player, i))
{
if(g_Knives[i][_TeamLock] && Team != g_Knives[i][_TeamLock])
{
continue
}
NextKnifeIndex = i
break
}
}
if(NextKnifeIndex != g_CurrentKnife[Player])
{
g_CurrentKnife[Player] = NextKnifeIndex
redeployKnife(Player)
}
}
redeployKnife(Player)
{
new CurrentKnife = g_CurrentKnife[Player]
if(g_Knives[CurrentKnife][_TeamLock] && get_user_team(Player) != g_Knives[CurrentKnife][_TeamLock])
{
setNextWeapon(Player)
return
}
new WeaponId = get_pdata_cbase(Player, m_rgpPlayerItems_CBasePlayer[3])
client_cmd(Player, "weapon_knife")
if(pev_valid(WeaponId))
{
ExecuteHamB(Ham_Item_Deploy, WeaponId)
}
sendKnifeAnimation(Player)
updateWeaponHud(Player)
}
sendKnifeAnimation(id, Anim = 3)
{
set_pev(id, pev_weaponanim, Anim)
message_begin(MSG_ONE, SVC_WEAPONANIM, {0, 0, 0}, id)
write_byte(Anim)
write_byte(0)
message_end();
}
spawnKnifeFromPlayer(Player, Knife, bool:SetVelocity = false, bool:FindEmptyLoc = false)
{
new Float:PlayerOrigin[3]
entity_get_vector(Player, EV_VEC_origin, PlayerOrigin)
if(FindEmptyLoc)
{
new Num
if(!findEmptyLocation(Player, PlayerOrigin, Num, 45.0))
{
client_print(Player, print_chat, "Oops, couldn't create knife entity in your location.")
return
}
}
new Entity = create_entity("info_target")
entity_set_string(Entity, EV_SZ_classname, "tossed_knife")
entity_set_origin(Entity, PlayerOrigin)
if(SetVelocity)
{
new Float:NewVelocity[3]
velocity_by_aim(Player, 350, NewVelocity)
entity_set_vector(Entity, EV_VEC_velocity, NewVelocity)
}
static const Float:Minbox[3] = {-2.5, -2.5, -2.5}
static const Float:Maxbox[3] = {2.5, 2.5, -2.5}
entity_set_vector(Entity, EV_VEC_mins, Minbox)
entity_set_vector(Entity, EV_VEC_maxs, Maxbox)
entity_set_int(Entity, EV_INT_solid, SOLID_TRIGGER)
entity_set_int(Entity, EV_INT_movetype, MOVETYPE_TOSS)
// so it's not picked up immediately after throwing it
set_pev(Entity, pev_pickable, get_gametime() + 1.3)
if(g_Knives[Knife][_WModel][0])
{
entity_set_model(Entity, g_Knives[Knife][_WModel])
}
else
{
entity_set_model(Entity, DEFAULT_WMODEL)
}
set_pev(Entity, pev_knifevalue, Knife)
}
findEmptyLocation(id, Float:Origin[3], &Num, Float:Radius)
{
if(Num++ > 100)
return 0
new Float:PlayerOrigin[3]
pev(id, pev_origin, PlayerOrigin)
for(new i; i < 2; i++)
PlayerOrigin[i] += random_float(-Radius, Radius)
if(PointContents(PlayerOrigin) != CONTENTS_EMPTY && PointContents(PlayerOrigin) != CONTENTS_SKY)
return findEmptyLocation(id, Origin, Num, Radius)
Origin = PlayerOrigin
return 1
}
bool:isBackstab(const Attacker, const Victim)
{
new Float:Vec1[3]
new Float:Vec2[3]
velocity_by_aim(Attacker, 1, Vec1)
new Float:InvLen = xs_rsqrt(Vec1[0] * Vec1[0] + Vec1[1] * Vec1[1])
Vec1[0] *= InvLen
Vec1[1] *= InvLen
pev(Victim, pev_angles, Vec2)
angle_vector(Vec2, ANGLEVECTOR_FORWARD, Vec2)
return Vec1[0] * Vec2[0] + Vec1[1] * Vec2[1] > 0.8 ? true : false
}
UTIL_BloodDrips(Float:Origin[3], Color, Amount)
{
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_BLOODSPRITE)
engfunc(EngFunc_WriteCoord, Origin[0])
engfunc(EngFunc_WriteCoord, Origin[1])
engfunc(EngFunc_WriteCoord, Origin[2])
write_short(g_sModelIndexBloodSpray)
write_short(g_sModelIndexBloodDrop)
write_byte(Color)
write_byte(min(max(3, Amount/10), 16))
message_end()
}
UTIL_BloodDecal(Float:Origin[3], DecalIndex)
{
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_WORLDDECAL)
engfunc(EngFunc_WriteCoord, Origin[0]) // x
engfunc(EngFunc_WriteCoord, Origin[1]) // y
engfunc(EngFunc_WriteCoord, Origin[2]) // z
write_byte(DecalIndex) // random decal number
message_end()
}
public plugin_end()
nvault_close(plik_vault)
public load_g_Knife(id)
{
new name[48]
get_user_name(id,name,47)
new vaultkey[64],vaultdata[128]
formatex(vaultkey,63,"%s-g_Knife",name)
if(nvault_get(plik_vault,vaultkey,vaultdata,127)) { // pobieramy dane
new g_Knifetemp[16], nametemp[48];
parse(vaultdata, g_Knifetemp, 15, nametemp, 47) // wydobywamy z ciagu vaultdata nasze dane
g_Knife[id]=str_to_num(g_Knifetemp) // przypisujemy danym ich wartosci wczytane
Knife_PlayerGive(id,g_Knife[id])
copy(g_name[id], 47, nametemp);
}
return PLUGIN_CONTINUE
}
public save_g_Knife(id) {
g_Knife[id]+=Knife_PlayerGive(id) // zwiekszamy liczbe fragow i deadow o stan bierzacy
new name[48]
get_user_name(id,name,47)
new vaultkey[64],vaultdata[128] // 2 zmienne na klucz i dane ktore bedziemy zapisywac
formatex(vaultkey,63,"%s-g_Knife",name) //formatujemy klucz czyli nasz identyfikator dostepu najlepiej zeby roznil sie on 1 czlonem od pozostalych
formatex(vaultdata,127,"%d %d ^"%s^"", g_Knife[id], name) // formatujemy dane
nvault_set(plik_vault,vaultkey,vaultdata) // zapisujemy dane "pod" danym kluczem w pliku
return PLUGIN_CONTINUE
}
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PLUGIN_VERSION "2.1.1"
// comment this if you want CS knife as the default weapon
#define DEFAULT_HANDS
// because I think it looks cooler. And also, I'm cool, you're cool
// and this plugin is cool.
#define pev_pickable pev_renderamt
#define pev_knifevalue pev_iuser1
new g_name[33][48]
new plik_vault
new g_Knife[33];
#define KNIFE_CLASSNAME "tossed_knife"
const MAXPLAYERS = 32
const MAX_KNIVES = 32
new const DEFAULT_WMODEL[] = "models/knife_api/w_knifepack.mdl"
#if defined DEFAULT_HANDS
new const HANDS_VMODEL[] = "models/knife_api/v_default.mdl"
new const HANDS_SOUND[] = "knife_api/default.wav"
#else
new const KNIFE_VMODEL[] = "models/v_knife.mdl"
new const KNIFE_PMODEL[] = "models/p_knife.mdl"
#endif
new g_MaxPlayers
new g_MsgIndexWeaponList
new g_MsgIndexWeapPickup
new g_sModelIndexBloodSpray, g_sModelIndexBloodDrop
#define IsPlayer(%1) (1 <= %1 <= g_MaxPlayers)
#define IsKnife(%1) (0 <= %1 <= g_TotalKnives)
enum _:ForwardIds
{
Forward_ProcessAttackPre,
Forward_ProcessAttackPost,
Forward_DealDamage,
Forward_Deploy,
Forward_SoundPlay
}
new g_ForwardIds[ForwardIds]
/* that's a lot of stuff, fortunately, all of these
* values are easily changeable using the Knife_SetProperty() native.
* See the .inc file to see the usage
*/
enum _:KnifeAttackType
{
Primary,
Secondary
}
enum _:KnifeDataStructure
{
_WeaponName[32],
_VModel[64],
_PModel[64],
_WModel[64],
_DeploySound[64],
_SlashSound[64],
_StabSound[64],
_WhiffSound[64],
_WallSound[64],
_SpriteName[32],
bool:_Droppable,
Float:_Damage[KnifeAttackType],
Float:_NextAttack[KnifeAttackType],
Float:_Range[KnifeAttackType],
Float:_DamageDelay[KnifeAttackType],
_DmgBits[KnifeAttackType],
_TeamLock,
bool:_NextAttackDependency,
bool:_IgnoreFriendlyFire,
// internal variables, do not change these!
__BitKnifeOwners__,
__CommandIndex__
}
new g_Knives[MAX_KNIVES][KnifeDataStructure], g_TotalKnives
#define BitFunc_SetKnife(%1,%2) (g_Knives[%2][__BitKnifeOwners__] |= (1<<%1-1))
#define BitFunc_RemoveKnife(%1,%2) (g_Knives[%2][__BitKnifeOwners__] &= ~(1<<%1-1))
#define BitFunc_HasKnife(%1,%2) (g_Knives[%2][__BitKnifeOwners__] & (1<<%1-1))
new g_CurrentKnife[MAXPLAYERS+1], bool:g_LockedKnife[MAXPLAYERS+1]
new g_CvarDropOnDeath, g_CvarLossOnDeath, g_CvarSwitchMenu, g_CvarRoundRemoval
new g_CvarPointerFF
// CSTRIKE PRIVATE DATA
const XO_CBASEPLAYERITEM = 4
const m_pPlayer = 41
const m_flNextPrimaryAttack = 46
const m_flNextSecondaryAttack = 47
new const m_rgpPlayerItems_CBasePlayer[6] = {367, 368, ...}
const m_LastHitGroup = 75
// CSTRIKE HITZONE/SOUND DATA
// the damage (1.0 by default) of your knife will multiply this
// resulting in the total damage (*3 if backstab)
new const Float:g_HitgroupDamage[KnifeAttackType][] =
{
{ // slash
15.0, /* Generic */
60.0, /* Head */
15.0, /* Chest */
18.75, /* Stomach */
15.0, /* Left Arm */
15.0, /* Right Arm */
11.25, /* Left Leg */
11.25 /* Right Leg */
},
{ // stab
65.0, /* Generic */
260.0, /* Head */
65.0, /* Chest */
81.25, /* Stomach */
65.0, /* Left Arm */
65.0, /* Right Arm */
48.75, /* Left Leg */
48.75 /* Right Leg */
}
}
// default flesh sound
new const g_HitFleshSound[2][][] =
{
{ // HIT_*
"player/bhit_flesh-1.wav",
"player/bhit_flesh-2.wav",
"player/bhit_flesh-3.wav"
},
{ // HIT_HEAD
"player/headshot1.wav",
"player/headshot2.wav",
"player/headshot3.wav"
}
}
// blood decals
new g_BloodDecals[6]
public plugin_precache()
{
precache_model(DEFAULT_WMODEL)
#if defined DEFAULT_HANDS
precache_model(HANDS_VMODEL)
precache_sound(HANDS_SOUND)
#endif
g_sModelIndexBloodSpray = precache_model("sprites/bloodspray.spr")
g_sModelIndexBloodDrop = precache_model("sprites/blood.spr")
// must be executed here, if any subplugin adds a knife earlier it would be the default knife
__addDefaultKnife()
}
__addDefaultKnife()
{
/* FEEL FREE TO CHANGE WHATEVER YOU WANT HERE.
* UNDER NO CIRCUMSTANCES MAKE THE DEFAULT KNIFE DROPPABLE!*/
#if defined DEFAULT_HANDS
g_Knives[0][_WeaponName] = "Hands"
g_Knives[0][_VModel] = HANDS_VMODEL
g_Knives[0][_SlashSound] = HANDS_SOUND
g_Knives[0][_StabSound] = HANDS_SOUND
g_Knives[0][_WallSound] = HANDS_SOUND
g_Knives[0][_DeploySound] = "weapons/knife_slash1.wav"
g_Knives[0][_WhiffSound] = "weapons/knife_slash1.wav"
g_Knives[0][_Damage] = {_:0.5, _:0.5}
g_Knives[0][_Range] = {_:35.0, _:35.0}
g_Knives[0][_NextAttack] = {_:0.3, _:0.6}
#else
g_Knives[0][_WeaponName] = "Hunting Knife"
g_Knives[0][_VModel] = KNIFE_VMODEL
g_Knives[0][_PModel] = KNIFE_PMODEL
g_Knives[0][_DeploySound] = "weapons/knife_deploy1.wav"
g_Knives[0][_SlashSound] = "weapons/knife_hit1.wav"
g_Knives[0][_StabSound] = "weapons/knife_stab.wav"
g_Knives[0][_WallSound] = "weapons/knife_hitwall1.wav"
g_Knives[0][_WhiffSound] = "weapons/knife_slash1.wav"
g_Knives[0][_Damage] = {_:1.0, _:1.0}
g_Knives[0][_Range] = {_:48.0, _:32.0}
#endif
g_Knives[0][__BitKnifeOwners__] = -1
}
public plugin_natives()
{
register_library("knifeapi")
register_native("Knife_Register", "_Knife_Register")
register_native("Knife_GetTotal", "_Knife_GetTotal")
register_native("Knife_GetProperty", "_Knife_GetProperty")
register_native("Knife_SetProperty", "_Knife_SetProperty")
register_native("Knife_PlayerGive", "_Knife_PlayerGive")
register_native("Knife_PlayerGetCurrent", "_Knife_PlayerGetCurrent")
register_native("Knife_PlayerSetCurrent", "_Knife_PlayerSetCurrent")
register_native("Knife_PlayerHas", "_Knife_PlayerHas")
register_native("Knife_PlayerSetLock", "_Knife_PlayerSetLock")
register_native("Knife_PlayerGetLock", "_Knife_PlayerGetLock")
register_native("Knife_PlayerRemoveAll", "_Knife_PlayerRemoveAll")
}
public _Knife_Register(Plugin, Params)
{
if(g_TotalKnives++ >= MAX_KNIVES)
{
log_error(AMX_ERR_NATIVE, "Knife limit has been reached. Increase MAX_KNIVES in the source code to continue.")
return 0
}
get_string(1, g_Knives[g_TotalKnives][_WeaponName], charsmax(g_Knives[][_WeaponName]))
get_string(2, g_Knives[g_TotalKnives][_VModel], charsmax(g_Knives[][_VModel]))
get_string(3, g_Knives[g_TotalKnives][_PModel], charsmax(g_Knives[][_PModel]))
get_string(4, g_Knives[g_TotalKnives][_WModel], charsmax(g_Knives[][_WModel]))
get_string(5, g_Knives[g_TotalKnives][_DeploySound], charsmax(g_Knives[][_DeploySound]))
get_string(6, g_Knives[g_TotalKnives][_SlashSound], charsmax(g_Knives[][_SlashSound]))
get_string(7, g_Knives[g_TotalKnives][_StabSound], charsmax(g_Knives[][_StabSound]))
get_string(8, g_Knives[g_TotalKnives][_WhiffSound], charsmax(g_Knives[][_WhiffSound]))
get_string(9, g_Knives[g_TotalKnives][_WallSound], charsmax(g_Knives[][_WallSound]))
g_Knives[g_TotalKnives][_Damage][Primary] = get_param(10)
g_Knives[g_TotalKnives][_Damage][Secondary] = get_param(11)
//DEFAULT SETTINGS
g_Knives[g_TotalKnives][_Range] = {_:48.0, _:32.0}
g_Knives[g_TotalKnives][_NextAttackDependency] = true
return g_TotalKnives
}
public _Knife_GetTotal(Plugin, Params)
{
if(Params != 0)
{
log_error(AMX_ERR_NATIVE, "Invalid amount of parameters. Expected: 0, Found: %d", Params)
return -1
}
return g_TotalKnives
}
public _Knife_GetProperty(Plugin, Params)
{
new Knife = get_param(1)
if(!IsKnife(Knife))
{
log_error(AMX_ERR_NATIVE, "Invalid knife (%d)", Knife)
return 0
}
new KnifeProperties:Value = KnifeProperties:get_param(2)
switch(Value)
{
case KN_STR_WeaponName: set_string(3, g_Knives[Knife][_WeaponName], get_param(4))
case KN_STR_VModel: set_string(3, g_Knives[Knife][_VModel], get_param(4))
case KN_STR_PModel: set_string(3, g_Knives[Knife][_PModel], get_param(4))
case KN_STR_WModel: set_string(3, g_Knives[Knife][_WModel], get_param(4))
case KN_STR_DeploySound: set_string(3, g_Knives[Knife][_DeploySound], get_param(4))
case KN_STR_SlashSound: set_string(3, g_Knives[Knife][_SlashSound], get_param(4))
case KN_STR_StabSound: set_string(3, g_Knives[Knife][_StabSound], get_param(4))
case KN_STR_WhiffSound: set_string(3, g_Knives[Knife][_WhiffSound], get_param(4))
case KN_STR_WallSound: set_string(3, g_Knives[Knife][_WallSound], get_param(4))
case KN_STR_SpriteName: set_string(3, g_Knives[Knife][_SpriteName], get_param(4))
case KN_CLL_Droppable: set_param_byref(3, _:g_Knives[Knife][_Droppable])
case KN_CLL_PrimaryDamage: set_param_byref(3, _:g_Knives[Knife][_Damage][Primary])
case KN_CLL_SecondaryDamage: set_param_byref(3, _:g_Knives[Knife][_Damage][Secondary])
case KN_CLL_PrimaryNextAttack: set_param_byref(3, _:g_Knives[Knife][_NextAttack][Primary])
case KN_CLL_SecondaryNextAttack: set_param_byref(3, _:g_Knives[Knife][_NextAttack][Secondary])
case KN_CLL_PrimaryRange: set_param_byref(3, _:g_Knives[Knife][_Range][Primary])
case KN_CLL_SecondaryRange: set_param_byref(3, _:g_Knives[Knife][_Range][Secondary])
case KN_CLL_PrimaryDamageDelay: set_param_byref(3, _:g_Knives[Knife][_DamageDelay][Primary])
case KN_CLL_SecondaryDamageDelay: set_param_byref(3, _:g_Knives[Knife][_DamageDelay][Secondary])
case KN_CLL_PrimaryDmgBits: set_param_byref(3, g_Knives[Knife][_DmgBits][Primary])
case KN_CLL_SecondaryDmgBits: set_param_byref(3, g_Knives[Knife][_DmgBits][Secondary])
case KN_CLL_TeamLock: set_param_byref(3, g_Knives[Knife][_TeamLock])
case KN_CLL_NextAttackDependency: set_param_byref(3, g_Knives[Knife][_NextAttackDependency])
case KN_CLL_IgnoreFriendlyFire: set_param_byref(3, g_Knives[Knife][_IgnoreFriendlyFire])
default: {
log_error(AMX_ERR_NATIVE, "Value is not a member of the KnifeProperties enum: %d", Value)
return 0
}
}
return 1
}
public _Knife_SetProperty(Plugin, Params)
{
new Knife = get_param(1)
if(!IsKnife(Knife))
{
log_error(AMX_ERR_NATIVE, "Invalid knife (%d)Version 2.2 released on 21st of July, 2014", Knife)
return 0
}
new KnifeProperties:Value = KnifeProperties:get_param(2)
// gotta use get_param_byref since we're passing the params with any:...
switch(Value)
{
case KN_STR_WeaponName: get_string(3, g_Knives[Knife][_WeaponName], charsmax(g_Knives[][_WeaponName]))
case KN_STR_VModel: get_string(3, g_Knives[Knife][_VModel], charsmax(g_Knives[][_VModel]))
case KN_STR_PModel: get_string(3, g_Knives[Knife][_PModel], charsmax(g_Knives[][_PModel]))
case KN_STR_WModel: get_string(3, g_Knives[Knife][_WModel], charsmax(g_Knives[][_WModel]))
case KN_STR_DeploySound: get_string(3, g_Knives[Knife][_DeploySound], charsmax(g_Knives[][_DeploySound]))
case KN_STR_SlashSound: get_string(3, g_Knives[Knife][_SlashSound], charsmax(g_Knives[][_SlashSound]))
case KN_STR_StabSound: get_string(3, g_Knives[Knife][_StabSound], charsmax(g_Knives[][_StabSound]))
case KN_STR_WhiffSound: get_string(3, g_Knives[Knife][_WhiffSound], charsmax(g_Knives[][_WhiffSound]))
case KN_STR_WallSound: get_string(3, g_Knives[Knife][_WallSound], charsmax(g_Knives[][_WallSound]))
case KN_STR_SpriteName: get_string(3, g_Knives[Knife][_SpriteName], charsmax(g_Knives[][_SpriteName]))
case KN_CLL_Droppable: g_Knives[Knife][_Droppable] = bool:get_param_byref(3)
case KN_CLL_PrimaryDamage: g_Knives[Knife][_Damage][Primary] = get_param_byref(3)
case KN_CLL_SecondaryDamage: g_Knives[Knife][_Damage][Secondary] = get_param_byref(3)
case KN_CLL_PrimaryNextAttack: g_Knives[Knife][_NextAttack][Primary] = get_param_byref(3)
case KN_CLL_SecondaryNextAttack: g_Knives[Knife][_NextAttack][Secondary] = get_param_byref(3)
case KN_CLL_PrimaryRange: g_Knives[Knife][_Range][Primary] = get_param_byref(3)
case KN_CLL_SecondaryRange: g_Knives[Knife][_Range][Secondary] = get_param_byref(3)
case KN_CLL_PrimaryDamageDelay: g_Knives[Knife][_DamageDelay][Primary] = get_param_byref(3)
case KN_CLL_SecondaryDamageDelay: g_Knives[Knife][_DamageDelay][Secondary] = get_param_byref(3)
case KN_CLL_PrimaryDmgBits: g_Knives[Knife][_DmgBits][Primary] = get_param_byref(3)
case KN_CLL_SecondaryDmgBits: g_Knives[Knife][_DmgBits][Secondary] = get_param_byref(3)
case KN_CLL_TeamLock: g_Knives[Knife][_TeamLock] = get_param_byref(3)
case KN_CLL_NextAttackDependency: g_Knives[Knife][_NextAttackDependency] = get_param_byref(3)
case KN_CLL_IgnoreFriendlyFire: g_Knives[Knife][_IgnoreFriendlyFire] = get_param_byref(3)
default: {
log_error(AMX_ERR_NATIVE, "Value is not a member of the KnifeProperties enum: %d", Value)
return 0
}
}
return 1
}
public _Knife_PlayerGive(Plugin, Params)
{
if(Params != 3)
{
log_error(AMX_ERR_NATIVE, "Invalid amount of parameters. Expected: 3, Found: %d", Params)
return 0
}
new Player = get_param(1)
new Knife = get_param(2)
if(!IsPlayer(Player) || !IsKnife(Knife))
{
log_error(AMX_ERR_NATIVE, "Invalid player (%d) or knife (%d)", Player, Knife)
return 0
}
if(BitFunc_HasKnife(Player, Knife))
{
return 0
}
return giveKnife(Player, Knife, bool:get_param(3))
}
public _Knife_PlayerGetCurrent(Plugin, Params)
{
if(Params != 1)
{
log_error(AMX_ERR_NATIVE, "Invalid amount of parameters. Expected: 1, Found: %d", Params)
return -1
}
new Player = get_param(1)
if(!IsPlayer(Player))
{
log_error(AMX_ERR_NATIVE, "Invalid player (%d)", Player)
return -1
}
return g_CurrentKnife[Player]
}
public _Knife_PlayerSetCurrent(Plugin, Params)
{
if(Params != 2)
{
log_error(AMX_ERR_NATIVE, "Invalid amount of parameters. Expected: 2, Found: %d", Params)
return 0
}
new Player = get_param(1)
new Knife = get_param(2)
if(!IsPlayer(Player) || !IsKnife(Knife))
{
log_error(AMX_ERR_NATIVE, "Invalid player (%d) or knife (%d)", Player, Knife)
return 0
}
if(!BitFunc_HasKnife(Player, Knife))
{
return 0
}
g_CurrentKnife[Player] = Knife
redeployKnife(Player)
return 1
}
public _Knife_PlayerHas(Plugin, Params)
{
if(Params != 2)
{
log_error(AMX_ERR_NATIVE, "Invalid amount of parameters. Expected: 2, Found: %d", Params)
return 0
}
new Player = get_param(1)
new Knife = get_param(2)
if(!IsPlayer(Player) || !IsKnife(Knife))
{
log_error(AMX_ERR_NATIVE, "Invalid player (%d) or knife (%d)", Player, Knife)
return 0
}
return BitFunc_HasKnife(Player, Knife)
}
public _Knife_PlayerSetLock(Plugin, Params)
{
if(Params != 2)
{
log_error(AMX_ERR_NATIVE, "Invalid amount of parameters. Expected: 2, Found: %d", Params)
return
}
new Player = get_param(1)
if(!IsPlayer(Player))
{
log_error(AMX_ERR_NATIVE, "Invalid player (%d)", Player)
return
}
g_LockedKnife[Player] = bool:get_param(2)
}
public bool:_Knife_PlayerGetLock(Plugin, Params)
{
if(Params != 1)
{
log_error(AMX_ERR_NATIVE, "Invalid amount of parameters. Expected: 1, Found: %d", Params)
return false
}
new Player = get_param(1)
if(!IsPlayer(Player))
{
log_error(AMX_ERR_NATIVE, "Invalid player (%d)", Player)
return false
}
return g_LockedKnife[Player]
}
public _Knife_PlayerRemoveAll(Plugin, Params)
{
if(Params != 1)
{
log_error(AMX_ERR_NATIVE, "Invalid amount of parameters. Expected: 1, Found: %d", Params)
return
}
new Player = get_param(1)
if(!IsPlayer(Player))
{
log_error(AMX_ERR_NATIVE, "Invalid player (%d)", Player)
return
}
for(new i = 1; i <= g_TotalKnives; i++)
{
BitFunc_RemoveKnife(Player, i)
}
g_CurrentKnife[Player] = 0
}
public plugin_init()
{
register_plugin("Knife API", PLUGIN_VERSION, "idiotstrike")
g_MaxPlayers = get_maxplayers()
g_MsgIndexWeaponList = get_user_msgid("WeaponList")
g_MsgIndexWeapPickup = get_user_msgid("WeapPickup")
RegisterHam(Ham_TraceAttack, "player", "_fwTraceAttack")
RegisterHam(Ham_Item_Deploy, "weapon_knife", "_fwDeploy", true)
RegisterHam(Ham_Weapon_PrimaryAttack, "weapon_knife", "_fwPrimaryAttack", false)
RegisterHam(Ham_Weapon_SecondaryAttack, "weapon_knife", "_fwSecondaryAttack", false)
// the purpose of hooking post is solely to set the m_flNextPrimary/SecondaryAttack values.
RegisterHam(Ham_Weapon_PrimaryAttack, "weapon_knife", "_fwPrimaryAttack_Post", true)
RegisterHam(Ham_Weapon_SecondaryAttack, "weapon_knife", "_fwSecondaryAttack_Post", true)
RegisterHam(Ham_Killed, "player", "_fwKilled", true)
// register the weapon touch for pickup
register_touch(KNIFE_CLASSNAME, "player", "_fwTouch")
register_forward(FM_EmitSound, "_fwEmitSound")
register_forward(FM_CmdStart, "_fwCmdStart", true)
register_event("HLTV", "_eNewRound", "a", "1=0", "2=0")
g_CvarDropOnDeath = register_cvar("knifeapi_dropondeath", "1")
g_CvarLossOnDeath = register_cvar("knifeapi_lossondeath", "1")
g_CvarSwitchMenu = register_cvar("knifeapi_switchmenu", "1")
g_CvarRoundRemoval = register_cvar("knifeapi_roundremoval", "1")
g_CvarPointerFF = get_cvar_pointer("mp_friendlyfire")
register_clcmd("drop", "_cDrop")
register_concmd("knifeapi_list", "_cKnivesList", ADMIN_ALL)
// our Five(5) forwards
g_ForwardIds[Forward_ProcessAttackPre] = CreateMultiForward("KnifeAction_ProcessAttack_Pre", ET_STOP, FP_CELL, FP_CELL, FP_CELL)
g_ForwardIds[Forward_ProcessAttackPost] = CreateMultiForward("KnifeAction_ProcessAttack_Post", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_ARRAY, FP_ARRAY)
g_ForwardIds[Forward_DealDamage] = CreateMultiForward("KnifeAction_DealDamage", ET_STOP, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_CELL, FP_ARRAY, FP_ARRAY, FP_CELL)
g_ForwardIds[Forward_Deploy] = CreateMultiForward("KnifeAction_Deploy", ET_IGNORE, FP_CELL, FP_CELL)
g_ForwardIds[Forward_SoundPlay] = CreateMultiForward("KnifeAction_SoundPlay", ET_STOP, FP_CELL, FP_CELL, FP_STRING)
g_BloodDecals[0] = engfunc(EngFunc_DecalIndex, "{blood1")
g_BloodDecals[1] = engfunc(EngFunc_DecalIndex, "{blood2")
g_BloodDecals[2] = engfunc(EngFunc_DecalIndex, "{blood3")
g_BloodDecals[3] = engfunc(EngFunc_DecalIndex, "{blood4")
g_BloodDecals[4] = engfunc(EngFunc_DecalIndex, "{blood5")
g_BloodDecals[5] = engfunc(EngFunc_DecalIndex, "{blood6")
plik_vault = nvault_open("noze")
if(plik_vault == INVALID_HANDLE)
set_fail_state("Nie moge otworzyc pliku ");
}
public client_authorized(id)
load_g_Knife(id);
public client_disconnect(id) {
save_g_Knife(id)
g_Knife[id]=0 // zeby ktos kto wejdzie po nas nie mial naszych fragow zapisanych w tablicy
copy(g_name[id], 47, "");
// mozna by wyswietlic komunikat ale tylko gdy uzywamy komendy bo inaczej nie dosc ze nic sie nie wyswietli
// to w logach zobaczymy "index out of bound"
}
public plugin_cfg()
{
// we register the commands in plugin_cfg, since plugins registering knives post plugin_init would not work correctly
for(new i = 0; i <= g_TotalKnives; i++)
{
if(g_Knives[i][_SpriteName][0])
{
g_Knives[i][__CommandIndex__] = register_clcmd(g_Knives[i][_SpriteName], "_cKnifeUsage")
}
}
}
// remove the knives lying on the ground here
public _eNewRound()
{
if(!get_pcvar_num(g_CvarRoundRemoval))
{
return
}
new Ent = -1
while((Ent = find_ent_by_class(Ent, KNIFE_CLASSNAME)))
{
remove_entity(Ent)
}
}
// first I wanted to hook Ham_Weapon_Reload, but I guessed it wouldn't work with knife
public _fwCmdStart(id, UcHandle, Seed)
{
if(!is_user_alive(id) || get_user_weapon(id) != CSW_KNIFE)
{
return
}
if(get_uc(UcHandle, UC_Buttons) & IN_RELOAD && !(pev(id, pev_oldbuttons) & IN_RELOAD))
{
if(g_LockedKnife[id])
{
client_print(id, print_center, "You cannot change your knife right now.")
return
}
if(get_pcvar_num(g_CvarSwitchMenu))
{
showKnivesMenu(id)
}
else
{
setNextWeapon(id)
}
}
}
public _fwKilled(Victim)
{
remove_task(Victim)
if(get_pcvar_num(g_CvarDropOnDeath))
{
for(new i = 1; i <= g_TotalKnives; i++)
{
if(BitFunc_HasKnife(Victim, i))
{
if(g_Knives[i][_Droppable])
{
spawnKnifeFromPlayer(Victim, i, false, true)
}
}
}
}
if(get_pcvar_num(g_CvarLossOnDeath))
{
for(new i = 1; i <= g_TotalKnives; i++)
{
BitFunc_RemoveKnife(Victim, i)
}
g_CurrentKnife[Victim] = 0
updateWeaponHud(Victim)
g_LockedKnife[Victim] = false
}
}
public client_connect(id)
{
for(new i = 1; i <= g_TotalKnives; i++)
{
BitFunc_RemoveKnife(id, i)
}
g_CurrentKnife[id] = 0
g_LockedKnife[id] = false
}
public _fwEmitSound(id, Channel, Sample[])
{
if(!is_user_alive(id) || (Channel != CHAN_WEAPON && Channel != CHAN_ITEM))
{
return FMRES_IGNORED
}
if(equal(Sample, "weapons/knife_", 14))
{
if(equal(Sample[14], "deploy", 6))
{
new Knife = g_CurrentKnife[id]
if(g_Knives[Knife][_DeploySound][0])
{
new ReturnVal
ExecuteForward(g_ForwardIds[Forward_SoundPlay], ReturnVal, id, Knife, g_Knives[Knife][_DeploySound])
if(ReturnVal == KnifeAction_Block)
{
return FMRES_SUPERCEDE
}
emit_sound(id, Channel, g_Knives[Knife][_DeploySound], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
}
return FMRES_SUPERCEDE
}
return FMRES_SUPERCEDE
}
return FMRES_IGNORED
}
public _fwTraceAttack(Victim, Attacker, Float:Damage, Float:VecDir[3], Ptr, DamageBitsum)
{
static const DMG_KNIFE = (DMG_BULLET | DMG_NEVERGIB)
if(IsPlayer(Attacker) && get_user_weapon(Attacker) == CSW_KNIFE && DamageBitsum & DMG_KNIFE)
{
return HAM_SUPERCEDE
}
return HAM_IGNORED
}
public _fwDeploy(Entity)
{
new PlayerId = get_pdata_cbase(Entity, m_pPlayer, XO_CBASEPLAYERITEM)
new CurrentKnife = g_CurrentKnife[PlayerId]
set_pev(PlayerId, pev_viewmodel2, g_Knives[CurrentKnife][_VModel])
set_pev(PlayerId, pev_weaponmodel2, g_Knives[CurrentKnife][_PModel])
set_pev(Entity, pev_knifevalue, CurrentKnife)
new ReturnVal
ExecuteForward(g_ForwardIds[Forward_Deploy], ReturnVal, PlayerId, CurrentKnife)
}
public _fwPrimaryAttack(Entity)
{
return ProcessAttack(Entity, Primary)
}
public _fwSecondaryAttack(Entity)
{
return ProcessAttack(Entity, Secondary)
}
public _fwPrimaryAttack_Post(Entity)
{
new Player = get_pdata_cbase(Entity, m_pPlayer, XO_CBASEPLAYERITEM)
new Knife = g_CurrentKnife[Player]
new Float:PrimaryNextAttack = Float:g_Knives[Knife][_NextAttack][Primary]
if(PrimaryNextAttack)
{
set_pdata_float(Entity, m_flNextPrimaryAttack, PrimaryNextAttack, XO_CBASEPLAYERITEM)
if(g_Knives[Knife][_NextAttackDependency])
{
set_pdata_float(Entity, m_flNextSecondaryAttack, PrimaryNextAttack, XO_CBASEPLAYERITEM)
}
}
}
public _fwSecondaryAttack_Post(Entity)
{
new Player = get_pdata_cbase(Entity, m_pPlayer, XO_CBASEPLAYERITEM)
new Knife = g_CurrentKnife[Player]
new Float:SecondaryNextAttack = Float:g_Knives[Knife][_NextAttack][Secondary]
if(SecondaryNextAttack)
{
set_pdata_float(Entity, m_flNextSecondaryAttack, SecondaryNextAttack, XO_CBASEPLAYERITEM)
if(g_Knives[Knife][_NextAttackDependency])
{
set_pdata_float(Entity, m_flNextPrimaryAttack, SecondaryNextAttack, XO_CBASEPLAYERITEM)
}
}
}
ProcessAttack(Entity, AttackType)
{
new Player = get_pdata_cbase(Entity, m_pPlayer, XO_CBASEPLAYERITEM)
new Knife = g_CurrentKnife[Player]
new ReturnVal
ExecuteForward(g_ForwardIds[Forward_ProcessAttackPre], ReturnVal, Player, Knife, !AttackType)
if(ReturnVal == KnifeAction_Block)
{
return HAM_SUPERCEDE
}
new TaskData[4]
TaskData[0] = Player
TaskData[1] = Knife
TaskData[2] = AttackType
TaskData[3] = Entity
if(g_Knives[Knife][_DamageDelay][AttackType])
{
set_task(g_Knives[Knife][_DamageDelay][AttackType], "DelayAttack", Player, TaskData, sizeof TaskData)
}
else
{
DelayAttack(TaskData)
}
return HAM_IGNORED
}
public DelayAttack(TaskData[])
{
new Player = TaskData[0]
new Knife = TaskData[1]
new AttackType = TaskData[2]
new Entity = TaskData[3]
if(!is_user_connected(Player))
{
return
}
new Float:ViewOfs[3], Float:Start[3], Float:End[3], Float:Aim[3]
pev(Player, pev_origin, Start)
pev(Player, pev_view_ofs, ViewOfs)
xs_vec_add(Start, ViewOfs, Start)
velocity_by_aim(Player, 1, Aim)
xs_vec_mul_scalar(Aim, g_Knives[Knife][_Range][AttackType], End)
xs_vec_add(Start, End, End)
new Trace, Float:Fraction
engfunc(EngFunc_TraceLine, Start, End, DONT_IGNORE_MONSTERS, Player, Trace)
get_tr2(Trace, TR_flFraction, Fraction)
if(Fraction >= 1.0)
{
engfunc(EngFunc_TraceHull, Start, End, DONT_IGNORE_MONSTERS, HULL_HEAD, Player, Trace)
get_tr2(Trace, TR_flFraction, Fraction)
}
new ReturnVal
new PreparedEndVector = PrepareArray(_:End, 3)
new PreparedAimVector = PrepareArray(_:Aim, 3)
if(Fraction >= 1.0)
{
ExecuteForward(g_ForwardIds[Forward_ProcessAttackPost], ReturnVal, Player, 0, Knife,
!AttackType, PreparedEndVector, PreparedAimVector
)
if(g_Knives[Knife][_WhiffSound][0])
{
new ReturnVal
ExecuteForward(g_ForwardIds[Forward_SoundPlay], ReturnVal, Player, Knife, g_Knives[Knife][_WhiffSound])
if(ReturnVal != KnifeAction_Block)
{
emit_sound(Player, CHAN_WEAPON, g_Knives[Knife][_WhiffSound], VOL_NORM, ATTN_NORM, 0, 94)
}
}
}
else
{
new HitPlayer = get_tr2(Trace, TR_pHit)
if(IsPlayer(HitPlayer))
{
ExecuteForward(g_ForwardIds[Forward_ProcessAttackPost], ReturnVal, Player, HitPlayer, Knife,
!AttackType, PreparedEndVector, PreparedAimVector
)
// to ignore friendly fire
new Previous = get_pcvar_num(g_CvarPointerFF)
if(!Previous)
{
if(g_Knives[Knife][_IgnoreFriendlyFire]) set_pcvar_num(g_CvarPointerFF, 1)
else return
}
new Hitgroup = get_tr2(Trace, TR_iHitgroup)
new bool:Backstab = isBackstab(Player, HitPlayer)
new Float:Damage = g_HitgroupDamage[AttackType][Hitgroup] * Float:g_Knives[Knife][_Damage][Primary]
if(AttackType == Primary && Backstab)
{
Damage *= 3.0
}
new DmgBits = g_Knives[Knife][_DmgBits][AttackType] ? g_Knives[Knife][_DmgBits][AttackType] : DMG_BULLET|DMG_NEVERGIB
ExecuteForward(g_ForwardIds[Forward_DealDamage], ReturnVal, Player, HitPlayer, Knife, Damage,
!AttackType, DmgBits, Backstab, PreparedEndVector, PreparedAimVector, Hitgroup
)
if(ReturnVal == KnifeAction_Block)
{
return
}
UTIL_BloodDrips(End, 248, _:Damage)
new Float:HitOrigin[3]
pev(HitPlayer, pev_origin, HitOrigin)
if(pev(HitPlayer, pev_bInDuck))
{
HitOrigin[2] -= 18.0
}
else
{
HitOrigin[2] -= 36.0
}
UTIL_BloodDecal(HitOrigin, g_BloodDecals[random(sizeof g_BloodDecals)])
set_pdata_int(HitPlayer, m_LastHitGroup, Hitgroup)
emit_sound(HitPlayer, CHAN_VOICE,
g_HitFleshSound[Hitgroup == HIT_HEAD ? 1:0][random(sizeof g_HitFleshSound[])],
VOL_NORM, ATTN_NORM, 0, PITCH_NORM
)
if(AttackType == Primary)
{
if(g_Knives[Knife][_SlashSound][0])
{
new ReturnVal
ExecuteForward(g_ForwardIds[Forward_SoundPlay], ReturnVal, Player, Knife, g_Knives[Knife][_SlashSound])
if(ReturnVal != KnifeAction_Block)
{
emit_sound(Player, CHAN_WEAPON, g_Knives[Knife][_SlashSound], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
}
}
ExecuteHam(Ham_TakeDamage, HitPlayer, Entity, Player, Damage, DmgBits)
}
else
{
if(g_Knives[Knife][_StabSound][0])
{
new ReturnVal
ExecuteForward(g_ForwardIds[Forward_SoundPlay], ReturnVal, Player, Knife, g_Knives[Knife][_StabSound])
if(ReturnVal != KnifeAction_Block)
{
emit_sound(Player, CHAN_WEAPON, g_Knives[Knife][_StabSound], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
}
}
ExecuteHam(Ham_TakeDamage, HitPlayer, Entity, Player, Damage, DmgBits)
}
if(Previous && g_Knives[Knife][_IgnoreFriendlyFire])
{
set_pcvar_num(g_CvarPointerFF, 1)
}
}
else if(g_Knives[Knife][_WallSound][0])
{
new ReturnVal
ExecuteForward(g_ForwardIds[Forward_ProcessAttackPost], ReturnVal, Player, 0, Knife,
!AttackType, PreparedEndVector, PreparedAimVector
)
ExecuteForward(g_ForwardIds[Forward_SoundPlay], ReturnVal, Player, Knife, g_Knives[Knife][_WallSound])
if(ReturnVal != KnifeAction_Block)
{
emit_sound(Player, CHAN_ITEM, g_Knives[Knife][_WallSound], VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
}
}
}
free_tr2(Trace)
}
public _cDrop(id)
{
if(!is_user_alive(id) || get_user_weapon(id) != CSW_KNIFE)
{
return PLUGIN_CONTINUE
}
if(g_LockedKnife[id])
{
client_print(id, print_center, "Nie mozna upuscic noz.")
return PLUGIN_HANDLED
}
new CurrentKnife = g_CurrentKnife[id]
if(g_Knives[CurrentKnife][_Droppable])
{
spawnKnifeFromPlayer(id, CurrentKnife, true)
removeKnife(id, CurrentKnife)
return PLUGIN_HANDLED
}
return PLUGIN_CONTINUE
}
public _cKnifeUsage(id, level, cid)
{
engclient_cmd(id, "weapon_knife")
if(g_LockedKnife[id])
{
client_print(id, print_center, "Nie mozna zmienic noza.")
return PLUGIN_HANDLED
}
for(new i = 0; i <= g_TotalKnives; i++)
{
if(BitFunc_HasKnife(id, i) && g_Knives[i][__CommandIndex__] == cid && i != g_CurrentKnife[id])
{
g_CurrentKnife[id] = i
redeployKnife(id)
}
}
return PLUGIN_HANDLED
}
public _cKnivesList(id, Level)
{
if(~get_user_flags(id) & Level)
{
return PLUGIN_CONTINUE
}
new Len, Buffer[2048]
for(new i = 1; i <= g_TotalKnives; i++)
{
Len = formatex(Buffer, charsmax(Buffer), "^nKnife Index: #%d^nName: %s^nVModel: %s^nPModel: %s^nWModel: %s^n", i,
g_Knives[i][_WeaponName],
g_Knives[i][_VModel],
g_Knives[i][_PModel],
g_Knives[i][_WModel]
)
Len += formatex(Buffer[Len], charsmax(Buffer) - Len, "Deploy Sound: %s^nSlash Sound: %s^n", g_Knives[i][_DeploySound], g_Knives[i][_SlashSound])
Len += formatex(Buffer[Len], charsmax(Buffer) - Len, "Stab Sound: %s^nWhiff Sound: %s^nWall Sound: %s^n",
g_Knives[i][_StabSound],
g_Knives[i][_WhiffSound],
g_Knives[i][_WallSound]
)
Len += formatex(Buffer[Len], charsmax(Buffer) - Len,
"Droppable: %s^nCustom Sprite: %s^nPrimary Damage: %.1f^nSecondary Damage: %.1f^nPrimary NextAttack: %.1f^nSecondary NextAttack %.1f^n",
g_Knives[i][_Droppable] ? "Yes" : "No",
g_Knives[i][_SpriteName][0] ? "Yes" : "No",
g_Knives[i][_Damage][Primary],
g_Knives[i][_Damage][Secondary],
g_Knives[i][_NextAttack][Primary],
g_Knives[i][_NextAttack][Secondary]
)
Len += formatex(Buffer[Len], charsmax(Buffer) - Len,
"Primary Range: %.1f^nSecondary Range: %.1f^nPrimary Damage Delay: %.1f^nSecondary Damage Delay: %.1f^n",
g_Knives[i][_Range][Primary],
g_Knives[i][_Range][Secondary],
g_Knives[i][_DamageDelay][Primary],
g_Knives[i][_DamageDelay][Secondary]
)
if(IsPlayer(id))
{
engclient_print(id, engprint_console, Buffer)
}
else
{
server_print(Buffer)
}
}
return PLUGIN_HANDLED
}
public _fwTouch(Entity, Player)
{
if(!IsPlayer(Player) || !pev_valid(Entity))
{
return
}
new KnifeType = pev(Entity, pev_knifevalue)
if(!KnifeType)
{
return
}
if(pev(Entity, pev_pickable) > get_gametime())
{
return
}
if(!BitFunc_HasKnife(Player, KnifeType))
{
if(giveKnife(Player, KnifeType))
{
set_pev(Entity, pev_flags, FL_KILLME)
}
}
}
showKnivesMenu(id)
{
new Knife[4], Menu = menu_create("Choose your knife", "_mKnivesHandler")
new MenuItem[45]
new Team = get_user_team(id)
for(new i = 0; i <= g_TotalKnives; i++)
{
if(BitFunc_HasKnife(id, i))
{
if(g_Knives[i][_TeamLock] && Team != g_Knives[i][_TeamLock])
{
continue
}
num_to_str(i, Knife, charsmax(Knife))
formatex(MenuItem, charsmax(MenuItem), "%s%s",
g_Knives[i][_WeaponName],
i == g_CurrentKnife[id] ? "\y - Selected" : ""
)
menu_additem(Menu, MenuItem, Knife)
}
}
menu_display(id, Menu)
}
public _mKnivesHandler(id, Menu, Item)
{
if (Item != MENU_EXIT)
{
if(g_LockedKnife[id])
{
client_print(id, print_center, "You cannot change your knife right now.")
menu_destroy(Menu)
return PLUGIN_HANDLED
}
new Junk, Knife[4]
menu_item_getinfo(Menu, Item, Junk, Knife, charsmax(Knife), .callback = Junk)
new KnifeIndex = str_to_num(Knife)
if(BitFunc_HasKnife(id, KnifeIndex))
{
g_CurrentKnife[id] = KnifeIndex
redeployKnife(id)
}
}
menu_destroy(Menu)
return PLUGIN_HANDLED
}
updateWeaponHud(id)
{
new CurrentKnife = g_CurrentKnife[id]
message_begin(MSG_ONE, g_MsgIndexWeaponList, _, id)
if(!g_Knives[CurrentKnife][_SpriteName][0])
{
write_string("weapon_knife")
}
else
{
write_string(g_Knives[CurrentKnife][_SpriteName])
}
write_byte(-1)
write_byte(-1)
write_byte(-1)
write_byte(-1)
write_byte(2)
write_byte(1)
write_byte(CSW_KNIFE)
write_byte(0)
message_end()
}
giveKnife(Player, Knife, bool:Set = true)
{
if(g_Knives[Knife][_TeamLock] && get_user_team(Player) != g_Knives[Knife][_TeamLock])
{
return 0
}
BitFunc_SetKnife(Player, Knife)
if(Set) g_CurrentKnife[Player] = Knife
if(is_user_alive(Player))
{
emit_sound(Player, CHAN_AUTO, "items/gunpickup2.wav", VOL_NORM, ATTN_NORM, 0, PITCH_NORM)
if(Set) redeployKnife(Player)
set_dhudmessage( 0, 160, 0, -1.0, 0.25, 2, 6.0, 3.0, 0.1, 1.5 );
show_dhudmessage( 0, "Wygrales %s. Nacisnij klawisz R (przeladowanie) aby zmienic noz.",
g_Knives[Knife][_WeaponName]
)
message_begin(MSG_ONE, g_MsgIndexWeapPickup, _, Player)
write_byte(CSW_KNIFE)
message_end()
}
return 1
}
removeKnife(Player, Knife)
{
if(g_CurrentKnife[Player] == Knife)
{
setNextWeapon(Player)
}
BitFunc_RemoveKnife(Player, Knife)
redeployKnife(Player)
}
setNextWeapon(Player)
{
new NextKnifeIndex, Team = get_user_team(Player)
for(new i = g_CurrentKnife[Player] + 1; i <= g_TotalKnives; i++)
{
if(BitFunc_HasKnife(Player, i))
{
if(g_Knives[i][_TeamLock] && Team != g_Knives[i][_TeamLock])
{
continue
}
NextKnifeIndex = i
break
}
}
if(NextKnifeIndex != g_CurrentKnife[Player])
{
g_CurrentKnife[Player] = NextKnifeIndex
redeployKnife(Player)
}
}
redeployKnife(Player)
{
new CurrentKnife = g_CurrentKnife[Player]
if(g_Knives[CurrentKnife][_TeamLock] && get_user_team(Player) != g_Knives[CurrentKnife][_TeamLock])
{
setNextWeapon(Player)
return
}
new WeaponId = get_pdata_cbase(Player, m_rgpPlayerItems_CBasePlayer[3])
client_cmd(Player, "weapon_knife")
if(pev_valid(WeaponId))
{
ExecuteHamB(Ham_Item_Deploy, WeaponId)
}
sendKnifeAnimation(Player)
updateWeaponHud(Player)
}
sendKnifeAnimation(id, Anim = 3)
{
set_pev(id, pev_weaponanim, Anim)
message_begin(MSG_ONE, SVC_WEAPONANIM, {0, 0, 0}, id)
write_byte(Anim)
write_byte(0)
message_end();
}
spawnKnifeFromPlayer(Player, Knife, bool:SetVelocity = false, bool:FindEmptyLoc = false)
{
new Float:PlayerOrigin[3]
entity_get_vector(Player, EV_VEC_origin, PlayerOrigin)
if(FindEmptyLoc)
{
new Num
if(!findEmptyLocation(Player, PlayerOrigin, Num, 45.0))
{
client_print(Player, print_chat, "Oops, couldn't create knife entity in your location.")
return
}
}
new Entity = create_entity("info_target")
entity_set_string(Entity, EV_SZ_classname, "tossed_knife")
entity_set_origin(Entity, PlayerOrigin)
if(SetVelocity)
{
new Float:NewVelocity[3]
velocity_by_aim(Player, 350, NewVelocity)
entity_set_vector(Entity, EV_VEC_velocity, NewVelocity)
}
static const Float:Minbox[3] = {-2.5, -2.5, -2.5}
static const Float:Maxbox[3] = {2.5, 2.5, -2.5}
entity_set_vector(Entity, EV_VEC_mins, Minbox)
entity_set_vector(Entity, EV_VEC_maxs, Maxbox)
entity_set_int(Entity, EV_INT_solid, SOLID_TRIGGER)
entity_set_int(Entity, EV_INT_movetype, MOVETYPE_TOSS)
// so it's not picked up immediately after throwing it
set_pev(Entity, pev_pickable, get_gametime() + 1.3)
if(g_Knives[Knife][_WModel][0])
{
entity_set_model(Entity, g_Knives[Knife][_WModel])
}
else
{
entity_set_model(Entity, DEFAULT_WMODEL)
}
set_pev(Entity, pev_knifevalue, Knife)
}
findEmptyLocation(id, Float:Origin[3], &Num, Float:Radius)
{
if(Num++ > 100)
return 0
new Float:PlayerOrigin[3]
pev(id, pev_origin, PlayerOrigin)
for(new i; i < 2; i++)
PlayerOrigin[i] += random_float(-Radius, Radius)
if(PointContents(PlayerOrigin) != CONTENTS_EMPTY && PointContents(PlayerOrigin) != CONTENTS_SKY)
return findEmptyLocation(id, Origin, Num, Radius)
Origin = PlayerOrigin
return 1
}
bool:isBackstab(const Attacker, const Victim)
{
new Float:Vec1[3]
new Float:Vec2[3]
velocity_by_aim(Attacker, 1, Vec1)
new Float:InvLen = xs_rsqrt(Vec1[0] * Vec1[0] + Vec1[1] * Vec1[1])
Vec1[0] *= InvLen
Vec1[1] *= InvLen
pev(Victim, pev_angles, Vec2)
angle_vector(Vec2, ANGLEVECTOR_FORWARD, Vec2)
return Vec1[0] * Vec2[0] + Vec1[1] * Vec2[1] > 0.8 ? true : false
}
UTIL_BloodDrips(Float:Origin[3], Color, Amount)
{
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_BLOODSPRITE)
engfunc(EngFunc_WriteCoord, Origin[0])
engfunc(EngFunc_WriteCoord, Origin[1])
engfunc(EngFunc_WriteCoord, Origin[2])
write_short(g_sModelIndexBloodSpray)
write_short(g_sModelIndexBloodDrop)
write_byte(Color)
write_byte(min(max(3, Amount/10), 16))
message_end()
}
UTIL_BloodDecal(Float:Origin[3], DecalIndex)
{
message_begin(MSG_BROADCAST, SVC_TEMPENTITY)
write_byte(TE_WORLDDECAL)
engfunc(EngFunc_WriteCoord, Origin[0]) // x
engfunc(EngFunc_WriteCoord, Origin[1]) // y
engfunc(EngFunc_WriteCoord, Origin[2]) // z
write_byte(DecalIndex) // random decal number
message_end()
}
public plugin_end()
nvault_close(plik_vault)
public load_g_Knife(id)
{
new name[48]
get_user_name(id,name,47)
new vaultkey[64],vaultdata[128]
formatex(vaultkey,63,"%s-g_Knife",name)
if(nvault_get(plik_vault,vaultkey,vaultdata,127)) { // pobieramy dane
new g_Knifetemp[16], nametemp[48];
parse(vaultdata, g_Knifetemp, 15, nametemp, 47) // wydobywamy z ciagu vaultdata nasze dane
g_Knife[id]=str_to_num(g_Knifetemp) // przypisujemy danym ich wartosci wczytane
Knife_PlayerGive(id,g_Knife[id])
copy(g_name[id], 47, nametemp);
}
return PLUGIN_CONTINUE
}
public save_g_Knife(id) {
g_Knife[id]+=Knife_PlayerGive(id) // zwiekszamy liczbe fragow i deadow o stan bierzacy
new name[48]
get_user_name(id,name,47)
new vaultkey[64],vaultdata[128] // 2 zmienne na klucz i dane ktore bedziemy zapisywac
formatex(vaultkey,63,"%s-g_Knife",name) //formatujemy klucz czyli nasz identyfikator dostepu najlepiej zeby roznil sie on 1 czlonem od pozostalych
formatex(vaultdata,127,"%d %d ^"%s^"", g_Knife[id], name) // formatujemy dane
nvault_set(plik_vault,vaultkey,vaultdata) // zapisujemy dane "pod" danym kluczem w pliku
return PLUGIN_CONTINUE
}
Załączone pliki
-
aaknifeapi.sma 49,88 KB 63 Ilość pobrań
aaknifeapi.amxx