X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=blobdiff_plain;f=qcsrc%2Fserver%2Fclient.qc;h=f1f67a7924650492e25b2634684135862dec1a92;hp=ec6d292d9f9de701c43360c370b662a1aceaa02a;hb=65459f5d1671e5ce33cffcf78f6da10b8966c171;hpb=926c661916abe4e27456dd977025fe4c56042626 diff --git a/qcsrc/server/client.qc b/qcsrc/server/client.qc index ec6d292d9f..f1f67a7924 100644 --- a/qcsrc/server/client.qc +++ b/qcsrc/server/client.qc @@ -1,5 +1,8 @@ #include "client.qh" +#include +#include +#include #include "anticheat.qh" #include "impulse.qh" #include "player.qh" @@ -9,6 +12,7 @@ #include "teamplay.qh" #include "playerdemo.qh" #include "spawnpoints.qh" +#include "resources.qh" #include "g_damage.qh" #include "g_hook.qh" #include "command/common.qh" @@ -110,20 +114,18 @@ bool ClientData_Send(entity this, entity to, int sf) if (IS_SPEC(e)) e = e.enemy; sf = 0; - if (e.race_completed) sf |= 1; // forced scoreboard - if (CS(to).spectatee_status) sf |= 2; // spectator ent number follows - if (CS(e).zoomstate) sf |= 4; // zoomed - if (autocvar_sv_showspectators) sf |= 16; // show spectators + if (CS(e).race_completed) sf |= BIT(0); // forced scoreboard + if (CS(to).spectatee_status) sf |= BIT(1); // spectator ent number follows + if (CS(e).zoomstate) sf |= BIT(2); // zoomed + if (autocvar_sv_showspectators) sf |= BIT(4); // show spectators WriteHeader(MSG_ENTITY, ENT_CLIENT_CLIENTDATA); WriteByte(MSG_ENTITY, sf); - if (sf & 2) - { + if (sf & BIT(1)) WriteByte(MSG_ENTITY, CS(to).spectatee_status); - } - if(sf & 16) + if(sf & BIT(4)) { float specs = CountSpectators(e, to); WriteByte(MSG_ENTITY, specs); @@ -135,23 +137,23 @@ bool ClientData_Send(entity this, entity to, int sf) void ClientData_Attach(entity this) { - Net_LinkEntity(this.clientdata = new_pure(clientdata), false, 0, ClientData_Send); - this.clientdata.drawonlytoclient = this; - this.clientdata.owner = this; + Net_LinkEntity(CS(this).clientdata = new_pure(clientdata), false, 0, ClientData_Send); + CS(this).clientdata.drawonlytoclient = this; + CS(this).clientdata.owner = this; } void ClientData_Detach(entity this) { - delete(this.clientdata); - this.clientdata = NULL; + delete(CS(this).clientdata); + CS(this).clientdata = NULL; } void ClientData_Touch(entity e) { - e.clientdata.SendFlags = 1; + CS(e).clientdata.SendFlags = 1; // make it spectatable - FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != e && IS_SPEC(it) && it.enemy == e, LAMBDA(it.clientdata.SendFlags = 1)); + FOREACH_CLIENT(IS_REAL_CLIENT(it) && it != e && IS_SPEC(it) && it.enemy == e, { CS(it).clientdata.SendFlags = 1; }); } void SetSpectatee(entity this, entity spectatee); @@ -225,12 +227,10 @@ void PutObserverInServer(entity this) { entity spot = SelectSpawnPoint(this, true); if (!spot) LOG_FATAL("No spawnpoints for observers?!?"); - this.angles = spot.angles; - this.angles_z = 0; + this.angles = vec2(spot.angles); this.fixangle = true; // offset it so that the spectator spawns higher off the ground, looks better this way setorigin(this, spot.origin + STAT(PL_VIEW_OFS, this)); - this.prevorigin = this.origin; if (IS_REAL_CLIENT(this)) { msg_entity = this; @@ -281,10 +281,10 @@ void PutObserverInServer(entity this) if(autocvar_g_chat_nospectators == 1 || (!warmup_stage && autocvar_g_chat_nospectators == 2)) Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_CHAT_NOSPECTATORS); - if(this.just_joined == false) { + if(!CS(this).just_joined) LogTeamchange(this.playerid, -1, 4); - } else - this.just_joined = false; + else + CS(this).just_joined = false; } accuracy_resend(this); @@ -336,7 +336,6 @@ void PutObserverInServer(entity this) this.items = 0; this.weapons = '0 0 0'; - this.dual_weapons = '0 0 0'; this.drawonlytoclient = this; this.weaponmodel = ""; @@ -400,7 +399,7 @@ void FixPlayermodel(entity player) int n = tokenize_console(defaultmodel); if(n > 0) { - defaultmodel = argv(floor(n * player.model_randomizer)); + defaultmodel = argv(floor(n * CS(player).model_randomizer)); // However, do NOT randomize if the player-selected model is in the list. for (int i = 0; i < n; ++i) if ((argv(i) == player.playermodel && defaultskin == stof(player.playerskin)) || argv(i) == strcat(player.playermodel, ":", player.playerskin)) @@ -504,7 +503,7 @@ void PutPlayerInServer(entity this) TRANSMUTE(Player, this); - this.wasplayer = true; + CS(this).wasplayer = true; this.iscreature = true; this.teleportable = TELEPORT_NORMAL; if(!this.damagedbycontents) @@ -546,10 +545,14 @@ void PutPlayerInServer(entity this) this.health = start_health; this.armorvalue = start_armorvalue; this.weapons = start_weapons; + GiveRandomWeapons(this, random_start_weapons_count, + cvar_string("g_random_start_weapons"), random_start_shells, + random_start_bullets, random_start_rockets, random_start_cells, + random_start_plasma); } SetSpectatee_status(this, 0); - this.dual_weapons = '0 0 0'; + PS(this).dual_weapons = '0 0 0'; this.superweapons_finished = (this.weapons & WEPSET_SUPERWEAPONS) ? time + autocvar_g_balance_superweapons_time : 0; @@ -581,7 +584,7 @@ void PutPlayerInServer(entity this) setthink(this, func_null); // players have no think function this.nextthink = 0; this.dmg_team = 0; - this.ballistics_density = autocvar_g_ballistics_density_player; + PS(this).ballistics_density = autocvar_g_ballistics_density_player; this.deadflag = DEAD_NO; @@ -622,7 +625,6 @@ void PutPlayerInServer(entity this) setorigin(this, spot.origin + '0 0 1' * (1 - this.mins.z - 24)); // don't reset back to last position, even if new position is stuck in solid this.oldorigin = this.origin; - this.prevorigin = this.origin; this.lastteleporttime = time; // prevent insane speeds due to changing origin if(this.conveyor) IL_REMOVE(g_conveyed, this); @@ -663,7 +665,7 @@ void PutPlayerInServer(entity this) target_voicescript_clear(this); // reset fields the weapons may use - FOREACH(Weapons, true, LAMBDA( + FOREACH(Weapons, true, { it.wr_resetplayer(it, this); // reload all reloadable weapons if (it.spawnflags & WEP_FLAG_RELOADABLE) { @@ -673,7 +675,7 @@ void PutPlayerInServer(entity this) this.(weaponentity).weapon_load[it.m_id] = it.reloading_ammo; } } - )); + }); { string s = spot.target; @@ -729,7 +731,8 @@ void PutClientInServer(entity this) SetSpectatee(this, NULL); // reset player keys - this.itemkeys = 0; + if(PS(this)) + PS(this).itemkeys = 0; MUTATOR_CALLHOOK(PutClientInServer, this); @@ -775,6 +778,7 @@ void ClientInit_misc(entity this) else WriteString(channel, ""); WriteByte(channel, this.count * 255.0); // g_balance_armor_blockpercent + WriteByte(channel, this.cnt * 255.0); // g_balance_damagepush_speedfactor WriteByte(channel, serverflags); WriteCoord(channel, autocvar_g_trueaim_minrange); } @@ -787,6 +791,11 @@ void ClientInit_CheckUpdate(entity this) this.count = autocvar_g_balance_armor_blockpercent; this.SendFlags |= 1; } + if(this.cnt != autocvar_g_balance_damagepush_speedfactor) + { + this.cnt = autocvar_g_balance_damagepush_speedfactor; + this.SendFlags |= 1; + } } void ClientInit_Spawn() @@ -1183,14 +1192,17 @@ void ClientConnect(entity this) PlayerStats_GameReport_AddEvent(sprintf("kills-%d", this.playerid)); // always track bots, don't ask for cl_allow_uidtracking - if (IS_BOT_CLIENT(this)) PlayerStats_GameReport_AddPlayer(this); + if (IS_BOT_CLIENT(this)) + PlayerStats_GameReport_AddPlayer(this); + else + CS(this).allowed_timeouts = autocvar_sv_timeout_number; if (autocvar_sv_eventlog) GameLogEcho(strcat(":join:", ftos(this.playerid), ":", ftos(etof(this)), ":", ((IS_REAL_CLIENT(this)) ? this.netaddress : "bot"), ":", playername(this, false))); LogTeamchange(this.playerid, this.team, 1); - this.just_joined = true; // stop spamming the eventlog with additional lines when the client connects + CS(this).just_joined = true; // stop spamming the eventlog with additional lines when the client connects CS(this).netname_previous = strzone(this.netname); @@ -1232,7 +1244,6 @@ void ClientConnect(entity this) } CS(this).jointime = time; - CS(this).allowed_timeouts = autocvar_sv_timeout_number; if (IS_REAL_CLIENT(this)) { @@ -1249,15 +1260,13 @@ void ClientConnect(entity this) CSQCMODEL_AUTOINIT(this); - this.model_randomizer = random(); + CS(this).model_randomizer = random(); if (IS_REAL_CLIENT(this)) sv_notice_join(this); // update physics stats (players can spawn before physics runs) - STAT(MOVEVARS_HIGHSPEED, this) = autocvar_g_movement_highspeed; - MUTATOR_CALLHOOK(PlayerPhysics_UpdateStats, this); // do it BEFORE the function so we can modify highspeed! - Physics_UpdateStats(this, PHYS_HIGHSPEED(this)); + Physics_UpdateStats(this); IL_EACH(g_initforplayer, it.init_for_player, { it.init_for_player(it, this); @@ -1618,15 +1627,14 @@ void player_regen(entity this) regen_health_stable = M_ARGV(9, float); regen_health_rotstable = M_ARGV(10, float); - if(!mutator_returnvalue) if(!STAT(FROZEN, this)) { float mina, maxa, limith, limita; maxa = autocvar_g_balance_armor_rotstable; mina = autocvar_g_balance_armor_regenstable; - limith = autocvar_g_balance_health_limit; - limita = autocvar_g_balance_armor_limit; + limith = GetResourceLimit(this, RESOURCE_HEALTH); + limita = GetResourceLimit(this, RESOURCE_ARMOR); regen_health_rotstable = regen_health_rotstable * max_mod; regen_health_stable = regen_health_stable * max_mod; @@ -1653,10 +1661,22 @@ void player_regen(entity this) maxf = autocvar_g_balance_fuel_rotstable; minf = autocvar_g_balance_fuel_regenstable; - limitf = autocvar_g_balance_fuel_limit; + limitf = GetResourceLimit(this, RESOURCE_FUEL); this.ammo_fuel = CalcRotRegen(this.ammo_fuel, minf, autocvar_g_balance_fuel_regen, autocvar_g_balance_fuel_regenlinear, frametime * (time > this.pauseregen_finished) * ((this.items & ITEM_JetpackRegen.m_itemid) != 0), maxf, autocvar_g_balance_fuel_rot, autocvar_g_balance_fuel_rotlinear, frametime * (time > this.pauserotfuel_finished), limitf); } + // Ugly hack to make sure the health and armor don't go beyond hard limit. + // TODO: Remove this hack when all code uses GivePlayerHealth and + // GivePlayerArmor. + if (this.health > RESOURCE_AMOUNT_HARD_LIMIT) + { + this.health = RESOURCE_AMOUNT_HARD_LIMIT; + } + if (this.armorvalue > RESOURCE_AMOUNT_HARD_LIMIT) + { + this.armorvalue = RESOURCE_AMOUNT_HARD_LIMIT; + } + // End hack. } bool zoomstate_set; @@ -1721,7 +1741,6 @@ void SpectateCopy(entity this, entity spectatee) this.superweapons_finished = spectatee.superweapons_finished; STAT(PRESSED_KEYS, this) = STAT(PRESSED_KEYS, spectatee); this.weapons = spectatee.weapons; - this.dual_weapons = spectatee.dual_weapons; this.vortex_charge = spectatee.vortex_charge; this.vortex_chargepool_ammo = spectatee.vortex_chargepool_ammo; this.hagar_load = spectatee.hagar_load; @@ -1957,7 +1976,7 @@ void ShowRespawnCountdown(entity this) .bool team_selected; bool ShowTeamSelection(entity this) { - if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || this.team_selected || (this.wasplayer && autocvar_g_changeteam_banned) || this.team_forced > 0) + if(!teamplay || autocvar_g_campaign || autocvar_g_balance_teams || this.team_selected || (CS(this).wasplayer && autocvar_g_changeteam_banned) || this.team_forced > 0) return false; stuffcmd(this, "menu_showteamselect\n"); return true; @@ -2009,13 +2028,13 @@ int nJoinAllowed(entity this, entity ignore) // TODO simplify this int totalClients = 0; int currentlyPlaying = 0; - FOREACH_CLIENT(true, LAMBDA( + FOREACH_CLIENT(true, { if(it != ignore) ++totalClients; if(IS_REAL_CLIENT(it)) if(IS_PLAYER(it) || it.caplayer) ++currentlyPlaying; - )); + }); float free_slots = 0; if (!autocvar_g_maxplayers) @@ -2203,8 +2222,6 @@ bool PlayerThink(entity this) return false; } - this.prevorigin = this.origin; - bool have_hook = false; for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot) { @@ -2310,7 +2327,7 @@ void ObserverThink(entity this) TRANSMUTE(Spectator, this); } } else { - int preferred_movetype = ((!PHYS_INPUT_BUTTON_USE(this) ? this.cvar_cl_clippedspectating : !this.cvar_cl_clippedspectating) ? MOVETYPE_FLY_WORLDONLY : MOVETYPE_NOCLIP); + int preferred_movetype = ((!PHYS_INPUT_BUTTON_USE(this) ? CS(this).cvar_cl_clippedspectating : !CS(this).cvar_cl_clippedspectating) ? MOVETYPE_FLY_WORLDONLY : MOVETYPE_NOCLIP); set_movetype(this, preferred_movetype); } } else { @@ -2448,14 +2465,10 @@ Called every frame for each client before the physics are run .float last_vehiclecheck; void PlayerPreThink (entity this) { - WarpZone_PlayerPhysics_FixVAngle(this); - - STAT(GAMESTARTTIME, this) = game_starttime; - STAT(ROUNDSTARTTIME, this) = round_starttime; - STAT(ALLOW_OLDVORTEXBEAM, this) = autocvar_g_allow_oldvortexbeam; - STAT(LEADLIMIT, this) = autocvar_leadlimit; + STAT(GUNALIGN, this) = CS(this).cvar_cl_gunalign; // TODO + STAT(MOVEVARS_CL_TRACK_CANJUMP, this) = CS(this).cvar_cl_movement_track_canjump; - STAT(WEAPONSINMAP, this) = weaponsInMap; + WarpZone_PlayerPhysics_FixVAngle(this); if (frametime) { // physics frames: update anticheat stuff @@ -2484,19 +2497,19 @@ void PlayerPreThink (entity this) } // version nagging - if (CS(this).version_nagtime && this.cvar_g_xonoticversion && time > CS(this).version_nagtime) { + if (CS(this).version_nagtime && CS(this).cvar_g_xonoticversion && time > CS(this).version_nagtime) { CS(this).version_nagtime = 0; - if (strstrofs(this.cvar_g_xonoticversion, "git", 0) >= 0 || strstrofs(this.cvar_g_xonoticversion, "autobuild", 0) >= 0) { + if (strstrofs(CS(this).cvar_g_xonoticversion, "git", 0) >= 0 || strstrofs(CS(this).cvar_g_xonoticversion, "autobuild", 0) >= 0) { // git client } else if (strstrofs(autocvar_g_xonoticversion, "git", 0) >= 0 || strstrofs(autocvar_g_xonoticversion, "autobuild", 0) >= 0) { // git server - Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_VERSION_BETA, autocvar_g_xonoticversion, this.cvar_g_xonoticversion); + Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_VERSION_BETA, autocvar_g_xonoticversion, CS(this).cvar_g_xonoticversion); } else { - int r = vercmp(this.cvar_g_xonoticversion, autocvar_g_xonoticversion); + int r = vercmp(CS(this).cvar_g_xonoticversion, autocvar_g_xonoticversion); if (r < 0) { // old client - Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_VERSION_OUTDATED, autocvar_g_xonoticversion, this.cvar_g_xonoticversion); + Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_VERSION_OUTDATED, autocvar_g_xonoticversion, CS(this).cvar_g_xonoticversion); } else if (r > 0) { // old server - Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_VERSION_OLD, autocvar_g_xonoticversion, this.cvar_g_xonoticversion); + Send_Notification(NOTIF_ONE_ONLY, this, MSG_INFO, INFO_VERSION_OLD, autocvar_g_xonoticversion, CS(this).cvar_g_xonoticversion); } } } @@ -2508,29 +2521,32 @@ void PlayerPreThink (entity this) this.max_armorvalue = 0; } - if (STAT(FROZEN, this) == 2) - { - this.revive_progress = bound(0, this.revive_progress + frametime * this.revive_speed, 1); - this.health = max(1, this.revive_progress * start_health); - this.iceblock.alpha = bound(0.2, 1 - this.revive_progress, 1); - - if (this.revive_progress >= 1) - Unfreeze(this); - } - else if (STAT(FROZEN, this) == 3) + if(IS_PLAYER(this)) { - this.revive_progress = bound(0, this.revive_progress - frametime * this.revive_speed, 1); - this.health = max(0, autocvar_g_nades_ice_health + (start_health-autocvar_g_nades_ice_health) * this.revive_progress ); + if (STAT(FROZEN, this) == 2) + { + this.revive_progress = bound(0, this.revive_progress + frametime * this.revive_speed, 1); + this.health = max(1, this.revive_progress * start_health); + this.iceblock.alpha = bound(0.2, 1 - this.revive_progress, 1); - if (this.health < 1) + if (this.revive_progress >= 1) + Unfreeze(this); + } + else if (STAT(FROZEN, this) == 3) { - if (this.vehicle) - vehicles_exit(this.vehicle, VHEF_RELEASE); - if(this.event_damage) - this.event_damage(this, this, this.frozen_by, 1, DEATH_NADE_ICE_FREEZE.m_id, this.origin, '0 0 0'); + this.revive_progress = bound(0, this.revive_progress - frametime * this.revive_speed, 1); + this.health = max(0, autocvar_g_nades_ice_health + (start_health-autocvar_g_nades_ice_health) * this.revive_progress ); + + if (this.health < 1) + { + if (this.vehicle) + vehicles_exit(this.vehicle, VHEF_RELEASE); + if(this.event_damage) + this.event_damage(this, this, this.frozen_by, 1, DEATH_NADE_ICE_FREEZE.m_id, this.origin, '0 0 0'); + } + else if (this.revive_progress <= 0) + Unfreeze(this); } - else if (this.revive_progress <= 0) - Unfreeze(this); } MUTATOR_CALLHOOK(PlayerPreThink, this); @@ -2557,7 +2573,7 @@ void PlayerPreThink (entity this) this.last_vehiclecheck = time + 1; } - if(!this.cvar_cl_newusekeysupported) // FIXME remove this - it was a stupid idea to begin with, we can JUST use the button + if(!CS(this).cvar_cl_newusekeysupported) // FIXME remove this - it was a stupid idea to begin with, we can JUST use the button { if(PHYS_INPUT_BUTTON_USE(this) && !CS(this).usekeypressed) PlayerUseKey(this);