Off course it needs to be 1 CT nominated not 1 zm [T TEAM] , weapon doesnt matter i can do that myself to give special weapon. and also next round happens nothing. its pretty simple plugin to understand.Once nominated, you become a "survivor". Your team is T. Only you & awp, alone.
All other players receive knives and are transfered to CT automatically. They're your "enemies".
source: https://forums.alliedmods.net/showthread.php?p=841879
Code: Select all
#define PLUGINNAME "Survivor"
#define VERSION "1.0"
#define AUTHOR "beybe"
#include <amxmodx>
#include <amxmisc>
#include <cstrike>
#include <fun>
#pragma semicolon 1
/*
* survivor is limited to weapons: awp, hegrenade, knife and C4.
*/
#define SURVIVOR_WEAPONS 4
new g_survivor_weapons[SURVIVOR_WEAPONS] = {CSW_KNIFE, CSW_AWP, CSW_C4, CSW_HEGRENADE};
/*
* Enemies are limited to 1 weapon type: only knife, smoke&flash grenades.
*/
#define ENEMY_WEAPONS 2
new g_enemy_weapons[ENEMY_WEAPONS] = {CSW_KNIFE, CSW_SMOKEGRENADE};
// this one is simply hardcoded,
const g_maxusers = 32;
// survive next round: true or false.
new bool:g_survivenextround;
/* g_survivormode:
0 - disabled. Mode is not scheduled.
1 - init. Next round is survivor, make preparations.
2 - running. Current round is running in survivor mode.
11 - is handled in eventRoundEnd ONLY.
Current round is runnig with mode activated. And next round is scheduled to run mode also.
Only 2 situations we need to handle in this way:
1st - next-round survivor and current survivor is the same player - no actions in this case(no transfers between the teams).
2nd - next-round survivor is a new player - we need to swap only these two players.
*/
new g_survivormode;
// collects players original teams, before switching to survivor mode.
new CsTeams:g_teams[32];
// survivor player index.
new g_survivor_user;
// collects next survivor player index(for next survive-round).
new g_survivor_user_next;
// Indicates current round is finished.
new bool:g_roundend;
// Single round survivor's frags.
new g_roundfrags;
public plugin_init() {
register_plugin(PLUGINNAME, VERSION, AUTHOR);
g_survivenextround = false;
g_survivormode = 0;
g_roundend = false;
g_roundfrags = 0;
// Catch player's weapon change.
register_event("CurWeapon", "eventOnWeaponSelect", "be", "1=1");
// Catch round start.
register_event("ResetHUD", "eventOnRoundStart", "be");
// Catch round end.
register_event("SendAudio", "eventOnRoundEnd", "a", "2&%!MRAD_terwin");
register_event("SendAudio", "eventOnRoundEnd", "a", "2&%!MRAD_ctwin");
register_event("SendAudio", "eventOnRoundEnd", "a", "2&%!MRAD_rounddraw");
// Catch when smbd selects T team.
//register_event("TeamInfo", "eventOnJoinT", "a", "2=TERRORIST" );
register_event("TextMsg", "eventOnJoinT", "a", "2=#Game_join_terrorist" );
// Catch when smbd selects CT team.
//register_event("TeamInfo", "eventOnJoinCT", "a", "2=CT" );
register_event("TextMsg", "eventOnJoinCT", "a", "2=#Game_join_ct" );
// Killing eventþ
register_event("DeathMsg", "eventOnKilling", "a", "1>0");
register_clcmd("amx_survivor", "eventOnActivateCommand", ADMIN_MAP, "amx_survivor <user id,nick> - force survivor mode next round with <user> as a survivor.");
// ML support.
register_dictionary("survivor.txt");
}
/**
* Callback. Called when a player disconnects.
*
*/
public client_disconnect(Index) {
/*
* In survivor mode, catch survivor diconnection.
*/
if(g_survivormode) {
// If current survivor disconnects, select another one.
if(Index==g_survivor_user) {
g_survivor_user = PrepareSurvivor(1, 0);
}
}
}
/**
* Fires on every killing.
*/
public eventOnKilling() {
/*
* In survivor mode, catch survivor diconnection.
*/
if(g_survivormode) {
new KillerId = read_data(1);
if(KillerId==get_user_userid(g_survivor_user))
g_roundfrags++;
}
return PLUGIN_HANDLED;
}
public eventOnJoinT() {
/*
* If survivor mode is active - nobody can join survivor-team, excepting survivor:).
* So, we simply enforces the team change, but survivors are allowed.
*/
if(g_survivormode) {
const PlayerNameLen = 32;
new PlayerName[PlayerNameLen+1];
read_data(3, PlayerName, PlayerNameLen);
new PlayerIndex = find_player("al", PlayerName);
if(PlayerIndex!=g_survivor_user)
Transfer2Team(PlayerIndex, CS_TEAM_CT);
}
return PLUGIN_HANDLED;
}
public eventOnJoinCT() {
/*
* If survivor mode is active - everyone is allowed to join enemy-team.
* Excepting survivors... :)
*/
// Prevent survivor from switching to enemy-team(CT).
if(g_survivormode) {
const PlayerNameLen = 32;
new PlayerName[PlayerNameLen+1];
read_data(3, PlayerName, PlayerNameLen);
new PlayerIndex = find_player("al", PlayerName);
if(PlayerIndex==g_survivor_user) {
Transfer2Team(PlayerIndex, CS_TEAM_T);
}
}
return PLUGIN_HANDLED;
}
/**
* This one is called when each player shoots or tries to select weapon.
*
*/
public eventOnWeaponSelect(UserIndex) {
if(!g_survivormode)
return PLUGIN_HANDLED;
if(!is_user_alive(UserIndex))
return PLUGIN_HANDLED;
new Weapon = read_data(2);
const StrDefaultWeaponLen = 20;
new StrDefaultWeapon[StrDefaultWeaponLen+1];
if(g_survivor_user==UserIndex) {
// survivor.
for (new i=0; i<SURVIVOR_WEAPONS; i++)
if(Weapon == g_survivor_weapons[i])
return PLUGIN_HANDLED;
format( StrDefaultWeapon, StrDefaultWeaponLen, "weapon_knife");
}
else {
// enemy.
for (new i=0; i<ENEMY_WEAPONS; i++)
if (Weapon== g_enemy_weapons[i])
return PLUGIN_HANDLED;
format( StrDefaultWeapon, StrDefaultWeaponLen, "weapon_knife");
}
engclient_cmd(UserIndex, StrDefaultWeapon);
return PLUGIN_HANDLED;
}
/**
* "amx_survivor <user>" callback.
*
*/
public eventOnActivateCommand(Id, Level, Cid) {
// Check permissions
if (!cmd_access(Id, Level, Cid, 2))
return PLUGIN_HANDLED;
// Round finished?
if(g_roundend) {
console_print(Id, "%L", Id, "MSG_ROUNDEND");
return PLUGIN_HANDLED;
}
const SurvivorNameLen = 32;
new SurvivorName[SurvivorNameLen+1];
read_argv(1, SurvivorName, SurvivorNameLen);
cmd_target(Id, SurvivorName);
// Try to find out specified player.
new Index = 0;
// 1st method - by #userid.
if(SurvivorName[0] == '#') {
SurvivorName[0] = '0';
Index = find_player("k", str_to_num(SurvivorName));
}
// 2nd method - by part of user nick.
if(!Index) {
Index = find_player("bl", SurvivorName);
}
// Check player with Index is online.
if(!is_user_connected(Index) || !Index) {
console_print(Id, "%L", Id, "MSG_PLAYER_NOTFOUND", SurvivorName);
return PLUGIN_HANDLED;
}
// If we are here - Index is the currect player index.
// Collect survivor index.
g_survivor_user_next = Index;
g_survivenextround = true;
get_user_name(Index, SurvivorName, SurvivorNameLen);
// Notify command succeed.
console_print(Id, "%L", Id, "MSG_NOMINATION_OK", SurvivorName);
return PLUGIN_HANDLED;
}
/**
* This function fires everytime round starts.
*
*/
public eventOnRoundStart() {
g_roundend = false;
if(g_survivormode==0) {
/*
* Round started. But the mode is disabled.
* Nothing to do here.
*/
return PLUGIN_HANDLED;
}
else if(g_survivormode==1) {
/*
* Round just started in survivor mode.
* This is a good point to prepare for war and supply weapons&ammo.
*/
// supply weapons.
set_task( 0.5, "GiveWeapons");
// When initialization is complete - indicate "running" state,
g_survivormode = 2;
g_roundfrags = 0;
}
else if(g_survivormode==2) {
/*
* Mode is active. We're in the middle of the round.
* Ensure there is only one survivor.
*/
new PlayersNum = GetTeamPlayers(CS_TEAM_T);
if(PlayersNum==1) {
// all ok. 1 - as desired.
// Nothing to do here.
}
else if(PlayersNum==0) {
// We are in the middle of the round.
// No survivor detected.
// Create new one.
// Transfer random player to survivor team.
new Tmp = get_playersnum();
if(Tmp) {
Tmp = (Tmp>1) ? random_num(1, Tmp) : 1;
}
else {
// No players online. Skipping.
return PLUGIN_HANDLED;
}
g_survivor_user = PrepareSurvivor(Tmp, 0);
}
else if(PlayersNum>1) {
// more than 1 members in survivor team.
// Re-transfer unexpected.
}
}
/*
* Only 100% pure code here.
* It runs always, if mode is active.
* Try to avoid this section.
*/
return PLUGIN_HANDLED;
}
/**
* This function fires on every round ends(one team wins or roundtime=0).
*
*/
public eventOnRoundEnd() {
if(g_survivenextround) {
g_survivormode = g_survivormode ? 11 : 1;
g_survivenextround = false;
}
g_roundend = true;
if(g_survivormode==0) {
/**
* Survivor mode is disabled in next round.
*/
return PLUGIN_HANDLED;
}
else if(g_survivormode==1) {
/**
* Some initialization, before next round starts in survivor mode.
* This is a good point to transfer players to specific teams - so they spawns where they should.
*/
//g_survivor_user = g_survivor_user_next;
//g_survivor_user_next = 0;
PrepareEnemy();
// PrepareSurvivor AFTER PrepareEnemy ONLY!
g_survivor_user = PrepareSurvivor(g_survivor_user_next, 0);
if(!g_survivor_user) {
// Indicate round end(rollback) & exec.
g_survivormode = 2;
eventOnRoundEnd();
return PLUGIN_HANDLED;
}
}
else if(g_survivormode==2) {
/*
* Survivor mode round is finished.
* Next round is normal.
* Rollback & reset values here.
*/
// Post-round notification.
set_hudmessage(90, 240, 100, -1.0, 0.4);
show_hudmessage(0, "%L", LANG_PLAYER, "ROUNDEND_ALL", g_roundfrags);
// Restore previous teams balance.
Rollback();
// indicate mode is disabled & reset values.
g_survivormode = 0;
g_survivor_user = 0;
}
else if(g_survivormode==11) {
g_survivormode = 1;
// Post-round notification.
set_hudmessage(90, 240, 100, -1.0, 0.4);
show_hudmessage(0, "%L", LANG_PLAYER, "ROUNDEND_ALL", g_roundfrags);
// Prepare next survivor.
g_survivor_user = PrepareSurvivor(g_survivor_user, g_survivor_user_next);
if(!g_survivor_user) {
// Indicate round end & call function.
g_survivormode = 2;
eventOnRoundEnd();
return PLUGIN_HANDLED;
}
}
/*
* Only 100% pure code here.
* It runs always, if mode is active.
* Try to avoid this section.
*/
return PLUGIN_HANDLED;
}
/**
* Supply all players with specified weapons.
* This functions must be called every time new round begins.
*/
public GiveWeapons() {
new CsTeams:Team;
new Players[g_maxusers];
new PlayersNum, i, Index;
get_players(Players, PlayersNum);
set_hudmessage(255, 125, 125, -1.0, 0.4);
for(i=0; i<PlayersNum; i++) {
Index = Players[i];
// supply specifiec weapon & ammo.
Team = CsTeams:cs_get_user_team(Index);
// strip all weapons.
//strip_user_weapons(Index);
// general items for all.
//give_item(Index, "weapon_knife");
// specific items.
if(Team==CS_TEAM_T) {
give_item(Index, "weapon_awp");
engclient_cmd(Index, "weapon_awp");
set_hudmessage(125, 125, 255, -1.0, 0.4);
show_hudmessage(Index, "%L", get_user_userid(Index), "ROUNDSTART_SURVIVOR");
set_hudmessage(255, 125, 125,-1.0, 0.4);
}
else if(Team==CS_TEAM_CT) {
engclient_cmd(Index, "weapon_knife");
show_hudmessage(Index, "%L", get_user_userid(Index), "ROUNDSTART_ENEMIES");
}
//engclient_cmd(g_challenger, "weapon_knife")
}
return 0;
}
/**
* Restore previous players teams positions.
*
*/
public Rollback() {
new CsTeams:Team;
new Players[g_maxusers];
new PlayersNum, i, Index;
get_players(Players, PlayersNum);
for(i=0; i<PlayersNum; i++) {
Index = Players[i];
/*
* We need to re-transfer only those, who goes to T team.
* Not touching CT, as they are in CT team already.
*/
// Restore previous player team.
// Avoid re-transfering from current player's team to current.
Team = g_teams[Index];
if(Team != CsTeams:cs_get_user_team(Index))
Transfer2Team(Index, Team);
}
return 0;
}
/**
* Transfers players from one team to another.
*
* @param Index User index(1-32) to apply transaction on.
* @param Team Available values:
CS_TEAM_T
CS_TEAM_CT
CS_TEAM_SPECTATOR
*/
public Transfer2Team(Index, CsTeams:Team) {
// TODO.
// SIGNIFICANT TEAM MODEL selection.
cs_set_user_team(Index, Team);
}
/**
* Prepare enemies. Moves players to single team(CT).
*
* @return 0 Success. All ok.
* @return >0 Error. Any positive value is actual error code.
*/
public PrepareEnemy() {
/*
* Transfer all players to enemy-team(CT).
*/
// prepare enemies.
new CsTeams:Team;
new Players[g_maxusers];
new PlayersNum, i, Index;
get_players(Players, PlayersNum);
for(i=0; i<PlayersNum; i++) {
Index = Players[i];
// Save current player team.
Team = CsTeams:cs_get_user_team(Index);
g_teams[Index] = Team;
switch(Team) {
case CS_TEAM_T:
// Prevent survivor from transfering to enemy-team(CT).
if(Index==g_survivor_user_next)
continue;
case CS_TEAM_CT:
// there is no need to transfer CT to CT(enemy-team).
continue;
case CS_TEAM_SPECTATOR:
// leave spectators alone :)
continue;
}
// transfer current player to enemy-team.
Transfer2Team(Index, CS_TEAM_CT);
}
return 0;
}
/**
* Check is specified player is ok(connected), and transfers it to T team, if required.
*
* @param Index Player index(1-32).
* @return false Error. Player with index specified is a bad choice.
* @return true Ok. Player is ok(re-transfered to T team if required).
*/
public PlayerIsGoodSurvivor(Index) {
if(!is_user_connected(Index))
return false;
switch(cs_get_user_team(Index)){
case CS_TEAM_T:
return true;
case CS_TEAM_CT:
Transfer2Team(Index, CS_TEAM_T);
case CS_TEAM_SPECTATOR:
return false;
}
return true;
}
/**
* Prepares survivor as well.
* Also tries to select random survivor if PlayerIndex is incorrect.
*
* @param PlayerIndex Index of player to survive.
* @param NewPlayerIndex If not 0 - function runs in swap mode. Swapping 2 players with each other(remove previous survivor, set new one).
*
* @return 0 Failed.
* @return >0 Actual survivor index.
*/
public PrepareSurvivor(PlayerIndex, NewPlayerIndex) {
/*
* Transfer survivor to it's team(T) alone.
*/
if(NewPlayerIndex) {
if(PlayerIndex != NewPlayerIndex) {
// Re-transfer old survivor to enemy-team(CT) if new one've been successfully created.
if(PlayerIsGoodSurvivor(NewPlayerIndex))
Transfer2Team(PlayerIndex, CS_TEAM_CT);
}
return NewPlayerIndex;
}
if(PlayerIsGoodSurvivor(PlayerIndex))
return PlayerIndex;
for(new i=1 ; i<=get_playersnum() ; i++) {
if(PlayerIsGoodSurvivor(i)) {
return i;
}
}
return 0;
}
/**
* Returns total number of players in the specified team.
* TODO.
* Search for internal cstrike function.
*
* @param Team One of the following values:
CS_TEAM_T
CS_TEAM_CT
CS_TEAM_SPECTATOR
*/
public GetTeamPlayers(CsTeams:Team) {
new Res = 0;
new Players[g_maxusers];
new PlayersNum, i, Index;
get_players(Players, PlayersNum);
for(i=0; i<PlayersNum; i++) {
Index = Players[i];
if(!is_user_alive(Index))
continue;
if(Team==CsTeams:cs_get_user_team(Index))
Res++;
}
return Res;
}