X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_client.qc;h=ca19ed7464b67307740805031f7b626ae8ea5c54;hb=1633673cc6c65bdca0120f2a4fc33e8c2449f06d;hp=5bc0178f560fc491adb64bb3d7cb706e002bbd34;hpb=71339e3d8238d561f929e680289e13649fa10bb6;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index 5bc0178f5..ca19ed746 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -277,7 +277,7 @@ entity SelectSpawnPoint (float anypoint) else { float mindist; - if (arena_roundbased && !g_ca) + if (g_arena && arena_roundbased) mindist = 800; else mindist = 100; @@ -385,6 +385,24 @@ void PutObserverInServer (void) WriteEntity(MSG_ONE, self); } + if(g_lms) + { + // Only if the player cannot play at all + if(PlayerScore_Add(self, SP_LMS_RANK, 0) == 666) + self.frags = FRAGS_SPECTATOR; + else + self.frags = FRAGS_LMS_LOSER; + } + else if((g_race && g_race_qualifying) || g_cts) + { + if(PlayerScore_Add(self, SP_RACE_FASTEST, 0)) + self.frags = FRAGS_LMS_LOSER; + else + self.frags = FRAGS_SPECTATOR; + } + else + self.frags = FRAGS_SPECTATOR; + MUTATOR_CALLHOOK(MakePlayerObserver); minstagib_stop_countdown(self); @@ -406,13 +424,9 @@ void PutObserverInServer (void) if not(g_ca) // don't reset teams when moving a ca player to the spectators self.team = -1; // move this as it is needed to log the player spectating in eventlog - if(self.killcount != -666) { - if(g_lms) { - if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0 && self.lms_spectate_warning != 2) - Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_NOLIVES, self.netname); - else - Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_LMS_FORFEIT, self.netname); - } else { Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_SPECTATE, self.netname); } + if(self.killcount != -666) + { + Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_QUIT_SPECTATE, self.netname); if(self.just_joined == FALSE) { LogTeamchange(self.playerid, -1, 4); @@ -443,7 +457,9 @@ void PutObserverInServer (void) self.pauseregen_finished = 0; self.damageforcescale = 0; self.death_time = 0; + self.respawn_flags = 0; self.respawn_time = 0; + self.stat_respawn_time = 0; self.alpha = 0; self.scale = 0; self.fade_time = 0; @@ -488,45 +504,6 @@ void PutObserverInServer (void) self.punchvector = '0 0 0'; self.oldvelocity = self.velocity; self.fire_endtime = -1; - - if(g_arena) - { - if(self.version_mismatch) - { - self.frags = FRAGS_SPECTATOR; - Spawnqueue_Unmark(self); - Spawnqueue_Remove(self); - } - else - { - self.frags = FRAGS_LMS_LOSER; - Spawnqueue_Insert(self); - } - } - else if(g_lms) - { - // Only if the player cannot play at all - if(PlayerScore_Add(self, SP_LMS_RANK, 0) == 666) - self.frags = FRAGS_SPECTATOR; - else - self.frags = FRAGS_LMS_LOSER; - } - else if(g_ca) - { - if(self.caplayer) - self.frags = FRAGS_LMS_LOSER; - else - self.frags = FRAGS_SPECTATOR; - } - else if((g_race && g_race_qualifying) || g_cts) - { - if(PlayerScore_Add(self, SP_RACE_FASTEST, 0)) - self.frags = FRAGS_LMS_LOSER; - else - self.frags = FRAGS_SPECTATOR; - } - else - self.frags = FRAGS_SPECTATOR; } .float model_randomizer; @@ -611,21 +588,6 @@ void FixPlayermodel() setcolor(self, stof(autocvar_sv_defaultplayercolors)); } -void PlayerTouchExplode(entity p1, entity p2) -{ - vector org; - org = (p1.origin + p2.origin) * 0.5; - org_z += (p1.mins_z + p2.mins_z) * 0.5; - - te_explosion(org); - - entity e; - e = spawn(); - setorigin(e, org); - RadiusDamage(e, world, g_touchexplode_damage, g_touchexplode_edgedamage, g_touchexplode_radius, world, g_touchexplode_force, DEATH_TOUCHEXPLODE, world); - remove(e); -} - /* ============= PutClientInServer @@ -637,11 +599,7 @@ Called when a client spawns in the server void PutClientInServer (void) { if(clienttype(self) == CLIENTTYPE_BOT) - { self.classname = "player"; - if(g_ca) - self.caplayer = 1; - } else if(clienttype(self) == CLIENTTYPE_REAL) { msg_entity = self; @@ -660,13 +618,12 @@ void PutClientInServer (void) self.classname = "observer"; } - if((g_arena && !self.spawned) || (g_ca && !allowed_to_spawn)) - self.classname = "observer"; + MUTATOR_CALLHOOK(PutClientInServer); if(gameover) self.classname = "observer"; - if(self.classname == "player" && (!g_ca || (g_ca && allowed_to_spawn))) { + if(self.classname == "player") { entity spot, oldself; float j; @@ -772,7 +729,9 @@ void PutClientInServer (void) } self.damageforcescale = 2; self.death_time = 0; + self.respawn_flags = 0; self.respawn_time = 0; + self.stat_respawn_time = 0; self.scale = 0; self.fade_time = 0; self.pain_frame = 0; @@ -824,14 +783,6 @@ void PutClientInServer (void) self.lastteleporttime = time; // prevent insane speeds due to changing origin self.hud = HUD_NORMAL; - if(g_arena) - { - Spawnqueue_Remove(self); - Spawnqueue_Mark(self); - } - else if(g_ca) - self.caplayer = 1; - self.event_damage = PlayerDamage; self.bot_attack = TRUE; @@ -857,14 +808,7 @@ void PutClientInServer (void) //stuffcmd(self, "chase_active 0"); //stuffcmd(self, "set viewsize $tmpviewsize \n"); - - if(g_assault) { - if(self.team == assault_attacker_team) - Send_Notification(NOTIF_TEAM, self, MSG_CENTER, CENTER_ASSAULT_ATTACKING); - else - Send_Notification(NOTIF_TEAM, self, MSG_CENTER, CENTER_ASSAULT_DEFENDING); - } - + target_voicescript_clear(self); // reset fields the weapons may use @@ -1062,14 +1006,13 @@ void ClientKill_Now_TeamChange() } else if(self.killindicator_teamchange == -2) { - if(g_ca) - self.caplayer = 0; if(blockSpectators) Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_SPECTATE_WARNING, autocvar_g_maxplayers_spectator_blocktime); PutObserverInServer(); } else SV_ChangeTeam(self.killindicator_teamchange - 1); + self.killindicator_teamchange = 0; } void ClientKill_Now() @@ -1245,19 +1188,11 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2 void ClientKill (void) { - if (gameover) - return; + if(gameover) return; + if(self.player_blocked) return; + if(self.freezetag_frozen) return; - if((g_arena || g_ca) && ((champion && champion.classname == "player" && player_count > 1) || player_count == 1)) // don't allow a kill in this case either - { - // do nothing - } - else if(self.freezetag_frozen) - { - // do nothing - } - else - ClientKill_TeamChange(0); + ClientKill_TeamChange(0); } void CTS_ClientKill (entity e) // silent version of ClientKill, used when player finishes a CTS run. Useful to prevent cheating by running back to the start line and starting out with more speed @@ -1417,7 +1352,7 @@ void ClientConnect (void) JoinBestTeam(self, FALSE, FALSE); // if the team number is valid, keep it - if((autocvar_sv_spectate == 1 && !g_lms) || autocvar_g_campaign || self.team_forced < 0) { + if((autocvar_sv_spectate == 1) || autocvar_g_campaign || self.team_forced < 0) { self.classname = "observer"; } else { if(teamplay) @@ -1487,13 +1422,6 @@ void ClientConnect (void) else stuffcmd(self, "set _teams_available 0\n"); - if(g_arena || g_ca) - { - self.classname = "observer"; - if(g_arena) - Spawnqueue_Insert(self); - } - attach_entcs(); bot_relinkplayerlist(); @@ -1519,15 +1447,6 @@ void ClientConnect (void) stuffcmd(self, "cl_cmd settemp chase_active 1\n"); } - if(g_lms) - { - if(PlayerScore_Add(self, SP_LMS_LIVES, LMS_NewPlayerLives()) <= 0) - { - PlayerScore_Add(self, SP_LMS_RANK, 666); - self.frags = FRAGS_SPECTATOR; - } - } - if(!sv_foginterval && world.fog != "") stuffcmd(self, strcat("\nfog ", world.fog, "\nr_fog_exp2 0\nr_drawfog 1\n")); @@ -1567,13 +1486,11 @@ void ClientConnect (void) CSQCMODEL_AUTOINIT(); self.model_randomizer = random(); - - if(clienttype(self) != CLIENTTYPE_REAL) - return; - - sv_notice_join(); - - MUTATOR_CALLHOOK(ClientConnect); + + if(clienttype(self) == CLIENTTYPE_REAL) + sv_notice_join(); + + MUTATOR_CALLHOOK(ClientConnect); } /* ============= @@ -1640,12 +1557,6 @@ void ClientDisconnect (void) bot_relinkplayerlist(); - if(g_arena) - { - Spawnqueue_Unmark(self); - Spawnqueue_Remove(self); - } - accuracy_free(self); ClientData_Detach(); PlayerScore_Detach(self); @@ -2003,7 +1914,7 @@ void player_regen (void) limita = limita * limit_mod; //limitf = limitf * limit_mod; - if(g_lms && g_ca) + if(g_ca) rot_mod = 0; if (!g_minstagib && !g_ca && (!g_lms || autocvar_g_lms_regenerate)) @@ -2128,7 +2039,6 @@ void SpectateCopy(entity spectatee) { self.dmg_inflictor = spectatee.dmg_inflictor; self.v_angle = spectatee.v_angle; self.angles = spectatee.v_angle; - self.stat_respawn_time = spectatee.stat_respawn_time; if(!self.BUTTON_USE) self.fixangle = TRUE; setorigin(self, spectatee.origin); @@ -2179,6 +2089,46 @@ float SpectateUpdate() { } +float setSpectator() +{ + if(self.enemy.classname != "player") + return FALSE; + /*if(self.enemy.vehicle) + { + + msg_entity = self; + WriteByte(MSG_ONE, SVC_SETVIEW); + WriteEntity(MSG_ONE, self.enemy); + //stuffcmd(self, "set viewsize $tmpviewsize \n"); + + self.movetype = MOVETYPE_NONE; + accuracy_resend(self); + } + else + {*/ + msg_entity = self; + WriteByte(MSG_ONE, SVC_SETVIEW); + WriteEntity(MSG_ONE, self.enemy); + //stuffcmd(self, "set viewsize $tmpviewsize \n"); + self.movetype = MOVETYPE_NONE; + accuracy_resend(self); + + if(!SpectateUpdate()) + PutObserverInServer(); + //} + return TRUE; +} + +float Spectate(entity pl) +{ + if(g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer) + if(pl.team != self.team) + return 0; + + self.enemy = pl; + return setSpectator(); +} + // Returns next available player to spectate if g_ca_spectate_enemies == 0 entity CA_SpectateNext(entity start) { if (start.team == self.team) { @@ -2202,13 +2152,10 @@ entity CA_SpectateNext(entity start) { return other; } -float SpectateNext(entity _prefer) { - - if(_prefer) - other = _prefer; - else - other = find(self.enemy, classname, "player"); - +float SpectateNext() +{ + other = find(self.enemy, classname, "player"); + if (g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer) { // CA and ca players when spectating enemies is forbidden other = CA_SpectateNext(other); @@ -2217,38 +2164,49 @@ float SpectateNext(entity _prefer) { if (!other) other = find(other, classname, "player"); } - + if (other) self.enemy = other; - if(self.enemy.classname == "player") { - /*if(self.enemy.vehicle) - { - - msg_entity = self; - WriteByte(MSG_ONE, SVC_SETVIEW); - WriteEntity(MSG_ONE, self.enemy); - //stuffcmd(self, "set viewsize $tmpviewsize \n"); - - self.movetype = MOVETYPE_NONE; - accuracy_resend(self); - } - else - {*/ - msg_entity = self; - WriteByte(MSG_ONE, SVC_SETVIEW); - WriteEntity(MSG_ONE, self.enemy); - //stuffcmd(self, "set viewsize $tmpviewsize \n"); - self.movetype = MOVETYPE_NONE; - accuracy_resend(self); - - if(!SpectateUpdate()) - PutObserverInServer(); - //} - return 1; - } else { - return 0; + return setSpectator(); +} + +float SpectatePrev() +{ + // NOTE: chain order is from the highest to the lower entnum (unlike find) + other = findchain(classname, "player"); + if not(other) // no player + return FALSE; + + entity first = other; + // skip players until current spectated player + if(self.enemy) + while(other && other != self.enemy) + other = other.chain; + + if (g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer) + { + do { other = other.chain; } + while(other && other.team != self.team); + + if not(other) + { + other = first; + while(other.team != self.team) + other = other.chain; + if(other == self.enemy) + return TRUE; + } + } + else + { + if(other.chain) + other = other.chain; + else + other = first; } + self.enemy = other; + return setSpectator(); } /* @@ -2279,6 +2237,8 @@ void ShowRespawnCountdown() void LeaveSpectatorMode() { + if(self.caplayer) + return; if(nJoinAllowed(self)) { if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0) @@ -2297,7 +2257,8 @@ void LeaveSpectatorMode() if(IS_PLAYER(self)) { Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_JOIN_PLAY, self.netname); } } - else if not(g_ca && self.caplayer) { stuffcmd(self, "menu_showteamselect\n"); } + else + stuffcmd(self, "menu_showteamselect\n"); } else { @@ -2337,8 +2298,9 @@ float nJoinAllowed(entity ignore) { return maxclients - totalClients; float currentlyPlaying = 0; - FOR_EACH_REALPLAYER(e) - currentlyPlaying += 1; + FOR_EACH_REALCLIENT(e) + if(e.classname == "player" || e.caplayer == 1) + currentlyPlaying += 1; if(currentlyPlaying < autocvar_g_maxplayers) return min(maxclients - totalClients, autocvar_g_maxplayers - currentlyPlaying); @@ -2415,7 +2377,7 @@ void ObserverThink() self.flags |= FL_SPAWNING; } else if(self.BUTTON_ATCK && !self.version_mismatch) { self.flags &~= FL_JUMPRELEASED; - if(SpectateNext(world) == 1) { + if(SpectateNext()) { self.classname = "spectator"; } } else { @@ -2442,14 +2404,24 @@ void SpectatorThink() if (self.BUTTON_JUMP && !self.version_mismatch) { self.flags &~= FL_JUMPRELEASED; self.flags |= FL_SPAWNING; - } else if(self.BUTTON_ATCK) { + } else if(self.BUTTON_ATCK || self.impulse == 10 || self.impulse == 15 || self.impulse == 18 || self.impulse >= 200 && self.impulse <= 209) { self.flags &~= FL_JUMPRELEASED; - if(SpectateNext(world) == 1) { + if(SpectateNext()) { self.classname = "spectator"; } else { self.classname = "observer"; PutClientInServer(); } + self.impulse = 0; + } else if(self.impulse == 12 || self.impulse == 16 || self.impulse == 19 || self.impulse >= 220 && self.impulse <= 229) { + self.flags &~= FL_JUMPRELEASED; + if(SpectatePrev()) { + self.classname = "spectator"; + } else { + self.classname = "observer"; + PutClientInServer(); + } + self.impulse = 0; } else if (self.BUTTON_ATCK2) { self.flags &~= FL_JUMPRELEASED; self.classname = "observer"; @@ -2490,8 +2462,6 @@ void PlayerUseKey() MUTATOR_CALLHOOK(PlayerUseKey); } -.float touchexplode_time; - /* ============= PlayerPreThink @@ -2507,14 +2477,10 @@ void PlayerPreThink (void) WarpZone_PlayerPhysics_FixVAngle(); self.stat_game_starttime = game_starttime; + self.stat_round_starttime = round_starttime; self.stat_allow_oldnexbeam = autocvar_g_allow_oldnexbeam; self.stat_leadlimit = autocvar_leadlimit; - if(g_arena || (g_ca && !allowed_to_spawn)) - self.stat_respawn_time = 0; - else - self.stat_respawn_time = self.respawn_time; - if(frametime) { // physics frames: update anticheat stuff @@ -2639,25 +2605,26 @@ void PlayerPreThink (void) if (self.deadflag != DEAD_NO) { - float button_pressed, force_respawn; if(self.personal && g_race_qualifying) { if(time > self.respawn_time) { self.respawn_time = time + 1; // only retry once a second + self.stat_respawn_time = self.respawn_time; respawn(); self.impulse = 141; } } else { + float button_pressed; if(frametime) player_anim(); button_pressed = (self.BUTTON_ATCK || self.BUTTON_JUMP || self.BUTTON_ATCK2 || self.BUTTON_HOOK || self.BUTTON_USE); - force_respawn = (g_lms || g_ca || g_cts || autocvar_g_forced_respawn); + if (self.deadflag == DEAD_DYING) { - if(force_respawn) + if(self.respawn_flags & RESPAWN_FORCE) self.deadflag = DEAD_RESPAWNING; else if(!button_pressed) self.deadflag = DEAD_DEAD; @@ -2680,7 +2647,13 @@ void PlayerPreThink (void) respawn(); } } + ShowRespawnCountdown(); + + if(self.respawn_flags & RESPAWN_SILENT) + self.stat_respawn_time = 0; + else + self.stat_respawn_time = self.respawn_time; } // if respawning, invert stat_respawn_time to indicate this, the client translates it @@ -2689,58 +2662,6 @@ void PlayerPreThink (void) return; } - // FIXME from now on self.deadflag is always 0 (and self.health is never < 1) - // so (self.deadflag == DEAD_NO) is always true in the code below - - if(g_touchexplode) - if(time > self.touchexplode_time) - if(self.classname == "player") - if(self.deadflag == DEAD_NO) - if not(IS_INDEPENDENT_PLAYER(self)) - FOR_EACH_PLAYER(other) if(self != other) - { - if(time > other.touchexplode_time) - if(other.deadflag == DEAD_NO) - if not(IS_INDEPENDENT_PLAYER(other)) - if(boxesoverlap(self.absmin, self.absmax, other.absmin, other.absmax)) - { - PlayerTouchExplode(self, other); - self.touchexplode_time = other.touchexplode_time = time + 0.2; - } - } - - if(g_lms && !self.deadflag && autocvar_g_lms_campcheck_interval) - { - vector dist; - - // calculate player movement (in 2 dimensions only, so jumping on one spot doesn't count as movement) - dist = self.prevorigin - self.origin; - dist_z = 0; - self.lms_traveled_distance += fabs(vlen(dist)); - - if((autocvar_g_campaign && !campaign_bots_may_start) || (time < game_starttime)) - { - self.lms_nextcheck = time + autocvar_g_lms_campcheck_interval*2; - self.lms_traveled_distance = 0; - } - - if(time > self.lms_nextcheck) - { - //sprint(self, "distance: ", ftos(self.lms_traveled_distance), "\n"); - if(self.lms_traveled_distance < autocvar_g_lms_campcheck_distance) - { - Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_LMS_CAMPCHECK); - // FIXME KadaverJack: gibbing player here causes playermodel to bounce around, instead of eye.md3 - // I wasn't able to find out WHY that happens, so I put a workaround in place that shall prevent players from being gibbed :( - if(self.vehicle) - Damage(self.vehicle, self, self, autocvar_g_lms_campcheck_damage * 2, DEATH_CAMP, self.vehicle.origin, '0 0 0'); - else - Damage(self, self, self, bound(0, autocvar_g_lms_campcheck_damage, self.health + self.armorvalue * autocvar_g_balance_armor_blockpercent + 5), DEATH_CAMP, self.origin, '0 0 0'); - } - self.lms_nextcheck = time + autocvar_g_lms_campcheck_interval; - self.lms_traveled_distance = 0; - } - } self.prevorigin = self.origin;