X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fg_world.qc;h=f97a4254dff37f194d242f65119cfe6f55e624b8;hp=b7c970715fe7e2e175d651bd98fc3b176911a5f6;hb=dc25d591f448c6ed191fcf9452d65b87d7a26e90;hpb=b2bebff5bd5d111bb469de032d9b878d95f3c033 diff --git a/qcsrc/server/g_world.qc b/qcsrc/server/g_world.qc index b7c970715f..f97a4254df 100644 --- a/qcsrc/server/g_world.qc +++ b/qcsrc/server/g_world.qc @@ -55,7 +55,6 @@ const float SPAWNFLAG_NO_WAYPOINTS_FOR_ITEMS = 1; string redirection_target; float world_initialized; -string GetMapname(); string GetGametype(); void GotoNextMap(float reinit); void ShuffleMaplist(); @@ -82,32 +81,6 @@ void SetDefaultAlpha() } } -void fteqcc_testbugs() -{ - float a, b; - - if(!autocvar_developer_fteqccbugs) - return; - - dprint("*** fteqcc test: checking for bugs...\n"); - - a = 1; - b = 5; - if(sqrt(a) - sqrt(b - a) == 0) - dprint("*** fteqcc test: found same-function-twice bug\n"); - else - dprint("*** fteqcc test: same-function-twice bug got FINALLY FIXED! HOORAY!\n"); - - world.cnt = -10; - world.enemy = world; - world.enemy.cnt += 10; - if(world.cnt > 0.2 || world.cnt < -0.2) // don't error out if it's just roundoff errors - dprint("*** fteqcc test: found += bug\n"); - else - dprint("*** fteqcc test: += bug got FINALLY FIXED! HOORAY!\n"); - world.cnt = 0; -} - void GotoFirstMap() { float n; @@ -216,7 +189,6 @@ void cvar_changes_init() // private BADCVAR("developer"); BADCVAR("log_dest_udp"); - BADCVAR("log_file"); BADCVAR("net_address"); BADCVAR("net_address_ipv6"); BADCVAR("port"); @@ -237,6 +209,7 @@ void cvar_changes_init() BADPREFIX("g_playerstats_"); BADPREFIX("g_respawn_ghosts"); BADPREFIX("g_voice_flood_"); + BADPREFIX("log_file"); BADPREFIX("rcon_"); BADPREFIX("sv_allowdownloads"); BADPREFIX("sv_autodemo"); @@ -421,7 +394,7 @@ void cvar_changes_init() BADPREFIX("sv_ready_restart_"); // mutators that announce themselves properly to the server browser - BADCVAR("g_minstagib"); + BADCVAR("g_instagib"); BADCVAR("g_new_toys"); BADCVAR("g_nix"); BADCVAR("g_grappling_hook"); @@ -546,6 +519,7 @@ void spawnfunc___init_dedicated_server(void) CALL_ACCUMULATED_FUNCTION(RegisterGametypes); CALL_ACCUMULATED_FUNCTION(RegisterNotifications); CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes); + CALL_ACCUMULATED_FUNCTION(RegisterBuffs); MapInfo_Enumerate(); MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0); @@ -572,8 +546,6 @@ void spawnfunc_worldspawn (void) remove = remove_safely; // during spawning, watch what you remove! - check_unacceptable_compiler_bugs(); - cvar_changes_init(); // do this very early now so it REALLY matches the server config compressShortVector_init(); @@ -595,6 +567,7 @@ void spawnfunc_worldspawn (void) CALL_ACCUMULATED_FUNCTION(RegisterGametypes); CALL_ACCUMULATED_FUNCTION(RegisterNotifications); CALL_ACCUMULATED_FUNCTION(RegisterDeathtypes); + CALL_ACCUMULATED_FUNCTION(RegisterBuffs); ServerProgsDB = db_load(strcat("server.db", autocvar_sessionid)); @@ -646,7 +619,7 @@ void spawnfunc_worldspawn (void) Map_MarkAsRecent(mapname); - PlayerStats_Init(); // we need this to be initiated before InitGameplayMode + PlayerStats_GameReport_Init(); // we need this to be initiated before InitGameplayMode precache_model ("null"); // we need this one before InitGameplayMode InitGameplayMode(); @@ -721,8 +694,6 @@ void spawnfunc_worldspawn (void) if(autocvar_g_campaign) CampaignPostInit(); - fteqcc_testbugs(); - Ban_LoadBans(); MapInfo_Enumerate(); @@ -770,7 +741,7 @@ void spawnfunc_worldspawn (void) addstat(STAT_SWITCHINGWEAPON, AS_INT, switchingweapon); addstat(STAT_GAMESTARTTIME, AS_FLOAT, stat_game_starttime); addstat(STAT_ROUNDSTARTTIME, AS_FLOAT, stat_round_starttime); - addstat(STAT_ALLOW_OLDNEXBEAM, AS_INT, stat_allow_oldnexbeam); + addstat(STAT_ALLOW_OLDVORTEXBEAM, AS_INT, stat_allow_oldvortexbeam); Nagger_Init(); addstat(STAT_STRENGTH_FINISHED, AS_FLOAT, strength_finished); @@ -784,7 +755,7 @@ void spawnfunc_worldspawn (void) addstat(STAT_WEAPON_CLIPLOAD, AS_INT, clip_load); addstat(STAT_WEAPON_CLIPSIZE, AS_INT, clip_size); addstat(STAT_LAST_PICKUP, AS_FLOAT, last_pickup); - addstat(STAT_HIT_TIME, AS_FLOAT, hit_time); + addstat(STAT_DAMAGE_DEALT_TOTAL, AS_INT, damage_dealt_total); addstat(STAT_TYPEHIT_TIME, AS_FLOAT, typehit_time); addstat(STAT_LAYED_MINES, AS_INT, minelayer_mines); @@ -792,6 +763,12 @@ void spawnfunc_worldspawn (void) addstat(STAT_VORTEX_CHARGEPOOL, AS_FLOAT, vortex_chargepool_ammo); addstat(STAT_HAGAR_LOAD, AS_INT, hagar_load); + + addstat(STAT_ARC_HEAT, AS_FLOAT, arc_heat_percent); + + // freeze attacks + addstat(STAT_FROZEN, AS_INT, frozen); + addstat(STAT_REVIVE_PROGRESS, AS_FLOAT, revive_progress); // g_movementspeed hack addstat(STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW, AS_FLOAT, stat_sv_airspeedlimit_nonqw); @@ -895,7 +872,6 @@ string GetGametype() return MapInfo_Type_ToString(MapInfo_LoadedGametype); } -string getmapname_stored; string GetMapname() { return mapname; @@ -1220,13 +1196,27 @@ float DoNextMapOverride(float reinit) return TRUE; } if(autocvar_nextmap != "") - if(MapInfo_CheckMap(autocvar_nextmap)) + { + string m; + m = GameTypeVote_MapInfo_FixName(autocvar_nextmap); + cvar_set("nextmap",m); + + if(!m || gametypevote) + return FALSE; + if(autocvar_sv_vote_gametype) { - Map_Goto_SetStr(autocvar_nextmap); + Map_Goto_SetStr(m); + return FALSE; + } + + if(MapInfo_CheckMap(m)) + { + Map_Goto_SetStr(m); Map_Goto(reinit); alreadychangedlevel = TRUE; return TRUE; } + } if(!reinit && autocvar_lastlevel) { cvar_settemp_restore(); @@ -1263,9 +1253,6 @@ When the player presses attack or jump, change to the next level ============ */ .float autoscreenshot; -void() MapVote_Start; -void() MapVote_Think; -float mapvote_initialized; void IntermissionThink() { FixIntermissionClient(self); @@ -1512,11 +1499,7 @@ void NextLevel() DumpStats(TRUE); // send statistics - entity e; - PlayerStats_EndMatch(1); - FOR_EACH_CLIENT(e) - PlayerStats_AddGlobalInfo(e); - PlayerStats_Shutdown(); + PlayerStats_GameReport(TRUE); WeaponStats_Shutdown(); Kill_Notification(NOTIF_ALL, world, MSG_CENTER, 0); // kill all centerprints now @@ -2030,17 +2013,6 @@ void CheckRules_World() SetDefaultAlpha(); - /* - MapVote_Think should now do that part - if (intermission_running) - if (time >= intermission_exittime + 60) - { - if(!DoNextMapOverride()) - GotoNextMap(); - return; - } - */ - if (gameover) // someone else quit the game already { if(player_count == 0) // Nobody there? Then let's go to the next map @@ -2202,517 +2174,14 @@ void CheckRules_World() } } -float mapvote_nextthink; -float mapvote_initialized; -float mapvote_keeptwotime; -float mapvote_timeout; -string mapvote_message; -#define MAPVOTE_SCREENSHOT_DIRS_COUNT 4 -string mapvote_screenshot_dirs[MAPVOTE_SCREENSHOT_DIRS_COUNT]; -float mapvote_screenshot_dirs_count; - -float mapvote_count; -float mapvote_count_real; -string mapvote_maps[MAPVOTE_COUNT]; -float mapvote_maps_screenshot_dir[MAPVOTE_COUNT]; -string mapvote_maps_pakfile[MAPVOTE_COUNT]; -float mapvote_maps_suggested[MAPVOTE_COUNT]; -string mapvote_suggestions[MAPVOTE_COUNT]; -float mapvote_suggestion_ptr; -float mapvote_voters; -float mapvote_selections[MAPVOTE_COUNT]; -float mapvote_run; -float mapvote_detail; -float mapvote_abstain; -.float mapvote; - -void MapVote_ClearAllVotes() -{ - FOR_EACH_CLIENT(other) - other.mapvote = 0; -} - -string MapVote_Suggest(string m) +string GotoMap(string m) { - float i; - if(m == "") - return "That's not how to use this command."; - if(!autocvar_g_maplist_votable_suggestions) - return "Suggestions are not accepted on this server."; - if(mapvote_initialized) - return "Can't suggest - voting is already in progress!"; - m = MapInfo_FixName(m); + m = GameTypeVote_MapInfo_FixName(m); if (!m) return "The map you suggested is not available on this server."; - if(!autocvar_g_maplist_votable_suggestions_override_mostrecent) - if(Map_IsRecent(m)) - return "This server does not allow for recent maps to be played again. Please be patient for some rounds."; - + if (!autocvar_sv_vote_gametype) if(!MapInfo_CheckMap(m)) return "The map you suggested does not support the current game mode."; - for(i = 0; i < mapvote_suggestion_ptr; ++i) - if(mapvote_suggestions[i] == m) - return "This map was already suggested."; - if(mapvote_suggestion_ptr >= MAPVOTE_COUNT) - { - i = floor(random() * mapvote_suggestion_ptr); - } - else - { - i = mapvote_suggestion_ptr; - mapvote_suggestion_ptr += 1; - } - if(mapvote_suggestions[i] != "") - strunzone(mapvote_suggestions[i]); - mapvote_suggestions[i] = strzone(m); - if(autocvar_sv_eventlog) - GameLogEcho(strcat(":vote:suggested:", m, ":", ftos(self.playerid))); - return strcat("Suggestion of ", m, " accepted."); -} - -void MapVote_AddVotable(string nextMap, float isSuggestion) -{ - float j, i, o; - string pakfile, mapfile; - - if(nextMap == "") - return; - for(j = 0; j < mapvote_count; ++j) - if(mapvote_maps[j] == nextMap) - return; - // suggestions might be no longer valid/allowed after gametype switch! - if(isSuggestion) - if(!MapInfo_CheckMap(nextMap)) - return; - mapvote_maps[mapvote_count] = strzone(nextMap); - mapvote_maps_suggested[mapvote_count] = isSuggestion; - - pakfile = string_null; - for(i = 0; i < mapvote_screenshot_dirs_count; ++i) - { - mapfile = strcat(mapvote_screenshot_dirs[i], "/", mapvote_maps[i]); - pakfile = whichpack(strcat(mapfile, ".tga")); - if(pakfile == "") - pakfile = whichpack(strcat(mapfile, ".jpg")); - if(pakfile == "") - pakfile = whichpack(strcat(mapfile, ".png")); - if(pakfile != "") - break; - } - if(i >= mapvote_screenshot_dirs_count) - i = 0; // FIXME maybe network this error case, as that means there is no mapshot on the server? - for(o = strstr(pakfile, "/", 0)+1; o > 0; o = strstr(pakfile, "/", 0)+1) - pakfile = substring(pakfile, o, -1); - - mapvote_maps_screenshot_dir[mapvote_count] = i; - mapvote_maps_pakfile[mapvote_count] = strzone(pakfile); - - mapvote_count += 1; -} - -void MapVote_Spawn(); -void MapVote_Init() -{ - float i; - float nmax, smax; - - MapVote_ClearAllVotes(); - - mapvote_count = 0; - mapvote_detail = !autocvar_g_maplist_votable_nodetail; - mapvote_abstain = autocvar_g_maplist_votable_abstain; - - if(mapvote_abstain) - nmax = min(MAPVOTE_COUNT - 1, autocvar_g_maplist_votable); - else - nmax = min(MAPVOTE_COUNT, autocvar_g_maplist_votable); - smax = min3(nmax, autocvar_g_maplist_votable_suggestions, mapvote_suggestion_ptr); - - // we need this for AddVotable, as that cycles through the screenshot dirs - mapvote_screenshot_dirs_count = tokenize_console(autocvar_g_maplist_votable_screenshot_dir); - if(mapvote_screenshot_dirs_count == 0) - mapvote_screenshot_dirs_count = tokenize_console("maps levelshots"); - mapvote_screenshot_dirs_count = min(mapvote_screenshot_dirs_count, MAPVOTE_SCREENSHOT_DIRS_COUNT); - for(i = 0; i < mapvote_screenshot_dirs_count; ++i) - mapvote_screenshot_dirs[i] = strzone(argv(i)); - - if(mapvote_suggestion_ptr) - for(i = 0; i < 100 && mapvote_count < smax; ++i) - MapVote_AddVotable(mapvote_suggestions[floor(random() * mapvote_suggestion_ptr)], TRUE); - - for(i = 0; i < 100 && mapvote_count < nmax; ++i) - MapVote_AddVotable(GetNextMap(), FALSE); - - if(mapvote_count == 0) - { - bprint( "Maplist contains no single playable map! Resetting it to default map list.\n" ); - cvar_set("g_maplist", MapInfo_ListAllAllowedMaps(MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags())); - if(autocvar_g_maplist_shuffle) - ShuffleMaplist(); - localcmd("\nmenu_cmd sync\n"); - for(i = 0; i < 100 && mapvote_count < nmax; ++i) - MapVote_AddVotable(GetNextMap(), FALSE); - } - - mapvote_count_real = mapvote_count; - if(mapvote_abstain) - MapVote_AddVotable("don't care", 0); - - //dprint("mapvote count is ", ftos(mapvote_count), "\n"); - - mapvote_keeptwotime = time + autocvar_g_maplist_votable_keeptwotime; - mapvote_timeout = time + autocvar_g_maplist_votable_timeout; - if(mapvote_count_real < 3 || mapvote_keeptwotime <= time) - mapvote_keeptwotime = 0; - mapvote_message = "Choose a map and press its key!"; - - MapVote_Spawn(); -} - -void MapVote_SendPicture(float id) -{ - msg_entity = self; - WriteByte(MSG_ONE, SVC_TEMPENTITY); - WriteByte(MSG_ONE, TE_CSQC_PICTURE); - WriteByte(MSG_ONE, id); - WritePicture(MSG_ONE, strcat(mapvote_screenshot_dirs[mapvote_maps_screenshot_dir[id]], "/", mapvote_maps[id]), 3072); -} - -float MapVote_GetMapMask() -{ - float mask, i, power; - mask = 0; - for(i = 0, power = 1; i < mapvote_count; ++i, power *= 2) - if(mapvote_maps[i] != "") - mask |= power; - return mask; -} - -entity mapvote_ent; -float MapVote_SendEntity(entity to, float sf) -{ - float i; - - if(sf & 1) - sf &= ~2; // if we send 1, we don't need to also send 2 - - WriteByte(MSG_ENTITY, ENT_CLIENT_MAPVOTE); - WriteByte(MSG_ENTITY, sf); - - if(sf & 1) - { - // flag 1 == initialization - for(i = 0; i < mapvote_screenshot_dirs_count; ++i) - WriteString(MSG_ENTITY, mapvote_screenshot_dirs[i]); - WriteString(MSG_ENTITY, ""); - WriteByte(MSG_ENTITY, mapvote_count); - WriteByte(MSG_ENTITY, mapvote_abstain); - WriteByte(MSG_ENTITY, mapvote_detail); - WriteCoord(MSG_ENTITY, mapvote_timeout); - if(mapvote_count <= 8) - WriteByte(MSG_ENTITY, MapVote_GetMapMask()); - else - WriteShort(MSG_ENTITY, MapVote_GetMapMask()); - for(i = 0; i < mapvote_count; ++i) - if(mapvote_maps[i] != "") - { - if(mapvote_abstain && i == mapvote_count - 1) - { - WriteString(MSG_ENTITY, ""); // abstain needs no text - WriteString(MSG_ENTITY, ""); // abstain needs no pack - WriteByte(MSG_ENTITY, 0); // abstain needs no screenshot dir - } - else - { - WriteString(MSG_ENTITY, mapvote_maps[i]); - WriteString(MSG_ENTITY, mapvote_maps_pakfile[i]); - WriteByte(MSG_ENTITY, mapvote_maps_screenshot_dir[i]); - } - } - } - - if(sf & 2) - { - // flag 2 == update of mask - if(mapvote_count <= 8) - WriteByte(MSG_ENTITY, MapVote_GetMapMask()); - else - WriteShort(MSG_ENTITY, MapVote_GetMapMask()); - } - - if(sf & 4) - { - if(mapvote_detail) - for(i = 0; i < mapvote_count; ++i) - if(mapvote_maps[i] != "") - WriteByte(MSG_ENTITY, mapvote_selections[i]); - - WriteByte(MSG_ENTITY, to.mapvote); - } - - return TRUE; -} - -void MapVote_Spawn() -{ - Net_LinkEntity(mapvote_ent = spawn(), FALSE, 0, MapVote_SendEntity); -} - -void MapVote_TouchMask() -{ - mapvote_ent.SendFlags |= 2; -} - -void MapVote_TouchVotes(entity voter) -{ - mapvote_ent.SendFlags |= 4; -} - -float MapVote_Finished(float mappos) -{ - string result; - float i; - float didntvote; - - if(autocvar_sv_eventlog) - { - result = strcat(":vote:finished:", mapvote_maps[mappos]); - result = strcat(result, ":", ftos(mapvote_selections[mappos]), "::"); - didntvote = mapvote_voters; - for(i = 0; i < mapvote_count; ++i) - if(mapvote_maps[i] != "") - { - didntvote -= mapvote_selections[i]; - if(i != mappos) - { - result = strcat(result, ":", mapvote_maps[i]); - result = strcat(result, ":", ftos(mapvote_selections[i])); - } - } - result = strcat(result, ":didn't vote:", ftos(didntvote)); - - GameLogEcho(result); - if(mapvote_maps_suggested[mappos]) - GameLogEcho(strcat(":vote:suggestion_accepted:", mapvote_maps[mappos])); - } - - FOR_EACH_REALCLIENT(other) - FixClientCvars(other); - - Map_Goto_SetStr(mapvote_maps[mappos]); - Map_Goto(0); - alreadychangedlevel = TRUE; - return TRUE; -} -void MapVote_CheckRules_1() -{ - float i; - - for(i = 0; i < mapvote_count; ++i) if(mapvote_maps[i] != "") - { - //dprint("Map ", ftos(i), ": "); dprint(mapvote_maps[i], "\n"); - mapvote_selections[i] = 0; - } - - mapvote_voters = 0; - FOR_EACH_REALCLIENT(other) - { - ++mapvote_voters; - if(other.mapvote) - { - i = other.mapvote - 1; - //dprint("Player ", other.netname, " vote = ", ftos(other.mapvote - 1), "\n"); - mapvote_selections[i] = mapvote_selections[i] + 1; - } - } -} - -float MapVote_CheckRules_2() -{ - float i; - float firstPlace, secondPlace; - float firstPlaceVotes, secondPlaceVotes; - float mapvote_voters_real; - string result; - - if(mapvote_count_real == 1) - return MapVote_Finished(0); - - mapvote_voters_real = mapvote_voters; - if(mapvote_abstain) - mapvote_voters_real -= mapvote_selections[mapvote_count - 1]; - - RandomSelection_Init(); - for(i = 0; i < mapvote_count_real; ++i) if(mapvote_maps[i] != "") - RandomSelection_Add(world, i, string_null, 1, mapvote_selections[i]); - firstPlace = RandomSelection_chosen_float; - firstPlaceVotes = RandomSelection_best_priority; - //dprint("First place: ", ftos(firstPlace), "\n"); - //dprint("First place votes: ", ftos(firstPlaceVotes), "\n"); - - RandomSelection_Init(); - for(i = 0; i < mapvote_count_real; ++i) if(mapvote_maps[i] != "") - if(i != firstPlace) - RandomSelection_Add(world, i, string_null, 1, mapvote_selections[i]); - secondPlace = RandomSelection_chosen_float; - secondPlaceVotes = RandomSelection_best_priority; - //dprint("Second place: ", ftos(secondPlace), "\n"); - //dprint("Second place votes: ", ftos(secondPlaceVotes), "\n"); - - if(firstPlace == -1) - error("No first place in map vote... WTF?"); - - if(secondPlace == -1 || time > mapvote_timeout || (mapvote_voters_real - firstPlaceVotes) < firstPlaceVotes) - return MapVote_Finished(firstPlace); - - if(mapvote_keeptwotime) - if(time > mapvote_keeptwotime || (mapvote_voters_real - firstPlaceVotes - secondPlaceVotes) < secondPlaceVotes) - { - float didntvote; - MapVote_TouchMask(); - mapvote_message = "Now decide between the TOP TWO!"; - mapvote_keeptwotime = 0; - result = strcat(":vote:keeptwo:", mapvote_maps[firstPlace]); - result = strcat(result, ":", ftos(firstPlaceVotes)); - result = strcat(result, ":", mapvote_maps[secondPlace]); - result = strcat(result, ":", ftos(secondPlaceVotes), "::"); - didntvote = mapvote_voters; - for(i = 0; i < mapvote_count; ++i) - if(mapvote_maps[i] != "") - { - didntvote -= mapvote_selections[i]; - if(i != firstPlace) - if(i != secondPlace) - { - result = strcat(result, ":", mapvote_maps[i]); - result = strcat(result, ":", ftos(mapvote_selections[i])); - if(i < mapvote_count_real) - { - strunzone(mapvote_maps[i]); - mapvote_maps[i] = ""; - strunzone(mapvote_maps_pakfile[i]); - mapvote_maps_pakfile[i] = ""; - } - } - } - result = strcat(result, ":didn't vote:", ftos(didntvote)); - if(autocvar_sv_eventlog) - GameLogEcho(result); - } - - return FALSE; -} -void MapVote_Tick() -{ - float keeptwo; - float totalvotes; - - keeptwo = mapvote_keeptwotime; - MapVote_CheckRules_1(); // count - if(MapVote_CheckRules_2()) // decide - return; - - totalvotes = 0; - FOR_EACH_REALCLIENT(other) - { - // hide scoreboard again - if(other.health != 2342) - { - other.health = 2342; - other.impulse = 0; - if(IS_REAL_CLIENT(other)) - { - msg_entity = other; - WriteByte(MSG_ONE, SVC_FINALE); - WriteString(MSG_ONE, ""); - } - } - - // clear possibly invalid votes - if(mapvote_maps[other.mapvote - 1] == "") - other.mapvote = 0; - // use impulses as new vote - if(other.impulse >= 1 && other.impulse <= mapvote_count) - if(mapvote_maps[other.impulse - 1] != "") - { - other.mapvote = other.impulse; - MapVote_TouchVotes(other); - } - other.impulse = 0; - - if(other.mapvote) - ++totalvotes; - } - - MapVote_CheckRules_1(); // just count -} -void MapVote_Start() -{ - if(mapvote_run) - return; - - // wait for stats to be sent first - if(!playerstats_waitforme) - return; - - MapInfo_Enumerate(); - if(MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1)) - mapvote_run = TRUE; -} -void MapVote_Think() -{ - if(!mapvote_run) - return; - - if(alreadychangedlevel) - return; - - if(time < mapvote_nextthink) - return; - //dprint("tick\n"); - - mapvote_nextthink = time + 0.5; - - if(!mapvote_initialized) - { - if(autocvar_rescan_pending == 1) - { - cvar_set("rescan_pending", "2"); - localcmd("fs_rescan\nrescan_pending 3\n"); - return; - } - else if(autocvar_rescan_pending == 2) - { - return; - } - else if(autocvar_rescan_pending == 3) - { - // now build missing mapinfo files - if(!MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 1)) - return; - - // we're done, start the timer - cvar_set("rescan_pending", "0"); - } - - mapvote_initialized = TRUE; - if(DoNextMapOverride(0)) - return; - if(!autocvar_g_maplist_votable || player_count <= 0) - { - GotoNextMap(0); - return; - } - MapVote_Init(); - } - - MapVote_Tick(); -} - -string GotoMap(string m) -{ - if(!MapInfo_CheckMap(m)) - return "The map you chose is not available on this server."; cvar_set("nextmap", m); cvar_set("timelimit", "-1"); if(mapvote_initialized || alreadychangedlevel) @@ -2734,19 +2203,21 @@ void EndFrame() float altime; FOR_EACH_REALCLIENT(self) { + self.damage_dealt_total = 0; + if(IS_SPEC(self)) { if(self.enemy.typehitsound) self.typehit_time = time; - else if(self.enemy.hitsound) - self.hit_time = time; + else if(self.enemy.damage_dealt) + self.damage_dealt_total = ceil(self.enemy.damage_dealt); } else { if(self.typehitsound) self.typehit_time = time; - else if(self.hitsound) - self.hit_time = time; + else if(self.damage_dealt) + self.damage_dealt_total = ceil(self.damage_dealt); } } altime = time + frametime * (1 + autocvar_g_antilag_nudge); @@ -2757,10 +2228,12 @@ void EndFrame() // needed! FOR_EACH_CLIENT(self) { - self.hitsound = FALSE; self.typehitsound = FALSE; + self.damage_dealt = 0; antilag_record(self, altime); } + FOR_EACH_MONSTER(self) + antilag_record(self, altime); } @@ -2832,8 +2305,6 @@ void RestoreGame() void Shutdown() { - entity e; - gameover = 2; if(world_initialized > 0) @@ -2842,10 +2313,8 @@ void Shutdown() print("Saving persistent data...\n"); Ban_SaveBans(); - PlayerStats_EndMatch(0); - FOR_EACH_CLIENT(e) - PlayerStats_AddGlobalInfo(e); - PlayerStats_Shutdown(); + // playerstats with unfinished match + PlayerStats_GameReport(FALSE); if(!cheatcount_total) {