Raised This Month: $51 Target: $400
 12% 

CS:GO Music Kit


Post New Thread Reply   
 
Thread Tools Display Modes
Plugin Info:     Modification:   Counter-Strike        Category:   Event Related       
hellmonja
Senior Member
Join Date: Oct 2015
Old 07-09-2016 , 15:02   CS:GO Music Kit
Reply With Quote #1

CS:GO MUSIC KIT v1.7.3
CS.16 JUST GOT A BIT LOUDER

Description:
A plugin that gives you CS:GO style music kit for CS1.6.
Music kits are event-triggered musical ques introduced in CS:GO.

Requires:
cstrike

CVAR:
  • musickit_set [default 1] - Sets which music kit is the default one.
  • musickit_howmany [default 5] - Number of music kits you have installed. Set manually in amxx.cfg so the plugin will know.

Console Commands:
  • "kit1" thru "kit5" - Change kits mid game.
  • "kit 0" - Mute command.

Notes:
  • One advantage of this plugin against the CS:GO version is that you can mix and match sound files.
  • All sounds are in MP3 format so they do not interfere with WAV sounds and they cancel each other out.
  • A variety of end round events are supported, including:
    - Bomb related end rounds like defused and target bombed
    - VIP escapes and assassinated
    - Hostages not rescued
    - Round draw
    - And many others
  • More music kits may come in the future.
  • This is still beta. I recognize it is not optimized and I humbly request this site's members to help me optimize it
  • Now you can set which kits to play in-game.

Change Log:
v1.7.3
  • Rewrote the whole thing.
  • Settings are now individualized. Players can choose their kits mid game without affecting others.
  • You can now have up to 99 kits.
  • Flexible system that registers console commands by how many kits you have.
  • Various bugs and fixes.
v1.0
  • Huge optimizations. (Thanks to addon_zz)
  • Can now choose from 5 sets of music kits and change them in-game. (Thanks to Bugsy)
  • Bugs on "ten seconds left" functions fixed.
Attached Files
File Type: sma Get Plugin or Get Source (csgo_musickit.sma - 1495 views - 7.8 KB)
File Type: 7z sample_kit_ct.7z (3.27 MB, 724 views)
File Type: 7z sample_kit_t.7z (2.28 MB, 548 views)
__________________

Last edited by hellmonja; 08-30-2016 at 08:53. Reason: Update v1.7.3
hellmonja is offline
EFFx
Veteran Member
Join Date: Feb 2016
Location: São Paulo, Brasil
Old 07-09-2016 , 16:50   Re: CS:GO Music Kit
Reply With Quote #2

I cant say bad words.
__________________
• Ranking System • AutoMix 5vs5 System
• Web Ban System • Plugins for free

____________________________________________
For private works:
• Discord: EFFEXo#8850 • Steam: EFFEXo
EFFx is offline
addons_zz
Veteran Member
Join Date: Aug 2015
Location: Dreams, zz
Old 07-10-2016 , 00:30   Re: CS:GO Music Kit
Reply With Quote #3

Quote:
Originally Posted by hellmonja View Post
This is still beta. I recognize it is not optimized and I humbly request this site's members to help
Hi,

Thoughs, do not use #define to define the string '#define lostround "media/musickit/lostround.mp3"', because it is used 11 times, them it will create a memory 11 copies of it.
Using:
Code:
new const lostround[] = "media/musickit/lostround.mp3";
Should do the trick. It will create the string lostround only one time, and the others, it will use its address to the initial string instead of another copy.
Also, is a convention to use UPPERCASE letters for constants. Exemple:
Code:
new const PLUGIN_VERSION[] = "v3.2.0-196"; #define MAX_LONG_STRING   256 #define MAX_COLOR_MESSAGE 192 #define MAX_SHORT_STRING  64
  1. For my personal code reading:
    I like to append the type, when it is not clear the the variable name.
    Prefix 'g_' when they are global scope, and 'cvar_' when it is a cvar in global scope.
    To create defines for common arrays sizes. Example 'new players[32];', instead of type 32, use MAX_PLAYERS.
    Do not use variable names as 't', 'i', as they are hard to see and find.
    Example:
    Code:
    /**  * Append the type, prefix 'g_' and 'cvar_' example.  */ new Array:g_recentListMapsArray; new Trie: g_recentMapsTrie; new cvar_extendmapAllowStayType; new cvar_nextMapChangeAnnounce; new cvar_mp_freezetime; new cvar_mp_winlimit; /**  * Defines the maximum players number, when it is not specified for olders AMXX versions.  */ #if !defined MAX_PLAYERS     #define MAX_PLAYERS 32 #endif
  2. This:
    Code:
                if(cs_get_user_team(id) == CS_TEAM_CT)                 client_cmd(id, "mp3 play ^"%s^"", wonround);             else if (cs_get_user_team(id) == CS_TEAM_T)                 client_cmd(id, "mp3 play ^"%s^"", lostround);                         bool_endofround = 1;             bool_bomb_planted = 0;
    // or this
            if(cs_get_user_team(id) == CS_TEAM_CT)             client_cmd(id, "mp3 play ^"%s^"", wonround);         else if (cs_get_user_team(id) == CS_TEAM_T)             client_cmd(id, "mp3 play ^"%s^"", lostround);
    Looks the same everywhere. To create a function which receive the only this that is constantly changing. If you want to avoid a function call, a macro should do the job.
    Example:
    Code:
    new g_dummy_value = 0; /** * Remove the colored strings codes '^4 for green', '^1 for yellow', '^3 for team' and * '^2 for unknown'. * * @param string[]       a string pointer to be formatted. */ #define REMOVE_CODE_COLOR_TAGS(%1) \ do \ { \     replace_all( %1, charsmax( %1 ), "^4", "" ); \     replace_all( %1, charsmax( %1 ), "^3", "" ); \     replace_all( %1, charsmax( %1 ), "^2", "" ); \     replace_all( %1, charsmax( %1 ), "^1", "" ); \ } while( g_dummy_value )
    // If you do not force semicolon use, something like this should be enough:
    #define REMOVE_CODE_COLOR_TAGS(%1) \ { \     replace_all( %1, charsmax( %1 ), "^4", "" ); \     replace_all( %1, charsmax( %1 ), "^3", "" ); \     replace_all( %1, charsmax( %1 ), "^2", "" ); \     replace_all( %1, charsmax( %1 ), "^1", "" ); \ }
  3. Do not hardcode values as in 'get_msg_arg_string(2, textmsg, 21);'. Use charmax instead.
    Example:
    Code:
    fgets( dictionaryFile, currentReadLine, charsmax( currentReadLine ) );
  4. Instead of looping throw all players, and doing 'client_cmd( id, ... )', why not remove the loop and to do only 'client_cmd( 0, ... )'?
    If you cannot to do this, you should loop throw them after you find which is the case is. This is to avoid repeated and unnecessary string comparisons.
    Example:
    Code:
        for(new i = 0; i < pnum; i++)     {         id = players[i];         if(equali(textmsg, "#Terrorists_Win"))         {                      ...
     // to
            if(equali(textmsg, "#Terrorists_Win"))         {             for(new i = 0; i < pnum; i++)             {                 id = players[i];                ...             }         }         else         {             ...
     // To create a function call or macro to perform the internal for, instead of creating repeated code everywhere.
            if(equali(textmsg, "#Terrorists_Win"))         {             myCoolFunctionCall( wonround, lostround );         }         else         {             ... /** * * @param ct_teamSound        the sound to play when the ct team wins * @param tr_teamSound        the sound to play when the tr team wins */ stock myCoolFunctionCall( ct_teamSound[], tr_teamSound[] ) {     new players[32], id, pnum;     get_players(players, pnum, "c");     for(new i = 0; i < pnum; i++)     {         id = players[i];        ...     }      bool_endofround = 1;      bool_bomb_planted = 0; }
  5. On those 'equali(textmsg, "#Terrorists_Win")', instead of to compare the whole string, just the second char is not enough?
    Example:
    Code:
        if(equali(textmsg, "#Terrorists_Win"))
     // to
            // #Terrorists_Win     if(textmsg[ 1 ] == 'T')
  6. I do not see any comments on you code or documentation on your code.
    They help to understand the system and to develop them. See what do you think about this mime.
__________________
Plugin: Sublime Text - ITE , Galileo
Multi-Mod: Manager / Plugin / Server

Support me on Patreon, Ko-fi, Liberapay or Open Collective

Last edited by addons_zz; 07-10-2016 at 00:41. Reason: update
addons_zz is offline
hellmonja
Senior Member
Join Date: Oct 2015
Old 07-10-2016 , 02:39   Re: CS:GO Music Kit
Reply With Quote #4

Hey addons_zz! Thanks for the tips. I'll try and get them all done once I get full control of pc. Probably tonight...
__________________
hellmonja is offline
HamletEagle
AMX Mod X Plugin Approver
Join Date: Sep 2013
Location: Romania
Old 07-10-2016 , 05:09   Re: CS:GO Music Kit
Reply With Quote #5

That's still just playing some sounds and as per rules it can't be approved. What you can do to make this better and make it a true cs go music kit: create a configuration file where for each player steam id there are different sounds for each event. If player x defuse the bomb, play his sounds. When y plant, play his own sounds. If player has no custom config, then player a default sound.

Of course owner has to install the sound and set up config file, but it's not that hard. Player can simply request his own sounds by a menu or whatever.

That's just an ideea, what do you guys think?
__________________

Last edited by HamletEagle; 07-10-2016 at 05:10.
HamletEagle is offline
addons_zz
Veteran Member
Join Date: Aug 2015
Location: Dreams, zz
Old 07-10-2016 , 10:34   Re: CS:GO Music Kit
Reply With Quote #6

Update from yesterday. I do not see you precaching the sounds you to play. Then only you will have them to listen to. Is that what do you intent?

Quote:
Originally Posted by HamletEagle View Post
That's just an ideea, what do you guys think?
It is interesting. Reading a default configuration file listing all sounds available.
Then another configuration, which in-game allow each player to open a menu, and choose
from a list of sounds (already on the default config file and precached), which sound they would like
to play on each of the moments.


More precisely,
  1. It would require a new folder 'csgp_music_kit' on 'addons/amxmodx/config', which contains a file called 'default_sounds_list.ini' listing all sounds allowed to be played and which must to be precached form the folder 'game_mod/sounds/csgp_music_kit'. The folder 'game_mod/sounds/csgp_music_kit' would be where you place your sounds you are providing for download.
    This was done before on others plugins, you can get the ideia/how from there and give the credits.
  2. It would require another file on the folder 'csgp_music_kit' called 'default_sounds_assignments.ini'. It would contain the default sounds assignments. Example, on the round end event, is assigned to be played by default the sound 'csgp_music_kit/my_cool_sound.mp3'.
  3. Second, on you new folder 'csgp_music_kit' on configs you create a file to each player which chooses to change the default configuration. This file would be on the format 'PLAYER_STEAM_ID_assignments.ini'. The other players which do not changed the default configuration by the menu, will always load the default configuration 'default_sounds_assignments.ini' instead of their own file 'PLAYER_STEAM_ID.ini'.
  4. To save server disk space, refer to each sound by and ID, on the 'PLAYER_STEAM_ID.ini' and 'default_sounds_assignments.ini'. Example for what would be my server configuration, loaded when I enter the server:
    STEAM_0:0:15944955.ini
    Code:
    2 7 10 15 1 3
    Assuming the order;
    1. first line is the round_end sound
    2. seconds line is the round_start sound
    3. third line is the terror_win sound
    4. etc
    Here, it says 'round_end' will the the 6th sound (not 6th line) the the config file 'default_sounds_list.ini'. And 'terror_win' will the the first sound (not first line) the the config file 'default_sounds_list.ini'.
    The other lines, if not present, means they will be using the default configuration file 'default_sounds_assignments.ini'.
    Example of the file 'default_sounds_assignments.ini':
    default_sounds_assignments.ini
    Code:
    1 2 3 4 5 6
  5. Using the 'default_sounds_list.ini' order to refer to each sound will mess with evebody configuration if you change the order on the file ''default_sounds_list.ini'. To solve that problem, manually atribute an id to each sound, then you can sort the lines as much as you need.
    Example of the file 'default_sounds_list.ini':
    'default_sounds_list.ini'
    Code:
    1 sounds/csgp_music_kit/deathcam.mp3 4 sounds/csgp_music_kit/roundtenseccount.mp3 2 sounds/csgp_music_kit/bombplanted.mp3 3 sounds/csgp_music_kit/bombtenseccount.mp3 5 sounds/csgp_music_kit/wonround.mp3 6 sounds/csgp_music_kit/lostround.mp3
    Here, each sound has its id, and they order, will determine which sound is showed first, second, ... on the menu.
    But this has the concern to do not use the same id twice or more times. So, when parsing/reading the file, print out when you find out the same id more than once. And to skip that line.

I did this specifications fast, but they sound me good. If you have some problems understanding or may be someone notice I wrote something wrong, just say/ask it.
If someone else has a better/improved idea/way about doing this using with nvault or mysql, could share. I think that using a file name with the steam id as its name is very fast to locate which file is. Just doing 'file_exists(1)', we can find out whether to load the user config or use the default config (already on memory, as it is loaded on the 'plugin_cfg(0)).
__________________
Plugin: Sublime Text - ITE , Galileo
Multi-Mod: Manager / Plugin / Server

Support me on Patreon, Ko-fi, Liberapay or Open Collective
addons_zz is offline
hellmonja
Senior Member
Join Date: Oct 2015
Old 07-13-2016 , 17:25   Re: CS:GO Music Kit
Reply With Quote #7

Sorry guys, I was sick these past few days. I got a headache that's making it hard for me to stair at a monitor.

Anyway, I like the idea of a config file. It would bring a whole new level of customization for the plugin. The problem is my skill level isn't up to par yet and I don't know how to code that. For now I want to get simple stuff done perfectly then I'm going to add that feature once I get a study on it.

And here's the updated code. I hope I did everything right. If I forgot something, just tell me. Also, is there a way of coding those 'Round_Ten_Seconds_Left' and 'Bomb_Ten_Seconds_Left' functions? Originally I used a simple set_task for them but they keep going over the next round...
Attached Files
File Type: sma Get Plugin or Get Source (csgo_musickit_v1.sma - 1016 views - 7.4 KB)
__________________
hellmonja is offline
BeNq!
Senior Member
Join Date: Mar 2009
Old 07-13-2016 , 19:12   Re: CS:GO Music Kit
Reply With Quote #8

AD 1. This would give the council extend the end of the round?
AD 2. "STARTACTION" shoult be switched on after the passage of x meters from resp.
BeNq! is offline
addons_zz
Veteran Member
Join Date: Aug 2015
Location: Dreams, zz
Old 07-13-2016 , 21:51   Re: CS:GO Music Kit
Reply With Quote #9

Quote:
Originally Posted by hellmonja View Post
Sorry guys, I was sick these past few days. I got a headache that's making it hard for me to stair at a monitor.
There is no need to answer ASAP (as soon as possible), everybody has its own life and scheduling.

Quote:
Originally Posted by hellmonja View Post
And here's the updated code. I hope I did everything right. If I forgot something, just tell me.
  1. Let us see. This line:
    Code:
    client_cmd(id, "mp3 play ^"%s^"", WONROUND);
    It is very repetitive and that is not good. I do it sometimes when I am not paying attention. But when I see them, I create a stock for them, or macro. On this case, a macro would fit good. I am thinking something like this:
    Code:
    /**  * Play a mp3 sound to a given player.  *  * @param playerId an player id from 0 to until MAX_PLAYERS.  * @param soundToPlay[] an string as the path to the sound to be played.  */ #define PLAY_MP3_SOUND(%1,%2) client_cmd(%1, "mp3 play ^"%s^"", %2)
    So every time you need to use it, will be like this:
    Code:
    PLAY_MP3_SOUND( id, WONROUND );
    Update:
    If you are going to use this:
    Quote:
    Originally Posted by Bugsy View Post
    PHP Code:
    variantid ] = random(sizeofSTARTROUND ) );
    new 
    iFolder clampget_pcvar_numcvar_musickit_set ) , sizeofFOLDER ) - );
        
    client_cmdid "mp3 play ^"%s%s^""FOLDERiFolder ] , STARTROUNDvariantid ] ] ); 
    Them this macro will confuse/disturb, then just keep using 'client_cmd( id , "mp3 play ^"%s^"", FOLDER[ iFolder ] , STARTROUND[ variant[ id ] ] );'.


  2. This stock:
    Code:
    stock Victory(winning_team) {     new players[32], id, pnum;     get_players(players, pnum, "c");         for(new i = 0; i < pnum; i++)     {         id = players[i];         if(winning_team == 1) // If the Terrorists won the round         {             if(cs_get_user_team(id) == CS_TEAM_T)                 client_cmd(id, "mp3 play ^"%s^"", WONROUND);             else if (cs_get_user_team(id) == CS_TEAM_CT)                 client_cmd(id, "mp3 play ^"%s^"", LOSTROUND);         }         else if(winning_team == 2) // If the Counter-Terrorists won the round         {             if(cs_get_user_team(id) == CS_TEAM_CT)                 client_cmd(id, "mp3 play ^"%s^"", WONROUND);             else if (cs_get_user_team(id) == CS_TEAM_T)                 client_cmd(id, "mp3 play ^"%s^"", LOSTROUND);         }         else if(winning_team == 0) //If nobody won, everybody loses         {             client_cmd(id, "mp3 play ^"%s^"", LOSTROUND);         }     }     // Resetting values for next round     bool_endofround = 1;     bool_bomb_planted = 0; }
    Instead of passing another code for the winner team and loser, pass directly what is the right sound.
    Example:
    Code:
    /**  * Function that plays 'victory' or 'losing' sounds for each team  *  * @param winningTeam an CsTeams enum constant from the 'cstrike' module. Ex: CS_TEAM_T, CS_TEAM_UNASSIGNED, CS_TEAM_CT  */ stock Victory(CsTeams:winningTeam) {     if( winningTeam )     {         new players[32], id, pnum;         get_players(players, pnum, "c");                 for(new i = 0; i < pnum; i++)         {             id = players[i];                         if(cs_get_user_team(id) == winningTeam)             {                 PLAY_MP3_SOUND( id, WONROUND );             }             else             {                 PLAY_MP3_SOUND( id, LOSTROUND );             }         }     }     else     {         PLAY_MP3_SOUND( 0, LOSTROUND );     }         // Resetting values for next round     bool_endofround = 1;     bool_bomb_planted = 0; }
    Then you would call them like this:
    Code:
        else if(equali(textmsg, "#CTs_Win"))         Victory(CS_TEAM_CT);         else if(equali(textmsg, "#Round_Draw"))         Victory(CS_TEAM_UNASSIGNED);             else if(equali(textmsg, "#Target_Bombed"))         Victory(CS_TEAM_T);
  3. This line below is not the round end event. It is called very more often than that:
    Code:
    register_message(get_user_msgid("TextMsg"),    "Event_End_Round");
    Call the right event for the right function. Example:
    Code:
        register_logevent("Event_Draw" , 4, "1=Round_Draw")     register_logevent("Event_TerroristWin" , 6, "3=Terrorists_Win", "3=Target_Bombed") ... public Event_Draw() {     Victory(CS_TEAM_UNASSIGNED); } public Event_TerroristWin() {     Victory(CS_TEAM_T); }
  4. Do not use variable names as 't'. There is not problem about that, but doing it make more difficult to read the code and develop it. Example:
    Code:
    new Float:t = float((get_pcvar_num(cvar_round_time) * 60) - 10);
    A new name to 't' could be 'aimSecondsUntilRoundEnd'. You can write them until 31 characters lenght.
    Code:
    new Float:aimSecondsUntilRoundEnd = float((get_pcvar_num(cvar_round_time) * 60) - 10);
  5. You are not precaching the '.mp3' sounds. If you do not do it only you can listen to the sounds.


Quote:
Originally Posted by hellmonja View Post
Also, is there a way of coding those 'Round_Ten_Seconds_Left' and 'Bomb_Ten_Seconds_Left' functions? Originally I used a simple set_task for them but they keep going over the next round...
You can register a task with an ID, then on the round start you delete the old task and create a new one.
Example:
Code:
/**  * Task ids are 100000 apart.  */ enum (+= 100000) {     TASKID_ROUND_TEN_SECONDS_LEFT = 100000, // start with 100000     TASKID_BOMB_SOUND_PLAY,     TASKID_MY_SECOND_COOL_TASK_ID,     TASKID_MY_THRID_COOL_TASK_ID, } // New round. Sound is played during freezetime public Event_New_Round(id) {     // Resetting some values for later     bool_endofround = 0;     bool_bomb_planted = 0;     round_gametime = 0.0;     bomb_gametime = 0.0         remove_task( TASKID_ROUND_TEN_SECONDS_LEFT );     remove_task( TASKID_BOMB_SOUND_PLAY );         new Float:aimSecondsUntilRoundEnd = float((get_pcvar_num(cvar_round_time) * 60) - 10);     set_task( aimSecondsUntilRoundEnd, "Round_Ten_Seconds_Left", TASKID_ROUND_TEN_SECONDS_LEFT ); ... // Plays sound when there's 10 seconds left of round time public Round_Ten_Seconds_Left() {     if(get_pcvar_num(cvar_musickit_on) == 0)         return         PLAY_MP3_SOUND( 0, ROUNDTEN ); } // When C4 is planted, a tense sound is played public Event_Bomb_Planted() {     if(get_pcvar_num(cvar_musickit_on) == 0)         return         // Again, prevents sound from playing when the C4 has been planted after end of round     if(bool_endofround == 1)         return           PLAY_MP3_SOUND( 0, BOMBPLANTED);     bool_bomb_planted = 1;     new Float:secondsUntilBombSound = float(get_pcvar_num(cvar_c4_time) - 11);     set_task( secondsUntilBombSound, "Bomb_Ten_Seconds_Left", TASKID_BOMB_SOUND_PLAY ); } // Plays an even more tense sound when C4 timer winds down to 10 seconds public Bomb_Ten_Seconds_Left() {     if(get_pcvar_num(cvar_musickit_on) == 0)         return         if(bool_endofround == 1)         return     if(bool_bomb_planted == 0)         return         PLAY_MP3_SOUND( 0, BOMBTEN ); }
__________________
Plugin: Sublime Text - ITE , Galileo
Multi-Mod: Manager / Plugin / Server

Support me on Patreon, Ko-fi, Liberapay or Open Collective

Last edited by addons_zz; 07-13-2016 at 22:29. Reason: update
addons_zz is offline
hellmonja
Senior Member
Join Date: Oct 2015
Old 07-14-2016 , 08:39   Re: CS:GO Music Kit
Reply With Quote #10

Updated to v1.0.

I did the stuff you asked and took some liberties of my own:

- I put the task removers on End Round instead of New Round in case the task runs after round has ended
- I employed both the MACRO and the changing folders method by using formatex()
- Made 'iFolder' global and it is set every New Round
- I know how you guys hate hardcoding but I had to hardcode variable sounds' character length for now. When I use charmax() is gives me errors. (line 237)
__________________
hellmonja is offline
Reply



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 08:42.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode