X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fcl_client.qc;h=71efa5f9d931233f32899305692f023ceaea5d96;hp=f0a615a236e0a50c8f76e5dee981adf771cc5c33;hb=a97b89297fa91ae42b9d56c262662eb34ede3e45;hpb=a97f97fea293089f2e7b6c26304d4355a649cde3 diff --git a/qcsrc/server/cl_client.qc b/qcsrc/server/cl_client.qc index f0a615a236..71efa5f9d9 100644 --- a/qcsrc/server/cl_client.qc +++ b/qcsrc/server/cl_client.qc @@ -1,7 +1,5 @@ #include "cl_client.qh" -#include "waypointsprites.qh" - #include "anticheat.qh" #include "cl_impulse.qh" #include "cl_player.qh" @@ -25,7 +23,7 @@ #include "bot/bot.qh" #include "bot/navigation.qh" -#include "vehicles/vehicle.qh" +#include "../common/vehicles/all.qh" #include "weapons/hitplot.qh" #include "weapons/weaponsystem.qh" @@ -35,10 +33,14 @@ #include "../common/items/all.qc" +#include "../common/mutators/mutator/waypoints/all.qh" + #include "../common/triggers/subs.qh" #include "../common/triggers/triggers.qh" #include "../common/triggers/trigger/secret.qh" +#include "../common/minigames/sv_minigames.qh" + #include "../common/items/inventory.qh" #include "../common/monsters/sv_monsters.qh" @@ -51,7 +53,7 @@ void send_CSQC_teamnagger() { WriteByte(MSG_BROADCAST, TE_CSQC_TEAMNAGGER); } -float ClientData_Send(entity to, int sf) +bool ClientData_Send(entity this, entity to, int sf) { if(to != self.owner) { @@ -92,14 +94,14 @@ float ClientData_Send(entity to, int sf) } void ClientData_Attach() -{ +{SELFPARAM(); Net_LinkEntity(self.clientdata = spawn(), false, 0, ClientData_Send); self.clientdata.drawonlytoclient = self; self.clientdata.owner = self; } void ClientData_Detach() -{ +{SELFPARAM(); remove(self.clientdata); self.clientdata = world; } @@ -170,7 +172,7 @@ string CheckPlayerModel(string plyermodel) { void setplayermodel(entity e, string modelname) { precache_model(modelname); - setmodel(e, modelname); + _setmodel(e, modelname); player_setupanimsformodel(); UpdatePlayerSounds(); } @@ -184,11 +186,11 @@ putting a client as observer in the server */ void FixPlayermodel(); void PutObserverInServer (void) -{ +{SELFPARAM(); entity spot; self.hud = HUD_NORMAL; - if(IS_PLAYER(self)) { Send_Effect("spawn_event_neutral", self.origin, '0 0 0', 1); } + if(IS_PLAYER(self)) { Send_Effect(EFFECT_SPAWN_NEUTRAL, self.origin, '0 0 0', 1); } spot = SelectSpawnPoint (true); if(!spot) @@ -197,13 +199,13 @@ void PutObserverInServer (void) if(IS_REAL_CLIENT(self)) { - Item_ItemsTime_SetTimesForPlayer(self); msg_entity = self; WriteByte(MSG_ONE, SVC_SETVIEW); WriteEntity(MSG_ONE, self); } self.frags = FRAGS_SPECTATOR; + self.bot_attack = false; MUTATOR_CALLHOOK(MakePlayerObserver); @@ -219,7 +221,7 @@ void PutObserverInServer (void) } if(self.vehicle) - vehicles_exit(VHEF_RELESE); + vehicles_exit(VHEF_RELEASE); WaypointSprite_PlayerDead(); @@ -291,7 +293,7 @@ void PutObserverInServer (void) self.weapons = '0 0 0'; self.model = ""; FixPlayermodel(); - setmodel(self, "null"); + setmodel(self, MDL_Null); self.drawonlytoclient = self; setsize (self, PL_CROUCH_MIN, PL_CROUCH_MAX); // give the spectator some space between walls for MOVETYPE_FLY_WORLDONLY @@ -315,7 +317,7 @@ void PutObserverInServer (void) .float model_randomizer; void FixPlayermodel() -{ +{SELFPARAM(); string defaultmodel; float defaultskin, chmdl, oldskin, n, i; vector m1, m2; @@ -328,9 +330,8 @@ void FixPlayermodel() { if(teamplay) { - string s; - s = Static_Team_ColorName_Lower(self.team); - if(s != "neutral") + string s = Static_Team_ColorName_Lower(self.team); + if (s != "neutral") { defaultmodel = cvar_string(strcat("sv_defaultplayermodel_", s)); defaultskin = cvar(strcat("sv_defaultplayerskin_", s)); @@ -361,6 +362,10 @@ void FixPlayermodel() } } + MUTATOR_CALLHOOK(FixPlayermodel, defaultmodel, defaultskin); + defaultmodel = ret_string; + defaultskin = ret_int; + if(defaultmodel != "") { if (defaultmodel != self.model) @@ -401,15 +406,11 @@ void FixPlayermodel() setcolor(self, stof(autocvar_sv_defaultplayercolors)); } -/* -============= -PutClientInServer -Called when a client spawns in the server -============= -*/ -void PutClientInServer (void) +/** Called when a client spawns in the server */ +void PutClientInServer() { + SELFPARAM(); if(IS_BOT_CLIENT(self)) self.classname = "player"; else if(IS_REAL_CLIENT(self)) @@ -431,7 +432,7 @@ void PutClientInServer (void) if(IS_PLAYER(self)) { - entity spot, oldself; + entity spot; accuracy_resend(self); @@ -447,9 +448,6 @@ 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; @@ -465,7 +463,7 @@ void PutClientInServer (void) self.frags = FRAGS_PLAYER; if(INDEPENDENT_PLAYERS) MAKE_INDEPENDENT_PLAYER(self); - self.flags = FL_CLIENT; + self.flags = FL_CLIENT | FL_PICKUPITEMS; if(autocvar__notarget) self.flags |= FL_NOTARGET; self.takedamage = DAMAGE_AIM; @@ -510,16 +508,13 @@ void PutClientInServer (void) else self.superweapons_finished = 0; - if(!warmup_stage) - Item_ItemsTime_ResetTimesForPlayer(self); - if(g_weaponarena_random) // WEAPONTODO: more stuff that should be in a mutator. also: rename those cvars { if(g_weaponarena_random_with_blaster) - self.weapons &= ~WEPSET_BLASTER; + self.weapons &= ~WEPSET(BLASTER); W_RandomWeapons(self, g_weaponarena_random); if(g_weaponarena_random_with_blaster) - self.weapons |= WEPSET_BLASTER; + self.weapons |= WEPSET(BLASTER); } self.items = start_items; @@ -610,7 +605,7 @@ void PutClientInServer (void) self.killcount = 0; } - CL_SpawnWeaponentity(); + CL_SpawnWeaponentity(self); self.alpha = default_player_alpha; self.colormod = '1 1 1' * autocvar_g_player_brightness; self.exteriorweaponentity.alpha = default_weapon_alpha; @@ -625,7 +620,8 @@ void PutClientInServer (void) // reset fields the weapons may use for (int j = WEP_FIRST; j <= WEP_LAST; ++j) { - WEP_ACTION(j, WR_RESETPLAYER); + Weapon w = get_weaponinfo(j); + w.wr_resetplayer(w); // all weapons must be fully loaded when we spawn entity e = get_weaponinfo(j); @@ -633,16 +629,12 @@ void PutClientInServer (void) self.(weapon_load[j]) = e.reloading_ammo; } - oldself = self; - self = spot; - activator = oldself; - string s; - s = self.target; - self.target = string_null; - SUB_UseTargets(); - self.target = s; - activator = world; - self = oldself; + string s = spot.target; + spot.target = string_null; + activator = self; + WITH(entity, self, spot, SUB_UseTargets()); + activator = world; + spot.target = s; Unfreeze(self); @@ -675,7 +667,7 @@ void PutClientInServer (void) .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? -float ClientInit_SendEntity(entity to, int sf) +bool ClientInit_SendEntity(entity this, entity to, int sf) { WriteByte(MSG_ENTITY, ENT_CLIENT_INIT); WriteByte(MSG_ENTITY, g_nexball_meter_period * 32); @@ -708,7 +700,7 @@ float ClientInit_SendEntity(entity to, int sf) } void ClientInit_CheckUpdate() -{ +{SELFPARAM(); self.nextthink = time; if(self.count != autocvar_g_balance_armor_blockpercent) { @@ -738,18 +730,13 @@ void ClientInit_CheckUpdate() } void ClientInit_Spawn() -{ - entity o; - entity e; - e = spawn(); +{SELFPARAM(); + entity e = spawn(); e.classname = "clientinit"; e.think = ClientInit_CheckUpdate; Net_LinkEntity(e, false, 0, ClientInit_SendEntity); - o = self; - self = e; - ClientInit_CheckUpdate(); - self = o; + WITH(entity, self, e, ClientInit_CheckUpdate()); } /* @@ -769,7 +756,7 @@ SetChangeParms ============= */ void SetChangeParms (void) -{ +{SELFPARAM(); // save parms for level change parm1 = self.parm_idlesince - time; } @@ -780,7 +767,7 @@ DecodeLevelParms ============= */ void DecodeLevelParms (void) -{ +{SELFPARAM(); // load parms self.parm_idlesince = parm1; if(self.parm_idlesince == -(86400 * 366)) @@ -800,7 +787,7 @@ Called when a client types 'kill' in the console .float clientkill_nexttime; void ClientKill_Now_TeamChange() -{ +{SELFPARAM(); if(self.killindicator_teamchange == -1) { JoinBestTeam( self, false, true ); @@ -817,10 +804,10 @@ void ClientKill_Now_TeamChange() } void ClientKill_Now() -{ +{SELFPARAM(); if(self.vehicle) { - vehicles_exit(VHEF_RELESE); + vehicles_exit(VHEF_RELEASE); if(!self.killindicator_teamchange) { self.vehicle_health = -1; @@ -842,7 +829,7 @@ void ClientKill_Now() // now I am sure the player IS dead } void KillIndicator_Think() -{ +{SELFPARAM(); if (gameover) { self.owner.killindicator = world; @@ -859,8 +846,7 @@ void KillIndicator_Think() if(self.cnt <= 0) { - self = self.owner; - ClientKill_Now(); // no oldself needed + WITH(entity, self, self.owner, ClientKill_Now()); return; } else if(g_cts && self.health == 1) // health == 1 means that it's silent @@ -871,7 +857,7 @@ void KillIndicator_Think() else { if(self.cnt <= 10) - setmodel(self, strcat("models/sprites/", ftos(self.cnt), ".spr32")); + setmodel(self, MDL_NUM(self.cnt)); if(IS_REAL_CLIENT(self.owner)) { if(self.cnt <= 10) @@ -884,7 +870,7 @@ void KillIndicator_Think() float clientkilltime; void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2 = spec -{ +{SELFPARAM(); float killtime; float starttime; entity e; @@ -988,7 +974,7 @@ void ClientKill_TeamChange (float targetteam) // 0 = don't change, -1 = auto, -2 } void ClientKill (void) -{ +{SELFPARAM(); if(gameover) return; if(self.player_blocked) return; if(self.frozen) return; @@ -1049,7 +1035,7 @@ Called once (not at each match start) when a client begins a connection to the s ============= */ void ClientPreConnect (void) -{ +{SELFPARAM(); if(autocvar_sv_eventlog) { GameLogEcho(sprintf(":connect:%d:%d:%s", @@ -1069,15 +1055,13 @@ Called when a client connects to the server ============= */ void DecodeLevelParms (void); -//void dom_player_join_team(entity pl); -void set_dom_state(entity e); void ClientConnect (void) -{ +{SELFPARAM(); float t; if(IS_CLIENT(self)) { - print("Warning: ClientConnect, but already connected!\n"); + LOG_INFO("Warning: ClientConnect, but already connected!\n"); return; } @@ -1097,7 +1081,7 @@ void ClientConnect (void) if(player_count<0) { - dprint("BUG player count is lower than zero, this cannot happen!\n"); + LOG_TRACE("BUG player count is lower than zero, this cannot happen!\n"); player_count = 0; } @@ -1232,7 +1216,7 @@ void ClientConnect (void) else stuffcmd(self, "set _teams_available 0\n"); - attach_entcs(); + attach_entcs(self); bot_relinkplayerlist(); @@ -1253,7 +1237,7 @@ void ClientConnect (void) Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, getwelcomemessage()); } - if(autocvar_g_bugrigs || (g_weaponarena_weapons == WEPSET_TUBA)) + if(autocvar_g_bugrigs || (g_weaponarena_weapons == WEPSET(TUBA))) stuffcmd(self, "cl_cmd settemp chase_active 1\n"); } @@ -1267,7 +1251,7 @@ void ClientConnect (void) CheatInitClient(); - CSQCMODEL_AUTOINIT(); + CSQCMODEL_AUTOINIT(self); self.model_randomizer = random(); @@ -1275,10 +1259,7 @@ void ClientConnect (void) sv_notice_join(); for (entity e = world; (e = findfloat(e, init_for_player_needed, 1)); ) { - entity oldself = self; - self = e; - e.init_for_player(oldself); - self = oldself; + WITH(entity, self, e, e.init_for_player(this)); } MUTATOR_CALLHOOK(ClientConnect, self); @@ -1293,19 +1274,22 @@ Called when a client disconnects from the server .entity chatbubbleentity; void ReadyCount(); void ClientDisconnect (void) -{ +{SELFPARAM(); if(self.vehicle) - vehicles_exit(VHEF_RELESE); + vehicles_exit(VHEF_RELEASE); if (!IS_CLIENT(self)) { - print("Warning: ClientDisconnect without ClientConnect\n"); + LOG_INFO("Warning: ClientDisconnect without ClientConnect\n"); return; } PlayerStats_GameReport_FinalizePlayer(self); - if(IS_PLAYER(self)) { Send_Effect("spawn_event_neutral", self.origin, '0 0 0', 1); } + if ( self.active_minigame ) + part_minigame(self); + + if(IS_PLAYER(self)) { Send_Effect(EFFECT_SPAWN_NEUTRAL, self.origin, '0 0 0', 1); } CheatShutdownClient(); @@ -1318,8 +1302,7 @@ void ClientDisconnect (void) bot_clientdisconnect(); - if(self.entcs) - detach_entcs(); + detach_entcs(self); if(autocvar_sv_eventlog) GameLogEcho(strcat(":part:", ftos(self.playerid))); @@ -1374,7 +1357,7 @@ void ClientDisconnect (void) .float BUTTON_CHAT; void ChatBubbleThink() -{ +{SELFPARAM(); self.nextthink = time; if ((self.owner.alpha < 0) || self.owner.chatbubbleentity != self) { @@ -1383,18 +1366,24 @@ void ChatBubbleThink() remove(self); return; } - if ((self.owner.BUTTON_CHAT && !self.owner.deadflag) -#ifdef TETRIS - || self.owner.tetris_on -#endif - ) - self.model = self.mdl; - else - self.model = ""; + + self.mdl = ""; + + if ( !self.owner.deadflag && IS_PLAYER(self.owner) ) + { + if ( self.owner.active_minigame ) + self.mdl = "models/sprites/minigame_busy.iqm"; + else if ( self.owner.BUTTON_CHAT ) + self.mdl = "models/misc/chatbubble.spr"; + } + + if ( self.model != self.mdl ) + _setmodel(self, self.mdl); + } void UpdateChatBubble() -{ +{SELFPARAM(); if (self.alpha < 0) return; // spawn a chatbubble entity if needed @@ -1405,12 +1394,12 @@ void UpdateChatBubble() self.chatbubbleentity.exteriormodeltoclient = self; self.chatbubbleentity.think = ChatBubbleThink; self.chatbubbleentity.nextthink = time; - setmodel(self.chatbubbleentity, "models/misc/chatbubble.spr"); // precision set below + setmodel(self.chatbubbleentity, MDL_CHAT); // precision set below //setorigin(self.chatbubbleentity, self.origin + '0 0 15' + self.maxs_z * '0 0 1'); - setorigin(self.chatbubbleentity, '0 0 15' + self.maxs.z * '0 0 1'); + setorigin(self.chatbubbleentity, '0 0 15' + self.maxs_z * '0 0 1'); setattachment(self.chatbubbleentity, self, ""); // sticks to moving player better, also conserves bandwidth self.chatbubbleentity.mdl = self.chatbubbleentity.model; - self.chatbubbleentity.model = ""; + //self.chatbubbleentity.model = ""; self.chatbubbleentity.effects = EF_LOWPRECISION; } } @@ -1433,7 +1422,7 @@ void UpdateChatBubble() }*/ void respawn(void) -{ +{SELFPARAM(); if(self.alpha >= 0 && autocvar_g_respawn_ghosts) { self.solid = SOLID_NOT; @@ -1442,7 +1431,7 @@ void respawn(void) self.velocity = '0 0 1' * autocvar_g_respawn_ghosts_speed; self.avelocity = randomvec() * autocvar_g_respawn_ghosts_speed * 3 - randomvec() * autocvar_g_respawn_ghosts_speed * 3; self.effects |= CSQCMODEL_EF_RESPAWNGHOST; - Send_Effect("respawn_ghost", self.origin, '0 0 0', 1); + Send_Effect(EFFECT_RESPAWN_GHOST, self.origin, '0 0 0', 1); if(autocvar_g_respawn_ghosts_maxtime) SUB_SetFade (self, time + autocvar_g_respawn_ghosts_maxtime / 2 + random () * (autocvar_g_respawn_ghosts_maxtime - autocvar_g_respawn_ghosts_maxtime / 2), 1.5); } @@ -1454,15 +1443,15 @@ void respawn(void) } void play_countdown(float finished, string samp) -{ +{SELFPARAM(); if(IS_REAL_CLIENT(self)) if(floor(finished - time - frametime) != floor(finished - time)) if(finished - time < 6) - sound (self, CH_INFO, samp, VOL_BASE, ATTEN_NORM); + _sound (self, CH_INFO, samp, VOL_BASE, ATTEN_NORM); } void player_powerups (void) -{ +{SELFPARAM(); // add a way to see what the items were BEFORE all of these checks for the mutator hook int items_prev = self.items; @@ -1483,7 +1472,7 @@ void player_powerups (void) { if (self.items & ITEM_Strength.m_itemid) { - play_countdown(self.strength_finished, "misc/poweroff.wav"); + play_countdown(self.strength_finished, SND(POWEROFF)); self.effects = self.effects | (EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT); if (time > self.strength_finished) { @@ -1503,7 +1492,7 @@ void player_powerups (void) } if (self.items & ITEM_Shield.m_itemid) { - play_countdown(self.invincible_finished, "misc/poweroff.wav"); + play_countdown(self.invincible_finished, SND(POWEROFF)); self.effects = self.effects | (EF_RED | EF_ADDITIVE | EF_FULLBRIGHT); if (time > self.invincible_finished) { @@ -1536,7 +1525,7 @@ void player_powerups (void) } else { - play_countdown(self.superweapons_finished, "misc/poweroff.wav"); + play_countdown(self.superweapons_finished, SND(POWEROFF)); if (time > self.superweapons_finished) { self.items = self.items - (self.items & IT_SUPERWEAPON); @@ -1625,16 +1614,25 @@ float CalcRotRegen(float current, float regenstable, float regenfactor, float re } void player_regen (void) -{ +{SELFPARAM(); float max_mod, regen_mod, rot_mod, limit_mod; max_mod = regen_mod = rot_mod = limit_mod = 1; - if(!MUTATOR_CALLHOOK(PlayerRegen, max_mod, regen_mod, rot_mod, limit_mod)) + regen_mod_max = max_mod; + regen_mod_regen = regen_mod; + regen_mod_rot = rot_mod; + regen_mod_limit = limit_mod; + + regen_health = autocvar_g_balance_health_regen; + regen_health_linear = autocvar_g_balance_health_regenlinear; + regen_health_rot = autocvar_g_balance_health_rot; + regen_health_rotlinear = autocvar_g_balance_health_rotlinear; + regen_health_stable = autocvar_g_balance_health_regenstable; + regen_health_rotstable = autocvar_g_balance_health_rotstable; + if(!MUTATOR_CALLHOOK(PlayerRegen)) if(!self.frozen) { - float minh, mina, maxh, maxa, limith, limita; - maxh = autocvar_g_balance_health_rotstable; + float mina, maxa, limith, limita; maxa = autocvar_g_balance_armor_rotstable; - minh = autocvar_g_balance_health_regenstable; mina = autocvar_g_balance_armor_regenstable; limith = autocvar_g_balance_health_limit; limita = autocvar_g_balance_armor_limit; @@ -1644,19 +1642,23 @@ void player_regen (void) rot_mod = regen_mod_rot; limit_mod = regen_mod_limit; - maxh = maxh * max_mod; - minh = minh * max_mod; + regen_health_rotstable = regen_health_rotstable * max_mod; + regen_health_stable = regen_health_stable * max_mod; limith = limith * limit_mod; limita = limita * limit_mod; self.armorvalue = CalcRotRegen(self.armorvalue, mina, autocvar_g_balance_armor_regen, autocvar_g_balance_armor_regenlinear, regen_mod * frametime * (time > self.pauseregen_finished), maxa, autocvar_g_balance_armor_rot, autocvar_g_balance_armor_rotlinear, rot_mod * frametime * (time > self.pauserotarmor_finished), limita); - self.health = CalcRotRegen(self.health, minh, autocvar_g_balance_health_regen, autocvar_g_balance_health_regenlinear, regen_mod * frametime * (time > self.pauseregen_finished), maxh, autocvar_g_balance_health_rot, autocvar_g_balance_health_rotlinear, rot_mod * frametime * (time > self.pauserothealth_finished), limith); + self.health = CalcRotRegen(self.health, regen_health_stable, regen_health, regen_health_linear, regen_mod * frametime * (time > self.pauseregen_finished), regen_health_rotstable, regen_health_rot, regen_health_rotlinear, rot_mod * frametime * (time > self.pauserothealth_finished), limith); } // if player rotted to death... die! // check this outside above checks, as player may still be able to rot to death if(self.health < 1) + { + if(self.vehicle) + vehicles_exit(VHEF_RELEASE); self.event_damage(self, self, 1, DEATH_ROT, self.origin, '0 0 0'); + } if (!(self.items & IT_UNLIMITED_WEAPON_AMMO)) { @@ -1672,7 +1674,7 @@ void player_regen (void) float zoomstate_set; void SetZoomState(float z) -{ +{SELFPARAM(); if(z != self.zoomstate) { self.zoomstate = z; @@ -1681,7 +1683,8 @@ void SetZoomState(float z) zoomstate_set = 1; } -void GetPressedKeys(void) { +void GetPressedKeys() +{SELFPARAM(); MUTATOR_CALLHOOK(GetPressedKeys); #define X(var,bit,flag) (flag ? var |= bit : var &= ~bit) X(self.pressedkeys, KEY_FORWARD, self.movement_x > 0); @@ -1702,7 +1705,8 @@ spectate mode routines ====================== */ -void SpectateCopy(entity spectatee) { +void SpectateCopy(entity spectatee) +{SELFPARAM(); MUTATOR_CALLHOOK(SpectateCopy, spectatee, self); self.armortype = spectatee.armortype; self.armorvalue = spectatee.armorvalue; @@ -1777,49 +1781,36 @@ void SpectateCopy(entity spectatee) { } } -float SpectateUpdate() -{ +bool SpectateUpdate() +{SELFPARAM(); if(!self.enemy) - return 0; + return false; if(!IS_PLAYER(self.enemy) || self == self.enemy) { SetSpectator(self, world); - return 0; + return false; } SpectateCopy(self.enemy); - return 1; + return true; } -float SpectateSet() -{ - if(self.enemy.classname != "player") +bool SpectateSet() +{SELFPARAM(); + if(!IS_PLAYER(self.enemy)) 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"); + msg_entity = self; + WriteByte(MSG_ONE, SVC_SETVIEW); + WriteEntity(MSG_ONE, self.enemy); + self.movetype = MOVETYPE_NONE; + accuracy_resend(self); - 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(); - if(!SpectateUpdate()) - PutObserverInServer(); - //} return true; } @@ -1835,47 +1826,47 @@ void SetSpectator(entity player, entity spectatee) if(player.enemy && player.enemy.arc_beam) { player.enemy.arc_beam.SendFlags |= ARC_SF_SETTINGS; } } -float Spectate(entity pl) -{ +bool Spectate(entity pl) +{SELFPARAM(); if(g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer) - if(pl.team != self.team) - return 0; + if(DIFF_TEAM(pl, self)) + return false; SetSpectator(self, 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) { +entity CA_SpectateNext(entity start) +{SELFPARAM(); + if(SAME_TEAM(start, self)) return start; - } other = start; // continue from current player - while(other && other.team != self.team) { + while(other && DIFF_TEAM(other, self)) other = find(other, classname, "player"); - } - if (!other) { + if (!other) + { // restart from begining other = find(other, classname, "player"); - while(other && other.team != self.team) { + while(other && DIFF_TEAM(other, self)) other = find(other, classname, "player"); - } } return other; } -float SpectateNext() -{ +bool SpectateNext() +{SELFPARAM(); other = find(self.enemy, classname, "player"); - if (g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer) { + if (g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer) // CA and ca players when spectating enemies is forbidden other = CA_SpectateNext(other); - } else { + else + { // other modes and ca spectators or spectating enemies is allowed if (!other) other = find(other, classname, "player"); @@ -1886,8 +1877,8 @@ float SpectateNext() return SpectateSet(); } -float SpectatePrev() -{ +bool SpectatePrev() +{SELFPARAM(); // NOTE: chain order is from the highest to the lower entnum (unlike find) other = findchain(classname, "player"); if (!other) // no player @@ -1902,12 +1893,12 @@ float SpectatePrev() if (g_ca && !autocvar_g_ca_spectate_enemies && self.caplayer) { do { other = other.chain; } - while(other && other.team != self.team); + while(other && DIFF_TEAM(other, self)); if (!other) { other = first; - while(other.team != self.team) + while(other && DIFF_TEAM(other, self)) other = other.chain; if(other == self.enemy) return true; @@ -1932,7 +1923,7 @@ Update a respawn countdown display. ============= */ void ShowRespawnCountdown() -{ +{SELFPARAM(); float number; if(self.deadflag == DEAD_NO) // just respawned? return; @@ -1951,7 +1942,7 @@ void ShowRespawnCountdown() } void LeaveSpectatorMode() -{ +{SELFPARAM(); if(self.caplayer) return; if(nJoinAllowed(self)) @@ -1989,7 +1980,8 @@ 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) { +float nJoinAllowed(entity ignore) +{SELFPARAM(); 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 @@ -2028,7 +2020,8 @@ float nJoinAllowed(entity ignore) { * Checks whether the client is an observer or spectator, if so, he will get kicked after * g_maxplayers_spectator_blocktime seconds */ -void checkSpectatorBlock() { +void checkSpectatorBlock() +{SELFPARAM(); if(IS_SPEC(self) || IS_OBSERVER(self)) if(!self.caplayer) if(IS_REAL_CLIENT(self)) @@ -2041,7 +2034,7 @@ void checkSpectatorBlock() { } void PrintWelcomeMessage() -{ +{SELFPARAM(); if(self.motd_actived_time == 0) { if (autocvar_g_campaign) { @@ -2088,7 +2081,12 @@ void PrintWelcomeMessage() } void ObserverThink() -{ +{SELFPARAM(); + if ( self.impulse ) + { + MinigameImpulse(self.impulse); + self.impulse = 0; + } float prefered_movetype; if (self.flags & FL_JUMPRELEASED) { if (self.BUTTON_JUMP && !self.version_mismatch) { @@ -2118,7 +2116,12 @@ void ObserverThink() } void SpectatorThink() -{ +{SELFPARAM(); + if ( self.impulse ) + { + if(MinigameImpulse(self.impulse)) + self.impulse = 0; + } if (self.flags & FL_JUMPRELEASED) { if (self.BUTTON_JUMP && !self.version_mismatch) { self.flags &= ~FL_JUMPRELEASED; @@ -2166,15 +2169,49 @@ void SpectatorThink() self.flags |= FL_CLIENT | FL_NOTARGET; } +void vehicles_enter (entity pl, entity veh); void PlayerUseKey() -{ +{SELFPARAM(); if (!IS_PLAYER(self)) return; if(self.vehicle) { - vehicles_exit(VHEF_NORMAL); - return; + if(!gameover) + { + vehicles_exit(VHEF_NORMAL); + return; + } + } + else if(autocvar_g_vehicles_enter) + { + if(!self.frozen) + if(self.deadflag == DEAD_NO) + if(!gameover) + { + entity head, closest_target = world; + head = WarpZone_FindRadius(self.origin, autocvar_g_vehicles_enter_radius, TRUE); + + while(head) // find the closest acceptable target to enter + { + if(head.vehicle_flags & VHF_ISVEHICLE) + if(head.deadflag == DEAD_NO) + if(!head.owner || ((head.vehicle_flags & VHF_MULTISLOT) && SAME_TEAM(head.owner, self))) + if(head.takedamage != DAMAGE_NO) + { + if(closest_target) + { + if(vlen(self.origin - head.origin) < vlen(self.origin - closest_target.origin)) + { closest_target = head; } + } + else { closest_target = head; } + } + + head = head.chain; + } + + if(closest_target) { vehicles_enter(self, closest_target); return; } + } } // a use key was pressed; call handlers @@ -2217,9 +2254,10 @@ Called every frame for each client before the physics are run */ .float usekeypressed; void() nexball_setstatus; +.float last_vehiclecheck; .int items_added; void PlayerPreThink (void) -{ +{SELFPARAM(); WarpZone_PlayerPhysics_FixVAngle(); self.stat_game_starttime = game_starttime; @@ -2243,7 +2281,7 @@ void PlayerPreThink (void) // Savage: Check for nameless players if (isInvisibleString(self.netname)) { - string new_name = strzone(strcat("Player@", self.netaddress)); + string new_name = strzone(strcat("Player@", ftos(self.playerid))); if(autocvar_sv_eventlog) GameLogEcho(strcat(":name:", ftos(self.playerid), ":", new_name)); if(self.netname_previous) @@ -2270,7 +2308,7 @@ void PlayerPreThink (void) if(strstr(autocvar_g_xonoticversion, "git", 0) >= 0 || strstr(autocvar_g_xonoticversion, "autobuild", 0) >= 0) { // notify release users if connecting to git - dprint("^1NOTE^7 to ", self.netname, "^7 - the server is running ^3Xonotic ", autocvar_g_xonoticversion, " (beta)^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n"); + LOG_TRACE("^1NOTE^7 to ", self.netname, "^7 - the server is running ^3Xonotic ", autocvar_g_xonoticversion, " (beta)^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n"); Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_VERSION_BETA, autocvar_g_xonoticversion, self.cvar_g_xonoticversion); } else @@ -2280,13 +2318,13 @@ void PlayerPreThink (void) if(r < 0) { // give users new version - dprint("^1NOTE^7 to ", self.netname, "^7 - ^3Xonotic ", autocvar_g_xonoticversion, "^7 is out, and you still have ^3Xonotic ", self.cvar_g_xonoticversion, "^1 - get the update from ^4http://www.xonotic.org/^1!\n"); + LOG_TRACE("^1NOTE^7 to ", self.netname, "^7 - ^3Xonotic ", autocvar_g_xonoticversion, "^7 is out, and you still have ^3Xonotic ", self.cvar_g_xonoticversion, "^1 - get the update from ^4http://www.xonotic.org/^1!\n"); Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_VERSION_OUTDATED, autocvar_g_xonoticversion, self.cvar_g_xonoticversion); } else if(r > 0) { // notify users about old server version - print("^1NOTE^7 to ", self.netname, "^7 - the server is running ^3Xonotic ", autocvar_g_xonoticversion, "^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n"); + LOG_INFO("^1NOTE^7 to ", self.netname, "^7 - the server is running ^3Xonotic ", autocvar_g_xonoticversion, "^7, you have ^3Xonotic ", self.cvar_g_xonoticversion, "^1\n"); Send_Notification(NOTIF_ONE_ONLY, self, MSG_INFO, INFO_VERSION_OLD, autocvar_g_xonoticversion, self.cvar_g_xonoticversion); } } @@ -2301,11 +2339,6 @@ void PlayerPreThink (void) self.max_armorvalue = 0; } -#ifdef TETRIS - if (TetrisPreFrame()) - return; -#endif - if(self.frozen == 2) { self.revive_progress = bound(0, self.revive_progress + frametime * self.revive_speed, 1); @@ -2323,7 +2356,7 @@ void PlayerPreThink (void) if(self.health < 1) { if(self.vehicle) - vehicles_exit(VHEF_RELESE); + vehicles_exit(VHEF_RELEASE); self.event_damage(self, self.frozen_by, 1, DEATH_NADE_ICE_FREEZE, self.origin, '0 0 0'); } else if ( self.revive_progress <= 0 ) @@ -2332,6 +2365,30 @@ void PlayerPreThink (void) MUTATOR_CALLHOOK(PlayerPreThink); + if(autocvar_g_vehicles_enter) + if(time > self.last_vehiclecheck) + if(IS_PLAYER(self)) + if(!gameover) + if(!self.frozen) + if(!self.vehicle) + if(self.deadflag == DEAD_NO) + { + entity veh; + for(veh = world; (veh = findflags(veh, vehicle_flags, VHF_ISVEHICLE)); ) + if(vlen(veh.origin - self.origin) < autocvar_g_vehicles_enter_radius) + if(veh.deadflag == DEAD_NO) + if(veh.takedamage != DAMAGE_NO) + if((veh.vehicle_flags & VHF_MULTISLOT) && SAME_TEAM(veh.owner, self)) + Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_VEHICLE_ENTER_GUNNER); + else if(!veh.owner) + if(!veh.team || SAME_TEAM(self, veh)) + Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_VEHICLE_ENTER); + else if(autocvar_g_vehicles_steal) + Send_Notification(NOTIF_ONE, self, MSG_CENTER, CENTER_VEHICLE_ENTER_STEAL); + + self.last_vehiclecheck = time + 1; + } + if(!self.cvar_cl_newusekeysupported) // FIXME remove this - it was a stupid idea to begin with, we can JUST use the button { if(self.BUTTON_USE && !self.usekeypressed) @@ -2363,7 +2420,7 @@ void PlayerPreThink (void) if(frametime) { - if(self.weapon == WEP_VORTEX && WEP_CVAR(vortex, charge)) + 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)); @@ -2459,7 +2516,7 @@ void PlayerPreThink (void) // WEAPONTODO: THIS SHIT NEEDS TO GO EVENTUALLY // It cannot be predicted by the engine! - if((self.weapon == WEP_SHOCKWAVE || self.weapon == WEP_SHOTGUN) && self.weaponentity.wframe == WFRAME_FIRE2 && time < self.weapon_nextthink) + if((self.weapon == WEP_SHOCKWAVE.m_id || self.weapon == WEP_SHOTGUN.m_id) && self.weaponentity.wframe == WFRAME_FIRE2 && time < self.weapon_nextthink) do_crouch = 0; if (do_crouch) @@ -2488,14 +2545,12 @@ void PlayerPreThink (void) FixPlayermodel(); - GrapplingHookFrame(); - // LordHavoc: allow firing on move frames (sub-ticrate), this gives better timing on slow servers //if(frametime) { self.items &= ~self.items_added; - W_WeaponFrame(); + W_WeaponFrame(self); self.items_added = 0; if(self.items & ITEM_Jetpack.m_itemid) @@ -2536,7 +2591,7 @@ void PlayerPreThink (void) // WEAPONTODO: Add weapon request for this if(!zoomstate_set) - SetZoomState(self.BUTTON_ZOOM || self.BUTTON_ZOOMSCRIPT || (self.BUTTON_ATCK2 && self.weapon == WEP_VORTEX) || (self.BUTTON_ATCK2 && self.weapon == WEP_RIFLE && WEP_CVAR(rifle, secondary) == 0)); // WEAPONTODO + 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 float oldspectatee_status; oldspectatee_status = self.spectatee_status; @@ -2556,15 +2611,14 @@ void PlayerPreThink (void) { self.teamkill_soundtime = 0; - entity oldpusher, oldself; - - oldself = self; self = self.teamkill_soundsource; - oldpusher = self.pusher; self.pusher = oldself; + setself(self.teamkill_soundsource); + entity oldpusher = self.pusher; + self.pusher = this; PlayerSound(playersound_teamshoot, CH_VOICE, VOICETYPE_LASTATTACKER_ONLY); self.pusher = oldpusher; - self = oldself; + setself(this); } if(self.taunt_soundtime) @@ -2591,8 +2645,9 @@ Called every frame for each client after the physics are run */ .float idlekick_lasttimeleft; void PlayerPostThink (void) -{ +{SELFPARAM(); 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_REAL_CLIENT(self)) if(IS_PLAYER(self) || sv_maxidle_spectatorsareidle) { if (time - self.parm_idlesince < 1) // instead of (time == self.parm_idlesince) to support sv_maxidle <= 10 @@ -2627,13 +2682,6 @@ void PlayerPostThink (void) } } -#ifdef TETRIS - if(self.impulse == 100) - ImpulseCommands(); - if (!TetrisPostFrame()) - { -#endif - CheatFrame(); //CheckPlayerJump(); @@ -2648,10 +2696,6 @@ void PlayerPostThink (void) GetPressedKeys(); } -#ifdef TETRIS - } -#endif - /* float i; for(i = 0; i < 1000; ++i) @@ -2673,5 +2717,5 @@ void PlayerPostThink (void) playerdemo_write(); - CSQCMODEL_AUTOUPDATE(); + CSQCMODEL_AUTOUPDATE(self); }