]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blobdiff - qcsrc/server/client.qc
Fixes the superweapons portion of #2422 "target_items issues"
[xonotic/xonotic-data.pk3dir.git] / qcsrc / server / client.qc
index 1d5e240b3872969166294ccf93211e1d131e3068..bb92c6ba066ee3a25b809fa9d79d76dfc9967ef7 100644 (file)
@@ -334,9 +334,10 @@ void PutObserverInServer(entity this)
        this.fade_time = 0;
        this.pain_frame = 0;
        this.pain_finished = 0;
-       this.strength_finished = 0;
-       this.invincible_finished = 0;
-       this.superweapons_finished = 0;
+       STAT(STRENGTH_FINISHED, this) = 0;
+       STAT(INVINCIBLE_FINISHED, this) = 0;
+       STAT(SUPERWEAPONS_FINISHED, this) = 0;
+       this.air_finished = 0;
        //this.dphitcontentsmask = 0;
        this.dphitcontentsmask = DPCONTENTS_SOLID;
        if (autocvar_g_playerclip_collisions)
@@ -588,7 +589,7 @@ void PutPlayerInServer(entity this)
 
        PS(this).dual_weapons = '0 0 0';
 
-       this.superweapons_finished = (STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS) ? time + autocvar_g_balance_superweapons_time : 0;
+       STAT(SUPERWEAPONS_FINISHED, this) = (STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS) ? time + autocvar_g_balance_superweapons_time : 0;
 
        this.items = start_items;
 
@@ -611,7 +612,8 @@ void PutPlayerInServer(entity this)
        this.respawn_flags = 0;
        this.respawn_time = 0;
        STAT(RESPAWN_TIME, this) = 0;
-       this.scale = autocvar_sv_player_scale;
+       bool q3dfcompat = autocvar_sv_q3defragcompat && autocvar_sv_q3defragcompat_changehitbox;
+       this.scale = ((q3dfcompat) ? 0.9 : autocvar_sv_player_scale);
        this.fade_time = 0;
        this.pain_frame = 0;
        this.pain_finished = 0;
@@ -636,8 +638,8 @@ void PutPlayerInServer(entity this)
        this.punchangle = '0 0 0';
        this.punchvector = '0 0 0';
 
-       this.strength_finished = 0;
-       this.invincible_finished = 0;
+       STAT(STRENGTH_FINISHED, this) = 0;
+       STAT(INVINCIBLE_FINISHED, this) = 0;
        this.fire_endtime = -1;
        STAT(REVIVE_PROGRESS, this) = 0;
        this.revival_time = 0;
@@ -646,7 +648,7 @@ void PutPlayerInServer(entity this)
        STAT(BUFFS, this) = 0;
        STAT(BUFF_TIME, this) = 0;
 
-       this.air_finished = time + 12;
+       this.air_finished = 0;
        this.waterlevel = WATERLEVEL_NONE;
        this.watertype = CONTENT_EMPTY;
 
@@ -1068,7 +1070,7 @@ string getwelcomemessage(entity this)
        return s;
 }
 
-bool autocvar_sv_qcphysics = false; // TODO this is for testing - remove when qcphysics work
+bool autocvar_sv_qcphysics = true; // TODO this is for testing - remove when qcphysics work
 
 /**
 =============
@@ -1107,7 +1109,7 @@ void ClientConnect(entity this)
                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)));
+               GameLogEcho(strcat(":join:", ftos(this.playerid), ":", ftos(etof(this)), ":", ((IS_REAL_CLIENT(this)) ? GameLog_ProcessIP(this.netaddress) : "bot"), ":", playername(this, false)));
 
        CS(this).just_joined = true;  // stop spamming the eventlog with additional lines when the client connects
 
@@ -1413,9 +1415,9 @@ void player_powerups(entity this)
        {
                if (this.items & ITEM_Strength.m_itemid)
                {
-                       play_countdown(this, this.strength_finished, SND_POWEROFF);
+                       play_countdown(this, STAT(STRENGTH_FINISHED, this), SND_POWEROFF);
                        this.effects = this.effects | (EF_BLUE | EF_ADDITIVE | EF_FULLBRIGHT);
-                       if (time > this.strength_finished)
+                       if (time > STAT(STRENGTH_FINISHED, this))
                        {
                                this.items = this.items - (this.items & ITEM_Strength.m_itemid);
                                //Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_POWERDOWN_STRENGTH, this.netname);
@@ -1424,7 +1426,7 @@ void player_powerups(entity this)
                }
                else
                {
-                       if (time < this.strength_finished)
+                       if (time < STAT(STRENGTH_FINISHED, this))
                        {
                                this.items = this.items | ITEM_Strength.m_itemid;
                                if(!g_cts)
@@ -1434,9 +1436,9 @@ void player_powerups(entity this)
                }
                if (this.items & ITEM_Shield.m_itemid)
                {
-                       play_countdown(this, this.invincible_finished, SND_POWEROFF);
+                       play_countdown(this, STAT(INVINCIBLE_FINISHED, this), SND_POWEROFF);
                        this.effects = this.effects | (EF_RED | EF_ADDITIVE | EF_FULLBRIGHT);
-                       if (time > this.invincible_finished)
+                       if (time > STAT(INVINCIBLE_FINISHED, this))
                        {
                                this.items = this.items - (this.items & ITEM_Shield.m_itemid);
                                //Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_POWERDOWN_SHIELD, this.netname);
@@ -1445,7 +1447,7 @@ void player_powerups(entity this)
                }
                else
                {
-                       if (time < this.invincible_finished)
+                       if (time < STAT(INVINCIBLE_FINISHED, this))
                        {
                                this.items = this.items | ITEM_Shield.m_itemid;
                                if(!g_cts)
@@ -1457,7 +1459,7 @@ void player_powerups(entity this)
                {
                        if (!(STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS))
                        {
-                               this.superweapons_finished = 0;
+                               STAT(SUPERWEAPONS_FINISHED, this) = 0;
                                this.items = this.items - (this.items & IT_SUPERWEAPON);
                                //Send_Notification(NOTIF_ALL, NULL, MSG_INFO, INFO_SUPERWEAPON_LOST, this.netname);
                                Send_Notification(NOTIF_ONE, this, MSG_CENTER, CENTER_SUPERWEAPON_LOST);
@@ -1468,8 +1470,8 @@ void player_powerups(entity this)
                        }
                        else
                        {
-                               play_countdown(this, this.superweapons_finished, SND_POWEROFF);
-                               if (time > this.superweapons_finished)
+                               play_countdown(this, STAT(SUPERWEAPONS_FINISHED, this), SND_POWEROFF);
+                               if (time > STAT(SUPERWEAPONS_FINISHED, this))
                                {
                                        this.items = this.items - (this.items & IT_SUPERWEAPON);
                                        STAT(WEAPONS, this) &= ~WEPSET_SUPERWEAPONS;
@@ -1480,7 +1482,7 @@ void player_powerups(entity this)
                }
                else if(STAT(WEAPONS, this) & WEPSET_SUPERWEAPONS)
                {
-                       if (time < this.superweapons_finished || (this.items & IT_UNLIMITED_SUPERWEAPONS))
+                       if (time < STAT(SUPERWEAPONS_FINISHED, this) || (this.items & IT_UNLIMITED_SUPERWEAPONS))
                        {
                                this.items = this.items | IT_SUPERWEAPON;
                                if(!(this.items & IT_UNLIMITED_SUPERWEAPONS))
@@ -1492,13 +1494,13 @@ void player_powerups(entity this)
                        }
                        else
                        {
-                               this.superweapons_finished = 0;
+                               STAT(SUPERWEAPONS_FINISHED, this) = 0;
                                STAT(WEAPONS, this) &= ~WEPSET_SUPERWEAPONS;
                        }
                }
                else
                {
-                       this.superweapons_finished = 0;
+                       STAT(SUPERWEAPONS_FINISHED, this) = 0;
                }
        }
 
@@ -1535,8 +1537,10 @@ float CalcRot(float current, float stable, float rotfactor, float rotframetime)
                return max(stable, current + (stable - current) * rotfactor * rotframetime);
 }
 
-float CalcRotRegen(float current, float regenstable, float regenfactor, float regenlinear, float regenframetime, float rotstable, float rotfactor, float rotlinear, float rotframetime, float limit)
+void RotRegen(entity this, int res, float regenstable, float regenfactor, float regenlinear, float regenframetime, float rotstable, float rotfactor, float rotlinear, float rotframetime, float limit_mod)
 {
+       float old = GetResource(this, res);
+       float current = old;
        if(current > rotstable)
        {
                if(rotframetime > 0)
@@ -1554,10 +1558,12 @@ float CalcRotRegen(float current, float regenstable, float regenfactor, float re
                }
        }
 
+       float limit = GetResourceLimit(this, res) * limit_mod;
        if(current > limit)
                current = limit;
 
-       return current;
+       if (current != old)
+               SetResource(this, res, current);
 }
 
 void player_regen(entity this)
@@ -1587,23 +1593,16 @@ void player_regen(entity this)
        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 = GetResourceLimit(this, RES_HEALTH);
-               limita = GetResourceLimit(this, RES_ARMOR);
+               float maxa = autocvar_g_balance_armor_rotstable;
+               float mina = autocvar_g_balance_armor_regenstable;
 
-               regen_health_rotstable = regen_health_rotstable * max_mod;
-               regen_health_stable = regen_health_stable * max_mod;
-               limith = limith * limit_mod;
-               limita = limita * limit_mod;
+               RotRegen(this, RES_ARMOR, mina, autocvar_g_balance_armor_regen, autocvar_g_balance_armor_regenlinear,
+                       regen_mod * frametime * (time > this.pauseregen_finished), maxa, autocvar_g_balance_armor_rot, autocvar_g_balance_armor_rotlinear,
+                       rot_mod * frametime * (time > this.pauserotarmor_finished), limit_mod);
 
-               SetResource(this, RES_ARMOR, CalcRotRegen(GetResource(this, RES_ARMOR), mina, autocvar_g_balance_armor_regen, autocvar_g_balance_armor_regenlinear, 
-                                                                       regen_mod * frametime * (time > this.pauseregen_finished), maxa, autocvar_g_balance_armor_rot, autocvar_g_balance_armor_rotlinear,
-                                                                       rot_mod * frametime * (time > this.pauserotarmor_finished), limita));
-               SetResource(this, RES_HEALTH, CalcRotRegen(GetResource(this, RES_HEALTH), regen_health_stable, regen_health, regen_health_linear,
-                                                                       regen_mod * frametime * (time > this.pauseregen_finished), regen_health_rotstable, regen_health_rot, regen_health_rotlinear,
-                                                                       rot_mod * frametime * (time > this.pauserothealth_finished), limith));
+               RotRegen(this, RES_HEALTH, regen_health_stable * max_mod, regen_health, regen_health_linear,
+                       regen_mod * frametime * (time > this.pauseregen_finished), regen_health_rotstable * max_mod, regen_health_rot, regen_health_rotlinear,
+                       rot_mod * frametime * (time > this.pauserothealth_finished), limit_mod);
        }
 
        // if player rotted to death...  die!
@@ -1618,15 +1617,12 @@ void player_regen(entity this)
 
        if (!(this.items & IT_UNLIMITED_AMMO))
        {
-               float minf, maxf, limitf;
+               float maxf = autocvar_g_balance_fuel_rotstable;
+               float minf = autocvar_g_balance_fuel_regenstable;
 
-               maxf = autocvar_g_balance_fuel_rotstable;
-               minf = autocvar_g_balance_fuel_regenstable;
-               limitf = GetResourceLimit(this, RES_FUEL);
-
-               SetResource(this, RES_FUEL, CalcRotRegen(GetResource(this, RES_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));
+               RotRegen(this, RES_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), 1);
        }
 }
 
@@ -1686,9 +1682,10 @@ void SpectateCopy(entity this, entity spectatee)
        this.items = spectatee.items;
        STAT(LAST_PICKUP, this) = STAT(LAST_PICKUP, spectatee);
        STAT(HIT_TIME, this) = STAT(HIT_TIME, spectatee);
-       this.strength_finished = spectatee.strength_finished;
-       this.invincible_finished = spectatee.invincible_finished;
-       this.superweapons_finished = spectatee.superweapons_finished;
+       STAT(STRENGTH_FINISHED, this) = STAT(STRENGTH_FINISHED, spectatee);
+       STAT(INVINCIBLE_FINISHED, this) = STAT(INVINCIBLE_FINISHED, spectatee);
+       STAT(SUPERWEAPONS_FINISHED, this) = STAT(SUPERWEAPONS_FINISHED, spectatee);
+       this.air_finished = spectatee.air_finished;
        STAT(PRESSED_KEYS, this) = STAT(PRESSED_KEYS, spectatee);
        STAT(WEAPONS, this) = STAT(WEAPONS, spectatee);
        this.punchangle = spectatee.punchangle;
@@ -1780,6 +1777,11 @@ void SetSpectatee_status(entity this, int spectatee_num)
 
        if (CS(this).spectatee_status != oldspectatee_status)
        {
+               if (STAT(PRESSED_KEYS, this))
+               {
+                       CS(this).pressedkeys = 0;
+                       STAT(PRESSED_KEYS, this) = 0;
+               }
                ClientData_Touch(this);
                if (g_race || g_cts) race_InitSpectator();
        }
@@ -1987,11 +1989,11 @@ int nJoinAllowed(entity this, entity ignore)
        else if(currentlyPlaying < player_limit)
                free_slots = min(maxclients - totalClients, player_limit - currentlyPlaying);
 
-       static float join_prevent_msg_time = 0;
-       if(this && ignore && !free_slots && time > join_prevent_msg_time)
+       static float msg_time = 0;
+       if(this && !this.caplayer && ignore && !free_slots && time > msg_time)
        {
                Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_JOIN_PREVENT);
-               join_prevent_msg_time = time + 3;
+               msg_time = time + 0.5;
        }
 
        return free_slots;
@@ -2021,7 +2023,7 @@ void PrintWelcomeMessage(entity this)
                if (autocvar_g_campaign) {
                        if ((IS_PLAYER(this) && PHYS_INPUT_BUTTON_INFO(this)) || (!IS_PLAYER(this))) {
                                CS(this).motd_actived_time = time;
-                               Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_MOTD, campaign_message);
+                               Send_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CENTER_CAMPAIGN_MESSAGE, Campaign_GetMessage(), Campaign_GetLevelNum());
                        }
                } else {
                        if (PHYS_INPUT_BUTTON_INFO(this)) {
@@ -2037,7 +2039,7 @@ void PrintWelcomeMessage(entity this)
                                CS(this).motd_actived_time = time;
                        else if ((time - CS(this).motd_actived_time > 2) && IS_PLAYER(this)) { // hide it some seconds after BUTTON_INFO has been released
                                CS(this).motd_actived_time = 0;
-                               Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_MOTD);
+                               Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_CAMPAIGN_MESSAGE);
                        }
                } else {
                        if (PHYS_INPUT_BUTTON_INFO(this))
@@ -2056,7 +2058,10 @@ void PrintWelcomeMessage(entity this)
                {
                        // instantly hide MOTD
                        CS(this).motd_actived_time = 0;
-                       Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_MOTD);
+                       if (autocvar_g_campaign)
+                               Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_CAMPAIGN_MESSAGE);
+                       else
+                               Kill_Notification(NOTIF_ONE_ONLY, this, MSG_CENTER, CPID_MOTD);
                }
                else if (IS_PLAYER(this) || IS_SPEC(this))
                {
@@ -2266,7 +2271,8 @@ void ObserverThink(entity this)
                        if(this.flags & FL_SPAWNING)
                        {
                                this.flags &= ~FL_SPAWNING;
-                               Join(this);
+                               if(joinAllowed(this))
+                                       Join(this);
                                return;
                        }
                }
@@ -2605,16 +2611,21 @@ void DrownPlayer(entity this)
 
        if (this.waterlevel != WATERLEVEL_SUBMERGED || this.vehicle)
        {
-               if(this.air_finished < time)
+               if(this.air_finished && this.air_finished < time)
                        PlayerSound(this, playersound_gasp, CH_PLAYER, VOL_BASE, VOICETYPE_PLAYERSOUND);
-               this.air_finished = time + autocvar_g_balance_contents_drowndelay;
+               this.air_finished = 0;
        }
-       else if (this.air_finished < time)
-       {       // drown!
-               if (this.pain_finished < time)
-               {
-                       Damage (this, NULL, NULL, autocvar_g_balance_contents_playerdamage_drowning * autocvar_g_balance_contents_damagerate, DEATH_DROWN.m_id, DMG_NOWEP, this.origin, '0 0 0');
-                       this.pain_finished = time + 0.5;
+       else
+       {
+               if (!this.air_finished)
+                       this.air_finished = time + autocvar_g_balance_contents_drowndelay;
+               if (this.air_finished < time)
+               {       // drown!
+                       if (this.pain_finished < time)
+                       {
+                               Damage (this, NULL, NULL, autocvar_g_balance_contents_playerdamage_drowning * autocvar_g_balance_contents_damagerate, DEATH_DROWN.m_id, DMG_NOWEP, this.origin, '0 0 0');
+                               this.pain_finished = time + 0.5;
+                       }
                }
        }
 }
@@ -2719,6 +2730,11 @@ void PlayerPostThink (entity this)
                }
                GetPressedKeys(this);
        }
+       else if (IS_OBSERVER(this) && STAT(PRESSED_KEYS, this))
+       {
+               CS(this).pressedkeys = 0;
+               STAT(PRESSED_KEYS, this) = 0;
+       }
 
        if (this.waypointsprite_attachedforcarrier) {
                float hp = healtharmor_maxdamage(GetResource(this, RES_HEALTH), GetResource(this, RES_ARMOR), autocvar_g_balance_armor_blockpercent, DEATH_WEAPON.m_id).x;