Как-то видел на одном сервере плагин с голосованием за режим в Deathmatch Моде.
Так вот нашел что-то похожее но в плагине происходит рестарт. И только после рестарта срабатывает плагин.
Можете пожалуйста помочь. Как сделать так чтобы плагин срабатывал сразу после окончания голосования и без всяких рестартов?
И да. После того как выбрали режим. Допустим Headshot Only . То в название сервера добавляется HS ONLY
Так вот нашел что-то похожее но в плагине происходит рестарт. И только после рестарта срабатывает плагин.
Можете пожалуйста помочь. Как сделать так чтобы плагин срабатывал сразу после окончания голосования и без всяких рестартов?
Код:
/*
* Modified by Safety1st
* 2/1/2014
*
* Original topic: https://forums.alliedmods.net/showthread.php?t=186460
*
*
* Changes are:
* - huge performance optimization thanks to ConnorMcLeod's idea
* - proper knife attacks handling
* - fixed 'Run time error 4: index out of bounds' error
* - revized redisplaying menu algorithm, now it also could be easily closed to continue playing
* - corrected colorchat function
* - other optimizations
*
* version 1.65
* {
* wopox1337:
* - add support ReAPI,
* - add support bots for amxx 1.8.3,
* - add more custom info about HUDMessage's
* }
*/
// Use ReAPI for correctly work with bots
// #define USE_REAPI
// Use DHUD or HUD informer
#define USE_DHUD
#include <amxmodx>
#include <fakemeta>
#if !defined USE_REAPI
#include <hamsandwich>
#else
#include <reapi>
#endif
#define SERVER_TAG " DM VOTE " // Tag in chat
//#define USE_MENU_FIX // should be commented for AMXX 1.8.3
#if AMXX_VERSION_NUM < 183
#define MAX_PLAYERS 32
#if defined USE_DHUD
#include <dhudmessage>
#endif
#endif
const STATUSICON_SHOW = 1
enum _:TASKS
{
TASK_VOTE_INIT = 1445,
TASK_VOTE_TIME,
TASK_VOTE_COUNTDOWN
}
enum _:MODES
{
NORMAL = 0,
HEAD
}
enum {
// Settings color for HeadShot sprite
iColor_R = 139,
iColor_G = 0,
iColor_B = 250
}
new g_iMaxPlayers, g_iVoteTime, g_iVoteCountdown = 7
new cvar_votetime, cvar_blockknife_dmg, cvar_voteinit_time
#define NO_MENU -1
#define MENU_CLOSE 2
new g_vote[MODES], g_menu_id[ MAX_PLAYERS + 1 ] = { NO_MENU, NO_MENU, ... }
// macro; %1 - variable being modified, %2 - player index
#define CheckFlag(%1,%2) ( %1 & ( 1 << (%2-1) ) )
#define AddFlag(%1,%2) ( %1 |= ( 1 << (%2-1) ) )
new giHasVoted, giHasCloseOption
new g_iMsgIdStatusIcon
new const sound_countdown[ ][ ] = {
"misc/one.wav",
"misc/two.wav",
"misc/three.wav",
"misc/four.wav",
"misc/five.wav"
}
// temporary holds info
new szBuffer[MODES][64]
new iSum, iNormal, iHead
const m_iMenu = 205 // cbaseplayer offset
new gMsgSayText
public plugin_precache() {
for( new i = 0; i < sizeof sound_countdown; i++ )
precache_sound( sound_countdown[i] )
}
public plugin_init() {
register_plugin( "DeathMatch Mod's Vote", "1.65", "Neeeeeeeeeel.- / Safety1st" )
register_dictionary( "dm_vote.txt" )
cvar_votetime = register_cvar( "dm_vote_time", "10" )
cvar_blockknife_dmg = register_cvar( "dm_block_knife_dmg", "1" )
cvar_voteinit_time = register_cvar( "dm_voteinit_time", "30" )
g_iMaxPlayers = get_maxplayers()
gMsgSayText = get_user_msgid("SayText")
g_iMsgIdStatusIcon = get_user_msgid("StatusIcon")
}
public plugin_cfg() {
set_task( get_pcvar_float( cvar_voteinit_time ), "show_vote", TASK_VOTE_INIT )
}
public client_disconnect(id) {
g_menu_id[id] = NO_MENU
}
#if defined USE_DHUD
#define set_hudmessage set_dhudmessage
#define show_hudmessage show_dhudmessage
#endif
public show_vote()
{
if( g_iVoteCountdown == 7 )
{
g_iVoteCountdown--
set_task( 1.0, "show_vote", TASK_VOTE_COUNTDOWN, _, _, "b" )
return
}
else if( g_iVoteCountdown )
{
// Custom your HUD Message as you want
// Add info: https://goldsrc.ru/amxxapi/amxmodx/set_hudmessage
set_hudmessage(
.red = 85,
.green = 255,
.blue = 0,
.x = -1.0,
.y = 0.09,
.effects = 1,
.fxtime = 6.0,
.holdtime = 0.8,
.fadeintime = 0.1,
.fadeouttime = 0.2
)
if( g_iVoteCountdown != 1 )
{
for( new i = 1; i <= g_iMaxPlayers; i++ )
{
if( is_user_connected( i ) )
show_hudmessage( i, "%L", i, "VOTE_STARTS_IN", g_iVoteCountdown - 1 )
}
PlaySound( g_iVoteCountdown - 2 )
g_iVoteCountdown--
return
}
else
{
for( new i = 1; i <= g_iMaxPlayers; i++ )
{
if( is_user_connected( i ) )
show_hudmessage( i, "%L", i, "VOTE_STARTING" )
}
}
}
remove_task( TASK_VOTE_COUNTDOWN )
g_iVoteTime = get_pcvar_num( cvar_votetime )
set_task( 1.0, "time_vote", TASK_VOTE_TIME, _, _, "b" )
for( new i = 1; i <= g_iMaxPlayers; i++ )
{
if( is_user_connected( i ) )
prepare_menu_vote( i )
}
return
}
public time_vote()
{
if( !g_iVoteTime ) {
remove_task( TASK_VOTE_TIME )
finish_vote()
return
}
// Custom your HUD Message as you want
// Add info: https://goldsrc.ru/amxxapi/amxmodx/set_hudmessage
set_hudmessage(
.red = 85,
.green = 255,
.blue = 0,
.x = -1.0,
.y = 0.09,
.effects = 1,
.fxtime = 6.0,
.holdtime = 0.8
)
for( new i = 1; i <= g_iMaxPlayers; i++ )
{
if( is_user_connected( i ) )
show_hudmessage( i, "%L", i, "VOTE_FINISHS_IN", g_iVoteTime )
}
g_iVoteTime--
}
public finish_vote() {
// hide menu
show_menu( 0, 0, "^n", .time = 1 )
new result = g_vote[ HEAD ] == g_vote[ NORMAL ] ? 0 : 1
if( result )
calculate_votes()
for( new i = 1; i <= g_iMaxPlayers; i++ )
{
if( is_user_connected( i ) )
{
if( !result )
ChatColor( i, "!g[%s] %L", SERVER_TAG, i, "VOTE_NOWINNER" )
else
{
ChatColor( i, "!g[%s] %L", SERVER_TAG, i, "VOTE_FINISH", iHead, iNormal )
ChatColor( i, "!g[%s] %L", SERVER_TAG, i, "VOTE_RESULT", g_vote [ HEAD ] > g_vote[ NORMAL ] ? "Only Headshot mode" : "Normal mode" )
}
}
}
if( g_vote[ HEAD ] > g_vote[ NORMAL ] ){
// we will block all damage except headshots and knife
#if !defined USE_REAPI
#if AMXX_VERSION_NUM < 183
RegisterHam( Ham_TraceAttack, "player", "CBasePlayer_TraceAttack", .Post = false)
#else
RegisterHam( Ham_TraceAttack, "player", "CBasePlayer_TraceAttack", .Post = false, .specialbot = true)
#endif
RegisterHamPlayer( Ham_Spawn, "CBasePlayer_Spawn", .Post = true )
#else
RegisterHookChain( RG_CBasePlayer_TraceAttack, "CBasePlayer_TraceAttack", .post = false);
RegisterHookChain( RG_CBasePlayer_Spawn, "CBasePlayer_Spawn", .post = true);
#endif
}
set_cvar_num( "sv_restart", 3 )
}
public PlaySound( sound )
client_cmd( 0, "spk ^"%s^"", sound_countdown[ sound ] )
public prepare_menu_vote(id) {
formatex( szBuffer[NORMAL], 63, "%L", id, "VOTE_MENU_TITLE" )
new Menu = menu_create( szBuffer[NORMAL], "menu_vote" ) // menu ids start from 0
new iCallback = menu_makecallback( "CallbackMenu" )
menu_additem( Menu, "", .callback = iCallback )
menu_additem( Menu, "", .callback = iCallback )
formatex( szBuffer[NORMAL], 63, "%L", id, "VOTE_MENU_EXIT" )
menu_additem( Menu, szBuffer[NORMAL] )
menu_setprop( Menu, MPROP_EXIT, MEXIT_NEVER )
show_menu_vote( id, Menu )
g_menu_id[id] = Menu
}
public CallbackMenu( id, menu, item ) {
if( CheckFlag( giHasVoted, id ) )
return ITEM_DISABLED
return ITEM_IGNORE
}
show_menu_vote( id, menu ) {
formatex( szBuffer[NORMAL], 63, "Normal mode \r[\y%d%%\r]", iSum ? iNormal : 0 )
formatex( szBuffer[HEAD], 63, "Only Headshot \r[\y%d%%\r]", iSum ? iHead : 0 )
menu_item_setname( menu, NORMAL, szBuffer[NORMAL] )
menu_item_setname( menu, HEAD, szBuffer[HEAD] )
if( CheckFlag( giHasVoted, id ) && !CheckFlag( giHasCloseOption, id ) ) {
formatex( szBuffer[NORMAL], 63, "%L", id, "VOTE_MENU_CLOSE" )
menu_item_setname( menu, MENU_CLOSE, szBuffer[NORMAL] )
AddFlag( giHasCloseOption, id )
}
#if defined USE_MENU_FIX
/* Fix for AMXX menus, more info here:
https://bugs.alliedmods.net/show_bug.cgi?id=4778
https://forums.alliedmods.net/showthread.php?t=230887 */
set_pdata_int( id, m_iMenu, 0 )
#endif
menu_display( id, menu )
}
public menu_vote( id, menu, item ) {
if( item == MENU_EXIT )
return PLUGIN_HANDLED
/* do you see that? Even if a menu hasn't 'exit' option it is called anyway when menu is redisplayed for player.
who made this crap called 'new menus'?! */
if( item == MENU_CLOSE ) {
// destroy the menu and don't disturb player anymore
menu_destroy(menu)
g_menu_id[id] = NO_MENU
return PLUGIN_HANDLED
}
AddFlag( giHasVoted, id );
g_vote[item]++
new uName[ 33 ]
get_user_name( id, uName, charsmax( uName ) )
ChatColor( 0, "!g[%s] %L", SERVER_TAG, id, "VOTE_HAS_CHOOSEN", uName, !item ? "Normal" : "OnlyHead" )
new iMenuId
calculate_votes()
for( new i = 1; i <= g_iMaxPlayers; i++ ) {
iMenuId = g_menu_id[i]
if( iMenuId != NO_MENU )
show_menu_vote( i, iMenuId )
}
return PLUGIN_HANDLED
}
calculate_votes() {
iSum = g_vote[ NORMAL ] + g_vote[ HEAD ]
if( iSum ) {
iNormal = g_vote[ NORMAL ] * 100 / iSum
iHead = 100 - iNormal
}
}
public CBasePlayer_TraceAttack( victim, attacker, Float:damage, Float:direction[3], trace, damageBits ) {
if( get_user_weapon( attacker ) == CSW_KNIFE ) {
if( get_pcvar_num( cvar_blockknife_dmg ) )
{
#if !defined USE_REAPI
return HAM_SUPERCEDE
#else
return HC_SUPERCEDE
#endif
}
}
else if( victim != attacker && ( 1 <= attacker <= g_iMaxPlayers ) && get_tr2( trace, TR_iHitgroup ) != HIT_HEAD ) {
set_tr2( trace, TR_flFraction, 1.0 ) // didn't hit anything
#if !defined USE_REAPI
return HAM_SUPERCEDE
#else
return HC_SUPERCEDE
#endif
}
#if !defined USE_REAPI
return HAM_IGNORED
#else
return HC_CONTINUE
#endif
}
public CBasePlayer_Spawn(id) {
if( !is_user_alive(id) )
return
SendStatusIcon(id)
}
stock SendStatusIcon(id)
{
message_begin(MSG_ONE_UNRELIABLE, g_iMsgIdStatusIcon, .player = id)
write_byte(STATUSICON_SHOW) // status: 0 - off, 1 - on, 2 - flash
write_string("d_headshot") // sprite name in hud.txt
write_byte(iColor_R)
write_byte(iColor_G)
write_byte(iColor_B)
message_end()
}
ChatColor( const id, const input[ ], any:... ) {
new count = 1, players[32], player
static msg[191]
vformat( msg, 190, input, 3 )
replace_all( msg, 190, "!g", "^4" )
replace_all( msg, 190, "!y", "^1" )
replace_all( msg, 190, "!team", "^3" )
replace_all( msg, 190, "!team2", "^0" )
if( id ) {
if( !is_user_connected(id) )
return
players[0] = id
}
else
get_players(players, count, "ch")
for( new i = 0; i < count; i++ ) {
player = players[i]
message_begin(MSG_ONE_UNRELIABLE, gMsgSayText, _, player)
write_byte(player)
write_string(msg)
message_end()
}
}
Сообщение автоматически объединено:
И да. После того как выбрали режим. Допустим Headshot Only . То в название сервера добавляется HS ONLY
Последнее редактирование: