X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_client.qc;h=6c3e2ec0c5860c7759d95c156501781d65d16948;hb=c26d994a788be2bc2eadf6891da23916cf428311;hp=24a63d5aab0e8823b07b5fec3eb73dba70528d7c;hpb=e9f30b97435c6afe3d6911f21e1f4fd1b97e93da;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index 24a63d5aa..6c3e2ec0c 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -3,7 +3,6 @@ #include "anticheat.qh" #include "cl_impulse.qh" #include "cl_player.qh" -#include "ent_cs.qh" #include "ipban.qh" #include "miscfunctions.qh" #include "portals.qh" @@ -23,14 +22,18 @@ #include "bot/bot.qh" #include "bot/navigation.qh" -#include "../common/vehicles/all.qh" +#include "../common/ent_cs.qh" +#include "../common/state.qh" + #include "../common/triggers/teleporters.qh" +#include "../common/vehicles/all.qh" + #include "weapons/hitplot.qh" #include "weapons/weaponsystem.qh" #include "../common/net_notice.qh" -#include "../common/physics.qh" +#include "../common/physics/player.qh" #include "../common/items/all.qc" @@ -175,7 +178,6 @@ void setplayermodel(entity e, string modelname) precache_model(modelname); _setmodel(e, modelname); player_setupanimsformodel(); - UpdatePlayerSounds(e); } /* @@ -187,7 +189,9 @@ putting a client as observer in the server */ void FixPlayermodel(entity player); void PutObserverInServer() -{SELFPARAM(); +{ + SELFPARAM(); + PlayerState_detach(this); entity spot; self.hud = HUD_NORMAL; @@ -300,9 +304,9 @@ void PutObserverInServer() 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; + PS(self).m_weapon = WEP_Null; self.weaponname = ""; - self.switchingweapon = 0; + PS(self).m_switchingweapon = WEP_Null; self.weaponmodel = ""; for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { @@ -405,7 +409,6 @@ void FixPlayermodel(entity player) if(chmdl || oldskin != player.skin) // model or skin has changed { player.species = player_getspecies(player); // update species - UpdatePlayerSounds(player); // update skin sounds } if(!teamplay) @@ -440,6 +443,7 @@ void PutClientInServer() if (IS_OBSERVER(this)) { PutObserverInServer(); } else if (IS_PLAYER(this)) { + PlayerState_attach(this); accuracy_resend(this); if (this.team < 0) @@ -572,8 +576,6 @@ void PutClientInServer() this.bot_attack = true; this.monster_attack = true; - this.spider_slowness = 0; - this.BUTTON_ATCK = this.BUTTON_JUMP = this.BUTTON_ATCK2 = false; if (this.killcount == FRAGS_SPECTATOR) { @@ -621,11 +623,11 @@ void PutClientInServer() remove(spot); // usefull for checking if there are spawnpoints, that let drop through the floor } - this.switchweapon = w_getbestweapon(this); + PS(this).m_switchweapon = w_getbestweapon(this); this.cnt = -1; // W_LastWeapon will not complain - this.weapon = 0; + PS(this).m_weapon = WEP_Null; this.weaponname = ""; - this.switchingweapon = 0; + PS(this).m_switchingweapon = WEP_Null; if (!warmup_stage && !this.alivetime) this.alivetime = time; @@ -634,6 +636,8 @@ void PutClientInServer() } } +void ClientInit_misc(); + .float ebouncefactor, ebouncestop; // electro's values // TODO do we need all these fields, or should we stop autodetecting runtime // changes and just have a console command to update this? @@ -642,7 +646,15 @@ bool ClientInit_SendEntity(entity this, entity to, int sf) WriteHeader(MSG_ENTITY, _ENT_CLIENT_INIT); return = true; msg_entity = to; + // MSG_INIT replacement + // TODO: make easier to use Registry_send_all(); + W_PROP_reload(MSG_ONE, to); + ClientInit_misc(); + MUTATOR_CALLHOOK(Ent_Init); +} +void ClientInit_misc() +{ int channel = MSG_ONE; WriteHeader(channel, ENT_CLIENT_INIT); WriteByte(channel, g_nexball_meter_period * 32); @@ -660,19 +672,8 @@ bool ClientInit_SendEntity(entity this, entity to, int sf) else WriteString(channel, ""); WriteByte(channel, self.count * 255.0); // g_balance_armor_blockpercent - WriteCoord(channel, self.bouncefactor); // g_balance_mortar_bouncefactor // WEAPONTODO - WriteCoord(channel, self.bouncestop); // g_balance_mortar_bouncestop - WriteCoord(channel, self.ebouncefactor); // g_balance_mortar_bouncefactor - WriteCoord(channel, self.ebouncestop); // g_balance_mortar_bouncestop - WriteByte(channel, WEP_CVAR(vortex, secondary)); // client has to know if it should zoom or not // WEAPONTODO - WriteByte(channel, WEP_CVAR(rifle, secondary)); // client has to know if it should zoom or not // WEAPONTODO WriteByte(channel, serverflags); // client has to know if it should zoom or not - WriteByte(channel, WEP_CVAR(minelayer, limit)); // minelayer max mines // WEAPONTODO - WriteByte(channel, WEP_CVAR_SEC(hagar, load_max)); // hagar max loadable rockets // WEAPONTODO WriteCoord(channel, autocvar_g_trueaim_minrange); - WriteByte(channel, WEP_CVAR(porto, secondary)); // WEAPONTODO - - MUTATOR_CALLHOOK(Ent_Init); } void ClientInit_CheckUpdate() @@ -683,26 +684,6 @@ void ClientInit_CheckUpdate() self.count = autocvar_g_balance_armor_blockpercent; self.SendFlags |= 1; } - if(self.bouncefactor != autocvar_g_balance_mortar_bouncefactor) // WEAPONTODO - { - self.bouncefactor = autocvar_g_balance_mortar_bouncefactor; - self.SendFlags |= 1; - } - if(self.bouncestop != autocvar_g_balance_mortar_bouncestop) - { - self.bouncestop = autocvar_g_balance_mortar_bouncestop; - self.SendFlags |= 1; - } - if(self.ebouncefactor != autocvar_g_balance_electro_secondary_bouncefactor) - { - self.ebouncefactor = autocvar_g_balance_electro_secondary_bouncefactor; - self.SendFlags |= 1; - } - if(self.ebouncestop != autocvar_g_balance_electro_secondary_bouncestop) - { - self.ebouncestop = autocvar_g_balance_electro_secondary_bouncestop; - self.SendFlags |= 1; - } } void ClientInit_Spawn() @@ -967,6 +948,8 @@ void FixClientCvars(entity e) stuffcmd(e, "cl_cmd settemp cl_prydoncursor_notrace 0\n"); if(autocvar_sv_gentle) stuffcmd(e, "cl_cmd settemp cl_gentle 1\n"); + + MUTATOR_CALLHOOK(FixClientCvars, e); } float PlayerInIDList(entity p, string idlist) @@ -1004,7 +987,7 @@ void ClientPreConnect () { GameLogEcho(sprintf(":connect:%d:%d:%s", self.playerid, - num_for_edict(self), + etof(self), ((IS_REAL_CLIENT(self)) ? self.netaddress : "bot") )); } @@ -1020,7 +1003,9 @@ Called when a client connects to the server */ void DecodeLevelParms (); void ClientConnect () -{SELFPARAM(); +{ + SELFPARAM(); + ClientState_attach(this); float t; if(IS_CLIENT(self)) @@ -1049,7 +1034,8 @@ void ClientConnect () player_count = 0; } - if(IS_REAL_CLIENT(self)) { PlayerStats_PlayerBasic_CheckUpdate(self); } + // TODO: xonstat elo.txt support, until then just 404s + if(false && IS_REAL_CLIENT(self)) { PlayerStats_PlayerBasic_CheckUpdate(self); } PlayerScore_Attach(self); ClientData_Attach(); @@ -1136,7 +1122,7 @@ void ClientConnect () PlayerStats_GameReport_AddPlayer(self); if(autocvar_sv_eventlog) - GameLogEcho(strcat(":join:", ftos(self.playerid), ":", ftos(num_for_edict(self)), ":", ((IS_REAL_CLIENT(self)) ? self.netaddress : "bot"), ":", self.netname)); + GameLogEcho(strcat(":join:", ftos(self.playerid), ":", ftos(etof(self)), ":", ((IS_REAL_CLIENT(self)) ? self.netaddress : "bot"), ":", self.netname)); LogTeamchange(self.playerid, self.team, 1); @@ -1180,7 +1166,7 @@ void ClientConnect () else stuffcmd(self, "set _teams_available 0\n"); - attach_entcs(self); + entcs_attach(self); bot_relinkplayerlist(); @@ -1201,7 +1187,7 @@ void ClientConnect () Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, getwelcomemessage()); } - if(autocvar_g_bugrigs || (g_weaponarena_weapons == WEPSET(TUBA))) + if(g_weaponarena_weapons == WEPSET(TUBA)) stuffcmd(self, "cl_cmd settemp chase_active 1\n"); } @@ -1220,7 +1206,7 @@ void ClientConnect () self.model_randomizer = random(); if(IS_REAL_CLIENT(self)) - sv_notice_join(); + sv_notice_join(self); for (entity e = world; (e = findfloat(e, init_for_player_needed, 1)); ) { WITH(entity, self, e, e.init_for_player(this)); @@ -1238,7 +1224,9 @@ Called when a client disconnects from the server .entity chatbubbleentity; void ReadyCount(); void ClientDisconnect () -{SELFPARAM(); +{ + SELFPARAM(); + ClientState_detach(this); if(self.vehicle) vehicles_exit(VHEF_RELEASE); @@ -1266,7 +1254,7 @@ void ClientDisconnect () bot_clientdisconnect(); - detach_entcs(self); + entcs_detach(self); if(autocvar_sv_eventlog) GameLogEcho(strcat(":part:", ftos(self.playerid))); @@ -1307,8 +1295,6 @@ void ClientDisconnect () if(self.weaponorder_byimpulse) strunzone(self.weaponorder_byimpulse); - ClearPlayerSounds(self); - if(self.personal) remove(self.personal); @@ -1621,7 +1607,8 @@ void player_regen () { if(self.vehicle) vehicles_exit(VHEF_RELEASE); - self.event_damage(self, self, 1, DEATH_ROT.m_id, self.origin, '0 0 0'); + if(self.event_damage) + self.event_damage(self, self, 1, DEATH_ROT.m_id, self.origin, '0 0 0'); } if (!(self.items & IT_UNLIMITED_WEAPON_AMMO)) @@ -1670,8 +1657,8 @@ spectate mode routines ====================== */ -void SpectateCopy(entity spectatee) -{SELFPARAM(); +void SpectateCopy(entity this, entity spectatee) +{ MUTATOR_CALLHOOK(SpectateCopy, spectatee, self); self.armortype = spectatee.armortype; self.armorvalue = spectatee.armorvalue; @@ -1693,9 +1680,9 @@ void SpectateCopy(entity spectatee) self.invincible_finished = spectatee.invincible_finished; self.pressedkeys = spectatee.pressedkeys; self.weapons = spectatee.weapons; - self.switchweapon = spectatee.switchweapon; - self.switchingweapon = spectatee.switchingweapon; - self.weapon = spectatee.weapon; + PS(self).m_switchweapon = PS(spectatee).m_switchweapon; + PS(self).m_switchingweapon = PS(spectatee).m_switchingweapon; + PS(self).m_weapon = PS(spectatee).m_weapon; self.vortex_charge = spectatee.vortex_charge; self.vortex_chargepool_ammo = spectatee.vortex_chargepool_ammo; self.hagar_load = spectatee.hagar_load; @@ -1756,7 +1743,7 @@ bool SpectateUpdate() return false; } - SpectateCopy(self.enemy); + SpectateCopy(this, this.enemy); return true; } @@ -1880,7 +1867,7 @@ void LeaveSpectatorMode() {SELFPARAM(); if(self.caplayer) return; - if(nJoinAllowed(self)) + if(nJoinAllowed(self, self)) { if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || (self.wasplayer && autocvar_g_changeteam_banned) || self.team_forced > 0) { @@ -1914,40 +1901,39 @@ void LeaveSpectatorMode() * it checks whether the number of currently playing players exceeds g_maxplayers. * @return int number of free slots for players, 0 if none */ -float nJoinAllowed(entity ignore) -{SELFPARAM(); +bool nJoinAllowed(entity this, entity ignore) +{ if(!ignore) // this is called that way when checking if anyone may be able to join (to build qcstatus) // so report 0 free slots if restricted { if(autocvar_g_forced_team_otherwise == "spectate") - return 0; + return false; if(autocvar_g_forced_team_otherwise == "spectator") - return 0; + return false; } - if(self.team_forced < 0) - return 0; // forced spectators can never join + if(this.team_forced < 0) + return false; // forced spectators can never join // TODO simplify this - entity e; - float totalClients = 0; - FOR_EACH_CLIENT(e) - if(e != ignore) - totalClients += 1; + int totalClients = 0; + int currentlyPlaying = 0; + FOREACH_CLIENT(true, LAMBDA( + if(it != ignore) + ++totalClients; + if(IS_REAL_CLIENT(it)) + if(IS_PLAYER(it) || it.caplayer) + ++currentlyPlaying; + )); if (!autocvar_g_maxplayers) return maxclients - totalClients; - float currentlyPlaying = 0; - FOR_EACH_REALCLIENT(e) - if(IS_PLAYER(e) || e.caplayer) - currentlyPlaying += 1; - if(currentlyPlaying < autocvar_g_maxplayers) return min(maxclients - totalClients, autocvar_g_maxplayers - currentlyPlaying); - return 0; + return false; } /** @@ -2018,7 +2004,7 @@ void ObserverThink() {SELFPARAM(); if ( self.impulse ) { - MinigameImpulse(self.impulse); + MinigameImpulse(self, self.impulse); self.impulse = 0; } float prefered_movetype; @@ -2053,7 +2039,7 @@ void SpectatorThink() {SELFPARAM(); if ( self.impulse ) { - if(MinigameImpulse(self.impulse)) + if(MinigameImpulse(self, self.impulse)) self.impulse = 0; } if (self.flags & FL_JUMPRELEASED) { @@ -2328,22 +2314,6 @@ void PlayerPreThink () if(frametime) { - if(self.weapon == WEP_VORTEX.m_id && WEP_CVAR(vortex, charge)) - { - self.weaponentity_glowmod_x = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_half * min(1, self.vortex_charge / WEP_CVAR(vortex, charge_animlimit)); - self.weaponentity_glowmod_y = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_half * min(1, self.vortex_charge / WEP_CVAR(vortex, charge_animlimit)); - self.weaponentity_glowmod_z = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_half * min(1, self.vortex_charge / WEP_CVAR(vortex, charge_animlimit)); - - if(self.vortex_charge > WEP_CVAR(vortex, charge_animlimit)) - { - self.weaponentity_glowmod_x = self.weaponentity_glowmod.x + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_full * (self.vortex_charge - WEP_CVAR(vortex, charge_animlimit)) / (1 - WEP_CVAR(vortex, charge_animlimit)); - self.weaponentity_glowmod_y = self.weaponentity_glowmod.y + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_full * (self.vortex_charge - WEP_CVAR(vortex, charge_animlimit)) / (1 - WEP_CVAR(vortex, charge_animlimit)); - self.weaponentity_glowmod_z = self.weaponentity_glowmod.z + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_full * (self.vortex_charge - WEP_CVAR(vortex, charge_animlimit)) / (1 - WEP_CVAR(vortex, charge_animlimit)); - } - } - else - self.weaponentity_glowmod = colormapPaletteColor(self.clientcolors & 0x0F, true) * 2; - player_powerups(); } @@ -2425,7 +2395,7 @@ void PlayerPreThink () // WEAPONTODO: THIS SHIT NEEDS TO GO EVENTUALLY // It cannot be predicted by the engine! .entity weaponentity = weaponentities[0]; // TODO: unhardcode - if((self.weapon == WEP_SHOCKWAVE.m_id || self.weapon == WEP_SHOTGUN.m_id) && self.(weaponentity).wframe == WFRAME_FIRE2 && time < self.(weaponentity).weapon_nextthink) + if((PS(self).m_weapon == WEP_SHOCKWAVE || PS(self).m_weapon == WEP_SHOTGUN) && self.(weaponentity).wframe == WFRAME_FIRE2 && time < self.(weaponentity).weapon_nextthink) do_crouch = 0; if (do_crouch) @@ -2433,8 +2403,8 @@ void PlayerPreThink () if (!self.crouch) { self.crouch = true; - self.view_ofs = self.stat_pl_crouch_view_ofs; - setsize (self, self.stat_pl_crouch_min, self.stat_pl_crouch_max); + self.view_ofs = STAT(PL_CROUCH_VIEW_OFS, self); + setsize (self, STAT(PL_CROUCH_MIN, self), STAT(PL_CROUCH_MAX, self)); // setanim(self, self.anim_duck, false, true, true); // this anim is BROKEN anyway } } @@ -2442,12 +2412,12 @@ void PlayerPreThink () { if (self.crouch) { - tracebox(self.origin, self.stat_pl_min, self.stat_pl_max, self.origin, false, self); + tracebox(self.origin, STAT(PL_MIN, self), STAT(PL_MAX, self), self.origin, false, self); if (!trace_startsolid) { self.crouch = false; - self.view_ofs = self.stat_pl_view_ofs; - setsize (self, self.stat_pl_min, self.stat_pl_max); + self.view_ofs = STAT(PL_VIEW_OFS, self); + setsize (self, STAT(PL_MIN, self), STAT(PL_MAX, self)); } } } @@ -2500,19 +2470,26 @@ void PlayerPreThink () // WEAPONTODO: Add weapon request for this if(!zoomstate_set) - SetZoomState(self.BUTTON_ZOOM || self.BUTTON_ZOOMSCRIPT || (self.BUTTON_ATCK2 && self.weapon == WEP_VORTEX.m_id) || (self.BUTTON_ATCK2 && self.weapon == WEP_RIFLE.m_id && WEP_CVAR(rifle, secondary) == 0)); // WEAPONTODO + SetZoomState( + self.BUTTON_ZOOM + || self.BUTTON_ZOOMSCRIPT + || (self.BUTTON_ATCK2 && PS(self).m_weapon == WEP_VORTEX) + || (self.BUTTON_ATCK2 && PS(self).m_weapon == WEP_RIFLE && WEP_CVAR(rifle, secondary) == 0) + ); // WEAPONTODO float oldspectatee_status; oldspectatee_status = self.spectatee_status; if(IS_SPEC(self)) - self.spectatee_status = num_for_edict(self.enemy); + self.spectatee_status = etof(self.enemy); else if(IS_OBSERVER(self)) - self.spectatee_status = num_for_edict(self); + self.spectatee_status = etof(self); else self.spectatee_status = 0; if(self.spectatee_status != oldspectatee_status) { ClientData_Touch(self); + if(g_race || g_cts) + race_InitSpectator(); } if(self.teamkill_soundtime) @@ -2520,31 +2497,50 @@ void PlayerPreThink () { self.teamkill_soundtime = 0; - setself(self.teamkill_soundsource); - entity oldpusher = self.pusher; - self.pusher = this; - - PlayerSound(playersound_teamshoot, CH_VOICE, VOICETYPE_LASTATTACKER_ONLY); - - self.pusher = oldpusher; - setself(this); + entity e = self.teamkill_soundsource; + entity oldpusher = e.pusher; + e.pusher = this; + PlayerSound(e, playersound_teamshoot, CH_VOICE, VOICETYPE_LASTATTACKER_ONLY); + e.pusher = oldpusher; } if(self.taunt_soundtime) if(time > self.taunt_soundtime) { self.taunt_soundtime = 0; - PlayerSound(playersound_taunt, CH_VOICE, VOICETYPE_AUTOTAUNT); + PlayerSound(self, playersound_taunt, CH_VOICE, VOICETYPE_AUTOTAUNT); } target_voicescript_next(self); // WEAPONTODO: Move into weaponsystem somehow // if a player goes unarmed after holding a loaded weapon, empty his clip size and remove the crosshair ammo ring - if(!self.weapon) + if (PS(self).m_weapon == WEP_Null) self.clip_load = self.clip_size = 0; } +void DrownPlayer(entity this) +{ + if(this.deadflag != DEAD_NO) + return; + + if (this.waterlevel != WATERLEVEL_SUBMERGED) + { + if(this.air_finished < time) + PlayerSound(this, playersound_gasp, CH_PLAYER, VOICETYPE_PLAYERSOUND); + this.air_finished = time + autocvar_g_balance_contents_drowndelay; + this.dmg = 2; + } + else if (this.air_finished < time) + { // drown! + if (this.pain_finished < time) + { + Damage (this, world, world, autocvar_g_balance_contents_playerdamage_drowning * autocvar_g_balance_contents_damagerate, DEATH_DROWN.m_id, this.origin, '0 0 0'); + this.pain_finished = time + 0.5; + } + } +} + /* ============= PlayerPostThink @@ -2596,10 +2592,11 @@ void PlayerPostThink () //CheckPlayerJump(); if(IS_PLAYER(self)) { + DrownPlayer(self); CheckRules_Player(); UpdateChatBubble(); if (self.impulse) - ImpulseCommands(); + ImpulseCommands(self); if (intermission_running) return; // intermission or finale GetPressedKeys();