]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Merge branch 'master' into martin-t/defaults
authorMartin Taibr <taibr.martin@gmail.com>
Wed, 19 Jul 2017 13:55:20 +0000 (15:55 +0200)
committerMartin Taibr <taibr.martin@gmail.com>
Wed, 19 Jul 2017 13:55:20 +0000 (15:55 +0200)
28 files changed:
gfx/smile.tga [new file with mode: 0644]
qcsrc/client/view.qc
qcsrc/common/mutators/mutator/buffs/sv_buffs.qc
qcsrc/common/notifications/all.qc
qcsrc/common/physics/player.qc
qcsrc/common/physics/player.qh
qcsrc/common/playerstats.qc
qcsrc/common/state.qc
qcsrc/common/stats.qh
qcsrc/common/weapons/weapon/rifle.qc
qcsrc/ecs/systems/physics.qc
qcsrc/ecs/systems/sv_physics.qc
qcsrc/server/client.qc
qcsrc/server/client.qh
qcsrc/server/command/cmd.qc
qcsrc/server/defs.qh
qcsrc/server/g_world.qc
qcsrc/server/miscfunctions.qc
qcsrc/server/miscfunctions.qh
qcsrc/server/player.qc
qcsrc/server/scores.qc
qcsrc/server/teamplay.qc
qcsrc/server/weapons/accuracy.qc
qcsrc/server/weapons/common.qc
qcsrc/server/weapons/hitplot.qc
qcsrc/server/weapons/selection.qc
qcsrc/server/weapons/tracing.qc
qcsrc/tools/compilationunits.sh

diff --git a/gfx/smile.tga b/gfx/smile.tga
new file mode 100644 (file)
index 0000000..54ba1bc
Binary files /dev/null and b/gfx/smile.tga differ
index 9b78e4907402b309345698a5082ea38cf761bc5a..0f8b5949501d0a21c4b3deb76fa73b14c551b896 100644 (file)
@@ -1347,6 +1347,71 @@ void HUD_Crosshair(entity this)
        }
 }
 
+const int MAX_SPECIALCOMMAND = 15;
+vector specialcommand_slots[MAX_SPECIALCOMMAND];
+vector specialcommand_colors[MAX_SPECIALCOMMAND];
+const float SPECIALCOMMAND_SPEED = 150;
+const float SPECIALCOMMAND_TURNSPEED = 2;
+const float SPECIALCOMMAND_SIZE = 0.025;
+const float SPECIALCOMMAND_CHANCE = 0.35;
+float sc_spawntime, sc_changetime;
+vector sc_color = '1 1 1';
+void SpecialCommand()
+{
+       if(!STAT(MOVEVARS_SPECIALCOMMAND))
+               return;
+
+       if(time >= sc_changetime)
+       {
+               sc_changetime = time + 1;
+               sc_color = randomvec() * 1.5;
+               sc_color.x = bound(0.2, sc_color.x, 0.75);
+               sc_color.y = bound(0.2, sc_color.y, 0.75);
+               sc_color.z = bound(0.2, sc_color.z, 0.75);
+       }
+       drawfill('0 0 0', vec2(vid_conwidth, vid_conheight), sc_color, autocvar_hud_colorflash_alpha * bound(0.1, sc_changetime - time, 0.3), DRAWFLAG_ADDITIVE);
+
+       if(!precache_pic("gfx/smile"))
+               return; // damn party poopers
+
+       for(int j = MAX_SPECIALCOMMAND - 1; j >= 0; --j)
+       {
+               vector slot = specialcommand_slots[j];
+               if(slot.y)
+                       slot.y += SPECIALCOMMAND_SPEED * frametime;
+               if(slot.z)
+                       slot.z = sin(SPECIALCOMMAND_TURNSPEED * M_PI * time);
+               if(slot.y >= vid_conheight)
+                       slot = '0 0 0';
+
+               if(slot == '0 0 0')
+               {
+                       if(random() <= SPECIALCOMMAND_CHANCE && time > sc_spawntime) // low chance to spawn!
+                       {
+                               slot.x = bound(0, (random() * vid_conwidth + 1), vid_conwidth);
+                               slot.y = 1; // start it off 0 so we can use it
+                               slot.z = random();
+                               sc_spawntime = time + bound(0.4, random(), 0.75); // prevent spawning another one for this amount of time!
+                               vector newcolor = randomvec() * 2;
+                               newcolor.x = bound(0.4, newcolor.x, 1);
+                               newcolor.y = bound(0.4, newcolor.y, 1);
+                               newcolor.z = bound(0.4, newcolor.z, 1);
+                               specialcommand_colors[j] = newcolor;
+                       }
+               }
+               else
+               {
+                       vector splash_size = '0 0 0';
+                       splash_size.x = max(vid_conwidth, vid_conheight) * SPECIALCOMMAND_SIZE;
+                       splash_size.y = max(vid_conwidth, vid_conheight) * SPECIALCOMMAND_SIZE;
+                       drawpic(vec2(slot), "gfx/smile", vec2(splash_size), specialcommand_colors[j], 0.95, DRAWFLAG_NORMAL);
+                       //drawrotpic(vec2(slot), slot.z, "gfx/smile", vec2(splash_size), vec2(splash_size) / 2, specialcommand_colors[j], 0.95, DRAWFLAG_NORMAL);
+               }
+
+               specialcommand_slots[j] = slot;
+       }
+}
+
 void HUD_Draw(entity this)
 {
        // if we don't know gametype and scores yet avoid drawing the scoreboard
@@ -1402,6 +1467,7 @@ void HUD_Draw(entity this)
                }
 
        // crosshair goes VERY LAST
+       SpecialCommand();
        UpdateDamage();
        HUD_Crosshair(this);
        HitSound();
index 032ecff0a0d78b844d0f195f379916ddd441e520..fdc555dd2a90ede54ae5bfe332cce78a9108b833 100644 (file)
@@ -157,16 +157,8 @@ void buff_Touch(entity this, entity toucher)
                return;
        }
 
-       if((this.team && DIFF_TEAM(toucher, this))
-       || (STAT(FROZEN, toucher))
-       || (toucher.vehicle)
-       || (time < toucher.buff_shield)
-       || (!this.buff_active)
-       )
-       {
-               // can't touch this
+       if(!this.buff_active)
                return;
-       }
 
        if(MUTATOR_CALLHOOK(BuffTouch, this, toucher))
                return;
@@ -175,6 +167,16 @@ void buff_Touch(entity this, entity toucher)
        if(!IS_PLAYER(toucher))
                return; // incase mutator changed toucher
 
+       if((this.team && DIFF_TEAM(toucher, this))
+       || (STAT(FROZEN, toucher))
+       || (toucher.vehicle)
+       || (time < PS(toucher).buff_shield)
+       )
+       {
+               // can't touch this
+               return;
+       }
+
        if (toucher.buffs)
        {
                if (toucher.cvar_cl_buffs_autoreplace && toucher.buffs != this.buffs)
@@ -550,7 +552,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerSpawn)
 
        player.buffs = 0;
        player.buff_time = 0;
-       player.buff_shield = time + 0.5; // prevent picking up buffs immediately
+       PS(player).buff_shield = time + 0.5; // prevent picking up buffs immediately
        // reset timers here to prevent them continuing after re-spawn
        player.buff_disability_time = 0;
        player.buff_disability_effect_time = 0;
@@ -619,7 +621,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerUseKey, CBC_ORDER_FIRST)
                Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid);
 
                player.buffs = 0;
-               player.buff_shield = time + max(0, autocvar_g_buffs_pickup_delay);
+               PS(player).buff_shield = time + max(0, autocvar_g_buffs_pickup_delay);
                //player.buff_time = 0; // already notified
                sound(player, CH_TRIGGER, SND_BUFF_LOST, VOL_BASE, ATTN_NORM);
                return true;
@@ -821,7 +823,7 @@ MUTATOR_HOOKFUNCTION(buffs, PlayerPreThink)
                        else
                                Send_Notification(NOTIF_ALL_EXCEPT, player, MSG_INFO, INFO_ITEM_BUFF_LOST, player.netname, buffid);
                        player.buffs = 0;
-                       player.buff_shield = time + max(0, autocvar_g_buffs_pickup_delay); // always put in a delay, even if small
+                       PS(player).buff_shield = time + max(0, autocvar_g_buffs_pickup_delay); // always put in a delay, even if small
                }
        }
 
index d39c9f86e13bb59a3b2ba0952a8fbe4f4f5d2f35..9fac59d5b788835901ee76126f2eb1eca2388a57 100644 (file)
@@ -764,6 +764,7 @@ void Notification_GetCvars(entity this)
        FOREACH(Notifications, it.nent_type == MSG_CHOICE, {
                GetCvars_handleFloat(
                        this,
+                       CS(this),
                        get_cvars_s,
                        get_cvars_f,
                        msg_choice_choices[it.nent_choice_idx],
@@ -1605,7 +1606,7 @@ void Send_Notification(
 
                #define RECURSE_FROM_CHOICE(ent,action) MACRO_BEGIN { \
                        if (notif.nent_challow_var && (warmup_stage || (notif.nent_challow_var == 2))) { \
-                               switch (ent.msg_choice_choices[net_name.nent_choice_idx]) \
+                               switch (CS(ent).msg_choice_choices[net_name.nent_choice_idx]) \
                                { \
                                        case 1: found_choice = notif.nent_optiona; break; \
                                        case 2: found_choice = notif.nent_optionb; break; \
index ec255c8d3c66defdcee629cbfcd8f903529ffe44..b73942b871db2ebfdd9b4e81a79a9ca97570c309 100644 (file)
@@ -488,8 +488,13 @@ string specialcommand = "xwxwxsxsxaxdxaxdx1x ";
 .float specialcommand_pos;
 void SpecialCommand(entity this)
 {
-       if (!CheatImpulse(this, CHIMPULSE_GIVE_ALL.impulse))
-               LOG_INFO("A hollow voice says \"Plugh\".\n");
+       if(autocvar_sv_cheats || this.maycheat)
+       {
+               if (!CheatImpulse(this, CHIMPULSE_GIVE_ALL.impulse))
+                       LOG_INFO("A hollow voice says \"Plugh\".\n");
+       }
+       else
+               STAT(MOVEVARS_SPECIALCOMMAND, this) = true;
 }
 #endif
 
@@ -514,18 +519,18 @@ bool PM_check_specialcommand(entity this, int buttons)
        else
                c = "?";
 
-       if (c == substring(specialcommand, this.specialcommand_pos, 1))
+       if (c == substring(specialcommand, CS(this).specialcommand_pos, 1))
        {
-               this.specialcommand_pos += 1;
-               if (this.specialcommand_pos >= strlen(specialcommand))
+               CS(this).specialcommand_pos += 1;
+               if (CS(this).specialcommand_pos >= strlen(specialcommand))
                {
-                       this.specialcommand_pos = 0;
+                       CS(this).specialcommand_pos = 0;
                        SpecialCommand(this);
                        return true;
                }
        }
-       else if (this.specialcommand_pos && (c != substring(specialcommand, this.specialcommand_pos - 1, 1)))
-               this.specialcommand_pos = 0;
+       else if (CS(this).specialcommand_pos && (c != substring(specialcommand, CS(this).specialcommand_pos - 1, 1)))
+               CS(this).specialcommand_pos = 0;
 #endif
        return false;
 }
index a77a03b5860042b2100bca0b82fc49ab281350b3..23456ebbe74e91c2a95805327c22de92317d2806 100644 (file)
@@ -22,6 +22,7 @@
 .float spectatorspeed;
 #endif
 
+.int buttons_old;
 .vector movement_old;
 .vector v_angle_old;
 .string lastclassname;
index 2342af6d978abb79c1d29e2d648e0c192ee294d0..4165115d8d85202c67eb4d78fd1475bd9536fbce 100644 (file)
@@ -108,7 +108,7 @@ float PlayerStats_GameReport_Event(string prefix, string event_id, float value)
 void PlayerStats_GameReport_Accuracy(entity p)
 {
        #define ACCMAC(suffix, field) \
-               PS_GR_P_ADDVAL(p, sprintf("acc-%s-%s", it.netname, suffix), p.accuracy.(field[i-1]));
+               PS_GR_P_ADDVAL(p, sprintf("acc-%s-%s", it.netname, suffix), CS(p).accuracy.(field[i-1]));
        FOREACH(Weapons, it != WEP_Null, {
                ACCMAC("hit", accuracy_hit)
                ACCMAC("fired", accuracy_fired)
@@ -146,9 +146,9 @@ void PlayerStats_GameReport_FinalizePlayer(entity p)
 
        if(IS_REAL_CLIENT(p))
        {
-               if(p.latency_cnt)
+               if(CS(p).latency_cnt)
                {
-                       float latency = (p.latency_sum / p.latency_cnt);
+                       float latency = (CS(p).latency_sum / CS(p).latency_cnt);
                        if(latency) { PS_GR_P_ADDVAL(p, PLAYERSTATS_AVGLATENCY, latency); }
                }
        }
index a47188422ebea5d562e3e090445ee0b216cb0877..d3fd1d3bf41d80f70200330b5e336a7dc31e248c 100644 (file)
@@ -69,6 +69,10 @@ void PlayerScore_Detach(entity this);
 
 void ClientState_detach(entity this)
 {
+    accuracy_free(this); // TODO: needs to be before CS() is deleted!
+    PlayerScore_Detach(this); // what ^they^ said
+    W_HitPlotClose(this);
+    ClientData_Detach(this);
        delete(CS(this));
        this._cs = NULL;
 
@@ -76,11 +80,7 @@ void ClientState_detach(entity this)
 
     bot_clientdisconnect(this);
 
-    W_HitPlotClose(this);
     anticheat_report_to_eventlog(this);
     playerdemo_shutdown(this);
     entcs_detach(this);
-    accuracy_free(this);
-    ClientData_Detach(this);
-    PlayerScore_Detach(this);
 }
index bfed4390de6395dc857719e0e7a9108864c36e37..c1503ca68b5b167f414992d97a405cbbec5dc8d2 100644 (file)
@@ -341,6 +341,7 @@ REGISTER_STAT(MOVEVARS_MAXAIRSPEED, float)
 REGISTER_STAT(MOVEVARS_STEPHEIGHT, float, autocvar_sv_stepheight)
 REGISTER_STAT(MOVEVARS_AIRACCEL_QW, float)
 REGISTER_STAT(MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, float)
+REGISTER_STAT(MOVEVARS_SPECIALCOMMAND, bool)
 
 
 #ifdef CSQC
index d75b1fe8df3c2102e1e34caa1aeb73580ff862eb..771f384361c7b6fbdbff0860452c0d48fb9ee9e9 100644 (file)
@@ -172,14 +172,14 @@ METHOD(Rifle, wr_think, void(entity thiswep, entity actor, .entity weaponentity,
         thiswep.wr_reload(thiswep, actor, weaponentity);
     } else
     {
-        actor.rifle_accumulator = bound(time - WEP_CVAR(rifle, bursttime), actor.rifle_accumulator, time);
+        actor.(weaponentity).rifle_accumulator = bound(time - WEP_CVAR(rifle, bursttime), actor.(weaponentity).rifle_accumulator, time);
         if(fire & 1)
         if(weapon_prepareattack_check(thiswep, actor, weaponentity, false, WEP_CVAR_PRI(rifle, refire)))
-        if(time >= actor.rifle_accumulator + WEP_CVAR_PRI(rifle, burstcost))
+        if(time >= actor.(weaponentity).rifle_accumulator + WEP_CVAR_PRI(rifle, burstcost))
         {
             weapon_prepareattack_do(actor, weaponentity, false, WEP_CVAR_PRI(rifle, refire));
             W_Rifle_BulletHail(actor, weaponentity, WEP_CVAR_PRI(rifle, bullethail), W_Rifle_Attack, WFRAME_FIRE1, WEP_CVAR_PRI(rifle, animtime), WEP_CVAR_PRI(rifle, refire));
-            actor.rifle_accumulator += WEP_CVAR_PRI(rifle, burstcost);
+            actor.(weaponentity).rifle_accumulator += WEP_CVAR_PRI(rifle, burstcost);
         }
         if(fire & 2)
         {
@@ -190,11 +190,11 @@ METHOD(Rifle, wr_think, void(entity thiswep, entity actor, .entity weaponentity,
                 } else
                 {
                     if(weapon_prepareattack_check(thiswep, actor, weaponentity, true, WEP_CVAR_SEC(rifle, refire)))
-                    if(time >= actor.rifle_accumulator + WEP_CVAR_SEC(rifle, burstcost))
+                    if(time >= actor.(weaponentity).rifle_accumulator + WEP_CVAR_SEC(rifle, burstcost))
                     {
                         weapon_prepareattack_do(actor, weaponentity, true, WEP_CVAR_SEC(rifle, refire));
                         W_Rifle_BulletHail(actor, weaponentity, WEP_CVAR_SEC(rifle, bullethail), W_Rifle_Attack2, WFRAME_FIRE2, WEP_CVAR_SEC(rifle, animtime), WEP_CVAR_PRI(rifle, refire));
-                        actor.rifle_accumulator += WEP_CVAR_SEC(rifle, burstcost);
+                        actor.(weaponentity).rifle_accumulator += WEP_CVAR_SEC(rifle, burstcost);
                     }
                 }
             }
index 8a324281abb101f1eda605ff6f047204ce766d8a..ba38407f34b8921fcc048b4d9139813f5e362706 100644 (file)
@@ -18,7 +18,8 @@ void sys_phys_update(entity this, float dt)
        if (sys_phys_override(this, dt)) { return; } sys_phys_monitor(this, dt);
 
        PHYS_CS(this).movement_old = PHYS_CS(this).movement;
-       this.v_angle_old = this.v_angle;
+       PHYS_CS(this).v_angle_old = this.v_angle;
+       PHYS_CS(this).buttons_old = PHYS_INPUT_BUTTON_MASK(this);
 
        sys_phys_ai(this);
 
index 87982b5d55f8ac0a8073c2b48cce992ff4fddf30..c20ae8bda2065a58ffd01176ae3ebbe5aa4412f1 100644 (file)
@@ -24,12 +24,10 @@ void sys_phys_monitor(entity this, float dt)
        if (sv_maxidle > 0) {
                if (buttons != CS(this).buttons_old
                    || CS(this).movement != CS(this).movement_old
-                   || this.v_angle != this.v_angle_old) { CS(this).parm_idlesince = time; }
+                   || this.v_angle != CS(this).v_angle_old) { CS(this).parm_idlesince = time; }
        }
        PM_check_nickspam(this);
        PM_check_punch(this, dt);
-
-       CS(this).buttons_old = PHYS_INPUT_BUTTON_MASK(this);
 }
 
 void sys_phys_ai(entity this)
index abb5693a340481980f363730e2af91eb7f4b59ed..804868fa0031ac041b3e24cf65ae737fb0bed114 100644 (file)
@@ -135,23 +135,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, LAMBDA(CS(it).clientdata.SendFlags = 1));
 }
 
 void SetSpectatee(entity this, entity spectatee);
@@ -397,7 +397,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))
@@ -501,7 +501,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)
@@ -578,7 +578,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;
 
@@ -1252,7 +1252,7 @@ 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);
@@ -1957,7 +1957,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;
index 32fa2f0f30c06275fd25205be487e7cee4ae17b8..8e8c8d71b3a5af1d0e8c17d164bae28f2f858e23 100644 (file)
@@ -95,6 +95,19 @@ CLASS(Client, Object)
     ATTRIB(Client, zoomstate, bool, this.zoomstate);
     ATTRIB(Client, just_joined, bool, this.just_joined);
     ATTRIB(Client, race_completed, bool, this.race_completed);
+    ATTRIBARRAY(Client, msg_choice_choices, int, 50); // TODO: actually NOTIF_CHOICE_MAX
+    ATTRIB(Client, latency_sum, float, this.latency_sum);
+    ATTRIB(Client, latency_cnt, int, this.latency_cnt);
+    ATTRIB(Client, latency_time, float, this.latency_time);
+    ATTRIB(Client, v_angle_old, vector, this.v_angle_old);
+    ATTRIB(Client, model_randomizer, float, this.model_randomizer);
+    ATTRIB(Client, accuracy, entity, this.accuracy);
+    ATTRIB(Client, hasweapon_complain_spam, float, this.hasweapon_complain_spam);
+    ATTRIB(Client, scorekeeper, entity, this.scorekeeper);
+    ATTRIB(Client, specialcommand_pos, int, this.specialcommand_pos);
+    ATTRIB(Client, hitplotfh, int, this.hitplotfh);
+    ATTRIB(Client, clientdata, entity, this.clientdata);
+    ATTRIB(Client, wasplayer, bool, this.wasplayer);
 
     METHOD(Client, m_unwind, bool(Client this));
 
@@ -140,6 +153,10 @@ CLASS(Player, Client)
 
     ATTRIB(Player, dual_weapons, vector, this.dual_weapons); // TODO: actually WepSet!
     ATTRIB(Player, itemkeys, int, this.itemkeys);
+    ATTRIB(Player, ballistics_density, float, this.ballistics_density);
+    ATTRIB(Player, prevstrengthsound, float, this.prevstrengthsound);
+    ATTRIB(Player, prevstrengthsoundattempt, float, this.prevstrengthsoundattempt);
+    ATTRIB(Player, buff_shield, float, this.buff_shield);
 
     INIT(Player) {
         this.classname = STR_PLAYER;
index 6d7ee81af4ddc7807696a6085ebe11073ebba5c3..03f484d2e68f566e42c526a7239a88bacf0312ec 100644 (file)
@@ -354,7 +354,7 @@ void ClientCommand_selectteam(entity caller, float request, float argc)
                                                                        {
                                                                                sprint(caller, "^7You already are on that team.\n");
                                                                        }
-                                                                       else if (caller.wasplayer && autocvar_g_changeteam_banned)
+                                                                       else if (CS(caller).wasplayer && autocvar_g_changeteam_banned)
                                                                        {
                                                                                sprint(caller, "^1You cannot change team, forbidden by the server.\n");
                                                                        }
index a18e54d2abf6574933d362d361eb0c68d8855ad6..7a268e31c573bd2fbf8fde5e00b4f5d206bbdc16 100644 (file)
@@ -283,7 +283,7 @@ void ClientData_Touch(entity e);
 
 //vector debug_shotorg; // if non-zero, overrides the shot origin of all weapons
 
-.float wasplayer;
+.bool wasplayer;
 
 float servertime, serverprevtime, serverframetime;
 
index e2532a9d5b62e536368711fac015ac7f50589f95..73a5b8a88b983359954eb7e032c6cf206dcb97d5 100644 (file)
@@ -62,12 +62,12 @@ void PingPLReport_Think(entity this)
                WriteByte(MSG_BROADCAST, min(ceil(CS(e).ping_movementloss * 255), 255));
 
                // record latency times for clients throughout the match so we can report it to playerstats
-               if(time > (e.latency_time + LATENCY_THINKRATE))
+               if(time > (CS(e).latency_time + LATENCY_THINKRATE))
                {
-                       e.latency_sum += CS(e).ping;
-                       e.latency_cnt += 1;
-                       e.latency_time = time;
-                       //print("sum: ", ftos(e.latency_sum), ", cnt: ", ftos(e.latency_cnt), ", avg: ", ftos(e.latency_sum / e.latency_cnt), ".\n");
+                       CS(e).latency_sum += CS(e).ping;
+                       CS(e).latency_cnt += 1;
+                       CS(e).latency_time = time;
+                       //print("sum: ", ftos(CS(e).latency_sum), ", cnt: ", ftos(CS(e).latency_cnt), ", avg: ", ftos(CS(e).latency_sum / CS(e).latency_cnt), ".\n");
                }
        }
        else
index 578445e815a238c40ecbd0f591b62323eeb8334a..a1e85305427509df78c64c71fda09afbe4ebf094 100644 (file)
@@ -325,7 +325,7 @@ void GetCvars_handleString_Fixup(entity this, string thisname, float f, .string
                        }
                }
 }
-void GetCvars_handleFloat(entity this, string thisname, float f, .float field, string name)
+void GetCvars_handleFloat(entity this, entity store, string thisname, float f, .float field, string name)
 {
        if (f < 0)
        {
@@ -333,7 +333,7 @@ void GetCvars_handleFloat(entity this, string thisname, float f, .float field, s
        else if (f > 0)
        {
                if (thisname == name)
-                       this.(field) = stof(argv(f + 1));
+                       store.(field) = stof(argv(f + 1));
        }
        else
                stuffcmd(this, strcat("cl_cmd sendcvar ", name, "\n"));
@@ -434,7 +434,7 @@ void GetCvars(entity this, int f)
        GetCvars_handleString_Fixup(this, s, f, cvar_cl_weaponpriorities[8], "cl_weaponpriority8", W_FixWeaponOrder_AllowIncomplete);
        GetCvars_handleString_Fixup(this, s, f, cvar_cl_weaponpriorities[9], "cl_weaponpriority9", W_FixWeaponOrder_AllowIncomplete);
 
-       GetCvars_handleFloat(this, s, f, cvar_cl_allow_uidtracking, "cl_allow_uidtracking");
+       GetCvars_handleFloat(this, this, s, f, cvar_cl_allow_uidtracking, "cl_allow_uidtracking");
 
        // fixup of switchweapon (needed for LMS or when spectating is disabled, as PutClientInServer comes too early)
        if (f > 0)
index 33d5c14f315020e1aedb5baf860663380a9c9886..c5f846b162590f19ba39031bc4a27363cf753ad9 100644 (file)
@@ -38,7 +38,7 @@ void play2all(string samp);
 
 void play2team(float t, string filename);
 
-void GetCvars_handleFloat(entity this, string thisname, float f, .float field, string name);
+void GetCvars_handleFloat(entity this, entity store, string thisname, float f, .float field, string name);
 
 float spamsound(entity e, float chan, Sound samp, float vol, float _atten);
 
index e34826cabcad0966b03af6d1b58a2a4774a343c2..4e8663d24af0a5aaf8b6b3f574fdd9acd9dab8d8 100644 (file)
@@ -97,7 +97,6 @@ void CopyBody(entity this, float keepvelocity)
        clone.move_qcphysics = false; // don't run gamecode logic on clones, too many
        set_movetype(clone, this.move_movetype);
        clone.solid = this.solid;
-       clone.ballistics_density = this.ballistics_density;
        clone.takedamage = this.takedamage;
        setcefc(clone, getcefc(this));
        clone.uncustomizeentityforclient = this.uncustomizeentityforclient;
@@ -553,7 +552,7 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
         // increment frag counter for used weapon type
         Weapon w = DEATH_WEAPONOF(deathtype);
                if(w != WEP_Null && accuracy_isgooddamage(attacker, this))
-                       attacker.accuracy.(accuracy_frags[w.m_id-1]) += 1;
+                       CS(attacker).accuracy.(accuracy_frags[w.m_id-1]) += 1;
 
                MUTATOR_CALLHOOK(PlayerDies, inflictor, attacker, this, deathtype, damage);
                damage = M_ARGV(4, float);
@@ -610,12 +609,14 @@ void PlayerDamage(entity this, entity inflictor, entity attacker, float damage,
                set_movetype(this, MOVETYPE_TOSS);
                // shootable corpse
                this.solid = SOLID_CORPSE;
-               this.ballistics_density = autocvar_g_ballistics_density_corpse;
+               PS(this).ballistics_density = autocvar_g_ballistics_density_corpse;
                // don't stick to the floor
                UNSET_ONGROUND(this);
                // dying animation
                this.deadflag = DEAD_DYING;
 
+               STAT(MOVEVARS_SPECIALCOMMAND, this) = false; // sweet release
+
                // when to allow respawn
                calculate_player_respawn_time(this);
 
index 6bfb09cc97a2978be06048928dbf4366a675a6c2..042d450ec98e9a74c41e92d1c54a42230fc71770 100644 (file)
@@ -262,7 +262,7 @@ float PlayerScore_Clear(entity player)
 
        if(MUTATOR_CALLHOOK(ForbidPlayerScore_Clear)) return 0;
 
-       sk = player.scorekeeper;
+       sk = CS(player).scorekeeper;
        FOREACH(Scores, true, {
                if(sk.(scores(it)) != 0)
                        if(scores_label(it) != "")
@@ -279,7 +279,7 @@ void Score_ClearAll()
        entity sk;
        float t;
        FOREACH_CLIENTSLOT(true, {
-               sk = it.scorekeeper;
+               sk = CS(it).scorekeeper;
                if (!sk) continue;
                FOREACH(Scores, true, {
                        if(sk.(scores(it)) != 0)
@@ -306,20 +306,20 @@ void Score_ClearAll()
 
 void PlayerScore_Attach(entity player)
 {
-       if(player.scorekeeper)
+       if(CS(player).scorekeeper)
                error("player already has a scorekeeper");
        entity sk = new_pure(scorekeeper);
        sk.owner = player;
        Net_LinkEntity(sk, false, 0, PlayerScore_SendEntity);
-       player.scorekeeper = sk;
+       CS(player).scorekeeper = sk;
 }
 
 void PlayerScore_Detach(entity player)
 {
-       if(!player.scorekeeper)
+       if(!CS(player).scorekeeper)
                error("player has no scorekeeper");
-       delete(player.scorekeeper);
-       player.scorekeeper = NULL;
+       delete(CS(player).scorekeeper);
+       CS(player).scorekeeper = NULL;
 }
 
 float PlayerScore_Add(entity player, PlayerScoreField scorefield, float score)
@@ -332,7 +332,7 @@ float PlayerScore_Add(entity player, PlayerScoreField scorefield, float score)
                score = 0;
 
        if(!scores_initialized) return 0; // FIXME remove this when everything uses this system
-       entity s = player.scorekeeper;
+       entity s = CS(player).scorekeeper;
        if(!s)
        {
                if(game_stopped)
@@ -455,7 +455,7 @@ void WinningConditionHelper(entity this)
                winnerscorekeeper = NULL;
                secondscorekeeper = NULL;
                FOREACH_CLIENT(IS_PLAYER(it), LAMBDA(
-                       sk = it.scorekeeper;
+                       sk = CS(it).scorekeeper;
                        c = PlayerScore_Compare(winnerscorekeeper, sk, 1);
                        if(c < 0)
                        {
@@ -589,7 +589,7 @@ string GetPlayerScoreString(entity pl, float shortString)
         });
                out = substring(out, 0, strlen(out) - 1);
        }
-       else if((sk = pl.scorekeeper))
+       else if((sk = CS(pl).scorekeeper))
        {
                FOREACH(Scores, true, {
                        if ((scores_flags(it) & SFL_SORT_PRIO_MASK) == SFL_SORT_PRIO_PRIMARY)
@@ -684,7 +684,7 @@ float PlayerTeamScore_Compare(entity p1, entity p2, float teams, float strict)
                        return 0;
        }
 
-       return PlayerScore_Compare(p1.scorekeeper, p2.scorekeeper, strict);
+       return PlayerScore_Compare(CS(p1).scorekeeper, CS(p2).scorekeeper, strict);
 }
 
 entity PlayerScore_Sort(.float field, float teams, float strict, float nospectators)
@@ -696,7 +696,7 @@ entity PlayerScore_Sort(.float field, float teams, float strict, float nospectat
 
        FOREACH_CLIENT(true, LAMBDA(it.(field) = 0));
 
-       FOREACH_CLIENT(it.scorekeeper,
+       FOREACH_CLIENT(CS(it).scorekeeper,
        {
                if(nospectators)
                        if(it.frags == FRAGS_SPECTATOR)
@@ -828,7 +828,7 @@ void Score_NicePrint_Player(entity to, entity p, float w)
        float fl, sc;
        s = "  ";
 
-       sk = p.scorekeeper;
+       sk = CS(p).scorekeeper;
 
        s = strcat(s, playername(p, false));
        for (;;)
@@ -904,7 +904,7 @@ void Score_NicePrint(entity to)
 
 void PlayerScore_PlayerStats(entity p)
 {
-       entity s = p.scorekeeper;
+       entity s = CS(p).scorekeeper;
        FOREACH(Scores, true, {
                if(s.(scores(it)) != 0)
                        if(scores_label(it) != "")
index d991794b75b69e9107c48577fe89602821a291bd..2d6ceb8e0257f3546820544f276cb873d946e863 100644 (file)
@@ -650,7 +650,7 @@ void SV_ChangeTeam(entity this, float _color)
                return;
        }
 
-       if((autocvar_g_campaign) || (autocvar_g_changeteam_banned && this.wasplayer)) {
+       if((autocvar_g_campaign) || (autocvar_g_changeteam_banned && CS(this).wasplayer)) {
                Send_Notification(NOTIF_ONE, this, MSG_INFO, INFO_TEAMCHANGE_NOTALLOWED);
                return; // changing teams is not allowed
        }
index 7cc06da3e6dc05b32595b85556ff43d4ecb11225..bee961bc080d0aecd64ccc284e02a0d49be4517b 100644 (file)
@@ -20,7 +20,7 @@ bool accuracy_send(entity this, entity to, int sf)
 
        entity a = this.owner;
        if (IS_SPEC(a)) a = a.enemy;
-       a = a.accuracy;
+       a = CS(a).accuracy;
 
        if (to != a.owner)
                if (!autocvar_sv_accuracy_data_share && !a.owner.cvar_cl_accuracy_data_share)
@@ -40,7 +40,7 @@ bool accuracy_send(entity this, entity to, int sf)
 // init/free
 void accuracy_init(entity e)
 {
-       entity a = e.accuracy = new_pure(accuracy);
+       entity a = CS(e).accuracy = new_pure(accuracy);
        a.owner = e;
        a.drawonlytoclient = e;
        Net_LinkEntity(a, false, 0, accuracy_send);
@@ -48,13 +48,13 @@ void accuracy_init(entity e)
 
 void accuracy_free(entity e)
 {
-       delete(e.accuracy);
+       delete(CS(e).accuracy);
 }
 
 // force a resend of a player's accuracy stats
 void accuracy_resend(entity e)
 {
-       e.accuracy.SendFlags = 0xFFFFFF;
+       CS(e).accuracy.SendFlags = 0xFFFFFF;
 }
 
 // update accuracy stats
@@ -64,7 +64,7 @@ void accuracy_resend(entity e)
 void accuracy_add(entity this, int w, int fired, int hit)
 {
        if (IS_INDEPENDENT_PLAYER(this)) return;
-       entity a = this.accuracy;
+       entity a = CS(this).accuracy;
        if (!a) return;
        if (!hit && !fired) return;
        w -= WEP_FIRST;
@@ -85,7 +85,7 @@ void accuracy_add(entity this, int w, int fired, int hit)
        if (b == accuracy_byte(a.accuracy_hit[w], a.accuracy_fired[w])) return; // no change
        int sf = 1 << (w % 24);
        a.SendFlags |= sf;
-       FOREACH_CLIENT(IS_SPEC(it) && it.enemy == this, LAMBDA(it.accuracy.SendFlags |= sf));
+       FOREACH_CLIENT(IS_SPEC(it) && it.enemy == this, LAMBDA(CS(it).accuracy.SendFlags |= sf));
 }
 
 bool accuracy_isgooddamage(entity attacker, entity targ)
index 6d163755067def2224a973db9bc311f1dcb60770..fb57d92774d01657e5c4e98228a7175f8efe6252 100644 (file)
@@ -5,6 +5,7 @@
 #include <common/net_linked.qh>
 #include <common/deathtypes/all.qh>
 #include <common/notifications/all.qh>
+#include <common/state.qh>
 #include <common/util.qh>
 #include <common/weapons/_all.qh>
 #include <common/items/_mod.qh>
@@ -20,16 +21,18 @@ void W_GiveWeapon(entity e, int wep)
     }
 }
 
-void W_PlayStrengthSound(entity player) // void W_PlayStrengthSound
+void W_PlayStrengthSound(entity player)
 {
+       entity store = IS_PLAYER(player) ? PS(player) : player; // because non-player entities can fire, but can they have items? TODO
+
        if((player.items & ITEM_Strength.m_itemid)
-               && ((time > player.prevstrengthsound + autocvar_sv_strengthsound_antispam_time) // prevent insane sound spam
-               || (time > player.prevstrengthsoundattempt + autocvar_sv_strengthsound_antispam_refire_threshold)))
+               && ((time > store.prevstrengthsound + autocvar_sv_strengthsound_antispam_time) // prevent insane sound spam
+               || (time > store.prevstrengthsoundattempt + autocvar_sv_strengthsound_antispam_refire_threshold)))
                {
                        sound(player, CH_TRIGGER, SND_STRENGTH_FIRE, VOL_BASE, ATTEN_NORM);
-                       player.prevstrengthsound = time;
+                       store.prevstrengthsound = time;
                }
-               player.prevstrengthsoundattempt = time;
+               store.prevstrengthsoundattempt = time;
 }
 
 float W_CheckProjectileDamage(entity inflictor, entity projowner, int deathtype, float exception)
index 2a0fad7dee0c832e086d8feb2ff85ea347d7f3d3..89cec6aea98dacaadca0f44df7c58e82e63653c1 100644 (file)
@@ -54,27 +54,23 @@ vector W_HitPlotNormalizedUntransform(vector org, entity targ, vector screenforw
 
 void W_HitPlotAnalysis(entity player, .entity weaponentity, vector screenforward, vector screenright, vector screenup)
 {
-       vector hitplot;
-       vector org;
-       float lag;
-
-       if(player.hitplotfh >= 0)
+       if(CS(player).hitplotfh >= 0)
        {
-               lag = ANTILAG_LATENCY(player);
+               float lag = ANTILAG_LATENCY(player);
                if(lag < 0.001)
                        lag = 0;
                if(!IS_REAL_CLIENT(player))
                        lag = 0; // only antilag for clients
 
-               org = player.origin + player.view_ofs;
+               vector org = player.origin + player.view_ofs;
                traceline_antilag_force(player, org, org + screenforward * max_shot_distance, MOVE_NORMAL, player, lag);
                if(IS_CLIENT(trace_ent) || IS_MONSTER(trace_ent))
                {
                    entity store = IS_CLIENT(trace_ent) ? CS(trace_ent) : trace_ent;
                        antilag_takeback(trace_ent, store, time - lag);
-                       hitplot = W_HitPlotNormalizedUntransform(org, trace_ent, screenforward, screenright, screenup, trace_endpos);
+                       vector hitplot = W_HitPlotNormalizedUntransform(org, trace_ent, screenforward, screenright, screenup, trace_endpos);
                        antilag_restore(trace_ent, store);
-                       fputs(player.hitplotfh, strcat(ftos(hitplot.x), " ", ftos(hitplot.y), " ", ftos(hitplot.z), " ", ftos(player.(weaponentity).m_switchweapon.m_id), "\n"));
+                       fputs(CS(player).hitplotfh, strcat(ftos(hitplot.x), " ", ftos(hitplot.y), " ", ftos(hitplot.z), " ", ftos(player.(weaponentity).m_switchweapon.m_id), "\n"));
                        //print(strcat(ftos(hitplot_x), " ", ftos(hitplot_y), " ", ftos(hitplot_z), "\n"));
                }
        }
@@ -84,17 +80,17 @@ void W_HitPlotOpen(entity player)
 {
        if(autocvar_g_hitplots || strhasword(autocvar_g_hitplots_individuals, player.netaddress))
        {
-               player.hitplotfh = fopen(strcat("hits-", matchid, "-", player.netaddress, "-", ftos(player.playerid), ".plot"), FILE_WRITE);
-               fputs(player.hitplotfh, strcat("#name ", playername(player, false), "\n"));
+               CS(player).hitplotfh = fopen(strcat("hits-", matchid, "-", player.netaddress, "-", ftos(player.playerid), ".plot"), FILE_WRITE);
+               fputs(CS(player).hitplotfh, strcat("#name ", playername(player, false), "\n"));
        }
-       else { player.hitplotfh = -1; }
+       else { CS(player).hitplotfh = -1; }
 }
 
 void W_HitPlotClose(entity player)
 {
-       if(player.hitplotfh >= 0)
+       if(CS(player).hitplotfh >= 0)
        {
-               fclose(player.hitplotfh);
-               player.hitplotfh = -1;
+               fclose(CS(player).hitplotfh);
+               CS(player).hitplotfh = -1;
        }
 }
index 17ba0dc9dfafb4f1063e0f20f14b292f11856b56..6f3fd85a8d21795cc6acd8345cfed5ed7964f2e5 100644 (file)
@@ -44,7 +44,7 @@ bool client_hasweapon(entity this, Weapon wpn, .entity weaponentity, float andam
 {
        float f = 0;
 
-       if (time < this.hasweapon_complain_spam)
+       if (time < CS(this).hasweapon_complain_spam)
                complain = 0;
 
        // ignore hook button when using other offhand equipment
@@ -53,7 +53,7 @@ bool client_hasweapon(entity this, Weapon wpn, .entity weaponentity, float andam
            complain = 0;
 
        if (complain)
-               this.hasweapon_complain_spam = time + 0.2;
+               CS(this).hasweapon_complain_spam = time + 0.2;
 
        if (wpn == WEP_Null)
        {
index 4c6304a1b1b50439070afa5c43a78a71d26d5846..475eb3d265c086e769242548ab018ed6a00e1bb3 100644 (file)
@@ -438,16 +438,17 @@ void fireBullet(entity this, .entity weaponentity, vector start, vector dir, flo
                        break;
 
                float maxdist;
+               entity hitstore = IS_PLAYER(hit) ? PS(hit) : hit;
                if(max_solid_penetration < 0)
                        break;
-               else if(hit.ballistics_density < -1)
+               else if(hitstore.ballistics_density < -1)
                        break; // -2: no solid penetration, ever
-               else if(hit.ballistics_density < 0)
+               else if(hitstore.ballistics_density < 0)
                        maxdist = vlen(hit.maxs - hit.mins) + 1; // -1: infinite travel distance
-               else if(hit.ballistics_density == 0)
+               else if(hitstore.ballistics_density == 0)
                        maxdist = max_solid_penetration * solid_penetration_left;
                else
-                       maxdist = max_solid_penetration * solid_penetration_left * hit.ballistics_density;
+                       maxdist = max_solid_penetration * solid_penetration_left * hitstore.ballistics_density;
 
                if(maxdist <= autocvar_g_ballistics_mindistance)
                        break;
index 8543f8c861244934b6b4af4277a80d9ad1ebeace..55799ff7c4db70fe3d470284b1c8bc6b4548b69d 100755 (executable)
@@ -2,6 +2,25 @@
 set -eu
 cd ${0%/*}
 
+# This script attempts to build the codebase in every possible header configuration,
+# to check that all files #include what they need, so that we can eventually move away
+# from a unity build and into incremental compilation.
+
+# If these files exist from previous compilation, `./all compile` will stop
+# detecting changes after running this script so delete them to trigger
+# a recompile next time.
+if [ -f ../../csprogs.dat ]; then
+    rm ../../csprogs.dat
+fi
+
+if [ -f ../../menu.dat ]; then
+    rm ../../menu.dat
+fi
+
+if [ -f ../../progs.dat ]; then
+    rm ../../progs.dat
+fi
+
 WORKDIR=../.tmp
 
 CPP="cc -xc -E"