X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fclient.qc;h=00063bba214fae3ba064a144ec18bf2983db2eae;hb=94d74449f36b5750f1d1450b02c3817f179211b1;hp=17893200dbfc3a5b9a14d7c648fe2e5ea8a9f51f;hpb=633208780cb9d495626fdea4b3f5b3af548d81d3;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/client.qc b/qcsrc/server/client.qc index 17893200d..00063bba2 100644 --- a/qcsrc/server/client.qc +++ b/qcsrc/server/client.qc @@ -2,6 +2,7 @@ #include #include +#include #include #include #include @@ -51,7 +52,8 @@ #include #include #include -#include +#include +#include #include #include #include @@ -138,6 +140,8 @@ bool ClientData_Send(entity this, entity to, int sf) if (CS(e).race_completed) sf |= BIT(0); // forced scoreboard if (CS(to).spectatee_status) sf |= BIT(1); // spectator ent number follows if (CS(e).zoomstate) sf |= BIT(2); // zoomed + if (observe_blocked_if_eliminated && INGAME(to)) + sf |= BIT(3); // observing blocked if (autocvar_sv_showspectators == 1 || (autocvar_sv_showspectators && IS_SPEC(to))) sf |= BIT(4); // show spectators @@ -256,7 +260,7 @@ void PutObserverInServer(entity this, bool is_forced, bool use_spawnpoint) { if (vote_called) { VoteCount(false); } this.ready = false; - if (warmup_stage) recount_ready = true; + if (warmup_stage || game_starttime > time) recount_ready = true; } entcs_update_players(this); } @@ -534,6 +538,19 @@ void FixPlayermodel(entity player) setcolor(player, stof(autocvar_sv_defaultplayercolors)); } +void GiveWarmupResources(entity this) +{ + SetResource(this, RES_SHELLS, warmup_start_ammo_shells); + SetResource(this, RES_BULLETS, warmup_start_ammo_nails); + SetResource(this, RES_ROCKETS, warmup_start_ammo_rockets); + SetResource(this, RES_CELLS, warmup_start_ammo_cells); + SetResource(this, RES_PLASMA, warmup_start_ammo_plasma); + SetResource(this, RES_FUEL, warmup_start_ammo_fuel); + SetResource(this, RES_HEALTH, warmup_start_health); + SetResource(this, RES_ARMOR, warmup_start_armorvalue); + STAT(WEAPONS, this) = WARMUP_START_WEAPONS; +} + void PutPlayerInServer(entity this) { if (this.vehicle) vehicles_exit(this.vehicle, VHEF_RELEASE); @@ -576,17 +593,10 @@ void PutPlayerInServer(entity this) this.takedamage = DAMAGE_AIM; this.effects = EF_TELEPORT_BIT | EF_RESTARTANIM_BIT; - if (warmup_stage) { - SetResource(this, RES_SHELLS, warmup_start_ammo_shells); - SetResource(this, RES_BULLETS, warmup_start_ammo_nails); - SetResource(this, RES_ROCKETS, warmup_start_ammo_rockets); - SetResource(this, RES_CELLS, warmup_start_ammo_cells); - SetResource(this, RES_PLASMA, warmup_start_ammo_plasma); - SetResource(this, RES_FUEL, warmup_start_ammo_fuel); - SetResource(this, RES_HEALTH, warmup_start_health); - SetResource(this, RES_ARMOR, warmup_start_armorvalue); - STAT(WEAPONS, this) = WARMUP_START_WEAPONS; - } else { + if (warmup_stage) + GiveWarmupResources(this); + else + { SetResource(this, RES_SHELLS, start_ammo_shells); SetResource(this, RES_BULLETS, start_ammo_nails); SetResource(this, RES_ROCKETS, start_ammo_rockets); @@ -633,7 +643,8 @@ void PutPlayerInServer(entity this) this.respawn_flags = 0; this.respawn_time = 0; STAT(RESPAWN_TIME, this) = 0; - this.scale = ((q3compat && autocvar_sv_q3compat_changehitbox) ? 0.9 : autocvar_sv_player_scale); + // DP model scaling uses 1/16 accuracy and 13/16 is closest to 56/69 + this.scale = ((q3compat && autocvar_sv_q3compat_changehitbox) ? 0.8125 : autocvar_sv_player_scale); this.fade_time = 0; this.pain_finished = 0; this.pushltime = 0; @@ -810,7 +821,7 @@ void PutPlayerInServer(entity this) antilag_clear(this, CS(this)); - if (warmup_stage == -1) + if (warmup_stage < 0 || warmup_stage > 1) ReadyCount(); } @@ -971,7 +982,7 @@ bool findinlist_abbrev(string tofind, string list) return false; // empty list or search, just return // this function allows abbreviated strings! - FOREACH_WORD(list, it == substring(tofind, 0, strlen(it)), + FOREACH_WORD(list, it != "" && it == substring(tofind, 0, strlen(it)), { return true; }); @@ -999,6 +1010,8 @@ bool PlayerInIDList(entity p, string idlist) bool PlayerInList(entity player, string list) { + if (list == "") + return false; return boolean(PlayerInIDList(player, list) || PlayerInIPList(player, list)); } @@ -1031,16 +1044,14 @@ void SendWelcomeMessage(entity this, int msg_type) WriteByte(msg_type, boolean(autocvar_g_campaign)); if (boolean(autocvar_g_campaign)) { - WriteString(msg_type, Campaign_GetTitle()); WriteByte(msg_type, Campaign_GetLevelNum()); - WriteString(msg_type, Campaign_GetMessage()); return; } WriteString(msg_type, autocvar_hostname); WriteString(msg_type, autocvar_g_xonoticversion); WriteByte(msg_type, CS(this).version_mismatch); WriteByte(msg_type, (CS(this).version < autocvar_gameversion)); - WriteByte(msg_type, map_minplayers); + WriteByte(msg_type, autocvar_g_warmup > 1 ? autocvar_g_warmup : map_minplayers); WriteByte(msg_type, GetPlayerLimit()); MUTATOR_CALLHOOK(BuildMutatorsPrettyString, ""); @@ -1166,7 +1177,7 @@ void ClientConnect(entity this) if (IS_REAL_CLIENT(this)) sv_notice_join(this); - this.move_qcphysics = autocvar_sv_qcphysics; + this.move_qcphysics = true; // update physics stats (players can spawn before physics runs) Physics_UpdateStats(this); @@ -1177,10 +1188,21 @@ void ClientConnect(entity this) Handicap_Initialize(this); + // playban + if (PlayerInList(this, autocvar_g_playban_list)) + TRANSMUTE(Observer, this); + + if (PlayerInList(this, autocvar_g_chatban_list)) // chatban + CS(this).muted = true; + MUTATOR_CALLHOOK(ClientConnect, this); if (player_count == 1) + { + if (autocvar_sv_autopause && server_is_dedicated) + setpause(0); localcmd("\nsv_hook_firstjoin\n"); + } } /* ============= @@ -1196,6 +1218,20 @@ void ClientDisconnect(entity this) { assert(IS_CLIENT(this), return); + /* from "ignore" command */ + strfree(this.ignore_list); + FOREACH_CLIENT(IS_REAL_CLIENT(it) && it.ignore_list, + { + if(it.crypto_idfp && it.crypto_idfp != "") + continue; + string mylist = ignore_removefromlist(it, this); + if(it.ignore_list) + strunzone(it.ignore_list); + + it.ignore_list = strzone(mylist); + }); + /* from "ignore" command */ + PlayerStats_GameReport_FinalizePlayer(this); if (this.vehicle) vehicles_exit(this.vehicle, VHEF_RELEASE); if (CS(this).active_minigame) part_minigame(this); @@ -1241,7 +1277,7 @@ void ClientDisconnect(entity this) if (this.personal) delete(this.personal); this.playerid = 0; - if (warmup_stage) ReadyCount(); + if (warmup_stage || game_starttime > time) ReadyCount(); if (vote_called && IS_REAL_CLIENT(this)) VoteCount(false); player_powerups_remove_all(this); // stop powerup sound @@ -2013,6 +2049,17 @@ int nJoinAllowed(entity this, entity ignore) if(this && (Player_GetForcedTeamIndex(this) == TEAM_FORCE_SPECTATOR)) return 0; // forced spectators can never join + static float msg_time = 0; + if(this && !INGAME(this) && ignore && PlayerInList(this, autocvar_g_playban_list)) + { + if(time > msg_time) + { + Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_JOIN_PLAYBAN); + msg_time = time + 0.5; + } + return 0; + } + // TODO simplify this int totalClients = 0; int currentlyPlaying = 0; @@ -2031,7 +2078,6 @@ int nJoinAllowed(entity this, entity ignore) else if(player_limit > 0 && currentlyPlaying < player_limit) free_slots = min(maxclients - totalClients, player_limit - currentlyPlaying); - static float msg_time = 0; if(this && !INGAME(this) && ignore && !free_slots && time > msg_time) { Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_JOIN_PREVENT, player_limit); @@ -2052,6 +2098,32 @@ bool joinAllowed(entity this) return true; } +void show_entnum(entity this) +{ + // waypoint editor implements a similar feature for waypoints + if (waypointeditor_enabled) + return; + + if (wasfreed(this.wp_aimed)) + this.wp_aimed = NULL; + + WarpZone_crosshair_trace_plusvisibletriggers(this); + entity ent = NULL; + if (trace_ent) + { + ent = trace_ent; + if (ent != this.wp_aimed) + { + string str = sprintf( + "^7ent #%d\n^8 netname: ^3%s\n^8 classname: ^5%s\n^8 origin: ^2'%s'", + etof(ent), ent.netname, ent.classname, vtos(ent.origin)); + debug_text_3d((ent.absmin + ent.absmax) * 0.5, str, 0, 7, '0 0 0'); + } + } + if (this.wp_aimed != ent) + this.wp_aimed = ent; +} + .string shootfromfixedorigin; .bool dualwielding_prev; bool PlayerThink(entity this) @@ -2073,6 +2145,8 @@ bool PlayerThink(entity this) if (frametime) player_powerups(this); + if (frametime && autocvar_sv_show_entnum) show_entnum(this); + if (IS_DEAD(this)) { if (this.personal && g_race_qualifying) { if (time > this.respawn_time) { @@ -2217,11 +2291,18 @@ void ObserverOrSpectatorThink(entity this) } } + if (frametime && autocvar_sv_show_entnum) show_entnum(this); + if (IS_BOT_CLIENT(this) && !CS(this).autojoin_checked) { CS(this).autojoin_checked = true; TRANSMUTE(Player, this); PutClientInServer(this); + + .entity weaponentity = weaponentities[0]; + if(this.(weaponentity).m_weapon == WEP_Null) + W_NextWeapon(this, 0, weaponentity); + return; } @@ -2253,10 +2334,12 @@ void ObserverOrSpectatorThink(entity this) } CS(this).impulse = 0; } else if(PHYS_INPUT_BUTTON_ATCK2(this)) { - this.would_spectate = false; - this.flags &= ~FL_JUMPRELEASED; - TRANSMUTE(Observer, this); - PutClientInServer(this); + if(!observe_blocked_if_eliminated || !INGAME(this)) { + this.would_spectate = false; + this.flags &= ~FL_JUMPRELEASED; + TRANSMUTE(Observer, this); + PutClientInServer(this); + } } else if(!SpectateUpdate(this) && !SpectateNext(this)) { PutObserverInServer(this, false, true); this.would_spectate = true; @@ -2273,6 +2356,7 @@ void ObserverOrSpectatorThink(entity this) if ((is_spec && !(PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_ATCK2(this))) || (!is_spec && !(PHYS_INPUT_BUTTON_ATCK(this) || PHYS_INPUT_BUTTON_JUMP(this)))) { this.flags |= FL_JUMPRELEASED; + // primary attack pressed if(this.flags & FL_SPAWNING) { this.flags &= ~FL_SPAWNING;