From 0152cdd53b822df0da3156d71b3654ef2aa68740 Mon Sep 17 00:00:00 2001 From: Jbleezy Date: Mon, 13 Mar 2023 02:48:28 -0700 Subject: [PATCH] Encounter: add map voting --- README.md | 1 + scripts/zm/replaced/_zm.gsc | 10 +- scripts/zm/zgrief/zgrief_reimagined.gsc | 24 +- .../zm/zgrief/zgrief_reimagined_server.gsc | 568 ++++++++++++++++++ 4 files changed, 594 insertions(+), 9 deletions(-) create mode 100644 scripts/zm/zgrief/zgrief_reimagined_server.gsc diff --git a/README.md b/README.md index 1f9ae731..c3584d11 100644 --- a/README.md +++ b/README.md @@ -541,6 +541,7 @@ * Added player downed and bled out icons on scoreboard * Announcer audio always plays * Last player alive audio only plays for the player who is alive instead of every player on the team +* Added map voting on servers #### Grief * Gain score by making enemy players bleed out diff --git a/scripts/zm/replaced/_zm.gsc b/scripts/zm/replaced/_zm.gsc index 4aeee11a..d05997f4 100644 --- a/scripts/zm/replaced/_zm.gsc +++ b/scripts/zm/replaced/_zm.gsc @@ -1344,6 +1344,14 @@ end_game() players[ i ] cameraactivate( 0 ); } - exitlevel( 0 ); + if (is_true(level.map_restart)) + { + map_restart(); + } + else + { + exitlevel(0); + } + wait 666; } \ No newline at end of file diff --git a/scripts/zm/zgrief/zgrief_reimagined.gsc b/scripts/zm/zgrief/zgrief_reimagined.gsc index c6e635e0..1c7698d7 100644 --- a/scripts/zm/zgrief/zgrief_reimagined.gsc +++ b/scripts/zm/zgrief/zgrief_reimagined.gsc @@ -328,8 +328,16 @@ set_grief_vars() setDvar("ui_gametype_obj", "zgrief zsnr zrace zcontainment zmeat"); } - gamemodes = strTok(getDvar("ui_gametype_obj"), " "); - level.scr_zm_ui_gametype_obj = random(gamemodes); + if(getDvar("ui_gametype_obj_cur") != "") + { + level.scr_zm_ui_gametype_obj = getDvar("ui_gametype_obj_cur"); + } + else + { + gamemodes = strTok(getDvar("ui_gametype_obj"), " "); + level.scr_zm_ui_gametype_obj = random(gamemodes); + } + level.scr_zm_ui_gametype_pro = getDvarIntDefault("ui_gametype_pro", 0); level.noroundnumber = 1; @@ -1468,26 +1476,26 @@ grief_intro_text() self iPrintLn("Good luck!"); } -get_gamemode_display_name() +get_gamemode_display_name(gamemode = level.scr_zm_ui_gametype_obj) { name = ""; - if(level.scr_zm_ui_gametype_obj == "zgrief") + if(gamemode == "zgrief") { name = "Grief"; } - else if(level.scr_zm_ui_gametype_obj == "zsnr") + else if(gamemode == "zsnr") { name = "Search & Rezurrect"; } - else if(level.scr_zm_ui_gametype_obj == "zrace") + else if(gamemode == "zrace") { name = "Race"; } - else if(level.scr_zm_ui_gametype_obj == "zcontainment") + else if(gamemode == "zcontainment") { name = "Containment"; } - else if(level.scr_zm_ui_gametype_obj == "zmeat") + else if(gamemode == "zmeat") { name = "Meat"; } diff --git a/scripts/zm/zgrief/zgrief_reimagined_server.gsc b/scripts/zm/zgrief/zgrief_reimagined_server.gsc new file mode 100644 index 00000000..5bd5ad9d --- /dev/null +++ b/scripts/zm/zgrief/zgrief_reimagined_server.gsc @@ -0,0 +1,568 @@ +#include maps\mp\_utility; +#include common_scripts\utility; +#include maps\mp\zombies\_zm_utility; +#include maps\mp\gametypes_zm\_hud_util; +#include maps\mp\gametypes_zm\_hud_message; + +main() +{ + if (getDvar("g_gametype") != "zgrief") + { + return; + } + + if (!isDedicated()) + { + return; + } +} + +init() +{ + if (getDvar("g_gametype") != "zgrief") + { + return; + } + + if (!isDedicated()) + { + return; + } + + precache_map_strings(); + precache_map_images(); + precacheshader("menu_zm_popup"); + + level thread connect_timeout_changes(); + level thread random_map_rotation(); + level thread map_vote(); +} + +precache_map_strings() +{ + precachestring(&"ZMUI_TRANSIT_STARTLOC"); + precachestring(&"ZMUI_FARM"); + precachestring(&"ZMUI_TOWN"); + precachestring(&"ZMUI_DINER"); + precachestring(&"ZMUI_TUNNEL"); + precachestring(&"ZMUI_POWER"); + precachestring(&"ZMUI_CELLBLOCK"); + precachestring(&"ZMUI_STREET_LOC"); +} + +precache_map_images() +{ + preCacheShader("loadscreen_zm_transit_zgrief_transit"); + preCacheShader("loadscreen_zm_transit_zgrief_farm"); + preCacheShader("loadscreen_zm_transit_zgrief_town"); + preCacheShader("loadscreen_zm_transit_zgrief_power"); + preCacheShader("loadscreen_zm_transit_zgrief_tunnel"); + preCacheShader("loadscreen_zm_transit_dr_zcleansed_diner"); + preCacheShader("loadscreen_zm_prison_zgrief_cellblock"); + preCacheShader("loadscreen_zm_buried_zgrief_street"); +} + +connect_timeout_changes() +{ + setDvar("sv_connectTimeout", 30); + + flag_wait("initial_players_connected"); + + setDvar("sv_connectTimeout", 60); +} + +random_map_rotation() +{ + initial_map = 0; + if(getDvar("sv_mapRotationRandom") == "") + { + initial_map = 1; + setDvar("sv_mapRotationRandom", 1); + } + + if(!initial_map && getDvar("sv_mapRotationCurrent") != "") + { + return; + } + + rotation_string = getDvar("sv_mapRotation"); + rotation_array = rotation_string_to_array(rotation_string); + + if(rotation_array.size < 2) + { + return; + } + + // randomize maps + rotation_array = array_randomize(rotation_array); + + // make sure current map isn't first + // except for initially since map hasn't been played + if(!initial_map) + { + location = get_location_from_rotation(rotation_array[0]); + mapname = get_mapname_from_rotation(rotation_array[0]); + + if(level.scr_zm_map_start_location == location && level.script == mapname) + { + num = randomIntRange(1, rotation_array.size); + rotation_array = array_swap(rotation_array, 0, num); + } + } + + rotation_string = rotation_array_to_string(rotation_array); + + setDvar("sv_mapRotation", rotation_string); + setDvar("sv_mapRotationCurrent", rotation_string); + + // make initial map random + if(initial_map) + { + exitLevel(0); + } +} + +rotation_string_to_array(rotation_string) +{ + rotation_array = []; + + tokens = strTok(rotation_string, " "); + for(i = 0; i < tokens.size; i += 4) + { + rotation_array[rotation_array.size] = tokens[i] + " " + tokens[i+1] + " " + tokens[i+2] + " " + tokens[i+3]; + } + + return rotation_array; +} + +rotation_array_to_string(rotation_array) +{ + rotation_string = ""; + + for(i = 0; i < rotation_array.size; i++) + { + rotation_string += rotation_array[i]; + + if(i < (rotation_array.size - 1)) + { + rotation_string += " "; + } + } + + return rotation_string; +} + +get_location_from_rotation(rotation) +{ + tokens = strTok(rotation, " "); + + location = tokens[1]; // zm_gamemode_location.cfg + location = strTok(location, "."); + location = location[0]; // zm_gamemode_location + location = strTok(location, "_"); + location = location[2]; // location + + return location; +} + +get_mapname_from_rotation(rotation) +{ + tokens = strTok(rotation, " "); + + mapname = tokens[3]; + + return mapname; +} + +map_vote() +{ + level waittill("intermission"); + + maps = []; + exclude_locs = []; + rotation_string = getDvar("sv_mapRotation"); + rotation_array = rotation_string_to_array(rotation_string); + rotation_array = array_randomize(rotation_array); + + for (i = 0; i < 3; i++) + { + maps[i] = []; + } + + maps[1]["rotation_string"] = "exec zm_grief_" + level.scr_zm_map_start_location + ".cfg map " + level.script; + maps[1]["map_name"] = level.script; + maps[1]["loc_name"] = level.scr_zm_map_start_location; + maps[1]["gametype_name"] = level.scr_zm_ui_gametype_obj; + exclude_locs[exclude_locs.size] = maps[1]["loc_name"]; + + rotation = undefined; + foreach (rotation in rotation_array) + { + if (!isInArray(exclude_locs, get_location_from_rotation(rotation))) + { + break; + } + } + + maps[0]["rotation_string"] = rotation; + maps[0]["map_name"] = get_mapname_from_rotation(rotation); + maps[0]["loc_name"] = get_location_from_rotation(rotation); + maps[0]["gametype_name"] = random(strTok(getDvar("ui_gametype_obj"), " ")); + exclude_locs[exclude_locs.size] = maps[0]["loc_name"]; + + rotation = undefined; + foreach (rotation in rotation_array) + { + if (!isInArray(exclude_locs, get_location_from_rotation(rotation))) + { + break; + } + } + + maps[2]["rotation_string"] = rotation; + maps[2]["map_name"] = get_mapname_from_rotation(rotation); + maps[2]["loc_name"] = get_location_from_rotation(rotation); + maps[2]["gametype_name"] = random(strTok(getDvar("ui_gametype_obj"), " ")); + + image_hud = []; + image_hud[0] = create_map_image_hud(get_image_for_loc(maps[0]["map_name"], maps[0]["loc_name"]), -200, 170); + image_hud[1] = create_map_image_hud(get_image_for_loc(maps[1]["map_name"], maps[1]["loc_name"]), 0, 170); + image_hud[2] = create_map_image_hud(get_image_for_loc(maps[2]["map_name"], maps[2]["loc_name"]), 200, 170); + + name_hud = []; + name_hud[0] = create_map_name_hud(get_name_for_loc(maps[0]["loc_name"]), -200, 170); + name_hud[1] = create_map_name_hud(get_name_for_loc(maps[1]["loc_name"]), 0, 170); + name_hud[2] = create_map_name_hud(get_name_for_loc(maps[2]["loc_name"]), 200, 170); + + gametype_hud = []; + gametype_hud[0] = create_map_gametype_hud(scripts\zm\zgrief\zgrief_reimagined::get_gamemode_display_name(maps[0]["gametype_name"]), -200, 187.5); + gametype_hud[1] = create_map_gametype_hud(scripts\zm\zgrief\zgrief_reimagined::get_gamemode_display_name(maps[1]["gametype_name"]), 0, 187.5); + gametype_hud[2] = create_map_gametype_hud(scripts\zm\zgrief\zgrief_reimagined::get_gamemode_display_name(maps[2]["gametype_name"]), 200, 187.5); + + level.map_votes = []; + level.map_votes[0] = 0; + level.map_votes[1] = 0; + level.map_votes[2] = 0; + + level.vote_hud = []; + level.vote_hud[0] = create_map_vote_hud(-200, 205); + level.vote_hud[1] = create_map_vote_hud(0, 205); + level.vote_hud[2] = create_map_vote_hud(200, 205); + + array_thread( get_players(), ::player_choose_map ); + + level waittill("stop_intermission"); + + map_won_ind = get_map_winner(); + + for (i = 0; i < 3; i++) + { + if (i != map_won_ind) + { + image_hud[i].alpha = 0; + name_hud[i].alpha = 0; + gametype_hud[i].alpha = 0; + level.vote_hud[i].alpha = 0; + } + } + + if (map_won_ind != 1) + { + image_hud[map_won_ind] moveOverTime(0.5); + name_hud[map_won_ind] moveOverTime(0.5); + gametype_hud[map_won_ind] moveOverTime(0.5); + level.vote_hud[map_won_ind] moveOverTime(0.5); + + image_hud[map_won_ind].x = 0; + name_hud[map_won_ind].x = 0; + gametype_hud[map_won_ind].x = 0; + level.vote_hud[map_won_ind].x = 0; + } + + if (map_won_ind == 1) + { + level.map_restart = 1; + } + else + { + makeDvarServerInfo("ui_zm_mapstartlocation", maps[map_won_ind]["loc_name"]); + setDvar("ui_zm_mapstartlocation", maps[map_won_ind]["loc_name"]); + + setDvar("ui_gametype_obj_cur", maps[map_won_ind]["gametype_name"]); + + // can only map_restart() from and to added Tranzit maps, others get client field mismatch + added_maps = array("diner", "power", "tunnel", "cornfield"); + + if (isInArray(added_maps, maps[map_won_ind]["loc_name"]) && isInArray(added_maps, level.scr_zm_map_start_location)) + { + level.map_restart = 1; + } + else + { + setDvar("sv_mapRotationCurrent", maps[map_won_ind]["rotation_string"]); + } + } +} + +create_map_image_hud(image, x, y) +{ + hud = newHudElem(); + hud.x = x; + hud.y = y; + hud.horzalign = "center"; + hud.vertalign = "middle"; + hud.alignx = "center"; + hud.aligny = "middle"; + hud.sort = -1; + hud.alpha = 1; + hud setshader(image, 175, 100); + + return hud; +} + +create_map_name_hud(name, x, y) +{ + hud = newHudElem(); + hud.x = x; + hud.y = y; + hud.font = "objective"; + hud.fontscale = 1.8; + hud.horzalign = "center"; + hud.vertalign = "middle"; + hud.alignx = "center"; + hud.aligny = "middle"; + hud.alpha = 1; + hud setText(name); + + return hud; +} + +create_map_gametype_hud(name, x, y) +{ + hud = newHudElem(); + hud.x = x; + hud.y = y; + hud.font = "objective"; + hud.fontscale = 1.5; + hud.horzalign = "center"; + hud.vertalign = "middle"; + hud.alignx = "center"; + hud.aligny = "middle"; + hud.alpha = 1; + hud setText(name); + + return hud; +} + +create_map_vote_hud(x, y) +{ + hud = newHudElem(); + hud.x = x; + hud.y = y; + hud.font = "objective"; + hud.fontscale = 1.2; + hud.horzalign = "center"; + hud.vertalign = "middle"; + hud.alignx = "center"; + hud.aligny = "middle"; + hud.alpha = 1; + hud setValue(0); + + return hud; +} + +create_map_select_hud(x, y) +{ + hud = newClientHudElem(self); + hud.x = x; + hud.y = y + 2.5; + hud.horzalign = "center"; + hud.vertalign = "middle"; + hud.alignx = "center"; + hud.aligny = "middle"; + hud.alpha = 1; + hud setshader("menu_zm_popup", 175, 110); + + return hud; +} + +player_choose_map() +{ + self endon("disconnect"); + + wait 0.1; + + self.sessionstate = "playing"; // must change sessionstate or hud elems don't show + self setOrigin((0, 0, -10000)); + self.map_select_hud = self create_map_select_hud(0, 170); + self.map_select_ind = 1; + self.map_selected = 0; + + self notifyonplayercommand("left", "+speed_throw"); + self notifyonplayercommand("left", "+moveleft"); + self notifyonplayercommand("right", "+attack"); + self notifyonplayercommand("right", "+moveright"); + self notifyonplayercommand("select", "+usereload"); + self notifyonplayercommand("select", "+activate"); + self notifyonplayercommand("select", "+gostand"); + + self thread left_watcher(); + self thread right_watcher(); + self thread select_watcher(); + + level waittill( "stop_intermission" ); + + self.map_select_hud destroy(); +} + +left_watcher() +{ + level endon( "stop_intermission" ); + self endon("disconnect"); + + while(1) + { + self waittill("left"); + + if (self.map_selected) + { + continue; + } + + if (self.map_select_ind == 0) + { + self.map_select_ind = 2; + self.map_select_hud.x += 400; + continue; + } + + self.map_select_ind--; + self.map_select_hud.x -= 200; + } +} + +right_watcher() +{ + level endon( "stop_intermission" ); + self endon("disconnect"); + + while(1) + { + self waittill("right"); + + if (self.map_selected) + { + continue; + } + + if (self.map_select_ind == 2) + { + self.map_select_ind = 0; + self.map_select_hud.x -= 400; + continue; + } + + self.map_select_ind++; + self.map_select_hud.x += 200; + } +} + +select_watcher() +{ + level endon( "stop_intermission" ); + self endon("disconnect"); + + while(1) + { + self waittill("select"); + + if (!self.map_selected) + { + self.map_selected = 1; + self.map_select_hud.color = (0, 1, 0); + + level.map_votes[self.map_select_ind]++; + level.vote_hud[self.map_select_ind] setValue(level.map_votes[self.map_select_ind]); + } + else + { + self.map_selected = 0; + self.map_select_hud.color = (1, 1, 1); + + level.map_votes[self.map_select_ind]--; + level.vote_hud[self.map_select_ind] setValue(level.map_votes[self.map_select_ind]); + } + } +} + +get_map_winner() +{ + winner_ind = array(0); + + for (i = 1; i < 3; i++) + { + if (level.map_votes[i] == level.map_votes[winner_ind[0]]) + { + winner_ind[winner_ind.size] = i; + } + else if(level.map_votes[i] > level.map_votes[winner_ind[0]]) + { + winner_ind = array(i); + } + } + + if (winner_ind.size > 1 && isInArray(winner_ind, 1)) + { + arrayRemoveValue(winner_ind, 1); + } + + return random(winner_ind); +} + +get_name_for_loc(locname) +{ + if (locname == "transit") + { + return &"ZMUI_TRANSIT_STARTLOC"; + } + else if (locname == "farm") + { + return &"ZMUI_FARM"; + } + else if (locname == "town") + { + return &"ZMUI_TOWN"; + } + else if (locname == "diner") + { + return &"ZMUI_DINER"; + } + else if (locname == "power") + { + return "Power Station"; + } + else if (locname == "tunnel") + { + return &"ZMUI_TUNNEL"; + } + else if (locname == "cellblock") + { + return &"ZMUI_CELLBLOCK"; + } + else if (locname == "street") + { + return &"ZMUI_STREET_LOC"; + } + + return ""; +} + +get_image_for_loc(mapname, locname) +{ + if (locname == "diner") + { + return "loadscreen_zm_transit_dr_zcleansed_diner"; + } + + return "loadscreen_" + mapname + "_zgrief_" + locname; +} \ No newline at end of file