// l4d2-campaign-shortcuts.sp — Left 4 Dead 2 SourceMod plugin // // Admin-only chat shortcuts to jump straight to any campaign (L4D1 + L4D2). // Each command requires the standard ADMFLAG_CHANGEMAP ("a") flag. // // Build: // spcomp l4d2-campaign-shortcuts.sp -o l4d2-campaign-shortcuts.smx // Drop the .smx into addons/sourcemod/plugins/ on the server. // // Commands (use ! or sm_ prefix in chat / RCON): // !campaigns list every shortcut in chat // !dead Dead Center !nm No Mercy // !dc Dark Carnival !cc Crash Course // !sf Swamp Fever !toll Death Toll // !hr Hard Rain !da Dead Air // !parish The Parish !bh Blood Harvest // !passing The Passing !cs Cold Stream // !sacrifice The Sacrifice // // Behavior: // On any shortcut, the plugin announces the switch in chat, waits 2 seconds // so players see why the map is changing, then issues `changelevel `. // // Author: magikh0e // License: GPL-3.0-or-later #include #include #pragma semicolon 1 #pragma newdecls required #define PLUGIN_VERSION "1.0" public Plugin myinfo = { name = "Campaign Shortcuts (Admin)", author = "magikh0e", description = "Admin-only chat commands to jump to any campaign", version = PLUGIN_VERSION, url = "" }; public void OnPluginStart() { // Each shortcut requires ADMFLAG_CHANGEMAP (the standard 'a' flag for map admins) RegAdminCmd("sm_campaigns", Cmd_ListCampaigns, ADMFLAG_CHANGEMAP, "List all campaign shortcuts"); RegAdminCmd("sm_dc", Cmd_GoDarkCarnival, ADMFLAG_CHANGEMAP, "Jump to Dark Carnival"); RegAdminCmd("sm_dead", Cmd_GoDeadCenter, ADMFLAG_CHANGEMAP, "Jump to Dead Center"); RegAdminCmd("sm_sf", Cmd_GoSwampFever, ADMFLAG_CHANGEMAP, "Jump to Swamp Fever"); RegAdminCmd("sm_hr", Cmd_GoHardRain, ADMFLAG_CHANGEMAP, "Jump to Hard Rain"); RegAdminCmd("sm_parish", Cmd_GoParish, ADMFLAG_CHANGEMAP, "Jump to The Parish"); RegAdminCmd("sm_passing", Cmd_GoPassing, ADMFLAG_CHANGEMAP, "Jump to The Passing"); RegAdminCmd("sm_sacrifice", Cmd_GoSacrifice, ADMFLAG_CHANGEMAP, "Jump to The Sacrifice"); RegAdminCmd("sm_nm", Cmd_GoNoMercy, ADMFLAG_CHANGEMAP, "Jump to No Mercy"); RegAdminCmd("sm_cc", Cmd_GoCrashCourse, ADMFLAG_CHANGEMAP, "Jump to Crash Course"); RegAdminCmd("sm_toll", Cmd_GoDeathToll, ADMFLAG_CHANGEMAP, "Jump to Death Toll"); RegAdminCmd("sm_da", Cmd_GoDeadAir, ADMFLAG_CHANGEMAP, "Jump to Dead Air"); RegAdminCmd("sm_bh", Cmd_GoBloodHarvest, ADMFLAG_CHANGEMAP, "Jump to Blood Harvest"); RegAdminCmd("sm_cs", Cmd_GoColdStream, ADMFLAG_CHANGEMAP, "Jump to Cold Stream"); } void JumpToMap(int client, const char[] mapName, const char[] campaignName) { char cmd[128]; Format(cmd, sizeof(cmd), "changelevel %s", mapName); PrintToChatAll("\x04[Server]\x01 \x05%N\x01 is switching to \x04%s\x01...", client, campaignName); CreateTimer(2.0, Timer_Changelevel, CreateArrayFromString(cmd)); } Handle CreateArrayFromString(const char[] str) { Handle arr = CreateArray(128); PushArrayString(arr, str); return arr; } public Action Timer_Changelevel(Handle timer, Handle data) { char cmd[128]; GetArrayString(data, 0, cmd, sizeof(cmd)); CloseHandle(data); ServerCommand(cmd); return Plugin_Stop; } public Action Cmd_ListCampaigns(int client, int args) { PrintToChat(client, "\x04[Campaigns]\x01 Available shortcuts:"); PrintToChat(client, "\x04!dead\x01 - Dead Center | \x04!dc\x01 - Dark Carnival | \x04!sf\x01 - Swamp Fever"); PrintToChat(client, "\x04!hr\x01 - Hard Rain | \x04!parish\x01 - Parish | \x04!passing\x01 - Passing"); PrintToChat(client, "\x04!sacrifice\x01 - Sacrifice | \x04!nm\x01 - No Mercy | \x04!cc\x01 - Crash Course"); PrintToChat(client, "\x04!toll\x01 - Death Toll | \x04!da\x01 - Dead Air | \x04!bh\x01 - Blood Harvest"); PrintToChat(client, "\x04!cs\x01 - Cold Stream | \x04!campaigns\x01 - Show this list"); return Plugin_Handled; } public Action Cmd_GoDeadCenter(int client, int args) { JumpToMap(client, "c1m1_hotel", "Dead Center"); return Plugin_Handled; } public Action Cmd_GoDarkCarnival(int client, int args) { JumpToMap(client, "c2m1_highway", "Dark Carnival"); return Plugin_Handled; } public Action Cmd_GoSwampFever(int client, int args) { JumpToMap(client, "c3m1_plankcountry", "Swamp Fever"); return Plugin_Handled; } public Action Cmd_GoHardRain(int client, int args) { JumpToMap(client, "c4m1_milltown_a", "Hard Rain"); return Plugin_Handled; } public Action Cmd_GoParish(int client, int args) { JumpToMap(client, "c5m1_waterfront", "The Parish"); return Plugin_Handled; } public Action Cmd_GoPassing(int client, int args) { JumpToMap(client, "c6m1_riverbank", "The Passing"); return Plugin_Handled; } public Action Cmd_GoSacrifice(int client, int args) { JumpToMap(client, "c7m1_docks", "The Sacrifice"); return Plugin_Handled; } public Action Cmd_GoNoMercy(int client, int args) { JumpToMap(client, "c8m1_apartment", "No Mercy"); return Plugin_Handled; } public Action Cmd_GoCrashCourse(int client, int args) { JumpToMap(client, "c9m1_alleys", "Crash Course"); return Plugin_Handled; } public Action Cmd_GoDeathToll(int client, int args) { JumpToMap(client, "c10m1_caves", "Death Toll"); return Plugin_Handled; } public Action Cmd_GoDeadAir(int client, int args) { JumpToMap(client, "c11m1_greenhouse", "Dead Air"); return Plugin_Handled; } public Action Cmd_GoBloodHarvest(int client, int args) { JumpToMap(client, "c12m1_hilltop", "Blood Harvest"); return Plugin_Handled; } public Action Cmd_GoColdStream(int client, int args) { JumpToMap(client, "c13m1_alpinecreek", "Cold Stream"); return Plugin_Handled; }