X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fg_world.qc;h=67049e73b24261fee11aacd7e1a66791496d2bd7;hb=9315733d04c3fab6b6ad1e3f6d8c4627ffb860b6;hp=c3dc5be39f605369ca208c79ec61490d9bdda3cd;hpb=185c7b56bb0d8bbb204cbbf0696dd96c069fffc3;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index c3dc5be39..67049e73b 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -332,18 +332,26 @@ void cvar_changes_init() BADCVAR("g_buffs_randomize"); BADCVAR("g_buffs_randomize_teamplay"); BADCVAR("g_campcheck_distance"); + BADCVAR("g_chatsounds"); BADCVAR("g_ca_point_leadlimit"); BADCVAR("g_ca_point_limit"); BADCVAR("g_ctf_captimerecord_always"); BADCVAR("g_ctf_flag_glowtrails"); + BADCVAR("g_ctf_dynamiclights"); BADCVAR("g_ctf_flag_pickup_verbosename"); + BADPRESUFFIX("g_ctf_flag_", "_model"); + BADPRESUFFIX("g_ctf_flag_", "_skin"); BADCVAR("g_domination_point_leadlimit"); BADCVAR("g_forced_respawn"); BADCVAR("g_freezetag_point_leadlimit"); BADCVAR("g_freezetag_point_limit"); + BADCVAR("g_glowtrails"); BADCVAR("g_hats"); + BADCVAR("g_casings"); BADCVAR("g_invasion_point_limit"); BADCVAR("g_jump_grunt"); + BADCVAR("g_keepaway_ballcarrier_effects"); + BADCVAR("g_keepawayball_effects"); BADCVAR("g_keyhunt_point_leadlimit"); BADCVAR("g_nexball_goalleadlimit"); BADCVAR("g_new_toys_autoreplace"); @@ -357,6 +365,7 @@ void cvar_changes_init() BADCVAR("leadlimit_and_fraglimit"); BADCVAR("leadlimit_override"); BADCVAR("pausable"); + BADCVAR("sv_announcer"); BADCVAR("sv_checkforpacketsduringsleep"); BADCVAR("sv_damagetext"); BADCVAR("sv_db_saveasdump"); @@ -365,10 +374,12 @@ void cvar_changes_init() BADCVAR("sv_minigames"); BADCVAR("sv_namechangetimer"); BADCVAR("sv_precacheplayermodels"); + BADCVAR("sv_radio"); BADCVAR("sv_stepheight"); BADCVAR("sv_timeout"); BADCVAR("sv_weapons_modeloverride"); BADCVAR("w_prop_interval"); + BADPREFIX("chat_"); BADPREFIX("crypto_"); BADPREFIX("gameversion_"); BADPREFIX("g_chat_"); @@ -397,6 +408,7 @@ void cvar_changes_init() // :%s,//\([^ ]*\).*,BADCVAR("\1");, // :%!sort // yes, this does contain some redundant stuff, don't really care + BADPREFIX("bot_ai_"); BADCVAR("bot_config_file"); BADCVAR("bot_number"); BADCVAR("bot_prefix"); @@ -493,6 +505,7 @@ void cvar_changes_init() BADCVAR("g_ca_weaponarena"); BADCVAR("g_freezetag_weaponarena"); BADCVAR("g_lms_weaponarena"); + BADCVAR("g_ctf_stalemate_time"); if(cvar_string("g_mod_balance") == "Testing") { @@ -562,9 +575,6 @@ spawnfunc(__init_dedicated_server) // handler for _init/_init map (only for dedicated server initialization) world_initialized = -1; // don't complain - cvar = cvar_normal; - cvar_string = cvar_string_normal; - cvar_set = cvar_set_normal; delete_fn = remove_unsafely; @@ -674,8 +684,8 @@ spawnfunc(worldspawn) // localcmd("\nfs_rescan\n"); // FIXME: does more harm than good, has unintended side effects. What we really want is to unload temporary pk3s only // restore csqc_progname too string expect = "csprogs.dat"; - wantrestart = cvar_string_normal("csqc_progname") != expect; - cvar_set_normal("csqc_progname", expect); + wantrestart = cvar_string("csqc_progname") != expect; + cvar_set("csqc_progname", expect); } else { @@ -686,9 +696,9 @@ spawnfunc(worldspawn) // This always works; fall back to it if a versioned csprogs.dat is suddenly missing string select = "csprogs.dat"; if (fexists(pk3csprogs)) select = pk3csprogs; - if (cvar_string_normal("csqc_progname") != select) + if (cvar_string("csqc_progname") != select) { - cvar_set_normal("csqc_progname", select); + cvar_set("csqc_progname", select); wantrestart = true; } // Check for updates on startup @@ -707,13 +717,13 @@ spawnfunc(worldspawn) string newprogs = sprintf("progs-%s.dat", switchversion); if (fexists(newprogs)) { - cvar_set_normal("sv_progs", newprogs); + cvar_set("sv_progs", newprogs); wantrestart = true; } string newcsprogs = sprintf("csprogs-%s.dat", switchversion); if (fexists(newcsprogs)) { - cvar_set_normal("csqc_progname", newcsprogs); + cvar_set("csqc_progname", newcsprogs); wantrestart = true; } } @@ -727,10 +737,6 @@ spawnfunc(worldspawn) } } - cvar = cvar_normal; - cvar_string = cvar_string_normal; - cvar_set = cvar_set_normal; - if(world_already_spawned) error("world already spawned - you may have EXACTLY ONE worldspawn!"); world_already_spawned = true; @@ -811,8 +817,6 @@ spawnfunc(worldspawn) if(this.spawnflags & SPAWNFLAG_NO_WAYPOINTS_FOR_ITEMS) bot_waypoints_for_items = 0; - precache(); - WaypointSprite_Init(); GameLogInit(); // prepare everything @@ -822,7 +826,7 @@ spawnfunc(worldspawn) // character set: ASCII 33-126 without the following characters: : ; ' " \ $ if(autocvar_sv_eventlog) { - string s = sprintf("%d.%s.%06d", itos(autocvar_sv_eventlog_files_counter), strftime(false, "%s"), floor(random() * 1000000)); + string s = sprintf("%s.%s.%06d", itos(autocvar_sv_eventlog_files_counter), strftime(false, "%s"), floor(random() * 1000000)); matchid = strzone(s); GameLogEcho(strcat(":gamestart:", GetGametype(), "_", GetMapname(), ":", s)); @@ -1071,7 +1075,8 @@ bool MapHasRightSize(string map) // open map size restriction file string opensize_msg = strcat("opensize ", map); float fh = fopen(strcat("maps/", map, ".sizes"), FILE_READ); - int pcount = player_count; + int player_limit = ((autocvar_g_maplist_sizes_count_maxplayers) ? GetPlayerLimit() : 0); + int pcount = ((player_limit > 0) ? min(player_count, player_limit) : player_count); // bind it to the player limit so that forced spectators don't influence the limits if(!autocvar_g_maplist_sizes_count_bots) pcount -= currentbots; if(fh >= 0) @@ -1104,7 +1109,7 @@ string Map_Filename(float position) void Map_MarkAsRecent(string m) { - cvar_set("g_maplist_mostrecent", strwords(strcat(m, " ", autocvar_g_maplist_mostrecent), max(0, autocvar_g_maplist_mostrecent_count))); + cvar_set("g_maplist_mostrecent", strwords(cons(m, autocvar_g_maplist_mostrecent), max(0, autocvar_g_maplist_mostrecent_count))); } float Map_IsRecent(string m) @@ -1258,7 +1263,7 @@ void Maplist_Init() break; } } - + if (i == Map_Count) { bprint( "Maplist contains no usable maps! Resetting it to default map list.\n" ); @@ -1416,54 +1421,6 @@ void IntermissionThink(entity this) MapVote_Start(); } -/* -============ -FindIntermission - -Returns the entity to view from -============ -*/ -/* -entity FindIntermission() -{ - local entity spot; - local float cyc; - -// look for info_intermission first - spot = find(NULL, classname, "info_intermission"); - if (spot) - { // pick a random one - cyc = random() * 4; - while (cyc > 1) - { - spot = find(spot, classname, "info_intermission"); - if (!spot) - spot = find(spot, classname, "info_intermission"); - cyc = cyc - 1; - } - return spot; - } - -// then look for the start position - spot = find(NULL, classname, "info_player_start"); - if (spot) - return spot; - -// testinfo_player_start is only found in regioned levels - spot = find(NULL, classname, "testplayerstart"); - if (spot) - return spot; - -// then look for the start position - spot = find(NULL, classname, "info_player_deathmatch"); - if (spot) - return spot; - - //objerror ("FindIntermission: no spot"); - return NULL; -} -*/ - /* =============================================================================== @@ -1753,11 +1710,9 @@ void ShuffleMaplist() cvar_set("g_maplist", shufflewords(autocvar_g_maplist)); } -float leaderfrags; +int fragsleft_last; float WinningCondition_Scores(float limit, float leadlimit) { - float limitreached; - // TODO make everything use THIS winning condition (except LMS) WinningConditionHelper(NULL); @@ -1787,42 +1742,52 @@ float WinningCondition_Scores(float limit, float leadlimit) leadlimit = 0; // not supported in this mode if(MUTATOR_CALLHOOK(Scores_CountFragsRemaining)) - // these modes always score in increments of 1, thus this makes sense { - if(leaderfrags != WinningConditionHelper_topscore) + float fragsleft; + if (checkrules_suddendeathend && time >= checkrules_suddendeathend) { - leaderfrags = WinningConditionHelper_topscore; - + fragsleft = 1; + } + else + { + fragsleft = FLOAT_MAX; + float leadingfragsleft = FLOAT_MAX; if (limit) - { - if (leaderfrags == limit - 1) - Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_REMAINING_FRAG_1); - else if (leaderfrags == limit - 2) - Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_REMAINING_FRAG_2); - else if (leaderfrags == limit - 3) - Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_REMAINING_FRAG_3); - } + fragsleft = limit - WinningConditionHelper_topscore; + if (leadlimit) + leadingfragsleft = WinningConditionHelper_secondscore + leadlimit - WinningConditionHelper_topscore; + + if (limit && leadlimit && autocvar_leadlimit_and_fraglimit) + fragsleft = max(fragsleft, leadingfragsleft); + else + fragsleft = min(fragsleft, leadingfragsleft); } - } - limitreached = false; - if (limit && WinningConditionHelper_topscore >= limit) - limitreached = true; - if(leadlimit) - { - float leadlimitreached; - leadlimitreached = (WinningConditionHelper_topscore - WinningConditionHelper_secondscore >= leadlimit); - if(autocvar_leadlimit_and_fraglimit) - limitreached = (limitreached && leadlimitreached); - else - limitreached = (limitreached || leadlimitreached); + if (fragsleft_last != fragsleft) // do not announce same remaining frags multiple times + { + if (fragsleft == 1) + Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_REMAINING_FRAG_1); + else if (fragsleft == 2) + Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_REMAINING_FRAG_2); + else if (fragsleft == 3) + Send_Notification(NOTIF_ALL, NULL, MSG_ANNCE, ANNCE_REMAINING_FRAG_3); + + fragsleft_last = fragsleft; + } } - if(limit) - game_completion_ratio = max(game_completion_ratio, bound(0, WinningConditionHelper_topscore / limit, 1)); + bool fraglimit_reached = (limit && WinningConditionHelper_topscore >= limit); + bool leadlimit_reached = (leadlimit && WinningConditionHelper_topscore - WinningConditionHelper_secondscore >= leadlimit); + + bool limit_reached; + // only respect leadlimit_and_fraglimit when both limits are set or the game will never end + if (limit && leadlimit && autocvar_leadlimit_and_fraglimit) + limit_reached = (fraglimit_reached && leadlimit_reached); + else + limit_reached = (fraglimit_reached || leadlimit_reached); return GetWinningCode( - WinningConditionHelper_topscore && limitreached, + WinningConditionHelper_topscore && limit_reached, WinningConditionHelper_equality ); } @@ -1913,10 +1878,6 @@ Exit deathmatch games upon conditions */ void CheckRules_World() { - float timelimit; - float fraglimit; - float leadlimit; - VoteThink(); MapVote_Think(); @@ -1931,9 +1892,10 @@ void CheckRules_World() return; } - timelimit = autocvar_timelimit * 60; - fraglimit = autocvar_fraglimit; - leadlimit = autocvar_leadlimit; + float timelimit = autocvar_timelimit * 60; + float fraglimit = autocvar_fraglimit; + float leadlimit = autocvar_leadlimit; + if (leadlimit < 0) leadlimit = 0; if(warmup_stage || time <= game_starttime) // NOTE: this is <= to prevent problems in the very tic where the game starts { @@ -1958,11 +1920,6 @@ void CheckRules_World() float wantovertime; wantovertime = 0; - if(timelimit > game_starttime) - game_completion_ratio = (time - game_starttime) / (timelimit - game_starttime); - else - game_completion_ratio = 0; - if(checkrules_suddendeathend) { if(!checkrules_suddendeathwarning) @@ -2108,7 +2065,7 @@ void Physics_Frame() if(autocvar_sv_freezenonclients) return; - FOREACH_ENTITY_FLOAT(pure_data, false, + IL_EACH(g_moveables, true, { if(IS_CLIENT(it) || it.classname == "" || it.move_movetype == MOVETYPE_PUSH || it.move_movetype == MOVETYPE_FAKEPUSH || it.move_movetype == MOVETYPE_PHYSICS) continue; @@ -2134,7 +2091,7 @@ void Physics_Frame() if(autocvar_sv_gameplayfix_delayprojectiles >= 0) return; - FOREACH_ENTITY_FLOAT(move_qcphysics, true, + IL_EACH(g_moveables, it.move_qcphysics, { if(IS_CLIENT(it) || is_pure(it) || it.classname == "" || it.move_movetype == MOVETYPE_NONE) continue; @@ -2256,6 +2213,11 @@ void Shutdown() if(world_initialized > 0) { world_initialized = 0; + + // if a timeout is active, reset the slowmo value to normal + if(timeout_status == TIMEOUT_ACTIVE) + cvar_set("slowmo", ftos(orig_slowmo)); + LOG_TRACE("Saving persistent data..."); Ban_SaveBans();