X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_client.qc;h=fab6f400adc1fb31616936618e07e72fc11ce4c1;hb=28db67726bdcc01ded4d4c942326dfc7f7375e18;hp=7f16dfd74ba449302824326641e3d6cdd07da71e;hpb=0ee28e07a9b549802219bea01852416e7d622e60;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index 7f16dfd74..fab6f400a 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -17,7 +17,7 @@ float ClientData_Send(entity to, float sf) entity e; e = to; - if(to.classname == "spectator") + if(IS_SPEC(to)) e = to.enemy; sf = 0; @@ -68,245 +68,14 @@ void ClientData_Touch(entity e) FOR_EACH_REALCLIENT(e2) { if(e2 != e) - if(e2.classname == "spectator") + if(IS_SPEC(e2)) if(e2.enemy == e) e2.clientdata.SendFlags = 1; } } - -.vector spawnpoint_score; .string netname_previous; -void spawnfunc_info_player_survivor (void) -{ - spawnfunc_info_player_deathmatch(); -} - -void spawnfunc_info_player_start (void) -{ - spawnfunc_info_player_deathmatch(); -} - -void spawnfunc_info_player_deathmatch (void) -{ - self.classname = "info_player_deathmatch"; - relocate_spawnpoint(); -} - -void spawnpoint_use() -{ - if(teamplay) - if(have_team_spawns > 0) - { - self.team = activator.team; - some_spawn_has_been_used = 1; - } -} - -// Returns: -// _x: prio (-1 if unusable) -// _y: weight -vector Spawn_Score(entity spot, float mindist, float teamcheck) -{ - float shortest, thisdist; - float prio; - entity player; - - prio = 0; - - // filter out spots for the wrong team - if(teamcheck >= 0) - if(spot.team != teamcheck) - return '-1 0 0'; - - if(race_spawns) - if(spot.target == "") - return '-1 0 0'; - - if(clienttype(self) == CLIENTTYPE_REAL) - { - if(spot.restriction == 1) - return '-1 0 0'; - } - else - { - if(spot.restriction == 2) - return '-1 0 0'; - } - - shortest = vlen(world.maxs - world.mins); - FOR_EACH_PLAYER(player) if (player != self) - { - thisdist = vlen(player.origin - spot.origin); - if (thisdist < shortest) - shortest = thisdist; - } - if(shortest > mindist) - prio += SPAWN_PRIO_GOOD_DISTANCE; - - spawn_score = prio * '1 0 0' + shortest * '0 1 0'; - spawn_spot = spot; - - // filter out spots for assault - if(spot.target != "") { - entity ent; - float found; - - found = 0; - for(ent = world; (ent = find(ent, targetname, spot.target)); ) - { - ++found; - if(ent.spawn_evalfunc) - { - entity oldself = self; - self = ent; - spawn_score = ent.spawn_evalfunc(oldself, spot, spawn_score); - self = oldself; - if(spawn_score_x < 0) - return spawn_score; - } - } - - if(!found) - { - dprint("WARNING: spawnpoint at ", vtos(spot.origin), " could not find its target ", spot.target, "\n"); - return '-1 0 0'; - } - } - - MUTATOR_CALLHOOK(Spawn_Score); - return spawn_score; -} - -void Spawn_ScoreAll(entity firstspot, float mindist, float teamcheck) -{ - entity spot; - for(spot = firstspot; spot; spot = spot.chain) - spot.spawnpoint_score = Spawn_Score(spot, mindist, teamcheck); -} - -entity Spawn_FilterOutBadSpots(entity firstspot, float mindist, float teamcheck) -{ - entity spot, spotlist, spotlistend; - - spotlist = world; - spotlistend = world; - - Spawn_ScoreAll(firstspot, mindist, teamcheck); - - for(spot = firstspot; spot; spot = spot.chain) - { - if(spot.spawnpoint_score_x >= 0) // spawning allowed here - { - if(spotlistend) - spotlistend.chain = spot; - spotlistend = spot; - if(!spotlist) - spotlist = spot; - } - } - if(spotlistend) - spotlistend.chain = world; - - return spotlist; -} - -entity Spawn_WeightedPoint(entity firstspot, float lower, float upper, float exponent) -{ - // weight of a point: bound(lower, mindisttoplayer, upper)^exponent - // multiplied by spot.cnt (useful if you distribute many spawnpoints in a small area) - entity spot; - - RandomSelection_Init(); - for(spot = firstspot; spot; spot = spot.chain) - RandomSelection_Add(spot, 0, string_null, pow(bound(lower, spot.spawnpoint_score_y, upper), exponent) * spot.cnt, (spot.spawnpoint_score_y >= lower) * 0.5 + spot.spawnpoint_score_x); - - return RandomSelection_chosen_ent; -} - -/* -============= -SelectSpawnPoint - -Finds a point to respawn -============= -*/ -entity SelectSpawnPoint (float anypoint) -{ - float teamcheck; - entity spot, firstspot; - - spot = find (world, classname, "testplayerstart"); - if (spot) - return spot; - - if(anypoint || autocvar_g_spawn_useallspawns) - teamcheck = -1; - else if(have_team_spawns > 0) - { - if(have_team_spawns_forteam[self.team] == 0) - { - // we request a spawn for a team, and we have team - // spawns, but that team has no spawns? - if(have_team_spawns_forteam[0]) - // try noteam spawns - teamcheck = 0; - else - // if not, any spawn has to do - teamcheck = -1; - } - else - teamcheck = self.team; // MUST be team - } - else if(have_team_spawns == 0 && have_team_spawns_forteam[0]) - teamcheck = 0; // MUST be noteam - else - teamcheck = -1; - // if we get here, we either require team spawns but have none, or we require non-team spawns and have none; use any spawn then - - - // get the entire list of spots - firstspot = findchain(classname, "info_player_deathmatch"); - // filter out the bad ones - // (note this returns the original list if none survived) - if(anypoint) - { - spot = Spawn_WeightedPoint(firstspot, 1, 1, 1); - } - else - { - float mindist; - if (arena_roundbased && !g_ca) - mindist = 800; - else - mindist = 100; - firstspot = Spawn_FilterOutBadSpots(firstspot, mindist, teamcheck); - - // there is 50/50 chance of choosing a random spot or the furthest spot - // (this means that roughly every other spawn will be furthest, so you - // usually won't get fragged at spawn twice in a row) - if (random() > autocvar_g_spawn_furthest) - spot = Spawn_WeightedPoint(firstspot, 1, 1, 1); - else - spot = Spawn_WeightedPoint(firstspot, 1, 5000, 5); // chooses a far far away spawnpoint - } - - if (!spot) - { - if(autocvar_spawn_debug) - GotoNextMap(0); - else - { - if(some_spawn_has_been_used) - return world; // team can't spawn any more, because of actions of other team - else - error("Cannot find a spawn point - please fix the map!"); - } - } - - return spot; -} /* ============= @@ -378,22 +147,30 @@ void PutObserverInServer (void) error("No spawnpoints for observers?!?\n"); RemoveGrapplingHook(self); // Wazat's Grappling Hook - if(clienttype(self) == CLIENTTYPE_REAL) + if(IS_REAL_CLIENT(self)) { msg_entity = self; WriteByte(MSG_ONE, SVC_SETVIEW); WriteEntity(MSG_ONE, self); } - MUTATOR_CALLHOOK(MakePlayerObserver); + 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; - minstagib_stop_countdown(self); + MUTATOR_CALLHOOK(MakePlayerObserver); Portal_ClearAll(self); if(self.alivetime) { - if(!inWarmupStage) + if(!warmup_stage) PlayerStats_Event(self, PLAYERSTATS_ALIVETIME, time - self.alivetime); self.alivetime = 0; } @@ -406,13 +183,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 +216,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; @@ -466,7 +241,7 @@ void PutObserverInServer (void) setorigin (self, (spot.origin + PL_VIEW_OFS)); // offset it so that the spectator spawns higher off the ground, looks better this way self.prevorigin = self.origin; self.items = 0; - WEPSET_CLEAR_E(self); + self.weapons = '0 0 0'; self.model = ""; FixPlayermodel(); setmodel(self, "null"); @@ -488,45 +263,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; @@ -618,16 +354,11 @@ PutClientInServer Called when a client spawns in the server ============= */ - void PutClientInServer (void) { - if(clienttype(self) == CLIENTTYPE_BOT) - { + if(IS_BOT_CLIENT(self)) self.classname = "player"; - if(g_ca) - self.caplayer = 1; - } - else if(clienttype(self) == CLIENTTYPE_REAL) + else if(IS_REAL_CLIENT(self)) { msg_entity = self; WriteByte(MSG_ONE, SVC_SETVIEW); @@ -637,21 +368,13 @@ void PutClientInServer (void) // reset player keys self.itemkeys = 0; - // player is dead and becomes observer - // FIXME fix LMS scoring for new system - if(g_lms) - { - if(PlayerScore_Add(self, SP_LMS_RANK, 0) > 0) - 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(IS_PLAYER(self)) + { entity spot, oldself; float j; @@ -671,6 +394,9 @@ void PutClientInServer (void) RemoveGrapplingHook(self); // Wazat's Grappling Hook + if(self.vehicle) + vehicles_exit(VHEF_RELESE); + self.classname = "player"; self.wasplayer = TRUE; self.iscreature = TRUE; @@ -681,7 +407,7 @@ void PutClientInServer (void) self.dphitcontentsmask = DPCONTENTS_BODY | DPCONTENTS_SOLID; if(autocvar_g_playerclip_collisions) self.dphitcontentsmask |= DPCONTENTS_PLAYERCLIP; - if(clienttype(self) == CLIENTTYPE_BOT && autocvar_g_botclip_collisions) + if(IS_BOT_CLIENT(self) && autocvar_g_botclip_collisions) self.dphitcontentsmask |= DPCONTENTS_BOTCLIP; self.frags = FRAGS_PLAYER; if(INDEPENDENT_PLAYERS) @@ -690,10 +416,7 @@ void PutClientInServer (void) if(autocvar__notarget) self.flags |= FL_NOTARGET; self.takedamage = DAMAGE_AIM; - if(g_minstagib) - self.effects = EF_FULLBRIGHT; - else - self.effects = 0; + self.effects = 0; self.effects |= EF_TELEPORT_BIT | EF_RESTARTANIM_BIT; self.air_finished = time + 12; self.dmg = 2; @@ -704,7 +427,7 @@ void PutClientInServer (void) self.nex_charge = autocvar_g_balance_nex_charge_start; } - if(inWarmupStage) + if(warmup_stage) { self.ammo_shells = warmup_start_ammo_shells; self.ammo_nails = warmup_start_ammo_nails; @@ -713,7 +436,7 @@ void PutClientInServer (void) self.ammo_fuel = warmup_start_ammo_fuel; self.health = warmup_start_health; self.armorvalue = warmup_start_armorvalue; - WEPSET_COPY_EA(self, warmup_start_weapons); + self.weapons = warmup_start_weapons; } else { @@ -724,10 +447,10 @@ void PutClientInServer (void) self.ammo_fuel = start_ammo_fuel; self.health = start_health; self.armorvalue = start_armorvalue; - WEPSET_COPY_EA(self, start_weapons); + self.weapons = start_weapons; } - if(WEPSET_CONTAINS_ANY_EA(self, WEPBIT_SUPERWEAPONS)) // exception for minstagib, as minstanex is a superweapon + if(self.weapons & WEPSET_SUPERWEAPONS) self.superweapons_finished = time + autocvar_g_balance_superweapons_time; else self.superweapons_finished = 0; @@ -735,10 +458,10 @@ void PutClientInServer (void) if(g_weaponarena_random) { if(g_weaponarena_random_with_laser) - WEPSET_ANDNOT_EW(self, WEP_LASER); + self.weapons &= ~WEPSET_LASER; W_RandomWeapons(self, g_weaponarena_random); if(g_weaponarena_random_with_laser) - WEPSET_OR_EW(self, WEP_LASER); + self.weapons |= WEPSET_LASER; } self.items = start_items; @@ -757,7 +480,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; @@ -787,11 +512,9 @@ void PutClientInServer (void) self.oldvelocity = self.velocity; self.fire_endtime = -1; - msg_entity = self; - WRITESPECTATABLE_MSG_ONE({ - WriteByte(MSG_ONE, SVC_TEMPENTITY); - WriteByte(MSG_ONE, TE_CSQC_SPAWN); - }); + entity spawnevent = spawn(); + spawnevent.owner = self; + Net_LinkEntity(spawnevent, FALSE, 0.5, SpawnEvent_Send); self.model = ""; FixPlayermodel(); @@ -809,14 +532,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; @@ -834,22 +549,13 @@ void PutClientInServer (void) self.colormod = '1 1 1' * autocvar_g_player_brightness; self.exteriorweaponentity.alpha = default_weapon_alpha; - self.lms_nextcheck = time + autocvar_g_lms_campcheck_interval*2; - self.lms_traveled_distance = 0; self.speedrunning = FALSE; race_PostSpawn(spot); //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 @@ -890,15 +596,14 @@ void PutClientInServer (void) self.weaponname = ""; self.switchingweapon = 0; - if(!inWarmupStage) + if(!warmup_stage) if(!self.alivetime) self.alivetime = time; antilag_clear(self); - - if (autocvar_g_spawnsound) - soundat(world, self.origin, CH_TRIGGER, "misc/spawn.wav", VOL_BASE, ATTN_NORM); - } else if(self.classname == "observer") { + } + else if(IS_OBSERVER(self)) + { PutObserverInServer (); } } @@ -927,7 +632,6 @@ float ClientInit_SendEntity(entity to, float sf) else WriteString(MSG_ENTITY, ""); WriteByte(MSG_ENTITY, self.count * 255.0); // g_balance_armor_blockpercent - WriteByte(MSG_ENTITY, self.cnt * 255.0); // g_balance_weaponswitchdelay WriteCoord(MSG_ENTITY, self.bouncefactor); // g_balance_grenadelauncher_bouncefactor WriteCoord(MSG_ENTITY, self.bouncestop); // g_balance_grenadelauncher_bouncestop WriteCoord(MSG_ENTITY, self.ebouncefactor); // g_balance_grenadelauncher_bouncefactor @@ -950,11 +654,6 @@ void ClientInit_CheckUpdate() self.count = autocvar_g_balance_armor_blockpercent; self.SendFlags |= 1; } - if(self.cnt != autocvar_g_balance_weaponswitchdelay) - { - self.cnt = autocvar_g_balance_weaponswitchdelay; - self.SendFlags |= 1; - } if(self.bouncefactor != autocvar_g_balance_grenadelauncher_bouncefactor) { self.bouncefactor = autocvar_g_balance_grenadelauncher_bouncefactor; @@ -1047,14 +746,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() @@ -1113,10 +811,10 @@ void KillIndicator_Think() { if(self.cnt <= 10) setmodel(self, strcat("models/sprites/", ftos(self.cnt), ".spr32")); - if(clienttype(self.owner) == CLIENTTYPE_REAL) + if(IS_REAL_CLIENT(self.owner)) { if(self.cnt <= 10) - { Send_Notification(NOTIF_ONE, self.owner, MSG_ANNCE, Announcer_PickNumber(self.cnt)); } + { Send_Notification(NOTIF_ONE, self.owner, MSG_ANNCE, Announcer_PickNumber(CNT_KILL, self.cnt)); } } self.nextthink = time + 1; self.cnt -= 1; @@ -1157,7 +855,7 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2 self.clientkill_nexttime = time + killtime + autocvar_g_balance_kill_antispam; } - if(killtime <= 0 || self.classname != "player" || self.deadflag != DEAD_NO) + if(killtime <= 0 || !IS_PLAYER(self) || self.deadflag != DEAD_NO) { ClientKill_Now(); } @@ -1199,28 +897,28 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2 if(targetteam == 0) // just die { self.killindicator.colormod = '0 0 0'; - if(clienttype(self) == CLIENTTYPE_REAL) + if(IS_REAL_CLIENT(self)) if(self.killindicator.cnt > 0) Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_TEAMCHANGE_SUICIDE, self.killindicator.cnt); } else if(targetteam == -1) // auto { self.killindicator.colormod = '0 1 0'; - if(clienttype(self) == CLIENTTYPE_REAL) + if(IS_REAL_CLIENT(self)) if(self.killindicator.cnt > 0) Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_TEAMCHANGE_AUTO, self.killindicator.cnt); } else if(targetteam == -2) // spectate { self.killindicator.colormod = '0.5 0.5 0.5'; - if(clienttype(self) == CLIENTTYPE_REAL) + if(IS_REAL_CLIENT(self)) if(self.killindicator.cnt > 0) Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_TEAMCHANGE_SPECTATE, self.killindicator.cnt); } else { self.killindicator.colormod = Team_ColorRGB(targetteam); - if(clienttype(self) == CLIENTTYPE_REAL) + if(IS_REAL_CLIENT(self)) if(self.killindicator.cnt > 0) Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, APP_TEAM_NUM_4(targetteam, CENTER_TEAMCHANGE_), self.killindicator.cnt); } @@ -1230,19 +928,11 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2 void ClientKill (void) { - if (gameover) - 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); + if(gameover) return; + if(self.player_blocked) return; + if(self.freezetag_frozen) return; + + 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 @@ -1320,7 +1010,7 @@ void ClientConnect (void) { float t; - if(self.flags & FL_CLIENT) + if(IS_CLIENT(self)) { print("Warning: ClientConnect, but already connected!\n"); return; @@ -1361,7 +1051,7 @@ void ClientConnect (void) // identify the right forced team if(autocvar_g_campaign) { - if(clienttype(self) == CLIENTTYPE_REAL) // only players, not bots + if(IS_REAL_CLIENT(self)) // only players, not bots { switch(autocvar_g_campaign_forceteam) { @@ -1402,7 +1092,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) @@ -1428,11 +1118,11 @@ void ClientConnect (void) PlayerStats_AddEvent(sprintf("kills-%d", self.playerid)); - if(clienttype(self) == CLIENTTYPE_BOT) + if(IS_BOT_CLIENT(self)) PlayerStats_AddPlayer(self); if(autocvar_sv_eventlog) - GameLogEcho(strcat(":join:", ftos(self.playerid), ":", ftos(num_for_edict(self)), ":", ((clienttype(self) == CLIENTTYPE_REAL) ? self.netaddress : "bot"), ":", self.netname)); + GameLogEcho(strcat(":join:", ftos(self.playerid), ":", ftos(num_for_edict(self)), ":", ((IS_REAL_CLIENT(self)) ? self.netaddress : "bot"), ":", self.netname)); LogTeamchange(self.playerid, self.team, 1); @@ -1440,7 +1130,7 @@ void ClientConnect (void) self.netname_previous = strzone(self.netname); - if((self.classname == STR_PLAYER && teamplay)) + if(IS_PLAYER(self) && teamplay) Send_Notification(NOTIF_ALL, world, MSG_INFO, APP_TEAM_ENT_4(self, INFO_JOIN_CONNECT_TEAM_), self.netname); else Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_JOIN_CONNECT, self.netname); @@ -1472,13 +1162,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(); @@ -1492,7 +1175,7 @@ void ClientConnect (void) self.jointime = time; self.allowed_timeouts = autocvar_sv_timeout_number; - if(clienttype(self) == CLIENTTYPE_REAL) + if(IS_REAL_CLIENT(self)) { if(!autocvar_g_campaign) { @@ -1500,19 +1183,10 @@ void ClientConnect (void) Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, getwelcomemessage()); } - if(autocvar_g_bugrigs || WEPSET_EQ_AW(g_weaponarena_weapons, WEP_TUBA)) + if(autocvar_g_bugrigs || (g_weaponarena_weapons == WEPSET_TUBA)) 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")); @@ -1552,13 +1226,11 @@ void ClientConnect (void) CSQCMODEL_AUTOINIT(); self.model_randomizer = random(); - - if(clienttype(self) != CLIENTTYPE_REAL) - return; - - sv_notice_join(); - - MUTATOR_CALLHOOK(ClientConnect); + + if(IS_REAL_CLIENT(self)) + sv_notice_join(); + + MUTATOR_CALLHOOK(ClientConnect); } /* ============= @@ -1574,7 +1246,7 @@ void ClientDisconnect (void) if(self.vehicle) vehicles_exit(VHEF_RELESE); - if not(self.flags & FL_CLIENT) + if not(IS_CLIENT(self)) { print("Warning: ClientDisconnect without ClientConnect\n"); return; @@ -1613,7 +1285,7 @@ void ClientDisconnect (void) // Here, everything has been done that requires this player to be a client. - self.flags &~= FL_CLIENT; + self.flags &= ~FL_CLIENT; if (self.chatbubbleentity) remove (self.chatbubbleentity); @@ -1625,12 +1297,6 @@ void ClientDisconnect (void) bot_relinkplayerlist(); - if(g_arena) - { - Spawnqueue_Unmark(self); - Spawnqueue_Remove(self); - } - accuracy_free(self); ClientData_Detach(); PlayerScore_Detach(self); @@ -1737,10 +1403,10 @@ void respawn(void) void play_countdown(float finished, string samp) { - if(clienttype(self) == CLIENTTYPE_REAL) + if(IS_REAL_CLIENT(self)) if(floor(finished - time - frametime) != floor(finished - time)) if(finished - time < 6) - sound (self, CH_INFO, samp, VOL_BASE, ATTN_NORM); + sound (self, CH_INFO, samp, VOL_BASE, ATTEN_NORM); } void player_powerups (void) @@ -1751,65 +1417,17 @@ void player_powerups (void) if((self.items & IT_USING_JETPACK) && !self.deadflag) self.modelflags |= MF_ROCKET; else - self.modelflags &~= MF_ROCKET; + self.modelflags &= ~MF_ROCKET; - self.effects &~= (EF_RED | EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT | EF_FLAME | EF_NODEPTHTEST); + self.effects &= ~(EF_RED | EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT | EF_FLAME | EF_NODEPTHTEST); - if(self.alpha < 0 || self.deadflag) // don't apply the flags if the player is gibbed + if((self.alpha < 0 || self.deadflag) && !self.vehicle) // don't apply the flags if the player is gibbed return; Fire_ApplyDamage(self); Fire_ApplyEffect(self); - if (g_minstagib) - { - self.effects |= EF_FULLBRIGHT; - - if (self.items & IT_STRENGTH) - { - play_countdown(self.strength_finished, "misc/poweroff.wav"); - if (time > self.strength_finished) - { - self.alpha = default_player_alpha; - self.exteriorweaponentity.alpha = default_weapon_alpha; - self.items &~= IT_STRENGTH; - //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_INVISIBILITY, self.netname); - Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_INVISIBILITY); - } - } - else - { - if (time < self.strength_finished) - { - self.alpha = g_minstagib_invis_alpha; - self.exteriorweaponentity.alpha = g_minstagib_invis_alpha; - self.items |= IT_STRENGTH; - Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_INVISIBILITY, self.netname); - Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_INVISIBILITY); - } - } - - if (self.items & IT_INVINCIBLE) - { - play_countdown(self.invincible_finished, "misc/poweroff.wav"); - if (time > self.invincible_finished) - { - self.items = self.items - (self.items & IT_INVINCIBLE); - //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERDOWN_SPEED, self.netname); - Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERDOWN_SPEED); - } - } - else - { - if (time < self.invincible_finished) - { - self.items = self.items | IT_INVINCIBLE; - Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_POWERUP_SPEED, self.netname); - Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_POWERUP_SPEED); - } - } - } - else // if we're not in minstagib, continue. I added this else to replace the "return" which was here that broke the callhook for this function -- This code is nasty. + if not(g_minstagib) { if (self.items & IT_STRENGTH) { @@ -1853,7 +1471,7 @@ void player_powerups (void) } if (self.items & IT_SUPERWEAPON) { - if (!WEPSET_CONTAINS_ANY_EA(self, WEPBIT_SUPERWEAPONS)) + if (!(self.weapons & WEPSET_SUPERWEAPONS)) { self.superweapons_finished = 0; self.items = self.items - (self.items & IT_SUPERWEAPON); @@ -1870,13 +1488,13 @@ void player_powerups (void) if (time > self.superweapons_finished) { self.items = self.items - (self.items & IT_SUPERWEAPON); - WEPSET_ANDNOT_EA(self, WEPBIT_SUPERWEAPONS); + self.weapons &= ~WEPSET_SUPERWEAPONS; //Send_Notification(NOTIF_ALL, world, MSG_INFO, INFO_SUPERWEAPON_BROKEN, self.netname); Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_SUPERWEAPON_BROKEN); } } } - else if(WEPSET_CONTAINS_ANY_EA(self, WEPBIT_SUPERWEAPONS)) + else if(self.weapons & WEPSET_SUPERWEAPONS) { if (time < self.superweapons_finished || (self.items & IT_UNLIMITED_SUPERWEAPONS)) { @@ -1887,7 +1505,7 @@ void player_powerups (void) else { self.superweapons_finished = 0; - WEPSET_ANDNOT_EA(self, WEPBIT_SUPERWEAPONS); + self.weapons &= ~WEPSET_SUPERWEAPONS; } } else @@ -1902,15 +1520,6 @@ void player_powerups (void) if(autocvar_g_fullbrightplayers) self.effects = self.effects | EF_FULLBRIGHT; - // midair gamemode: damage only while in the air - // if in midair mode, being on ground grants temporary invulnerability - // (this is so that multishot weapon don't clear the ground flag on the - // first damage in the frame, leaving the player vulnerable to the - // remaining hits in the same frame) - if (self.flags & FL_ONGROUND) - if (g_midair) - self.spawnshieldtime = max(self.spawnshieldtime, time + autocvar_g_midair_shieldtime); - if (time >= game_starttime) if (time < self.spawnshieldtime) self.effects = self.effects | (EF_ADDITIVE | EF_FULLBRIGHT); @@ -1988,7 +1597,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)) @@ -2002,7 +1611,7 @@ void player_regen (void) } if not(self.items & IT_UNLIMITED_WEAPON_AMMO) - self.ammo_fuel = CalcRotRegen(self.ammo_fuel, minf, autocvar_g_balance_fuel_regen, autocvar_g_balance_fuel_regenlinear, regen_mod * frametime * (time > self.pauseregen_finished) * (self.items & IT_FUEL_REGEN != 0), maxf, autocvar_g_balance_fuel_rot, autocvar_g_balance_fuel_rotlinear, rot_mod * frametime * (time > self.pauserotfuel_finished), limitf); + self.ammo_fuel = CalcRotRegen(self.ammo_fuel, minf, autocvar_g_balance_fuel_regen, autocvar_g_balance_fuel_regenlinear, regen_mod * frametime * (time > self.pauseregen_finished) * ((self.items & IT_FUEL_REGEN) != 0), maxf, autocvar_g_balance_fuel_rot, autocvar_g_balance_fuel_rotlinear, rot_mod * frametime * (time > self.pauserotfuel_finished), limitf); } float zoomstate_set; @@ -2021,52 +1630,52 @@ void GetPressedKeys(void) { if (self.movement_x > 0) // get if movement keys are pressed { // forward key pressed self.pressedkeys |= KEY_FORWARD; - self.pressedkeys &~= KEY_BACKWARD; + self.pressedkeys &= ~KEY_BACKWARD; } else if (self.movement_x < 0) { // backward key pressed self.pressedkeys |= KEY_BACKWARD; - self.pressedkeys &~= KEY_FORWARD; + self.pressedkeys &= ~KEY_FORWARD; } else { // no x input - self.pressedkeys &~= KEY_FORWARD; - self.pressedkeys &~= KEY_BACKWARD; + self.pressedkeys &= ~KEY_FORWARD; + self.pressedkeys &= ~KEY_BACKWARD; } if (self.movement_y > 0) { // right key pressed self.pressedkeys |= KEY_RIGHT; - self.pressedkeys &~= KEY_LEFT; + self.pressedkeys &= ~KEY_LEFT; } else if (self.movement_y < 0) { // left key pressed self.pressedkeys |= KEY_LEFT; - self.pressedkeys &~= KEY_RIGHT; + self.pressedkeys &= ~KEY_RIGHT; } else { // no y input - self.pressedkeys &~= KEY_RIGHT; - self.pressedkeys &~= KEY_LEFT; + self.pressedkeys &= ~KEY_RIGHT; + self.pressedkeys &= ~KEY_LEFT; } if (self.BUTTON_JUMP) // get if jump and crouch keys are pressed self.pressedkeys |= KEY_JUMP; else - self.pressedkeys &~= KEY_JUMP; + self.pressedkeys &= ~KEY_JUMP; if (self.BUTTON_CROUCH) self.pressedkeys |= KEY_CROUCH; else - self.pressedkeys &~= KEY_CROUCH; + self.pressedkeys &= ~KEY_CROUCH; if (self.BUTTON_ATCK) self.pressedkeys |= KEY_ATCK; else - self.pressedkeys &~= KEY_ATCK; + self.pressedkeys &= ~KEY_ATCK; if (self.BUTTON_ATCK2) self.pressedkeys |= KEY_ATCK2; else - self.pressedkeys &~= KEY_ATCK2; + self.pressedkeys &= ~KEY_ATCK2; } /* @@ -2097,7 +1706,7 @@ void SpectateCopy(entity spectatee) { self.strength_finished = spectatee.strength_finished; self.invincible_finished = spectatee.invincible_finished; self.pressedkeys = spectatee.pressedkeys; - WEPSET_COPY_EE(self, spectatee); + self.weapons = spectatee.weapons; self.switchweapon = spectatee.switchweapon; self.switchingweapon = spectatee.switchingweapon; self.weapon = spectatee.weapon; @@ -2113,7 +1722,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); @@ -2155,7 +1763,7 @@ float SpectateUpdate() { if (self == self.enemy) return 0; - if(self.enemy.classname != "player") + if not(IS_PLAYER(self.enemy)) return 0; SpectateCopy(self.enemy); @@ -2164,6 +1772,46 @@ float SpectateUpdate() { } +float SpectateSet() +{ + 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 SpectateSet(); +} + // Returns next available player to spectate if g_ca_spectate_enemies == 0 entity CA_SpectateNext(entity start) { if (start.team == self.team) { @@ -2187,13 +1835,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); @@ -2202,38 +1847,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 SpectateSet(); +} + +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 SpectateSet(); } /* @@ -2257,13 +1913,15 @@ void ShowRespawnCountdown() { self.respawn_countdown = number - 1; if(ceil(self.respawn_time - (time + 0.5)) == number) // only say it if it is the same number even in 0.5s; to prevent overlapping sounds - Send_Notification(NOTIF_ONE, self, MSG_ANNCE, Announcer_PickNumber(number)); + { Send_Notification(NOTIF_ONE, self, MSG_ANNCE, Announcer_PickNumber(CNT_RESPAWN, number)); } } } } 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) @@ -2282,7 +1940,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 { @@ -2322,8 +1981,9 @@ float nJoinAllowed(entity ignore) { return maxclients - totalClients; float currentlyPlaying = 0; - FOR_EACH_REALPLAYER(e) - currentlyPlaying += 1; + FOR_EACH_REALCLIENT(e) + if(IS_PLAYER(e) || e.caplayer == 1) + currentlyPlaying += 1; if(currentlyPlaying < autocvar_g_maxplayers) return min(maxclients - totalClients, autocvar_g_maxplayers - currentlyPlaying); @@ -2336,7 +1996,7 @@ float nJoinAllowed(entity ignore) { * g_maxplayers_spectator_blocktime seconds */ void checkSpectatorBlock() { - if(self.classname == "spectator" || self.classname == "observer") { + if(IS_SPEC(self) || IS_OBSERVER(self)) { if( time > (self.spectatortime + autocvar_g_maxplayers_spectator_blocktime) ) { Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_QUIT_KICK_SPECTATING); dropclient(self); @@ -2349,7 +2009,7 @@ void PrintWelcomeMessage() if(self.motd_actived_time == 0) { if (autocvar_g_campaign) { - if ((self.classname == "player" && self.BUTTON_INFO) || (self.classname != "player")) { + if ((IS_PLAYER(self) && self.BUTTON_INFO) || (!IS_PLAYER(self))) { self.motd_actived_time = time; Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, campaign_message); } @@ -2365,7 +2025,7 @@ void PrintWelcomeMessage() if (autocvar_g_campaign) { if (self.BUTTON_INFO) self.motd_actived_time = time; - else if ((time - self.motd_actived_time > 2) && self.classname == "player") { // hide it some seconds after BUTTON_INFO has been released + else if ((time - self.motd_actived_time > 2) && IS_PLAYER(self)) { // hide it some seconds after BUTTON_INFO has been released self.motd_actived_time = 0; Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_MOTD); } @@ -2396,11 +2056,11 @@ void ObserverThink() float prefered_movetype; if (self.flags & FL_JUMPRELEASED) { if (self.BUTTON_JUMP && !self.version_mismatch) { - self.flags &~= FL_JUMPRELEASED; + self.flags &= ~FL_JUMPRELEASED; self.flags |= FL_SPAWNING; } else if(self.BUTTON_ATCK && !self.version_mismatch) { - self.flags &~= FL_JUMPRELEASED; - if(SpectateNext(world) == 1) { + self.flags &= ~FL_JUMPRELEASED; + if(SpectateNext()) { self.classname = "spectator"; } } else { @@ -2413,7 +2073,7 @@ void ObserverThink() self.flags |= FL_JUMPRELEASED; if(self.flags & FL_SPAWNING) { - self.flags &~= FL_SPAWNING; + self.flags &= ~FL_SPAWNING; LeaveSpectatorMode(); return; } @@ -2425,18 +2085,28 @@ void SpectatorThink() { if (self.flags & FL_JUMPRELEASED) { if (self.BUTTON_JUMP && !self.version_mismatch) { - self.flags &~= FL_JUMPRELEASED; + self.flags &= ~FL_JUMPRELEASED; self.flags |= FL_SPAWNING; - } else if(self.BUTTON_ATCK) { - self.flags &~= FL_JUMPRELEASED; - if(SpectateNext(world) == 1) { + } 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()) { + 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.flags &= ~FL_JUMPRELEASED; self.classname = "observer"; PutClientInServer(); } else { @@ -2448,7 +2118,7 @@ void SpectatorThink() self.flags |= FL_JUMPRELEASED; if(self.flags & FL_SPAWNING) { - self.flags &~= FL_SPAWNING; + self.flags &= ~FL_SPAWNING; LeaveSpectatorMode(); return; } @@ -2462,7 +2132,7 @@ void SpectatorThink() void PlayerUseKey() { - if(self.classname != "player") + if not(IS_PLAYER(self)) return; if(self.vehicle) @@ -2490,14 +2160,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 @@ -2575,10 +2241,11 @@ void PlayerPreThink (void) self.usekeypressed = self.BUTTON_USE; } - if(clienttype(self) == CLIENTTYPE_REAL) + if(IS_REAL_CLIENT(self)) PrintWelcomeMessage(); - if(self.classname == "player") { + if(IS_PLAYER(self)) + { CheckRules_Player(); @@ -2617,30 +2284,28 @@ void PlayerPreThink (void) player_powerups(); } - if (g_minstagib) - minstagib_ammocheck(); - 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; @@ -2663,7 +2328,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 @@ -2673,46 +2344,11 @@ void PlayerPreThink (void) return; } - 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; float do_crouch = self.BUTTON_CROUCH; if(self.hook.state) do_crouch = 0; - if(self.health <= g_bloodloss) - do_crouch = 1; if(self.vehicle) do_crouch = 0; if(self.freezetag_frozen) @@ -2744,15 +2380,6 @@ void PlayerPreThink (void) } } - if(self.health <= g_bloodloss && self.deadflag == DEAD_NO) - { - if(self.bloodloss_timer < time) - { - self.event_damage(self, self, 1, DEATH_ROT, self.origin, '0 0 0'); - self.bloodloss_timer = time + 0.5 + random() * 0.5; - } - } - FixPlayermodel(); GrapplingHookFrame(); @@ -2760,7 +2387,7 @@ void PlayerPreThink (void) // LordHavoc: allow firing on move frames (sub-ticrate), this gives better timing on slow servers //if(frametime) { - self.items &~= self.items_added; + self.items &= ~self.items_added; W_WeaponFrame(); @@ -2780,9 +2407,6 @@ void PlayerPreThink (void) if(frametime) player_anim(); - - if(g_nexball) - nexball_setstatus(); // secret status secrets_setstatus(); @@ -2794,9 +2418,9 @@ void PlayerPreThink (void) if (intermission_running) IntermissionThink (); // otherwise a button could be missed between return; - } else if(self.classname == "observer") { + } else if(IS_OBSERVER(self)) { ObserverThink(); - } else if(self.classname == "spectator") { + } else if(IS_SPEC(self)) { SpectatorThink(); } @@ -2805,9 +2429,9 @@ void PlayerPreThink (void) float oldspectatee_status; oldspectatee_status = self.spectatee_status; - if(self.classname == "spectator") + if(IS_SPEC(self)) self.spectatee_status = num_for_edict(self.enemy); - else if(self.classname == "observer") + else if(IS_OBSERVER(self)) self.spectatee_status = num_for_edict(self); else self.spectatee_status = 0; @@ -2891,11 +2515,16 @@ void PlayerPostThink (void) stuffcmd(self, strcat("name ", self.netname, substring(ftos(random()), 2, -1), "\n")); } - if(sv_maxidle && frametime) // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero). + if(sv_maxidle > 0 && frametime) // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero). + if(IS_PLAYER(self) || sv_maxidle_spectatorsareidle) { if (time - self.parm_idlesince < 1) // instead of (time == self.parm_idlesince) to support sv_maxidle <= 10 { - if(self.idlekick_lasttimeleft) { self.idlekick_lasttimeleft = 0; } + if(self.idlekick_lasttimeleft) + { + self.idlekick_lasttimeleft = 0; + Kill_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER_CPID, CPID_IDLING); + } } else { @@ -2915,7 +2544,7 @@ void PlayerPostThink (void) else if(timeleft <= 10) { if(timeleft != self.idlekick_lasttimeleft) - Send_Notification(NOTIF_ONE, self, MSG_ANNCE, Announcer_PickNumber(timeleft)); + { Send_Notification(NOTIF_ONE, self, MSG_ANNCE, Announcer_PickNumber(CNT_IDLE, timeleft)); } self.idlekick_lasttimeleft = timeleft; } } @@ -2932,7 +2561,7 @@ void PlayerPostThink (void) //CheckPlayerJump(); - if(self.classname == "player") { + if(IS_PLAYER(self)) { CheckRules_Player(); UpdateChatBubble(); if (self.impulse)