X-Git-Url: http://de.git.xonotic.org/?a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_client.qc;h=d3d14a5cfb5118b180e52eeaf1e7a148897cf779;hb=6794689f122acf95658dd7378155b9dee5293921;hp=0cc6a0b65d745e6a0b784ecbf3fa362714df8a5e;hpb=201f6309c92217b63dc34daf004fbb7424096eca;p=xonotic%2Fxonotic-data.pk3dir.git diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index 0cc6a0b65..d3d14a5cf 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -23,9 +23,12 @@ #include "bot/navigation.qh" #include "../common/ent_cs.qh" -#include "../common/vehicles/all.qh" +#include "../common/state.qh" + #include "../common/triggers/teleporters.qh" +#include "../common/vehicles/all.qh" + #include "weapons/hitplot.qh" #include "weapons/weaponsystem.qh" @@ -186,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; @@ -299,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) { @@ -438,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) @@ -617,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; @@ -630,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? @@ -638,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); @@ -656,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() @@ -679,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() @@ -963,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) @@ -1000,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") )); } @@ -1016,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)) @@ -1045,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(); @@ -1132,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); @@ -1234,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); @@ -1615,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)) @@ -1664,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; @@ -1687,10 +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; - self.weapon_nextthink = spectatee.weapon_nextthink; + 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; @@ -1751,7 +1743,7 @@ bool SpectateUpdate() return false; } - SpectateCopy(self.enemy); + SpectateCopy(this, this.enemy); return true; } @@ -2013,7 +2005,7 @@ void ObserverThink() {SELFPARAM(); if ( self.impulse ) { - MinigameImpulse(self.impulse); + MinigameImpulse(self, self.impulse); self.impulse = 0; } float prefered_movetype; @@ -2048,7 +2040,7 @@ void SpectatorThink() {SELFPARAM(); if ( self.impulse ) { - if(MinigameImpulse(self.impulse)) + if(MinigameImpulse(self, self.impulse)) self.impulse = 0; } if (self.flags & FL_JUMPRELEASED) { @@ -2148,8 +2140,6 @@ void PlayerUseKey() } -void wglow_send(entity actor, vector g); - /* ============= PlayerPreThink @@ -2325,28 +2315,6 @@ void PlayerPreThink () if(frametime) { - vector g; - if (IS_SPEC(self)) - { - g = self.enemy.weaponentity_glowmod; - } - else if(self.weapon == WEP_VORTEX.m_id && WEP_CVAR(vortex, charge)) - { - g.x = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_half * min(1, self.vortex_charge / WEP_CVAR(vortex, charge_animlimit)); - g.y = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_half * min(1, self.vortex_charge / WEP_CVAR(vortex, charge_animlimit)); - g.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)) - { - g.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)); - g.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)); - g.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 - g = colormapPaletteColor(self.clientcolors & 0x0F, true) * 2; - if (g != self.weaponentity_glowmod) - wglow_send(self, self.weaponentity_glowmod = g); player_powerups(); } @@ -2428,7 +2396,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) @@ -2503,19 +2471,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) @@ -2523,31 +2498,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 @@ -2599,10 +2593,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();