├── .gitignore ├── .gitmodules ├── smbuild ├── translations ├── chi │ └── executes.phrases.txt ├── es │ └── executes.phrases.txt └── executes.phrases.txt ├── cfg └── sourcemod │ └── executes │ └── executes_game.cfg ├── .travis.yml ├── misc └── format.py ├── scripting ├── executes │ ├── find_sites.sp │ ├── loadout_pistolrounds.sp │ ├── loadout_common.sp │ ├── editor_commands.sp │ ├── loadout_forcerounds.sp │ ├── prefs_menu.sp │ ├── loadout_gunrounds.sp │ ├── natives.sp │ ├── util.sp │ ├── executes_config.sp │ ├── editor.sp │ └── editor_menus.sp ├── .clang-format └── include │ ├── queue.inc │ ├── priorityqueue.inc │ ├── restorecvars.inc │ ├── logdebug.inc │ └── executes.inc ├── README.md └── configs └── executes ├── de_dust2.cfg ├── de_nuke.cfg ├── de_train.cfg └── de_cbble.cfg /.gitignore: -------------------------------------------------------------------------------- 1 | builds 2 | *.smx 3 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "csgo-practice-mode"] 2 | path = csgo-practice-mode 3 | url = https://github.com/splewis/csgo-practice-mode 4 | -------------------------------------------------------------------------------- /smbuild: -------------------------------------------------------------------------------- 1 | Plugin(name='executes', source='scripting/executes.sp') 2 | Plugin(name='csutils', source='csgo-practice-mode/scripting/csutils.sp') 3 | 4 | Package(name='executes-base', 5 | plugins=[ 6 | 'executes', 7 | 'csutils', 8 | ] 9 | ) 10 | 11 | Package(name='executes-release', 12 | extends=['executes-base'], 13 | plugins=Plugins('executes*'), 14 | filegroups={ 15 | '.': ['LICENSE', 'README.md'], 16 | }, 17 | ) 18 | -------------------------------------------------------------------------------- /translations/chi/executes.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "JoinedQueueMessage" 4 | { 5 | "chi" "您已被放置在等待队列中。" 6 | } 7 | "WaitingQueueMessage" 8 | { 9 | "chi" "本回合的成员名单已满,共有{GREEN}{1}{NORMAL}名玩家。您当前在等待列表中。" 10 | } 11 | "ScrambleMessage" 12 | { 13 | "chi" "反恐精英已经获得了{GREEN}{1}{NORMAL}回合的胜利。{PURPLE}已随机重组队伍!" 14 | } 15 | "WinStreakAlmostToScramble" 16 | { 17 | "chi" "反恐精英已经获得了{GREEN}{1}{NORMAL}回合的胜利 —— 如果他们再次以{GREEN}{2}{PURPLE}人组合赢得本回合,那么将会随机重组队伍。" 18 | } 19 | "WinStreak" 20 | { 21 | "chi" "反恐精英已经获得了{GREEN}{1}{NORMAL}回合的胜利!" 22 | } 23 | "WinStreakOver" 24 | { 25 | "chi" "恐怖分子终结了{GREEN}{1}{NORMAL}回合的胜利——连胜局!" 26 | } 27 | "AdminScrambleTeams" 28 | { 29 | "chi" "{1}已经设置了下一回合的队伍成员名单。" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /translations/es/executes.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "JoinedQueueMessage" 4 | { 5 | "es" "Fuiste colocado en la lista de espera." 6 | } 7 | "WaitingQueueMessage" 8 | { 9 | "es" "La partida está llena con {GREEN}{1} {NORMAL}jugadores. Te encuentras en la lista de espera." 10 | } 11 | "ScrambleMessage" 12 | { 13 | "es" "Los terroristas ganaron {GREEN}{1}{NORMAL} rondas seguidas. {PURPLE}Los equipos serán mezclados!" 14 | } 15 | "WinStreakAlmostToScramble" 16 | { 17 | "es" "Los terroristas van ganando {GREEN}{1}{NORMAL} rondas seguidas - Si ganan {GREEN}{2} más, {PURPLE}los equipos serán a mezclados." 18 | } 19 | "WinStreak" 20 | { 21 | "es" "Los terroristas ganaron {GREEN}{1}{NORMAL} rondas seguidas!" 22 | } 23 | "WinStreakOver" 24 | { 25 | "es" "Los CTs habían perdido {GREEN}{1}{NORMAL} rondas, pero al fin ganaron 1." 26 | } 27 | "AdminScrambleTeams" 28 | { 29 | "es" "{1} se han establecidos los equipos para que sean mezclados en la siguiente ronda." 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /cfg/sourcemod/executes/executes_game.cfg: -------------------------------------------------------------------------------- 1 | // Things you shouldn't change: 2 | bot_kick 3 | bot_quota 0 4 | mp_autoteambalance 0 5 | mp_do_warmup_period 1 6 | mp_forcecamera 1 7 | mp_give_player_c4 0 8 | mp_halftime 0 9 | mp_ignore_round_win_conditions 0 10 | mp_join_grace_time 0 11 | mp_match_can_clinch 0 12 | mp_maxmoney 0 13 | mp_playercashawards 0 14 | mp_respawn_on_death_ct 0 15 | mp_respawn_on_death_t 0 16 | mp_teamcashawards 0 17 | mp_warmup_pausetimer 0 18 | 19 | // Things you can change, and may want to: 20 | mp_autokick 0 21 | mp_c4timer 40 22 | mp_maxrounds 20 23 | mp_solid_teammates 1 24 | mp_friendlyfire 0 25 | 26 | mp_endmatch_votenextleveltime 3 27 | mp_endmatch_votenextmap 0 28 | mp_endmatch_votenextmap_keepcurrent 0 29 | 30 | sv_talk_enemy_dead 0 31 | sv_talk_enemy_living 0 32 | sv_deadtalk 1 33 | sv_allow_votes 0 34 | spec_replay_enable 0 35 | mp_round_restart_delay 5 36 | mp_freezetime 8 37 | 38 | // ESL deathcam settings 39 | spec_freeze_deathanim_time 0 40 | spec_freeze_panel_extended_time 0 41 | spec_freeze_time 2 42 | spec_freeze_time_lock 2 43 | -------------------------------------------------------------------------------- /translations/executes.phrases.txt: -------------------------------------------------------------------------------- 1 | "Phrases" 2 | { 3 | "JoinedQueueMessage" 4 | { 5 | "en" "You have been placed in the waiting queue." 6 | } 7 | "WaitingQueueMessage" 8 | { 9 | "#format" "{1:i}" 10 | "en" "The game is currently full with {GREEN}{1} {NORMAL}players. You are in the waiting queue." 11 | } 12 | "ScrambleMessage" 13 | { 14 | "#format" "{1:d}" 15 | "en" "The CTs won {GREEN}{1}{NORMAL} rounds in a row. {PURPLE}Teams are being scrambled!" 16 | } 17 | "WinStreakAlmostToScramble" 18 | { 19 | "#format" "{1:d},{2:d}" 20 | "en" "The CTs have won {GREEN}{1}{NORMAL} rounds in a row - if they win {GREEN}{2} more, {PURPLE}teams will be scrambled." 21 | } 22 | "WinStreak" 23 | { 24 | "#format" "{1:d}" 25 | "en" "The CTs have won {GREEN}{1}{NORMAL} rounds in a row!" 26 | } 27 | "WinStreakOver" 28 | { 29 | "#format" "{1:d}" 30 | "en" "The terrorists have ended a {GREEN}{1}{NORMAL}-round long win streak!" 31 | } 32 | "AdminScrambleTeams" 33 | { 34 | "#format" "{1:N}" 35 | "en" "{1} has set the teams to be scrambled next round." 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | 3 | addons: 4 | apt_packages: 5 | - lib32stdc++6 # needed for spcomp 6 | 7 | env: 8 | - SMVERSION=1.9 9 | 10 | before_script: 11 | # install smbuilder 12 | - git clone https://github.com/splewis/sm-builder 13 | - cd sm-builder 14 | - pip install --user -r requirements.txt 15 | - python setup.py install --prefix=~/.local 16 | - cd .. 17 | 18 | # install the sourcemod compiler 19 | - SMPACKAGE="http://sourcemod.net/latest.php?os=linux&version=${SMVERSION}" 20 | - wget $SMPACKAGE 21 | - tar xfz $(basename $SMPACKAGE) 22 | - cd addons/sourcemod/scripting/ 23 | - chmod +x spcomp 24 | - PATH+=":$PWD" 25 | 26 | # install smlib 27 | - cd include 28 | - git clone https://github.com/bcserv/smlib 29 | - cp -r smlib/scripting/include/* . 30 | 31 | # get pugsetup include 32 | - wget https://raw.githubusercontent.com/splewis/csgo-pug-setup/master/scripting/include/pugsetup.inc 33 | 34 | # get botmimic include 35 | - wget https://raw.githubusercontent.com/peace-maker/botmimic/master/scripting/include/botmimic.inc 36 | 37 | - cd ../../../.. 38 | 39 | script: 40 | - smbuilder --flags="-E" 41 | -------------------------------------------------------------------------------- /misc/format.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | 3 | import os 4 | import subprocess 5 | 6 | 7 | replacements = { 8 | '\npublic\n' : '\npublic ', 9 | 'any : ...' : 'any:...', 10 | '% 1' : '%1', 11 | } 12 | 13 | 14 | def main(): 15 | root_path, _ = os.path.split(os.path.dirname(os.path.realpath(__file__))) 16 | scripting_path = os.path.join(root_path, 'scripting') 17 | files = [] 18 | for (dirpath, dirnames, filenames) in os.walk(scripting_path): 19 | for f in filenames: 20 | if '.inc' in f or '.sp' in f: 21 | files.append(os.path.join(dirpath, f)) 22 | 23 | for filename in files: 24 | subprocess.call('clang-format-3.9 -i {}'.format(filename), shell=True) 25 | with open(filename, 'r+') as f: 26 | data = f.read() 27 | for (k, v) in replacements.items(): 28 | data = data.replace(k, v) 29 | 30 | # Trick of a hack so the 1st line of files also don't split 31 | # public onto a single line. The normal replacement doesn't work 32 | # since it assumes a blank line in front of it. 33 | if data.startswith('public\n'): 34 | data = data.replace('public\n', 'public ', 1) 35 | 36 | f.seek(0) 37 | f.write(data) 38 | f.truncate() 39 | 40 | 41 | main() 42 | -------------------------------------------------------------------------------- /scripting/executes/find_sites.sp: -------------------------------------------------------------------------------- 1 | // ======================================================================== 2 | // Thanks to exvel - http://forums.alliedmods.net/showthread.php?p=1287116 3 | // Provided the GetBombsitesIndexes() and tock bool:IsVecBetween 4 | // ======================================================================== 5 | stock void GetBombSitesIndexes() { 6 | int index = -1; 7 | 8 | float vecBombsiteCenterA[3]; 9 | float vecBombsiteCenterB[3]; 10 | 11 | index = FindEntityByClassname(index, "cs_player_manager"); 12 | if (IsValidEntity(index)) { 13 | GetEntPropVector(index, Prop_Send, "m_bombsiteCenterA", vecBombsiteCenterA); 14 | GetEntPropVector(index, Prop_Send, "m_bombsiteCenterB", vecBombsiteCenterB); 15 | } else { 16 | LogError("Failed to find cs_player_manager"); 17 | return; 18 | } 19 | 20 | index = -1; 21 | while ((index = FindEntityByClassname(index, "func_bomb_target")) != -1) { 22 | float vecBombsiteMin[3]; 23 | float vecBombsiteMax[3]; 24 | 25 | GetEntPropVector(index, Prop_Send, "m_vecMins", vecBombsiteMin); 26 | GetEntPropVector(index, Prop_Send, "m_vecMaxs", vecBombsiteMax); 27 | 28 | if (IsVecBetween(vecBombsiteCenterA, vecBombsiteMin, vecBombsiteMax)) { 29 | g_BombSiteAIndex = index; 30 | } 31 | if (IsVecBetween(vecBombsiteCenterB, vecBombsiteMin, vecBombsiteMax)) { 32 | g_BombSiteBIndex = index; 33 | } 34 | } 35 | } 36 | 37 | stock bool IsVecBetween(float vecVector[3], float vecMin[3], float vecMax[3]) { 38 | return ((vecMin[0] <= vecVector[0] <= vecMax[0]) && (vecMin[1] <= vecVector[1] <= vecMax[1]) && 39 | (vecMin[2] <= vecVector[2] <= vecMax[2])); 40 | } 41 | -------------------------------------------------------------------------------- /scripting/executes/loadout_pistolrounds.sp: -------------------------------------------------------------------------------- 1 | public void PistolRounds_Assign(ArrayList tPlayers, ArrayList ctPlayers, Bombsite site) { 2 | for (int i = 0; i < tPlayers.Length; i++) { 3 | AssignT(tPlayers.Get(i)); 4 | } 5 | 6 | for (int i = 0; i < ctPlayers.Length; i++) { 7 | AssignCT(ctPlayers.Get(i)); 8 | } 9 | } 10 | 11 | static void AssignCT(int client) { 12 | g_PlayerKit[client] = false; 13 | g_PlayerArmor[client] = 100; 14 | g_PlayerHelmet[client] = false; 15 | g_PlayerPrimary[client] = ""; 16 | g_PlayerSecondary[client] = "weapon_hkp2000"; 17 | 18 | if (Chance(0.2)) { 19 | g_PlayerKit[client] = true; 20 | g_PlayerArmor[client] = 0; 21 | if (Chance(0.5)) 22 | g_PlayerNades[client] = "s"; 23 | else 24 | g_PlayerNades[client] = "ff"; 25 | } 26 | } 27 | 28 | static void AssignT(int client) { 29 | int spawn = g_SpawnIndices[client]; 30 | bool throwingSetNade = IsGrenade(g_SpawnGrenadeTypes[spawn]); 31 | 32 | g_PlayerArmor[client] = 100; 33 | g_PlayerHelmet[client] = false; 34 | g_PlayerPrimary[client] = ""; 35 | g_PlayerSecondary[client] = "weapon_glock"; 36 | 37 | if (throwingSetNade) { 38 | g_PlayerArmor[client] = 0; 39 | float f = GetRandomFloat(); 40 | if (f < 0.30) { 41 | g_PlayerSecondary[client] = "weapon_glock"; 42 | g_PlayerNades[client] = "ff"; 43 | 44 | } else if (f < 0.6) { 45 | g_PlayerSecondary[client] = "weapon_glock"; 46 | g_PlayerNades[client] = ""; 47 | 48 | } else if (f < 0.8) { 49 | GiveUpgradedSecondary(client, CS_TEAM_T); 50 | g_PlayerNades[client] = ""; 51 | 52 | } else { 53 | g_PlayerSecondary[client] = "weapon_p250"; 54 | g_PlayerNades[client] = "f"; 55 | } 56 | 57 | if (Chance(0.7)) { 58 | g_PlayerArmor[client] = 100; 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /scripting/executes/loadout_common.sp: -------------------------------------------------------------------------------- 1 | stock void AssignRandomNades(int client, int strength = 1) { 2 | char buffer[NADE_STRING_LENGTH]; 3 | int idx = 0; 4 | while (strength > 0) { 5 | char c = RandomNade(); 6 | buffer[idx] = c; 7 | strength -= NadeStrength(c); 8 | idx++; 9 | } 10 | buffer[idx] = '\0'; 11 | 12 | g_PlayerNades[client] = buffer; 13 | } 14 | 15 | public int NadeStrength(char c) { 16 | switch (c) { 17 | case 'f': 18 | return 1; 19 | case 'h': 20 | return 1; 21 | case 's': 22 | return 2; 23 | case 'i': 24 | return 2; 25 | case 'm': 26 | return 2; 27 | } 28 | return 0; 29 | } 30 | 31 | public char RandomNade() { 32 | float f = GetRandomFloat(); 33 | if (f < 0.5) { 34 | // TODO: why the view_as here? 35 | return view_as('f'); 36 | } else if (f < 0.55) { 37 | return view_as('h'); 38 | } else if (f < 0.8) { 39 | return view_as('s'); 40 | } else { 41 | return view_as('m'); 42 | } 43 | } 44 | 45 | public void SetPrimaryRifle(int client, int team) { 46 | if (team == CS_TEAM_CT) { 47 | if (g_CTRifle[client] == CTRiflePref_M4) { 48 | g_PlayerPrimary[client] = "weapon_m4a1"; 49 | } else if (g_CTRifle[client] == CTRiflePref_Silenced_M4) { 50 | g_PlayerPrimary[client] = "weapon_m4a1_silencer"; 51 | } else { 52 | g_PlayerPrimary[client] = "weapon_aug"; 53 | } 54 | } else { 55 | if (g_TRifle[client] == TRiflePref_Ak) { 56 | g_PlayerPrimary[client] = "weapon_ak47"; 57 | } else { 58 | g_PlayerPrimary[client] = "weapon_sg556"; 59 | } 60 | } 61 | } 62 | 63 | public void GiveUpgradedSecondary(int client, int team) { 64 | if (team == CS_TEAM_CT) { 65 | if (g_DFCTSide[client]) { 66 | g_PlayerSecondary[client] = "weapon_deagle"; 67 | } else { 68 | g_PlayerSecondary[client] = "weapon_fiveseven"; 69 | } 70 | } else { 71 | if (g_DTTSide[client]) { 72 | g_PlayerSecondary[client] = "weapon_deagle"; 73 | } else { 74 | g_PlayerSecondary[client] = "weapon_tec9"; 75 | } 76 | } 77 | } 78 | 79 | public void AddNade(int client, const char[] nade) { 80 | if (!StrContains(g_PlayerNades[client], nade)) { 81 | StrCat(g_PlayerNades[client], NADE_STRING_LENGTH, nade); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /scripting/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | # BasedOnStyle: Google 4 | AccessModifierOffset: -1 5 | AlignAfterOpenBracket: true 6 | AlignConsecutiveAssignments: false 7 | AlignEscapedNewlinesLeft: true 8 | AlignOperands: true 9 | AlignTrailingComments: true 10 | AllowAllParametersOfDeclarationOnNextLine: true 11 | AllowShortBlocksOnASingleLine: false 12 | AllowShortCaseLabelsOnASingleLine: false 13 | AllowShortFunctionsOnASingleLine: Empty 14 | AllowShortIfStatementsOnASingleLine: false 15 | AllowShortLoopsOnASingleLine: false 16 | AlwaysBreakAfterDefinitionReturnType: None 17 | AlwaysBreakBeforeMultilineStrings: false 18 | AlwaysBreakTemplateDeclarations: true 19 | BinPackArguments: true 20 | BinPackParameters: true 21 | BreakBeforeBinaryOperators: None 22 | BreakBeforeBraces: Attach 23 | BreakBeforeTernaryOperators: true 24 | BreakConstructorInitializersBeforeComma: false 25 | BreakStringLiterals: false 26 | ColumnLimit: 100 27 | CommentPragmas: '^ IWYU pragma:' 28 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 29 | ConstructorInitializerIndentWidth: 4 30 | ContinuationIndentWidth: 4 31 | Cpp11BracedListStyle: true 32 | DerivePointerAlignment: true 33 | DisableFormat: false 34 | ExperimentalAutoDetectBinPacking: false 35 | ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] 36 | IndentCaseLabels: true 37 | IndentWidth: 2 38 | IndentWrappedFunctionNames: false 39 | KeepEmptyLinesAtTheStartOfBlocks: false 40 | MacroBlockBegin: '' 41 | MacroBlockEnd: '' 42 | MaxEmptyLinesToKeep: 1 43 | NamespaceIndentation: None 44 | ObjCBlockIndentWidth: 2 45 | ObjCSpaceAfterProperty: false 46 | ObjCSpaceBeforeProtocolList: false 47 | PenaltyBreakBeforeFirstCallParameter: 1 48 | PenaltyBreakComment: 300 49 | PenaltyBreakFirstLessLess: 120 50 | PenaltyBreakString: 100000000 51 | PenaltyExcessCharacter: 1000000 52 | PenaltyReturnTypeOnItsOwnLine: 200 53 | PointerAlignment: Left 54 | SpaceAfterCStyleCast: false 55 | SpaceBeforeAssignmentOperators: true 56 | SpaceBeforeParens: ControlStatements 57 | SpaceInEmptyParentheses: false 58 | SpacesBeforeTrailingComments: 2 59 | SpacesInAngles: false 60 | SpacesInContainerLiterals: true 61 | SpacesInCStyleCastParentheses: false 62 | SpacesInParentheses: false 63 | SpacesInSquareBrackets: false 64 | Standard: Auto 65 | TabWidth: 8 66 | UseTab: Never 67 | ... 68 | -------------------------------------------------------------------------------- /scripting/include/queue.inc: -------------------------------------------------------------------------------- 1 | #if defined _queue_included 2 | #endinput 3 | #endif 4 | #define _queue_included 5 | 6 | /** 7 | * Initializes the queue and returns a new handle to it that must be closed. 8 | */ 9 | stock ArrayList Queue_Init() { 10 | ArrayList queueHandle = new ArrayList(); 11 | return queueHandle; 12 | } 13 | 14 | /** 15 | * Push a Client to the end of the Queue (don't add a client if already in queue). 16 | */ 17 | stock void Queue_Enqueue(ArrayList queueHandle, int client) { 18 | if (Queue_Find(queueHandle, client) == -1) 19 | queueHandle.Push(client); 20 | } 21 | 22 | stock void Queue_EnqueueFront(ArrayList queueHandle, int client) { 23 | if (Queue_Find(queueHandle, client) != -1) 24 | return; 25 | 26 | if (queueHandle.Length == 0) { 27 | Queue_Enqueue(queueHandle, client); 28 | } else { 29 | queueHandle.ShiftUp(0); 30 | queueHandle.Set(0, client); 31 | } 32 | } 33 | 34 | /** 35 | * Finds a client in the Queue and returns their index. 36 | */ 37 | stock int Queue_Find(ArrayList queueHandle, int client) { 38 | return queueHandle.FindValue(client); 39 | } 40 | 41 | /** 42 | * Drops a client from the Queue. 43 | */ 44 | stock void Queue_Drop(ArrayList queueHandle, int client) { 45 | int index = Queue_Find(queueHandle, client); 46 | if (index != -1) 47 | queueHandle.Erase(index); 48 | } 49 | 50 | /** 51 | * Get queue length, does not validate clients in queue. 52 | */ 53 | stock int Queue_Length(ArrayList queueHandle) { 54 | return queueHandle.Length; 55 | } 56 | 57 | /** 58 | * Test if queue is empty. 59 | */ 60 | stock bool Queue_IsEmpty(ArrayList queueHandle) { 61 | return Queue_Length(queueHandle) == 0; 62 | } 63 | 64 | /** 65 | * Peeks the head of the queue. 66 | */ 67 | stock int Queue_Peek(ArrayList queueHandle) { 68 | return queueHandle.Get(0); 69 | } 70 | 71 | /** 72 | * Fetch next client from queue. 73 | */ 74 | stock int Queue_Dequeue(ArrayList queueHandle) { 75 | int val = Queue_Peek(queueHandle); 76 | queueHandle.Erase(0); 77 | return val; 78 | } 79 | 80 | /** 81 | * Clears all entires in a queue. 82 | */ 83 | stock void Queue_Clear(ArrayList queueHandle) { 84 | queueHandle.Clear(); 85 | } 86 | 87 | /** 88 | * Closes the handle for the queue. 89 | */ 90 | stock void Queue_Destroy(ArrayList queueHandle) { 91 | delete queueHandle; 92 | } 93 | -------------------------------------------------------------------------------- /scripting/executes/editor_commands.sp: -------------------------------------------------------------------------------- 1 | public Action Command_EditSpawns(int client, int args) { 2 | if (g_hEditorEnabled.IntValue == 0) { 3 | Executes_Message(client, "The editor is currently disabled."); 4 | return Plugin_Handled; 5 | } 6 | 7 | BreakBreakableEntities(); 8 | if (!g_EditMode) { 9 | StartEditMode(); 10 | } 11 | 12 | GiveEditorMenu(client); 13 | 14 | return Plugin_Handled; 15 | } 16 | 17 | public Action Command_Name(int client, int args) { 18 | if (!g_EditMode) 19 | return Plugin_Handled; 20 | 21 | if (args >= 1 && GetCmdArgString(g_TempNameBuffer, sizeof(g_TempNameBuffer))) { 22 | if (g_EditingExecutes) { 23 | GiveNewExecuteMenu(client); 24 | } else { 25 | GiveNewSpawnMenu(client); 26 | } 27 | } else { 28 | Executes_Message(client, "Usage: !setname "); 29 | } 30 | 31 | return Plugin_Handled; 32 | } 33 | 34 | public Action Command_GotoSpawn(int client, int args) { 35 | if (g_hEditorEnabled.IntValue == 0) { 36 | Executes_Message(client, "The editor is currently disabled."); 37 | return Plugin_Handled; 38 | } 39 | 40 | if (!g_EditMode) { 41 | Executes_Message(client, "You are not in edit mode."); 42 | return Plugin_Handled; 43 | } 44 | 45 | char buffer[32]; 46 | if (args >= 1 && GetCmdArg(1, buffer, sizeof(buffer))) { 47 | int spawn = SpawnIdToIndex(buffer); 48 | if (IsValidSpawn(spawn)) { 49 | MoveToSpawnInEditor(client, spawn); 50 | } 51 | } 52 | 53 | return Plugin_Handled; 54 | } 55 | 56 | public Action Command_GotoNearestSpawn(int client, int args) { 57 | if (g_hEditorEnabled.IntValue == 0) { 58 | Executes_Message(client, "The editor is currently disabled."); 59 | return Plugin_Handled; 60 | } 61 | 62 | if (!g_EditMode) { 63 | Executes_Message(client, "You are not in edit mode."); 64 | return Plugin_Handled; 65 | } 66 | 67 | int spawn = FindClosestSpawn(client); 68 | if (IsValidSpawn(spawn)) { 69 | MoveToSpawnInEditor(client, spawn); 70 | } 71 | 72 | return Plugin_Handled; 73 | } 74 | 75 | public Action Command_NextSpawn(int client, int args) { 76 | if (g_hEditorEnabled.IntValue == 0) { 77 | Executes_Message(client, "The editor is currently disabled."); 78 | return Plugin_Handled; 79 | } 80 | 81 | if (!g_EditMode) { 82 | Executes_Message(client, "You are not in edit mode."); 83 | return Plugin_Handled; 84 | } 85 | 86 | int spawn = g_EditingSpawnIndex + 1; 87 | while (!IsValidSpawn(spawn) && spawn < MAX_SPAWNS) { 88 | spawn++; 89 | } 90 | 91 | if (IsValidSpawn(spawn)) { 92 | EditSpawn(client, spawn); 93 | } else { 94 | g_EditingSpawnIndex = 0; 95 | } 96 | 97 | return Plugin_Handled; 98 | } 99 | -------------------------------------------------------------------------------- /scripting/include/priorityqueue.inc: -------------------------------------------------------------------------------- 1 | #if defined _priorityqueue_included 2 | #endinput 3 | #endif 4 | #define _priorityqueue_included 5 | 6 | /** 7 | * Initializes the queue and returns a handle to it that must be closed. 8 | */ 9 | stock ArrayList PQ_Init() { 10 | ArrayList queueHandle = new ArrayList(2); 11 | return queueHandle; 12 | } 13 | 14 | /** 15 | * Adds a player and a value to the queue. 16 | * If the player is already in the queue, their score is updated in place. 17 | */ 18 | stock void PQ_Enqueue(ArrayList queueHandle, int client, int value) { 19 | int index = PQ_FindClient(queueHandle, client); 20 | 21 | // if they're not already in, put them at the end 22 | if (index == -1) { 23 | index = queueHandle.Length; 24 | queueHandle.Push(client); 25 | queueHandle.Set(index, client, 0); 26 | } 27 | 28 | // set their value 29 | queueHandle.Set(index, value, 1); 30 | } 31 | 32 | /** 33 | * Selects the player with the max value in the queue and removes them, returning their client 34 | * index. 35 | */ 36 | stock int PQ_Dequeue(ArrayList queueHandle) { 37 | int maxIndex = -1; 38 | int maxClient = -1; 39 | int maxScore = -1; 40 | 41 | for (int i = 0; i < queueHandle.Length; i++) { 42 | int client = queueHandle.Get(i, 0); 43 | int score = queueHandle.Get(i, 1); 44 | if (maxIndex == -1 || score > maxScore) { 45 | maxIndex = i; 46 | maxClient = client; 47 | maxScore = score; 48 | } 49 | } 50 | if (maxIndex != -1) { 51 | queueHandle.Erase(maxIndex); 52 | } 53 | return maxClient; 54 | } 55 | 56 | /** 57 | * Finds an index of the client in the queue. Returns -1 if the client isn't in it. 58 | */ 59 | stock int PQ_FindClient(ArrayList queueHandle, int client) { 60 | for (int i = 0; i < queueHandle.Length; i++) { 61 | int c = queueHandle.Get(i, 0); 62 | if (client == c) 63 | return i; 64 | } 65 | return -1; 66 | } 67 | 68 | /** 69 | * Drops a client from the queue completely. 70 | */ 71 | stock void PQ_DropFromQueue(ArrayList queueHandle, int client) { 72 | int index = PQ_FindClient(queueHandle, client); 73 | if (index != -1) 74 | queueHandle.Erase(index); 75 | } 76 | 77 | /** 78 | * Returns the current size of the queue. 79 | */ 80 | stock int PQ_GetSize(ArrayList queueHandle) { 81 | return queueHandle.Length; 82 | } 83 | 84 | /** 85 | * Returns is the queu is empty. 86 | */ 87 | stock bool PQ_IsEmpty(ArrayList queueHandle) { 88 | return PQ_GetSize(queueHandle) == 0; 89 | } 90 | 91 | /** 92 | * Clears all entires in a queue. 93 | */ 94 | stock void PQ_Clear(ArrayList queueHandle) { 95 | queueHandle.Clear(); 96 | } 97 | 98 | /** 99 | * Clears the Handle for a queue. 100 | */ 101 | stock void PQ_Destroy(ArrayList queueHandle) { 102 | delete queueHandle; 103 | } 104 | -------------------------------------------------------------------------------- /scripting/include/restorecvars.inc: -------------------------------------------------------------------------------- 1 | #define CVAR_NAME_MAX_LENGTH 255 2 | #define CVAR_VALUE_MAX_LENGTH 255 3 | 4 | // Returns a cvar Handle that can be used to restore cvars. 5 | stock ArrayList SaveCvars(ArrayList cvarNames) { 6 | ArrayList storageList = new ArrayList(); 7 | ArrayList cvarNameList = new ArrayList(CVAR_NAME_MAX_LENGTH); 8 | ArrayList cvarValueList = new ArrayList(CVAR_VALUE_MAX_LENGTH); 9 | 10 | char nameBuffer[CVAR_NAME_MAX_LENGTH]; 11 | char valueBuffer[CVAR_VALUE_MAX_LENGTH]; 12 | for (int i = 0; cvarNames != null && i < cvarNames.Length; i++) { 13 | cvarNames.GetString(i, nameBuffer, sizeof(nameBuffer)); 14 | 15 | ConVar cvar = FindConVar(nameBuffer); 16 | if (cvar != null) { 17 | cvar.GetString(valueBuffer, sizeof(valueBuffer)); 18 | cvarNameList.PushString(nameBuffer); 19 | cvarValueList.PushString(valueBuffer); 20 | } 21 | } 22 | 23 | storageList.Push(cvarNameList); 24 | storageList.Push(cvarValueList); 25 | return storageList; 26 | } 27 | 28 | // Restores cvars to their previous value using a return value of SaveCvars. 29 | stock void RestoreCvars(ArrayList &cvarStorage, bool close = false) { 30 | ArrayList cvarNameList = view_as(cvarStorage.Get(0)); 31 | ArrayList cvarValueList = view_as(cvarStorage.Get(1)); 32 | 33 | char name[CVAR_NAME_MAX_LENGTH]; 34 | char value[CVAR_VALUE_MAX_LENGTH]; 35 | for (int i = 0; i < cvarNameList.Length; i++) { 36 | cvarNameList.GetString(i, name, sizeof(name)); 37 | cvarValueList.GetString(i, value, sizeof(value)); 38 | 39 | ConVar cvar = FindConVar(name); 40 | if (cvar != null) { 41 | cvar.SetString(value); 42 | } 43 | } 44 | 45 | if (close) { 46 | CloseCvarStorage(cvarStorage); 47 | } 48 | } 49 | 50 | // Closes a cvar storage object returned by SaveCvars. 51 | stock void CloseCvarStorage(ArrayList &cvarStorage) { 52 | delete view_as(cvarStorage.Get(0)); 53 | delete view_as(cvarStorage.Get(1)); 54 | delete cvarStorage; 55 | cvarStorage = null; 56 | } 57 | 58 | // Returns the first "word" in a line, as seperated by whitespace. 59 | stock bool __firstWord(const char[] line, char[] buffer, int len) { 60 | char[] lineBuffer = new char[strlen(line)]; 61 | strcopy(lineBuffer, strlen(line), line); 62 | TrimString(lineBuffer); 63 | int splitIndex = StrContains(line, " "); 64 | if (splitIndex == -1) 65 | splitIndex = StrContains(line, "\t"); 66 | 67 | if (splitIndex == -1) { 68 | Format(buffer, len, ""); 69 | return false; 70 | } 71 | 72 | int destLen = splitIndex + 1; 73 | if (destLen > len) 74 | destLen = len; 75 | 76 | strcopy(buffer, destLen, lineBuffer); 77 | return true; 78 | } 79 | 80 | // Wrapper for SetCvars from an arbitrary file. 81 | // Returns if successful. 82 | stock ArrayList ExecuteAndSaveCvars(const char[] cfgFile) { 83 | char lineBuffer[CVAR_NAME_MAX_LENGTH + CVAR_VALUE_MAX_LENGTH]; 84 | char nameBuffer[CVAR_NAME_MAX_LENGTH]; 85 | 86 | char filePath[PLATFORM_MAX_PATH]; 87 | Format(filePath, sizeof(filePath), "cfg/%s", cfgFile); 88 | 89 | File file = OpenFile(filePath, "r"); 90 | if (file != null) { 91 | ArrayList nameList = new ArrayList(CVAR_NAME_MAX_LENGTH); 92 | 93 | while (!file.EndOfFile() && file.ReadLine(lineBuffer, sizeof(lineBuffer))) { 94 | if (__firstWord(lineBuffer, nameBuffer, sizeof(nameBuffer))) { 95 | TrimString(nameBuffer); 96 | nameList.PushString(nameBuffer); 97 | } 98 | } 99 | 100 | ArrayList ret = SaveCvars(nameList); 101 | ServerCommand("exec %s", cfgFile); 102 | delete nameList; 103 | delete file; 104 | return ret; 105 | } else { 106 | LogError("Failed to open file for reading: %s", filePath); 107 | return null; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /scripting/executes/loadout_forcerounds.sp: -------------------------------------------------------------------------------- 1 | public void ForceRounds_Assign(ArrayList tPlayers, ArrayList ctPlayers, Bombsite site) { 2 | for (int i = 0; i < tPlayers.Length; i++) { 3 | AssignT(tPlayers.Get(i)); 4 | } 5 | 6 | for (int i = 0; i < ctPlayers.Length; i++) { 7 | AssignCT(ctPlayers.Get(i)); 8 | } 9 | } 10 | 11 | static void AssignCT(int client) { 12 | int spawn = g_SpawnIndices[client]; 13 | g_PlayerHelmet[client] = Chance(0.5); 14 | g_PlayerKit[client] = Chance(0.6); 15 | 16 | AssignCTNades(client, spawn); 17 | 18 | if (client == g_CTAwper) { 19 | g_PlayerPrimary[client] = "weapon_ssg08"; 20 | g_PlayerSecondary[client] = "weapon_p250"; 21 | 22 | } else { 23 | float f = GetRandomFloat(); 24 | if (f < 0.1) { 25 | g_PlayerPrimary[client] = "weapon_famas"; 26 | AssignRandomNades(client, 1); 27 | 28 | } else if (f < 0.2) { 29 | g_PlayerPrimary[client] = "weapon_mp9"; 30 | AssignRandomNades(client, 2); 31 | 32 | } else if (f < 0.3) { 33 | g_PlayerSecondary[client] = "weapon_deagle"; 34 | AssignRandomNades(client, 2); 35 | 36 | } else if (f < 0.4) { 37 | SetPrimaryRifle(client, CS_TEAM_CT); 38 | AssignRandomNades(client, 0); 39 | 40 | } else if (f < 0.5) { 41 | GiveUpgradedSecondary(client, CS_TEAM_CT); 42 | AssignRandomNades(client, 2); 43 | 44 | } else if (f < 0.6) { 45 | GiveUpgradedSecondary(client, CS_TEAM_CT); 46 | AssignRandomNades(client, 1); 47 | 48 | } else if (f < 0.7) { 49 | g_PlayerPrimary[client] = "weapon_famas"; 50 | AssignRandomNades(client, 2); 51 | 52 | } else if (f < 0.8) { 53 | g_PlayerPrimary[client] = "weapon_famas"; 54 | AssignRandomNades(client, 3); 55 | } else if (f < 0.87) { 56 | g_PlayerPrimary[client] = "weapon_p90"; 57 | AssignRandomNades(client, 1); 58 | 59 | } else { 60 | g_PlayerPrimary[client] = "weapon_famas"; 61 | AssignRandomNades(client, 1); 62 | } 63 | 64 | // Alternate distribution for close spawns 65 | if (g_SpawnAwpFriendly[spawn] <= 2) { 66 | f = GetRandomFloat(); 67 | if (f < 0.55) { 68 | g_PlayerPrimary[client] = "weapon_ump45"; 69 | AssignRandomNades(client, 1); 70 | } else if (f < 0.7) { 71 | g_PlayerPrimary[client] = "weapon_p90"; 72 | AssignRandomNades(client, 0); 73 | } else { 74 | g_PlayerPrimary[client] = "weapon_mp9"; 75 | AssignRandomNades(client, 2); 76 | } 77 | } 78 | 79 | if (HasFlag(spawn, SPAWNFLAG_MAG7) && Chance(0.2)) { 80 | g_PlayerPrimary[client] = "weapon_mag7"; 81 | if (Chance(0.1)) { 82 | g_PlayerPrimary[client] = "weapon_p90"; 83 | } 84 | } 85 | 86 | if (StrEqual(g_LastItemPickup[client], "ak47")) { 87 | g_PlayerPrimary[client] = "weapon_ak47"; 88 | } 89 | } 90 | } 91 | 92 | static void AssignCTNades(int client, int spawn) { 93 | int friendliness = g_SpawnSiteFriendly[spawn][g_Bombsite]; 94 | float f = GetRandomFloat(); 95 | 96 | if (friendliness >= 4) { 97 | if (f < 0.3) { 98 | g_PlayerNades[client] = "f"; 99 | } else if (f < 0.25) { 100 | g_PlayerNades[client] = "s"; 101 | } else if (f < 0.35) { 102 | g_PlayerNades[client] = "h"; 103 | } else if (f < 0.42) { 104 | g_PlayerNades[client] = "f"; 105 | } else if (f < 0.45) { 106 | g_PlayerNades[client] = "i"; 107 | } 108 | 109 | } else { 110 | if (f < 0.2) { 111 | g_PlayerNades[client] = "f"; 112 | } else if (f < 0.3) { 113 | g_PlayerNades[client] = "s"; 114 | } else if (f < 0.4) { 115 | g_PlayerNades[client] = "h"; 116 | } else if (f < 0.5) { 117 | g_PlayerNades[client] = "f"; 118 | } else if (f < 0.6) { 119 | g_PlayerNades[client] = "i"; 120 | } 121 | } 122 | 123 | if (HasFlag(spawn, SPAWNFLAG_FLASH && GetRandomFloat() < 0.5)) { 124 | AddNade(client, "f"); 125 | } 126 | 127 | if (HasFlag(spawn, SPAWNFLAG_SMOKE && GetRandomFloat() < 0.5)) { 128 | AddNade(client, "s"); 129 | } 130 | 131 | if (HasFlag(spawn, SPAWNFLAG_MOLOTOV && GetRandomFloat() < 0.5)) { 132 | AddNade(client, "i"); 133 | } 134 | } 135 | 136 | static void AssignT(int client) { 137 | float f = GetRandomFloat(); 138 | if (f < 0.1) { 139 | SetPrimaryRifle(client, CS_TEAM_T); 140 | g_PlayerNades[client] = "f"; 141 | } else if (f < 0.3) { 142 | SetPrimaryRifle(client, CS_TEAM_T); 143 | g_PlayerNades[client] = ""; 144 | 145 | } else if (f < 0.35) { 146 | g_PlayerPrimary[client] = "weapon_galilar"; 147 | g_PlayerNades[client] = "mi"; 148 | 149 | } else if (f < 0.5) { 150 | g_PlayerPrimary[client] = "weapon_galilar"; 151 | g_PlayerNades[client] = "f"; 152 | 153 | } else if (f < 0.8) { 154 | g_PlayerPrimary[client] = ""; 155 | GiveUpgradedSecondary(client, CS_TEAM_T); 156 | g_PlayerNades[client] = "fm"; 157 | 158 | } else { 159 | g_PlayerPrimary[client] = ""; 160 | GiveUpgradedSecondary(client, CS_TEAM_T); 161 | g_PlayerNades[client] = "f"; 162 | } 163 | } 164 | -------------------------------------------------------------------------------- /scripting/include/logdebug.inc: -------------------------------------------------------------------------------- 1 | /* 2 | * logdebug.inc by Dr. McKay 3 | * 4 | * A simple to use library for debug logging which can be redirected or disabled on-the-fly. 5 | * Employs transitional syntax - SourceMod 1.7 or newer is required to compile and run. 6 | */ 7 | 8 | #if defined _logdebug_included 9 | #endinput 10 | #endif 11 | #define _logdebug_included 12 | 13 | // define NO_DEBUG before including this file to completely disable all debugging 14 | #if defined NO_DEBUG 15 | stock void InitDebugLog(const char[] convarName, const char[] debugTag, 16 | int adminFlags = ADMFLAG_GENERIC) {} 17 | stock bool LogDebug(const char[] format, any...) { 18 | return false; 19 | } 20 | #endinput 21 | #endif 22 | 23 | #define DEBUG_SERVER_CONSOLE 1 /**< Message will be routed to server console */ 24 | #define DEBUG_CLIENT_CONSOLE 2 /**< Message will be routed to all clients' consoles */ 25 | #define DEBUG_ADMIN_CONSOLE \ 26 | 4 /**< Message will be routed to consoles of admins with a flag specified by plugin */ 27 | #define DEBUG_CLIENT_CHAT \ 28 | 8 /**< Message will be routed to all clients' chat boxes (and consequently consoles) */ 29 | #define DEBUG_ADMIN_CHAT \ 30 | 16 /**< Message will be routed to chat boxes of admins with a flag specified by plugin */ 31 | #define DEBUG_LOG_FILE 32 /**< Message will be routed to plugin's debug log */ 32 | 33 | ConVar g_cvarDebugMode; 34 | char g_DebugLogFileName[PLATFORM_MAX_PATH]; 35 | char g_DebugTag[11]; 36 | char g_DebugCvarName[64]; 37 | int g_DebugAdminFlags; 38 | 39 | /** 40 | * Inits debug logging. You must call this in OnPluginStart(). 41 | * 42 | * @param convarName A name to use for the cvar which controls debug log output. Also 43 | * used 44 | * as filename for logfile. 45 | * @param debugTag Tag to prepend to messages, without []. Max 10 characters. 46 | * @param adminFlag One or more admin flagbits which define whether a user is an 47 | * "admin". If you pass multiple flags, users will need ALL flags. 48 | * @noreturn 49 | */ 50 | stock void InitDebugLog(const char[] convarName, const char[] debugTag, 51 | int adminFlags = ADMFLAG_GENERIC) { 52 | BuildPath(Path_SM, g_DebugLogFileName, sizeof(g_DebugLogFileName), "logs/%s.log", convarName); 53 | 54 | char flagChars[32]; 55 | AdminFlag flags[22]; 56 | int numFlags = FlagBitsToArray(adminFlags, flags, sizeof(flags)); 57 | for (int i = 0; i < numFlags; i++) { 58 | int len = strlen(flagChars); 59 | 60 | if (len > 0) { 61 | len += StrCat(flagChars, sizeof(flagChars), ", "); 62 | } 63 | 64 | FindFlagChar(flags[i], view_as(flagChars[len])); 65 | flagChars[len + 1] = '\0'; 66 | } 67 | 68 | g_DebugAdminFlags = adminFlags; 69 | 70 | char convarDescription[512]; 71 | Format( 72 | convarDescription, sizeof(convarDescription), 73 | "Add up values to enable debug logging to those locations\n 1 = server console\n 2 = all clients' consoles\n 4 = consoles of admins with '%s' flag%s or access to '%s' override\n 8 = all clients' chat\n 16 = chat of admins with '%s' flag%s or access to '%s' override\n 32 = debug log file %s", 74 | flagChars, flagChars[1] == '\0' ? "" : "s", convarName, flagChars, 75 | flagChars[1] == '\0' ? "" : "s", convarName, g_DebugLogFileName); 76 | g_cvarDebugMode = 77 | CreateConVar(convarName, "0", convarDescription, FCVAR_DONTRECORD, true, 0.0, true, 63.0); 78 | 79 | strcopy(g_DebugTag, sizeof(g_DebugTag), debugTag); 80 | strcopy(g_DebugCvarName, sizeof(g_DebugCvarName), convarName); 81 | } 82 | 83 | /** 84 | * Logs a message to all enabled debug output points 85 | * 86 | * @param format Message text with formatting tokens 87 | * @param ... Variable number of format parameters 88 | * @return true if message was output to at least one place 89 | */ 90 | stock bool LogDebug(const char[] format, any...) { 91 | if (g_cvarDebugMode == null) { 92 | ThrowError("InitDebugLog must be called before LogDebug"); 93 | } 94 | 95 | int output = g_cvarDebugMode.IntValue; 96 | if (output == 0) { 97 | return false; 98 | } 99 | 100 | char buffer[512]; 101 | VFormat(buffer, sizeof(buffer), format, 2); 102 | 103 | if (output & DEBUG_SERVER_CONSOLE) { 104 | PrintToServer("[%s] %s", g_DebugTag, buffer); 105 | } 106 | 107 | if (output & DEBUG_CLIENT_CONSOLE) { 108 | for (int i = 1; i <= MaxClients; i++) { 109 | if (IsClientInGame(i) && !IsFakeClient(i)) { 110 | PrintToConsole(i, "[%s] %s", g_DebugTag, buffer); 111 | } 112 | } 113 | } 114 | 115 | if (output & DEBUG_ADMIN_CONSOLE) { 116 | for (int i = 1; i <= MaxClients; i++) { 117 | if (IsClientInGame(i) && !IsFakeClient(i) && 118 | CheckCommandAccess(i, g_DebugCvarName, g_DebugAdminFlags, true)) { 119 | PrintToConsole(i, "[%s] %s", g_DebugTag, buffer); 120 | } 121 | } 122 | } 123 | 124 | if (output & DEBUG_CLIENT_CHAT) { 125 | PrintToChatAll("[%s] %s", g_DebugTag, buffer); 126 | } 127 | 128 | if (output & DEBUG_ADMIN_CHAT) { 129 | for (int i = 1; i <= MaxClients; i++) { 130 | if (IsClientInGame(i) && !IsFakeClient(i) && 131 | CheckCommandAccess(i, g_DebugCvarName, g_DebugAdminFlags, true)) { 132 | PrintToChat(i, "[%s] %s", g_DebugTag, buffer); 133 | } 134 | } 135 | } 136 | 137 | if (output & DEBUG_LOG_FILE) { 138 | LogToFileEx(g_DebugLogFileName, "[%s] %s", g_DebugTag, buffer); 139 | } 140 | 141 | return true; 142 | } 143 | 144 | /** 145 | * Returns a bitstring containing bits enabled for each output location (see DEBUG_ constants) 146 | * 147 | * @return bitstring for enabled outputs 148 | */ 149 | stock int GetDebugOutputs() { 150 | return g_cvarDebugMode.IntValue; 151 | } 152 | -------------------------------------------------------------------------------- /scripting/executes/prefs_menu.sp: -------------------------------------------------------------------------------- 1 | public void GivePreferencesMenu(int client) { 2 | Menu menu = new Menu(PreferencesMenuHandler); 3 | char buffer[128]; 4 | 5 | menu.SetTitle("Select weapon preferences"); 6 | 7 | char choice[32]; 8 | switch(g_CTRifle[client]) { 9 | case CTRiflePref_M4: 10 | choice = "M4A4"; 11 | case CTRiflePref_Silenced_M4: 12 | choice = "M4A1-S"; 13 | case CTRiflePref_Aug: 14 | choice = "AUG"; 15 | } 16 | Format(buffer, sizeof(buffer), "CT Rifle choice: %s", choice); 17 | menu.AddItem("ct_rifle", buffer); 18 | 19 | switch(g_TRifle[client]) { 20 | case TRiflePref_Ak: 21 | choice = "AK-47"; 22 | case TRiflePref_Sg: 23 | choice = "SG 553"; 24 | } 25 | Format(buffer, sizeof(buffer), "T Rifle choice: %s", choice); 26 | menu.AddItem("t_rifle", buffer); 27 | 28 | buffer = "Allow receiving awps: no"; 29 | if (g_AllowAWP[client]) 30 | buffer = "Allow receiving awps: yes"; 31 | menu.AddItem("allow_awp", buffer); 32 | 33 | switch (g_SitePreference[client]) { 34 | case SitePref_A: 35 | choice = "A"; 36 | case SitePref_B: 37 | choice = "B"; 38 | case SitePref_Mid: 39 | choice = "Mid"; 40 | default: 41 | choice = "none"; 42 | } 43 | Format(buffer, sizeof(buffer), "CT site preference: %s", choice); 44 | menu.AddItem("site_pref", buffer); 45 | 46 | buffer = "Deagle/Five-Seven choice: Five-Seven"; 47 | if (g_DFCTSide[client]) { 48 | buffer = "Deagle/Five-Seven choice: Deagle"; 49 | } 50 | menu.AddItem("df_ct", buffer); 51 | 52 | buffer = "Deagle/Tec9 choice: Tec9"; 53 | if (g_DTTSide[client]) { 54 | buffer = "Deagle/Tec9 choice: Deagle"; 55 | } 56 | menu.AddItem("dt_t", buffer); 57 | 58 | menu.Display(client, 15); 59 | } 60 | 61 | public int PreferencesMenuHandler(Menu menu, MenuAction action, int param1, int param2) { 62 | if (action == MenuAction_Select) { 63 | int client = param1; 64 | char choice[64]; 65 | menu.GetItem(param2, choice, sizeof(choice)); 66 | 67 | if (StrEqual(choice, "ct_rifle")) { 68 | if (g_CTRifle[client] == CTRiflePref_M4) 69 | g_CTRifle[client] = CTRiflePref_Silenced_M4; 70 | else if (g_CTRifle[client] == CTRiflePref_Silenced_M4) 71 | g_CTRifle[client] = CTRiflePref_Aug; 72 | else if (g_CTRifle[client] == CTRiflePref_Aug) 73 | g_CTRifle[client] = CTRiflePref_M4; 74 | 75 | SetCTRiflePrefCookie(client, g_CTRifle[client]); 76 | GivePreferencesMenu(client); 77 | 78 | } else if (StrEqual(choice, "t_rifle")) { 79 | if (g_TRifle[client] == TRiflePref_Ak) 80 | g_TRifle[client] = TRiflePref_Sg; 81 | else if (g_TRifle[client] == TRiflePref_Sg) 82 | g_TRifle[client] = TRiflePref_Ak; 83 | 84 | SetTRiflePrefCookie(client, g_TRifle[client]); 85 | GivePreferencesMenu(client); 86 | 87 | } else if (StrEqual(choice, "allow_awp")) { 88 | g_AllowAWP[client] = !g_AllowAWP[client]; 89 | SetCookieBool(client, g_AllowAWPCookie, g_AllowAWP[client]); 90 | GivePreferencesMenu(client); 91 | 92 | } else if (StrEqual(choice, "site_pref")) { 93 | if (g_SitePreference[client] == SitePref_A) 94 | g_SitePreference[client] = SitePref_B; 95 | else if (g_SitePreference[client] == SitePref_B) 96 | g_SitePreference[client] = SitePref_Mid; 97 | else if (g_SitePreference[client] == SitePref_Mid) 98 | g_SitePreference[client] = SitePref_None; 99 | else 100 | g_SitePreference[client] = SitePref_A; 101 | 102 | SetSitePrefCookie(client, g_SitePreference[client]); 103 | GivePreferencesMenu(client); 104 | 105 | } else if (StrEqual(choice, "df_ct")) { 106 | g_DFCTSide[client] = !g_DFCTSide[client]; 107 | SetCookieBool(client, g_DFCTSideCookie, g_DFCTSide[client]); 108 | GivePreferencesMenu(client); 109 | 110 | } else if (StrEqual(choice, "dt_t")) { 111 | g_DTTSide[client] = !g_DTTSide[client]; 112 | SetCookieBool(client, g_DTTSideCookie, g_DTTSide[client]); 113 | GivePreferencesMenu(client); 114 | 115 | } else { 116 | LogError("unknown pref string = %s", choice); 117 | } 118 | 119 | } else if (action == MenuAction_End) { 120 | delete menu; 121 | } 122 | } 123 | 124 | public void OnClientCookiesCached(int client) { 125 | if (IsFakeClient(client)) 126 | return; 127 | 128 | g_AllowAWP[client] = GetCookieBool(client, g_AllowAWPCookie); 129 | g_SitePreference[client] = GetSitePrefCookie(client); 130 | g_DFCTSide[client] = GetCookieBool(client, g_DFCTSideCookie, true); 131 | g_DTTSide[client] = GetCookieBool(client, g_DTTSideCookie, true); 132 | g_CTRifle[client] = GetCTRiflePrefCookie(client); 133 | g_TRifle[client] = GetTRiflePrefCookie(client); 134 | } 135 | 136 | public void SetSitePrefCookie(int client, SitePref site) { 137 | char mapName[32]; 138 | GetCleanMapName(mapName, sizeof(mapName)); 139 | char cookieName[128]; 140 | Format(cookieName, sizeof(cookieName), "exec_%s_ct_site", mapName); 141 | SetCookieIntByName(client, cookieName, view_as(site)); 142 | } 143 | 144 | public SitePref GetSitePrefCookie(int client) { 145 | char mapName[32]; 146 | GetCleanMapName(mapName, sizeof(mapName)); 147 | char cookieName[128]; 148 | Format(cookieName, sizeof(cookieName), "exec_%s_ct_site", mapName); 149 | return view_as(GetCookieIntByName(client, cookieName)); 150 | } 151 | 152 | public CTRiflePref GetCTRiflePrefCookie(int client) { 153 | return view_as(GetCookieIntByName(client, "executes_ct_rifle")); 154 | } 155 | 156 | public TRiflePref GetTRiflePrefCookie(int client) { 157 | return view_as(GetCookieIntByName(client, "executes_t_rifle")); 158 | } 159 | 160 | public void SetCTRiflePrefCookie(int client, CTRiflePref pref) { 161 | SetCookieInt(client, g_CTRiflePrefCookie, view_as(pref)); 162 | } 163 | 164 | public void SetTRiflePrefCookie(int client, TRiflePref pref) { 165 | SetCookieInt(client, g_TRiflePrefCookie, view_as(pref)); 166 | } 167 | -------------------------------------------------------------------------------- /scripting/executes/loadout_gunrounds.sp: -------------------------------------------------------------------------------- 1 | public void GunRounds_Assign(ArrayList tPlayers, ArrayList ctPlayers, Bombsite site) { 2 | bool helpCT = false; 3 | bool hurtT = false; 4 | 5 | if (g_NumT > g_NumCT) { 6 | if (Chance(0.5)) { 7 | hurtT = true; 8 | } else { 9 | helpCT = true; 10 | } 11 | } 12 | 13 | for (int i = 0; i < tPlayers.Length; i++) { 14 | AssignT(tPlayers.Get(i), hurtT); 15 | } 16 | 17 | for (int i = 0; i < ctPlayers.Length; i++) { 18 | AssignCT(ctPlayers.Get(i), helpCT); 19 | } 20 | } 21 | 22 | static void AssignCT(int client, bool helpCT) { 23 | int spawn = g_SpawnIndices[client]; 24 | if (helpCT) { 25 | g_PlayerHelmet[client] = true; 26 | g_PlayerKit[client] = true; 27 | } else { 28 | g_PlayerHelmet[client] = Chance(0.6); 29 | g_PlayerKit[client] = Chance(0.85); 30 | } 31 | AssignCTNades(client, spawn, helpCT); 32 | 33 | if (client == g_CTAwper) { 34 | // TODO: maybe add a cvar for... 'stupid stuff' like this :) 35 | if (Chance(0.03)) { 36 | g_PlayerPrimary[client] = "weapon_scar20"; 37 | } else { 38 | g_PlayerPrimary[client] = "weapon_awp"; 39 | g_PlayerSecondary[client] = "weapon_p250"; 40 | } 41 | 42 | } else { 43 | if (Chance(0.02)) { 44 | g_PlayerPrimary[client] = "weapon_famas"; 45 | } else if (Chance(0.0005)) { 46 | g_PlayerPrimary[client] = "weapon_negev"; 47 | } else if (Chance(0.0005)) { 48 | g_PlayerPrimary[client] = "weapon_m249"; 49 | } 50 | 51 | if (HasFlag(spawn, SPAWNFLAG_MAG7) && Chance(0.15) && !helpCT) { 52 | g_PlayerPrimary[client] = "weapon_mag7"; 53 | } 54 | } 55 | } 56 | 57 | static void AssignCTNades(int client, int spawn, bool help) { 58 | int friendliness = g_SpawnSiteFriendly[spawn][g_Bombsite]; 59 | float f = GetRandomFloat(); 60 | 61 | if (help) { 62 | if (friendliness >= 4) { 63 | if (f < 0.2) { 64 | g_PlayerNades[client] = "fh"; 65 | } else if (f < 0.25) { 66 | g_PlayerNades[client] = "s"; 67 | } else if (f < 0.35) { 68 | g_PlayerNades[client] = "f"; 69 | } else if (f < 0.7) { 70 | g_PlayerNades[client] = "f"; 71 | } else if (f < 0.72) { 72 | g_PlayerNades[client] = "i"; 73 | } 74 | } else { 75 | if (f < 0.2) { 76 | g_PlayerNades[client] = "if"; 77 | } else if (f < 0.4) { 78 | g_PlayerNades[client] = "s"; 79 | } else if (f < 0.5) { 80 | g_PlayerNades[client] = "fh"; 81 | } else if (f < 0.675) { 82 | g_PlayerNades[client] = "f"; 83 | } 84 | } 85 | 86 | } else { 87 | if (friendliness >= 4) { 88 | if (f < 0.2) { 89 | g_PlayerNades[client] = "fh"; 90 | } else if (f < 0.25) { 91 | g_PlayerNades[client] = "s"; 92 | } else if (f < 0.35) { 93 | g_PlayerNades[client] = "f"; 94 | } else if (f < 0.75) { 95 | g_PlayerNades[client] = "f"; 96 | } else if (f < 0.8) { 97 | g_PlayerNades[client] = "i"; 98 | } 99 | 100 | } else { 101 | if (f < 0.2) { 102 | g_PlayerNades[client] = "if"; 103 | } else if (f < 0.4) { 104 | g_PlayerNades[client] = "s"; 105 | } else if (f < 0.5) { 106 | g_PlayerNades[client] = "fh"; 107 | } else if (f < 0.7) { 108 | g_PlayerNades[client] = "f"; 109 | } 110 | } 111 | } 112 | 113 | if (Chance(0.2)) { 114 | g_PlayerNades[client] = ""; 115 | } 116 | 117 | if (HasFlag(spawn, SPAWNFLAG_FLASH && GetRandomFloat() < 0.75)) { 118 | AddNade(client, "f"); 119 | } 120 | 121 | if (HasFlag(spawn, SPAWNFLAG_SMOKE && GetRandomFloat() < 0.75)) { 122 | AddNade(client, "s"); 123 | } 124 | 125 | if (HasFlag(spawn, SPAWNFLAG_MOLOTOV && GetRandomFloat() < 0.75)) { 126 | AddNade(client, "i"); 127 | } 128 | } 129 | 130 | static void AssignT(int client, bool hurtT) { 131 | int spawn = g_SpawnIndices[client]; 132 | AssignTNades(client, spawn, hurtT); 133 | 134 | if (client == g_TAwper) { 135 | g_PlayerPrimary[client] = "weapon_awp"; 136 | g_PlayerSecondary[client] = "weapon_p250"; 137 | 138 | } else if (hurtT) { 139 | if (Chance(0.06)) { 140 | g_PlayerPrimary[client] = "weapon_galilar"; 141 | } 142 | 143 | } else { 144 | if (Chance(0.02)) { 145 | g_PlayerPrimary[client] = "weapon_galilar"; 146 | } else if (Chance(0.002)) { 147 | g_PlayerPrimary[client] = "weapon_m249"; 148 | } 149 | } 150 | } 151 | 152 | static void AssignTNades(int client, int spawn, bool hurt) { 153 | float f = GetRandomFloat(); 154 | bool throwingSetNade = IsGrenade(g_SpawnGrenadeTypes[spawn]); 155 | 156 | if (hurt) { 157 | if (f < 0.15 && !throwingSetNade) { 158 | g_PlayerNades[client] = "m"; 159 | } else if (f < 0.3 && !throwingSetNade) { 160 | g_PlayerNades[client] = "s"; 161 | } else if (f < 0.6) { 162 | g_PlayerNades[client] = "f"; 163 | } 164 | 165 | } else { 166 | if (f < 0.25) { 167 | g_PlayerNades[client] = "f"; 168 | } else if (f < 0.4 && !throwingSetNade) { 169 | g_PlayerNades[client] = "s"; 170 | } else if (f < 0.6 && !throwingSetNade) { 171 | g_PlayerNades[client] = "m"; 172 | } else if (f < 0.6) { 173 | g_PlayerNades[client] = "f"; 174 | } else if (f < 0.7) { 175 | g_PlayerNades[client] = "h"; 176 | } else if (f < 0.76 && !throwingSetNade) { 177 | g_PlayerNades[client] = "fs"; 178 | } else if (f < 0.82 && !throwingSetNade) { 179 | g_PlayerNades[client] = "f"; 180 | } 181 | 182 | if (!throwingSetNade && HasFlag(spawn, SPAWNFLAG_MOLOTOV)) { 183 | if (f < 0.6) 184 | g_PlayerNades[client] = "m"; 185 | else if (f < 0.8) 186 | g_PlayerNades[client] = "fm"; 187 | else if (f < 0.9) 188 | g_PlayerNades[client] = "s"; 189 | } 190 | } 191 | 192 | if (HasFlag(spawn, SPAWNFLAG_FLASH)) { 193 | if (f < 0.8) { 194 | AddNade(client, "f"); 195 | } 196 | } 197 | 198 | if (!throwingSetNade && HasFlag(spawn, SPAWNFLAG_SMOKE)) { 199 | if (f < 0.8) { 200 | AddNade(client, "s"); 201 | } 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | csgo-executes 2 | ============= 3 | 4 | [![Build status](http://ci.splewis.net/job/csgo-executes/badge/icon)](http://ci.splewis.net/job/csgo-executes/) 5 | [![Discord Chat](https://img.shields.io/discord/926309849673895966.svg)](https://discord.gg/zmqEa4keCk) 6 | 7 | ## Gameplay 8 | 9 | The T team setup to execute onto a site with ~40 seconds left and the CT team is typically in a fairly standard setup. Grenades are automatically thrown for the T players and the rounds plays out the way counter-strike plays. The game goes through pistol rounds, forcebuy/lowbuy rounds, then standard gun rounds. Players can use the ``guns`` menu to select some preferences: whether they want to have an AWP, which M4 to use, and what site they prefer to play on the CT side. 10 | 11 | When a T team wins a round, the players typically move to CT. The goal is the defend off the executes and stay on CT. However, because executes is typically best played 5v5 it's hard to get varied teams if this is strictly followed, so there is some auto-scrambling of teams every ``sm_executes_auto_scramble`` rounds. 12 | 13 | ## Installation 14 | 15 | #### Instructions 16 | 17 | Download the archive from the latest [build](http://ci.splewis.net/job/csgo-executes/lastSuccessfulBuild/) and extract ALL the files to the game server. This includes both the ``executes.smx`` and ``csutils.smx`` plugin files needed. 18 | 19 | Note: the ``csutils.smx`` plugin comes from the [practicemode](https://github.com/splewis/csgo-practice-mode) project, and is used to throw the execute grenades. 20 | 21 | #### Configuration 22 | 23 | The file ``cfg/sourcemod/executes/executes.cfg`` will be autogenerated when the plugin is first run and you can tweak it if you wish. 24 | 25 | You may also tweak the values in ``cfg/sourcemod/executes/executes_game.cfg``, which is executed by the plugin each map start. 26 | 27 | Some important cvars: 28 | - ``sm_executes_minplayers`` 29 | - ``sm_executes_maxplayers`` 30 | - ``sm_executes_ratio_constant`` 31 | - ``sm_executes_round_time`` 32 | - ``sm_executes_auto_scramble`` 33 | 34 | 35 | #### Creating Executes and Spawns 36 | 37 | The plugin now comes with some default spawn configs, but you are **strongly recommended** to create your own. The provides spawns are likely quite out of date (some grenades may not even work) and may reflect a poor variety of executes that don't represent the current meta. 38 | 39 | ``!edit``: launches the editor, opens the edit menu. You will use this a lot 40 | ``!setname``: sets the name of the spawn/execute being edited 41 | ``!clearbuffers``: clears any spawn/execute edit buffers 42 | 43 | When working on a map, you should: 44 | 1. **Add CT spawns.** Each has a notion of 'friendliness' to a site. For example, a B site spawn on de_cache should typically have a '5' friendliness to B and a '1' to A. A spawn in mid might have a '3' to each site. This must be accurate for the CT spawn algorithm to work. 45 | 1. **Add some basic T spawns.** Add them in spots you don't throw nades from. Name them in a way you can identify where they are later, e.g. 'B main 1', 'B main 2', etc. 46 | 1. **Start adding the spawns for the smokes/mollies you want.** To do this, stand in the spot, go to 'new spawn' in the menu, throw the greande, and save the spawn. The editor will remember the LAST grenade thrown and attach it to the next spawn made (unless you use !clearbuffs before then). 47 | 1. **Start adding executes.** You will select a list of 'required' T spawns for the execute (typically these are your set smokes), and 'optional' ones. The execute is only eligible to be picked if all the required spawns can be chosen (so if there are 4 required spawns, there must be at least 4 T's). 48 | 49 | Other notes: 50 | - All spawns have a 'awp friendliness' rating. Spots good for awpers should get a 5, spots very bad should get a 1. TODO: awp friendliness should be renamed something like 'range friendliness'. 51 | - I don't recommend using the special support for 'lurk' spawns. The feature was never finished. 52 | - You can set some flags on spawns for some extra flavor, e.g. CT spawns can be marked with a 'mag7' flag so sometimes a CT spawned there will get a mag7. There are several flags for T and CT spawns. 53 | - Only 1 player should be workiing on the editor at a time. It saves a single buffer for the spawn/execute being edited, not one per player. If multiple players are throwing nades, the buffer will **keep getting overwritten**. 54 | - Install [practicemode](https://github.com/splewis/csgo-practice-mode) for a better editing experience so you will have the ``.back`` command, which helps you make sure your nades landed before saving them. 55 | - The editor can be buggy. Saving the config & reloading them can help if your spawns aren't showing up on the 'add spawns' menu for the execute builder menu. 56 | - If you don't know how something works, **look at the code**. 57 | 58 | 59 | ## Contributing 60 | 61 | [Pull requests](https://github.com/splewis/csgo-executes/pulls) will be reviewed if they meet a few guidelines: 62 | - Follow the code style (2 spaces for indentation, 100 line column limits, same bracing style) 63 | - Add some useful feature or make the use of plugin better. 64 | - Don't make arbitrary gameplay changes - those should be left out. I am not interesting in debating gameplay decisions. The plugin has an [API](scripting/include/executes.inc) for a reason - leave your other gameplay choices in other plugins. If you need a new native/forward (and you very likely **will**) feel free to add it. 65 | 66 | There is a significant amount of bad code and TODOs - 95% of this was written in a few days. Cleaning those problems up is appreciated. 67 | 68 | ### Discord Chat 69 | 70 | A [Discord](https://discord.gg/zmqEa4keCk) channel is available for general discussion. 71 | 72 | #### Known issues and limitations 73 | 74 | - Only 1 set grenade can be thrown from a spawn. This makes certain executes hard (upper executes on nuke, for example), but you can try to compensate by adding the 'flash' flag to T spawns that would typically flash after throwing their smoke/molotov. 75 | - Molotovs don't spread correctly when automatically thrown: this is a [csutils bug](https://github.com/splewis/csgo-practice-mode/issues/44). 76 | - The sm_executes_enabled cvar doesn't work very well. 77 | -------------------------------------------------------------------------------- /scripting/executes/natives.sp: -------------------------------------------------------------------------------- 1 | #define MESSAGE_PREFIX "[\x05Executes\x01]" 2 | 3 | #define CHECK_CONNECTED(%1) \ 4 | if (!IsClientConnected(%1)) \ 5 | ThrowNativeError(SP_ERROR_PARAM, "Client %d is not connected", %1) 6 | 7 | public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max) { 8 | CreateNative("Executes_IsJoined", Native_IsJoined); 9 | CreateNative("Executes_IsInQueue", Native_IsInQueue); 10 | CreateNative("Executes_Message", Native_PluginMessage); 11 | CreateNative("Executes_MessageToAll", Native_PluginMessageToAll); 12 | CreateNative("Executes_GetNumActiveTs", Native_GetNumActiveTs); 13 | CreateNative("Executes_GetNumActiveCTs", Native_GetNumActiveCTs); 14 | CreateNative("Executes_GetNumActivePlayers", Native_GetNumActivePlayers); 15 | CreateNative("Executes_GetCurrrentBombsite", Native_GetCurrrentBombsite); 16 | CreateNative("Executes_GetRoundPoints", Native_GetRoundPoints); 17 | CreateNative("Executes_SetRoundPoints", Native_SetRoundPoints); 18 | CreateNative("Executes_ChangeRoundPoints", Native_ChangeRoundPoints); 19 | CreateNative("Executes_GetPlayerInfo", Native_GetPlayerInfo); 20 | CreateNative("Executes_SetPlayerInfo", Native_SetPlayerInfo); 21 | CreateNative("Executes_GetRoundsPlayed", Native_GetRoundsPlayed); 22 | CreateNative("Executes_InEditMode", Native_InEditMode); 23 | CreateNative("Executes_Enabled", Native_Enabled); 24 | CreateNative("Executes_GetMaxPlayers", Native_GetMaxPlayers); 25 | CreateNative("Executes_InWarmup", Native_InWarmup); 26 | RegPluginLibrary("executes"); 27 | return APLRes_Success; 28 | } 29 | 30 | public int Native_IsJoined(Handle plugin, int numParams) { 31 | int client = GetNativeCell(1); 32 | if (!IsPlayer(client)) 33 | return false; 34 | return GetClientTeam(client) == CS_TEAM_T || GetClientTeam(client) == CS_TEAM_CT || 35 | Queue_Find(g_hWaitingQueue, client) != -1; 36 | } 37 | 38 | public int Native_IsInQueue(Handle plugin, int numParams) { 39 | int client = GetNativeCell(1); 40 | if (!IsPlayer(client)) 41 | return false; 42 | return Queue_Find(g_hWaitingQueue, client) != -1; 43 | } 44 | 45 | public int Native_PluginMessage(Handle plugin, int numParams) { 46 | int client = GetNativeCell(1); 47 | SetGlobalTransTarget(client); 48 | char buffer[1024]; 49 | int bytesWritten = 0; 50 | FormatNativeString(0, 2, 3, sizeof(buffer), bytesWritten, buffer); 51 | 52 | char finalMsg[1024]; 53 | Format(finalMsg, sizeof(finalMsg), "%s %s", MESSAGE_PREFIX, buffer); 54 | 55 | if (client == 0) { 56 | Colorize(finalMsg, sizeof(finalMsg), true); 57 | PrintToConsole(client, finalMsg); 58 | } else { 59 | Colorize(finalMsg, sizeof(finalMsg)); 60 | PrintToChat(client, finalMsg); 61 | } 62 | } 63 | 64 | public int Native_PluginMessageToAll(Handle plugin, int numParams) { 65 | char buffer[1024]; 66 | char finalMsg[1024]; 67 | int bytesWritten = 0; 68 | 69 | FormatNativeString(0, 1, 2, sizeof(buffer), bytesWritten, buffer); 70 | Format(finalMsg, sizeof(finalMsg), "%s %s", MESSAGE_PREFIX, buffer); 71 | Colorize(finalMsg, sizeof(finalMsg), true); 72 | PrintToConsole(0, finalMsg); 73 | LogDebug(finalMsg); 74 | 75 | for (int i = 1; i <= MaxClients; i++) { 76 | if (IsClientInGame(i)) { 77 | SetGlobalTransTarget(i); 78 | FormatNativeString(0, 1, 2, sizeof(buffer), bytesWritten, buffer); 79 | Format(finalMsg, sizeof(finalMsg), "%s %s", MESSAGE_PREFIX, buffer); 80 | Colorize(finalMsg, sizeof(finalMsg)); 81 | PrintToChat(i, finalMsg); 82 | } 83 | } 84 | } 85 | 86 | public int Native_GetNumActiveTs(Handle plugin, int numParams) { 87 | return g_NumT; 88 | } 89 | 90 | public int Native_GetNumActiveCTs(Handle plugin, int numParams) { 91 | return g_NumCT; 92 | } 93 | 94 | public int Native_GetNumActivePlayers(Handle plugin, int numParams) { 95 | return g_NumT + g_NumCT; 96 | } 97 | 98 | public int Native_GetCurrrentBombsite(Handle plugin, int numParams) { 99 | return view_as(g_Bombsite); 100 | } 101 | 102 | public int Native_GetRoundPoints(Handle plugin, int numParams) { 103 | int client = GetNativeCell(1); 104 | CHECK_CONNECTED(client); 105 | return g_RoundPoints[client]; 106 | } 107 | 108 | public int Native_SetRoundPoints(Handle plugin, int numParams) { 109 | int client = GetNativeCell(1); 110 | CHECK_CONNECTED(client); 111 | int points = GetNativeCell(2); 112 | g_RoundPoints[client] = points; 113 | } 114 | 115 | public int Native_ChangeRoundPoints(Handle plugin, int numParams) { 116 | int client = GetNativeCell(1); 117 | CHECK_CONNECTED(client); 118 | int dp = GetNativeCell(2); 119 | g_RoundPoints[client] += dp; 120 | } 121 | 122 | public int Native_GetPlayerInfo(Handle plugin, int numParams) { 123 | int client = GetNativeCell(1); 124 | CHECK_CONNECTED(client); 125 | SetNativeString(2, g_PlayerPrimary[client], WEAPON_STRING_LENGTH); 126 | SetNativeString(3, g_PlayerSecondary[client], WEAPON_STRING_LENGTH); 127 | SetNativeString(4, g_PlayerNades[client], NADE_STRING_LENGTH); 128 | 129 | SetNativeCellRef(5, g_PlayerHealth[client]); 130 | SetNativeCellRef(6, g_PlayerArmor[client]); 131 | SetNativeCellRef(7, g_PlayerHelmet[client]); 132 | SetNativeCellRef(8, g_PlayerKit[client]); 133 | } 134 | 135 | public int Native_SetPlayerInfo(Handle plugin, int numParams) { 136 | int client = GetNativeCell(1); 137 | CHECK_CONNECTED(client); 138 | 139 | GetNativeString(2, g_PlayerPrimary[client], WEAPON_STRING_LENGTH); 140 | GetNativeString(3, g_PlayerSecondary[client], WEAPON_STRING_LENGTH); 141 | GetNativeString(4, g_PlayerNades[client], NADE_STRING_LENGTH); 142 | 143 | g_PlayerHealth[client] = GetNativeCell(5); 144 | g_PlayerArmor[client] = GetNativeCell(6); 145 | g_PlayerHelmet[client] = GetNativeCell(7); 146 | g_PlayerKit[client] = GetNativeCell(8); 147 | } 148 | 149 | public int Native_GetRoundsPlayed(Handle plugin, int numParams) { 150 | return g_RoundCount; 151 | } 152 | 153 | public int Native_InEditMode(Handle plugin, int numParams) { 154 | return g_EditMode; 155 | } 156 | 157 | public int Native_Enabled(Handle plugin, int numParams) { 158 | return g_Enabled; 159 | } 160 | 161 | public int Native_GetMaxPlayers(Handle plugin, int numParams) { 162 | return g_hMaxPlayers.IntValue; 163 | } 164 | 165 | public int Native_InWarmup(Handle plugin, int numParams) { 166 | return InWarmup(); 167 | } 168 | -------------------------------------------------------------------------------- /scripting/include/executes.inc: -------------------------------------------------------------------------------- 1 | #if defined _executes_included 2 | #endinput 3 | #endif 4 | #define _executes_included 5 | 6 | enum Bombsite { 7 | BombsiteA = 0, 8 | BombsiteB = 1, 9 | }; 10 | 11 | enum SpawnSite { 12 | SpawnSite_Any = 0, 13 | SpawnSite_A = 1, 14 | SpawnSite_B = 2, 15 | }; 16 | 17 | enum SitePref { 18 | SitePref_None = 0, 19 | SitePref_A = 1, 20 | SitePref_B = 2, 21 | SitePref_Mid = 3, 22 | }; 23 | 24 | enum StratType { 25 | StratType_Normal = 0, 26 | StratType_Pistol = 1, 27 | StratType_ForceBuy = 2, 28 | }; 29 | 30 | // Most spawn flags only apply to gun rounds typically. 31 | #define SPAWNFLAG_MOLOTOV (1 << 0) 32 | #define SPAWNFLAG_MAG7 (1 << 1) // CT only 33 | #define SPAWNFLAG_ALURKER (1 << 2) // T only 34 | #define SPAWNFLAG_BLURKER (1 << 3) // T only 35 | #define SPAWNFLAG_FLASH (1 << 4) 36 | #define SPAWNFLAG_SMOKE (1 << 5) 37 | 38 | #define SITESTRING(%1) ((%1) == BombsiteA ? "A" : "B") 39 | #define TEAMSTRING(%1) ((%1) == CS_TEAM_CT ? "CT" : "T") 40 | 41 | /** 42 | * Maxmimum length of a nade string. Example: "hfs" is a hegrenade, flashbang, and smoke. 43 | */ 44 | #define NADE_STRING_LENGTH 8 45 | 46 | /** 47 | * Maxmimum length of a weapon name. Example: "weapon_ak47" 48 | */ 49 | #define WEAPON_STRING_LENGTH 32 50 | 51 | /** 52 | * Called right before players get put onto teams for the next round. 53 | * This is the best place to decide who goes onto what team if you want 54 | * to change the default behavior. 55 | * 56 | * @param rankingQueue a priority queue (see include/priorityqueue.inc) 57 | * @param waitingQueue a queue of the players waiting to join (see include/queue.inc) 58 | * @noreturn 59 | */ 60 | forward void Executes_OnPreRoundEnqueue(ArrayList rankingQueue, ArrayList waitingQueue); 61 | 62 | /** 63 | * Called after active players have been placed into the priority scoring queue 64 | * for the next round. This is a convenient place to change their scores by 65 | * editing the ranking priority queue itself. 66 | * (rather than using the Executes_SetRoundPoints native) 67 | * 68 | * @param rankingQueue a priority queue (see include/priorityqueue.inc) 69 | * @noreturn 70 | */ 71 | forward void Executes_OnPostRoundEnqueue(ArrayList rankingQueue); 72 | 73 | /** 74 | * Called when the team sizes are set for the round. 75 | * 76 | * @param tCount the number of terrorists that will play the round 77 | * @param ctcount the number of counter-terrorists that will play the round 78 | * @noreturn 79 | */ 80 | forward void Executes_OnTeamSizesSet(int& tCount, int& ctCount); 81 | 82 | /** 83 | * Called when a team wins a round. 84 | * 85 | * @param winner the winning team (CS_TEAM_T or CS_TEAM_CT) 86 | * @param tPlayers an ArrayList of the players on the terrorist team 87 | * @param ctPlayers an ArrayList of the players on the counter-terrorist team 88 | * @noreturn 89 | */ 90 | forward void Executes_OnRoundWon(int winner, ArrayList tPlayers, ArrayList ctPlayers, int executeId, 91 | StratType stratType); 92 | 93 | /** 94 | * Called after teams have been determined for the round. 95 | * 96 | * @param tPlayers an ArrayList of the players on the terrorist team 97 | * @param ctPlayers an ArrayList of the players on the counter-terrorist team 98 | * @param bombsite 99 | * @noreturn 100 | */ 101 | forward void Executes_OnTeamsSet(ArrayList tPlayers, ArrayList ctPlayers, Bombsite bombsite); 102 | 103 | /** 104 | * Called when a client issues a command to bring up a "guns" menu. 105 | */ 106 | forward void Executes_OnGunsCommand(int client); 107 | 108 | /** 109 | * TODO 110 | */ 111 | forward void Executes_GetPlayerSpecialPowers(int client, bool& higherAwpPriority); 112 | 113 | /** 114 | * Returns if a player has joined the game, i.e., if they are on T/Ct or in the waiting queue. 115 | * 116 | * @param client a player 117 | * @return if the player has joined 118 | */ 119 | native bool Executes_IsJoined(int client); 120 | 121 | /** 122 | * Returns if a player is in the waiting queue. 123 | * 124 | * @param client a player 125 | * @return if the player is in the waiting queue 126 | */ 127 | native bool Executes_IsInQueue(int client); 128 | 129 | /** 130 | * Sends a retake formatted message to a client. 131 | * 132 | * @param client a player 133 | * @param format string message 134 | * @noreturn 135 | */ 136 | native void Executes_Message(int client, const char[] format, any ...); 137 | 138 | /** 139 | * Sends a retake formatted message to all clients. 140 | * 141 | * @param format string message 142 | * @noreturn 143 | */ 144 | native void Executes_MessageToAll(const char[] format, any ...); 145 | 146 | /** 147 | * Returns the number of terrorists for the current round. 148 | */ 149 | native int Executes_GetNumActiveTs(); 150 | 151 | /** 152 | * Returns the number of terrorists for the current round. 153 | */ 154 | native int Executes_GetNumActiveCTs(); 155 | 156 | /** 157 | * Returns the number of active players (t+ct) for the current round. 158 | */ 159 | native int Executes_GetNumActivePlayers(); 160 | 161 | /** 162 | * Returns the bombsite for the current scenario. 163 | */ 164 | native Bombsite Executes_GetCurrrentBombsite(); 165 | 166 | /** 167 | * Returns the round points for a client in the current round. 168 | */ 169 | native int Executes_GetRoundPoints(int client); 170 | 171 | /** 172 | * Sets the round points for a client in the current round. 173 | */ 174 | native int Executes_SetRoundPoints(int client, int points); 175 | 176 | /** 177 | * Changes the round points for a client in the current round. 178 | */ 179 | native void Executes_ChangeRoundPoints(int client, int dp); 180 | 181 | /** 182 | * Sets player weapon/equipment information for the current round. 183 | */ 184 | native void Executes_SetPlayerInfo(int client, const char[] primary = "", 185 | const char[] secondary = "", const char[] nades = "", 186 | int health = 100, int armor = 0, bool helmet = false, 187 | bool kit = false); 188 | 189 | /** 190 | * Gets player weapon/equipment information for the current round. 191 | */ 192 | native void Executes_GetPlayerInfo(int client, char primary[WEAPON_STRING_LENGTH], 193 | char secondary[WEAPON_STRING_LENGTH], 194 | char nades[NADE_STRING_LENGTH], int& health, int& armor, 195 | bool& helmet, bool& kit); 196 | 197 | /** 198 | * Returns the total number of live rounds played on the current map. 199 | */ 200 | native int Executes_GetRoundsPlayed(); 201 | 202 | /** 203 | * Returns if edit mode is active. 204 | */ 205 | native bool Executes_InEditMode(); 206 | 207 | /** 208 | * Returns if the plugin is enabled. 209 | */ 210 | native bool Executes_Enabled(); 211 | 212 | /** 213 | * Returns the maximum number of players allowed into the game. 214 | */ 215 | native int Executes_GetMaxPlayers(); 216 | 217 | native bool Executes_InWarmup(); 218 | 219 | public SharedPlugin __pl_executes = { 220 | name = "executes", file = "executes.smx", 221 | #if defined REQUIRE_PLUGIN 222 | required = 1, 223 | #else 224 | required = 0, 225 | #endif 226 | }; 227 | 228 | #if !defined REQUIRE_PLUGIN 229 | public __pl_Executes_SetNTVOptional() { 230 | MarkNativeAsOptional("Executes_IsJoined"); 231 | MarkNativeAsOptional("Executes_IsInQueue"); 232 | MarkNativeAsOptional("Executes_Message"); 233 | MarkNativeAsOptional("Executes_MessageToAll"); 234 | MarkNativeAsOptional("Executes_GetNumActiveTs"); 235 | MarkNativeAsOptional("Executes_GetNumActiveCTs"); 236 | MarkNativeAsOptional("Executes_GetNumActivePlayers"); 237 | MarkNativeAsOptional("Executes_GetCurrrentBombsite"); 238 | MarkNativeAsOptional("Executes_GetRoundPoints"); 239 | MarkNativeAsOptional("Executes_SetRoundPoints"); 240 | MarkNativeAsOptional("Executes_ChangeRoundPoints"); 241 | MarkNativeAsOptional("Executes_SetPlayerInfo"); 242 | MarkNativeAsOptional("Executes_GetPlayerInfo"); 243 | MarkNativeAsOptional("Executes_GetRoundsPlayed"); 244 | MarkNativeAsOptional("Executes_InEditMode"); 245 | MarkNativeAsOptional("Executes_Enabled"); 246 | MarkNativeAsOptional("Executes_GetMaxPlayers"); 247 | MarkNativeAsOptional("Executes_InWarmup"); 248 | } 249 | #endif -------------------------------------------------------------------------------- /scripting/executes/util.sp: -------------------------------------------------------------------------------- 1 | #tryinclude "manual_version.sp" 2 | #if !defined PLUGIN_VERSION 3 | #define PLUGIN_VERSION "1.0.0-dev" 4 | #endif 5 | 6 | #define INTEGER_STRING_LENGTH 20 // max number of digits a 64-bit integer can use up as a string 7 | // this is for converting ints to strings when setting menu values/cookies 8 | 9 | #include 10 | #include 11 | 12 | char g_ColorNames[][] = {"{NORMAL}", "{DARK_RED}", "{PURPLE}", "{GREEN}", 13 | "{MOSS_GREEN}", "{LIGHT_GREEN}", "{LIGHT_RED}", "{GRAY}", 14 | "{ORANGE}", "{LIGHT_BLUE}", "{DARK_BLUE}", "{PURPLE}"}; 15 | char g_ColorCodes[][] = {"\x01", "\x02", "\x03", "\x04", "\x05", "\x06", 16 | "\x07", "\x08", "\x09", "\x0B", "\x0C", "\x0E"}; 17 | 18 | /** 19 | * Switches a player to a new team. 20 | */ 21 | stock void SwitchPlayerTeam(int client, int team) { 22 | if (GetClientTeam(client) == team) 23 | return; 24 | 25 | g_PluginTeamSwitch[client] = true; 26 | if (team > CS_TEAM_SPECTATOR) { 27 | CS_SwitchTeam(client, team); 28 | CS_UpdateClientModel(client); 29 | } else { 30 | ChangeClientTeam(client, team); 31 | } 32 | g_PluginTeamSwitch[client] = false; 33 | } 34 | 35 | /** 36 | * Returns if the 2 players should be fighting each other. 37 | * Returns false on friendly fire/suicides. 38 | */ 39 | stock bool HelpfulAttack(int attacker, int victim) { 40 | if (!IsValidClient(attacker) || !IsValidClient(victim)) { 41 | return false; 42 | } 43 | int ateam = GetClientTeam(attacker); // Get attacker's team 44 | int vteam = GetClientTeam(victim); // Get the victim's team 45 | return ateam != vteam && attacker != victim; 46 | } 47 | 48 | /** 49 | * Returns the Human counts of the T & CT Teams. 50 | * Use this function for optimization if you have to get the counts of both teams, 51 | */ 52 | stock void GetTeamsClientCounts(int &tHumanCount, int &ctHumanCount) { 53 | for (int client = 1; client <= MaxClients; client++) { 54 | if (IsClientConnected(client) && IsClientInGame(client)) { 55 | if (GetClientTeam(client) == CS_TEAM_T) 56 | tHumanCount++; 57 | 58 | else if (GetClientTeam(client) == CS_TEAM_CT) 59 | ctHumanCount++; 60 | } 61 | } 62 | } 63 | 64 | /** 65 | * Returns the number of players currently on an active team (T/CT). 66 | */ 67 | stock int GetActivePlayerCount() { 68 | int count = 0; 69 | for (int client = 1; client <= MaxClients; client++) { 70 | if (IsClientConnected(client) && IsClientInGame(client)) { 71 | if (GetClientTeam(client) == CS_TEAM_T) 72 | count++; 73 | else if (GetClientTeam(client) == CS_TEAM_CT) 74 | count++; 75 | } 76 | } 77 | return count; 78 | } 79 | 80 | /** 81 | * Returns if a player is on an active/player team. 82 | */ 83 | stock bool IsOnTeam(int client) { 84 | int team = GetClientTeam(client); 85 | return (team == CS_TEAM_CT) || (team == CS_TEAM_T); 86 | } 87 | 88 | stock bool IsConnected(int client) { 89 | return client > 0 && client <= MaxClients && IsClientConnected(client) && !IsFakeClient(client); 90 | } 91 | 92 | /** 93 | * Function to identify if a client is valid and in game. 94 | */ 95 | stock bool IsValidClient(int client) { 96 | if (client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client)) 97 | return true; 98 | return false; 99 | } 100 | 101 | /** 102 | * Function to identify if a client is valid and in game. 103 | */ 104 | stock bool IsPlayer(int client) { 105 | return IsValidClient(client) && !IsFakeClient(client); 106 | } 107 | 108 | stock void AddMenuOption(Menu menu, const char[] info, const char[] display, any ...) { 109 | char formattedDisplay[128]; 110 | VFormat(formattedDisplay, sizeof(formattedDisplay), display, 4); 111 | menu.AddItem(info, formattedDisplay); 112 | } 113 | 114 | stock void AddMenuOptionDisabled(Menu menu, const char[] info, const char[] display, any ...) { 115 | char formattedDisplay[128]; 116 | VFormat(formattedDisplay, sizeof(formattedDisplay), display, 4); 117 | menu.AddItem(info, formattedDisplay, ITEMDRAW_DISABLED); 118 | } 119 | 120 | /** 121 | * Adds an integer to a menu as a string choice. 122 | */ 123 | stock void AddMenuInt(Menu menu, int value, const char[] display) { 124 | char buffer[INTEGER_STRING_LENGTH]; 125 | IntToString(value, buffer, sizeof(buffer)); 126 | menu.AddItem(buffer, display); 127 | } 128 | 129 | /** 130 | * Adds an integer to a menu as a string choice with the integer as the display. 131 | */ 132 | stock void AddMenuInt2(Menu menu, int value) { 133 | char buffer[INTEGER_STRING_LENGTH]; 134 | IntToString(value, buffer, sizeof(buffer)); 135 | menu.AddItem(buffer, buffer); 136 | } 137 | 138 | /** 139 | * Gets an integer to a menu from a string choice. 140 | */ 141 | stock int GetMenuInt(Menu menu, int param2) { 142 | char choice[INTEGER_STRING_LENGTH]; 143 | menu.GetItem(param2, choice, sizeof(choice)); 144 | return StringToInt(choice); 145 | } 146 | 147 | /** 148 | * Adds a boolean to a menu as a string choice. 149 | */ 150 | stock void AddMenuBool(Menu menu, bool value, const char[] display) { 151 | int convertedInt = value ? 1 : 0; 152 | AddMenuInt(menu, convertedInt, display); 153 | } 154 | 155 | /** 156 | * Gets a boolean to a menu from a string choice. 157 | */ 158 | stock bool GetMenuBool(Menu menu, int param2) { 159 | return GetMenuInt(menu, param2) != 0; 160 | } 161 | 162 | /** 163 | * Returns a random index from an array. 164 | */ 165 | stock int RandomIndex(ArrayList array) { 166 | int len = array.Length; 167 | if (len == 0) 168 | ThrowError("Can't get random index from empty array"); 169 | return GetRandomInt(0, len - 1); 170 | } 171 | 172 | /** 173 | * Returns a random element from an array. 174 | */ 175 | stock int RandomElement(ArrayList array) { 176 | return array.Get(RandomIndex(array)); 177 | } 178 | 179 | /** 180 | * Returns a randomly-created boolean. 181 | */ 182 | stock bool GetRandomBool() { 183 | return GetRandomInt(0, 1) == 0; 184 | } 185 | 186 | /** 187 | * Returns a handle to a cookie with the given name, creating it if it doesn't exist. 188 | */ 189 | stock Handle FindNamedCookie(const char[] cookieName) { 190 | Handle cookie = FindClientCookie(cookieName); 191 | if (cookie == null) { 192 | cookie = RegClientCookie(cookieName, "", CookieAccess_Protected); 193 | } 194 | return cookie; 195 | } 196 | 197 | /** 198 | * Sets the value of a client cookie given the cookie name. 199 | */ 200 | stock void SetCookieStringByName(int client, const char[] cookieName, const char[] value) { 201 | Handle cookie = FindNamedCookie(cookieName); 202 | SetClientCookie(client, cookie, value); 203 | delete cookie; 204 | } 205 | 206 | /** 207 | * Gets the value of a client cookie given the cookie name. 208 | */ 209 | stock void GetCookieStringByName(int client, const char[] cookieName, char[] buffer, int length) { 210 | Handle cookie = FindNamedCookie(cookieName); 211 | GetClientCookie(client, cookie, buffer, length); 212 | delete cookie; 213 | } 214 | 215 | /** 216 | * Sets a cookie to an integer value by converting it to a string. 217 | */ 218 | stock void SetCookieIntByName(int client, const char[] cookieName, int value) { 219 | char buffer[INTEGER_STRING_LENGTH]; 220 | IntToString(value, buffer, sizeof(buffer)); 221 | SetCookieStringByName(client, cookieName, buffer); 222 | } 223 | 224 | /** 225 | * Fetches the value of a cookie that is an integer. 226 | */ 227 | stock int GetCookieIntByName(int client, const char[] cookieName) { 228 | char buffer[INTEGER_STRING_LENGTH]; 229 | GetCookieStringByName(client, cookieName, buffer, sizeof(buffer)); 230 | return StringToInt(buffer); 231 | } 232 | 233 | /** 234 | * Sets a cookie to a boolean value. 235 | */ 236 | stock void SetCookieBoolByName(int client, const char[] cookieName, bool value) { 237 | int convertedInt = value ? 1 : 0; 238 | SetCookieIntByName(client, cookieName, convertedInt); 239 | } 240 | 241 | /** 242 | * Gets a cookie that represents a boolean. 243 | */ 244 | stock bool GetCookieBoolByName(int client, const char[] cookieName) { 245 | return GetCookieIntByName(client, cookieName) != 0; 246 | } 247 | 248 | /** 249 | * Sets a cookie to an integer value by converting it to a string. 250 | */ 251 | stock void SetCookieInt(int client, Handle cookie, int value) { 252 | char buffer[INTEGER_STRING_LENGTH]; 253 | IntToString(value, buffer, sizeof(buffer)); 254 | SetClientCookie(client, cookie, buffer); 255 | } 256 | 257 | /** 258 | * Fetches the value of a cookie that is an integer. 259 | */ 260 | stock int GetCookieInt(int client, Handle cookie, int defaultValue = 0) { 261 | char buffer[INTEGER_STRING_LENGTH]; 262 | GetClientCookie(client, cookie, buffer, sizeof(buffer)); 263 | if (StrEqual(buffer, "")) { 264 | return defaultValue; 265 | } 266 | 267 | return StringToInt(buffer); 268 | } 269 | 270 | /** 271 | * Sets a cookie to a boolean value. 272 | */ 273 | stock void SetCookieBool(int client, Handle cookie, bool value) { 274 | int convertedInt = value ? 1 : 0; 275 | SetCookieInt(client, cookie, convertedInt); 276 | } 277 | 278 | /** 279 | * Gets a cookie that represents a boolean. 280 | */ 281 | stock bool GetCookieBool(int client, Handle cookie, bool defaultValue = false) { 282 | return GetCookieInt(client, cookie, defaultValue) != 0; 283 | } 284 | 285 | stock bool Chance(float p) { 286 | float f = GetRandomFloat(); 287 | return f < p; 288 | } 289 | 290 | /** 291 | * Fills a buffer with the current map name, 292 | * with any directory information removed. 293 | * Example: de_dust2 instead of workshop/125351616/de_dust2 294 | */ 295 | stock void GetCleanMapName(char[] buffer, int size) { 296 | char mapName[PLATFORM_MAX_PATH + 1]; 297 | GetCurrentMap(mapName, sizeof(mapName)); 298 | int last_slash = 0; 299 | int len = strlen(mapName); 300 | for (int i = 0; i < len; i++) { 301 | if (mapName[i] == '/') 302 | last_slash = i + 1; 303 | } 304 | strcopy(buffer, size, mapName[last_slash]); 305 | } 306 | 307 | /** 308 | * Applies colorized characters across a string to replace color tags. 309 | */ 310 | stock void Colorize(char[] msg, int size, bool strip = false) { 311 | for (int i = 0; i < sizeof(g_ColorNames); i++) { 312 | if (strip) { 313 | ReplaceString(msg, size, g_ColorNames[i], "\x01"); 314 | } else { 315 | ReplaceString(msg, size, g_ColorNames[i], g_ColorCodes[i]); 316 | } 317 | } 318 | } 319 | 320 | stock bool InWarmup() { 321 | return GameRules_GetProp("m_bWarmupPeriod") != 0; 322 | } 323 | 324 | stock void EnsurePausedWarmup() { 325 | if (!InWarmup()) { 326 | StartPausedWarmup(); 327 | } 328 | 329 | ServerCommand("mp_warmup_pausetimer 1"); 330 | ServerCommand("mp_do_warmup_period 1"); 331 | ServerCommand("mp_warmup_pausetimer 1"); 332 | ServerCommand("mp_death_drop_gun 0"); 333 | } 334 | 335 | stock void StartPausedWarmup() { 336 | ServerCommand("mp_warmup_start"); 337 | ServerCommand("mp_warmuptime 120"); // this value must be greater than 6 or the warmup countdown 338 | // will always start 339 | ServerCommand("mp_warmup_pausetimer 1"); 340 | } 341 | 342 | stock void StartTimedWarmup(int time) { 343 | ServerCommand("mp_do_warmup_period 1"); 344 | ServerCommand("mp_warmup_pausetimer 0"); 345 | ServerCommand("mp_warmuptime %d", time); 346 | ServerCommand("mp_warmup_start"); 347 | ServerCommand("mp_warmup_start"); // don't ask. 348 | } 349 | 350 | stock void CopyList(ArrayList list1, ArrayList list2) { 351 | char buffer[ID_LENGTH]; 352 | for (int i = 0; i < list1.Length; i++) { 353 | list1.GetString(i, buffer, sizeof(buffer)); 354 | list2.PushString(buffer); 355 | } 356 | } 357 | 358 | stock int WipeFromList(ArrayList list, const char[] str) { 359 | int count = 0; 360 | for (int idx = list.FindString(str); idx >= 0; idx = list.FindString(str)) { 361 | count++; 362 | list.Erase(idx); 363 | } 364 | return count; 365 | } 366 | 367 | stock void AddRepeatedElement(ArrayList list, int element, int count = 1) { 368 | for (int i = 0; i < count; i++) { 369 | list.Push(element); 370 | } 371 | } 372 | 373 | stock void SetTeamMoveType(int team, MoveType moveType) { 374 | for (int i = 1; i <= MaxClients; i++) { 375 | if (IsPlayer(i) && GetClientTeam(i) == team) 376 | SetEntityMoveType(i, moveType); 377 | } 378 | } 379 | 380 | stock int CountArrayListOccurances(ArrayList list, int element) { 381 | int count = 0; 382 | for (int i = 0; i < list.Length; i++) { 383 | if (list.Get(i) == element) 384 | count++; 385 | } 386 | return count; 387 | } 388 | 389 | stock int GetOtherTeam(int team) { 390 | return (team == CS_TEAM_CT) ? CS_TEAM_T : CS_TEAM_CT; 391 | } 392 | 393 | stock Bombsite GetOtherSite(Bombsite site) { 394 | return (site == BombsiteA) ? BombsiteB : BombsiteA; 395 | } 396 | 397 | stock bool InFreezeTime() { 398 | return GameRules_GetProp("m_bFreezePeriod") != 0; 399 | } 400 | 401 | stock bool EnforceDirectoryExists(const char[] smPath) { 402 | char dir[PLATFORM_MAX_PATH + 1]; 403 | BuildPath(Path_SM, dir, sizeof(dir), smPath); 404 | if (!DirExists(dir)) { 405 | if (!CreateDirectory(dir, 511)) { 406 | LogError("Failed to create directory %s", dir); 407 | return false; 408 | } 409 | } 410 | return true; 411 | } -------------------------------------------------------------------------------- /scripting/executes/executes_config.sp: -------------------------------------------------------------------------------- 1 | /** 2 | * Reads the scenario keyvalues config file and sets up the global scenario and player arrays. 3 | */ 4 | public void ReadMapConfig() { 5 | g_DirtySpawns = false; 6 | char configFile[PLATFORM_MAX_PATH]; 7 | GetConfigFileName(configFile, sizeof(configFile)); 8 | 9 | g_NumSpawns = 0; 10 | g_NextSpawnId = 0; 11 | g_NextExecuteId = 0; 12 | g_NumExecutes = 0; 13 | 14 | if (!FileExists(configFile)) { 15 | LogMessage("The executes config file (%s) does not exist", configFile); 16 | return; 17 | } 18 | 19 | KeyValues kv = new KeyValues("Executes"); 20 | if (!kv.ImportFromFile(configFile)) { 21 | LogMessage("The executes config file was empty"); 22 | delete kv; 23 | return; 24 | } 25 | 26 | if (kv.JumpToKey("Spawns")) { 27 | if (kv.GotoFirstSubKey(false)) { 28 | ReadSpawns(kv); 29 | kv.GoBack(); 30 | } 31 | kv.GoBack(); 32 | } 33 | 34 | for (int i = 0; i < MAX_EXECUTES; i++) { 35 | g_ExecuteTSpawnsRequired[i].Clear(); 36 | g_ExecuteTSpawnsOptional[i].Clear(); 37 | } 38 | 39 | if (kv.JumpToKey("Executes")) { 40 | if (kv.GotoFirstSubKey(false)) { 41 | ReadExecutes(kv); 42 | kv.GoBack(); 43 | } 44 | kv.GoBack(); 45 | } 46 | } 47 | 48 | /** 49 | * Writes the stored scenario structures back to the config file. 50 | */ 51 | public void WriteMapConfig() { 52 | KeyValues kv = new KeyValues("Executes"); 53 | 54 | if (kv.JumpToKey("Spawns", true)) { 55 | WriteSpawns(kv); 56 | kv.GoBack(); 57 | } 58 | 59 | if (kv.JumpToKey("Executes", true)) { 60 | WriteExecutes(kv); 61 | kv.GoBack(); 62 | } 63 | 64 | char configFile[PLATFORM_MAX_PATH]; 65 | GetConfigFileName(configFile, sizeof(configFile)); 66 | DeleteFile(configFile); 67 | 68 | if (FileExists(configFile)) { 69 | if (!DeleteFile(configFile)) { 70 | LogError("Couldn't delete previous config %s", configFile); 71 | } 72 | } 73 | 74 | kv.Rewind(); 75 | EnforceDirectoryExists("configs/executes"); 76 | if (!kv.ExportToFile(configFile)) { 77 | LogError("Failed to write map config to %s", configFile); 78 | } 79 | delete kv; 80 | 81 | g_DirtySpawns = false; 82 | } 83 | 84 | static void ReadSpawns(KeyValues spawnsKv) { 85 | int spawn = 0; 86 | 87 | do { 88 | spawnsKv.GetSectionName(g_SpawnIDs[spawn], ID_LENGTH); 89 | spawnsKv.GetString("name", g_SpawnNames[spawn], SPAWN_NAME_LENGTH); 90 | spawnsKv.GetVector("origin", g_SpawnPoints[spawn], NULL_VECTOR); 91 | spawnsKv.GetVector("angle", g_SpawnAngles[spawn], NULL_VECTOR); 92 | spawnsKv.GetVector("grenadeOrigin", g_SpawnNadePoints[spawn], NULL_VECTOR); 93 | spawnsKv.GetVector("grenadeVelocity", g_SpawnNadeVelocities[spawn], NULL_VECTOR); 94 | 95 | g_SpawnGrenadeThrowTimes[spawn] = spawnsKv.GetNum("grenadeThrowTime", DEFAULT_THROWTIME); 96 | g_SpawnFlags[spawn] = spawnsKv.GetNum("flags", 0); 97 | 98 | g_SpawnSiteFriendly[spawn][BombsiteA] = ReadFriendliness(spawnsKv, "A_friendly"); 99 | g_SpawnSiteFriendly[spawn][BombsiteB] = ReadFriendliness(spawnsKv, "B_friendly"); 100 | g_SpawnAwpFriendly[spawn] = ReadFriendliness(spawnsKv, "awp_friendly"); 101 | g_SpawnBombFriendly[spawn] = ReadFriendliness(spawnsKv, "bomb_friendly"); 102 | g_SpawnLikelihood[spawn] = ReadFriendliness(spawnsKv, "likelihood"); 103 | 104 | char buffer[32]; 105 | spawnsKv.GetString("grenadeType", buffer, sizeof(buffer)); 106 | if (StrEqual(buffer, "smoke")) { 107 | g_SpawnGrenadeTypes[spawn] = GrenadeType_Smoke; 108 | } else if (StrEqual(buffer, "flash")) { 109 | g_SpawnGrenadeTypes[spawn] = GrenadeType_Flash; 110 | } else if (StrEqual(buffer, "molotov")) { 111 | g_SpawnGrenadeTypes[spawn] = GrenadeType_Molotov; 112 | } else if (StrEqual(buffer, "he")) { 113 | g_SpawnGrenadeTypes[spawn] = GrenadeType_HE; 114 | } else if (StrEqual(buffer, "decoy")) { 115 | g_SpawnGrenadeTypes[spawn] = GrenadeType_Decoy; 116 | } else { 117 | g_SpawnGrenadeTypes[spawn] = GrenadeType_None; 118 | } 119 | 120 | spawnsKv.GetString("team", buffer, sizeof(buffer), "T"); 121 | g_SpawnTeams[spawn] = (StrEqual(buffer, "CT", false)) ? CS_TEAM_CT : CS_TEAM_T; 122 | 123 | g_SpawnDeleted[spawn] = false; 124 | 125 | char excludedList[1024]; 126 | spawnsKv.GetString("excluded", excludedList, sizeof(excludedList)); 127 | AddSpawnExclusionsToList(excludedList, g_SpawnExclusionRules[spawn]); 128 | 129 | spawn++; 130 | g_NumSpawns = spawn; 131 | if (spawn == MAX_SPAWNS) { 132 | LogError("Hit the max number of spawns"); 133 | break; 134 | } 135 | 136 | } while (spawnsKv.GotoNextKey()); 137 | 138 | g_NextSpawnId = StringToInt(g_SpawnIDs[g_NumSpawns - 1]) + 1; 139 | } 140 | 141 | static void WriteSpawns(KeyValues spawnsKv) { 142 | for (int spawn = 0; spawn < g_NumSpawns; spawn++) { 143 | if (spawn == MAX_SPAWNS) { 144 | LogError("Hit the max number (%d) of spawns", MAX_SPAWNS); 145 | break; 146 | } 147 | 148 | if (g_SpawnDeleted[spawn]) 149 | continue; 150 | 151 | spawnsKv.JumpToKey(g_SpawnIDs[spawn], true); 152 | 153 | spawnsKv.SetString("name", g_SpawnNames[spawn]); 154 | spawnsKv.SetVector("origin", g_SpawnPoints[spawn]); 155 | spawnsKv.SetVector("angle", g_SpawnAngles[spawn]); 156 | spawnsKv.SetString("team", TEAMSTRING(g_SpawnTeams[spawn])); 157 | spawnsKv.SetNum("flags", g_SpawnFlags[spawn]); 158 | spawnsKv.SetNum("awp_friendly", g_SpawnAwpFriendly[spawn]); 159 | 160 | if (g_SpawnTeams[spawn] == CS_TEAM_CT) { 161 | spawnsKv.SetNum("A_friendly", g_SpawnSiteFriendly[spawn][BombsiteA]); 162 | spawnsKv.SetNum("B_friendly", g_SpawnSiteFriendly[spawn][BombsiteB]); 163 | spawnsKv.SetNum("likelihood", g_SpawnLikelihood[spawn]); 164 | } else { 165 | spawnsKv.SetNum("bomb_friendly", g_SpawnBombFriendly[spawn]); 166 | 167 | char buffer[32] = "none"; 168 | if (g_SpawnGrenadeTypes[spawn] == GrenadeType_Smoke) { 169 | buffer = "smoke"; 170 | } else if (g_SpawnGrenadeTypes[spawn] == GrenadeType_Flash) { 171 | buffer = "flash"; 172 | } else if (g_SpawnGrenadeTypes[spawn] == GrenadeType_Molotov) { 173 | buffer = "molotov"; 174 | } 175 | 176 | spawnsKv.SetString("grenadeType", buffer); 177 | if (!StrEqual(buffer, "none")) { 178 | spawnsKv.SetVector("grenadeOrigin", g_SpawnNadePoints[spawn]); 179 | spawnsKv.SetVector("grenadeVelocity", g_SpawnNadeVelocities[spawn]); 180 | spawnsKv.SetNum("grenadeThrowTime", g_SpawnGrenadeThrowTimes[spawn]); 181 | } 182 | } 183 | 184 | char excludedList[1024]; 185 | CollapseSpawnExclusionsToString(g_SpawnExclusionRules[spawn], excludedList, 186 | sizeof(excludedList)); 187 | spawnsKv.SetString("excluded", excludedList); 188 | 189 | spawnsKv.GoBack(); 190 | } 191 | } 192 | 193 | static void ReadExecutes(KeyValues executesKv) { 194 | int execute = 0; 195 | 196 | do { 197 | executesKv.GetSectionName(g_ExecuteIDs[execute], ID_LENGTH); 198 | executesKv.GetString("name", g_ExecuteNames[execute], EXECUTE_NAME_LENGTH); 199 | 200 | char buffer[32]; 201 | executesKv.GetString("site", buffer, sizeof(buffer), "A"); 202 | g_ExecuteSites[execute] = (StrEqual(buffer, "A", false)) ? BombsiteA : BombsiteB; 203 | g_ExecuteLikelihood[execute] = ReadFriendliness(executesKv, "likelihood"); 204 | executesKv.GetString("forcebomb_id", g_ExecuteForceBombId[execute], ID_LENGTH, ""); 205 | 206 | g_ExecuteStratTypes[execute][StratType_Normal] = (executesKv.GetNum("strat_normal", 1) != 0); 207 | g_ExecuteStratTypes[execute][StratType_Pistol] = (executesKv.GetNum("strat_pistol", 0) != 0); 208 | g_ExecuteStratTypes[execute][StratType_ForceBuy] = (executesKv.GetNum("strat_force", 0) != 0); 209 | g_ExecuteFake[execute] = (executesKv.GetNum("fake") != 0); 210 | g_ExecuteExtraFreezeTime[execute] = 211 | executesKv.GetFloat("extra_freeze_time", g_ExtraFreezeTimeCvar.FloatValue); 212 | 213 | g_ExecuteDeleted[execute] = false; 214 | 215 | ReadExecuteSpawnsHelper("t_players", executesKv, g_ExecuteTSpawnsRequired[execute], 216 | g_ExecuteTSpawnsOptional[execute]); 217 | 218 | execute++; 219 | g_NumExecutes = execute; 220 | if (execute == MAX_SPAWNS) { 221 | LogError("Hit the max number of executes"); 222 | break; 223 | } 224 | 225 | } while (executesKv.GotoNextKey()); 226 | 227 | g_NextExecuteId = StringToInt(g_ExecuteIDs[g_NumExecutes - 1]) + 1; 228 | } 229 | 230 | static void ReadExecuteSpawnsHelper(const char[] section, KeyValues kv, ArrayList required, 231 | ArrayList optional) { 232 | required.Clear(); 233 | optional.Clear(); 234 | 235 | if (kv.JumpToKey(section)) { 236 | if (kv.GotoFirstSubKey(false)) { 237 | char id[ID_LENGTH]; 238 | char buffer[32]; 239 | do { 240 | kv.GetSectionName(id, sizeof(id)); 241 | kv.GetString(NULL_STRING, buffer, sizeof(buffer)); 242 | int spawnIndex = SpawnIdToIndex(id); 243 | if (IsValidSpawn(spawnIndex)) { 244 | if (StrEqual(buffer, "required", false)) { 245 | required.PushString(id); 246 | } else if (StrEqual(buffer, "optional", false)) { 247 | optional.PushString(id); 248 | } 249 | } else { 250 | LogError("Spawn id %s does not exist, but used in an execute!", id); 251 | } 252 | } while (kv.GotoNextKey(false)); 253 | kv.GoBack(); 254 | } 255 | kv.GoBack(); 256 | } 257 | } 258 | 259 | static void WriteExecutes(KeyValues executesKv) { 260 | for (int execute = 0; execute < g_NumExecutes; execute++) { 261 | if (execute == MAX_EXECUTES) { 262 | LogError("Hit the max number (%d) of executes", MAX_EXECUTES); 263 | break; 264 | } 265 | 266 | if (g_ExecuteDeleted[execute]) 267 | continue; 268 | 269 | executesKv.JumpToKey(g_ExecuteIDs[execute], true); 270 | executesKv.SetString("name", g_ExecuteNames[execute]); 271 | executesKv.SetString("site", SITESTRING(g_ExecuteSites[execute])); 272 | executesKv.SetNum("likelihood", g_ExecuteLikelihood[execute]); 273 | executesKv.SetString("forcebomb_id", g_ExecuteForceBombId[execute]); 274 | executesKv.SetNum("strat_normal", g_ExecuteStratTypes[execute][StratType_Normal]); 275 | executesKv.SetNum("strat_pistol", g_ExecuteStratTypes[execute][StratType_Pistol]); 276 | executesKv.SetNum("strat_force", g_ExecuteStratTypes[execute][StratType_ForceBuy]); 277 | executesKv.SetNum("fake", g_ExecuteFake[execute]); 278 | 279 | float delta = g_ExecuteExtraFreezeTime[execute] - g_ExtraFreezeTimeCvar.FloatValue; 280 | if (delta < 0.01 && -delta < 0.01) 281 | executesKv.SetFloat("extra_freeze_time", g_ExecuteExtraFreezeTime[execute]); 282 | 283 | WriteExecuteSpawnsHelper("t_players", executesKv, g_ExecuteTSpawnsRequired[execute], 284 | g_ExecuteTSpawnsOptional[execute]); 285 | 286 | executesKv.GoBack(); 287 | } 288 | } 289 | 290 | static void WriteExecuteSpawnsHelper(const char[] section, KeyValues kv, ArrayList required, 291 | ArrayList optional) { 292 | char id[ID_LENGTH]; 293 | if (kv.JumpToKey(section, true)) { 294 | for (int i = 0; i < required.Length; i++) { 295 | required.GetString(i, id, sizeof(id)); 296 | kv.SetString(id, "required"); 297 | } 298 | for (int i = 0; i < optional.Length; i++) { 299 | optional.GetString(i, id, sizeof(id)); 300 | kv.SetString(id, "optional"); 301 | } 302 | kv.GoBack(); 303 | } 304 | } 305 | 306 | public int SpawnIdToIndex(const char[] id) { 307 | for (int i = 0; i < g_NumSpawns; i++) { 308 | if (StrEqual(id, g_SpawnIDs[i])) { 309 | if (g_SpawnDeleted[i]) 310 | return -1; 311 | 312 | return i; 313 | } 314 | } 315 | return -1; 316 | } 317 | 318 | public int ExecuteIdToIndex(const char[] id) { 319 | for (int i = 0; i < g_NumExecutes; i++) { 320 | if (StrEqual(id, g_ExecuteIDs[i])) { 321 | if (g_ExecuteDeleted[i]) 322 | return -1; 323 | 324 | return i; 325 | } 326 | } 327 | return -1; 328 | } 329 | 330 | public bool IsValidSpawn(int index) { 331 | return index >= 0 && index < g_NumSpawns && !g_SpawnDeleted[index]; 332 | } 333 | 334 | public bool IsValidExecute(int index) { 335 | return index >= 0 && index < g_NumExecutes && !g_ExecuteDeleted[index]; 336 | } 337 | 338 | static void GetConfigFileName(char[] buffer, int size) { 339 | // Get the map, with any workshop stuff before removed 340 | char mapName[128]; 341 | GetCleanMapName(mapName, sizeof(mapName)); 342 | BuildPath(Path_SM, buffer, size, "configs/executes/%s.cfg", mapName); 343 | } 344 | 345 | stock int ReadFriendliness(KeyValues kv, const char[] name, int defaultValue = AVG_FRIENDLINESS) { 346 | int value = kv.GetNum(name, defaultValue); 347 | if (value < MIN_FRIENDLINESS) 348 | return MIN_FRIENDLINESS; 349 | else if (value > MAX_FRIENDLINESS) 350 | return MAX_FRIENDLINESS; 351 | else 352 | return value; 353 | } 354 | 355 | public int AddSpawnExclusionsToList(const char[] inputString, ArrayList list) { 356 | const int maxSpawns = 10; 357 | char parts[maxSpawns][ID_LENGTH]; 358 | int foundSpawns = ExplodeString(inputString, ";", parts, maxSpawns, ID_LENGTH); 359 | for (int i = 0; i < foundSpawns; i++) { 360 | if (!StrEqual(parts[i], "")) { 361 | list.Push(SpawnIdToIndex(parts[i])); 362 | } 363 | } 364 | return foundSpawns; 365 | } 366 | 367 | public void CollapseSpawnExclusionsToString(ArrayList list, char[] output, int len) { 368 | for (int i = 0; i < list.Length; i++) { 369 | StrCat(output, len, g_SpawnIDs[list.Get(i)]); 370 | StrCat(output, len, ";"); 371 | } 372 | } 373 | -------------------------------------------------------------------------------- /scripting/executes/editor.sp: -------------------------------------------------------------------------------- 1 | int g_iBeamSprite; 2 | int g_iHaloSprite; 3 | 4 | public void StartEditMode() { 5 | g_EditMode = true; 6 | StartPausedWarmup(); 7 | 8 | for (int i = 1; i <= MaxClients; i++) { 9 | if (IsValidClient(i) && !IsFakeClient(i)) { 10 | MovePlayerToEditMode(i); 11 | } 12 | } 13 | 14 | Executes_MessageToAll("Edit mode launched, type !edit to open the edit menu"); 15 | 16 | g_EditingExecutes = false; 17 | g_EditingASpawn = false; 18 | g_EditingAnExecute = false; 19 | 20 | if (LibraryExists("practicemode")) { 21 | PM_StartPracticeMode(); 22 | } 23 | 24 | ServerCommand("sv_infinite_ammo 1"); 25 | } 26 | 27 | public void ExitEditMode() { 28 | g_EditMode = false; 29 | 30 | if (LibraryExists("practicemode")) { 31 | PM_ExitPracticeMode(); 32 | } 33 | 34 | ServerCommand("sv_infinite_ammo 0"); 35 | 36 | if (InWarmup()) { 37 | ServerCommand("mp_warmup_end"); 38 | } else { 39 | ServerCommand("mp_restartgame 1"); 40 | } 41 | } 42 | 43 | public void CSU_OnThrowGrenade(int client, int entity, GrenadeType grenadeType, const float origin[3], 44 | const float velocity[3]) { 45 | LogDebug("CSU_OnThrowGrenade %L %d", client, grenadeType); 46 | if (g_EditMode && CheckCommandAccess(client, "sm_edit", ADMFLAG_CHANGEMAP)) { 47 | g_EditingSpawnGrenadeType = grenadeType; 48 | g_EditingSpawnNadePoint = origin; 49 | g_EditingSpawnNadeVelocity = velocity; 50 | 51 | // TODO: add a way to disable this 52 | if (!g_EditingExecutes) { 53 | GiveNewSpawnMenu(client); 54 | } 55 | } 56 | } 57 | 58 | public void MovePlayerToEditMode(int client) { 59 | SwitchPlayerTeam(client, CS_TEAM_T); 60 | CS_RespawnPlayer(client); 61 | } 62 | 63 | // public void ShowSpawns(Bombsite site) { 64 | // g_EditingSite = site; 65 | // Executes_MessageToAll("Showing spawns for bombsite \x04%s.", SITESTRING(site)); 66 | 67 | // int ct_count = 0; 68 | // int t_count = 0; 69 | // for (int i = 0; i < g_NumSpawns; i++) { 70 | // if (!g_SpawnDeleted[i]) { 71 | // if (g_SpawnTeams[i] == CS_TEAM_CT) { 72 | // ct_count++; 73 | // } else { 74 | // t_count++; 75 | // } 76 | // } 77 | // } 78 | // Executes_MessageToAll("Found %d CT spawns.", ct_count); 79 | // Executes_MessageToAll("Found %d T spawns.", t_count); 80 | // } 81 | 82 | public Action Timer_ShowSpawns(Handle timer) { 83 | if (!g_EditMode || g_hEditorEnabled.IntValue == 0 || !g_ShowingEditorInformation) 84 | return Plugin_Continue; 85 | 86 | g_iBeamSprite = PrecacheModel("sprites/laserbeam.vmt", true); 87 | g_iHaloSprite = PrecacheModel("sprites/halo.vmt", true); 88 | float origin[3]; 89 | float angle[3]; 90 | 91 | for (int i = 1; i <= MaxClients; i++) { 92 | if (!IsValidClient(i) || IsFakeClient(i)) { 93 | continue; 94 | } 95 | 96 | for (int j = 0; j < g_NumSpawns; j++) { 97 | origin = g_SpawnPoints[j]; 98 | angle = g_SpawnPoints[j]; 99 | if (!g_SpawnDeleted[j]) { 100 | DisplaySpawnPoint(i, origin, angle, 40.0, g_SpawnTeams[j] == CS_TEAM_CT); 101 | } 102 | } 103 | } 104 | 105 | return Plugin_Continue; 106 | } 107 | 108 | public Action Timer_ShowClosestSpawn(Handle timer) { 109 | if (!g_EditMode || g_hEditorEnabled.IntValue == 0 || !g_ShowingEditorInformation) 110 | return Plugin_Continue; 111 | 112 | for (int i = 1; i <= MaxClients; i++) { 113 | if (!IsValidClient(i) || IsFakeClient(i)) { 114 | continue; 115 | } 116 | 117 | int closest = FindClosestSpawn(i); 118 | if (closest > 0) { 119 | bool ct = g_SpawnTeams[closest] == CS_TEAM_CT; 120 | // TODO: color this text red/blue whether ct or T 121 | PrintHintText(i, "%s Spawn %s: \"%s\"", ct ? "CT" : "T", g_SpawnIDs[closest], 122 | g_SpawnNames[closest]); 123 | } 124 | } 125 | 126 | return Plugin_Continue; 127 | } 128 | 129 | stock bool SpawnFilter(int spawn) { 130 | if (!IsValidSpawn(spawn) || g_SpawnDeleted[spawn]) { 131 | return false; 132 | } 133 | 134 | // if (g_SpawnSites[spawn] != g_EditingSite) { 135 | // return false; 136 | // } 137 | 138 | return true; 139 | } 140 | 141 | stock void AddSpawn(int client) { 142 | g_DirtySpawns = true; 143 | if (g_NumSpawns + 1 >= MAX_SPAWNS) { 144 | Executes_MessageToAll( 145 | "{DARK_RED}WARNING: {NORMAL}the maximum number of spawns has been reached. New spawns cannot be added."); 146 | LogError("Maximum number of spawns reached"); 147 | return; 148 | } 149 | 150 | int spawnIndex = g_NumSpawns; 151 | if (g_EditingASpawn) { 152 | spawnIndex = g_EditingSpawnIndex; 153 | } 154 | 155 | strcopy(g_SpawnNames[spawnIndex], SPAWN_NAME_LENGTH, g_TempNameBuffer); 156 | 157 | if (!g_EditingASpawn) { 158 | IntToString(g_NextSpawnId, g_SpawnIDs[spawnIndex], ID_LENGTH); 159 | g_NextSpawnId++; 160 | } 161 | 162 | GetClientAbsOrigin(client, g_SpawnPoints[spawnIndex]); 163 | GetClientEyeAngles(client, g_SpawnAngles[spawnIndex]); 164 | g_SpawnTeams[spawnIndex] = g_EditingSpawnTeam; 165 | g_SpawnGrenadeTypes[spawnIndex] = g_EditingSpawnGrenadeType; 166 | 167 | g_SpawnNadePoints[spawnIndex] = g_EditingSpawnNadePoint; 168 | g_SpawnNadeVelocities[spawnIndex] = g_EditingSpawnNadeVelocity; 169 | g_SpawnSiteFriendly[spawnIndex] = g_EditingSpawnSiteFriendly; 170 | g_SpawnAwpFriendly[spawnIndex] = g_EditingSpawnAwpFriendly; 171 | g_SpawnBombFriendly[spawnIndex] = g_EditingSpawnBombFriendly; 172 | g_SpawnLikelihood[spawnIndex] = g_EditingSpawnLikelihood; 173 | g_SpawnGrenadeThrowTimes[spawnIndex] = g_EditingSpawnThrowTime; 174 | g_SpawnFlags[spawnIndex] = g_EditingSpawnFlags; 175 | 176 | g_SpawnDeleted[spawnIndex] = false; 177 | ClearSpawnBuffers(); 178 | 179 | if (!g_EditingASpawn) { 180 | Executes_MessageToAll("Added %s spawn (id:%s).", TEAMSTRING(g_EditingSpawnTeam), 181 | g_SpawnIDs[spawnIndex]); 182 | 183 | g_NumSpawns++; 184 | } else { 185 | Executes_MessageToAll("Edited %s spawn (id:%s).", TEAMSTRING(g_EditingSpawnTeam), 186 | g_SpawnIDs[spawnIndex]); 187 | } 188 | 189 | g_EditingASpawn = false; 190 | g_EditingSpawnThrowTime = DEFAULT_THROWTIME; 191 | g_EditingSpawnFlags = 0; 192 | g_EditingSpawnGrenadeType = GrenadeType_None; 193 | } 194 | 195 | public void ClearSpawnBuffers() { 196 | Format(g_TempNameBuffer, sizeof(g_TempNameBuffer), ""); 197 | } 198 | 199 | public void ClearExecuteBuffers() { 200 | Format(g_EditingExecuteForceBombId, sizeof(g_EditingExecuteForceBombId), ""); 201 | Format(g_TempNameBuffer, sizeof(g_TempNameBuffer), ""); 202 | g_EditingExecuteTRequired.Clear(); 203 | g_EditingExecuteTOptional.Clear(); 204 | g_EditingExecuteStratTypes[StratType_Normal] = true; 205 | g_EditingExecuteStratTypes[StratType_Pistol] = false; 206 | g_EditingExecuteStratTypes[StratType_ForceBuy] = false; 207 | g_EditingExecuteFake = false; 208 | } 209 | 210 | public void AddExecute(int client) { 211 | g_DirtySpawns = true; 212 | if (g_NumExecutes + 1 >= MAX_EXECUTES) { 213 | Executes_MessageToAll( 214 | "{DARK_RED}WARNING: {NORMAL}the maximum number of spawns has been reached. New spawns cannot be added."); 215 | LogError("Maximum number of spawns reached"); 216 | return; 217 | } 218 | 219 | int execIndex = g_NumExecutes; 220 | if (g_EditingAnExecute) { 221 | execIndex = g_EditingExecuteIndex; 222 | } 223 | 224 | strcopy(g_ExecuteNames[execIndex], EXECUTE_NAME_LENGTH, g_TempNameBuffer); 225 | 226 | if (!g_EditingAnExecute) { 227 | IntToString(g_NextExecuteId, g_ExecuteIDs[execIndex], ID_LENGTH); 228 | g_NextExecuteId++; 229 | } 230 | 231 | g_ExecuteLikelihood[execIndex] = AVG_FRIENDLINESS; 232 | g_ExecuteSites[execIndex] = g_EditingExecuteSite; 233 | g_ExecuteDeleted[execIndex] = false; 234 | g_ExecuteLikelihood[execIndex] = g_EditingExecuteLikelihood; 235 | strcopy(g_ExecuteForceBombId[execIndex], ID_LENGTH, g_EditingExecuteForceBombId); 236 | 237 | g_ExecuteTSpawnsRequired[execIndex].Clear(); 238 | g_ExecuteTSpawnsOptional[execIndex].Clear(); 239 | CopyList(g_EditingExecuteTRequired, g_ExecuteTSpawnsRequired[execIndex]); 240 | CopyList(g_EditingExecuteTOptional, g_ExecuteTSpawnsOptional[execIndex]); 241 | g_ExecuteStratTypes[execIndex] = g_EditingExecuteStratTypes; 242 | g_ExecuteFake[execIndex] = g_EditingExecuteFake; 243 | 244 | ClearExecuteBuffers(); 245 | 246 | if (!g_EditingAnExecute) { 247 | Executes_MessageToAll("Added %s execute (id:%s).", SITESTRING(g_EditingExecuteSite), 248 | g_ExecuteIDs[execIndex]); 249 | g_NumExecutes++; 250 | } else { 251 | Executes_MessageToAll("Edited %s execute (id:%s).", SITESTRING(g_EditingExecuteSite), 252 | g_ExecuteIDs[execIndex]); 253 | } 254 | 255 | g_EditingAnExecute = false; 256 | g_EditingExecuteLikelihood = AVG_FRIENDLINESS; 257 | } 258 | 259 | public void DisplaySpawnPoint(int client, const float position[3], const float angles[3], float size, 260 | bool ct) { 261 | float direction[3]; 262 | GetAngleVectors(angles, direction, NULL_VECTOR, NULL_VECTOR); 263 | ScaleVector(direction, size / 2); 264 | AddVectors(position, direction, direction); 265 | 266 | int r, g, b; 267 | if (ct) { 268 | // blue 269 | r = 0; 270 | g = 0; 271 | b = 255; 272 | } else { 273 | // red 274 | r = 255; 275 | g = 0; 276 | b = 0; 277 | } 278 | 279 | TE_Start("BeamRingPoint"); 280 | TE_WriteVector("m_vecCenter", position); 281 | TE_WriteFloat("m_flStartRadius", 10.0); 282 | TE_WriteFloat("m_flEndRadius", size); 283 | TE_WriteNum("m_nModelIndex", g_iBeamSprite); 284 | TE_WriteNum("m_nHaloIndex", g_iHaloSprite); 285 | TE_WriteNum("m_nStartFrame", 0); 286 | TE_WriteNum("m_nFrameRate", 0); 287 | TE_WriteFloat("m_fLife", 1.0); 288 | TE_WriteFloat("m_fWidth", 1.0); 289 | TE_WriteFloat("m_fEndWidth", 1.0); 290 | TE_WriteFloat("m_fAmplitude", 0.0); 291 | TE_WriteNum("r", r); 292 | TE_WriteNum("g", g); 293 | TE_WriteNum("b", b); 294 | TE_WriteNum("a", 255); 295 | TE_WriteNum("m_nSpeed", 50); 296 | TE_WriteNum("m_nFlags", 0); 297 | TE_WriteNum("m_nFadeLength", 0); 298 | TE_SendToClient(client); 299 | 300 | TE_Start("BeamPoints"); 301 | TE_WriteVector("m_vecStartPoint", position); 302 | TE_WriteVector("m_vecEndPoint", direction); 303 | TE_WriteNum("m_nModelIndex", g_iBeamSprite); 304 | TE_WriteNum("m_nHaloIndex", g_iHaloSprite); 305 | TE_WriteNum("m_nStartFrame", 0); 306 | TE_WriteNum("m_nFrameRate", 0); 307 | TE_WriteFloat("m_fLife", 1.0); 308 | TE_WriteFloat("m_fWidth", 1.0); 309 | TE_WriteFloat("m_fEndWidth", 1.0); 310 | TE_WriteFloat("m_fAmplitude", 0.0); 311 | TE_WriteNum("r", r); 312 | TE_WriteNum("g", g); 313 | TE_WriteNum("b", b); 314 | TE_WriteNum("a", 255); 315 | TE_WriteNum("m_nSpeed", 50); 316 | TE_WriteNum("m_nFlags", 0); 317 | TE_WriteNum("m_nFadeLength", 0); 318 | TE_SendToClient(client); 319 | } 320 | 321 | stock int FindClosestSpawn(int client) { 322 | int closest = -1; 323 | float minDist = 0.0; 324 | for (int i = 0; i < g_NumSpawns; i++) { 325 | if (!SpawnFilter(i)) { 326 | continue; 327 | } 328 | 329 | float origin[3]; 330 | origin = g_SpawnPoints[i]; 331 | 332 | float playerOrigin[3]; 333 | GetClientAbsOrigin(client, playerOrigin); 334 | 335 | float dist = GetVectorDistance(origin, playerOrigin); 336 | if (closest < 0 || dist < minDist) { 337 | minDist = dist; 338 | closest = i; 339 | } 340 | } 341 | return closest; 342 | } 343 | 344 | public int CountSpawnUse(int spawn) { 345 | int count = 0; 346 | for (int i = 0; i < g_NumExecutes; i++) { 347 | if (!g_ExecuteDeleted[i]) { 348 | bool required = g_ExecuteTSpawnsRequired[i].FindString(g_SpawnIDs[spawn]) >= 0; 349 | bool opt = g_ExecuteTSpawnsOptional[i].FindString(g_SpawnIDs[spawn]) >= 0; 350 | if (required || opt) { 351 | count++; 352 | } 353 | } 354 | } 355 | return count; 356 | } 357 | 358 | public void DeleteClosestSpawn(int client) { 359 | g_DirtySpawns = true; 360 | int closestSpawnIndex = FindClosestSpawn(client); 361 | if (IsValidSpawn(closestSpawnIndex)) { 362 | int useCount = CountSpawnUse(closestSpawnIndex); 363 | if (useCount >= 1) { 364 | Executes_MessageToAll("Cannot delete spawn since it is used in %d executes.", useCount); 365 | } else { 366 | Executes_MessageToAll("Deleted spawn id %s.", g_SpawnIDs[closestSpawnIndex]); 367 | g_SpawnDeleted[closestSpawnIndex] = true; 368 | } 369 | } 370 | } 371 | 372 | public void SaveMapData() { 373 | WriteMapConfig(); 374 | Executes_MessageToAll("Saved map data, %d spawns, %d executes.", g_NumSpawns, g_NumExecutes); 375 | } 376 | 377 | public void ReloadMapData() { 378 | ReadMapConfig(); 379 | Executes_MessageToAll("Reloaded map data, got %d spawns, %d executes.", g_NumSpawns, 380 | g_NumExecutes); 381 | } 382 | 383 | public void MoveToSpawnInEditor(int client, int spawnIndex) { 384 | TeleportEntity(client, g_SpawnPoints[spawnIndex], g_SpawnAngles[spawnIndex], NULL_VECTOR); 385 | Executes_Message(client, "Teleporting to spawn id: {GREEN}%s", g_SpawnIDs[spawnIndex]); 386 | Executes_Message(client, " Name: {MOSS_GREEN}%s", g_SpawnNames[spawnIndex]); 387 | Executes_Message(client, " Team: {MOSS_GREEN}%s", TEAMSTRING(g_SpawnTeams[spawnIndex])); 388 | } 389 | 390 | public void GrenadeTypeName(GrenadeType grenadeType, char[] buf, int len) { 391 | switch (grenadeType) { 392 | case GrenadeType_Smoke: 393 | Format(buf, len, "smoke"); 394 | case GrenadeType_Flash: 395 | Format(buf, len, "flash"); 396 | case GrenadeType_Molotov: 397 | Format(buf, len, "molotov"); 398 | case GrenadeType_HE: 399 | Format(buf, len, "he"); 400 | case GrenadeType_Decoy: 401 | Format(buf, len, "decoy"); 402 | default: 403 | Format(buf, len, "none"); 404 | } 405 | } 406 | 407 | public Action Command_ClearBuffers(int client, int args) { 408 | ClearEditBuffers(); 409 | return Plugin_Handled; 410 | } 411 | 412 | public void ClearEditBuffers() { 413 | g_EditingSpawnGrenadeType = GrenadeType_None; 414 | ClearSpawnBuffers(); 415 | ClearExecuteBuffers(); 416 | } 417 | 418 | public Action Command_ExecuteDistribution(int client, int args) { 419 | if (g_NumExecutes == 0) { 420 | ReplyToCommand(client, "No executes found"); 421 | } else { 422 | char arg[32]; 423 | if (args >= 1 && GetCmdArg(1, arg, sizeof(arg))) { 424 | int numt = StringToInt(arg); 425 | 426 | ArrayList potentialExecutes = new ArrayList(); 427 | for (int i = 0; i < g_NumExecutes; i++) { 428 | int weight = ExecuteValid(numt, 5, i); 429 | AddRepeatedElement(potentialExecutes, i, weight); 430 | } 431 | 432 | for (int i = 0; i < g_NumExecutes; i++) { 433 | if (!g_ExecuteDeleted[i]) { 434 | float p = float(CountArrayListOccurances(potentialExecutes, i)) / 435 | float(potentialExecutes.Length); 436 | ReplyToCommand(client, "Execute \"%s\": %s, has likelihood %.1f%%", g_ExecuteIDs[i], 437 | g_ExecuteNames[i], 100.0 * p); 438 | } 439 | } 440 | 441 | delete potentialExecutes; 442 | 443 | } else { 444 | ReplyToCommand(client, "Usage: sm_execute_distrubtion "); 445 | } 446 | } 447 | return Plugin_Handled; 448 | } 449 | 450 | public Action Command_EditorInfo(int client, int args) { 451 | g_ShowingEditorInformation = !g_ShowingEditorInformation; 452 | } 453 | -------------------------------------------------------------------------------- /configs/executes/de_dust2.cfg: -------------------------------------------------------------------------------- 1 | "Executes" 2 | { 3 | "Spawns" 4 | { 5 | "0" 6 | { 7 | "name" "Pit" 8 | "origin" "1350.702271 698.976807 -31.040985" 9 | "angle" "-1.666507 170.443970 0.000000" 10 | "team" "CT" 11 | "flags" "0" 12 | "awp_friendly" "1" 13 | "A_friendly" "4" 14 | "B_friendly" "1" 15 | "likelihood" "3" 16 | "close" "0" 17 | "site" "any" 18 | } 19 | "1" 20 | { 21 | "name" "Long corner" 22 | "origin" "1405.932007 1335.119995 -11.316048" 23 | "angle" "-0.693012 -141.095291 0.000000" 24 | "team" "CT" 25 | "flags" "0" 26 | "awp_friendly" "1" 27 | "A_friendly" "4" 28 | "B_friendly" "1" 29 | "likelihood" "3" 30 | "close" "0" 31 | "site" "any" 32 | } 33 | "2" 34 | { 35 | "name" "Car" 36 | "origin" "1766.291870 2029.986206 1.278505" 37 | "angle" "-4.702497 175.641205 0.000000" 38 | "team" "CT" 39 | "flags" "0" 40 | "awp_friendly" "5" 41 | "A_friendly" "5" 42 | "B_friendly" "2" 43 | "likelihood" "3" 44 | "close" "0" 45 | "site" "any" 46 | } 47 | "3" 48 | { 49 | "name" "A ramp" 50 | "origin" "1366.641235 2601.421387 77.857979" 51 | "angle" "-1.633408 -164.822601 0.000000" 52 | "team" "CT" 53 | "flags" "16" 54 | "awp_friendly" "4" 55 | "A_friendly" "5" 56 | "B_friendly" "2" 57 | "likelihood" "3" 58 | "close" "0" 59 | "site" "any" 60 | } 61 | "4" 62 | { 63 | "name" "Goose" 64 | "origin" "1088.267090 2998.743408 129.295868" 65 | "angle" "2.904070 -104.894669 0.000000" 66 | "team" "CT" 67 | "flags" "0" 68 | "awp_friendly" "3" 69 | "A_friendly" "5" 70 | "B_friendly" "2" 71 | "likelihood" "3" 72 | "close" "0" 73 | "site" "any" 74 | } 75 | "5" 76 | { 77 | "name" "A side of CT" 78 | "origin" "961.402527 2056.017090 -10.847634" 79 | "angle" "-10.361899 178.198639 0.000000" 80 | "team" "CT" 81 | "flags" "0" 82 | "awp_friendly" "1" 83 | "A_friendly" "5" 84 | "B_friendly" "3" 85 | "likelihood" "3" 86 | "close" "0" 87 | "site" "any" 88 | } 89 | "6" 90 | { 91 | "name" "CT spawn" 92 | "origin" "166.637024 2302.480957 -118.968773" 93 | "angle" "0.709579 -147.464798 0.000000" 94 | "team" "CT" 95 | "flags" "16" 96 | "awp_friendly" "3" 97 | "A_friendly" "3" 98 | "B_friendly" "3" 99 | "likelihood" "3" 100 | "close" "0" 101 | "site" "any" 102 | } 103 | "7" 104 | { 105 | "name" "CT spawn cubby" 106 | "origin" "-192.407700 2013.880737 -123.562546" 107 | "angle" "2.524579 -168.964340 0.000000" 108 | "team" "CT" 109 | "flags" "0" 110 | "awp_friendly" "1" 111 | "A_friendly" "3" 112 | "B_friendly" "3" 113 | "likelihood" "3" 114 | "close" "1" 115 | "site" "any" 116 | } 117 | "8" 118 | { 119 | "name" "Mid doors cubby" 120 | "origin" "-279.001862 1750.754639 -100.233055" 121 | "angle" "8.926600 -151.095123 0.000000" 122 | "team" "CT" 123 | "flags" "0" 124 | "awp_friendly" "1" 125 | "A_friendly" "3" 126 | "B_friendly" "3" 127 | "likelihood" "1" 128 | "close" "0" 129 | "site" "any" 130 | } 131 | "9" 132 | { 133 | "name" "Window" 134 | "origin" "-1303.162231 2675.962402 130.031250" 135 | "angle" "13.414613 -38.733376 0.000000" 136 | "team" "CT" 137 | "flags" "0" 138 | "awp_friendly" "3" 139 | "A_friendly" "2" 140 | "B_friendly" "4" 141 | "likelihood" "1" 142 | "close" "0" 143 | "site" "any" 144 | } 145 | "10" 146 | { 147 | "name" "B boxes" 148 | "origin" "-1218.005005 2185.482910 5.272250" 149 | "angle" "10.741611 -10.006851 0.000000" 150 | "team" "CT" 151 | "flags" "0" 152 | "awp_friendly" "3" 153 | "A_friendly" "2" 154 | "B_friendly" "4" 155 | "likelihood" "1" 156 | "close" "1" 157 | "site" "any" 158 | } 159 | "11" 160 | { 161 | "name" "B car" 162 | "origin" "-1616.790894 1640.266846 2.670927" 163 | "angle" "-1.385936 121.072334 0.000000" 164 | "team" "CT" 165 | "flags" "0" 166 | "awp_friendly" "1" 167 | "A_friendly" "1" 168 | "B_friendly" "5" 169 | "likelihood" "3" 170 | "close" "0" 171 | "site" "any" 172 | } 173 | "12" 174 | { 175 | "name" "B plat" 176 | "origin" "-1769.801392 2685.990967 33.035950" 177 | "angle" "2.095563 -114.745667 0.000000" 178 | "team" "CT" 179 | "flags" "0" 180 | "awp_friendly" "1" 181 | "A_friendly" "1" 182 | "B_friendly" "5" 183 | "likelihood" "4" 184 | "close" "1" 185 | "site" "any" 186 | } 187 | "13" 188 | { 189 | "name" "Back B plat" 190 | "origin" "-2071.871338 2984.193115 33.515884" 191 | "angle" "-0.263937 -85.111603 0.000000" 192 | "team" "CT" 193 | "flags" "0" 194 | "awp_friendly" "1" 195 | "A_friendly" "1" 196 | "B_friendly" "5" 197 | "likelihood" "4" 198 | "close" "0" 199 | "site" "any" 200 | } 201 | "14" 202 | { 203 | "name" "B site" 204 | "origin" "-1392.322754 2781.637695 17.075352" 205 | "angle" "-0.890934 -119.481110 0.000000" 206 | "team" "CT" 207 | "flags" "0" 208 | "awp_friendly" "1" 209 | "A_friendly" "1" 210 | "B_friendly" "5" 211 | "likelihood" "3" 212 | "close" "0" 213 | "site" "any" 214 | } 215 | "15" 216 | { 217 | "name" "B double stack" 218 | "origin" "-1698.995117 2622.608154 7.638706" 219 | "angle" "0.280566 -98.971596 0.000000" 220 | "team" "CT" 221 | "flags" "1" 222 | "awp_friendly" "1" 223 | "A_friendly" "1" 224 | "B_friendly" "5" 225 | "likelihood" "3" 226 | "close" "0" 227 | "site" "any" 228 | } 229 | "16" 230 | { 231 | "name" "B doors" 232 | "origin" "-1334.731201 2267.263428 2.229717" 233 | "angle" "-2.144934 -145.451828 0.000000" 234 | "team" "CT" 235 | "flags" "0" 236 | "awp_friendly" "1" 237 | "A_friendly" "1" 238 | "B_friendly" "4" 239 | "likelihood" "4" 240 | "close" "0" 241 | "site" "any" 242 | } 243 | "17" 244 | { 245 | "name" "Front B tunnels smoke" 246 | "origin" "-1799.751099 995.184509 40.233788" 247 | "angle" "-7.606470 108.497833 0.000000" 248 | "team" "T" 249 | "flags" "0" 250 | "awp_friendly" "3" 251 | "bomb_friendly" "3" 252 | "grenadeType" "smoke" 253 | "grenadeOrigin" "-1804.611694 1009.713196 108.848015" 254 | "grenadeVelocity" "-205.057907 612.930725 194.660034" 255 | "grenadeThrowTime" "0" 256 | } 257 | "18" 258 | { 259 | "name" "Left tunnels 1" 260 | "origin" "-2121.227539 1207.902588 36.670998" 261 | "angle" "-0.395997 39.296970 0.000000" 262 | "team" "T" 263 | "flags" "0" 264 | "awp_friendly" "1" 265 | "bomb_friendly" "3" 266 | "grenadeType" "none" 267 | } 268 | "19" 269 | { 270 | "name" "Left tunnels 2" 271 | "origin" "-2130.340820 1116.912476 34.920341" 272 | "angle" "3.663003 55.780479 0.000000" 273 | "team" "T" 274 | "flags" "0" 275 | "awp_friendly" "2" 276 | "bomb_friendly" "3" 277 | "grenadeType" "none" 278 | } 279 | "20" 280 | { 281 | "name" "Right tunnels 1" 282 | "origin" "-1865.666016 1347.402710 36.489273" 283 | "angle" "2.689480 148.163986 0.000000" 284 | "team" "T" 285 | "flags" "0" 286 | "awp_friendly" "1" 287 | "bomb_friendly" "3" 288 | "grenadeType" "none" 289 | } 290 | "21" 291 | { 292 | "name" "Right tunnels 2" 293 | "origin" "-1721.489746 1317.186890 38.984444" 294 | "angle" "4.916979 159.515839 0.000000" 295 | "team" "T" 296 | "flags" "0" 297 | "awp_friendly" "3" 298 | "bomb_friendly" "3" 299 | "grenadeType" "none" 300 | } 301 | "22" 302 | { 303 | "name" "Right tunnels 3" 304 | "origin" "-1802.796875 1204.927124 32.197723" 305 | "angle" "3.497844 122.754265 0.000000" 306 | "team" "T" 307 | "flags" "0" 308 | "awp_friendly" "4" 309 | "bomb_friendly" "3" 310 | "grenadeType" "none" 311 | } 312 | "23" 313 | { 314 | "name" "Waiting lower tunnels" 315 | "origin" "-706.169189 1517.759521 -107.662354" 316 | "angle" "-9.520752 -12.842823 0.000000" 317 | "team" "T" 318 | "flags" "0" 319 | "awp_friendly" "1" 320 | "bomb_friendly" "1" 321 | "grenadeType" "none" 322 | } 323 | "24" 324 | { 325 | "name" "Lower tunnels 2" 326 | "origin" "-569.791138 1334.028320 -108.150162" 327 | "angle" "5.114741 55.368256 0.000000" 328 | "team" "T" 329 | "flags" "0" 330 | "awp_friendly" "1" 331 | "bomb_friendly" "1" 332 | "grenadeType" "none" 333 | } 334 | "25" 335 | { 336 | "name" "Mid to B smoke" 337 | "origin" "-278.988586 1327.827759 -123.116394" 338 | "angle" "-36.613716 128.941742 0.000000" 339 | "team" "T" 340 | "flags" "0" 341 | "awp_friendly" "1" 342 | "bomb_friendly" "1" 343 | "grenadeType" "smoke" 344 | "grenadeOrigin" "-294.698059 1347.267700 -47.916485" 345 | "grenadeVelocity" "-406.738464 503.325287 456.673279" 346 | "grenadeThrowTime" "0" 347 | } 348 | "26" 349 | { 350 | "name" "Cat bricks smoke" 351 | "origin" "489.964386 1446.031250 0.553161" 352 | "angle" "-4.999693 88.194336 0.000000" 353 | "team" "T" 354 | "flags" "0" 355 | "awp_friendly" "4" 356 | "bomb_friendly" "4" 357 | "grenadeType" "smoke" 358 | "grenadeOrigin" "490.452484 1461.517822 68.544144" 359 | "grenadeVelocity" "20.596004 653.339417 168.369659" 360 | "grenadeThrowTime" "0" 361 | } 362 | "27" 363 | { 364 | "name" "Spawn drop smoke" 365 | "origin" "190.762848 1334.774780 1.083762" 366 | "angle" "-15.534101 66.162834 0.000000" 367 | "team" "T" 368 | "flags" "0" 369 | "awp_friendly" "4" 370 | "bomb_friendly" "4" 371 | "grenadeType" "smoke" 372 | "grenadeOrigin" "196.678802 1348.164551 71.542549" 373 | "grenadeVelocity" "249.579605 564.880127 272.480286" 374 | "grenadeThrowTime" "0" 375 | } 376 | "28" 377 | { 378 | "name" "Cat flash 1" 379 | "origin" "273.008301 1604.145996 3.648018" 380 | "angle" "-52.213566 54.266373 0.000000" 381 | "team" "T" 382 | "flags" "0" 383 | "awp_friendly" "1" 384 | "bomb_friendly" "1" 385 | "grenadeType" "flash" 386 | "grenadeOrigin" "278.177704 1611.330933 80.976631" 387 | "grenadeVelocity" "218.084595 303.120880 562.300476" 388 | "grenadeThrowTime" "1" 389 | } 390 | "29" 391 | { 392 | "name" "Close cat" 393 | "origin" "432.008301 1827.916138 97.993523" 394 | "angle" "1.741428 70.848984 0.000000" 395 | "team" "T" 396 | "flags" "0" 397 | "awp_friendly" "1" 398 | "bomb_friendly" "1" 399 | "grenadeType" "none" 400 | } 401 | "30" 402 | { 403 | "name" "Long lurker" 404 | "origin" "740.968750 387.822784 4.441135" 405 | "angle" "2.170490 115.151260 0.000000" 406 | "team" "T" 407 | "flags" "0" 408 | "awp_friendly" "1" 409 | "bomb_friendly" "1" 410 | "grenadeType" "none" 411 | } 412 | "31" 413 | { 414 | "name" "Long doors 1" 415 | "origin" "539.660156 492.402313 3.814667" 416 | "angle" "1.048471 65.436722 0.000000" 417 | "team" "T" 418 | "flags" "0" 419 | "awp_friendly" "3" 420 | "bomb_friendly" "3" 421 | "grenadeType" "none" 422 | } 423 | "32" 424 | { 425 | "name" "Long doors 2" 426 | "origin" "679.579041 530.009460 0.025734" 427 | "angle" "3.754471 112.032753 0.000000" 428 | "team" "T" 429 | "flags" "0" 430 | "awp_friendly" "3" 431 | "bomb_friendly" "3" 432 | "grenadeType" "none" 433 | } 434 | "33" 435 | { 436 | "name" "Long doors 3" 437 | "origin" "649.472717 314.541046 0.342297" 438 | "angle" "1.972467 92.595955 0.000000" 439 | "team" "T" 440 | "flags" "0" 441 | "awp_friendly" "3" 442 | "bomb_friendly" "3" 443 | "grenadeType" "none" 444 | } 445 | "34" 446 | { 447 | "name" "Long flash" 448 | "origin" "709.609009 -217.926590 0.970274" 449 | "angle" "-26.572487 86.424995 0.000000" 450 | "team" "T" 451 | "flags" "0" 452 | "awp_friendly" "3" 453 | "bomb_friendly" "3" 454 | "grenadeType" "flash" 455 | "grenadeOrigin" "728.379456 -157.564819 109.793694" 456 | "grenadeVelocity" "35.049236 560.998169 637.945801" 457 | "grenadeThrowTime" "1" 458 | } 459 | "35" 460 | { 461 | "name" "Holding back cat" 462 | "origin" "-1.821666 1352.190796 0.263943" 463 | "angle" "5.355042 152.309250 0.000000" 464 | "team" "T" 465 | "flags" "0" 466 | "awp_friendly" "1" 467 | "bomb_friendly" "1" 468 | "grenadeType" "none" 469 | } 470 | "36" 471 | { 472 | "name" "Long corner smoke" 473 | "origin" "-1.005188 -660.002747 10.353168" 474 | "angle" "-14.362556 58.311890 0.000000" 475 | "team" "T" 476 | "flags" "0" 477 | "awp_friendly" "3" 478 | "bomb_friendly" "1" 479 | "grenadeType" "smoke" 480 | "grenadeOrigin" "6.744706 -647.448669 108.448402" 481 | "grenadeVelocity" "326.948669 529.620667 525.421997" 482 | "grenadeThrowTime" "0" 483 | } 484 | "37" 485 | { 486 | "name" "Close right mid" 487 | "origin" "-760.346375 2084.879639 -110.074974" 488 | "angle" "3.226404 -1.322089 0.000000" 489 | "team" "CT" 490 | "flags" "16" 491 | "awp_friendly" "1" 492 | "A_friendly" "2" 493 | "B_friendly" "3" 494 | "likelihood" "1" 495 | "close" "0" 496 | "site" "any" 497 | } 498 | "38" 499 | { 500 | "name" "Close cat 2" 501 | "origin" "382.946716 1731.744263 90.222168" 502 | "angle" "-0.221937 78.065369 0.000000" 503 | "team" "T" 504 | "flags" "0" 505 | "awp_friendly" "1" 506 | "bomb_friendly" "3" 507 | "grenadeType" "none" 508 | } 509 | "39" 510 | { 511 | "name" "Close cat 3" 512 | "origin" "352.767731 1588.341919 3.368080" 513 | "angle" "-11.359447 87.833244 0.000000" 514 | "team" "T" 515 | "flags" "0" 516 | "awp_friendly" "3" 517 | "bomb_friendly" "3" 518 | "grenadeType" "none" 519 | } 520 | "40" 521 | { 522 | "name" "Long blue corner" 523 | "origin" "916.030212 1195.969238 36.031239" 524 | "angle" "4.009556 -89.005135 0.000000" 525 | "team" "CT" 526 | "flags" "0" 527 | "awp_friendly" "1" 528 | "A_friendly" "3" 529 | "B_friendly" "1" 530 | "likelihood" "1" 531 | "close" "0" 532 | "site" "any" 533 | } 534 | } 535 | "Executes" 536 | { 537 | "0" 538 | { 539 | "name" "B hit with front tunnels smoke" 540 | "site" "B" 541 | "likelihood" "3" 542 | "strat_normal" "1" 543 | "strat_pistol" "1" 544 | "strat_force" "1" 545 | "fake" "0" 546 | "extra_freeze_time" "1.300000" 547 | "t_players" 548 | { 549 | "17" "required" 550 | "18" "optional" 551 | "19" "optional" 552 | "20" "optional" 553 | "21" "optional" 554 | "22" "optional" 555 | "23" "optional" 556 | } 557 | } 558 | "1" 559 | { 560 | "name" "Mid to B split" 561 | "site" "B" 562 | "likelihood" "4" 563 | "strat_normal" "1" 564 | "strat_pistol" "1" 565 | "strat_force" "1" 566 | "fake" "0" 567 | "extra_freeze_time" "1.300000" 568 | "t_players" 569 | { 570 | "22" "required" 571 | "23" "required" 572 | "25" "required" 573 | "19" "optional" 574 | "20" "optional" 575 | "17" "optional" 576 | "24" "optional" 577 | } 578 | } 579 | "2" 580 | { 581 | "name" "Contact B" 582 | "site" "B" 583 | "likelihood" "2" 584 | "strat_normal" "1" 585 | "strat_pistol" "1" 586 | "strat_force" "1" 587 | "fake" "0" 588 | "extra_freeze_time" "1.300000" 589 | "t_players" 590 | { 591 | "18" "optional" 592 | "19" "optional" 593 | "20" "optional" 594 | "21" "optional" 595 | "22" "optional" 596 | "23" "optional" 597 | } 598 | } 599 | "3" 600 | { 601 | "name" "Cat execute" 602 | "site" "A" 603 | "likelihood" "4" 604 | "strat_normal" "1" 605 | "strat_pistol" "0" 606 | "strat_force" "1" 607 | "fake" "0" 608 | "extra_freeze_time" "1.300000" 609 | "t_players" 610 | { 611 | "27" "required" 612 | "26" "required" 613 | "28" "required" 614 | "23" "optional" 615 | "29" "optional" 616 | "30" "optional" 617 | } 618 | } 619 | "4" 620 | { 621 | "name" "Straight cat hit" 622 | "site" "A" 623 | "likelihood" "2" 624 | "strat_normal" "1" 625 | "strat_pistol" "1" 626 | "strat_force" "1" 627 | "fake" "0" 628 | "extra_freeze_time" "1.300000" 629 | "t_players" 630 | { 631 | "29" "required" 632 | "28" "required" 633 | "30" "optional" 634 | "35" "optional" 635 | "38" "optional" 636 | "39" "optional" 637 | } 638 | } 639 | "5" 640 | { 641 | "name" "Long A hit" 642 | "site" "A" 643 | "likelihood" "2" 644 | "forcebomb_id" "32" 645 | "strat_normal" "1" 646 | "strat_pistol" "0" 647 | "strat_force" "0" 648 | "fake" "0" 649 | "extra_freeze_time" "1.300000" 650 | "t_players" 651 | { 652 | "34" "required" 653 | "31" "required" 654 | "32" "required" 655 | "23" "optional" 656 | "33" "optional" 657 | "35" "optional" 658 | } 659 | } 660 | "6" 661 | { 662 | "name" "Mid to B with spawn drop" 663 | "site" "B" 664 | "likelihood" "2" 665 | "strat_normal" "1" 666 | "strat_pistol" "1" 667 | "strat_force" "1" 668 | "fake" "0" 669 | "extra_freeze_time" "1.300000" 670 | "t_players" 671 | { 672 | "18" "required" 673 | "20" "required" 674 | "23" "required" 675 | "24" "required" 676 | "27" "required" 677 | "21" "optional" 678 | } 679 | } 680 | } 681 | } 682 | -------------------------------------------------------------------------------- /configs/executes/de_nuke.cfg: -------------------------------------------------------------------------------- 1 | "Executes" 2 | { 3 | "Spawns" 4 | { 5 | "0" 6 | { 7 | "name" "Mini smoke" 8 | "origin" "-51.252750 -348.252869 -117.477882" 9 | "angle" "-63.213902 -58.335827 0.000000" 10 | "team" "T" 11 | "flags" "0" 12 | "awp_friendly" "1" 13 | "bomb_friendly" "1" 14 | "grenadeType" "smoke" 15 | "grenadeOrigin" "-47.862038 -353.750580 -38.839596" 16 | "grenadeAngle" "0.000000 0.000000 0.000000" 17 | "grenadeVelocity" "143.045731 -231.935013 617.550842" 18 | "grenadeImpulse" "600.000000 -708.000000 0.000000" 19 | "grenadeThrowTime" "0" 20 | } 21 | "1" 22 | { 23 | "name" "Right skylight flash" 24 | "origin" "2.312462 -958.142944 7.070084" 25 | "angle" "-3.033749 -20.336504 0.000000" 26 | "team" "T" 27 | "flags" "1" 28 | "awp_friendly" "3" 29 | "bomb_friendly" "3" 30 | "grenadeType" "flash" 31 | "grenadeOrigin" "16.948290 -963.567871 74.586716" 32 | "grenadeAngle" "-3.033749 -20.336504 0.000000" 33 | "grenadeVelocity" "617.448975 -228.848618 148.357864" 34 | "grenadeImpulse" "600.000000 -675.000000 0.000000" 35 | "grenadeThrowTime" "0" 36 | } 37 | "2" 38 | { 39 | "name" "Front of hut flash" 40 | "origin" "127.936577 -799.781311 -415.968750" 41 | "angle" "-1.032766 -60.248051 0.000000" 42 | "team" "T" 43 | "flags" "8" 44 | "awp_friendly" "3" 45 | "bomb_friendly" "3" 46 | "grenadeType" "flash" 47 | "grenadeOrigin" "151.981628 -841.599487 -349.326782" 48 | "grenadeAngle" "-1.032766 -60.248051 0.000000" 49 | "grenadeVelocity" "460.555084 -800.617310 111.450188" 50 | "grenadeImpulse" "600.000000 -98.000000 0.000000" 51 | "grenadeThrowTime" "1" 52 | } 53 | "3" 54 | { 55 | "name" "Waiting middle lobby" 56 | "origin" "-64.342972 -885.331665 -415.968750" 57 | "angle" "-0.590753 -19.616390 0.000000" 58 | "team" "T" 59 | "flags" "8" 60 | "awp_friendly" "3" 61 | "bomb_friendly" "4" 62 | "grenadeType" "none" 63 | } 64 | "4" 65 | { 66 | "name" "Left squeaky" 67 | "origin" "-59.358898 -1194.224609 -415.968750" 68 | "angle" "0.300866 -12.801997 0.000000" 69 | "team" "T" 70 | "flags" "8" 71 | "awp_friendly" "1" 72 | "bomb_friendly" "4" 73 | "grenadeType" "none" 74 | } 75 | "5" 76 | { 77 | "name" "Right squeaky" 78 | "origin" "-25.370789 -1359.356934 -415.968750" 79 | "angle" "1.802492 14.909307 0.000000" 80 | "team" "T" 81 | "flags" "8" 82 | "awp_friendly" "1" 83 | "bomb_friendly" "4" 84 | "grenadeType" "none" 85 | } 86 | "6" 87 | { 88 | "name" "T lobby ladder" 89 | "origin" "229.693634 -797.473022 -415.968750" 90 | "angle" "1.128943 -90.012512 0.000000" 91 | "team" "T" 92 | "flags" "8" 93 | "awp_friendly" "3" 94 | "bomb_friendly" "3" 95 | "grenadeType" "none" 96 | } 97 | "7" 98 | { 99 | "name" "Heaven" 100 | "origin" "1059.578613 -350.394684 -127.968773" 101 | "angle" "17.632771 -148.612213 0.000000" 102 | "team" "CT" 103 | "flags" "0" 104 | "awp_friendly" "1" 105 | "A_friendly" "5" 106 | "B_friendly" "2" 107 | "likelihood" "3" 108 | "close" "0" 109 | "site" "any" 110 | } 111 | "8" 112 | { 113 | "name" "Behind silos" 114 | "origin" "761.713684 -540.552124 -402.248413" 115 | "angle" "1.250158 -152.895737 0.000000" 116 | "team" "CT" 117 | "flags" "0" 118 | "awp_friendly" "1" 119 | "A_friendly" "5" 120 | "B_friendly" "2" 121 | "likelihood" "3" 122 | "close" "0" 123 | "site" "any" 124 | } 125 | "9" 126 | { 127 | "name" "Hut roof" 128 | "origin" "444.882782 -1127.706787 -255.968719" 129 | "angle" "31.998919 -128.599075 0.000000" 130 | "team" "CT" 131 | "flags" "0" 132 | "awp_friendly" "1" 133 | "A_friendly" "5" 134 | "B_friendly" "2" 135 | "likelihood" "2" 136 | "close" "0" 137 | "site" "any" 138 | } 139 | "10" 140 | { 141 | "name" "Mustang" 142 | "origin" "308.901245 -295.392273 -127.969948" 143 | "angle" "20.578793 -82.258713 0.000000" 144 | "team" "CT" 145 | "flags" "0" 146 | "awp_friendly" "1" 147 | "A_friendly" "5" 148 | "B_friendly" "2" 149 | "likelihood" "1" 150 | "close" "0" 151 | "site" "any" 152 | } 153 | "11" 154 | { 155 | "name" "Left mini" 156 | "origin" "552.618164 -1713.923340 -415.968750" 157 | "angle" "0.317822 87.331322 0.000000" 158 | "team" "CT" 159 | "flags" "0" 160 | "awp_friendly" "1" 161 | "A_friendly" "4" 162 | "B_friendly" "2" 163 | "likelihood" "3" 164 | "close" "0" 165 | "site" "any" 166 | } 167 | "12" 168 | { 169 | "name" "Outside mini" 170 | "origin" "975.927734 -1568.630737 -415.968750" 171 | "angle" "0.399238 -114.773224 0.000000" 172 | "team" "CT" 173 | "flags" "0" 174 | "awp_friendly" "1" 175 | "A_friendly" "4" 176 | "B_friendly" "2" 177 | "likelihood" "1" 178 | "close" "0" 179 | "site" "any" 180 | } 181 | "13" 182 | { 183 | "name" "Big garage" 184 | "origin" "1679.817993 -1794.829346 -415.968750" 185 | "angle" "-0.280667 -168.694534 0.000000" 186 | "team" "CT" 187 | "flags" "0" 188 | "awp_friendly" "5" 189 | "A_friendly" "3" 190 | "B_friendly" "3" 191 | "likelihood" "3" 192 | "close" "0" 193 | "site" "any" 194 | } 195 | "14" 196 | { 197 | "name" "CT spawn watching outside" 198 | "origin" "1656.454956 -942.147949 -301.968750" 199 | "angle" "4.823040 -131.810974 0.000000" 200 | "team" "CT" 201 | "flags" "0" 202 | "awp_friendly" "3" 203 | "A_friendly" "3" 204 | "B_friendly" "3" 205 | "likelihood" "3" 206 | "close" "0" 207 | "site" "any" 208 | } 209 | "15" 210 | { 211 | "name" "Heaven AC unit" 212 | "origin" "1197.094727 -550.475525 -230.968719" 213 | "angle" "8.430882 -99.650070 0.000000" 214 | "team" "CT" 215 | "flags" "0" 216 | "awp_friendly" "1" 217 | "A_friendly" "3" 218 | "B_friendly" "2" 219 | "likelihood" "1" 220 | "close" "0" 221 | "site" "any" 222 | } 223 | "16" 224 | { 225 | "name" "Lockers" 226 | "origin" "1074.636597 -620.129150 -415.969086" 227 | "angle" "0.649871 -93.303612 0.000000" 228 | "team" "CT" 229 | "flags" "0" 230 | "awp_friendly" "1" 231 | "A_friendly" "2" 232 | "B_friendly" "2" 233 | "likelihood" "2" 234 | "close" "0" 235 | "site" "any" 236 | } 237 | "17" 238 | { 239 | "name" "Hell ramp connector" 240 | "origin" "1214.702271 16.995377 -415.968750" 241 | "angle" "-0.305471 -179.932678 0.000000" 242 | "team" "CT" 243 | "flags" "0" 244 | "awp_friendly" "1" 245 | "A_friendly" "2" 246 | "B_friendly" "4" 247 | "likelihood" "3" 248 | "close" "0" 249 | "site" "any" 250 | } 251 | "18" 252 | { 253 | "name" "Bottom ramp boxes" 254 | "origin" "739.021301 924.404724 -479.968750" 255 | "angle" "-2.514075 -119.398132 0.000000" 256 | "team" "CT" 257 | "flags" "0" 258 | "awp_friendly" "3" 259 | "A_friendly" "1" 260 | "B_friendly" "5" 261 | "likelihood" "3" 262 | "close" "0" 263 | "site" "any" 264 | } 265 | "19" 266 | { 267 | "name" "Ramp middle boxes" 268 | "origin" "558.108948 322.031311 -371.968750" 269 | "angle" "4.511609 -135.604462 0.000000" 270 | "team" "CT" 271 | "flags" "0" 272 | "awp_friendly" "1" 273 | "A_friendly" "1" 274 | "B_friendly" "5" 275 | "likelihood" "2" 276 | "close" "0" 277 | "site" "any" 278 | } 279 | "20" 280 | { 281 | "name" "Boosted ramp" 282 | "origin" "318.031311 -218.968719 -271.968750" 283 | "angle" "17.841179 88.126137 0.000000" 284 | "team" "CT" 285 | "flags" "0" 286 | "awp_friendly" "1" 287 | "A_friendly" "1" 288 | "B_friendly" "5" 289 | "likelihood" "1" 290 | "close" "0" 291 | "site" "any" 292 | } 293 | "21" 294 | { 295 | "name" "Secret stairs" 296 | "origin" "1591.459961 -2167.410400 -637.968750" 297 | "angle" "-17.355093 -112.282959 0.000000" 298 | "team" "CT" 299 | "flags" "0" 300 | "awp_friendly" "1" 301 | "A_friendly" "1" 302 | "B_friendly" "5" 303 | "likelihood" "2" 304 | "close" "0" 305 | "site" "any" 306 | } 307 | "22" 308 | { 309 | "name" "Close catwalk" 310 | "origin" "1053.563965 -1276.475220 -103.968773" 311 | "angle" "13.998399 -93.803917 0.000000" 312 | "team" "CT" 313 | "flags" "0" 314 | "awp_friendly" "1" 315 | "A_friendly" "2" 316 | "B_friendly" "3" 317 | "likelihood" "1" 318 | "close" "0" 319 | "site" "any" 320 | } 321 | "23" 322 | { 323 | "name" "Catwalk smoke" 324 | "origin" "-496.784668 -1641.767090 -415.968750" 325 | "angle" "-45.642708 3.867188 0.000000" 326 | "team" "T" 327 | "flags" "0" 328 | "awp_friendly" "4" 329 | "bomb_friendly" "1" 330 | "grenadeType" "smoke" 331 | "grenadeOrigin" "-486.645935 -1643.081299 -339.610107" 332 | "grenadeAngle" "-45.642708 3.867188 0.000000" 333 | "grenadeVelocity" "427.728210 28.913502 521.380493" 334 | "grenadeImpulse" "600.000000 730.000000 0.000000" 335 | "grenadeThrowTime" "0" 336 | } 337 | "24" 338 | { 339 | "name" "Outside wallsmoke 1" 340 | "origin" "-165.114639 -1953.307129 -415.969025" 341 | "angle" "-7.734387 -5.273442 0.000000" 342 | "team" "T" 343 | "flags" "0" 344 | "awp_friendly" "1" 345 | "bomb_friendly" "3" 346 | "grenadeType" "smoke" 347 | "grenadeOrigin" "-149.868408 -1954.714233 -347.324280" 348 | "grenadeAngle" "-7.734387 -5.273442 0.000000" 349 | "grenadeVelocity" "643.200745 -59.367226 195.942169" 350 | "grenadeImpulse" "600.000000 530.000000 0.000000" 351 | "grenadeThrowTime" "0" 352 | } 353 | "25" 354 | { 355 | "name" "Outside Wallsmoke 2" 356 | "origin" "-568.152954 -1534.722290 -415.968750" 357 | "angle" "-57.656216 -11.601562 0.000000" 358 | "team" "T" 359 | "flags" "0" 360 | "awp_friendly" "3" 361 | "bomb_friendly" "1" 362 | "grenadeType" "smoke" 363 | "grenadeOrigin" "-560.614319 -1538.269897 -337.941101" 364 | "grenadeAngle" "-57.656216 -11.601562 0.000000" 365 | "grenadeVelocity" "318.034729 -65.292053 591.790527" 366 | "grenadeImpulse" "600.000000 1061.000000 0.000000" 367 | "grenadeThrowTime" "0" 368 | } 369 | "26" 370 | { 371 | "name" "Radio room 1" 372 | "origin" "-200.138260 -439.249573 -415.968750" 373 | "angle" "-0.615392 15.083660 0.000000" 374 | "team" "T" 375 | "flags" "0" 376 | "awp_friendly" "3" 377 | "bomb_friendly" "3" 378 | "grenadeType" "none" 379 | } 380 | "27" 381 | { 382 | "name" "Radio room 2" 383 | "origin" "-198.674026 -561.224731 -415.968750" 384 | "angle" "1.831559 39.854191 0.000000" 385 | "team" "T" 386 | "flags" "0" 387 | "awp_friendly" "3" 388 | "bomb_friendly" "3" 389 | "grenadeType" "none" 390 | } 391 | "28" 392 | { 393 | "name" "Radio room 3" 394 | "origin" "-89.696083 -429.786499 -415.968750" 395 | "angle" "1.140537 34.397804 0.000000" 396 | "team" "T" 397 | "flags" "0" 398 | "awp_friendly" "3" 399 | "bomb_friendly" "3" 400 | "grenadeType" "none" 401 | } 402 | "29" 403 | { 404 | "name" "Front of old secret" 405 | "origin" "1963.174683 -1533.584839 -407.968750" 406 | "angle" "-10.363839 -174.337204 0.000000" 407 | "team" "CT" 408 | "flags" "0" 409 | "awp_friendly" "3" 410 | "A_friendly" "2" 411 | "B_friendly" "2" 412 | "likelihood" "1" 413 | "close" "0" 414 | "site" "any" 415 | } 416 | "30" 417 | { 418 | "name" "Deep radio room" 419 | "origin" "251.968719 -635.820801 -415.968750" 420 | "angle" "0.106657 93.887207 0.000000" 421 | "team" "T" 422 | "flags" "0" 423 | "awp_friendly" "1" 424 | "bomb_friendly" "1" 425 | "grenadeType" "none" 426 | } 427 | "31" 428 | { 429 | "name" "Waiting lobby 2" 430 | "origin" "-65.416939 -1067.969360 -415.968750" 431 | "angle" "0.444699 26.042803 0.000000" 432 | "team" "T" 433 | "flags" "8" 434 | "awp_friendly" "2" 435 | "bomb_friendly" "4" 436 | "grenadeType" "none" 437 | } 438 | "32" 439 | { 440 | "name" "Fallen heaven smoke" 441 | "origin" "62.945980 -1430.770874 -89.968773" 442 | "angle" "-22.425739 49.516323 0.000000" 443 | "team" "T" 444 | "flags" "1" 445 | "awp_friendly" "2" 446 | "bomb_friendly" "2" 447 | "grenadeType" "smoke" 448 | "grenadeOrigin" "71.947983 -1420.224731 -17.984741" 449 | "grenadeAngle" "-22.425739 49.516323 0.000000" 450 | "grenadeVelocity" "379.771515 444.911926 336.826294" 451 | "grenadeImpulse" "600.000000 -340.000000 0.000000" 452 | "grenadeThrowTime" "0" 453 | } 454 | "33" 455 | { 456 | "name" "Left skylight flash" 457 | "origin" "2.209668 -824.712524 7.070107" 458 | "angle" "-2.512224 19.270422 0.000000" 459 | "team" "T" 460 | "flags" "0" 461 | "awp_friendly" "2" 462 | "bomb_friendly" "2" 463 | "grenadeType" "flash" 464 | "grenadeOrigin" "16.970263 -819.551453 74.460335" 465 | "grenadeAngle" "0.000000 0.000000 0.000000" 466 | "grenadeVelocity" "622.712708 217.710068 143.025223" 467 | "grenadeImpulse" "600.000000 -1012.000000 0.000000" 468 | "grenadeThrowTime" "0" 469 | } 470 | "34" 471 | { 472 | "name" "Hut molotov" 473 | "origin" "-69.182014 -1482.670898 -46.997749" 474 | "angle" "-12.531683 24.480843 0.000000" 475 | "team" "T" 476 | "flags" "0" 477 | "awp_friendly" "1" 478 | "bomb_friendly" "1" 479 | "grenadeType" "molotov" 480 | "grenadeOrigin" "-55.600319 -1476.486816 22.772511" 481 | "grenadeAngle" "0.000000 0.000000 0.000000" 482 | "grenadeVelocity" "572.977783 260.889404 243.429459" 483 | "grenadeImpulse" "600.000000 -1104.000000 0.000000" 484 | "grenadeThrowTime" "0" 485 | } 486 | "35" 487 | { 488 | "name" "Outside lurker" 489 | "origin" "-118.036034 -1786.697876 -415.979767" 490 | "angle" "2.225742 -38.229660 0.000000" 491 | "team" "T" 492 | "flags" "12" 493 | "awp_friendly" "1" 494 | "bomb_friendly" "1" 495 | "grenadeType" "none" 496 | } 497 | "36" 498 | { 499 | "name" "Mini smoke from hut" 500 | "origin" "169.031250 -1135.999390 -415.968750" 501 | "angle" "-11.285943 55.671116 0.000000" 502 | "team" "T" 503 | "flags" "0" 504 | "awp_friendly" "1" 505 | "bomb_friendly" "1" 506 | "grenadeType" "smoke" 507 | "grenadeOrigin" "217.751984 -1064.654419 -346.487640" 508 | "grenadeAngle" "0.000000 0.000000 0.000000" 509 | "grenadeVelocity" "522.654419 765.354614 231.217239" 510 | "grenadeImpulse" "600.000000 529.000000 0.000000" 511 | "grenadeThrowTime" "0" 512 | } 513 | "37" 514 | { 515 | "name" "Deep outside mini smoke" 516 | "origin" "-232.019638 -2037.716675 -415.968781" 517 | "angle" "-31.020014 15.786525 0.000000" 518 | "team" "T" 519 | "flags" "0" 520 | "awp_friendly" "2" 521 | "bomb_friendly" "1" 522 | "grenadeType" "smoke" 523 | "grenadeOrigin" "-202.824677 -2031.214233 -342.457428" 524 | "grenadeAngle" "-31.020014 15.786525 0.000000" 525 | "grenadeVelocity" "639.565063 190.942444 401.252899" 526 | "grenadeImpulse" "600.000000 683.000000 0.000000" 527 | "grenadeThrowTime" "0" 528 | } 529 | "38" 530 | { 531 | "name" "Big garage smoke" 532 | "origin" "-121.799622 -1951.538330 -415.969208" 533 | "angle" "-14.107574 1.167495 0.000000" 534 | "team" "T" 535 | "flags" "0" 536 | "awp_friendly" "2" 537 | "bomb_friendly" "3" 538 | "grenadeType" "smoke" 539 | "grenadeOrigin" "-107.024895 -1951.236816 -345.835785" 540 | "grenadeAngle" "0.000000 0.000000 0.000000" 541 | "grenadeVelocity" "623.308472 12.702682 258.747375" 542 | "grenadeImpulse" "600.000000 489.000000 0.000000" 543 | "grenadeThrowTime" "0" 544 | } 545 | "39" 546 | { 547 | "name" "Deep big garage" 548 | "origin" "2107.968750 -2268.442627 -415.968750" 549 | "angle" "0.825021 153.135727 0.000000" 550 | "team" "CT" 551 | "flags" "0" 552 | "awp_friendly" "2" 553 | "A_friendly" "2" 554 | "B_friendly" "2" 555 | "likelihood" "1" 556 | "close" "0" 557 | "site" "any" 558 | } 559 | "40" 560 | { 561 | "name" "Top silo" 562 | "origin" "147.829834 -1437.312012 -90.278763" 563 | "angle" "12.920609 -48.731430 0.000000" 564 | "team" "T" 565 | "flags" "8" 566 | "awp_friendly" "3" 567 | "bomb_friendly" "3" 568 | "grenadeType" "none" 569 | } 570 | "41" 571 | { 572 | "name" "new hut molotov" 573 | "origin" "-29.285677 -992.231262 7.070084" 574 | "angle" "-3.064573 -23.288260 0.000000" 575 | "team" "T" 576 | "flags" "0" 577 | "awp_friendly" "3" 578 | "bomb_friendly" "3" 579 | "grenadeType" "molotov" 580 | "grenadeOrigin" "-14.307736 -995.259644 74.601074" 581 | "grenadeAngle" "0.000000 0.000000 0.000000" 582 | "grenadeVelocity" "601.800476 -266.965881 148.964340" 583 | "grenadeImpulse" "600.000000 19.000000 0.000000" 584 | "grenadeThrowTime" "0" 585 | } 586 | "42" 587 | { 588 | "name" "RampBoxSmoke" 589 | "origin" "251.968719 -449.968750 -415.968750" 590 | "angle" "7.265834 151.275223 0.000000" 591 | "team" "T" 592 | "flags" "0" 593 | "awp_friendly" "3" 594 | "bomb_friendly" "3" 595 | "grenadeType" "smoke" 596 | "grenadeOrigin" "195.043991 -363.562408 -347.460632" 597 | "grenadeAngle" "0.000000 0.000000 0.000000" 598 | "grenadeVelocity" "-522.539978 793.410522 190.185379" 599 | "grenadeImpulse" "600.000000 479.000000 0.000000" 600 | "grenadeThrowTime" "0" 601 | } 602 | "43" 603 | { 604 | "name" "Top blue smoke" 605 | "origin" "-118.387840 -1339.351318 -255.968735" 606 | "angle" "-43.474270 -12.002246 0.000000" 607 | "team" "T" 608 | "flags" "0" 609 | "awp_friendly" "3" 610 | "bomb_friendly" "3" 611 | "grenadeType" "smoke" 612 | "grenadeOrigin" "-108.044167 -1341.535767 -179.958878" 613 | "grenadeAngle" "0.000000 0.000000 0.000000" 614 | "grenadeVelocity" "436.372864 -92.159012 506.666016" 615 | "grenadeImpulse" "600.000000 758.000000 0.000000" 616 | "grenadeThrowTime" "0" 617 | } 618 | } 619 | "Executes" 620 | { 621 | "0" 622 | { 623 | "name" "Upper Execute" 624 | "site" "A" 625 | "likelihood" "4" 626 | "strat_normal" "1" 627 | "strat_pistol" "0" 628 | "strat_force" "0" 629 | "fake" "0" 630 | "extra_freeze_time" "0.700000" 631 | "t_players" 632 | { 633 | "32" "required" 634 | "0" "required" 635 | "31" "optional" 636 | "2" "optional" 637 | "1" "optional" 638 | "33" "optional" 639 | "5" "optional" 640 | "4" "optional" 641 | "6" "optional" 642 | "3" "optional" 643 | "41" "optional" 644 | } 645 | } 646 | "1" 647 | { 648 | "name" "Outside smokes -> lower split" 649 | "site" "B" 650 | "likelihood" "3" 651 | "strat_normal" "1" 652 | "strat_pistol" "1" 653 | "strat_force" "1" 654 | "fake" "0" 655 | "extra_freeze_time" "0.700000" 656 | "t_players" 657 | { 658 | "23" "required" 659 | "24" "required" 660 | "25" "required" 661 | "26" "optional" 662 | "27" "optional" 663 | "28" "optional" 664 | "5" "optional" 665 | } 666 | } 667 | "2" 668 | { 669 | "name" "Outside smokes -> mini/upper split" 670 | "site" "A" 671 | "likelihood" "3" 672 | "strat_normal" "1" 673 | "strat_pistol" "0" 674 | "strat_force" "1" 675 | "fake" "0" 676 | "extra_freeze_time" "0.700000" 677 | "t_players" 678 | { 679 | "23" "required" 680 | "24" "required" 681 | "25" "required" 682 | "6" "required" 683 | "3" "optional" 684 | "4" "optional" 685 | "31" "optional" 686 | } 687 | } 688 | "3" 689 | { 690 | "name" "Simple ramp to lower take" 691 | "site" "B" 692 | "likelihood" "2" 693 | "strat_normal" "1" 694 | "strat_pistol" "1" 695 | "strat_force" "1" 696 | "fake" "0" 697 | "extra_freeze_time" "0.700000" 698 | "t_players" 699 | { 700 | "42" "required" 701 | "35" "optional" 702 | "5" "optional" 703 | "26" "optional" 704 | "27" "optional" 705 | "28" "optional" 706 | "30" "optional" 707 | } 708 | } 709 | "4" 710 | { 711 | "name" "Deep outside smokes -> mini split" 712 | "site" "A" 713 | "likelihood" "3" 714 | "strat_normal" "1" 715 | "strat_pistol" "0" 716 | "strat_force" "1" 717 | "fake" "0" 718 | "extra_freeze_time" "0.700000" 719 | "t_players" 720 | { 721 | "37" "required" 722 | "38" "required" 723 | "3" "required" 724 | "43" "required" 725 | "40" "optional" 726 | "6" "optional" 727 | "4" "optional" 728 | "5" "optional" 729 | } 730 | } 731 | } 732 | } 733 | -------------------------------------------------------------------------------- /configs/executes/de_train.cfg: -------------------------------------------------------------------------------- 1 | "Executes" 2 | { 3 | "Spawns" 4 | { 5 | "0" 6 | { 7 | "name" "Z smoke" 8 | "origin" "-449.044067 1236.031250 -86.902039" 9 | "angle" "-29.829967 -58.389664 0.000000" 10 | "team" "T" 11 | "flags" "0" 12 | "awp_friendly" "3" 13 | "bomb_friendly" "4" 14 | "grenadeType" "smoke" 15 | "grenadeOrigin" "-442.303680 1225.079834 -13.381392" 16 | "grenadeVelocity" "284.342865 -462.005890 401.652405" 17 | "grenadeThrowTime" "0" 18 | } 19 | "1" 20 | { 21 | "name" "Right-bomb-train smoke" 22 | "origin" "-645.470703 1697.723511 -209.968719" 23 | "angle" "-12.869808 -63.645943 0.000000" 24 | "team" "T" 25 | "flags" "0" 26 | "awp_friendly" "3" 27 | "bomb_friendly" "4" 28 | "grenadeType" "smoke" 29 | "grenadeOrigin" "-638.858948 1684.378540 -112.216705" 30 | "grenadeVelocity" "278.909058 -562.991699 510.939087" 31 | "grenadeThrowTime" "0" 32 | } 33 | "2" 34 | { 35 | "name" "Left-bomb-train smoke" 36 | "origin" "-453.064240 1286.164429 -86.553314" 37 | "angle" "-24.388783 -59.656487 0.000000" 38 | "team" "T" 39 | "flags" "0" 40 | "awp_friendly" "3" 41 | "bomb_friendly" "4" 42 | "grenadeType" "smoke" 43 | "grenadeOrigin" "-446.185608 1274.413940 -14.150766" 44 | "grenadeVelocity" "290.191315 -495.738098 354.482483" 45 | "grenadeThrowTime" "0" 46 | } 47 | "3" 48 | { 49 | "name" "Middle-bomb-train smoke" 50 | "origin" "-886.766357 1518.795898 -222.968719" 51 | "angle" "-13.686027 -51.505825 0.000000" 52 | "team" "T" 53 | "flags" "0" 54 | "awp_friendly" "3" 55 | "bomb_friendly" "4" 56 | "grenadeType" "smoke" 57 | "grenadeOrigin" "-877.543152 1507.199219 -125.028603" 58 | "grenadeVelocity" "389.094604 -489.261047 518.875061" 59 | "grenadeThrowTime" "0" 60 | } 61 | "4" 62 | { 63 | "name" "Sandwich smoke" 64 | "origin" "-827.988770 1268.044312 -222.968719" 65 | "angle" "-38.355480 -42.448128 0.000000" 66 | "team" "T" 67 | "flags" "0" 68 | "awp_friendly" "3" 69 | "bomb_friendly" "3" 70 | "grenadeType" "smoke" 71 | "grenadeOrigin" "-819.509460 1260.288574 -147.835403" 72 | "grenadeVelocity" "357.718414 -327.193207 469.688354" 73 | "grenadeThrowTime" "0" 74 | } 75 | "5" 76 | { 77 | "name" "Lower ramp smoke" 78 | "origin" "-1089.031250 -869.936035 -95.968773" 79 | "angle" "19.226316 -0.044042 0.000000" 80 | "team" "T" 81 | "flags" "0" 82 | "awp_friendly" "3" 83 | "bomb_friendly" "5" 84 | "grenadeType" "smoke" 85 | "grenadeOrigin" "-1073.345337 -869.947998 -35.121017" 86 | "grenadeVelocity" "661.769653 -0.508684 -132.986191" 87 | "grenadeThrowTime" "0" 88 | } 89 | "7" 90 | { 91 | "name" "Upper smoke" 92 | "origin" "-1053.751221 -1636.181274 -151.968719" 93 | "angle" "-3.561543 -11.308177 0.000000" 94 | "team" "T" 95 | "flags" "0" 96 | "awp_friendly" "3" 97 | "bomb_friendly" "1" 98 | "grenadeType" "smoke" 99 | "grenadeOrigin" "-1011.301941 -1656.318359 -86.025169" 100 | "grenadeVelocity" "886.637207 -102.145126 81.981422" 101 | "grenadeThrowTime" "0" 102 | } 103 | "8" 104 | { 105 | "name" "Back ivy smoke from above ladder" 106 | "origin" "-653.996521 -477.125885 16.031250" 107 | "angle" "-38.399132 30.540216 0.000000" 108 | "team" "T" 109 | "flags" "0" 110 | "awp_friendly" "3" 111 | "bomb_friendly" "1" 112 | "grenadeType" "smoke" 113 | "grenadeOrigin" "-644.105957 -471.290619 91.172356" 114 | "grenadeVelocity" "417.259308 246.179626 470.016510" 115 | "grenadeThrowTime" "0" 116 | } 117 | "9" 118 | { 119 | "name" "Back A train molotov" 120 | "origin" "-743.735229 426.614319 -215.968719" 121 | "angle" "-1.394784 7.208132 0.000000" 122 | "team" "T" 123 | "flags" "0" 124 | "awp_friendly" "3" 125 | "bomb_friendly" "4" 126 | "grenadeType" "molotov" 127 | "grenadeOrigin" "-633.065918 479.269501 -147.778320" 128 | "grenadeVelocity" "870.142151 -210.045990 324.370422" 129 | "grenadeThrowTime" "0" 130 | } 131 | "10" 132 | { 133 | "name" "Close T connector" 134 | "origin" "-871.302551 660.158142 -215.981354" 135 | "angle" "1.983313 -61.762108 0.000000" 136 | "team" "T" 137 | "flags" "8" 138 | "awp_friendly" "3" 139 | "bomb_friendly" "3" 140 | "grenadeType" "none" 141 | } 142 | "11" 143 | { 144 | "name" "back t connector" 145 | "origin" "-778.409851 799.658447 -215.981354" 146 | "angle" "2.360224 -111.372414 0.000000" 147 | "team" "T" 148 | "flags" "8" 149 | "awp_friendly" "3" 150 | "bomb_friendly" "3" 151 | "grenadeType" "none" 152 | } 153 | "12" 154 | { 155 | "name" "Above ladder" 156 | "origin" "-728.547485 -241.909073 16.031250" 157 | "angle" "7.175754 -92.866150 0.000000" 158 | "team" "T" 159 | "flags" "0" 160 | "awp_friendly" "1" 161 | "bomb_friendly" "2" 162 | "grenadeType" "none" 163 | } 164 | "13" 165 | { 166 | "name" "Bottom ladder" 167 | "origin" "-733.552124 -312.031311 -215.968719" 168 | "angle" "-0.843890 -5.979568 0.000000" 169 | "team" "T" 170 | "flags" "0" 171 | "awp_friendly" "3" 172 | "bomb_friendly" "2" 173 | "grenadeType" "none" 174 | } 175 | "14" 176 | { 177 | "name" "Waiting ivy" 178 | "origin" "1122.480713 1437.918335 -223.968719" 179 | "angle" "0.504250 -10.303000 0.000000" 180 | "team" "T" 181 | "flags" "0" 182 | "awp_friendly" "3" 183 | "bomb_friendly" "1" 184 | "grenadeType" "none" 185 | } 186 | "15" 187 | { 188 | "name" "Waiting ivy by trash" 189 | "origin" "1087.469360 1711.969360 -220.968719" 190 | "angle" "0.679733 -62.274570 0.000000" 191 | "team" "T" 192 | "flags" "0" 193 | "awp_friendly" "3" 194 | "bomb_friendly" "1" 195 | "grenadeType" "none" 196 | } 197 | "16" 198 | { 199 | "name" "Holding right ivy" 200 | "origin" "1527.522217 408.798065 -215.968719" 201 | "angle" "-0.129362 112.412010 0.000000" 202 | "team" "CT" 203 | "flags" "0" 204 | "awp_friendly" "3" 205 | "A_friendly" "5" 206 | "B_friendly" "1" 207 | "likelihood" "3" 208 | } 209 | "17" 210 | { 211 | "name" "Hell" 212 | "origin" "718.180176 681.320679 -211.968719" 213 | "angle" "0.162467 -168.421265 0.000000" 214 | "team" "CT" 215 | "flags" "0" 216 | "awp_friendly" "2" 217 | "A_friendly" "5" 218 | "B_friendly" "1" 219 | "likelihood" "3" 220 | } 221 | "18" 222 | { 223 | "name" "in Z" 224 | "origin" "623.968750 -426.713593 -218.940170" 225 | "angle" "-0.400778 142.064072 0.000000" 226 | "team" "CT" 227 | "flags" "0" 228 | "awp_friendly" "4" 229 | "A_friendly" "4" 230 | "B_friendly" "2" 231 | "likelihood" "4" 232 | } 233 | "19" 234 | { 235 | "name" "Back 5 train" 236 | "origin" "430.247864 183.683426 -215.968719" 237 | "angle" "0.620027 -152.429062 0.000000" 238 | "team" "CT" 239 | "flags" "0" 240 | "awp_friendly" "1" 241 | "A_friendly" "5" 242 | "B_friendly" "2" 243 | "likelihood" "3" 244 | } 245 | "21" 246 | { 247 | "name" "Back bomb (a)" 248 | "origin" "747.664673 -69.557785 -215.968719" 249 | "angle" "-0.194005 -164.971405 0.000000" 250 | "team" "CT" 251 | "flags" "0" 252 | "awp_friendly" "2" 253 | "A_friendly" "4" 254 | "B_friendly" "2" 255 | "likelihood" "3" 256 | } 257 | "22" 258 | { 259 | "name" "Stopsign" 260 | "origin" "950.314636 126.405464 -215.968719" 261 | "angle" "-0.526496 163.093185 0.000000" 262 | "team" "CT" 263 | "flags" "0" 264 | "awp_friendly" "4" 265 | "A_friendly" "4" 266 | "B_friendly" "2" 267 | "likelihood" "3" 268 | } 269 | "23" 270 | { 271 | "name" "Back green/6" 272 | "origin" "1023.095032 517.705750 -218.065186" 273 | "angle" "0.408709 167.377426 0.000000" 274 | "team" "CT" 275 | "flags" "0" 276 | "awp_friendly" "5" 277 | "A_friendly" "5" 278 | "B_friendly" "1" 279 | "likelihood" "4" 280 | } 281 | "24" 282 | { 283 | "name" "Bottom pop" 284 | "origin" "337.332123 -970.781128 -351.968750" 285 | "angle" "-3.251369 173.292313 0.000000" 286 | "team" "CT" 287 | "flags" "0" 288 | "awp_friendly" "1" 289 | "A_friendly" "1" 290 | "B_friendly" "5" 291 | "likelihood" "4" 292 | } 293 | "25" 294 | { 295 | "name" "Back upper (inner)" 296 | "origin" "915.054688 -1641.573608 -198.968719" 297 | "angle" "3.402252 177.996948 0.000000" 298 | "team" "CT" 299 | "flags" "0" 300 | "awp_friendly" "4" 301 | "A_friendly" "1" 302 | "B_friendly" "4" 303 | "likelihood" "3" 304 | } 305 | "26" 306 | { 307 | "name" "Back red/3" 308 | "origin" "1064.789795 -1006.581543 -164.620407" 309 | "angle" "4.830492 175.649094 0.000000" 310 | "team" "CT" 311 | "flags" "0" 312 | "awp_friendly" "4" 313 | "A_friendly" "2" 314 | "B_friendly" "4" 315 | "likelihood" "2" 316 | } 317 | "27" 318 | { 319 | "name" "Back bomb (B)" 320 | "origin" "408.914398 -1361.071289 -349.953003" 321 | "angle" "0.208352 179.679825 0.000000" 322 | "team" "CT" 323 | "flags" "0" 324 | "awp_friendly" "1" 325 | "A_friendly" "1" 326 | "B_friendly" "5" 327 | "likelihood" "3" 328 | } 329 | "28" 330 | { 331 | "name" "Old bomb" 332 | "origin" "1769.367310 -236.138062 -215.968719" 333 | "angle" "0.120437 179.527756 0.000000" 334 | "team" "CT" 335 | "flags" "0" 336 | "awp_friendly" "5" 337 | "A_friendly" "3" 338 | "B_friendly" "2" 339 | "likelihood" "2" 340 | } 341 | "29" 342 | { 343 | "name" "sandwich" 344 | "origin" "261.017487 489.129486 -219.968719" 345 | "angle" "-1.231709 -160.872025 0.000000" 346 | "team" "CT" 347 | "flags" "0" 348 | "awp_friendly" "1" 349 | "A_friendly" "4" 350 | "B_friendly" "1" 351 | "likelihood" "3" 352 | } 353 | "30" 354 | { 355 | "name" "CT heaven" 356 | "origin" "820.248413 -385.185028 40.031216" 357 | "angle" "10.147228 149.959839 0.000000" 358 | "team" "CT" 359 | "flags" "0" 360 | "awp_friendly" "3" 361 | "A_friendly" "4" 362 | "B_friendly" "2" 363 | "likelihood" "3" 364 | } 365 | "31" 366 | { 367 | "name" "Back bomb molotov (B)" 368 | "origin" "-1074.770020 -979.807495 -55.968845" 369 | "angle" "-3.325052 -9.111917 0.000000" 370 | "team" "T" 371 | "flags" "0" 372 | "awp_friendly" "3" 373 | "bomb_friendly" "3" 374 | "grenadeType" "molotov" 375 | "grenadeOrigin" "-1053.214844 -983.264832 11.618402" 376 | "grenadeVelocity" "711.256470 -114.076530 151.332275" 377 | "grenadeThrowTime" "0" 378 | } 379 | "32" 380 | { 381 | "name" "Z smoke from box halls" 382 | "origin" "-1159.969360 -1094.309937 -95.968773" 383 | "angle" "-11.458089 5.494124 0.000000" 384 | "team" "T" 385 | "flags" "0" 386 | "awp_friendly" "3" 387 | "bomb_friendly" "5" 388 | "grenadeType" "smoke" 389 | "grenadeOrigin" "-1109.421021 -1089.161011 -26.447948" 390 | "grenadeVelocity" "781.222229 75.142265 232.910049" 391 | "grenadeThrowTime" "0" 392 | } 393 | "33" 394 | { 395 | "name" "Close lower ramp" 396 | "origin" "-916.771057 -942.245178 -151.968719" 397 | "angle" "20.438501 5.414600 0.000000" 398 | "team" "T" 399 | "flags" "0" 400 | "awp_friendly" "3" 401 | "bomb_friendly" "3" 402 | "grenadeType" "none" 403 | } 404 | "34" 405 | { 406 | "name" "Waiting upper" 407 | "origin" "-1047.969360 -1511.984253 -151.968719" 408 | "angle" "-0.299761 -48.424049 0.000000" 409 | "team" "T" 410 | "flags" "0" 411 | "awp_friendly" "3" 412 | "bomb_friendly" "1" 413 | "grenadeType" "none" 414 | } 415 | "35" 416 | { 417 | "name" "Holding ladder flank" 418 | "origin" "-1067.142822 -626.676453 -95.968773" 419 | "angle" "-11.751348 16.368731 0.000000" 420 | "team" "T" 421 | "flags" "0" 422 | "awp_friendly" "3" 423 | "bomb_friendly" "3" 424 | "grenadeType" "none" 425 | } 426 | "36" 427 | { 428 | "name" "secondary waiting upper" 429 | "origin" "-909.013062 -1386.510498 -151.968719" 430 | "angle" "-0.308480 -89.837982 0.000000" 431 | "team" "T" 432 | "flags" "0" 433 | "awp_friendly" "3" 434 | "bomb_friendly" "1" 435 | "grenadeType" "none" 436 | } 437 | "37" 438 | { 439 | "name" "Left-bomb smoke (inner)" 440 | "origin" "-1155.986206 -1301.504517 -95.968773" 441 | "angle" "-15.388991 38.766441 0.000000" 442 | "team" "T" 443 | "flags" "0" 444 | "awp_friendly" "3" 445 | "bomb_friendly" "5" 446 | "grenadeType" "smoke" 447 | "grenadeOrigin" "-1104.167725 -1259.767822 -25.550438" 448 | "grenadeVelocity" "641.303101 516.594238 270.772919" 449 | "grenadeThrowTime" "0" 450 | } 451 | "38" 452 | { 453 | "name" "Back pop molotov" 454 | "origin" "-1085.212280 -1158.709717 -55.968845" 455 | "angle" "-5.645924 19.902384 0.000000" 456 | "team" "T" 457 | "flags" "0" 458 | "awp_friendly" "3" 459 | "bomb_friendly" "3" 460 | "grenadeType" "molotov" 461 | "grenadeOrigin" "-1055.897217 -1147.913452 12.177372" 462 | "grenadeVelocity" "797.040955 288.562439 174.914398" 463 | "grenadeThrowTime" "0" 464 | } 465 | "39" 466 | { 467 | "name" "Deep 2/3 lane smoke" 468 | "origin" "-1074.991211 -1031.604004 -55.968845" 469 | "angle" "-8.528172 -4.847736 0.000000" 470 | "team" "T" 471 | "flags" "0" 472 | "awp_friendly" "3" 473 | "bomb_friendly" "5" 474 | "grenadeType" "smoke" 475 | "grenadeOrigin" "-1059.793091 -1032.892822 12.864001" 476 | "grenadeVelocity" "641.170959 -54.378632 203.881683" 477 | "grenadeThrowTime" "0" 478 | } 479 | "40" 480 | { 481 | "name" "Spools CT spawn" 482 | "origin" "-495.999786 -1469.855347 -351.334351" 483 | "angle" "-49.782230 -86.705154 0.000000" 484 | "team" "CT" 485 | "flags" "0" 486 | "awp_friendly" "1" 487 | "A_friendly" "1" 488 | "B_friendly" "5" 489 | "likelihood" "1" 490 | } 491 | "41" 492 | { 493 | "name" "middle A site molly" 494 | "origin" "-747.492737 528.339966 -215.974503" 495 | "angle" "-17.978291 -18.843719 0.000000" 496 | "team" "T" 497 | "flags" "0" 498 | "awp_friendly" "3" 499 | "bomb_friendly" "3" 500 | "grenadeType" "molotov" 501 | "grenadeOrigin" "-714.804932 517.184326 -145.657684" 502 | "grenadeVelocity" "825.233704 -281.114746 296.938202" 503 | "grenadeThrowTime" "0" 504 | } 505 | "42" 506 | { 507 | "name" "back old bomb smoke" 508 | "origin" "-766.784729 1444.959961 -223.122025" 509 | "angle" "15.291208 -44.440475 0.000000" 510 | "team" "T" 511 | "flags" "0" 512 | "awp_friendly" "3" 513 | "bomb_friendly" "3" 514 | "grenadeType" "smoke" 515 | "grenadeOrigin" "-744.844666 1435.404907 -121.801048" 516 | "grenadeVelocity" "404.008087 -442.576019 638.464722" 517 | "grenadeThrowTime" "0" 518 | } 519 | "43" 520 | { 521 | "name" "left side ivy smoke" 522 | "origin" "1535.996216 1775.969360 -223.968719" 523 | "angle" "-12.247518 -112.639328 0.000000" 524 | "team" "T" 525 | "flags" "0" 526 | "awp_friendly" "3" 527 | "bomb_friendly" "5" 528 | "grenadeType" "smoke" 529 | "grenadeOrigin" "1490.507812 1666.686279 -158.276642" 530 | "grenadeVelocity" "-359.916199 -865.216431 240.135223" 531 | "grenadeThrowTime" "0" 532 | } 533 | "44" 534 | { 535 | "name" "E-box off angle" 536 | "origin" "96.019348 -286.999420 -215.968719" 537 | "angle" "0.773704 131.936569 0.000000" 538 | "team" "CT" 539 | "flags" "0" 540 | "awp_friendly" "1" 541 | "A_friendly" "4" 542 | "B_friendly" "2" 543 | "likelihood" "2" 544 | } 545 | "45" 546 | { 547 | "name" "Back A ivy lane" 548 | "origin" "1939.406372 300.779419 -223.968719" 549 | "angle" "0.701974 146.106689 0.000000" 550 | "team" "CT" 551 | "flags" "0" 552 | "awp_friendly" "5" 553 | "A_friendly" "5" 554 | "B_friendly" "1" 555 | "likelihood" "3" 556 | } 557 | "46" 558 | { 559 | "name" "T-connector lurker" 560 | "origin" "-899.838379 767.968750 -215.968719" 561 | "angle" "0.669438 -67.377655 0.000000" 562 | "team" "T" 563 | "flags" "8" 564 | "awp_friendly" "3" 565 | "bomb_friendly" "1" 566 | "grenadeType" "none" 567 | } 568 | "47" 569 | { 570 | "name" "Bottom ladder lurker" 571 | "origin" "-616.338684 -316.004303 -215.968719" 572 | "angle" "0.071910 -21.929848 0.000000" 573 | "team" "T" 574 | "flags" "8" 575 | "awp_friendly" "3" 576 | "bomb_friendly" "1" 577 | "grenadeType" "none" 578 | } 579 | "48" 580 | { 581 | "name" "Back green molotov" 582 | "origin" "-921.786682 412.247437 -215.968735" 583 | "angle" "0.123108 8.913584 0.000000" 584 | "team" "T" 585 | "flags" "0" 586 | "awp_friendly" "1" 587 | "bomb_friendly" "3" 588 | "grenadeType" "molotov" 589 | "grenadeOrigin" "-804.352173 567.851440 -145.626053" 590 | "grenadeVelocity" "922.002319 11.104169 267.583282" 591 | "grenadeThrowTime" "0" 592 | } 593 | "49" 594 | { 595 | "name" "E-box smoke" 596 | "origin" "-755.421204 1450.515381 -222.675827" 597 | "angle" "-48.202168 -66.792961 0.019737" 598 | "team" "T" 599 | "flags" "0" 600 | "awp_friendly" "3" 601 | "bomb_friendly" "3" 602 | "grenadeType" "smoke" 603 | "grenadeOrigin" "-751.613342 1441.634033 -145.923553" 604 | "grenadeVelocity" "160.643616 -374.683380 537.987793" 605 | "grenadeThrowTime" "0" 606 | } 607 | "50" 608 | { 609 | "name" "Ebox" 610 | "origin" "-129.161392 35.239231 -215.935806" 611 | "angle" "2.248163 127.661064 0.000000" 612 | "team" "CT" 613 | "flags" "0" 614 | "awp_friendly" "1" 615 | "A_friendly" "5" 616 | "B_friendly" "1" 617 | "likelihood" "2" 618 | } 619 | "51" 620 | { 621 | "name" "Boosted z" 622 | "origin" "426.040466 -320.215302 -93.968765" 623 | "angle" "5.171659 140.495819 0.000000" 624 | "team" "CT" 625 | "flags" "0" 626 | "awp_friendly" "5" 627 | "A_friendly" "4" 628 | "B_friendly" "2" 629 | "likelihood" "1" 630 | } 631 | } 632 | "Executes" 633 | { 634 | "0" 635 | { 636 | "name" "A wall smokes" 637 | "site" "A" 638 | "likelihood" "4" 639 | "strat_normal" "1" 640 | "strat_pistol" "0" 641 | "strat_force" "1" 642 | "fake" "0" 643 | "extra_freeze_time" "1.300000" 644 | "t_players" 645 | { 646 | "1" "required" 647 | "2" "required" 648 | "3" "required" 649 | "4" "required" 650 | "47" "optional" 651 | "15" "optional" 652 | } 653 | } 654 | "2" 655 | { 656 | "name" "A wall smokes + ivy smoke" 657 | "site" "A" 658 | "likelihood" "3" 659 | "strat_normal" "1" 660 | "strat_pistol" "0" 661 | "strat_force" "1" 662 | "fake" "0" 663 | "extra_freeze_time" "1.300000" 664 | "t_players" 665 | { 666 | "1" "required" 667 | "2" "required" 668 | "3" "required" 669 | "8" "required" 670 | "13" "optional" 671 | "14" "optional" 672 | } 673 | } 674 | "3" 675 | { 676 | "name" "Back A site smokes" 677 | "site" "A" 678 | "likelihood" "2" 679 | "strat_normal" "1" 680 | "strat_pistol" "1" 681 | "strat_force" "1" 682 | "fake" "0" 683 | "extra_freeze_time" "1.300000" 684 | "t_players" 685 | { 686 | "0" "required" 687 | "8" "required" 688 | "2" "required" 689 | "42" "required" 690 | "13" "optional" 691 | "10" "optional" 692 | "15" "optional" 693 | "41" "optional" 694 | } 695 | } 696 | "4" 697 | { 698 | "name" "Generic inner take" 699 | "site" "B" 700 | "likelihood" "3" 701 | "strat_normal" "1" 702 | "strat_pistol" "1" 703 | "strat_force" "1" 704 | "fake" "0" 705 | "extra_freeze_time" "1.300000" 706 | "t_players" 707 | { 708 | "5" "required" 709 | "31" "optional" 710 | "32" "optional" 711 | "34" "optional" 712 | "35" "optional" 713 | "7" "optional" 714 | "10" "optional" 715 | "46" "optional" 716 | } 717 | } 718 | "6" 719 | { 720 | "name" "Close smokes inner take" 721 | "site" "B" 722 | "likelihood" "3" 723 | "strat_normal" "1" 724 | "strat_pistol" "0" 725 | "strat_force" "1" 726 | "fake" "0" 727 | "extra_freeze_time" "1.300000" 728 | "t_players" 729 | { 730 | "5" "required" 731 | "7" "required" 732 | "37" "required" 733 | "31" "optional" 734 | "35" "optional" 735 | "36" "optional" 736 | "33" "optional" 737 | } 738 | } 739 | "7" 740 | { 741 | "name" "Deep B smokes + back pop molotov" 742 | "site" "B" 743 | "likelihood" "4" 744 | "strat_normal" "1" 745 | "strat_pistol" "0" 746 | "strat_force" "1" 747 | "fake" "0" 748 | "extra_freeze_time" "1.300000" 749 | "t_players" 750 | { 751 | "39" "required" 752 | "38" "required" 753 | "32" "required" 754 | "31" "optional" 755 | "35" "optional" 756 | "36" "optional" 757 | "7" "optional" 758 | "34" "optional" 759 | "10" "optional" 760 | "46" "optional" 761 | "47" "optional" 762 | } 763 | } 764 | "8" 765 | { 766 | "name" "A split through ivy" 767 | "site" "A" 768 | "likelihood" "2" 769 | "strat_normal" "1" 770 | "strat_pistol" "1" 771 | "strat_force" "1" 772 | "fake" "0" 773 | "extra_freeze_time" "1.300000" 774 | "t_players" 775 | { 776 | "2" "required" 777 | "4" "required" 778 | "43" "required" 779 | "42" "required" 780 | "14" "optional" 781 | "15" "optional" 782 | } 783 | } 784 | "9" 785 | { 786 | "name" "Fast outside pistol" 787 | "site" "A" 788 | "likelihood" "3" 789 | "forcebomb_id" "0" 790 | "strat_normal" "0" 791 | "strat_pistol" "1" 792 | "strat_force" "1" 793 | "fake" "0" 794 | "extra_freeze_time" "1.300000" 795 | "t_players" 796 | { 797 | "0" "required" 798 | "10" "required" 799 | "11" "required" 800 | "4" "optional" 801 | "13" "optional" 802 | "14" "optional" 803 | "46" "optional" 804 | } 805 | } 806 | "10" 807 | { 808 | "name" "Inner fake -> outside" 809 | "site" "A" 810 | "likelihood" "3" 811 | "forcebomb_id" "10" 812 | "strat_normal" "1" 813 | "strat_pistol" "1" 814 | "strat_force" "1" 815 | "fake" "1" 816 | "extra_freeze_time" "1.300000" 817 | "t_players" 818 | { 819 | "5" "required" 820 | "10" "required" 821 | "12" "optional" 822 | "14" "optional" 823 | "15" "optional" 824 | "31" "optional" 825 | "11" "optional" 826 | } 827 | } 828 | "11" 829 | { 830 | "name" "Fast outside take" 831 | "site" "A" 832 | "likelihood" "4" 833 | "forcebomb_id" "0" 834 | "strat_normal" "1" 835 | "strat_pistol" "0" 836 | "strat_force" "0" 837 | "fake" "0" 838 | "extra_freeze_time" "1.300000" 839 | "t_players" 840 | { 841 | "0" "required" 842 | "48" "required" 843 | "41" "optional" 844 | "12" "optional" 845 | "9" "optional" 846 | } 847 | } 848 | "12" 849 | { 850 | "name" "Ebox + 5lane smokes" 851 | "site" "A" 852 | "likelihood" "3" 853 | "forcebomb_id" "49" 854 | "strat_normal" "1" 855 | "strat_pistol" "1" 856 | "strat_force" "1" 857 | "fake" "0" 858 | "extra_freeze_time" "1.300000" 859 | "t_players" 860 | { 861 | "49" "required" 862 | "4" "required" 863 | "11" "optional" 864 | "10" "optional" 865 | "12" "optional" 866 | "13" "optional" 867 | "14" "optional" 868 | "15" "optional" 869 | "48" "optional" 870 | "9" "optional" 871 | } 872 | } 873 | "13" 874 | { 875 | "name" "Fake outside smokes -> Inner" 876 | "site" "B" 877 | "likelihood" "1" 878 | "forcebomb_id" "34" 879 | "strat_normal" "1" 880 | "strat_pistol" "1" 881 | "strat_force" "1" 882 | "fake" "1" 883 | "extra_freeze_time" "1.300000" 884 | "t_players" 885 | { 886 | "49" "required" 887 | "4" "required" 888 | "34" "required" 889 | "35" "optional" 890 | "36" "optional" 891 | "33" "optional" 892 | } 893 | } 894 | } 895 | } 896 | -------------------------------------------------------------------------------- /scripting/executes/editor_menus.sp: -------------------------------------------------------------------------------- 1 | // TODO: add CT spawn "exclusions" to the editor 2 | 3 | enum SpawnStatus { 4 | Spawn_Required = 0, 5 | Spawn_Optional = 1, 6 | Spawn_NotUsed = 2, 7 | } 8 | 9 | stock void 10 | GiveEditorMenu(int client, int menuPosition = -1) { 11 | Menu menu = new Menu(EditorMenuHandler); 12 | menu.ExitButton = true; 13 | menu.SetTitle("Executes editor"); 14 | AddMenuOption(menu, "end_edit", "Exit edit mode"); 15 | AddMenuOption(menu, "add_spawn", "Add a spawn"); 16 | AddMenuOption(menu, "edit_spawn", "Edit a spawn"); 17 | AddMenuOption(menu, "add_execute", "Add an execute"); 18 | AddMenuOption(menu, "edit_execute", "Edit an execute"); 19 | AddMenuOption(menu, "edit_nearest_spawn", "Edit nearest spawn"); 20 | AddMenuOption(menu, "delete_nearest_spawn", "Delete nearest spawn"); 21 | AddMenuOption(menu, "save_map_data", "Save map data"); 22 | AddMenuOption(menu, "reload_map_data", "Reload map data (discard current changes)"); 23 | AddMenuOption(menu, "clear_edit_buffers", "Clear edit buffers"); 24 | 25 | if (menuPosition == -1) { 26 | menu.Display(client, MENU_TIME_FOREVER); 27 | } else { 28 | menu.DisplayAt(client, menuPosition, MENU_TIME_FOREVER); 29 | } 30 | } 31 | 32 | public int EditorMenuHandler(Menu menu, MenuAction action, int param1, int param2) { 33 | if (action == MenuAction_Select) { 34 | int client = param1; 35 | char choice[64]; 36 | menu.GetItem(param2, choice, sizeof(choice)); 37 | int menuPosition = GetMenuSelectionPosition(); 38 | 39 | if (StrEqual(choice, "end_edit")) { 40 | Executes_MessageToAll("Exiting edit mode."); 41 | ExitEditMode(); 42 | 43 | } else if (StrEqual(choice, "add_spawn")) { 44 | g_EditingASpawn = false; 45 | GiveNewSpawnMenu(client); 46 | 47 | } else if (StrEqual(choice, "add_execute")) { 48 | g_EditingAnExecute = false; 49 | GiveNewExecuteMenu(client); 50 | 51 | } else if (StrEqual(choice, "edit_spawn")) { 52 | GiveEditSpawnChoiceMenu(client); 53 | 54 | } else if (StrEqual(choice, "edit_nearest_spawn")) { 55 | int spawn = FindClosestSpawn(client); 56 | EditSpawn(client, spawn); 57 | 58 | } else if (StrEqual(choice, "delete_nearest_spawn")) { 59 | DeleteClosestSpawn(client); 60 | GiveEditorMenu(client, menuPosition); 61 | 62 | } else if (StrEqual(choice, "edit_execute")) { 63 | // ClearExecuteBuffers 64 | GiveExecuteEditMenu(client); 65 | 66 | } else if (StrEqual(choice, "save_map_data")) { 67 | SaveMapData(); 68 | GiveEditorMenu(client, menuPosition); 69 | 70 | } else if (StrEqual(choice, "reload_map_data")) { 71 | ReloadMapData(); 72 | GiveEditorMenu(client, menuPosition); 73 | 74 | } else if (StrEqual(choice, "clear_edit_buffers")) { 75 | ClearEditBuffers(); 76 | GiveEditorMenu(client, menuPosition); 77 | 78 | } else { 79 | LogError("unknown menu info string = %s", choice); 80 | } 81 | } else if (action == MenuAction_End) { 82 | delete menu; 83 | } 84 | } 85 | 86 | stock void GiveNewSpawnMenu(int client, int pos = -1) { 87 | g_EditingExecutes = false; 88 | Menu menu = new Menu(GiveNewSpawnMenuHandler); 89 | menu.SetTitle("Add a spawn"); 90 | 91 | if (StrEqual(g_TempNameBuffer, "")) 92 | AddMenuOptionDisabled(menu, "finish", "Finish spawn (use !setname to name first)"); 93 | else 94 | AddMenuOption(menu, "finish", "Finish spawn (%s)", g_TempNameBuffer); 95 | 96 | AddMenuOption(menu, "team", "Team: %s", TEAMSTRING(g_EditingSpawnTeam)); 97 | if (g_EditingSpawnTeam == CS_TEAM_CT) { 98 | AddMenuOption(menu, "a_friendly", "A site friendliness: %d", 99 | g_EditingSpawnSiteFriendly[BombsiteA]); 100 | AddMenuOption(menu, "b_friendly", "B site friendliness: %d", 101 | g_EditingSpawnSiteFriendly[BombsiteB]); 102 | AddMenuOption(menu, "awp_friendly", "AWP friendliness: %d", g_EditingSpawnAwpFriendly); 103 | AddMenuOption(menu, "likelihood", "Likelihood value: %d", g_EditingSpawnLikelihood); 104 | } else { 105 | AddMenuOption(menu, "bomb_friendly", "Bomb carrier friendliness: %d", 106 | g_EditingSpawnBombFriendly); 107 | AddMenuOption(menu, "awp_friendly", "AWP friendliness: %d", g_EditingSpawnAwpFriendly); 108 | 109 | char type[32]; 110 | GrenadeTypeName(g_EditingSpawnGrenadeType, type, sizeof(type)); 111 | AddMenuOptionDisabled(menu, "x", "Grenade: %s", type); 112 | 113 | char throwTime[32]; 114 | ThrowTimeString(g_EditingSpawnThrowTime, throwTime, sizeof(throwTime)); 115 | if (IsGrenade(g_EditingSpawnGrenadeType)) { 116 | AddMenuOption(menu, "grenade_throw_time", "Throw Grenade: %s", throwTime); 117 | } else { 118 | AddMenuOptionDisabled(menu, "grenade_throw_time", "Throw Grenade: %s", throwTime); 119 | } 120 | } 121 | 122 | AddMenuOption(menu, "flags", "Edit flags"); 123 | 124 | menu.ExitButton = true; 125 | menu.ExitBackButton = true; 126 | 127 | if (pos == -1) { 128 | menu.Display(client, MENU_TIME_FOREVER); 129 | } else { 130 | menu.DisplayAt(client, pos, MENU_TIME_FOREVER); 131 | } 132 | } 133 | 134 | public int GiveNewSpawnMenuHandler(Menu menu, MenuAction action, int param1, int param2) { 135 | if (action == MenuAction_Select) { 136 | int pos = GetMenuSelectionPosition(); 137 | int client = param1; 138 | char choice[64]; 139 | menu.GetItem(param2, choice, sizeof(choice)); 140 | if (StrEqual(choice, "finish")) { 141 | AddSpawn(client); 142 | GiveNewSpawnMenu(client, pos); 143 | 144 | } else if (StrEqual(choice, "team")) { 145 | g_EditingSpawnTeam = GetOtherTeam(g_EditingSpawnTeam); 146 | GiveNewSpawnMenu(client, pos); 147 | 148 | } else if (StrEqual(choice, "name")) { 149 | GiveNewSpawnMenu(client, pos); 150 | 151 | } else if (StrEqual(choice, "a_friendly")) { 152 | IncSiteFriendly(BombsiteA); 153 | GiveNewSpawnMenu(client, pos); 154 | 155 | } else if (StrEqual(choice, "b_friendly")) { 156 | IncSiteFriendly(BombsiteB); 157 | GiveNewSpawnMenu(client, pos); 158 | 159 | } else if (StrEqual(choice, "awp_friendly")) { 160 | IncAwpFriendly(); 161 | GiveNewSpawnMenu(client, pos); 162 | 163 | } else if (StrEqual(choice, "bomb_friendly")) { 164 | IncBombFriendly(); 165 | GiveNewSpawnMenu(client, pos); 166 | 167 | } else if (StrEqual(choice, "likelihood")) { 168 | IncSpawnLikelihood(); 169 | GiveNewSpawnMenu(client, pos); 170 | 171 | } else if (StrEqual(choice, "grenade_throw_time")) { 172 | IncThrowTime(); 173 | GiveNewSpawnMenu(client, pos); 174 | 175 | } else if (StrEqual(choice, "flags")) { 176 | GiveEditFlagsMenu(client); 177 | 178 | } else { 179 | LogError("unknown menu info string = %s", choice); 180 | } 181 | } else if (action == MenuAction_Cancel && param2 == MenuCancel_ExitBack) { 182 | int client = param1; 183 | GiveEditorMenu(client); 184 | } else if (action == MenuAction_End) { 185 | delete menu; 186 | } 187 | } 188 | 189 | public void IncSiteFriendly(Bombsite site) { 190 | g_EditingSpawnSiteFriendly[site]++; 191 | if (g_EditingSpawnSiteFriendly[site] > MAX_FRIENDLINESS) { 192 | g_EditingSpawnSiteFriendly[site] = MIN_FRIENDLINESS; 193 | } 194 | } 195 | 196 | public void IncAwpFriendly() { 197 | g_EditingSpawnAwpFriendly++; 198 | if (g_EditingSpawnAwpFriendly > MAX_FRIENDLINESS) { 199 | g_EditingSpawnAwpFriendly = MIN_FRIENDLINESS; 200 | } 201 | } 202 | 203 | public void IncBombFriendly() { 204 | g_EditingSpawnBombFriendly++; 205 | if (g_EditingSpawnBombFriendly > MAX_FRIENDLINESS) { 206 | g_EditingSpawnBombFriendly = MIN_FRIENDLINESS; 207 | } 208 | } 209 | 210 | public void IncSpawnLikelihood() { 211 | g_EditingSpawnLikelihood++; 212 | if (g_EditingSpawnLikelihood > MAX_FRIENDLINESS) { 213 | g_EditingSpawnLikelihood = MIN_FRIENDLINESS; 214 | } 215 | } 216 | 217 | public void IncExecuteLikelihood() { 218 | g_EditingExecuteLikelihood++; 219 | if (g_EditingExecuteLikelihood > MAX_FRIENDLINESS) { 220 | g_EditingExecuteLikelihood = MIN_FRIENDLINESS; 221 | } 222 | } 223 | 224 | public void ThrowTimeString(int time, char[] buf, int len) { 225 | if (time == 0) { 226 | Format(buf, len, "at freezetime end"); 227 | } else if (time > 0) { 228 | Format(buf, len, "%d AFTER freezetime end", time); 229 | } else { 230 | Format(buf, len, "%d BEFORE freezetime end", -time); 231 | } 232 | } 233 | 234 | public void IncThrowTime() { 235 | g_EditingSpawnThrowTime++; 236 | if (g_EditingSpawnThrowTime > 5) { 237 | g_EditingSpawnThrowTime = -3; 238 | } 239 | } 240 | 241 | stock void GiveNewExecuteMenu(int client, int pos = -1) { 242 | g_EditingExecutes = true; 243 | Menu menu = new Menu(GiveNewExecuteMenuHandler); 244 | if (g_EditingAnExecute) 245 | menu.SetTitle("Edit an execute"); 246 | else 247 | menu.SetTitle("Add an execute"); 248 | 249 | if (StrEqual(g_TempNameBuffer, "")) 250 | AddMenuOptionDisabled(menu, "finish", "Finish execute (use !setname to name it first)"); 251 | else 252 | AddMenuOption(menu, "finish", "finish execute (%s)", g_TempNameBuffer); 253 | 254 | AddMenuOption(menu, "site", "Site: %s", SITESTRING(g_EditingExecuteSite)); 255 | AddMenuOption(menu, "t_spawns", "Edit T spawns"); 256 | 257 | AddMenuOption(menu, "play_required_nades", "Play required nades"); 258 | AddMenuOption(menu, "play_all_nades", "Play all nades"); 259 | AddMenuOption(menu, "likelihood", "Likelihood value: %d", g_EditingExecuteLikelihood); 260 | 261 | AddMenuOption(menu, "strat_normal", "Gun round strat: %d", 262 | g_EditingExecuteStratTypes[StratType_Normal]); 263 | AddMenuOption(menu, "strat_pistol", "Pistol round strat: %d", 264 | g_EditingExecuteStratTypes[StratType_Pistol]); 265 | AddMenuOption(menu, "strat_force", "Force round strat: %d", 266 | g_EditingExecuteStratTypes[StratType_ForceBuy]); 267 | AddMenuOption(menu, "fake", "Is a fake: %s", g_EditingExecuteFake ? "yes" : "no"); 268 | 269 | if (IsValidSpawn(SpawnIdToIndex(g_EditingExecuteForceBombId))) { 270 | AddMenuOption(menu, "forcebomb_id", "Forced bomb spawn: %s", 271 | g_SpawnNames[SpawnIdToIndex(g_EditingExecuteForceBombId)]); 272 | } else { 273 | AddMenuOption(menu, "forcebomb_id", "Forced bomb spawn: none"); 274 | } 275 | 276 | if (g_EditingAnExecute) 277 | AddMenuOption(menu, "delete", "Delete this execute"); 278 | 279 | menu.ExitButton = true; 280 | menu.ExitBackButton = true; 281 | 282 | if (pos == -1) { 283 | menu.Display(client, MENU_TIME_FOREVER); 284 | } else { 285 | menu.DisplayAt(client, pos, MENU_TIME_FOREVER); 286 | } 287 | } 288 | 289 | public int GiveNewExecuteMenuHandler(Menu menu, MenuAction action, int param1, int param2) { 290 | if (action == MenuAction_Select) { 291 | int pos = GetMenuSelectionPosition(); 292 | int freezetime = GetEditMinFreezetime(); 293 | 294 | int client = param1; 295 | char choice[64]; 296 | menu.GetItem(param2, choice, sizeof(choice)); 297 | if (StrEqual(choice, "finish")) { 298 | AddExecute(client); 299 | GiveEditorMenu(client); 300 | 301 | } else if (StrEqual(choice, "delete")) { 302 | g_ExecuteDeleted[g_EditingExecuteIndex] = true; 303 | GiveEditorMenu(client); 304 | 305 | } else if (StrEqual(choice, "site")) { 306 | g_EditingExecuteSite = GetOtherSite(g_EditingExecuteSite); 307 | GiveNewExecuteMenu(client, pos); 308 | 309 | } else if (StrEqual(choice, "name")) { 310 | GiveNewExecuteMenu(client, pos); 311 | 312 | } else if (StrEqual(choice, "t_spawns")) { 313 | GiveExecuteSpawnsMenu(client); 314 | 315 | } else if (StrEqual(choice, "play_required_nades")) { 316 | ThrowEditingNades(float(freezetime), client, false); 317 | GiveNewExecuteMenu(client, pos); 318 | 319 | } else if (StrEqual(choice, "play_all_nades")) { 320 | ThrowEditingNades(float(freezetime), client, true); 321 | GiveNewExecuteMenu(client, pos); 322 | 323 | } else if (StrEqual(choice, "likelihood")) { 324 | IncExecuteLikelihood(); 325 | GiveNewExecuteMenu(client, pos); 326 | 327 | } else if (StrEqual(choice, "strat_normal")) { 328 | FlipStratType(StratType_Normal); 329 | GiveNewExecuteMenu(client, pos); 330 | 331 | } else if (StrEqual(choice, "strat_pistol")) { 332 | FlipStratType(StratType_Pistol); 333 | GiveNewExecuteMenu(client, pos); 334 | 335 | } else if (StrEqual(choice, "strat_force")) { 336 | FlipStratType(StratType_ForceBuy); 337 | GiveNewExecuteMenu(client, pos); 338 | 339 | } else if (StrEqual(choice, "fake")) { 340 | g_EditingExecuteFake = !g_EditingExecuteFake; 341 | GiveNewExecuteMenu(client, pos); 342 | 343 | } else if (StrEqual(choice, "forcebomb_id")) { 344 | GiveForceBombSpawneMenu(client); 345 | 346 | } else { 347 | LogError("unknown menu info string = %s", choice); 348 | } 349 | } else if (action == MenuAction_Cancel && param2 == MenuCancel_ExitBack) { 350 | int client = param1; 351 | GiveEditorMenu(client); 352 | g_EditingAnExecute = false; 353 | } else if (action == MenuAction_End) { 354 | delete menu; 355 | } 356 | } 357 | 358 | static void FlipStratType(StratType type) { 359 | g_EditingExecuteStratTypes[type] = !g_EditingExecuteStratTypes[type]; 360 | } 361 | 362 | public void GiveForceBombSpawneMenu(int client) { 363 | Menu menu = new Menu(GiveForceBombSpawneMenuHandler); 364 | menu.SetTitle("Select spawn to force bomb to"); 365 | 366 | for (int i = 0; i < g_EditingExecuteTRequired.Length; i++) { 367 | char id[ID_LENGTH]; 368 | g_EditingExecuteTRequired.GetString(i, id, sizeof(id)); 369 | int idx = SpawnIdToIndex(id); 370 | if (IsValidSpawn(idx)) 371 | AddMenuOption(menu, id, g_SpawnNames[idx]); 372 | } 373 | 374 | menu.ExitButton = true; 375 | menu.ExitBackButton = true; 376 | menu.Display(client, MENU_TIME_FOREVER); 377 | } 378 | 379 | public int GiveForceBombSpawneMenuHandler(Menu menu, MenuAction action, int param1, int param2) { 380 | if (action == MenuAction_Select) { 381 | int client = param1; 382 | menu.GetItem(param2, g_EditingExecuteForceBombId, ID_LENGTH); 383 | GiveNewExecuteMenu(client); 384 | 385 | } else if (action == MenuAction_Cancel && param2 == MenuCancel_ExitBack) { 386 | int client = param1; 387 | GiveNewExecuteMenu(client); 388 | 389 | } else if (action == MenuAction_End) { 390 | delete menu; 391 | } 392 | } 393 | 394 | static ArrayList GetSpawnList(bool required, int execute = -1) { 395 | // Use temp buffers lists 396 | if (execute == -1) { 397 | return required ? g_EditingExecuteTRequired : g_EditingExecuteTOptional; 398 | } 399 | 400 | return required ? g_ExecuteTSpawnsRequired[execute] : g_ExecuteTSpawnsOptional[execute]; 401 | } 402 | 403 | stock void GiveExecuteSpawnsMenu(int client, int menuPosition = -1) { 404 | Menu menu = new Menu(GiveExecuteSpawnsMenuHandler); 405 | menu.SetTitle("Select spawns"); 406 | int count = 0; 407 | 408 | for (int i = 0; i < g_NumSpawns; i++) { 409 | if (g_SpawnDeleted[i] || g_SpawnTeams[i] != CS_TEAM_T) { 410 | continue; 411 | } 412 | 413 | count++; 414 | 415 | char grenadeType[32]; 416 | GrenadeTypeName(g_SpawnGrenadeTypes[i], grenadeType, sizeof(grenadeType)); 417 | 418 | int useId = 0; 419 | char usedStr[32] = "not used"; 420 | if (GetSpawnList(true).FindString(g_SpawnIDs[i]) >= 0) { 421 | useId = 1; 422 | usedStr = "required"; 423 | } else if (GetSpawnList(false).FindString(g_SpawnIDs[i]) >= 0) { 424 | useId = 2; 425 | usedStr = "optional"; 426 | } 427 | 428 | char infoStr[ID_LENGTH + 16]; 429 | Format(infoStr, sizeof(infoStr), "%d %s", useId, g_SpawnIDs[i]); 430 | 431 | AddMenuOption(menu, infoStr, "%s: %s (id:%s, grenade:%s)", usedStr, g_SpawnNames[i], 432 | g_SpawnIDs[i], grenadeType); 433 | } 434 | 435 | menu.ExitButton = true; 436 | menu.ExitBackButton = true; 437 | 438 | if (count == 0) { 439 | delete menu; 440 | Executes_Message(client, "No spawns avaliable, add more."); 441 | GiveNewSpawnMenu(client); 442 | } else { 443 | if (menuPosition == -1) { 444 | menu.Display(client, MENU_TIME_FOREVER); 445 | } else { 446 | menu.DisplayAt(client, menuPosition, MENU_TIME_FOREVER); 447 | } 448 | } 449 | } 450 | 451 | public int GiveExecuteSpawnsMenuHandler(Menu menu, MenuAction action, int param1, int param2) { 452 | if (action == MenuAction_Select) { 453 | int client = param1; 454 | char info[32]; 455 | menu.GetItem(param2, info, sizeof(info)); 456 | 457 | char useString[2]; 458 | strcopy(useString, sizeof(useString), info); 459 | int useId = StringToInt(useString); 460 | 461 | char id[ID_LENGTH]; 462 | strcopy(id, sizeof(id), info[2]); 463 | int index = SpawnIdToIndex(id); 464 | 465 | if (useId == 0) { 466 | // not in use, make required 467 | SetSpawnStatus(id, Spawn_Required, GetSpawnList(true), GetSpawnList(false)); 468 | Executes_MessageToAll("Added spawn \"%s\" to execute.", g_SpawnNames[index]); 469 | 470 | } else if (useId == 1) { 471 | // required, make optional 472 | SetSpawnStatus(id, Spawn_Optional, GetSpawnList(true), GetSpawnList(false)); 473 | Executes_MessageToAll("Made spawn \"%s\" optional in execute.", g_SpawnNames[index]); 474 | 475 | } else { 476 | // optional, make not in use 477 | SetSpawnStatus(id, Spawn_NotUsed, GetSpawnList(true), GetSpawnList(false)); 478 | Executes_MessageToAll("Removed spawn \"%s\" from execute.", g_SpawnNames[index]); 479 | } 480 | 481 | int menuPosition = GetMenuSelectionPosition(); 482 | GiveExecuteSpawnsMenu(client, menuPosition); 483 | 484 | } else if (action == MenuAction_Cancel && param2 == MenuCancel_ExitBack) { 485 | int client = param1; 486 | GiveNewExecuteMenu(client); 487 | } else if (action == MenuAction_End) { 488 | delete menu; 489 | } 490 | } 491 | 492 | stock void GiveExecuteEditMenu(int client, int menuPosition = -1) { 493 | Menu menu = new Menu(GiveExecuteMenuHandler); 494 | menu.SetTitle("Select an execute to edit"); 495 | menu.ExitButton = true; 496 | menu.ExitBackButton = true; 497 | 498 | int count = 0; 499 | 500 | for (int i = 0; i < g_NumExecutes; i++) { 501 | if (g_ExecuteDeleted[i]) { 502 | continue; 503 | } 504 | 505 | AddMenuOption(menu, g_ExecuteIDs[i], "%s (id:%s)", g_ExecuteNames[i], g_ExecuteIDs[i]); 506 | count++; 507 | } 508 | 509 | if (count == 0) { 510 | delete menu; 511 | } else { 512 | if (menuPosition == -1) { 513 | menu.Display(client, MENU_TIME_FOREVER); 514 | } else { 515 | menu.DisplayAt(client, menuPosition, MENU_TIME_FOREVER); 516 | } 517 | } 518 | } 519 | 520 | public int GiveExecuteMenuHandler(Menu menu, MenuAction action, int param1, int param2) { 521 | if (action == MenuAction_Select) { 522 | int client = param1; 523 | char id[ID_LENGTH]; 524 | menu.GetItem(param2, id, sizeof(id)); 525 | int execute = ExecuteIdToIndex(id); 526 | 527 | g_TempNameBuffer = g_ExecuteNames[execute]; 528 | g_EditingAnExecute = true; 529 | g_EditingExecuteIndex = execute; 530 | g_EditingExecuteSite = g_ExecuteSites[execute]; 531 | g_EditingExecuteLikelihood = g_ExecuteLikelihood[execute]; 532 | 533 | g_EditingExecuteTRequired.Clear(); 534 | g_EditingExecuteTOptional.Clear(); 535 | CopyList(g_ExecuteTSpawnsRequired[execute], g_EditingExecuteTRequired); 536 | CopyList(g_ExecuteTSpawnsOptional[execute], g_EditingExecuteTOptional); 537 | strcopy(g_EditingExecuteForceBombId, ID_LENGTH, g_ExecuteForceBombId[execute]); 538 | g_EditingExecuteStratTypes = g_ExecuteStratTypes[execute]; 539 | 540 | GiveNewExecuteMenu(client); 541 | 542 | } else if (action == MenuAction_Cancel && param2 == MenuCancel_ExitBack) { 543 | g_EditingAnExecute = false; 544 | int client = param1; 545 | GiveNewExecuteMenu(client); 546 | } else if (action == MenuAction_End) { 547 | delete menu; 548 | } 549 | } 550 | 551 | stock void GiveEditSpawnChoiceMenu(int client, int menuPosition = -1) { 552 | Menu menu = new Menu(GiveEditSpawnChoiceMenuHandler); 553 | menu.SetTitle("Select a spawn to edit"); 554 | menu.ExitButton = true; 555 | menu.ExitBackButton = true; 556 | 557 | int count = 0; 558 | 559 | for (int i = 0; i < g_NumSpawns; i++) { 560 | if (g_SpawnDeleted[i]) { 561 | continue; 562 | } 563 | 564 | if (g_SpawnTeams[i] == CS_TEAM_CT) { 565 | AddMenuOption(menu, g_SpawnIDs[i], "%s (CT, id:%s)", g_SpawnNames[i], g_SpawnIDs[i]); 566 | } else { 567 | AddMenuOption(menu, g_SpawnIDs[i], "%s (T, id:%s)", g_SpawnNames[i], g_SpawnIDs[i]); 568 | } 569 | 570 | count++; 571 | } 572 | 573 | if (count == 0) { 574 | delete menu; 575 | } else { 576 | if (menuPosition == -1) { 577 | menu.Display(client, MENU_TIME_FOREVER); 578 | } else { 579 | menu.DisplayAt(client, menuPosition, MENU_TIME_FOREVER); 580 | } 581 | } 582 | } 583 | 584 | public int GiveEditSpawnChoiceMenuHandler(Menu menu, MenuAction action, int param1, int param2) { 585 | if (action == MenuAction_Select) { 586 | int client = param1; 587 | char id[ID_LENGTH]; 588 | menu.GetItem(param2, id, sizeof(id)); 589 | int spawn = SpawnIdToIndex(id); 590 | EditSpawn(client, spawn); 591 | 592 | } else if (action == MenuAction_Cancel && param2 == MenuCancel_ExitBack) { 593 | int client = param1; 594 | GiveEditorMenu(client); 595 | g_EditingASpawn = false; 596 | 597 | } else if (action == MenuAction_End) { 598 | delete menu; 599 | } 600 | } 601 | 602 | public void EditSpawn(int client, int spawn) { 603 | MoveToSpawnInEditor(client, spawn); 604 | g_TempNameBuffer = g_SpawnNames[spawn]; 605 | g_EditingSpawnTeam = g_SpawnTeams[spawn]; 606 | g_EditingSpawnGrenadeType = g_SpawnGrenadeTypes[spawn]; 607 | g_EditingSpawnNadePoint = g_SpawnNadePoints[spawn]; 608 | g_EditingSpawnNadeVelocity = g_SpawnNadeVelocities[spawn]; 609 | g_EditingSpawnSiteFriendly = g_SpawnSiteFriendly[spawn]; 610 | g_EditingSpawnAwpFriendly = g_SpawnAwpFriendly[spawn]; 611 | g_EditingSpawnBombFriendly = g_SpawnBombFriendly[spawn]; 612 | g_EditingSpawnLikelihood = g_SpawnLikelihood[spawn]; 613 | g_EditingSpawnThrowTime = g_SpawnGrenadeThrowTimes[spawn]; 614 | g_EditingSpawnFlags = g_SpawnFlags[spawn]; 615 | 616 | g_EditingASpawn = true; 617 | g_EditingSpawnIndex = spawn; 618 | GiveNewSpawnMenu(client); 619 | } 620 | 621 | public void GiveEditFlagsMenu(int client) { 622 | Menu menu = new Menu(EditFlagsHandler); 623 | menu.SetTitle("Select a flag to toggle"); 624 | menu.ExitButton = true; 625 | menu.ExitBackButton = true; 626 | 627 | AddFlag(menu, SPAWNFLAG_MOLOTOV, "molotov"); 628 | AddFlag(menu, SPAWNFLAG_FLASH, "flash"); 629 | AddFlag(menu, SPAWNFLAG_SMOKE, "smoke"); 630 | 631 | AddFlag(menu, SPAWNFLAG_MAG7, "mag7", CS_TEAM_CT); 632 | AddFlag(menu, SPAWNFLAG_ALURKER, "A lurker", CS_TEAM_T); 633 | AddFlag(menu, SPAWNFLAG_BLURKER, "B lurker", CS_TEAM_T); 634 | 635 | menu.Display(client, MENU_TIME_FOREVER); 636 | } 637 | 638 | static void AddFlag(Menu menu, int flag, const char[] title, int team = -1) { 639 | char tmp[16] = "enabled"; 640 | if (g_EditingSpawnFlags & flag == 0) { 641 | tmp = "disabled"; 642 | } 643 | char display[64]; 644 | Format(display, sizeof(display), "%s: %s", title, tmp); 645 | 646 | if (team == -1 || g_EditingSpawnTeam == team) { 647 | AddMenuInt(menu, flag, display); 648 | } 649 | } 650 | 651 | public int EditFlagsHandler(Menu menu, MenuAction action, int param1, int param2) { 652 | if (action == MenuAction_Select) { 653 | int client = param1; 654 | int flagMask = GetMenuInt(menu, param2); 655 | 656 | if (g_EditingSpawnFlags & flagMask == 0) { 657 | // Enabled the flag 658 | g_EditingSpawnFlags |= flagMask; 659 | } else { 660 | // Disable the flag 661 | g_EditingSpawnFlags &= ~flagMask; 662 | } 663 | 664 | GiveEditFlagsMenu(client); 665 | 666 | } else if (action == MenuAction_Cancel && param2 == MenuCancel_ExitBack) { 667 | int client = param1; 668 | GiveNewSpawnMenu(client); 669 | 670 | } else if (action == MenuAction_End) { 671 | delete menu; 672 | } 673 | } 674 | 675 | void SetSpawnStatus(const char[] id, SpawnStatus status, ArrayList req, ArrayList opt) { 676 | if (status == Spawn_NotUsed) { 677 | WipeFromList(req, id); 678 | WipeFromList(opt, id); 679 | } else if (status == Spawn_Required) { 680 | WipeFromList(opt, id); 681 | if (req.FindString(id) < 0) { 682 | req.PushString(id); 683 | } 684 | } else { 685 | // optional 686 | WipeFromList(req, id); 687 | if (opt.FindString(id) < 0) { 688 | opt.PushString(id); 689 | } 690 | } 691 | } 692 | -------------------------------------------------------------------------------- /configs/executes/de_cbble.cfg: -------------------------------------------------------------------------------- 1 | "Executes" 2 | { 3 | "Spawns" 4 | { 5 | "1" 6 | { 7 | "name" "balcony smoke" 8 | "origin" "-3168.003906 62.472958 -29.968748" 9 | "angle" "-51.585800 -47.890617 0.000000" 10 | "team" "T" 11 | "flags" "0" 12 | "awp_friendly" "3" 13 | "bomb_friendly" "3" 14 | "grenadeType" "smoke" 15 | "grenadeOrigin" "-3161.988281 69.353043 75.202255" 16 | "grenadeVelocity" "253.626587 -329.886780 823.930725" 17 | "grenadeThrowTime" "0" 18 | } 19 | "5" 20 | { 21 | "name" "A door smoke" 22 | "origin" "-3248.190674 42.692436 -29.968748" 23 | "angle" "-25.001642 -78.672066 0.000000" 24 | "team" "T" 25 | "flags" "1" 26 | "awp_friendly" "3" 27 | "bomb_friendly" "3" 28 | "grenadeType" "smoke" 29 | "grenadeOrigin" "-3274.628662 63.316380 48.702538" 30 | "grenadeVelocity" "378.546814 -295.197784 618.945068" 31 | "grenadeThrowTime" "0" 32 | } 33 | "6" 34 | { 35 | "name" "A van smoke" 36 | "origin" "-3328.597168 -50.507801 -29.968744" 37 | "angle" "-36.353714 -51.929157 0.000000" 38 | "team" "T" 39 | "flags" "1" 40 | "awp_friendly" "3" 41 | "bomb_friendly" "3" 42 | "grenadeType" "smoke" 43 | "grenadeOrigin" "-3321.437744 -60.365421 44.802422" 44 | "grenadeVelocity" "307.785309 -392.944855 454.408783" 45 | "grenadeThrowTime" "0" 46 | } 47 | "7" 48 | { 49 | "name" "backsite smoke" 50 | "origin" "-3314.211914 519.546448 0.031250" 51 | "angle" "-21.147161 -70.921265 0.000000" 52 | "team" "T" 53 | "flags" "0" 54 | "awp_friendly" "3" 55 | "bomb_friendly" "3" 56 | "grenadeType" "smoke" 57 | "grenadeOrigin" "-3309.629150 506.295715 99.642235" 58 | "grenadeVelocity" "193.348770 -559.029175 589.368164" 59 | "grenadeThrowTime" "0" 60 | } 61 | "8" 62 | { 63 | "name" "A left side van smoke" 64 | "origin" "-3295.982422 79.968773 -29.968739" 65 | "angle" "-15.550714 -33.114414 0.000000" 66 | "team" "T" 67 | "flags" "0" 68 | "awp_friendly" "3" 69 | "bomb_friendly" "3" 70 | "grenadeType" "smoke" 71 | "grenadeOrigin" "-3283.722900 71.972466 68.397385" 72 | "grenadeVelocity" "517.197327 -337.342102 536.848450" 73 | "grenadeThrowTime" "0" 74 | } 75 | "9" 76 | { 77 | "name" "vent room smoke" 78 | "origin" "-3313.382568 10.343041 -29.968739" 79 | "angle" "-39.734859 -44.060619 0.000000" 80 | "team" "T" 81 | "flags" "0" 82 | "awp_friendly" "3" 83 | "bomb_friendly" "3" 84 | "grenadeType" "smoke" 85 | "grenadeOrigin" "-3303.406006 1.395361 45.792622" 86 | "grenadeVelocity" "375.491150 -338.422882 496.182983" 87 | "grenadeThrowTime" "0" 88 | } 89 | "10" 90 | { 91 | "name" "sidewalk smoke" 92 | "origin" "-340.003784 -80.001907 -31.968739" 93 | "angle" "-53.169376 -64.604874 0.000000" 94 | "team" "T" 95 | "flags" "0" 96 | "awp_friendly" "3" 97 | "bomb_friendly" "3" 98 | "grenadeType" "smoke" 99 | "grenadeOrigin" "-336.293152 -87.818901 45.489635" 100 | "grenadeVelocity" "156.551407 -329.768768 567.775696" 101 | "grenadeThrowTime" "0" 102 | } 103 | "11" 104 | { 105 | "name" "B sitesmoke" 106 | "origin" "-435.381683 -87.356743 -32.275257" 107 | "angle" "-8.658939 -18.668797 0.000000" 108 | "team" "T" 109 | "flags" "0" 110 | "awp_friendly" "3" 111 | "bomb_friendly" "4" 112 | "grenadeType" "smoke" 113 | "grenadeOrigin" "-439.611816 -85.929733 66.410583" 114 | "grenadeVelocity" "645.009460 -217.601425 461.057281" 115 | "grenadeThrowTime" "0" 116 | } 117 | "12" 118 | { 119 | "name" "left rock smoke" 120 | "origin" "47.991901 -16.004313 -23.177280" 121 | "angle" "-61.010136 -110.672234 0.000000" 122 | "team" "T" 123 | "flags" "1" 124 | "awp_friendly" "2" 125 | "bomb_friendly" "3" 126 | "grenadeType" "smoke" 127 | "grenadeOrigin" "45.536339 -22.512306 55.231613" 128 | "grenadeVelocity" "-103.594048 -274.556030 607.875183" 129 | "grenadeThrowTime" "1" 130 | } 131 | "13" 132 | { 133 | "name" "right rock smoke" 134 | "origin" "-461.470001 -80.032967 -31.970100" 135 | "angle" "-73.145523 -83.263954 0.000000" 136 | "team" "T" 137 | "flags" "16" 138 | "awp_friendly" "4" 139 | "bomb_friendly" "4" 140 | "grenadeType" "smoke" 141 | "grenadeOrigin" "-460.984863 -84.140602 47.486031" 142 | "grenadeVelocity" "20.467514 -173.290726 652.055542" 143 | "grenadeThrowTime" "0" 144 | } 145 | "15" 146 | { 147 | "name" "B deep site smoke" 148 | "origin" "-703.985229 -80.679092 -28.984785" 149 | "angle" "-74.679573 -50.873196 0.000000" 150 | "team" "T" 151 | "flags" "0" 152 | "awp_friendly" "3" 153 | "bomb_friendly" "3" 154 | "grenadeType" "smoke" 155 | "grenadeOrigin" "-699.524231 -86.158783 78.458160" 156 | "grenadeVelocity" "125.182304 -153.456177 919.840942" 157 | "grenadeThrowTime" "0" 158 | } 159 | "16" 160 | { 161 | "name" "right drop smoke" 162 | "origin" "-865.995239 -80.031250 128.031250" 163 | "angle" "-3.135520 -49.315666 0.000000" 164 | "team" "T" 165 | "flags" "0" 166 | "awp_friendly" "1" 167 | "bomb_friendly" "1" 168 | "grenadeType" "smoke" 169 | "grenadeOrigin" "-855.823303 -91.863350 195.572525" 170 | "grenadeVelocity" "429.113312 -499.166565 149.397354" 171 | "grenadeThrowTime" "0" 172 | } 173 | "17" 174 | { 175 | "name" "treemolly" 176 | "origin" "47.985481 -16.006802 -23.172846" 177 | "angle" "-33.865200 -125.083618 0.000000" 178 | "team" "T" 179 | "flags" "0" 180 | "awp_friendly" "3" 181 | "bomb_friendly" "3" 182 | "grenadeType" "molotov" 183 | "grenadeOrigin" "40.951126 -26.021584 51.133522" 184 | "grenadeVelocity" "-296.756561 -422.498627 434.805054" 185 | "grenadeThrowTime" "0" 186 | } 187 | "18" 188 | { 189 | "name" "top drop room" 190 | "origin" "-775.832581 31.201242 128.031250" 191 | "angle" "2.257229 -93.757973 0.000000" 192 | "team" "T" 193 | "flags" "0" 194 | "awp_friendly" "1" 195 | "bomb_friendly" "1" 196 | "grenadeType" "none" 197 | } 198 | "19" 199 | { 200 | "name" "B door smoke" 201 | "origin" "-340.001556 -80.031250 -31.976334" 202 | "angle" "-61.373566 -112.646637 0.000000" 203 | "team" "T" 204 | "flags" "0" 205 | "awp_friendly" "3" 206 | "bomb_friendly" "3" 207 | "grenadeType" "smoke" 208 | "grenadeOrigin" "-342.639771 -86.379349 46.471554" 209 | "grenadeVelocity" "-111.300232 -267.810394 609.520203" 210 | "grenadeThrowTime" "1" 211 | } 212 | "20" 213 | { 214 | "name" "Back B" 215 | "origin" "-531.276917 -258.831360 -33.455585" 216 | "angle" "-0.645963 2.062818 0.000000" 217 | "team" "T" 218 | "flags" "0" 219 | "awp_friendly" "3" 220 | "bomb_friendly" "3" 221 | "grenadeType" "none" 222 | } 223 | "21" 224 | { 225 | "name" "close B plat" 226 | "origin" "-26.294006 -187.305527 -31.968739" 227 | "angle" "0.231082 -9.540668 0.000000" 228 | "team" "T" 229 | "flags" "0" 230 | "awp_friendly" "3" 231 | "bomb_friendly" "3" 232 | "grenadeType" "none" 233 | } 234 | "23" 235 | { 236 | "name" "brokenwallsmoke" 237 | "origin" "-320.954285 -239.968719 -31.968739" 238 | "angle" "9.272746 0.028717 0.000000" 239 | "team" "T" 240 | "flags" "0" 241 | "awp_friendly" "3" 242 | "bomb_friendly" "3" 243 | "grenadeType" "smoke" 244 | "grenadeOrigin" "-304.954651 -239.960678 31.946659" 245 | "grenadeVelocity" "674.990723 0.338309 -3.570511" 246 | "grenadeThrowTime" "0" 247 | } 248 | "24" 249 | { 250 | "name" "drop stairs" 251 | "origin" "-936.374207 85.497643 64.031250" 252 | "angle" "-4.977648 -41.470165 0.000000" 253 | "team" "T" 254 | "flags" "0" 255 | "awp_friendly" "1" 256 | "bomb_friendly" "1" 257 | "grenadeType" "none" 258 | } 259 | "26" 260 | { 261 | "name" "Close B" 262 | "origin" "-136.278534 -51.490200 -31.968739" 263 | "angle" "1.917794 -25.979240 0.000000" 264 | "team" "T" 265 | "flags" "0" 266 | "awp_friendly" "3" 267 | "bomb_friendly" "3" 268 | "grenadeType" "none" 269 | } 270 | "27" 271 | { 272 | "name" "Mid door spawn" 273 | "origin" "-2358.622559 505.707245 -239.968719" 274 | "angle" "-0.316562 -102.578888 0.000000" 275 | "team" "T" 276 | "flags" "0" 277 | "awp_friendly" "3" 278 | "bomb_friendly" "3" 279 | "grenadeType" "none" 280 | } 281 | "28" 282 | { 283 | "name" "near door" 284 | "origin" "-2561.298096 324.650787 -239.968719" 285 | "angle" "0.024144 -40.491199 0.000000" 286 | "team" "T" 287 | "flags" "0" 288 | "awp_friendly" "3" 289 | "bomb_friendly" "3" 290 | "grenadeType" "none" 291 | } 292 | "29" 293 | { 294 | "name" "bottom dungeon" 295 | "origin" "-2675.568848 115.890129 -213.583206" 296 | "angle" "2.061250 -8.466604 0.000000" 297 | "team" "T" 298 | "flags" "0" 299 | "awp_friendly" "3" 300 | "bomb_friendly" "3" 301 | "grenadeType" "none" 302 | } 303 | "30" 304 | { 305 | "name" "Top dungeon" 306 | "origin" "-3084.599854 -107.815147 -29.968739" 307 | "angle" "-2.929236 -120.363365 0.000000" 308 | "team" "T" 309 | "flags" "0" 310 | "awp_friendly" "3" 311 | "bomb_friendly" "4" 312 | "grenadeType" "none" 313 | } 314 | "31" 315 | { 316 | "name" "Dungeon stairs" 317 | "origin" "-2815.689697 105.340942 -159.968719" 318 | "angle" "8.943089 -6.005941 0.000000" 319 | "team" "T" 320 | "flags" "0" 321 | "awp_friendly" "3" 322 | "bomb_friendly" "5" 323 | "grenadeType" "none" 324 | } 325 | "32" 326 | { 327 | "name" "Middle dungeon" 328 | "origin" "-2652.031250 -151.998749 -95.968773" 329 | "angle" "-3.887691 177.493134 0.000000" 330 | "team" "T" 331 | "flags" "0" 332 | "awp_friendly" "3" 333 | "bomb_friendly" "4" 334 | "grenadeType" "none" 335 | } 336 | "33" 337 | { 338 | "name" "Back long A" 339 | "origin" "-3200.250244 207.761200 0.031250" 340 | "angle" "-0.625693 -90.838745 0.000000" 341 | "team" "T" 342 | "flags" "0" 343 | "awp_friendly" "3" 344 | "bomb_friendly" "4" 345 | "grenadeType" "none" 346 | } 347 | "34" 348 | { 349 | "name" "close A mid" 350 | "origin" "-2545.085449 -316.477051 -161.605820" 351 | "angle" "6.467269 40.387741 0.000000" 352 | "team" "CT" 353 | "flags" "0" 354 | "awp_friendly" "1" 355 | "A_friendly" "5" 356 | "B_friendly" "1" 357 | "likelihood" "3" 358 | "close" "1" 359 | "site" "any" 360 | } 361 | "35" 362 | { 363 | "name" "Boosted A wall" 364 | "origin" "-2513.451904 -622.978210 128.031250" 365 | "angle" "25.344646 64.515701 0.000000" 366 | "team" "CT" 367 | "flags" "0" 368 | "awp_friendly" "1" 369 | "A_friendly" "5" 370 | "B_friendly" "1" 371 | "likelihood" "1" 372 | "close" "1" 373 | "site" "any" 374 | } 375 | "36" 376 | { 377 | "name" "Back A site" 378 | "origin" "-2580.061523 -1836.113159 48.031216" 379 | "angle" "1.898932 102.956032 0.000000" 380 | "team" "CT" 381 | "flags" "0" 382 | "awp_friendly" "4" 383 | "A_friendly" "5" 384 | "B_friendly" "1" 385 | "likelihood" "4" 386 | "close" "0" 387 | "site" "any" 388 | } 389 | "37" 390 | { 391 | "name" "Back Van" 392 | "origin" "-2207.586670 -1455.057373 -9.803118" 393 | "angle" "1.412009 104.761559 0.000000" 394 | "team" "CT" 395 | "flags" "0" 396 | "awp_friendly" "4" 397 | "A_friendly" "4" 398 | "B_friendly" "2" 399 | "likelihood" "3" 400 | "close" "0" 401 | "site" "any" 402 | } 403 | "38" 404 | { 405 | "name" "A balcony" 406 | "origin" "-1792.376831 -1626.493042 96.031250" 407 | "angle" "4.068563 157.518158 0.000000" 408 | "team" "CT" 409 | "flags" "0" 410 | "awp_friendly" "4" 411 | "A_friendly" "4" 412 | "B_friendly" "2" 413 | "likelihood" "3" 414 | "close" "0" 415 | "site" "any" 416 | } 417 | "39" 418 | { 419 | "name" "watching drop window" 420 | "origin" "-1090.817993 -852.317505 -101.555458" 421 | "angle" "-15.861959 89.869942 0.000000" 422 | "team" "CT" 423 | "flags" "0" 424 | "awp_friendly" "1" 425 | "A_friendly" "3" 426 | "B_friendly" "3" 427 | "likelihood" "3" 428 | "close" "0" 429 | "site" "any" 430 | } 431 | "40" 432 | { 433 | "name" "Holding drop" 434 | "origin" "-548.668945 -702.442566 -31.968739" 435 | "angle" "0.593667 153.962570 0.000000" 436 | "team" "CT" 437 | "flags" "0" 438 | "awp_friendly" "1" 439 | "A_friendly" "2" 440 | "B_friendly" "4" 441 | "likelihood" "2" 442 | "close" "1" 443 | "site" "any" 444 | } 445 | "41" 446 | { 447 | "name" "Boosted tree" 448 | "origin" "-43.717197 -665.158447 67.746521" 449 | "angle" "7.587590 51.171616 0.000000" 450 | "team" "CT" 451 | "flags" "0" 452 | "awp_friendly" "1" 453 | "A_friendly" "1" 454 | "B_friendly" "5" 455 | "likelihood" "2" 456 | "close" "1" 457 | "site" "any" 458 | } 459 | "42" 460 | { 461 | "name" "Behind statue" 462 | "origin" "136.324493 -1157.432861 -119.387184" 463 | "angle" "-7.236179 54.717407 0.000000" 464 | "team" "CT" 465 | "flags" "0" 466 | "awp_friendly" "4" 467 | "A_friendly" "1" 468 | "B_friendly" "5" 469 | "likelihood" "5" 470 | "close" "0" 471 | "site" "any" 472 | } 473 | "44" 474 | { 475 | "name" "Back rock" 476 | "origin" "-462.608398 -933.743042 -115.551880" 477 | "angle" "-5.474607 50.497173 0.000000" 478 | "team" "CT" 479 | "flags" "0" 480 | "awp_friendly" "2" 481 | "A_friendly" "2" 482 | "B_friendly" "4" 483 | "likelihood" "3" 484 | "close" "0" 485 | "site" "any" 486 | } 487 | "45" 488 | { 489 | "name" "Near connector door" 490 | "origin" "-1611.850342 -1226.655762 0.031250" 491 | "angle" "0.765200 110.685234 0.000000" 492 | "team" "CT" 493 | "flags" "0" 494 | "awp_friendly" "3" 495 | "A_friendly" "3" 496 | "B_friendly" "3" 497 | "likelihood" "3" 498 | "close" "0" 499 | "site" "any" 500 | } 501 | "46" 502 | { 503 | "name" "Left drop smoke" 504 | "origin" "-752.002197 -80.007172 128.031250" 505 | "angle" "-2.510971 -119.470474 0.000000" 506 | "team" "T" 507 | "flags" "1" 508 | "awp_friendly" "1" 509 | "bomb_friendly" "1" 510 | "grenadeType" "smoke" 511 | "grenadeOrigin" "-759.708801 -93.611732 195.426041" 512 | "grenadeVelocity" "-325.120789 -573.942505 143.218399" 513 | "grenadeThrowTime" "0" 514 | } 515 | "47" 516 | { 517 | "name" "Chicken coop" 518 | "origin" "490.702515 -1431.969360 -79.968773" 519 | "angle" "1.387050 38.120560 0.000000" 520 | "team" "CT" 521 | "flags" "0" 522 | "awp_friendly" "5" 523 | "A_friendly" "1" 524 | "B_friendly" "5" 525 | "likelihood" "3" 526 | "close" "0" 527 | "site" "any" 528 | } 529 | "48" 530 | { 531 | "name" "B pit" 532 | "origin" "-131.191895 -708.959351 -107.908279" 533 | "angle" "-9.980068 156.442169 0.000000" 534 | "team" "CT" 535 | "flags" "0" 536 | "awp_friendly" "1" 537 | "A_friendly" "1" 538 | "B_friendly" "5" 539 | "likelihood" "2" 540 | "close" "0" 541 | "site" "any" 542 | } 543 | "51" 544 | { 545 | "name" "Under drop" 546 | "origin" "-941.531006 -423.942902 -31.968739" 547 | "angle" "-50.352997 15.808799 0.000000" 548 | "team" "CT" 549 | "flags" "2" 550 | "awp_friendly" "1" 551 | "A_friendly" "2" 552 | "B_friendly" "3" 553 | "likelihood" "1" 554 | "close" "1" 555 | "site" "any" 556 | } 557 | "52" 558 | { 559 | "name" "Wood" 560 | "origin" "-2877.090576 -1204.512573 32.031216" 561 | "angle" "2.719009 101.212456 0.000000" 562 | "team" "CT" 563 | "flags" "0" 564 | "awp_friendly" "1" 565 | "A_friendly" "5" 566 | "B_friendly" "1" 567 | "likelihood" "3" 568 | "close" "1" 569 | "site" "any" 570 | } 571 | "53" 572 | { 573 | "name" "A cannons" 574 | "origin" "-2991.456299 -1383.763062 48.031250" 575 | "angle" "3.140851 32.202957 0.000000" 576 | "team" "CT" 577 | "flags" "0" 578 | "awp_friendly" "1" 579 | "A_friendly" "5" 580 | "B_friendly" "1" 581 | "likelihood" "3" 582 | "close" "0" 583 | "site" "any" 584 | } 585 | "54" 586 | { 587 | "name" "A doors" 588 | "origin" "-1808.199219 -919.290833 0.031250" 589 | "angle" "-0.555075 169.600357 0.000000" 590 | "team" "CT" 591 | "flags" "0" 592 | "awp_friendly" "5" 593 | "A_friendly" "4" 594 | "B_friendly" "2" 595 | "likelihood" "3" 596 | "close" "0" 597 | "site" "any" 598 | } 599 | "55" 600 | { 601 | "name" "Back B popflash" 602 | "origin" "-703.968750 -149.581085 -29.971710" 603 | "angle" "-33.266975 -12.026841 0.000000" 604 | "team" "T" 605 | "flags" "0" 606 | "awp_friendly" "3" 607 | "bomb_friendly" "3" 608 | "grenadeType" "flash" 609 | "grenadeOrigin" "-691.906006 -152.150986 44.220741" 610 | "grenadeVelocity" "508.895782 -108.418373 429.994659" 611 | "grenadeThrowTime" "0" 612 | } 613 | "56" 614 | { 615 | "name" "Optic smoke 1" 616 | "origin" "-340.027283 -80.008278 -31.968739" 617 | "angle" "-73.718262 -70.933228 0.000308" 618 | "team" "T" 619 | "flags" "0" 620 | "awp_friendly" "3" 621 | "bomb_friendly" "3" 622 | "grenadeType" "smoke" 623 | "grenadeOrigin" "-338.721039 -83.787613 47.523518" 624 | "grenadeVelocity" "55.107437 -159.439774 653.580261" 625 | "grenadeThrowTime" "0" 626 | } 627 | "57" 628 | { 629 | "name" "Optic wall smoke 2" 630 | "origin" "47.968845 -16.005589 -23.177280" 631 | "angle" "-77.162354 -119.020355 0.000000" 632 | "team" "T" 633 | "flags" "1" 634 | "awp_friendly" "3" 635 | "bomb_friendly" "3" 636 | "grenadeType" "smoke" 637 | "grenadeOrigin" "46.433136 -18.773745 56.506439" 638 | "grenadeVelocity" "-64.787102 -116.781174 661.656494" 639 | "grenadeThrowTime" "0" 640 | } 641 | "58" 642 | { 643 | "name" "Optic wall smoke 3" 644 | "origin" "-703.999023 -80.668404 -28.982668" 645 | "angle" "-59.172363 -64.874268 0.000000" 646 | "team" "T" 647 | "flags" "0" 648 | "awp_friendly" "3" 649 | "bomb_friendly" "3" 650 | "grenadeType" "smoke" 651 | "grenadeOrigin" "-700.872314 -87.335396 49.222080" 652 | "grenadeVelocity" "131.907898 -281.264313 599.262634" 653 | "grenadeThrowTime" "0" 654 | } 655 | "59" 656 | { 657 | "name" "NiP smoke 1" 658 | "origin" "-1601.499268 1016.087524 100.240456" 659 | "angle" "-44.628632 -54.843750 0.000000" 660 | "team" "T" 661 | "flags" "0" 662 | "awp_friendly" "1" 663 | "bomb_friendly" "1" 664 | "grenadeType" "smoke" 665 | "grenadeOrigin" "-1595.536743 1007.621155 204.341187" 666 | "grenadeVelocity" "251.543869 -357.164825 778.782227" 667 | "grenadeThrowTime" "1" 668 | } 669 | "60" 670 | { 671 | "name" "NiP smoke 2" 672 | "origin" "-1602.274292 1060.870117 100.240456" 673 | "angle" "-41.835938 -52.031216 0.000000" 674 | "team" "T" 675 | "flags" "0" 676 | "awp_friendly" "1" 677 | "bomb_friendly" "1" 678 | "grenadeType" "smoke" 679 | "grenadeOrigin" "-1595.584473 1052.297485 203.881226" 680 | "grenadeVelocity" "282.225983 -361.638702 759.378052" 681 | "grenadeThrowTime" "1" 682 | } 683 | "61" 684 | { 685 | "name" "NiP smoke 3" 686 | "origin" "-1566.000977 1020.058472 64.031250" 687 | "angle" "-52.031216 -65.039062 0.000000" 688 | "team" "T" 689 | "flags" "0" 690 | "awp_friendly" "1" 691 | "bomb_friendly" "1" 692 | "grenadeType" "smoke" 693 | "grenadeOrigin" "-1562.249756 1011.999634 169.238312" 694 | "grenadeVelocity" "158.254410 -339.982666 825.452271" 695 | "grenadeThrowTime" "0" 696 | } 697 | "62" 698 | { 699 | "name" "B cubby" 700 | "origin" "893.449707 -750.114197 -113.078377" 701 | "angle" "-4.774032 153.584229 0.000000" 702 | "team" "CT" 703 | "flags" "0" 704 | "awp_friendly" "1" 705 | "A_friendly" "1" 706 | "B_friendly" "5" 707 | "likelihood" "2" 708 | "close" "0" 709 | "site" "any" 710 | } 711 | "63" 712 | { 713 | "name" "Back A site corner" 714 | "origin" "-2897.187744 -2019.120483 48.031219" 715 | "angle" "1.998016 43.374260 0.000000" 716 | "team" "CT" 717 | "flags" "2" 718 | "awp_friendly" "1" 719 | "A_friendly" "4" 720 | "B_friendly" "1" 721 | "likelihood" "1" 722 | "close" "0" 723 | "site" "any" 724 | } 725 | } 726 | "Executes" 727 | { 728 | "0" 729 | { 730 | "name" "Standard B smokes" 731 | "site" "B" 732 | "likelihood" "4" 733 | "strat_normal" "1" 734 | "strat_pistol" "0" 735 | "strat_force" "1" 736 | "fake" "0" 737 | "extra_freeze_time" "1.300000" 738 | "t_players" 739 | { 740 | "23" "required" 741 | "11" "required" 742 | "10" "required" 743 | "24" "optional" 744 | "26" "optional" 745 | "21" "optional" 746 | "20" "optional" 747 | } 748 | } 749 | "1" 750 | { 751 | "name" "Drop split to B (rock smokes)" 752 | "site" "B" 753 | "likelihood" "4" 754 | "strat_normal" "1" 755 | "strat_pistol" "1" 756 | "strat_force" "1" 757 | "fake" "0" 758 | "extra_freeze_time" "1.300000" 759 | "t_players" 760 | { 761 | "12" "required" 762 | "13" "required" 763 | "16" "required" 764 | "15" "optional" 765 | "24" "optional" 766 | "18" "optional" 767 | } 768 | } 769 | "2" 770 | { 771 | "name" "Sidewalk/drop smokes" 772 | "site" "B" 773 | "likelihood" "4" 774 | "strat_normal" "1" 775 | "strat_pistol" "1" 776 | "strat_force" "0" 777 | "fake" "0" 778 | "extra_freeze_time" "1.300000" 779 | "t_players" 780 | { 781 | "10" "required" 782 | "16" "required" 783 | "24" "optional" 784 | "18" "optional" 785 | "21" "optional" 786 | "26" "optional" 787 | } 788 | } 789 | "3" 790 | { 791 | "name" "Standard A smokes" 792 | "site" "A" 793 | "likelihood" "5" 794 | "strat_normal" "1" 795 | "strat_pistol" "1" 796 | "strat_force" "0" 797 | "fake" "0" 798 | "extra_freeze_time" "1.300000" 799 | "t_players" 800 | { 801 | "1" "required" 802 | "5" "required" 803 | "31" "optional" 804 | "33" "optional" 805 | "28" "optional" 806 | "29" "optional" 807 | "30" "optional" 808 | } 809 | } 810 | "4" 811 | { 812 | "name" "Full A wall smokes" 813 | "site" "A" 814 | "likelihood" "1" 815 | "strat_normal" "1" 816 | "strat_pistol" "0" 817 | "strat_force" "1" 818 | "fake" "0" 819 | "extra_freeze_time" "1.300000" 820 | "t_players" 821 | { 822 | "6" "required" 823 | "7" "required" 824 | "5" "required" 825 | "8" "required" 826 | "31" "optional" 827 | "33" "optional" 828 | "28" "optional" 829 | "29" "optional" 830 | "30" "optional" 831 | } 832 | } 833 | "5" 834 | { 835 | "name" "A isolation smokes" 836 | "site" "A" 837 | "likelihood" "2" 838 | "strat_normal" "1" 839 | "strat_pistol" "0" 840 | "strat_force" "0" 841 | "fake" "0" 842 | "extra_freeze_time" "1.300000" 843 | "t_players" 844 | { 845 | "1" "required" 846 | "5" "required" 847 | "9" "required" 848 | "32" "optional" 849 | "31" "optional" 850 | "27" "optional" 851 | "28" "optional" 852 | "29" "optional" 853 | } 854 | } 855 | "6" 856 | { 857 | "name" "A split through drop" 858 | "site" "A" 859 | "likelihood" "2" 860 | "strat_normal" "1" 861 | "strat_pistol" "1" 862 | "strat_force" "1" 863 | "fake" "0" 864 | "extra_freeze_time" "1.300000" 865 | "t_players" 866 | { 867 | "6" "required" 868 | "46" "required" 869 | "31" "optional" 870 | "33" "optional" 871 | "28" "optional" 872 | "29" "optional" 873 | "30" "optional" 874 | "24" "optional" 875 | "18" "optional" 876 | } 877 | } 878 | "7" 879 | { 880 | "name" "Explode out B with a popflash" 881 | "site" "B" 882 | "likelihood" "2" 883 | "strat_normal" "1" 884 | "strat_pistol" "1" 885 | "strat_force" "1" 886 | "fake" "0" 887 | "extra_freeze_time" "1.300000" 888 | "t_players" 889 | { 890 | "55" "required" 891 | "20" "optional" 892 | "21" "optional" 893 | "19" "optional" 894 | "18" "optional" 895 | "16" "optional" 896 | } 897 | } 898 | "8" 899 | { 900 | "name" "Optic B smoke wall" 901 | "site" "B" 902 | "likelihood" "4" 903 | "forcebomb_id" "57" 904 | "strat_normal" "1" 905 | "strat_pistol" "0" 906 | "strat_force" "1" 907 | "fake" "0" 908 | "extra_freeze_time" "1.300000" 909 | "t_players" 910 | { 911 | "56" "required" 912 | "57" "required" 913 | "58" "required" 914 | "18" "optional" 915 | "20" "optional" 916 | "24" "optional" 917 | "26" "optional" 918 | } 919 | } 920 | "9" 921 | { 922 | "name" "NiP B smokes to B" 923 | "site" "B" 924 | "likelihood" "1" 925 | "strat_normal" "1" 926 | "strat_pistol" "0" 927 | "strat_force" "0" 928 | "fake" "0" 929 | "extra_freeze_time" "1.300000" 930 | "t_players" 931 | { 932 | "59" "required" 933 | "60" "required" 934 | "61" "required" 935 | "10" "required" 936 | "20" "optional" 937 | "21" "optional" 938 | "26" "optional" 939 | "24" "optional" 940 | } 941 | } 942 | "10" 943 | { 944 | "name" "Fake NiP B smokes -> up mid to A" 945 | "site" "A" 946 | "likelihood" "1" 947 | "forcebomb_id" "32" 948 | "strat_normal" "1" 949 | "strat_pistol" "0" 950 | "strat_force" "0" 951 | "fake" "1" 952 | "extra_freeze_time" "1.300000" 953 | "t_players" 954 | { 955 | "59" "required" 956 | "60" "required" 957 | "61" "required" 958 | "10" "required" 959 | "32" "required" 960 | "29" "optional" 961 | "31" "optional" 962 | "30" "optional" 963 | } 964 | } 965 | } 966 | } 967 | --------------------------------------------------------------------------------