Thread: Knife API v2.2
View Single Post
Plugin Info:     Modification:          Category:          Approver:   hornet (5)
Backstabnoob
Veteran Member
Join Date: Feb 2009
Location: Iwotadai Dorm
Old 05-12-2014 , 12:46   Knife API v2.2
Reply With Quote #1

Knife API v2.2
Version 2.2 released on 21st of July, 2014



Table of Contents

Description top
My first intention for this plugin was for my upcoming RolePlaying mod, however I couldn't find anything like this in the plugins section, so I decided to pre-release it (same as my Database ORM).
Knife API makes adding new knives a breeze due to the knife pickup/switching/dropping mechanism it provides. This way, all knives are added via a standarized way. Version 2.0 has added many new possibilities and functions to the core.

If you have multiple knives, you can cycle between them (or display a menu if you have the cvar enabled) with the R (+reload) key.
WARNING: Plugins written for Knife API <2.0 ARE NOT COMPATIBLE with the latter versions. You will need to port your old plugin. Apologies, hopefully it won't happen again!

Possibilities top
This is a really great tool for plugins which depend on knives (such as knife servers, RolePlaying(), jailbreak and stuff like that). Creating knives via this will make them seem like seamless addition to the game, especially when combined with custom sprites.

What this plugin can do:
  • Assign basic values such as models and sounds to a newly created knife
  • Custom knife sprites, see examples
  • Custom knife range
  • Additional delay after the animation start
  • Catch events such as attacking/drawing weapon for even more extendability
  • Etc.

What this plugin can't do:
  • While it can do a lot, you still have to put in some work yourself
  • There's not much it can't do. It can't make you a sandwich.

Requirements top
The requirements are:
  • NOTHING RIGHT NOW! YAAY!

Installation, configuration top
To install:
Install like any other plugin. Download the source code, compile it and let other plugins take adventage of it.

To configure:
By default, the CS knife has been removed from game and replaced by Hands (you can see those on Jailbreak). If you want to change this habit, comment #define DEFAULT_HANDS in the source code on line 59. If you do this, you also don't need any of the resources.

To configure the default knife/hands values, edit the __addDefaultKnife() function in the source code on line 203.

Use the following cvars to change the basic plugin functionality:
  • knifeapi_dropondeath (default:1) - should droppable knives be dropped on the player death? This doesn't remove them from player. You must also use knifeapi_lossondeath!
  • knifeapi_lossondeath (default:1) - should player lose all of their knives on death (including droppable knives except the default one)?
  • knifeapi_switchmenu (default:1) - when pressing Reload, do you want to display the menu of knives rather than cycling through them?
  • knifeapi_roundremoval (default:1) - should knives dropped around be removed on round end?

API (Natives and forwards) top
I'll put the .inc file here, the natives and forwards should be explained in it. It won't tell you anything when it comes to writing down the actual plugins, you should look at the examples for that kind of stuff.
PHP Code:
// I don't really know what this does.
#pragma library "knifeapi"

/**************************************************
 ************ API ENUMS AND STRUCTURES ************
 *************************************************/

enum KnifeProperties
{
    
KN_STR_WeaponName,          // name of the weapon shown in the menu
    
KN_STR_VModel,              // v_model path including models/
    
KN_STR_PModel,              // p_model path including models/
    
KN_STR_WModel,              // w_model path including models/
    
KN_STR_DeploySound,         // deploy sound path
    
KN_STR_SlashSound,          // slash sound path
    
KN_STR_StabSound,           // stab sound path
    
KN_STR_WhiffSound,          // whiff (air) sound path
    
KN_STR_WallSound,           // wall hit sound path
    
KN_STR_SpriteName,          // if you're using a custom sprite, change this to the .txt filename (weapon_custom for example) - DON'T CHANGE IF YOU'RE NOT USING A CUSTOM SPRITE!!!
    
KN_CLL_Droppable,           // should be droppable?
    
KN_CLL_PrimaryDamage,       // primary damage multiplier (1.0 - default damage, 2.0 - double damage etc.)
    
KN_CLL_SecondaryDamage,     // secondary damage multiplier (1.0 - default damage, 2.0 - double damage etc.)
    
KN_CLL_PrimaryNextAttack,   // time between primary attacks in seconds
    
KN_CLL_SecondaryNextAttack// time between secondary attacks in seconds
    
KN_CLL_PrimaryRange,        // range of the primary attack
    
KN_CLL_SecondaryRange,      // range of the secondary attack
    
KN_CLL_PrimaryDamageDelay,  // delay between button press and the actual knife hit for primary damage
    
KN_CLL_SecondaryDamageDelay,// ^ for secondary damage
    
KN_CLL_PrimaryDmgBits,      // such as DMG_BULLET | DMG_ALWAYSGIB (makes the enemies explode), DMG_BULLET | DMG_NEVERGIB default
    
KN_CLL_SecondaryDmgBits,    // ^ for secondary
    
KN_CLL_TeamLock,            // if not 0, other team won't be able to pick up/deploy the knife
    
KN_CLL_NextAttackDependency,// if true, a primary attack also modifies the secondary next attack by the same amount (and vice versa); true by default
    
KN_CLL_IgnoreFriendlyFire   // ignore friendly fire?
};

enum _:ForwardReturns
{
    
KnifeAction_Block 5,
    
KnifeAction_DoNothing
};

/****************************************
 ************ PLUGIN NATIVES ************
 ***************************************/

/* Knife_Register(): Registers a knife.

 * @params: See KnifeProperties, they're the same
 * @info: You can use additional settings with Knife_SetProperty
 * @return: (Int) Pointer to the knife
*/
native Knife_Register(
    const 
WeaponName[] = "New Knife",             
    const 
VModel[],                                     
    const 
PModel[] = "",
    const 
WModel[] = "",
    const 
DeploySound[] = "weapons/knife_deploy1.wav",
    const 
SlashSound[] = "weapons/knife_hit1.wav",
    const 
StabSound[] = "weapons/knife_stab.wav",
    const 
WhiffSound[] = "weapons/knife_slash1.wav",
    const 
WallSound[] = "weapons/knife_hitwall1.wav",
    
Float:PrimaryDamage 1.0
    
Float:SecondaryDamage 1.0
);

/* Knife_GetTotal(): Returns the amount of knives registered.

 * @info: Used for loops of knives: for(new i=1; i<=Knife_GetTotal(); i++)
 
 * @return: (Int) amount of knives registered
*/
native Knife_GetTotal();

/* Knife_GetProperty(): Retrieves a property of a knife from the KnifeProperties enum.

 * @param (Int) Knife: Knife index
 * @param (Int) Value: Value from the KnifeProperties enum
 * @params (any...): If you're using a value from KN_STR_X, the next two params are output string and buffer size,
        otherwise it's only the output cell to which the data is saved by reference
 
 * @return: (Int) 1 on success, 0 on failure/error
*/
native Knife_GetProperty(KnifeKnifeProperties:Valueany:...);

/* Knife_SetProperty(): Sets a property of a knife from the KnifeProperties enum.

 * @param (Int) Knife: Knife index
 * @param (Int) Value: Value from the KnifeProperties enum
 * @params (any...): String/cell with the value
 
 * @return: (Int) 1 on success, 0 on failure/error
*/
native Knife_SetProperty(KnifeKnifeProperties:Valueany:...);

/* Knife_PlayerGive(): Gives a knife to a player.

 * @param (Int) Player: Index of the player
 * @param (Int) Knife: Knife index
 * @param (bool) Set: If true, the player will automatically equip the knife
 
 * @return: (Int) 1 on success, 0 on failure/error
*/
native Knife_PlayerGive(PlayerKnifebool:Set true);

/* Knife_PlayerGetCurrent(): Returns the current knife a player has equipped.

 * @param (Int) Player: Index of the player
 
 * @return: (Int) 0 - default knife, X - knife ID, -1 - error/failure
*/
native Knife_PlayerGetCurrent(Player);

/* Knife_PlayerSetCurrent(): Force-equips a knife on the player. Player must own the knife.

 * @param (Int) Player: Index of the player to give the knife to
 * @param (Int) Knife: Knife index
 
 * @return: (Int) 1 on success, 0 on failure/error
*/
native Knife_PlayerSetCurrent(PlayerKnife);

/* Knife_PlayerHas(): Check whether a player has a knife.

 * @param (Int) Player: Index of the player
 * @param (Int) Knife: Knife index
 
 * @return: (Int) 1 on yes, 0 on failure/error/no
*/
native Knife_PlayerHas(PlayerKnife);

/* Knife_PlayerSetLock(): Prevents a player from changing their knife.

 * @param (Int) Player: Index of the player
 * @param (Bool) Locked: Lock status - true: locked, false: unlocked
 
 * @return: nothing
*/
native Knife_PlayerSetLock(Playerbool:Locked);

/* Knife_PlayerGetLock(): Checks player's knife lock status.

 * @param (Int) Player: Index of the player
 
 * @return: (Bool) true: locked, false: unlocked
*/
native bool:Knife_PlayerGetLock(Player);

/* Knife_PlayerRemoveAll(): Removes all knives except default from the player.

 * @param (Int) Player: Index of the player
 
 * @return: nothing
*/
native Knife_PlayerRemoveAll(Player);

/**********************************
 ************ FORWARDS ************
 *********************************/ 

/* KnifeAction_ProcessAttack_Pre(): Called when an attack is about to happen.
        Pre hook: This gets called before the animation delay if there is any.
        You can block the action with KnifeAction_Block.
 * @param (Int) Player: Index of the player(attacker)
 * @param (Int) Knife: Knife index
 * @param (bool) PrimaryAttack: true: yes, false: no
*/
forward KnifeAction_ProcessAttack_Pre(PlayerKnifebool:PrimaryAttack);

/* KnifeAction_ProcessAttack_Post(): Called when an attack has happened.
        Post hook: This gets called after the animation delay, if there's any.
        You cannot block this forward. Block KnifeAction_DealDamage instead.
 * @param (Int) Player: Index of the player(attacker)
 * @param (Int) Victim: Player receiving the damage. If there was no player (wall/air slash), Victim is 0.
 * @param (Int) Knife: Knife index
 * @param (bool) PrimaryAttack: true: yes, false: no
 * @param (Vector) EndPoint: Ending point of the knife trace. This is the origin where the damage has happened.
        I recommend playing your custom sounds/showing various sprites using this.
 * @param (Vector) AimVector: Player's aiming direction
*/
forward KnifeAction_ProcessAttack_Post(PlayerVictimKnifebool:PrimaryAttackFloat:EndPoint[3], Float:AimVector[3]);

/* KnifeAction_DealDamage(): Called right before an attack happening
        Pre hook: You can block the action with KnifeAction_Block.
 * @param (Int) Attacker: Index of the player(attacker)
 * @param (Int) Victim: Player receiving the damage
 * @param (Int) Knife: Knife index
 * @param (Float) Damage: Damage received with modifiers in mind (hitboxes/backstab/custom damage multiplier)
 * @param (bool) PrimaryAttack: true: yes, false: no
 * @param (Vector) EndPoint: Ending point of the knife trace. This is the origin where the damage has happened.
        I recommend playing your custom sounds/showing various sprites using this.
 * @param (Vector) AimVector: Player's aiming direction
 * @param (Int) Hitzone: Damage hitzone, such as HIT_HEAD.
*/
forward KnifeAction_DealDamage(AttackerVictimKnifeFloat:Damagebool:PrimaryAttackDamageBitsbool:Backstab
    
Float:EndPoint[3], Float:AimVector[3], Hitzone
);

/* KnifeAction_Deploy(): Called when a player draws a knife.
        Post hook: You cannot block this forward.
 * @param (Int) Attacker: Index of the player
 * @param (Int) Knife: Knife index
*/
forward KnifeAction_Deploy(PlayerKnife);

/* KnifeAction_SoundPlay(): Called when a knife sound is about to play.
        Pre hook: You can block the action with KnifeAction_Block.
 * @param (Int) Player: Index of the player
 * @param (Int) Knife: Knife index
 * @param (String) Sound: Sound played
*/
forward KnifeAction_SoundPlay(PlayerKnife, const Sound[]); 
Credits top
  • Mario AR. - custom sprites for knives, noticing stupid mistakes I left behind.
  • Black Rose - attack range/animation delay code.



Changelog top
  • v2.2
    • Code improved, completely got rid of dynamic arrays (too much data manipulation = stack errors)
    • Headshot sounds now correct
    • No longer using Ham_TraceAttack, Ham_TakeDamage is enough (blood is spawned manually)
    • Knife_PlayerGive now has a new argument - bool:Set, if true then the knife is equipped upon receiving it
    • KnifeAction_DealDamage now has 3 new arguments: Float:EndPoint[3], Float:AimVector[3], Hitzone
    • Release date: 21 July, 2014 (21 downloads reset)
  • v2.1.1
    • Global vars having incorrect size (MAXPLAYERS rather than MAXPLAYERS+1) has been fixed
    • Added a new property: KN_CLL_IgnoreFriendlyFire (thanks to hornet)
    • Release date: 17 July, 2014 (11 downloads reset)
  • v2.1
    • Fixed a stack error bug on dropping knives
    • Some small optimizations and code enhancements
    • Fixed forward returns not being taken into account for blockable hooks
    • KnifeAction_DealDamage now provides two more arguments - DamageBits and bool:Backstab
    • Added 4 more properties: KN_CLL_Primary/SecondaryDmgBits, KN_CLL_TeamLock, KN_CLL_NextAttackDependency
    • Changed weapon commands to use command indexes instead
    • Release date: 17 July, 2014 (18 downloads reset)
  • v2.0 - Major
    • Style rewritten, I'm dropping my old stupid unreadable style
    • Renamed knife_api.inc to knifeapi.inc so it makes more sense
    • A lot of slight optimizations and bug fixes
    • Got rid of cstrike_pdatas requirement by copy-pasting the required constants right into the .sma file
    • Got rid of 32 knives limit, feel free to change it to whatever you wish
    • Added support for custom knife sprites, thanks Mario AR.
    • Added a cvar for optional menu with knives on R press rather than cycling through them (knifeapi_switchmenu), thanks Mario AR.
    • Added a cvar to optionally delete all knives lying on the ground at round end
    • Added a new admin command (knifeapi_list) which prints all of the registered knives into the console
    • Knives now also have names (and shortnames such as weapon_hands used for custom sprites)
    • Added support for primary/secondary attack range and animation delay
    • Completely renamed all of the natives to correspond with my new style; you'll have to change your plugins
    • Added new natives: Knife_GetTotal(), Knife_GetProperty(), Knife_SetProperty() - see the KnifeProperties enum for applicable values
    • Removed forwards KnifeAction_Primary/SecondaryAttack, replaced with KnifeAction_DealDamage and KnifeAction_ProcessAttack_Pre/Post
    • Release date: 14 July, 2014 (66 downloads reset)
  • v1.1
    • Fixed a bug where undroppable knives were also dropped on death
    • Fixed a bug where picking a knife up with a different weapon drawn, the weapon's submodel was changed only so you were shooting with knife
    • Fixed a bug where damage wasn't taking hitzones into account, thanks KliPPy
    • Changed KnifeAction_TakeDamage to KnifeAction_TraceAttack
    • Added new natives: lock_knife(), get_user_knife_status(), remove_knives()
    • Changed default hands damage from 13.0 and 25.0 to 5.0 and 15.0 to make it slower in duels
    • Release date: 13 May, 2014 (?? downloads reset)
  • v1.0.1
    • Fixed a small bug where knife would do no damage if #DEFAULT_HANDS was commented
    • Release date: 12 May, 2014 (?? downloads reset)
  • v1.0
    • Initial release
    • Release date: 12 May, 2014
Attached Files
File Type: zip resources.zip (244.5 KB, 1395 views)
File Type: sma Get Plugin or Get Source (knifeapi.sma - 2782 views - 47.9 KB)
File Type: inc knifeapi.inc (8.8 KB, 1264 views)
__________________
Currently busy working on a very large scale anime database project.

Last edited by Backstabnoob; 07-20-2014 at 19:16.
Backstabnoob is offline