Raised This Month: $ Target: $400
 0% 

CS Flags (dod like) - 1.194 [2013-11-09]


Post New Thread Reply   
 
Thread Tools Display Modes
work_SSS
Junior Member
Join Date: Aug 2009
Old 10-24-2009 , 12:00   Re: CS Flags (dod like) - 1.193 [2009-07-09]
Reply With Quote #451

Quote:
Originally Posted by commonbullet View Post
To solve this "problem" you would have to add a russian translation, or switch to any supported language.
Problem decided!
There was a problem with restarting!
And the question? Is it possible to tie on another plug-in plug-in.

Head Crab Me + CS Flags (dod like) help me?
1) When a team has won all the flags, crab is the one who won the last flag!
2) When you crab, kill you, you became a man
How do help me!
Maybe it will be a separate little script!
Crab infection

That's admin delat crab ---

say /headcrabme // Turn into a Head Crab
say /unheadcrabme // Turn back into human

Last edited by work_SSS; 10-24-2009 at 14:11.
work_SSS is offline
radda
New Member
Join Date: Jan 2008
Old 11-03-2009 , 14:48   Re: CS Flags (dod like) - 1.193 [2009-07-09]
Reply With Quote #452

Where's the .amxx plugin? I just downloaded and I can't find it.
radda is offline
Exolent[jNr]
Veteran Member
Join Date: Feb 2007
Location: Tennessee
Old 11-03-2009 , 14:49   Re: CS Flags (dod like) - 1.193 [2009-07-09]
Reply With Quote #453

Where you see the attachments, click "Get Plugin" for the plugin you want.
__________________
No private work or selling mods.
Quote:
Originally Posted by xPaw View Post
I love you exolent!
Exolent[jNr] is offline
radda
New Member
Join Date: Jan 2008
Old 11-03-2009 , 14:52   Re: CS Flags (dod like) - 1.193 [2009-07-09]
Reply With Quote #454

EDIT: Sorry, I haven't used amxx in a long time. Found the problem. Thanks xD
radda is offline
DruGzOG
Veteran Member
Join Date: Nov 2007
Location: Unknown
Old 02-16-2010 , 12:29   Re: CS Flags (dod like) - 1.193 [2009-07-09]
Reply With Quote #455

PHP Code:
#include <amxmodx>
#include <amxmisc>
#include <fakemeta>

#define VERSION "1.193"

#define USE_CUSTOM_SOUNDS

/* Activates loggers, commands for debugging */
//#define DEBUG_TOOLS

#if defined DEBUG_TOOLS
       /* debug results are stored in this file */
    #define DEBUG_FILE "csflags_debug.txt"
       /* automatically generates debug log */
    #define DEBUG_MODE
#endif

#define ADMIN_CSFLAGS ADMIN_ADMIN

// =================================================
// In the following pevs, 
// my intention was not to abuse from memory
// by creating an array for each required property.
// But storing values in entities like this can be a
// pain for documentation.

// uniqueid is meant to fast check if its
// a csflags entity in think and touch forwards;
#define pev_csf_uniqueid pev_groupinfo

// stores the id of player who's taken the flag
#define pev_csf_flagowner pev_iuser2

// stores the id of player who's touching the flag
#define pev_csf_flagtoucher pev_playerclass

// stores the delay for capturing this specific flag
#define pev_flagcapture_delay pev_fuser1


// the entity id of the flag controlled by this trigger
#define pev_csf_flagent pev_iuser3

// the array id of the flag controlled by this trigger
#define pev_csf_flagid pev_iuser4

// the flag status of a flag controlled by this trigger
#define pev_csf_flagstatus pev_body

// the type (size) of hitbox of this trigger
#define pev_csf_hitbox pev_team

// the entity id of the trigger that controls this flag
#define pev_csf_trigger pev_iuser1

// a special delay control for this entity to think
#define pev_think_delay pev_button

#define MAX_CSFLAGS 5 // hard limit
#define TEAMSNUM 2 // hard limit - designed for cs

#define ID_TEAM_CT 1
#define ID_TEAM_T 0
#define CLASSNAME_CSFLAG "_csf"
#define CLASSNAME_TRIGGER_FLAG "_ftrigger"
#define CSFLAG_TYPEID 11122
#define TRIGGERFLAG_TYPEID 11144

// random taskid
#define TASKID_SCORE_UPDATE 27328
#define TASKID_SYNC_SCORE 723
#define TASKID_RESTART_COUNTER 724
#define TASKID_MAPEND 2938
#define TASKID_RADIORANGE 33
#define TASKID_HIDERADIOICON 34
#define TASKID_RESTORE_MP 1298
#define TASKID_HUDREPEAT 989
#define TASKID_CAPTUREDELAY 1020

#define INTERVAL_SCORE_UPDATE 0.8
#define INTERVAL_SYNCH 0.5

#define GAMESTATE_STOPPED 1
#define GAMESTATE_STARTED 1 << 1
#define GAMESTATE_WAIT 1 << 2
#define GAMESTATE_FORCEDEND 1 << 3
#define GAMESTATE_SHOWSCORE 1 << 4
#define GAMESTATE_MATCHOVER 1 << 5
#define GAMESTATE_HUDREPEAT 1 << 6

#define MODEL_FLAGS "models/sicflag/sicflag.mdl"
#define FILE_DOMCFG "/csflags/%s.cfg"
#define SOUND_FLAGTAKEN "buttons/button9"
#define SOUND_OPPONENT_FLAGTAKEN "items/medshotno1"

#define CSFLAGS_ICON_NAME    "dmg_shock"
#define CSFLAGS_ICON_R         50
#define CSFLAGS_ICON_G         50
#define CSFLAGS_ICON_B         200

#define MAX_HITBOXES 3

#define HITBOX_ID_NORMAL 0
#define HITBOX_ID_LARGER 1
#define HITBOX_ID_LARGE 2

#define HITBOX_NORMAL {{-24.0, -24.0, -64.0}, {24.0, 24.0, 64.0}}
#define HITBOX_LARGER {{-60.0, -60.0, -80.0}, {60.0, 60.0, 80.0}}
#define HITBOX_LARGE {{-100.0, -100.0, -128.0}, {100.0, 100.0, 128.0}}

#define HITBOX_MAX 1
#define HITBOX_MIN 0

#if defined USE_CUSTOM_SOUNDS
/*
 * These are example sound files. 
 * if you choose USE_CUSTOM_SOUNDS, use your own sound files
 */
#define SOUND_MATCHWIN_CT "sicbf2/allie_match_win.mp3"
#define SOUND_MATCHWIN_T "sicbf2/axis_match_win.mp3"
#define SOUND_WIN_CT "sicbf2/allie_round_win.wav"
#define SOUND_WIN_T "sicbf2/allie_round_win.wav"

#else
#define SOUND_TEAMWIN "events/task_complete"

#define SOUND_OPPONENT_WIN "hassault/hw_spindown"
#define SOUND_MATCHWIN "ambience/goal_1"
#define SOUND_OPPONENT_MATCHWIN "ambience/xtal_down1"
#endif    //USE_CUSTOM_SOUNDS

#define HUD_LINE_MAXSIZE 32
#define HUD_FLAGS_STRING_MAXSIZE HUD_LINE_MAXSIZE * MAX_CSFLAGS

#define MSG_HEADER "[CSFLAGS]"

#define MSG_FLAGSTATE_NOTIFY_OP "^4[SIC BF2] ^1 %s(%d) captured the ^4[%s]^1 flag for the %s^1."
#define MSG_FLAGSTATE_NOTIFY    "^4[SIC BF2] ^3%s(%d)^1 captured the ^4[%s]^1 flag for the ^3%s^1."


#define MSG_COUNTER "}SIC{ BF2 restarting in %d"
#define MSG_RESTARTED "}SIC{ BF2 restarted!"
#define MSG_CONS_NOCFG "Could not start }SIC{ BF2 because there's no cfg file or file contains no flags."
#define MSG_CONS_NOT_ENABLED "Could not start because }SIC{ BF2 is not enabled."
#define MSG_TIME_OVER "Time is over. Waiting for a winner..."
#define MSG_CHANGEMAP_DELAY "}SIC{ BF2 match is over, waiting for the next map."
#define HUD_TEAMWINNER "%s have won this match!"
#define HUD_TEAMWINS "%s win this flag round!"
#define HUD_BESTSCORE "^n^nBest scores in this match:"
#define TEAM_DESC_CT "USMC"
#define TEAM_DESC_T "MEC"

#define IFW_FLAGTAKEN "csf_flag_taken"
#define IFW_ROUNDWON "csf_round_won"
#define IFW_MATCHWON "csf_match_won"

#define MSG_RADIO_POINTSECURED "Control point is secure."

#define LANG_PLAYER_C -76

/******************************************************************************************
 * The following function/values were taken from
 * VEN's CTF plugin
 */
 // private data deaths offset
#define OFFSET_DEATHS_32BIT 444
#define OFFSET_DEATHS_64BIT 493
// deaths offset linux difference
#define OFFSET_DEATHS_LINUXDIFF 5 

// determination of actual offsets
#if !defined PROCESSOR_TYPE // is automatic 32/64bit processor detection?
    #if cellbits == 32 // is the size of a cell are 32 bits?
        // then considering processor as 32bit
        #define OFFSET_DEATHS OFFSET_DEATHS_32BIT
        //not used in this version //#define OFFSET_MONEY OFFSET_MONEY_32BIT
    #else // in other case considering the size of a cell as 64 bits
        // and then considering processor as 64bit
        #define OFFSET_DEATHS OFFSET_DEATHS_64BIT
        //not used in this version //#define OFFSET_MONEY OFFSET_MONEY_64BIT
    #endif
#else // processor type specified by PROCESSOR_TYPE define
    #if PROCESSOR_TYPE == 0 // 32bit processor defined
        #define OFFSET_DEATHS OFFSET_DEATHS_32BIT
        //not used in this version //#define OFFSET_MONEY OFFSET_MONEY_32BIT
    #else // considering that 64bit processor defined
        #define OFFSET_DEATHS OFFSET_DEATHS_64BIT
        //not used in this version //#define OFFSET_MONEY OFFSET_MONEY_64BIT
    #endif
#endif


// marco to retrieve user deaths
#define CS_GET_USER_DEATHS_(%1) get_pdata_int(%1, OFFSET_DEATHS, OFFSET_DEATHS_LINUXDIFF)
/******************************************************************************************
*/

/** Names of dom areas */
new g_PlaceNames[MAX_CSFLAGS][16]

/** State of flas, i.e. flag taken, etc */
new g_FlagState[MAX_CSFLAGS] = {-,...}

/** Score Counter for each player */
new Float:g_PlayerScore[33]

/** Score counter for each team */
new Float:g_TeamScore[TEAMSNUM]

/** Matches won by each team */
new g_TeamWins[TEAMSNUM]

/** Number of flags for the current map*/
new g_MapFlagsNum

/** Radio messages state */
new g_Radio[33]

/** mp time backup for swap */
new Float:g_OldMPTime

/** time to restart the match */
new Float:g_RestartTime

/** 
 * last team winner of a match
 * used to display info if a round restarts
 * when csflags match end info was being shown. 
 */
new g_LastWinner

new bool:g_MatchLastWin

/** Stores pcvar for max points before a team win */
new g_cvarMaxPoints

/** Stores pcvar for csflags enabled */
new g_cvarDomEnabled

/** Stores pcvar for the delay before map ends */
new g_cvarMapEndTime

/** Stores pcvar for the number of csflags matches wins required for a map switch */
new g_cvarMaxWins

/** Stores pcvar that defines if a map switch should take place if csflags wins are tied */
new g_cvarTieMatch

/** Stores pcvar that defines if a match is won when all flags are taken by a team */
new g_cvarAllFlagsWin

/** Stores pcvar that switches radio messages */
new g_cvarUseRadio

/** Stores pcvar that defines if map objectives should be removed */
new g_cvarRemoveDefObjectives

/** Stores pcvar that defines how much frags are added to players of csflags winning team */ 
new g_cvarWinFrags

/** Stores pcvar that defines how much frags are added to a player that captures a flag */
new g_cvarCaptureFrags

/** Stores pcvar that defines how much time it takes for a player to capture a flag */
new g_cvarCaptureDelay

/** Stores pcvar that defines if players should respawn after match is over */
new g_cvarMatchRespawn

/** Stores pcvar that defines if players should freeze when a match is won */
new g_cvarFreeze

new g_cvarVoteStartCommand

new bool:g_VoteCmdExecuted false

/** Stores the message id for score info */
new g_msgidScoreInfo

/** Stores the message id for icon display */
new g_msgidIcon

/** Stores the message id for the progress bar*/
new g_msgidProgress

/** Stores the message id for players 'say text' */
new g_msgidSayText

/** Stores the fakemeta touch forward registry */
new g_fwTouch

/** Stores the fakemeta think forward registry */
new g_fwThink

/** Stores the fakemeta player think foward registry */
new g_fwPThink


/** Stores the flag taken forward registry */
new g_ifw_FlagTaken

/** Stores the round won forward registry */
new g_ifw_RoundWon

/** Stores the match won forward registry */
new g_ifw_MatchWon

/** Stores the max players to avoid get_maxplayers calls */
new g_MaxPlayers

/** Stores the origin of triggers */
new Float:g_TriggerOrigin[MAX_CSFLAGS][3]

/** 
 *  Stores the size of triggers 
 *  current values are:
 *  HITBOX_NORMAL {{-24.0, -24.0, -64.0}, {24.0, 24.0, 64.0}}
 *  HITBOX_LARGER {{-60.0, -60.0, -80.0}, {60.0, 60.0, 80.0}}
 *  HITBOX_LARGE {{-100.0, -100.0, -128.0}, {100.0, 100.0, 128.0}}
 */
new Float:g_mmSize[3][2][3] = 
{
    
HITBOX_NORMAL,
    
HITBOX_LARGER,
    
HITBOX_LARGE
}



/** Team name descriptions */ 
new g_Teams[2][] = {"Terrorists""CTs"}

/** Default notify sounds */
new g_NotifySound[2][] = {"csflags/allie_flag_cap_alt.wav""sicbf2/allie_flag_cap_alt.wav"}

/** 
 * Current plugin state thats defined by several flags: 
 * GAMESTATE_STOPPED - csflags has been stopped
 * GAMESTATE_STARTED - csflgas has started
 * GAMESTATE_WAIT - time is over, csflags is waiting for a winner.
 * GAMESTATE_FORCEDEND = csflags should end anyway
 * GAMESTATE_SHOWSCORE - csflags is showing score
 * GAMESTATE_MATCHOVER - csflags match is over
 * GAMESTATE_HUDREPEAT - hud info has been interrupted by a round restart and should be displayed again.
 */
public g_CSFlagsState




/** Flags if score hud string must be rebuilt */
new bool:g_UpdateScoresHud

/** Flags if flags hud string must be rebuilt */
new bool:g_UpdateFlagsHud

/** 
  * Stores last score integer for a team so script will detect
  * when score hud must be updated.
  */
new g_LastTeamScore[2] = {-1, ...}

/** Hud score messages are not translated for optimization */
new const g_ScoreHeaderFormat[2][] =
{
    
"Terrorists(%d) : %d",
    
"CTs(%d) : %d"
}


#if defined DEBUG_TOOLS

new const debugHeader[] =
{
    
"[CSFlags_Debug]"
}
new const 
debugLine[] = 
{
    
"----------------------------------"
}
new 
debugMsg[160]
new 
Tabs[16] = {'^t', ...}
new 
lastFlagState = -1
#if defined DEBUG_FILE
new pDebugFile
#endif // DEBUG_FILE
#endif // DEBUG_TOOLS

/**
 * (amxmodx core forward.)
 * - Register all required events
 * - Registers all required cvars.
 * - Initializes messages ids
 * - Starts csflags match if :
 *    1) amx_csflags_enabled is set to 1;
 *    2) this maps has a config file for csflags.
 */
public plugin_init() 
{
    
register_plugin("BattleField Addon : Flags"VERSION"www.sicinfitclan.com")    
    
register_event("HLTV""event_round_start""a""1=0""2=0")
    
register_logevent("event_game_commencing"2"1=Game_Commencing")
    
register_concmd("amx_csflags_restart""csflags_restart_cmd"ADMIN_CSFLAGS)
    
register_concmd("amx_csflags_stop""csflags_stop_cmd"ADMIN_CSFLAGS)
    
    
register_dictionary("csflags.txt")
    
    
g_cvarMaxWins register_cvar("amx_csflags_max_wins""3")
    
g_cvarMaxPoints register_cvar("amx_csflags_max_points""100")
    
g_cvarDomEnabled register_cvar("amx_csflags_enabled""1")
    
g_cvarMapEndTime register_cvar("amx_csflags_mapendtime""0.5")
    
g_cvarTieMatch register_cvar("amx_csflags_tiematch""0")
    
g_cvarAllFlagsWin register_cvar("amx_csflags_allflags_win""1")
    
g_cvarUseRadio register_cvar("amx_csflags_useradio""1")
    
g_cvarRemoveDefObjectives register_cvar("amx_csflags_remove_map_obj""1")
    
g_cvarWinFrags register_cvar("amx_csflags_winfrags""0")
    
g_cvarCaptureFrags register_cvar("amx_csflags_capturefrags""0")
    
g_cvarCaptureDelay register_cvar("amx_csflags_capturedelay""3")
    
g_cvarMatchRespawn register_cvar("amx_csflags_respawn""0")
    
g_cvarFreeze register_cvar("amx_csflags_freeze""0")
    
g_cvarVoteStartCommand register_cvar("amx_csflags_vote_startcmd""")

    
g_msgidProgress get_user_msgid("BarTime2")
    
g_msgidScoreInfo get_user_msgid("ScoreInfo")
    
g_msgidIcon get_user_msgid("StatusIcon")
    
g_msgidSayText get_user_msgid("SayText")
    
    
g_MaxPlayers get_maxplayers()
    
    if(
get_pcvar_num(g_cvarDomEnabled)) {
        if(
load_config()) {
            
csflags_init()
        }
    }
#if defined DEBUG_TOOLS
    
register_concmd("csflags_trace_flags""debug_flags")
    
register_concmd("csflags_trace_gamestate""debug_gamestate")
    
    new 
mapname[32]
    new 
msg[128]
    
    
get_mapname(mapname31)
    
    
open_debug_file()
    
formatex(msg127"***^nStarting Debug Section^nMap: %s^n***"mapname)
    
debug_print(0msg)
    
close_debug_file()    
#endif
}


/**
 * (amxmodx core forward)
 * - Precaches flags model
 * - Precaches sounds
 */
public plugin_precache() 
{
    
precache_model(MODEL_FLAGS)
    
precache_sound(g_NotifySound[0])
    
precache_sound(g_NotifySound[1])
    
#if defined USE_CUSTOM_SOUNDS
    
new prsounds[4][] = {
        
SOUND_MATCHWIN_CT,
        
SOUND_MATCHWIN_T,
        
SOUND_WIN_CT,
        
SOUND_WIN_T
    
}
    new 
cursound[72]
    for (new 
04i++) {
        
formatex(cursound71"sound/%s"prsounds[i])
        if(
file_exists(cursound))
            
precache_sound(prsounds[i])
        else
            
log_amx("%L Cound't find sound file %s to precache.""MSG_HEADER"idcursound)
    }
#endif    //USE_CUSTOM_SOUNDS
}

/**
 *  This function is called at the very beginning of csflags match. It resets game state and
 *  initializes all required resources.
 *  - Sets the game state to GAMESTATE_STARTED
 *  - Removes the objetives if cvar has been properly set.
 *  - Register touch, think and player think forwards.
 *  - Register forwards to be used externally: flag taken, match won, round won.
 *  - Sets time interval to update scores hud.
 *  - Sets a hook mapend, it's 11.0, one second before map end counter.
 */
public csflags_init() 
{    
    
g_CSFlagsState 0
    g_CSFlagsState 
|= GAMESTATE_STARTED
    
    
if(get_pcvar_num(g_cvarRemoveDefObjectives))
        
remove_default_objectives()
        
    
g_UpdateScoresHud true
    g_UpdateFlagsHud 
true
    
    set_task
(INTERVAL_SCORE_UPDATE"update_score"TASKID_SCORE_UPDATE__"b")
    
    
g_fwTouch register_forward(FM_Touch"forward_touch")
    
g_fwThink register_forward(FM_Think"flag_think")
    
g_fwPThink register_forward(FM_PlayerPreThink"player_think")
    
    
g_ifw_FlagTaken CreateMultiForward(IFW_FLAGTAKENET_IGNOREFP_CELL)    // toucher
    
g_ifw_MatchWon CreateMultiForward(IFW_MATCHWONET_IGNOREFP_CELL)    // team winner
    
g_ifw_RoundWon CreateMultiForward(IFW_ROUNDWONET_IGNOREFP_CELL)    // team winner

    
set_task(11.0"set_mapend_mptimelimit"TASKID_MAPEND__"d"1)
}

/**
 * Pauses a csflags match
 * @param pausescore If different from 0, it removes score hud.
 */
csflags_pause(pausescore 0
{
    
    if(
pausescore)
        
remove_task(TASKID_SCORE_UPDATE)
}

/**
 * Resets a csflags match by cleaning pevs stored in flags and triggers entities.
 * @param wins if different from 0, it resets also the team wins.
 * @param players if different from 0, it resets also the players score.
 **/
csflags_reset(wins 0players 0
{
    new 
flag

#if defined DEBUG_MODE
    
open_debug_file()
    
print_stack(0"csflags_reset")
    
printvar_cell(0"wins"wins)
    
printvar_cell(0"players"players)
    
close_debug_file()
#endif    
    
while((flag engfunc(EngFunc_FindEntityByStringflag"classname"CLASSNAME_CSFLAG))) {
        
        
set_pev(flagpev_csf_flagstatus0)
        
set_pev(flagpev_csf_flagowner0)        
        
        if(
task_exists(TASKID_CAPTUREDELAY flag))
            
remove_task(TASKID_CAPTUREDELAY flag)

        
set_pev(flagpev_csf_flagtoucher0)
    }
    
    
g_TeamScore[ID_TEAM_CT] = 0.0
    g_TeamScore
[ID_TEAM_T] = 0.0
    
    g_LastTeamScore
[ID_TEAM_CT] = -1
    g_LastTeamScore
[ID_TEAM_T] = -1
    
    
if(wins) {
        
g_TeamWins[ID_TEAM_CT] = 0
        g_TeamWins
[ID_TEAM_T] = 0
    
}
    
    if(
players) {
        for(new 
133i++)
            
g_PlayerScore[i] = 0.0
    
}
    
    for(new 
0MAX_CSFLAGSi++)
        
g_FlagState[i] = -1    
}

/**
 *  Makes sure all forwards are properly registered, resets the score hud and removes
 *  GAME_STOPPED flag from csflags' status.
 */
csflags_restart() 
{
    
#if defined DEBUG_MODE
    
open_debug_file()
    
print_stack(0"csflags_restart")
    
close_debug_file()
#endif
    
if(!g_fwTouch)
        
g_fwTouch register_forward(FM_Touch"forward_touch")
    if(!
g_fwThink)
        
g_fwThink register_forward(FM_Think"flag_think")
    if(!
g_fwPThink)
        
g_fwPThink register_forward(FM_Think"player_think")
        
    if(!
g_ifw_FlagTaken)
        
g_ifw_FlagTaken CreateMultiForward(IFW_FLAGTAKENET_IGNOREFP_CELL)    // toucher
    
if(!g_ifw_MatchWon)
        
g_ifw_MatchWon CreateMultiForward(IFW_MATCHWONET_IGNOREFP_CELL)    // team winner
    
if(!g_ifw_RoundWon)
        
g_ifw_RoundWon CreateMultiForward(IFW_ROUNDWONET_IGNOREFP_CELL)    // team winner
    
    
g_UpdateScoresHud true
    g_UpdateFlagsHud 
true
    g_LastTeamScore
[ID_TEAM_CT] = -
    g_LastTeamScore
[ID_TEAM_T] = -1
    
    g_MatchLastWin 
false
    
    
if(!g_VoteCmdExecuted) {
        
start_vote_cmd()
    }    
    
    if(!
task_exists(TASKID_SCORE_UPDATE))
        
set_task(INTERVAL_SCORE_UPDATE"update_score"TASKID_SCORE_UPDATE__"b")
    
    
    
g_CSFlagsState &= ~GAMESTATE_STOPPED
    
}

start_vote_cmd(Float:delay=6.0)
{
    new 
imminentWin
    
new checkstr[2]
    
    
get_pcvar_string(g_cvarVoteStartCommandcheckstr1)
    
    if(
checkstr[0]) {
        
imminentWin get_pcvar_flags(g_cvarMaxWins) - 1
        
        
if(imminentWin >= g_TeamWins[ID_TEAM_CT] || imminentWin >= g_TeamWins[ID_TEAM_T]) {
            
g_VoteCmdExecuted true
            set_task
(delay"exec_vote_cmd"2121)
        }
    }
}

public 
exec_vote_cmd()
{
    new 
voteCommand[64]
    
    
get_pcvar_string(g_cvarVoteStartCommandvoteCommand63)
    
server_cmd(voteCommand)
}

/**
 *  This function is called by the command "amx_csflags_restart",
 *  forces game to reset, stop and start.
 */
public csflags_restart_cmd(idlevelcid
{
    if(!
cmd_access(idlevelcid0))
        return 
PLUGIN_HANDLED
        
    
if(!get_pcvar_num(g_cvarDomEnabled))
        
console_print(id"%L"id"MSG_CONS_NOT_ENABLED")
    
    
csflags_reset()
    
csflags_stop(1)
    
    if(
load_config())
        
csflags_init()
    else 
        
console_print(id"%L"id"MSG_CONS_NOCFG")
    
    return 
PLUGIN_HANDLED
}

/**
 *  This function is called by the command "amx_csflags_stop", and just stops
 *  the plugin.
 */
public csflags_stop_cmd(idlevelcid
{
    if(!
cmd_access(idlevelcid0))
        return 
PLUGIN_HANDLED
    csflags_stop
(1)
    return 
PLUGIN_HANDLED
}

/**
 * Stops the plugin.
 * @param remove if different from 0, removes all csflags specific entities.
 */
csflags_stop(remove
{
#if defined DEBUG_MODE
    
open_debug_file()
    
print_stack(0"csflags_restart_cmd")
    
printvar_cell(0"remove"remove)
    
close_debug_file()
#endif

    
if(g_CSFlagsState GAMESTATE_STARTED) {
        if(
task_exists(TASKID_SCORE_UPDATE))
            
remove_task(TASKID_SCORE_UPDATE)
        if(
remove) {
            
remove_all_ents(CLASSNAME_CSFLAG)
            
remove_all_ents(CLASSNAME_TRIGGER_FLAG)
            
g_MapFlagsNum 0
        
}
        
g_CSFlagsState GAMESTATE_STOPPED  | (g_CSFlagsState GAMESTATE_SHOWSCORE)
        
        
/*
        unregister_forward(FM_Touch, g_fwTouch)
        unregister_forward(FM_Think, g_fwThink)
        g_fwThink = 0
        g_fwTouch = 0
        
        DestroyForward(g_ifw_FlagTaken)
        DestroyForward(g_ifw_MatchWon)
        DestroyForward(g_ifw_RoundWon)
        
        g_ifw_FlagTaken = 0
        g_ifw_MatchWon = 0
        g_ifw_RoundWon = 0 
        */
    
}
}

/**
 *  Called to 'make' a team win a match.
 *  - Pauses the plugin.
 *  - Updates teams scores.
 *  - Cleans flags states
 *  - Makes sure to clean progress bars from users who were capturing flags.
 *  - Sets GAMESTATE_SCORE on.
 *  - Executes team won forward.
 *  
 *  @param team the team param is the actual team id - 1 so Ts = 0, CTs = 1
 */
team_win(team
{
    
    
/* if this state has already been set, means
     * something wrong is going on, so get off here
     */    
    
if(g_CSFlagsState GAMESTATE_SHOWSCORE)
        return 
PLUGIN_CONTINUE

    
/* makes it pause */
    
csflags_pause(1)
    
    
/* this is used to check if csflags 
     * winning limit has been set in the cvar */
    
new winlimit
    
    
/* used as an iterator for map flags */
    
new flag
    
    
/* Adds a pont to the winner team */
    
g_TeamWins[team]++
    

#if defined DEBUG_MODE
    
debug_gamestate(0"team_win(0-0)")
#endif    

    /* reset flags being captured, also resets
     * status bars from players who were capturing the flag
     */
    
while((flag engfunc(EngFunc_FindEntityByStringflag"classname"CLASSNAME_CSFLAG))) {
        new 
toucher
        
        toucher 
pev(flagpev_csf_flagtoucher)
        if(
toucher) {
            
set_pev(flagpev_csf_flagtoucher0)

            if(
task_exists(TASKID_CAPTUREDELAY flag))
                
remove_task(TASKID_CAPTUREDELAY flag)

            
msg_csf_icon(toucherfalse)
            
msg_bar_progress(toucher100true)
        }
    }
    
    
/* updates plugin status */
    
g_CSFlagsState |= GAMESTATE_SHOWSCORE
    
    
/* executes "csf_round_won" forward */
    
if(g_ifw_RoundWon) {
        new 
retval
        ExecuteForward
(g_ifw_RoundWonretvalteam 1)
    }        
    
    
/* fetches current csflags winlimit value */
    
winlimit get_pcvar_num(g_cvarMaxWins)
    
    
/* Checks if the gamestate was set to wait.
     * Then a map_should_end call checks if map has max win limit
     * and if it as been reached.
     * If so csflags is stopped, lastwin is set to 1.
     */
    
if(g_CSFlagsState GAMESTATE_WAIT) {
        if(
map_should_end()) {
            
set_task(11.0"restore_mptimelimit"TASKID_RESTORE_MP)
            
csflags_stop(1)
            
g_MatchLastWin true
        
}
    }
    
    
/* 
     * The following code is run when plugin wasn't waiting for a winner
     * but the win limit has been reached by a team. In that case csflags
     * is stopped and lastwin variable is set to 1.
     */
    
if(winlimit && !g_MatchLastWin) {
        if(
g_TeamWins[team] >= winlimit && !(g_CSFlagsState GAMESTATE_WAIT)) {
            
force_end()
            
csflags_stop(1)
            
g_MatchLastWin true
        
}
    }
    
    
/*
     * If it's the last win of the match
     * the csflags state should be updated, and the match
     * won forward executed.
     */
    
if(g_MatchLastWin) {
        
        
g_CSFlagsState |= GAMESTATE_MATCHOVER
        
        
if(g_ifw_MatchWon) {
            new 
retval
            ExecuteForward
(g_ifw_MatchWonretvalteam 1)
        }        
    }
    
    
/* this variable is only used in win_hud_repeat
     * Version 1.19 has correct a bug it would only
     * be reset in that function.
    */
    
g_LastWinner = (team 1)
    
    
/*
     * displayes the winning hud for the teams.
     */
    
show_win_hud(team)

#if defined DEBUG_MODE
    
open_debug_file()
    
print_stack(0"team_win")
    
printvar_cell(0"team"team)
    
printvar_cell(0"lastwin"lastwin)
    
printvar_cell(0"winlimit"winlimit)
    
printvar_cell(0"g_TeamWins[team]"g_TeamWins[team])
    
printvar_cell(0"g_LastWinner"g_LastWinner)
    
close_debug_file()
    
    
debug_gamestate(0"team_win(0-1)")
    
#endif

    /* moves players to spawn if that's been set*/
    
if(get_pcvar_num(g_cvarMatchRespawn))
        
move_to_spawn()
    
    return 
PLUGIN_CONTINUE
}

/**
 * Prints those messages in players HUD channels when csflags match has
 * been partially or totally won.
 * @param team teamid - 1, so Ts = 0, CTs = 1.
 * @param lastwin used as a last win flag - last win messages are different.
 */
show_win_hud(team)
{
    
/* used to store text messages */
    
new message[256]
    
    
/* variables used in playes rank calculation */
    
new Float:score[5]
    new 
bestplayer[5]
    new 
name[32]
    new 
Float:currentscore
    
    
/* well known prelude to get_players core function*/
    
new players[32]
    new 
playersnum
    
    
/* shit names, here's a disambiguishing:
     * count - numbers of players in the rank, max 5 */
    
new count
    
/* has nothing to do with ranking, is used for
     * formatting strings */
    
new len
    
    
/* I don't want to comment this, it seems to be working. */
    
if(get_playersnum()) {        
        
get_players(playersplayersnum)
        for(new 
0playersnumi++) {            
            for(new 
05p++) {
                
currentscore g_PlayerScore[players[i]]
                if(
currentscore == 0.0)
                    continue
                if(
currentscore score[p]) {
                    for(new 
4&& 0q--) {
                        
score[q] = score[1]
                        
bestplayer[q] = bestplayer[1]
                    }                
                    
score[p] = currentscore
                    bestplayer
[p] = players[i]
                    
count++
                    break
                }
            }
        }
        
count = (count 5) ? count
    
}
    
    
/* adds a message header */
    
len format(message100"%s^n"MSG_HEADER)
    
    
/*
     * If it's the last win,the csflags winner is added the message
     */
     
    /* 
     *   Is there an amxmodx problem when concatening language strings with LANG_PLAYER?
     *   - At least for me the first time it's shown in english (LANG_SERVER ??).
     *     I didn't see any bug reports related and I don't know if its a bug or something
     *     weird going on my test server. If someone complains about this behavior I'll
     *     have to make this a loop with players id - that seems to work.
    */
    
if(g_MatchLastWin) {
        
// the team variable may be changed regardless the round winner.
        
team = (g_TeamWins[ID_TEAM_CT] > g_TeamWins[ID_TEAM_T]) ? ID_TEAM_CT ID_TEAM_T
        len 
+= format(message[len], 255 len"%L" LANG_PLAYER"HUD_TEAMWINNER"g_Teams[team])
    }
    else
        
len += format(message[len], 255 len"%L"LANG_PLAYER"HUD_TEAMWINS"g_Teams[team])
    
    
/* Adding the best scores */
    
len += format(message[len], 255 len"%L^n"LANG_PLAYER"HUD_BESTSCORE")
    
    for(new 
0counti++) {
        
get_user_name(bestplayer[i], name31)
        
len += format(message[len], 255 len"^n%s - %d"namefloatround(g_PlayerScore[bestplayer[i]]))        
    }
    
    
/* send'em to the hud */
    
set_hudmessage (25540200.100.3000.110.00.00.03)
    
show_hudmessage(0message)
    
    
/* checks if it isn't a repeatition because
     * the hud had been interrupted by a round restart
     * - in that case it has already been run */
    
if(!(g_CSFlagsState GAMESTATE_HUDREPEAT)) {
        
        
/* round will restart as long as
         * it wasn't the last one
         */
        
if(!g_MatchLastWin) {
            
g_RestartTime 10.0
            set_task
(1.0"restart_counter"TASKID_RESTART_COUNTER__"b")
        }
        
            
#if !defined USE_CUSTOM_SOUNDS
        
        
new t
        
for(new 0playersnumi++) {
            
            if(!
is_user_connected(players[i]))
                continue
                
            if((
get_user_team(players[i]))) {
                
                if((
1) == team) {
                    if(
g_MatchLastWinclient_cmd(players[i], "spk %s"SOUND_MATCHWIN)
                    else 
client_cmd(players[i], "spk %s"SOUND_TEAMWIN)
                }
                else if((
1) == (team 1)) {
                    if(
g_MatchLastWinclient_cmd(players[i], "spk %s"SOUND_OPPONENT_MATCHWIN)
                    else 
client_cmd(players[i], "spk %s"SOUND_OPPONENT_WIN)
                }
            }
    
        }
#else
        /**
         * This is not only custom songs, it behaves differently,
         * actually just like DOD there's a set of sound for each team:
         * 1) CTs win the match
         * 2) CTs win CSFlags in this map
         * 3) Ts win the match
         * 4) Ts win CSFlags in this map
         * So everybody hears one sound when the match is over,
         */
        
switch(team) {
            case 
ID_TEAM_CT: {
                if(
g_MatchLastWinclient_cmd(0"spk %s"SOUND_MATCHWIN_CT)
                else 
client_cmd(0"spk %s"SOUND_WIN_CT)        
            }
            case 
ID_TEAM_T: {
                if(
g_MatchLastWinclient_cmd(0"spk %s"SOUND_MATCHWIN_T)
                else 
client_cmd(0"spk %s"SOUND_WIN_T)
            }
            default: {}
        }
#endif //USE_CUSTOM_SOUNDS
    
}
}

/**
 * The win hud messages can be abrutely interrupted if the round restarts.
 * This function has been designed to recover hud messages whenever it's
 * needed.
 */
public win_hud_repeat() 
{
#if defined DEBUG_MODE
    
open_debug_file()
    
print_stack(0"win_hud_repeat")
    
printvar_cell(0"g_LastWinner"g_LastWinner)
    
close_debug_file()
#endif

    /* last winner has been set in team_win function
       with the unique purpose to be recovered here. */
    
if(g_LastWinner) {
        
        
/* repeat the hud message */
        
show_win_hud(g_LastWinner)
        
        
/* resets the last winner */
        
g_LastWinner 0
        
        
/* removes hud repeat flag from game state */
        
g_CSFlagsState &= ~GAMESTATE_HUDREPEAT

#if defined DEBUG_MODE
        
lastFlagState g_CSFlagsState
    
        open_debug_file
()
        
print_stack(0"win_hud_repeat(1,0)")
        
printvar_cell(0"lastwin"lastwin)
        
close_debug_file()
#endif
    
}
}



/**
 * This counter function calls itself through a timer until it's
 * ready to restart the match.
 */
public restart_counter() 
{

#if defined DEBUG_MODE
    
open_debug_file()
    
print_stack(0"restart_counter")
    
printvar_float(0"g_RestartTime"g_RestartTime)
    
close_debug_file()
#endif

    /* not ready yet */
    
if(g_RestartTime 0.0) {
        
client_print(0print_center"%L"LANG_PLAYER"MSG_COUNTER"floatround(g_RestartTime))
        
g_RestartTime -= 1.0
        
return PLUGIN_CONTINUE
    
}
    
    
/* ready, restart it */
    
remove_task(TASKID_RESTART_COUNTER)
    
client_print(0print_center"%L"LANG_PLAYER"MSG_RESTARTED")
    
g_CSFlagsState &= ~GAMESTATE_SHOWSCORE

#if defined DEBUG_MODE
    
lastFlagState g_CSFlagsState
    debug_gamestate
(0"restart_counter")
#endif
    
    /* restores players speed */
    
for(new 1<= g_MaxPlayersi++) {
        if(
is_user_connected(i) && is_user_alive(i)) {
            
engfunc(EngFunc_SetClientMaxspeedi250.0)
            
set_pev(ipev_maxspeed250.0)
        }
    }
    
    
g_LastWinner // 1.19 version - trying to fix array index out of bounds
    
csflags_reset()
    
csflags_restart()
    return 
PLUGIN_CONTINUE
}

/**
 *  forwarded in the log event it resets all
 *  csflags parameters.
 */
public event_game_commencing() 
{
    if(
g_CSFlagsState GAMESTATE_STARTED)
        
csflags_reset(11
}

/**
 *  Hooked from hltv event.
 *  - Checks if csflags was showing win scores when the round has been restarted; if so
 *    hud is displayed again.
 *  - Gets rid of hostages.
 */
public event_round_start() 
{
    
/* is it showing scores? */
    
if(g_CSFlagsState GAMESTATE_SHOWSCORE ) {
        
        
/* set a hud messages being repeated in csflags status */
        
g_CSFlagsState |= GAMESTATE_HUDREPEAT
        
        
/* in order to avoid bugs, sets a delay before hud is repeated*/
        
set_task(0.2"win_hud_repeat"TASKID_HUDREPEAT)
        
#if defined DEBUG_MODE
        
print_comment(0"event_round_start calls win_hut_repeat"0true)
        
lastFlagState g_CSFlagsState
#endif
        
    
}
    
    
/* if it's a rescue map, hostages are back - take them for a walk */
    
if(get_pcvar_num(g_cvarRemoveDefObjectives) && (g_CSFlagsState GAMESTATE_STARTED)) {
        if(
engfunc(EngFunc_FindEntityByString32"classname""hostage_entity"))
            
set_task(0.3"take_for_a_walk"2222)        
    }
}


/**
 * While there should be a better way to
 * safely remove hostages, this is simple enough for this plugin.
 * This has been taken from an old BAILOPAN's CSDM version.
 */
public take_for_a_walk() 
{
    new 
hostage
    
while((hostage engfunc(EngFunc_FindEntityByStringhostage"classname""hostage_entity"))) {
        new 
Float:origin[3] = {8191.08191.08191.0}
        
engfunc(EngFunc_SetOriginhostageorigin)
    }
}

/**
 * Utilitary - removes all entities with a specific class name,
 * @param classname name of class of the entities to be removed. 
 */
remove_all_ents(const classname[]) 
{
    new 
flag
    
while((flag engfunc(EngFunc_FindEntityByStringflag"classname"classname)))
        
engfunc(EngFunc_RemoveEntityflag)
}

/**
 * Clears the radio for a user.
 * g_Radio global is used as a flag to avoid players to get spammed by radio messaged.
 */
public radio_clear(const id[1]) 
{
    
g_Radio[id[0]] = 0
}

/**
 * Hides the radio icon for a player.
 */
public hide_radio_icon(const id[1]) 
{
    
message_begin (MSG_ALL135)
    
write_byte (0)
    
write_byte (id[0])
    
message_end ()
}

/**
 * This is called after the delay for capturing a flag has been consumed.
 * @param info a typical "set_task" target array with multiple params:
 *        0 -> the entity id of a flag
 *        1 -> then id of the toucher
 */
public flag_captured(const info[])
{
    new 
flag
    
new toucher
    
new flagid
    
new team
    
    
/* gets the flag ent id */
    
flag info[0]
    
    
/* get the toucher id */
    
toucher info[1]
    
    
/* the id (index for plugin global arrays) is stored
       inside the flag, through the defined pev_csf_flagid */
    
flagid pev(flagpev_csf_flagid)
    
    
/* the team of the "toucher" player */
    
team get_user_team(toucher)
    
    
/* if toucher's team is not CT or T, get off */
    
if(team != && team != 2)
        return
    
    
/* sets the new owner of a flag */
    
set_pev(flagpev_csf_flagownertoucher)
    
    
/* resets the flag toucher for that flag */
    
set_pev(flagpev_csf_flagtoucher0)
    
    
/* updates the team who's oweing that flag */
    
set_pev(flagpev_csf_flagstatusteam)
    
    
/* g_FlagsState global is used for faster score hud updating */
    
g_FlagState[flagid] = team 1                
    
    
/* clears icon for the toucher */
    
msg_csf_icon(toucherfalse)
    
    
/* clear the progress bar of the toucher */
    
msg_bar_progress(toucher100true)
    
    
/* if player frags for capturing flags cvar has been set, add it */
    
if(get_pcvar_num(g_cvarCaptureFrags))
        
add_user_frags(toucherget_pcvar_num(g_cvarCaptureFrags), team)
    
    
/* sends chat and radio messages */
    
notify_flag_taken(toucherflagid)
    
    
/* flags list to be updated in next hud refresh */
    
g_UpdateFlagsHud true
    
    
/* should this match end if all flags has been taken (cvar setting)? */
    
if(get_pcvar_num(g_cvarAllFlagsWin)) {
        new 
allflags 1
        
for(new 1g_MapFlagsNumi++) {
            if(
g_FlagState[i] != g_FlagState[-1]) {
                
allflags 0
                
break
            }
        }
        if(
allflags) {
            new 
wf
            wf 
get_pcvar_num(g_cvarWinFrags)
            if(
wf)    add_user_frags(0wfteam)                    
            
team_win(team 1)
        }
    }
}

/**
 * Player think forward. In this version it's only used
 * with a purpose: to prevent players from moving or attacking if
 * amx_csflags_freeze has been set to 1.
 * @param id entity id of a player.
 */
public player_think(id
{
    
/* if csflags hasn't been started, ignore it */
    
if(!(g_CSFlagsState GAMESTATE_STARTED))
        return 
FMRES_IGNORED
    
    
/* if it's not displaying score, ignore it */
    
if(!(g_CSFlagsState GAMESTATE_SHOWSCORE))
        return 
FMRES_IGNORED    
    
    
/* if it's not the end of a match, ignore it */
    
if(!(g_CSFlagsState GAMESTATE_MATCHOVER)) {
        
        
/* if user isn't alive, get off */
        
if(is_user_alive(id)) {
            
            
/* if freeze cvar is set, move on */
            
if(get_pcvar_num(g_cvarFreeze)) {
                
                
/* makes players freexe */
                
engfunc(EngFunc_SetClientMaxspeedid0.1)
                
set_pev(idpev_maxspeed0.1)
            }
            
            
/* blocks attacks */
            
set_pev(idpev_button, (pev(idpev_button) & ~IN_ATTACK) & ~IN_ATTACK2
        }
    }
    
    return 
FMRES_IGNORED
}

/**
 * Forward to update flags.
 * @param flag the flag entity
 */
public flag_think(flag
{    
    
/* if game is showing scores or stopped, flags won't think */    
    
if(g_CSFlagsState & (GAMESTATE_SHOWSCORE GAMESTATE_STOPPED)) {
        
#if defined DEBUG_MODE
        
if(lastFlagState != g_CSFlagsState) {
            
            
open_debug_file()
            
print_stack(0"flag_think")
            
printvar_cell(0"g_CSFlagsState & GAMESTATE_SHOWSCORE"g_CSFlagsState GAMESTATE_SHOWSCORE)
            
printvar_cell(0"g_CSFlagsState & GAMESTATE_STOPPED"g_CSFlagsState GAMESTATE_STOPPED)
            
close_debug_file()
            
lastFlagState g_CSFlagsState
        
}
#endif

        
return FMRES_IGNORED
    
}
    
    
/* pev_csf_uniqueid is used to fast check if it's a flag */
    
if(pev(flagpev_csf_uniqueid) != CSFLAG_TYPEID)
        return 
FMRES_IGNORED
    
    
/* flags will delay to think with this artificial but efficient next think */
    
if(pev(flagpev_think_delay) < 4) {
        
set_pev(flagpev_think_delaypev(flagpev_think_delay) + 1)
        return 
FMRES_IGNORED
    
}
    
    
/* resets the delay counter */
    
set_pev(flagpev_think_delay0)
    
    
/* this is thinking, variables are static so cells are previously allocated */
    
static classname[32]
    static 
team
    
static owner
    
static toucher    
    
    
/* now this actually checks if it is a csflag */
    
pev(flagpev_classnameclassname31)
    if(!
equal(classnameCLASSNAME_CSFLAG))
        return 
FMRES_IGNORED
        
    
/* this enables to stop csflags by setting this cvar. (why here?) */
    
if(!get_pcvar_flags(g_cvarDomEnabled))
        
csflags_stop(0)    
    
    
/* if there's a toucher, it should have been set in touch forward */
    
toucher pev(flagpev_csf_flagtoucher)

    if(
toucher) {
        
/* if toucher has died or it's not touching that flag anymore */
        
if(!is_user_alive(toucher) || !is_touching(toucherflag)) {
            
/* clears the capture delay for this flag */
            
if(task_exists(TASKID_CAPTUREDELAY flag)) {
                
/* removes the task */
                
remove_task(TASKID_CAPTUREDELAY flag)
                
/* resets the toucher*/
                
set_pev(flagpev_csf_flagtoucher0)
                
/* resets icon */
                
msg_csf_icon(toucherfalse)
                
/* resets progress bar */
                
msg_bar_progress(toucher100true)
            }
        }
        
    }
    
/* gets the team who's owning that flag */
    
team pev(flagpev_csf_flagstatus)
    
    
/* if it's owned by a team */
    
if(team) {    
        
/* gets the player who has captured this flag */
        
owner pev(flagpev_csf_flagowner)
        
        
/* adds a score to flag owner if he/she exists (that player may have disconnected) */
        
if(owner)
            
g_PlayerScore[owner] += 0.04
        
        
/* if team is ct or t (being checked to be more safe) */
        
if(team == || team == 2) {
            
            new 
curScore
            
            
/* adds a score for that team */
            
g_TeamScore[team 1] += 0.04
            
            
            
            curScore 
floatround(g_TeamScore[team 1])
            
            if(
g_LastTeamScore[team 1] != curScore) {
                
g_UpdateScoresHud true
                g_LastTeamScore
[team -1] = curScore
            
}
            
            
/* if max points has been reached */
            
if(curScore >= floatround(get_pcvar_float(g_cvarMaxPoints))) {
                
/* if it isn't tied */
                
if(curScore != floatround(g_TeamScore[(team 1) ^ 1])) {
                    
/* adds a frag to team as long as frags cvar has been set */
                    
new wf
                    wf 
get_pcvar_num(g_cvarWinFrags)
                    if(
wf)    add_user_frags(0wfteam)
                    
/* set this team as the match winner */
                    
team_win(team 1)
                    
                }
            }                
        }
    }
    return 
FMRES_IGNORED
}

/**
 * Amxmodx core forward
 * This is used to make sure that:
 * - score slot for player disconnected is reset
 * - if that player owns a flag it's reset (owner only, it continues up being captured to that player's team)
 * - removes a capture delay task
 * @param id Player id.
 */
public client_disconnect(id
{
    new 
flag
    
    
/* loops all existing csflags */
    
while((flag engfunc(EngFunc_FindEntityByStringflag"classname"CLASSNAME_CSFLAG))) {
        
        
/* if this user is the one who captured that flag, it's cleaned */
        
if(pev(flagpev_csf_flagowner) == id)
            
set_pev(flagpev_csf_flagowner0)
        
        
/* if this user is touching this flag, remove tasks */
        
if(pev(flagpev_csf_flagtoucher) == id) {

            if(
task_exists(TASKID_CAPTUREDELAY flag))
                
remove_task(TASKID_CAPTUREDELAY flag)
            
/* resets toucher */
            
set_pev(flagpev_csf_flagtoucher0)
        }
    }
    
/* resets that player' score */
    
g_PlayerScore[id] = 0.0
}

/**
 * Check's if a player is touching a csflags. This is meant to be faster
 * than engine's FindEntitiesInSphere because it requires no loops - it takes
 * some advantages of those flags+triggers specificity.
 * @param playerid id of the player
 * @param flagent the csflag entity that's touching that flag.
 */
is_touching(playeridflagent
{    
    
/* this is called inside think forwards,
       variables are static for best performance */
    
static Float:pl_origin[3]
    static 
hitbox
    
static flagid

    
/* gets the hitbox of that csflag */
    
hitbox pev(flagentpev_csf_hitbox)
    
    
/* gets the origin of the testing player */
    
pev(playeridpev_originpl_origin)
    
    
/* gets that flag index (for global variables) */
    
flagid pev(flagentpev_csf_flagid)
    
    
/* checks if a player is inside that box, a 17.0 margin is added */
    
if( (pl_origin[0] + 17.0 >= (g_TriggerOrigin[flagid][0] + g_mmSize[hitbox][HITBOX_MIN][0]) &&
          
pl_origin[0] - 17.0 <= (g_TriggerOrigin[flagid][0] + g_mmSize[hitbox][HITBOX_MAX][0])) &&
         (
pl_origin[1] + 17.0 >= (g_TriggerOrigin[flagid][1] + g_mmSize[hitbox][HITBOX_MIN][1]) &&
          
pl_origin[1] - 17.0 <= (g_TriggerOrigin[flagid][1] + g_mmSize[hitbox][HITBOX_MAX][1])) &&
         (
pl_origin[2] + 17.0 >= (g_TriggerOrigin[flagid][2] + g_mmSize[hitbox][HITBOX_MIN][2]) &&
          
pl_origin[2] - 17.0 <= (g_TriggerOrigin[flagid][2] + g_mmSize[hitbox][HITBOX_MAX][2])))
        return 
1
    
    
return 0
}

/**
 * Touch forward.
 * @param ent1 toucher
 * @param ent2 touched
 */
public forward_touch(ent2ent1
{
    
    
/* static variables in this forwards for best performance */
    
static toucher
    
static classname[32]
    static 
team
    
static flag
    
    
/* checks entities consistency */
    
if(!pev_valid(ent1) || !pev_valid(ent2))
        return 
FMRES_IGNORED
    
    
/* if this is a csflag trigger and the user is alive */
    
if(pev(ent2pev_csf_uniqueid) == TRIGGERFLAG_TYPEID && is_user_alive(ent1)) {
        
        
/* It's ignored in either cases:
           - math is over
           - score is being shown
           - plugin has been stopped
         */
        
if(g_CSFlagsState & (GAMESTATE_SHOWSCORE GAMESTATE_STOPPED GAMESTATE_MATCHOVER))
            return 
FMRES_IGNORED        
        
        
/* the first filter (uniqueid) was meant to discard non flag messages more quickly,
         * now it's time to make sure this is actually a csflag trigger */
        
pev(ent2pev_classnameclassname31)                
        if(!
equal(classnameCLASSNAME_TRIGGER_FLAG))
            return 
FMRES_IGNORED
        
        
/* checks if that player is in a valid team */
        
team get_user_team(ent1)
        if(
team || team 2)
            return 
FMRES_IGNORED
            
        
/* gets the flag entity from the touched csflag trigger entity */
        
flag pev(ent2pev_csf_flagent)
        if(!
pev_valid(flag))
            return 
FMRES_IGNORED
        
        
/* toucher stores the id of flag previous toucher */
        
toucher pev(flagpev_csf_flagtoucher)
        
        
/* was that being touched by someone? */
        
if(toucher) {
            
/* is that toucher someone else from the opposed team ? */
            
if(toucher != ent1 && get_user_team(toucher) != team) {
                
/* resets flag ownwer */
                
set_pev(flagpev_csf_flagtoucher0)

                
/* if there was a capture in progress, remove it */
                
if(task_exists(TASKID_CAPTUREDELAY flag)) {
                    
remove_task(TASKID_CAPTUREDELAY flag)
                    
msg_bar_progress(toucher100true)
                    
msg_csf_icon(toucherfalse)
                }
            }
        }
        
        
/* it wasn't being touched */
        
else if(pev(flagpev_csf_flagstatus) != team) {
            
            
/* avoids progress bar flicking - that's probably because
             * dimensions covered by hitboxes differ's a bit from that
             * one checked in is_touching function.
             */
            
if(!is_touching(ent1flag))
                return 
FMRES_IGNORED
            
            
/* updates that flag toucher */
            
set_pev(flagpev_csf_flagtoucherent1)
            
            
/* displays capturing icon */
            
msg_csf_icon(ent1true)
            
            
/* sets the delay for calling capture function */
            
new info[2]
            
info[0] = flag
            info
[1] = ent1
            
if(task_exists(TASKID_CAPTUREDELAY flag))
                
remove_task(TASKID_CAPTUREDELAY flag)
            
            
/* displays the progress bar */
            
msg_bar_progress(ent10)
            
            
set_task(get_pcvar_float(g_cvarCaptureDelay),
                 
"flag_captured"TASKID_CAPTUREDELAY flaginfo2)
        }
        
    }
    return 
FMRES_IGNORED
}

/** 
 * Displays or hides the capturing icon
 * @param id player id
 * @param show flag to show or hide that icon.
 */
msg_csf_icon(idbool:show true
{
    
message_begin(MSG_ONEg_msgidIcon, {000}, id)
    
write_byte((show << 10))
    
write_string(CSFLAGS_ICON_NAME)
    if (
show) {
        
write_byte(CSFLAGS_ICON_R)
        
write_byte(CSFLAGS_ICON_G)
        
write_byte(CSFLAGS_ICON_B)
    }
    
message_end()
}

/**
 * Shows or hides the capturing progress bar.
 * @param id player id
 * @param pos current position of the progress bar
 * @param kill flag to show or hide the progress bar
 */
msg_bar_progress(idposbool:kill false)
{    
    
message_begin(MSG_ONEg_msgidProgress, {000}, id)
    
write_short(killget_pcvar_num(g_cvarCaptureDelay))
    
write_short(pos)
    
message_end()
}

/** 
 * Notifies to the team that a flag has been taken
 * This consistis in a radio and chat message.
 * @param toucher id of the person who's captured that flag
 * @param flagid id of the captured flag
 */
notify_flag_taken(toucherflagid
{
    new 
name[32]
    new 
toucherteam
    
new sid[4]
    new 
team
    
new id[1]
    
//new message[93]
    //new message_op[93]
    
    
g_Radio[toucher] = 1
    id
[0] = toucher
    
    
// avoid radio spam
    
set_task(4.0"radio_clear"TASKID_RADIORANGEid1
    
    
set_task(1.5"hide_radio_icon"TASKID_HIDERADIOICONid1)
    
    
toucherteam get_user_team(toucher)
    
get_user_name(touchername31)
    
    
num_to_str(touchersid3)
    
//format(message, 92,  "%L", LANG_PLAYER, "MSG_FLAGSTATE_NOTIFY", name, floatround(g_PlayerScore[toucher]), g_PlaceNames[flagid], (toucherteam == 2) ? (TEAM_DESC_CT) : TEAM_DESC_T)//g_Teams[g_FlagState[flagid]])
    //format(message_op, 92, "%L", LANG_PLAYER, "MSG_FLAGSTATE_NOTIFY_OP", name, floatround(g_PlayerScore[toucher]), g_PlaceNames[flagid], (toucherteam == 2) ? (TEAM_DESC_CT) : TEAM_DESC_T)
    
    
if(g_ifw_FlagTaken) {
        new 
retval
        ExecuteForward
(g_ifw_FlagTakenretvaltoucher)
    }
    
    for(new 
1<= g_MaxPlayersi++) {
        
        if(!
is_user_connected(i))
            continue
        
        
team get_user_team(i)
        
        if(
get_pcvar_num(g_cvarUseRadio) && (team == || team == 2)) {
            if(
team == toucherteam) {
                
                
message_begin(MSG_ONE_UNRELIABLE77_,i)
                                    
                if (
is_running("czero")) {                    
                    
write_byte (5)
                    
write_string (sid
                    
write_string ("#Game_radio_location")
                    
write_string (name)
                    
write_string (g_PlaceNames[flagid])                
                }
                else {
                    
write_byte (3)
                    
write_string ("#Game_radio")
                    
write_string (name)
                }
                
                
write_string(MSG_RADIO_POINTSECURED)
                
message_end()
                
                
message_begin (MSG_ONE135_i)
                
write_byte (1)
                
write_byte (toucher)
                
message_end ()
                
                
client_cmd(i"spk %s"SOUND_FLAGTAKEN)
                
client_cmd(i"spk %s"g_NotifySound[team 1])
                
//send_chat_msg(i, message)
                
ml_client_print(i"%L"LANG_PLAYER_C"MSG_FLAGSTATE_NOTIFY"namefloatround(g_PlayerScore[toucher]), g_PlaceNames[flagid], (toucherteam == 2) ? (TEAM_DESC_CT) : TEAM_DESC_T)
            }
            
            else  {
                if((
team 1) == ((toucherteam 1) ^ 1))
                    
client_cmd(i"spk %s"SOUND_OPPONENT_FLAGTAKEN)
                
ml_client_print(i"%L"LANG_PLAYER_C"MSG_FLAGSTATE_NOTIFY_OP"namefloatround(g_PlayerScore[toucher]), g_PlaceNames[flagid], (toucherteam == 2) ? (TEAM_DESC_CT) : TEAM_DESC_T)
            }            
            
        }
        
    }
}

// this is gungame_print by Avalanche
// with some tiny modifications.
// I only changed the function name
// because it's not gungame :P. Still
// all solution were provided by his code.
// and I couldn't have figured out anything
// better.
ml_client_print(idmsg[],any:...)
{
    new 
changeCountnumijargnum numargs(), player
    
static newMsg[191], message[191], changed[8], players[32]

    if(
id) {
        
players[0] = id
        num 
1
    
}
    else 
get_players(playersnum)

    for(
0numi++) {
        
        
player players[i]
        
changeCount 0
        
        
if(!is_user_connected(player)) continue

        
// [Avalanche's comments] we have to change LANG_PLAYER into
        // a player-specific argument, because
        // ML doesn't work well with SayText
        
for(2;argnum;j++) {
            if(
getarg(j) == LANG_PLAYER_C) {
                
setarg(j,0,player);
                
changed[changeCount++] = j
            
}
        }

        
// [Avalanche's comments] do user formatting
        
vformat(newMsg,190,msg,3);
        
        
// [Avalanche's comments] and now we have to change what we changed
        // back into LANG_PLAYER, so that the next
        // player will be able to have it in his language
        
for(j=0;j<changeCount;j++) {
            
setarg(changed[j],0,LANG_PLAYER_C);
        }

        
// [Avalanche's comments] optimized color swapping
        
replace_all(newMsg,190,"%n","^x03"// %n = team color
        
replace_all(newMsg,190,"%g","^x04"// %g = green
        
replace_all(newMsg,190,"%e","^x01"// %e = regular
        

        // [Avalanche's comments] now do our formatting (I used two variables because sharing one caused glitches)
        
formatex(message,190,"^x01%s",newMsg)

        
message_begin(MSG_ONEg_msgidSayText_player)
        
write_byte(player)
        
write_string(message)
        
message_end()
    }
    
    return 
1
}


/*send_chat_msg(id, msg[])
{    
    if(!is_user_connected(id))
        return
    message_begin(MSG_ONE, g_msgidSayText, {0,0,0}, id)
    write_byte(id)
    write_string(msg)
    message_end()    
}*/

move_to_spawn()
{
    new 
ctspawn
    
new tspawn
    
new spawn
    
new players[32]
    new 
playersnum
    
new team
    
new Float:vec[3]
    new 
bool:restore
    
    restore 
= (get_pcvar_num(g_cvarMatchRespawn) == 2)    
    
get_players(playersplayersnum)
    
    for(new 
0playersnumi++) {
        
spawn 0
        
        
if(players[i] && is_user_alive(players[i])) {
            
team get_user_team(players[i])
            switch(
team) {
                case 
: {
                    if(
tspawn == -1)
                        continue
                    
tspawn engfunc(EngFunc_FindEntityByString
                             
tspawn,
                             
"classname",
                             
"info_player_deathmatch")
                    
spawn tspawn
                    
if(!tspawn)
                        
tspawn = -1
                
}
                case 
: {
                    if(
ctspawn == -1)
                        continue
                    
ctspawn engfunc(EngFunc_FindEntityByString,
                              
ctspawn,
                              
"classname",
                              
"info_player_start")
                    
spawn ctspawn
                    
if(!ctspawn)
                        
ctspawn = -1
                
}                
            }
            if(
spawn) {
                
                
pev(spawnpev_originvec)
                
engfunc(EngFunc_SetOriginplayers[i], vec)
                
set_pev(players[i], pev_fixangle1)
                
pev(spawnpev_anglesvec)
                
set_pev(players[i], pev_anglesvec)
                
                if(
restore)
                    
set_pev(players[i], pev_health100.0)
            }
        }
        
    }    
    
}

public 
update_score() 
{    
    
    static 
headerCT[25]
    static 
headerT[25]
    
    static 
flagsTakenT[HUD_FLAGS_STRING_MAXSIZE]
    static 
flagsTakenCT[HUD_FLAGS_STRING_MAXSIZE]
    
    
    static 
scoreCT[25 HUD_FLAGS_STRING_MAXSIZE]
    static 
scoreT[25 HUD_FLAGS_STRING_MAXSIZE]
    
    new 
ind
    
    
// updates scores
    
if(g_UpdateScoresHud) {
        
formatex(headerT30g_ScoreHeaderFormat[ID_TEAM_T], g_TeamWins[ID_TEAM_T], floatround(g_TeamScore[ID_TEAM_T]))
        
formatex(headerCT30g_ScoreHeaderFormat[ID_TEAM_CT], g_TeamWins[ID_TEAM_CT], floatround(g_TeamScore[ID_TEAM_CT]))
    }
    
    
// updates flags list
    
if(g_UpdateFlagsHud) {
        
        new 
flagsTakenCTLen
        
new flagsTakenTLen
        flagsTakenT
[0] = 0
        flagsTakenCT
[0] = 0
        
        
for(ind 0ind MAX_CSFLAGSind++) {
            
            if(
g_FlagState[ind] == 1) {
                
flagsTakenCTLen += format(flagsTakenCT[flagsTakenCTLen], 
                                
HUD_FLAGS_STRING_MAXSIZE flagsTakenCTLen,
                                
"^n%s"g_PlaceNames[ind])
            } 
            else if(
g_FlagState[ind] == 0) {
                
flagsTakenTLen += format(flagsTakenT[flagsTakenTLen], 
                               
HUD_FLAGS_STRING_MAXSIZE flagsTakenTLen,
                               
"^n%s"g_PlaceNames[ind])
            }
            
        }
    }
    
    
// only reformat if there was an update
    
if(g_UpdateFlagsHud || g_UpdateScoresHud) {
        
formatex(scoreCT24 HUD_FLAGS_STRING_MAXSIZE"%s%s"headerCTflagsTakenCT)
        
formatex(scoreT24 HUD_FLAGS_STRING_MAXSIZE"%s%s"headerTflagsTakenT)
    }
    
    
// clean updates
    
g_UpdateFlagsHud false
    g_UpdateScoresHud 
false
    
    
// send hud messages
    
for(ind 1ind <= g_MaxPlayersind++) {
        if(
is_user_connected(ind)) {
            if(
is_user_alive(ind)) {    
                
set_hudmessage(255000.30.006.0INTERVAL_SCORE_UPDATE0.10.23)
                
show_hudmessage(indscoreT)
                
set_hudmessage(ind02550.60.006.0INTERVAL_SCORE_UPDATE0.10.24)
                
show_hudmessage(indscoreCT)
            }
            else {
                
set_hudmessage(255000.30.1706.0INTERVAL_SCORE_UPDATE0.10.23)
                
show_hudmessage(indscoreT)
                
set_hudmessage(ind02550.60.1706.0INTERVAL_SCORE_UPDATE0.10.24)
                
show_hudmessage(indscoreCT)
            }
        }            
    }
}

remove_default_objectives() 
{
    new 
objectives[6][] = {
        
"func_bomb_target",
        
"info_bomb_target",
        
"info_hostage_rescue",
        
"func_hostage_rescue",
        
"func_vip_safetyzone",
        
"func_escapezone"
    
}
    for(new 
06i++)
        
remove_all_ents(objectives[i])
}
        
add_user_frags(idvalueteam)
{
    
/*
     * Taken from VEN's CTF,
     * modified to fit this plugin
     */
    
    
new Float:frags
    
new players[32]
    new 
playersnum
    
static const fnTeamFilter[3][] = { """TERRORIST""CT" }
    
    if(
id) {
        
playersnum 1
        players
[0] = id
    
}
    else {
        if(
team && team 2)
            
get_players(playersplayersnum"e",  fnTeamFilter[team])
        
        
/*new tstr[16]
        if(team == (ID_TEAM_T + 1))
            formatex(tstr, 15, "TERRORIST")
        else if(team == (ID_TEAM_CT + 1))
            formatex(tstr, 15, "CT")
        get_players(players, playersnum, "e",  tstr)*/
    
}    
    
    for(new 
0playersnumi++) {
        
pev(players[i], pev_fragsfrags)
        
frags += value
        set_pev
(players[i], pev_fragsfrags)
        
        
message_begin(MSG_ALLg_msgidScoreInfo)
        
write_byte(players[i])
        
write_short(floatround(frags))
        
write_short(CS_GET_USER_DEATHS_(players[i]))
        
write_short(0)
        
write_short(team)
        
message_end()
    }    
    
}
        
load_config() 
{
    new 
file[72]
    
    if(
get_configfile(file71)) {
        new 
numbers[5][6]
        new 
Float:origin[3]
        new 
Float:angle[3]
        new 
line[96]        
        new 
arg1[16]
        new 
arg2[80]
        new 
hitbox
        
new count        
        
new flag
        
new trigger
        
new filepointer
        
        filepointer 
fopen(file"r")
        
        while(
fgets(filepointerline95) && count MAX_CSFLAGS) {
            if(!
strlen(line) || line[0] == ';')
                continue
            
parse(linearg115arg279)
            
            if(!
strlen(arg2))
                continue
                
            if(
strlen(arg1))
                
copy(g_PlaceNames[count], 15arg1)
            else
                
formatex(g_PlaceNames[count], 15"Flag[%d]"count)
            
            
parse    (arg2
                
numbers[0], 5,
                
numbers[1], 5,
                
numbers[2], 5,
                
numbers[3], 5,
                
numbers[4], 5)
                
            
origin[0] = str_to_float(numbers[0])
            
origin[1] = str_to_float(numbers[1])
            
origin[2] = str_to_float(numbers[2])
            
angle[1] = str_to_float(numbers[3])
            
hitbox str_to_num(numbers[4])
            
engfunc(EngFunc_MakeVectorsangle)
            
            
flag engfunc(EngFunc_CreateNamedEntityengfunc(EngFunc_AllocString"cycler_sprite"))
            
            if(
pev_valid(flag)) {
                
engfunc(EngFunc_SetOriginflagorigin)                
                
set_pev(flagpev_modelMODEL_FLAGS)
                
set_pev(flagpev_framerate1.0)
                
dllfunc(DLLFunc_Spawnflag)                
                
set_pev(flagpev_classnameCLASSNAME_CSFLAG)
                
set_pev(flagpev_anglesangle)
                
set_pev(flagpev_csf_uniqueidCSFLAG_TYPEID)            
                
set_pev(flagpev_csf_flagidcount)
                
set_pev(flagpev_csf_hitboxhitbox)
                
                
trigger engfunc(EngFunc_CreateNamedEntityengfunc(EngFunc_AllocString"trigger_multiple"))
                
                if(
pev_valid(trigger)) {
                    
origin[2] += 48.0
                    engfunc
(EngFunc_SetOrigintriggerorigin)                    
                    
dllfunc(DLLFunc_Spawntrigger)
                    
engfunc(EngFunc_SetSizetriggerg_mmSize[hitbox][HITBOX_MIN], g_mmSize[hitbox][HITBOX_MAX])
                    
set_pev(triggerpev_csf_uniqueidTRIGGERFLAG_TYPEID)
                    
set_pev(triggerpev_classnameCLASSNAME_TRIGGER_FLAG)
                    
set_pev(triggerpev_csf_flagentflag)
                    
set_pev(triggerpev_csf_flagidcount)
                    
set_pev(flagpev_csf_triggertrigger)
                    
                    
                    
g_TriggerOrigin[count][0] = origin[0]
                    
g_TriggerOrigin[count][1] = origin[1]
                    
g_TriggerOrigin[count][2] = origin[2]                    
                }
                else {
                    
fclose(filepointer)
                    return 
0
                
}
                if(
count MAX_CSFLAGS)
                    
count++
            }
            else {
                
fclose(filepointer)
                return 
0
            
}
            
flag 0
            trigger 
0            
        
}
        
fclose(filepointer)
        
        if(
count) {
            
g_MapFlagsNum count
            
return 1
        
}
        else
            return 
0
    
}
    return 
0
}

get_configfile(file[], len
{
    new 
map[36]
    
    
get_mapname(map35)
    
get_configsdir(filelen)
    
format(file[strlen(file)], len strlen(file), FILE_DOMCFGmap)
    
    return 
file_exists(file)
}

// map time functions


/**
 * This is called when a csflags match is over, it's meant
 * to shorten the map left time to an acceptable time - to
 * do the voting maps or whatever. This delay is defined in
 * "amx_csflags_mapendtime" cvar.
 */
public force_end() 
{

#if defined DEBUG_MODE
    
open_debug_file()
    
print_stack(0"server_changelevel")
#endif

    
new Float:mplimit    // stores the current mp_timelimit
    
mplimit get_cvar_float("mp_timelimit")
    
    
// I don't remember why the number of players was relevant
    // it make some sense anyway.
    
if (get_playersnum() && mplimit != 0.0) {

        new 
Float:newlimit
        
        
// calculates the new limit
        
newlimit mplimit float(get_timeleft() / 60) + get_pcvar_float(g_cvarMapEndTime)
        
        
// flags game state so mp_timelimit can be recovered before the
        // level changes
        
g_CSFlagsState |= GAMESTATE_FORCEDEND
        
        
// stores the old mp_timelimit into the global 
        
g_OldMPTime mplimit
        
        
// attempts to launch a voting system
        // (if it's been defined)
        
start_vote_cmd(0.0)
        
        
// sets the new mp_time limit
        
server_cmd("mp_timelimit %f"newlimit)        
        
client_print(0,print_chat,"%s %s"MSG_HEADER"%L"LANG_PLAYER"MSG_CHANGEMAP_DELAY")

#if defined DEBUG_MODE
        
printvar_float(0"mplimit"mplimit)
        
printvar_float(0"newlimit"newlimit)
        
close_debug_file()
#endif

    
}
}

/**
 * Change level forward
 */
public server_changelevel(map[]) 
{
    
#if defined DEBUG_MODE
    
open_debug_file()
    
print_stack(0"server_changelevel")
#endif
    
    // checks if one of these situations is true so an previously saved mp_timelimit must be restored:
    // 1) the match was over, it's been given some delay but now it's time to go
    // 2) there wasn't a winner, now it came up
    
if((g_CSFlagsState GAMESTATE_FORCEDEND || g_CSFlagsState GAMESTATE_WAIT) && g_OldMPTime) {
        
        if (
get_cvar_num("mp_timelimit") == get_pcvar_num(g_cvarMapEndTime)) {
            
// restores the original value
            
server_cmd("mp_timelimit %d"g_OldMPTime)

#if defined DEBUG_MODE
        
print_comment(0"setting mp_timelimit to g_OldMPTime"1)
#endif
             
            
        
}
    }
#if defined DEBUG_MODE
    
close_debug_file()
#endif
}

/**
 *  Checks if game end should be delayed because csflags match isn't over.
 *  This is called when it's missing 11 seconds to change level process.
 *  The amxmodx count down starts at 10, so that's why it's 11. 
 */
public set_mapend_mptimelimit() 
{    
#if defined DEBUG_MODE
    
open_debug_file()
    
print_stack(0"set_mapend_mplimit")
#endif
    
    // confusing part; if statement was nested like that so
    // I could still have debug messages
    //
    // here's the first "if" description in the order statements are placed:
    // 1) csflags must have been started --> ok
    // 2) any of these case are true: 
    //    a) level being forced to end because of csflags match is over
    //    b) csflags match over
    //    c) csflags match is delaying the map time because it's waiting for a winner
    // 3) there are players (why am I checking this?)
    // 4) OldMPTime must not be set, added in 1.93
    // 5) the server has a level time limit --> would this function get called if not?
    // 6) what? why would that be disabled now?
    
if( (g_CSFlagsState GAMESTATE_STARTED) &&
        !(
g_CSFlagsState & (GAMESTATE_FORCEDEND GAMESTATE_MATCHOVER GAMESTATE_WAIT)) &&
         
get_playersnum() &&
         
g_OldMPTime == 0.0 &&
         
get_cvar_float("mp_timelimit") != 0.0 &&
         
get_pcvar_num(g_cvarDomEnabled)) {        
         
        
// it doesn't allow tied matches
        
if(!get_pcvar_num(g_cvarTieMatch)) {            
            
            
// checks csflags match isn't over
            
if(!map_should_end()) {
                
                
// flags it to wait
                
g_CSFlagsState |= GAMESTATE_WAIT
                
                
// stores the current mp_timelimit
                
g_OldMPTime get_cvar_float("mp_timelimit")
                
                
// set time limit to infinite
                
server_cmd("mp_timelimit 0")
                
                
// removing this task
                
remove_task(TASKID_MAPEND// <-- added in 1.93
                
                // attempts to launch a voting system
                // (if it's been defined)
                
start_vote_cmd(0.0)

#if defined DEBUG_MODE
                
print_comment(0"waiting for a winner"1)
                
print_comment(0"mp_timelimit = 0, gamestate |= GAMESTATE_WAIT"1)
                
printvar_float(0"g_OldMPTime"g_OldMPTime)
#endif

                
client_print(0print_chat"%L %L"LANG_PLAYER"MSG_HEADER"LANG_PLAYER"MSG_TIME_OVER")
            
            }

#if defined DEBUG_MODE
            
else
                
print_comment(0"map_should_end returned 1, won't mess with time")
#endif
        
}

#if defined DEBUG_MODE
        
else
            
print_comment(0"Tie match enabled, won't mess with time"1
#endif

    
}

#if defined DEBUG_MODE
    
else {
        
print_comment(0"At least one of these statements failed:"1)
        
printvar_cell(0"g_CSFlagsState & GAMESTATE_STARTED"g_CSFlagsState GAMESTATE_STARTED)
        
printvar_cell(0"!(g_CSFlagsState & GAMESTATE_FORCEDEND", !(g_CSFlagsState GAMESTATE_FORCEDEND))
        
printvar_cell(0"!(g_CSFlagsState & GAMESTATE_MATCHOVER)", !(g_CSFlagsState GAMESTATE_MATCHOVER))
        
printvar_cell(0"!(g_CSFlagsState & GAMESTATE_WAIT)", !(g_CSFlagsState GAMESTATE_WAIT))
        
printvar_cell(0"get_playersnum()"get_playersnum())
        
printvar_cell(0"get_cvar_float(^"mp_timelimit^") != 0.0"get_cvar_float("mp_timelimit") != 0.0)
        
printvar_cell(0"get_playersnum()"get_playersnum())
        
printvar_cell(0"get_pcvar_num(g_cvarDomEnabled)"get_pcvar_num(g_cvarDomEnabled))
        
    }
    
close_debug_file()
#endif
}

/**
 * Analyzes if there's a reason a map should end or not.
 * This functions doesn't consider the tie match configuration
 * in cvar for making the assertion.
 * @return 0 for negative, 1 for affirmative.
 */
map_should_end() 
{
    new 
maxwins get_pcvar_num(g_cvarMaxWins)
    
    new 
tscore g_TeamWins[ID_TEAM_T]
    new 
ctscore g_TeamWins[ID_TEAM_CT]
    
    
// 1) max wins must be a relevant condition (cvar)
    // 2) max wins must have been reached
    // 3) match must not be tied
    
if((maxwins) ? (maxwins ctscore && maxwins tscore) || tscore == ctscore tscore == ctscore)
        return 
0
        
    
return 1
}

public 
restore_mptimelimit() 
{
#if defined DEBUG_MODE
    
open_debug_file()
    
print_stack(0"restore_mplimit")
    
printvar_float(0"g_OldMPTime"g_OldMPTime)
    
printvar_cell(0"get_cvar_num(^"mp_timelimit^")"get_cvar_num("mp_timelimit"))
    
close_debug_file()
#endif

    
g_CSFlagsState GAMESTATE_STOPPED    
    
if (get_cvar_num("mp_timelimit") == 0)
        
server_cmd("mp_timelimit %f"g_OldMPTime)
}


// ---------------------------------------------------------------------------------------
// Debug tools

#if defined DEBUG_TOOLS

#define DEBUG_LINE 160

#define PRINT_MSG1(%1,%2,%3) format(debugMsg, 127, %2, %3); debug_print(%1, debugMsg)
#define PRINT_MSG2(%1,%2,%3,%4) format(debugMsg, 127, %2, %3, %4); debug_print(%1, debugMsg)
#define PRINT_MSG3(%1,%2,%3,%4,%5) format(debugMsg, 127, %2, %3, %4, %5); debug_print(%1, debugMsg)



public debug_gamestate(idstack[])
{
    
open_debug_file()
    
    if(
stack[0]) 
        
print_stack(idstack)
    else
        
print_stack(id)
    
    
print_debug_cmd(id"Game State tracing")
    
    
PRINT_MSG1(id"GAMESTATE_STARTED: %d"g_CSFlagsState GAMESTATE_STARTED 0)
    
PRINT_MSG1(id"GAMESTATE_FORCEDEND: %d"g_CSFlagsState GAMESTATE_FORCEDEND 0)
    
PRINT_MSG1(id"GAMESTATE_HUDREPEAT: %d"g_CSFlagsState GAMESTATE_HUDREPEAT 0)
    
PRINT_MSG1(id"GAMESTATE_MATCHOVER: %d"g_CSFlagsState GAMESTATE_MATCHOVER 0)
    
PRINT_MSG1(id"GAMESTATE_SHOWSCORE: %d"g_CSFlagsState GAMESTATE_SHOWSCORE 0)
    
PRINT_MSG1(id"GAMESTATE_STOPPED: %d"g_CSFlagsState GAMESTATE_STOPPED 0)
    
PRINT_MSG1(id"GAMESTATE_WAIT: %d"g_CSFlagsState GAMESTATE_WAIT 0)
    
    
close_debug_file()
}


open_debug_file()
{
#if defined DEBUG_FILE
    
if(!pDebugFile)
        
pDebugFile fopen(DEBUG_FILE"a+")
#endif
}
close_debug_file() {
#if defined DEBUG_FILE
    
if(pDebugFile) {
        
fclose(pDebugFile)
        
pDebugFile 0
    
}
#endif
}
    

public 
debug_flags(idstack[])
{
    new 
flag
    
new trigger
    
new Float:vector[3]
    new 
count
    
    open_debug_file
()
    
    if(!
stack[0]) 
        
print_stack(idstack)
    else
        
print_stack(id)
    
    
print_debug_cmd(id"Flags Tracing")
    
    while((
flag engfunc(EngFunc_FindEntityByStringflag"classname"CLASSNAME_CSFLAG))) {
        
        
PRINT_MSG2(id"***^nflagent: %d, flagid: %d"flagpev(flagpev_csf_flagid))
        
PRINT_MSG1(id"Flag name: %s"g_PlaceNames[pev(flagpev_csf_flagid)])
        
        
pev(flagpev_originvector)
        
PRINT_MSG3(id"Origin: %f %f %f"vector[0], vector[1], vector[2])
        
        
pev(flagpev_anglesvector)
        
PRINT_MSG3(id"Angles: %f %f %f"vector[0], vector[1], vector[2])
        
        
PRINT_MSG1(id"Hitbox: %d"pev(flagpev_csf_hitbox))
        
PRINT_MSG1(id"Owner: %d"pev(flagpev_csf_flagowner))
        
PRINT_MSG1(id"Toucher: %d"pev(flagpev_csf_flagtoucher))
        
PRINT_MSG1(id"Status: %d"pev(flagpev_csf_flagstatus))
        
PRINT_MSG1(id"typeid: %d"pev(flagpev_csf_uniqueid))    
        
        
trigger pev(flagpev_csf_trigger)
        
PRINT_MSG1(id"Flag trigger:"trigger)
        
        if(
pev_valid(trigger)) {
            
pev(triggerpev_originvector)
            
PRINT_MSG3(id"^tOrigin: %f %f %f"vector[0], vector[1], vector[2])
            
            
pev(triggerpev_maxsvector)
            
PRINT_MSG3(id"^tMaxs(size): %f %f %f"vector[0], vector[1], vector[2])
            
            
pev(triggerpev_minsvector)
            
PRINT_MSG3(id"^tMins(size): %f %f %f"vector[0], vector[1], vector[2])            
            
            
PRINT_MSG1(id"^tflagid(ref): %d"pev(triggerpev_csf_flagid))
            
PRINT_MSG1(id"^tflagent(ref): %d"pev(triggerpev_csf_flagent))
            
PRINT_MSG1(id"^ttypeid: %d"pev(triggerpev_csf_uniqueid))            
        }
        else
            
debug_print(id"^t[invalid trigger entity]")
        
        
count++
        
    }
    
    
PRINT_MSG1(id"--- Found %d flags"count)
    
    
close_debug_file()
}

debug_print(id, const msg[])
{
    if(
id)
        
console_print(idmsg)
    else
        
server_print(msg)
    
#if defined DEBUG_FILE
    
if(pDebugFile) {
        
fputs(pDebugFilemsg)
        
fputs(pDebugFile"^n")
    }
#endif // DEBUG_FILE
}

print_debug_cmd(idcmd[])
{
    
PRINT_MSG3(id"%s^n%s CMD: %s"debugLinedebugHeadercmd)
}

print_stack(idstack[] = "Unknown"bool:opendfile false)
{
    if(
opendfile)
        
open_debug_file()
    
    
PRINT_MSG2(id"^n%s Stack on %s"debugHeaderstack)
    
    if(
opendfile)
        
close_debug_file()
}

stock printvar_cell(id, const varname[], value)
{
    
PRINT_MSG2(id"^t[cell] %s = %d"varnamevalue)
}

stock printvar_float(id, const varname[], Float:value)
{
    
PRINT_MSG2(id"^t[float] %s = %f"varnamevalue)
}

stock printvar_string(id, const varname[], const value[])
{
    
PRINT_MSG2(id"^t[string] %s = %s"varnamevalue)
}

stock printvar_cell_array(id, const varname[], const array[], length)
{
    
PRINT_MSG1(id"^t[array] %s"varname)
    for(new 
ilengthi++)
        
PRINT_MSG2(id"^t^t[%d] = %d", array[i])  
}

stock printvar_float_array(id, const varname[], const Float:array[], length)
{
    
PRINT_MSG1(id"^t[array] %s"varname)
    for(new 
ilengthi++)
        
PRINT_MSG2(id"^t^t[%d] = %f", array[i])  
}

stock printvar_string_array(id, const varname[], const array[][], length)
{
    
PRINT_MSG1(id"^t[array] %s"varname)
    for(new 
ilengthi++)
        
PRINT_MSG2(id"^t^t[%d] = %s", array[i])  
}

stock print_comment(id, const comment[], tabnum 0bool:opendfile false)
{
    new 
fmt[180]
    
    new 
len
    
    
// why am I doing this?
    
if(tabnum >= 16)
        
tabnum 15
    
    len 
format(fmttabnumTabs)
    
len += format(fmt179"** %s"comment)
    
    if(
opendfile)
        
open_debug_file()
    
    
debug_print(idfmt)
    
    if(
opendfile)
        
close_debug_file()
}

#endif // DEBUG_TOOLS 
Error:
Quote:
Error: Undefined symbol "id" on line 477
Warning: Loose indentation on line 477
Warning: Expression has no effect on line 477
Error: Expected token: ";", but found ")" on line 477
Error: Invalid expression, assumed zero on line 477
Error: Too many error messages on one line on line 477

Compilation aborted.
4 Errors.
Mind Helping someone?
__________________
DruGzOG is offline
Send a message via AIM to DruGzOG
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 02-16-2010 , 12:45   Re: CS Flags (dod like) - 1.193 [2009-07-09]
Reply With Quote #456

log_amx("%L Cound't find sound file %s to precache.", "MSG_HEADER", id, cursound)

Remove id,

By the way :

Code:
register_plugin("BattleField Addon : Flags", VERSION, "www.****.com")

You are not the author, and you have change nothing. Nice to see how you care about the work of the real author.
__________________
Arkshine is offline
DruGzOG
Veteran Member
Join Date: Nov 2007
Location: Unknown
Old 02-16-2010 , 14:00   Re: CS Flags (dod like) - 1.193 [2009-07-09]
Reply With Quote #457

I realized Im not the author, the website was added. I see no issue with it.
__________________
DruGzOG is offline
Send a message via AIM to DruGzOG
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 02-16-2010 , 14:02   Re: CS Flags (dod like) - 1.193 [2009-07-09]
Reply With Quote #458

You must be joking.
__________________
Arkshine is offline
DruGzOG
Veteran Member
Join Date: Nov 2007
Location: Unknown
Old 02-16-2010 , 14:06   Re: CS Flags (dod like) - 1.193 [2009-07-09]
Reply With Quote #459

Nope, not at all.

I changed a few lines that aren't that big. Matter of fact I just changed the sound and model precache lines.

Nothing big, nor do I think CommonBullet would mind since he has alot more users using this plugin. Me changing the author isn't something quite big.
__________________
DruGzOG is offline
Send a message via AIM to DruGzOG
Arkshine
AMX Mod X Plugin Approver
Join Date: Oct 2005
Old 02-16-2010 , 14:44   Re: CS Flags (dod like) - 1.193 [2009-07-09]
Reply With Quote #460

Quote:
Me changing the author isn't something quite big.
You are NOT the author. Letting the original author means you respect his work. Are you idiot or what ? It's so common sense I don't know how you are still proud of that. It would be more appropriate to add a comment like "modified by blabla". It doesn't make sense to change the author just because you have changed one or two lines. Plus you have even removed the header. It's really pathetic.
__________________

Last edited by Arkshine; 02-16-2010 at 14:49.
Arkshine 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 00:32.


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