X-Git-Url: https://de.git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=qcsrc%2Fclient%2Fmain.qc;h=238ce891a2bada7c0fa4b65451a311cca23aa6c3;hb=765eed8d356d25d15047202838dc58db8cb80b89;hp=ad11dbd296254b5bdbf580109d0b9b3276278d2e;hpb=6ae488fa94396ad9ffa0dc3dbfbedb54c8b7983a;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/client/main.qc b/qcsrc/client/main.qc index ad11dbd29..238ce891a 100644 --- a/qcsrc/client/main.qc +++ b/qcsrc/client/main.qc @@ -1,32 +1,33 @@ #include "main.qh" +#include +#include +#include +#include +#include +#include +#include #include -#include -#include "miscfunctions.qh" -#include -#include -#include -#include -#include "hud/_mod.qh" -#include "command/cl_cmd.qh" -#include "mapvoting.qh" +#include #include -#include "hud/panel/centerprint.qh" -#include "hud/panel/scoreboard.qh" -#include "hud/panel/quickmenu.qh" -#include "shownames.qh" -#include "view.qh" -#include "weapons/projectile.qh" +#include +#include +#include #include -#include +#include +#include +#include +#include +#include #include +#include #include +#include #include #include #include #include #include -#include #include #include #include @@ -46,7 +47,7 @@ void CSQC_Init() prvm_language = strzone(cvar_string("prvm_language")); #ifdef WATERMARK - LOG_INFOF("^4CSQC Build information: ^1%s", WATERMARK); + LOG_TRACEF("^4CSQC Build information: ^1%s", WATERMARK); #endif { @@ -57,6 +58,8 @@ void CSQC_Init() maxclients = i; } + ReplicateVars(REPLICATEVARS_SEND_ALL); + // needs to be done so early because of the constants they create static_init(); static_init_late(); @@ -123,13 +126,13 @@ void CSQC_Init() { get_mi_min_max_texcoords(1); // try the CLEVER way first - minimapname = strcat("gfx/", mi_shortname, "_radar.tga"); + minimapname = strcat("gfx/", mi_shortname, "_radar"); shortmapname = mi_shortname; if (precache_pic(minimapname) == "") { // but maybe we have a non-clever minimap - minimapname = strcat("gfx/", mi_shortname, "_mini.tga"); + minimapname = strcat("gfx/", mi_shortname, "_mini"); if (precache_pic(minimapname) == "") minimapname = ""; // FAIL else @@ -167,6 +170,9 @@ void Shutdown() if(autocvar_chase_active < 0) cvar_set("chase_active", "0"); + if (autocvar_r_drawviewmodel < 0) + cvar_set("r_drawviewmodel", "0"); + cvar_set("slowmo", cvar_defstring("slowmo")); // reset it back to 'default' if (!isdemo()) @@ -184,7 +190,129 @@ void Shutdown() deactivate_minigame(); HUD_MinigameMenu_Close(NULL, NULL, NULL); - ReplicateVars(true); // destroy + ReplicateVars(REPLICATEVARS_DESTROY); +} + +void AuditLists() +{ + entity e; + entity prev; + + prev = players; + for(e = prev.sort_next; e; prev = e, e = e.sort_next) + { + if(prev != e.sort_prev) + error(strcat("sort list chain error\nplease submit the output of 'prvm_edicts client' to the developers")); + } + + prev = teams; + for(e = prev.sort_next; e; prev = e, e = e.sort_next) + { + if(prev != e.sort_prev) + error(strcat("sort list chain error\nplease submit the output of 'prvm_edicts client' to the developers")); + } +} + +float RegisterPlayer(entity player) +{ + entity pl; + AuditLists(); + for(pl = players.sort_next; pl; pl = pl.sort_next) + if(pl == player) + error("Player already registered!"); + player.sort_next = players.sort_next; + player.sort_prev = players; + if(players.sort_next) + players.sort_next.sort_prev = player; + players.sort_next = player; + AuditLists(); + return true; +} + +void RemovePlayer(entity player) +{ + entity pl, parent; + AuditLists(); + parent = players; + for(pl = players.sort_next; pl && pl != player; pl = pl.sort_next) + parent = pl; + + if(!pl) + { + error("Trying to remove a player which is not in the playerlist!"); + return; + } + parent.sort_next = player.sort_next; + if(player.sort_next) + player.sort_next.sort_prev = parent; + AuditLists(); +} + +void MoveToLast(entity e) +{ + AuditLists(); + entity ent = e.sort_next; + while(ent) + { + SORT_SWAP(ent, e); + ent = e.sort_next; + } + AuditLists(); +} + +float RegisterTeam(entity Team) +{ + assert_once(Team.team, eprint(Team)); + entity tm; + AuditLists(); + for(tm = teams.sort_next; tm; tm = tm.sort_next) + if(tm == Team) + error("Team already registered!"); + Team.sort_next = teams.sort_next; + Team.sort_prev = teams; + if(teams.sort_next) + teams.sort_next.sort_prev = Team; + teams.sort_next = Team; + if(Team.team && Team.team != NUM_SPECTATOR) + ++team_count; + AuditLists(); + return true; +} + +void RemoveTeam(entity Team) +{ + entity tm, parent; + AuditLists(); + parent = teams; + for(tm = teams.sort_next; tm && tm != Team; tm = tm.sort_next) + parent = tm; + + if(!tm) + { + LOG_INFO(_("Trying to remove a team which is not in the teamlist!")); + return; + } + parent.sort_next = Team.sort_next; + if(Team.sort_next) + Team.sort_next.sort_prev = parent; + if(Team.team && Team.team != NUM_SPECTATOR) + --team_count; + AuditLists(); +} + +entity GetTeam(int Team, bool add) +{ + TC(int, Team); TC(bool, add); + int num = (Team == NUM_SPECTATOR) ? 16 : Team; + if(teamslots[num]) + return teamslots[num]; + if (!add) + return NULL; + entity tm = new_pure(team); + tm.team = Team; + teamslots[num] = tm; + RegisterTeam(tm); + return tm; } .float has_team; @@ -325,10 +453,13 @@ float CSQC_InputEvent(int bInputType, float nPrimary, float nSecondary) { TC(int, bInputType); bool override = false; + override |= HUD_Panel_InputEvent(bInputType, nPrimary, nSecondary); if (override) return true; + override |= HUD_Panel_Chat_InputEvent(bInputType, nPrimary, nSecondary); + override |= QuickMenu_InputEvent(bInputType, nPrimary, nSecondary); override |= HUD_Radar_InputEvent(bInputType, nPrimary, nSecondary); @@ -340,6 +471,32 @@ float CSQC_InputEvent(int bInputType, float nPrimary, float nSecondary) if(override) return true; + if(bInputType == 3 || bInputType == 2) + return false; + + // at this point bInputType can only be 0 or 1 (key pressed or released) + bool key_pressed = (bInputType == 0); + + if(key_pressed) { + if(nPrimary == K_ALT) hudShiftState |= S_ALT; + if(nPrimary == K_CTRL) hudShiftState |= S_CTRL; + if(nPrimary == K_SHIFT) hudShiftState |= S_SHIFT; + } + else { + if(nPrimary == K_ALT) hudShiftState -= (hudShiftState & S_ALT); + if(nPrimary == K_CTRL) hudShiftState -= (hudShiftState & S_CTRL); + if(nPrimary == K_SHIFT) hudShiftState -= (hudShiftState & S_SHIFT); + } + + if (nPrimary == K_ESCAPE && !(hudShiftState & S_SHIFT) && key_pressed) + { + if (cvar("_menu_gamemenu_dialog_available")) + { + localcmd("\nmenu_showgamemenudialog\n"); + return true; + } + } + return false; } @@ -726,7 +883,7 @@ NET_HANDLE(ENT_CLIENT_SPAWNEVENT, bool is_new) } // CSQC_Ent_Update : Called every frame that the server has indicated an update to the SSQC / CSQC entity has occured. -// The only parameter reflects if the entity is "new" to the client, meaning it just came into the client's PVS. +// The parameter isnew reflects if the entity is "new" to the client, meaning it just came into the client's PVS. void CSQC_Ent_Update(entity this, bool isnew) { this.sourceLoc = __FILE__":"STR(__LINE__); @@ -752,6 +909,7 @@ void CSQC_Ent_Update(entity this, bool isnew) { LOG_INFOF("A CSQC entity changed its type! (edict: %d, server: %d, type: %d -> %d)", etof(this), this.entnum, this.enttype, t); Ent_Remove(this); + ONREMOVE(this); clearentity(this); isnew = true; } @@ -770,7 +928,7 @@ void CSQC_Ent_Update(entity this, bool isnew) FOREACH(LinkedEntities, it.m_id == t, { if (isnew) this.classname = it.netname; if (autocvar_developer_csqcentities) - LOG_INFOF("CSQC_Ent_Update(%d) at %f with this=%i {.entnum=%d, .enttype=%d} t=%s (%d)", isnew, savetime, this, this.entnum, this.enttype, this.classname, t); + LOG_INFOF("CSQC_Ent_Update(%i, %d) at %f {.entnum=%d, .enttype=%d} t=%s (%d)", this, isnew, savetime, this.entnum, this.enttype, this.classname, t); done = it.m_read(this, NULL, isnew); MUTATOR_CALLHOOK(Ent_Update, this, isnew); break; @@ -778,7 +936,7 @@ void CSQC_Ent_Update(entity this, bool isnew) time = savetime; if (!done) { - LOG_FATALF("CSQC_Ent_Update(%d) at %f with this=%i {.entnum=%d, .enttype=%d} t=%s (%d)", isnew, savetime, this, this.entnum, this.enttype, this.classname, t); + LOG_FATALF("CSQC_Ent_Update(%i, %d) at %f {.entnum=%d, .enttype=%d} t=%s (%d)", this, isnew, savetime, this.entnum, this.enttype, this.classname, t); } } @@ -879,6 +1037,7 @@ void Fog_Force() localcmd(sprintf("\nfog %s\nr_fog_exp2 0\nr_drawfog 1\n", forcefog)); } +bool net_handle_ServerWelcome(); NET_HANDLE(ENT_CLIENT_SCORES_INFO, bool isnew) { make_pure(this); @@ -894,6 +1053,8 @@ NET_HANDLE(ENT_CLIENT_SCORES_INFO, bool isnew) strcpy(teamscores_label(i), ReadString()); teamscores_flags(i) = ReadByte(); } + if (ReadByte()) + net_handle_ServerWelcome(); return = true; Scoreboard_InitScores(); Gamemode_Init(); @@ -1057,12 +1218,10 @@ NET_HANDLE(TE_CSQC_RACE, bool isNew) case RACE_NET_SPEED_AWARD: race_speedaward = ReadInt24_t() * GetSpeedUnitFactor(autocvar_hud_panel_physics_speed_unit); strcpy(race_speedaward_holder, ReadString()); - strcpy(race_speedaward_unit, GetSpeedUnit(autocvar_hud_panel_physics_speed_unit)); break; case RACE_NET_SPEED_AWARD_BEST: race_speedaward_alltimebest = ReadInt24_t() * GetSpeedUnitFactor(autocvar_hud_panel_physics_speed_unit); strcpy(race_speedaward_alltimebest_holder, ReadString()); - strcpy(race_speedaward_alltimebest_unit, GetSpeedUnit(autocvar_hud_panel_physics_speed_unit)); break; case RACE_NET_RANKINGS_CNT: RANKINGS_DISPLAY_CNT = ReadByte(); @@ -1156,6 +1315,64 @@ NET_HANDLE(TE_CSQC_WEAPONCOMPLAIN, bool isNew) } } +bool net_handle_ServerWelcome() +{ + bool campaign = ReadByte(); + if (campaign) + { + string campaign_title = ReadString(); + int campaign_level = ReadByte(); + string campaign_msg = ReadString(); + string welcomedialog_args; + welcomedialog_args = strcat("HOSTNAME \"", campaign_title, "\""); + string key = getcommandkey(_("jump"), "+jump"); + string msg = strcat( + CCR("^F1"), sprintf(_("Level %d:"), campaign_level), + sprintf(CCR(" ^BG%s\n^3\n"), campaign_msg), + sprintf(CCR(_("^BGPress ^F2%s^BG to enter the game")), key)); + msg = MakeConsoleSafe(strreplace("\n", "\\n", msg)); + welcomedialog_args = strcat(welcomedialog_args, " WELCOME \"", msg, "\""); + localcmd("\nmenu_cmd directmenu Welcome ", welcomedialog_args, "\n"); + return true; + } + + bool force_centerprint = ReadByte(); + string hostname = ReadString(); + string ver = ReadString(); + string modifications = ReadString(); + string cache_mutatormsg = ReadString(); + string mutator_msg = ReadString(); + string motd = ReadString(); + + string msg = ""; + msg = strcat(msg, ver); + msg = strcat(msg, "^8\n\n", strcat(_("Gametype:"), " ^1", MapInfo_Type_ToText(gametype)), "^8\n"); + if(modifications != "") + msg = strcat(msg, "^8\n", _("Active modifications:"), " ^3", modifications, "^8\n"); + if (cache_mutatormsg != "") + msg = strcat(msg, "\n\n^8", _("Special gameplay tips:"), " ^7", cache_mutatormsg); + msg = strcat(msg, mutator_msg); // trust that the mutator will do proper formatting + if (motd != "") + msg = strcat(msg, "\n\n^8", _("MOTD:"), " ^7", motd); + + if (!force_centerprint && !isdemo() && cvar("_menu_welcome_dialog_available") && autocvar_cl_welcome_in_menu_dialog) + { + string welcomedialog_args; + welcomedialog_args = strcat("HOSTNAME \"", hostname, "\""); + msg = MakeConsoleSafe(strreplace("\n", "\\n", msg)); + welcomedialog_args = strcat(welcomedialog_args, " WELCOME \"", msg, "\""); + localcmd("\nmenu_cmd directmenu Welcome ", welcomedialog_args, "\n"); + } + else + centerprint_Add(ORDINAL(CPID_MOTD), strcat(hostname, "\n\n\n", msg), -1, 0); + return true; +} + +NET_HANDLE(TE_CSQC_SERVERWELCOME, bool isNew) +{ + return net_handle_ServerWelcome(); +} + string _getcommandkey(string cmd_name, string command, bool forcename) { string keys; @@ -1207,3 +1424,26 @@ string _getcommandkey(string cmd_name, string command, bool forcename) else return keys; } + +/** engine callback */ +void URI_Get_Callback(int id, int status, string data) +{ + TC(int, id); TC(int, status); + if(url_URI_Get_Callback(id, status, data)) + { + // handled + } + else if (id == URI_GET_DISCARD) + { + // discard + } + else if (id >= URI_GET_CURL && id <= URI_GET_CURL_END) + { + // sv_cmd curl + Curl_URI_Get_Callback(id, status, data); + } + else + { + LOG_INFOF("Received HTTP request data for an invalid id %d.", id); + } +}