X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_client.qc;h=e6f0433c4e9eefc196bd7230db425506630af3fe;hb=5119ca4560e0c9864b4a88c91297a43e41947cc2;hp=40039ead81f107743a38a78b3a58be2ea38ba6cd;hpb=fb3dd670570afd2a2896108f02f4c85dd6b4b55c;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index 40039ead8..e6f0433c4 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -123,7 +123,7 @@ void spawnpoint_use() // Returns: // _x: prio (-1 if unusable) // _y: weight -vector Spawn_Score(entity spot, entity playerlist, float teamcheck, float anypoint) +vector Spawn_Score(entity spot, float mindist, float teamcheck) { float shortest, thisdist; float prio; @@ -151,55 +151,37 @@ vector Spawn_Score(entity spot, entity playerlist, float teamcheck, float anypoi 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 good, found; + float found; found = 0; - good = 0; for(ent = world; (ent = find(ent, targetname, spot.target)); ) { ++found; - if(ent.classname == "target_objective") - { - if(ent.health < 0 || ent.health >= ASSAULT_VALUE_INACTIVE) - continue; - } - else if(ent.classname == "trigger_race_checkpoint") + if(ent.spawn_evalfunc) { - if(!anypoint) // spectators may spawn everywhere - { - if(g_race_qualifying) - { - // spawn at first - if(ent.race_checkpoint != 0) - continue; - if(spot.race_place != race_lowest_place_spawn) - continue; - } - else - { - if(ent.race_checkpoint != self.race_respawn_checkpoint) - continue; - // try reusing the previous spawn - if(ent == self.race_respawn_spotref || spot == self.race_respawn_spotref) - prio += 1; - if(ent.race_checkpoint == 0) - { - float pl; - pl = self.race_place; - if(pl > race_highest_place_spawn) - pl = 0; - if(pl == 0 && !self.race_started) - pl = race_highest_place_spawn; // use last place if he has not even touched finish yet - if(spot.race_place != pl) - continue; - } - } - } + entity oldself = self; + self = ent; + spawn_score = ent.spawn_evalfunc(oldself, spot, spawn_score); + self = oldself; + if(spawn_score_x < 0) + return spawn_score; } - ++good; } if(!found) @@ -207,95 +189,42 @@ vector Spawn_Score(entity spot, entity playerlist, float teamcheck, float anypoi dprint("WARNING: spawnpoint at ", vtos(spot.origin), " could not find its target ", spot.target, "\n"); return '-1 0 0'; } - - if(good < found) // at least one was bad - return '-1 0 0'; } - player = playerlist; - shortest = vlen(world.maxs - world.mins); - for(player = playerlist; player; player = player.chain) - if (player != self) - { - thisdist = vlen(player.origin - spot.origin); - if (thisdist < shortest) - shortest = thisdist; - } - return prio * '1 0 0' + shortest * '0 1 0'; + MUTATOR_CALLHOOK(Spawn_Score); + return spawn_score; } -float spawn_allbad; -float spawn_allgood; -entity Spawn_FilterOutBadSpots(entity firstspot, entity playerlist, float mindist, float teamcheck, float anypoint) +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; - spawn_allgood = TRUE; - spawn_allbad = TRUE; spotlist = world; spotlistend = world; + Spawn_ScoreAll(firstspot, mindist, teamcheck); + for(spot = firstspot; spot; spot = spot.chain) { - spot.spawnpoint_score = Spawn_Score(spot, playerlist, teamcheck, anypoint); - - if(autocvar_spawn_debugview) - { - setmodel(spot, "models/runematch/rune.mdl"); - if(spot.spawnpoint_score_y < mindist) - { - spot.colormod = '1 0 0'; - spot.scale = 1; - } - else - { - spot.colormod = '0 1 0'; - spot.scale = spot.spawnpoint_score_y / mindist; - } - } - if(spot.spawnpoint_score_x >= 0) // spawning allowed here { - if(spot.spawnpoint_score_y < mindist) - { - // too short distance - spawn_allgood = FALSE; - } - else - { - // perfect - spawn_allbad = FALSE; - - if(spotlistend) - spotlistend.chain = spot; - spotlistend = spot; - if(!spotlist) - spotlist = spot; - - /* - if(teamcheck >= 0) - if(spot.team != teamcheck) - error("invalid spawn added"); - - print("added ", etos(spot), "\n"); - */ - } + if(spotlistend) + spotlistend.chain = spot; + spotlistend = spot; + if(!spotlist) + spotlist = spot; } } if(spotlistend) spotlistend.chain = world; - /* - entity e; - if(teamcheck >= 0) - for(e = spotlist; e; e = e.chain) - { - print("seen ", etos(e), "\n"); - if(e.team != teamcheck) - error("invalid spawn found"); - } - */ - return spotlist; } @@ -322,8 +251,7 @@ Finds a point to respawn entity SelectSpawnPoint (float anypoint) { float teamcheck; - entity firstspot_new; - entity spot, firstspot, playerlist; + entity spot, firstspot; spot = find (world, classname, "testplayerstart"); if (spot) @@ -354,8 +282,6 @@ entity SelectSpawnPoint (float anypoint) // 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 list of players - playerlist = findchain(classname, "player"); // get the entire list of spots firstspot = findchain(classname, "info_player_deathmatch"); // filter out the bad ones @@ -366,42 +292,26 @@ entity SelectSpawnPoint (float anypoint) } else { - firstspot_new = Spawn_FilterOutBadSpots(firstspot, playerlist, 100, teamcheck, anypoint); - if(!firstspot_new) - firstspot_new = Spawn_FilterOutBadSpots(firstspot, playerlist, -1, teamcheck, anypoint); - firstspot = firstspot_new; + 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 (arena_roundbased && !g_ca) - { - firstspot_new = Spawn_FilterOutBadSpots(firstspot, playerlist, 800, teamcheck, anypoint); - if(firstspot_new) - firstspot = firstspot_new; - spot = Spawn_WeightedPoint(firstspot, 1, 1, 1); - } - else if (random() > autocvar_g_spawn_furthest) + 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(autocvar_spawn_debugview) - { - print("spot mindistance: ", vtos(spot.spawnpoint_score), "\n"); - - entity e; - if(teamcheck >= 0) - for(e = firstspot; e; e = e.chain) - if(e.team != teamcheck) - error("invalid spawn found"); - } - if (!spot) { if(autocvar_spawn_debug) - GotoNextMap(); + GotoNextMap(0); else { if(some_spawn_has_been_used) @@ -431,160 +341,36 @@ string CheckPlayerModel(string plyermodel) { // to change a cvar default, we'll have a small leak here. FallbackPlayerModel = strzone(cvar_defstring("_cl_playermodel")); } - if(strlen(plyermodel) < 4) - return FallbackPlayerModel; + // only in right path if( substring(plyermodel,0,14) != "models/player/") return FallbackPlayerModel; - else if(autocvar_sv_servermodelsonly) + // only good file extensions + if(substring(plyermodel,-4,4) != ".zym") + if(substring(plyermodel,-4,4) != ".dpm") + if(substring(plyermodel,-4,4) != ".iqm") + if(substring(plyermodel,-4,4) != ".md3") + if(substring(plyermodel,-4,4) != ".psk") + return FallbackPlayerModel; + // forbid the LOD models + if(substring(plyermodel, -9,5) == "_lod1") + return FallbackPlayerModel; + if(substring(plyermodel, -9,5) == "_lod2") + return FallbackPlayerModel; + if(plyermodel != strtolower(plyermodel)) + return FallbackPlayerModel; + // also, restrict to server models + if(autocvar_sv_servermodelsonly) { - if(substring(plyermodel,-4,4) != ".zym") - if(substring(plyermodel,-4,4) != ".dpm") - if(substring(plyermodel,-4,4) != ".iqm") - if(substring(plyermodel,-4,4) != ".md3") - if(substring(plyermodel,-4,4) != ".psk") - return FallbackPlayerModel; - // forbid the LOD models - if(substring(plyermodel, -9,5) == "_lod1") - return FallbackPlayerModel; - if(substring(plyermodel, -9,5) == "_lod2") - return FallbackPlayerModel; - if(plyermodel != strtolower(plyermodel)) - return FallbackPlayerModel; if(!fexists(plyermodel)) return FallbackPlayerModel; } return plyermodel; } -/* -============= -Client_customizeentityforclient - -LOD reduction -============= -*/ -void Client_uncustomizeentityforclient() +void setplayermodel(entity e, string modelname) { - if(self.modelindex == 0) // no need to uncustomize then - return; - self.modelindex = self.modelindex_lod0; - self.skin = self.skinindex; -} - -float Client_customizeentityforclient() -{ - entity modelsource; - - if(self.modelindex == 0) - return TRUE; - - // forcemodel stuff - -#ifdef PROFILING - float t0; - t0 = gettime(GETTIME_HIRES); // reference -#endif - - modelsource = self; - -#ifdef ALLOW_FORCEMODELS - if(other.cvar_cl_forceplayermodelsfromxonotic) - if not(self.modelindex_lod0_from_xonotic) - modelsource = other; - if(other.cvar_cl_forceplayermodels && sv_clforceplayermodels) - modelsource = other; -#endif - - self.skin = modelsource.skinindex; - -#if 0 - if(modelsource == self) - self.skin = modelsource.skinindex; - else - self.skin = mod(modelsource.skinindex, 3); // forbid the fbskins as forced skins -#endif - - // self: me - // other: the player viewing me - float distance; - float f; - - if(other.cvar_cl_playerdetailreduction <= 0) - { - if(other.cvar_cl_playerdetailreduction <= -2) - self.modelindex = modelsource.modelindex_lod2; - else if(other.cvar_cl_playerdetailreduction <= -1) - self.modelindex = modelsource.modelindex_lod1; - else - self.modelindex = modelsource.modelindex_lod0; - } - else - { - distance = vlen(self.origin - other.origin); - f = (distance + 100.0) * other.cvar_cl_playerdetailreduction; - if(f > sv_loddistance2) - self.modelindex = modelsource.modelindex_lod2; - else if(f > sv_loddistance1) - self.modelindex = modelsource.modelindex_lod1; - else - self.modelindex = modelsource.modelindex_lod0; - } - -#ifdef PROFILING - float t1; - t1 = gettime(GETTIME_HIRES); // reference - client_cefc_accumulator += (t1 - t0); -#endif - - return TRUE; -} - -void setmodel_lod(entity e, string modelname) -{ - string s; - - if(sv_loddistance1) - { - // FIXME: this only supports 3-letter extensions - s = strcat(substring(modelname, 0, strlen(modelname)-4), "_lod1", substring(modelname, -4, 4)); - if(fexists(s)) - { - setmodel(e, s); // players have high precision - self.modelindex_lod1 = self.modelindex; - } - else - self.modelindex_lod1 = -1; - - s = strcat(substring(modelname, 0, strlen(modelname)-4), "_lod2", substring(modelname, -4, 4)); - if(fexists(s)) - { - setmodel(e, s); // players have high precision - self.modelindex_lod2 = self.modelindex; - } - else - self.modelindex_lod2 = -1; - - precache_model(modelname); - setmodel(e, modelname); // players have high precision - self.modelindex_lod0 = self.modelindex; - - if(self.modelindex_lod1 < 0) - self.modelindex_lod1 = self.modelindex; - - if(self.modelindex_lod2 < 0) - self.modelindex_lod2 = self.modelindex; - } - else - { - precache_model(modelname); - setmodel(e, modelname); // players have high precision - self.modelindex_lod0 = self.modelindex; - // save it for possible player model forcing - } - - s = whichpack(self.model); - self.modelindex_lod0_from_xonotic = ((s == "") || (substring(s, 0, 4) == "data")); - + precache_model(modelname); + setmodel(e, modelname); player_setupanimsformodel(); UpdatePlayerSounds(); } @@ -670,7 +456,7 @@ void PutObserverInServer (void) self.health = -666; self.takedamage = DAMAGE_NO; self.solid = SOLID_NOT; - self.movetype = MOVETYPE_FLY_WORLDONLY; //(self.cvar_cl_clippedspectating ? MOVETYPE_NOCLIP : MOVETYPE_FLY); // it's too early for this anyway, lets just set it in playerprethink + self.movetype = MOVETYPE_FLY_WORLDONLY; // user preference is controlled by playerprethink self.flags = FL_CLIENT | FL_NOTARGET; self.armorvalue = 666; self.effects = 0; @@ -680,7 +466,6 @@ void PutObserverInServer (void) self.pauseregen_finished = 0; self.damageforcescale = 0; self.death_time = 0; - self.dead_frame = 0; self.alpha = 0; self.scale = 0; self.fade_time = 0; @@ -699,16 +484,18 @@ void PutObserverInServer (void) self.fixangle = TRUE; self.crouch = FALSE; - self.view_ofs = '0 0 0'; // so that your view doesn't go into the ceiling with MOVETYPE_FLY_WORLDONLY, previously "PL_VIEW_OFS" - setorigin (self, spot.origin); - setsize (self, PL_CROUCH_MIN, PL_CROUCH_MAX); // give the spectator some space between walls for MOVETYPE_FLY_WORLDONLY + 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; self.weapons = 0; self.model = ""; FixPlayermodel(); - self.model = ""; - self.modelindex = 0; + setmodel(self, "null"); + self.drawonlytoclient = self; + + setsize (self, PL_CROUCH_MIN, PL_CROUCH_MAX); // give the spectator some space between walls for MOVETYPE_FLY_WORLDONLY + self.view_ofs = '0 0 0'; // so that your view doesn't go into the ceiling with MOVETYPE_FLY_WORLDONLY, previously "PL_VIEW_OFS" + self.weapon = 0; self.weaponname = ""; self.switchingweapon = 0; @@ -723,9 +510,6 @@ void PutObserverInServer (void) self.oldvelocity = self.velocity; self.fire_endtime = -1; - if(sv_loddistance1) - SetCustomizer(self, Client_customizeentityforclient, Client_uncustomizeentityforclient); - if(g_arena) { if(self.version_mismatch) @@ -799,42 +583,35 @@ void FixPlayermodel() } } - if(self.modelindex == 0 && self.deadflag == DEAD_NO) - { - if(self.model != "") - bprint("\{1}^1Player ", self.netname, "^1 has a zero modelindex, trying to fix...\n"); - self.model = ""; // force the != checks to return true - } - if(defaultmodel != "") { if (defaultmodel != self.model) { m1 = self.mins; m2 = self.maxs; - setmodel_lod (self, defaultmodel); + setplayermodel (self, defaultmodel); setsize (self, m1, m2); chmdl = TRUE; } - oldskin = self.skinindex; - self.skinindex = defaultskin; + oldskin = self.skin; + self.skin = defaultskin; } else { if (self.playermodel != self.model || self.playermodel == "") { self.playermodel = CheckPlayerModel(self.playermodel); // this is never "", so no endless loop m1 = self.mins; m2 = self.maxs; - setmodel_lod (self, self.playermodel); + setplayermodel (self, self.playermodel); setsize (self, m1, m2); chmdl = TRUE; } - oldskin = self.skinindex; - self.skinindex = stof(self.playerskin); + oldskin = self.skin; + self.skin = stof(self.playerskin); } - if(chmdl || oldskin != self.skinindex) + if(chmdl || oldskin != self.skin) self.species = player_getspecies(); // model or skin has changed if(!teamplay) @@ -939,6 +716,7 @@ void PutClientInServer (void) self.effects = EF_FULLBRIGHT; else self.effects = 0; + self.effects |= EF_TELEPORT_BIT | EF_RESTARTANIM_BIT; self.air_finished = time + 12; self.dmg = 2; if(autocvar_g_balance_nex_charge) @@ -981,7 +759,6 @@ void PutClientInServer (void) } self.items = start_items; - self.jump_interval = time; self.spawnshieldtime = time + autocvar_g_spawnshieldtime; self.pauserotarmor_finished = time + autocvar_g_balance_pause_armor_rot_spawn; @@ -997,8 +774,6 @@ void PutClientInServer (void) } self.damageforcescale = 2; self.death_time = 0; - self.dead_frame = 0; - self.alpha = 0; self.scale = 0; self.fade_time = 0; self.pain_frame = 0; @@ -1036,11 +811,9 @@ void PutClientInServer (void) WriteByte(MSG_ONE, TE_CSQC_SPAWN); }); - if(sv_loddistance1) - SetCustomizer(self, Client_customizeentityforclient, Client_uncustomizeentityforclient); - self.model = ""; FixPlayermodel(); + self.drawonlytoclient = world; self.crouch = FALSE; self.view_ofs = PL_VIEW_OFS; @@ -1086,12 +859,6 @@ void PutClientInServer (void) race_PostSpawn(spot); - if(autocvar_spawn_debug) - { - sprint(self, strcat("spawnpoint origin: ", vtos(spot.origin), "\n")); - remove(spot); // usefull for checking if there are spawnpoints, that let drop through the floor - } - //stuffcmd(self, "chase_active 0"); //stuffcmd(self, "set viewsize $tmpviewsize \n"); @@ -1130,8 +897,15 @@ void PutClientInServer (void) activator = world; self = oldself; + spawn_spot = spot; MUTATOR_CALLHOOK(PlayerSpawn); + if(autocvar_spawn_debug) + { + sprint(self, strcat("spawnpoint origin: ", vtos(spot.origin), "\n")); + remove(spot); // usefull for checking if there are spawnpoints, that let drop through the floor + } + self.switchweapon = w_getbestweapon(self); self.cnt = -1; // W_LastWeapon will not complain self.weapon = 0; @@ -1140,6 +914,8 @@ void PutClientInServer (void) if(!self.alivetime) self.alivetime = time; + + antilag_clear(self); } else if(self.classname == "observer" || (g_ca && !allowed_to_spawn)) { PutObserverInServer (); } @@ -1336,7 +1112,7 @@ void KillIndicator_Think() return; } - if (!self.owner.modelindex) + if (self.owner.alpha < 0) { self.owner.killindicator = world; remove(self); @@ -1396,13 +1172,13 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2 if(!self.killindicator) { - if(self.modelindex && self.deadflag == DEAD_NO) + if(self.deadflag == DEAD_NO) { killtime = max(killtime, self.clientkill_nexttime - time); self.clientkill_nexttime = time + killtime + autocvar_g_balance_kill_antispam; } - if(killtime <= 0 || !self.modelindex || self.deadflag != DEAD_NO) + if(killtime <= 0 || self.classname != "player" || self.deadflag != DEAD_NO) { ClientKill_Now(); } @@ -1724,8 +1500,6 @@ void ClientConnect (void) else stuffcmd(self, "set _teams_available 0\n"); - stuffcmd(self, strcat("set gametype ", ftos(game), "\n")); - if(g_arena || g_ca) { self.classname = "observer"; @@ -1748,7 +1522,7 @@ void ClientConnect (void) } self.jointime = time; - self.allowedTimeouts = autocvar_sv_timeout_number; + self.allowed_timeouts = autocvar_sv_timeout_number; if(clienttype(self) == CLIENTTYPE_REAL) { @@ -1810,6 +1584,8 @@ void ClientConnect (void) if(!autocvar_g_campaign) Send_CSQC_Centerprint_Generic(self, CPID_MOTD, getwelcomemessage(), autocvar_welcome_message_time, 0); + CSQCMODEL_AUTOINIT(); + self.model_randomizer = random(); } @@ -1918,7 +1694,7 @@ void ClientDisconnect (void) void ChatBubbleThink() { self.nextthink = time; - if (!self.owner.modelindex || self.owner.chatbubbleentity != self) + if ((self.owner.alpha < 0) || self.owner.chatbubbleentity != self) { if(self.owner) // but why can that ever be world? self.owner.chatbubbleentity = world; @@ -1937,7 +1713,7 @@ void ChatBubbleThink() void UpdateChatBubble() { - if (!self.modelindex) + if (self.alpha < 0) return; // spawn a chatbubble entity if needed if (!self.chatbubbleentity) @@ -1977,7 +1753,7 @@ void UpdateChatBubble() .float oldcolormap; void respawn(void) { - if(self.modelindex != 0 && autocvar_g_respawn_ghosts) + if(self.alpha >= 0 && autocvar_g_respawn_ghosts) { self.solid = SOLID_NOT; self.takedamage = DAMAGE_NO; @@ -2026,9 +1802,9 @@ void player_powerups (void) self.modelflags &~= MF_ROCKET; } - self.effects &~= (EF_DIMLIGHT | 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.modelindex || self.deadflag) // don't apply the flags if the player is gibbed + if(self.alpha < 0 || self.deadflag) // don't apply the flags if the player is gibbed return; Fire_ApplyDamage(self); @@ -2063,7 +1839,7 @@ void player_powerups (void) if (self.items & IT_INVINCIBLE) { play_countdown(self.invincible_finished, "misc/poweroff.wav"); - if (time > self.invincible_finished && autocvar_g_balance_powerup_timer) + if (time > self.invincible_finished) { self.items = self.items - (self.items & IT_INVINCIBLE); sprint(self, "^3Speed has worn off\n"); @@ -2084,7 +1860,7 @@ void player_powerups (void) { play_countdown(self.strength_finished, "misc/poweroff.wav"); self.effects = self.effects | (EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT); - if (time > self.strength_finished && autocvar_g_balance_powerup_timer) + if (time > self.strength_finished) { self.items = self.items - (self.items & IT_STRENGTH); sprint(self, "^3Strength has worn off\n"); @@ -2102,7 +1878,7 @@ void player_powerups (void) { play_countdown(self.invincible_finished, "misc/poweroff.wav"); self.effects = self.effects | (EF_RED | EF_ADDITIVE | EF_FULLBRIGHT); - if (time > self.invincible_finished && autocvar_g_balance_powerup_timer) + if (time > self.invincible_finished) { self.items = self.items - (self.items & IT_INVINCIBLE); sprint(self, "^3Shield has worn off\n"); @@ -2116,26 +1892,26 @@ void player_powerups (void) sprint(self, "^3Shield surrounds you\n"); } } + } + + if(autocvar_g_nodepthtestplayers) + self.effects = self.effects | EF_NODEPTHTEST; - if(autocvar_g_nodepthtestplayers) - self.effects = self.effects | EF_NODEPTHTEST; + if(autocvar_g_fullbrightplayers) + self.effects = self.effects | EF_FULLBRIGHT; - 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); - // 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); - } + if (time >= game_starttime) + if (time < self.spawnshieldtime) + self.effects = self.effects | (EF_ADDITIVE | EF_FULLBRIGHT); MUTATOR_CALLHOOK(PlayerPowerups); } @@ -2821,7 +2597,7 @@ void PlayerPreThink (void) } //don't allow the player to turn around while game is paused! - if(timeoutStatus == 2) { + if(timeout_status == TIMEOUT_ACTIVE) { // FIXME turn this into CSQC stuff self.v_angle = self.lastV_angle; self.angles = self.lastV_angle; @@ -2830,42 +2606,26 @@ void PlayerPreThink (void) if(frametime) { - if(self.health <= 0 && autocvar_g_deathglow) - { - if(self.glowmod_x > 0) - self.glowmod_x -= autocvar_g_deathglow * frametime; - else - self.glowmod_x = -1; - if(self.glowmod_y > 0) - self.glowmod_y -= autocvar_g_deathglow * frametime; - else - self.glowmod_y = -1; - if(self.glowmod_z > 0) - self.glowmod_z -= autocvar_g_deathglow * frametime; - else - self.glowmod_z = -1; - } - else +#ifndef NO_LEGACY_NETWORKING + self.glowmod = colormapPaletteColor(self.clientcolors & 0x0F, TRUE) * 2; +#endif + + if(self.weapon == WEP_NEX && autocvar_g_balance_nex_charge) { - // set weapon and player glowmod - self.glowmod = colormapPaletteColor(self.clientcolors & 0x0F, TRUE) * 2; + self.weaponentity_glowmod_x = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_animlimit); + self.weaponentity_glowmod_y = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_animlimit); + self.weaponentity_glowmod_z = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_animlimit); - if(self.weapon == WEP_NEX && autocvar_g_balance_nex_charge) + if(self.nex_charge > autocvar_g_balance_nex_charge_animlimit) { - self.weaponentity_glowmod_x = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_animlimit); - self.weaponentity_glowmod_y = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_animlimit); - self.weaponentity_glowmod_z = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_half * min(1, self.nex_charge / autocvar_g_balance_nex_charge_animlimit); - - if(self.nex_charge > autocvar_g_balance_nex_charge_animlimit) - { - self.weaponentity_glowmod_x = self.weaponentity_glowmod_x + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_full * (self.nex_charge - autocvar_g_balance_nex_charge_animlimit) / (1 - autocvar_g_balance_nex_charge_animlimit); - self.weaponentity_glowmod_y = self.weaponentity_glowmod_y + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_full * (self.nex_charge - autocvar_g_balance_nex_charge_animlimit) / (1 - autocvar_g_balance_nex_charge_animlimit); - self.weaponentity_glowmod_z = self.weaponentity_glowmod_z + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_full * (self.nex_charge - autocvar_g_balance_nex_charge_animlimit) / (1 - autocvar_g_balance_nex_charge_animlimit); - } + self.weaponentity_glowmod_x = self.weaponentity_glowmod_x + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_full * (self.nex_charge - autocvar_g_balance_nex_charge_animlimit) / (1 - autocvar_g_balance_nex_charge_animlimit); + self.weaponentity_glowmod_y = self.weaponentity_glowmod_y + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_full * (self.nex_charge - autocvar_g_balance_nex_charge_animlimit) / (1 - autocvar_g_balance_nex_charge_animlimit); + self.weaponentity_glowmod_z = self.weaponentity_glowmod_z + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_full * (self.nex_charge - autocvar_g_balance_nex_charge_animlimit) / (1 - autocvar_g_balance_nex_charge_animlimit); } - else - self.weaponentity_glowmod = self.glowmod; } + else + self.weaponentity_glowmod = colormapPaletteColor(self.clientcolors & 0x0F, TRUE) * 2; + player_powerups(); } @@ -3157,10 +2917,8 @@ void PlayerPostThink (void) stuffcmd(self, strcat("name ", self.netname, substring(ftos(random()), 2, -1), "\n")); } - if(sv_maxidle && frametime) + if(sv_maxidle && frametime) // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero). { - // WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero). - float timeleft; if (time - self.parm_idlesince < 1) // instead of (time == self.parm_idlesince) to support sv_maxidle <= 10 { if(self.idlekick_lasttimeleft) @@ -3168,34 +2926,37 @@ void PlayerPostThink (void) Send_CSQC_Centerprint_Generic_Expire(self, CPID_DISCONNECT_IDLING); self.idlekick_lasttimeleft = 0; } - return; - } - timeleft = ceil(sv_maxidle - (time - self.parm_idlesince)); - if(timeleft == min(10, sv_maxidle - 1)) // - 1 to support sv_maxidle <= 10 - { - if(!self.idlekick_lasttimeleft) - Send_CSQC_Centerprint_Generic(self, CPID_DISCONNECT_IDLING, "^3Stop idling!\n^3Disconnecting in %d seconds...", 1, timeleft); - } - if(timeleft <= 0) - { - bprint("^3", self.netname, "^3 was kicked for idling.\n"); - AnnounceTo(self, "terminated"); - dropclient(self); - return; } - else if(timeleft <= 10) + else { - if(timeleft != self.idlekick_lasttimeleft) - AnnounceTo(self, ftos(timeleft)); - self.idlekick_lasttimeleft = timeleft; + float timeleft; + timeleft = ceil(sv_maxidle - (time - self.parm_idlesince)); + if(timeleft == min(10, sv_maxidle - 1)) // - 1 to support sv_maxidle <= 10 + { + if(!self.idlekick_lasttimeleft) + Send_CSQC_Centerprint_Generic(self, CPID_DISCONNECT_IDLING, "^3Stop idling!\n^3Disconnecting in %d seconds...", 1, timeleft); + } + if(timeleft <= 0) + { + bprint("^3", self.netname, "^3 was kicked for idling.\n"); + AnnounceTo(self, "terminated"); + dropclient(self); + return; + } + else if(timeleft <= 10) + { + if(timeleft != self.idlekick_lasttimeleft) + AnnounceTo(self, ftos(timeleft)); + self.idlekick_lasttimeleft = timeleft; + } } } #ifdef TETRIS if(self.impulse == 100) ImpulseCommands(); - if (TetrisPostFrame()) - return; + if (!TetrisPostFrame()) + { #endif CheatFrame(); @@ -3216,6 +2977,10 @@ void PlayerPostThink (void) //do nothing } +#ifdef TETRIS + } +#endif + /* float i; for(i = 0; i < 1000; ++i) @@ -3278,4 +3043,6 @@ void PlayerPostThink (void) if(g_race) dprint(sprintf("%f %.6f\n", time, race_GetFractionalLapCount(self))); */ + + CSQCMODEL_AUTOUPDATE(); }