]> git.rm.cloudns.org Git - xonotic/xonotic-data.pk3dir.git/commitdiff
Implemented HUD pickup message
authorz411 <z411@omaera.org>
Mon, 19 Oct 2020 21:41:20 +0000 (18:41 -0300)
committerz411 <z411@omaera.org>
Mon, 19 Oct 2020 21:41:20 +0000 (18:41 -0300)
qcsrc/client/hud/panel/chat.qc
qcsrc/client/hud/panel/timer.qc
qcsrc/client/miscfunctions.qh
qcsrc/common/items/inventory.qh
qcsrc/server/items/items.qc
qcsrc/server/weapons/common.qc

index d46aa81b8269a29960a4b6a5b475b3fc44d4b6b4..6807c2183b5f47aa6d5f78ad24262f24d8216d3d 100644 (file)
@@ -2,6 +2,7 @@
 
 #include <client/autocvars.qh>
 #include <client/miscfunctions.qh>
+#include <common/items/inventory.qh>
 
 // Chat (#12)
 
@@ -81,9 +82,9 @@ void HUD_Chat()
        cvar_set("con_chatwidth", ftos(mySize.x/vid_conwidth));
        cvar_set("con_chat", ftos(floor(mySize.y/autocvar_con_chatsize - 0.5)));
 
+       vector chatsize = '1 1 0' * autocvar_con_chatsize;
        if(autocvar__hud_configure)
        {
-               vector chatsize = '1 1 0' * autocvar_con_chatsize;
                cvar_set("con_chatrect_x", "9001"); // over 9000, we'll fake it instead for more control over alpha and such
                string str = textShortenToWidth(_("^3Player^7: This is the chat area."), mySize.x, chatsize, stringwidth_colors);
                for(int i = 0; i < autocvar_con_chat; ++i)
@@ -93,4 +94,35 @@ void HUD_Chat()
                        pos.y += chatsize.y;
                }
        }
+       
+       // z411 items
+       float stat_last_pickup = STAT(LAST_PICKUP);
+       pos.y += mySize.y;
+       entity it = last_pickup_item;
+       
+       if(stat_last_pickup && stat_last_pickup > time - 3 && it) {
+               float a, y;
+               string str1, str2, icon;
+               vector sz, sz2;
+               vector pickupsize = chatsize * 1.25;
+               vector iconsize = chatsize * 2;
+               
+               icon = strcat(hud_skin_path, "/", ((it.model2) ? it.model2 : it.m_icon));
+               sz = draw_getimagesize(icon);
+               sz2 = vec2(iconsize.y*(sz.x/sz.y), iconsize.y);
+               str1 = seconds_tostring(last_pickup_timer);
+               str2 = ((last_pickup_times > 1) ? sprintf("%s (x%d)", it.m_name, last_pickup_times) : it.m_name);
+               y = (iconsize.y - pickupsize.y) / 2;
+               
+               if(time < stat_last_pickup + 3 - 0.5)
+                       a = 1;
+               else
+                       a = (stat_last_pickup + 3 - time) / 0.5;
+               
+               drawstring(pos + eY * y, str1, pickupsize, '1 1 1', a, DRAWFLAG_NORMAL);
+               pos.x += stringwidth(str1, false, pickupsize) + pickupsize.x * 0.25;
+               drawpic(pos, icon, sz2, '1 1 1', a, DRAWFLAG_NORMAL);
+               pos.x += sz2.x + pickupsize.x * 0.25;
+               drawstring(pos + eY * y, str2, pickupsize, '1 1 1', a, DRAWFLAG_NORMAL);
+       }
 }
index 65abb0d272a06a1f49fa054787cba5ecf90777aa..cfac04ecb7a58e30bdeb06c1245a39e8848a8739 100644 (file)
@@ -37,7 +37,6 @@ void HUD_Timer()
                mySize -= '2 2 0' * panel_bg_padding;
        }
 
-       string timer;
        string timer_sub = "";
        bool game_timeout;
        float timelimit, timeleft, minutesLeft, overtimes, timeout_last;
@@ -72,35 +71,35 @@ void HUD_Timer()
                timer_color = '1 0 0'; //red
 
        if (intermission_time) {
-               timer = seconds_tostring(max(0, floor(intermission_time - STAT(GAMESTARTTIME))));
+               timer = max(0, floor(intermission_time - STAT(GAMESTARTTIME)));
                timer_sub = "Intermission";
        //} else if (autocvar_hud_panel_timer_increment || (!warmup_stage && timelimit == 0) || (warmup_stage && warmup_timeleft <= 0)) {
        } else if (game_timeout) {
                if(autocvar_hud_panel_timer_increment)
-                       timer = seconds_tostring(max(0, floor(timeout_last - STAT(GAMESTARTTIME))));
+                       timer = max(0, floor(timeout_last - STAT(GAMESTARTTIME)));
                else
-                       timer = seconds_tostring(ceil(max(0, timelimit * 60 + STAT(GAMESTARTTIME) - timeout_last)));
+                       timer = ceil(max(0, timelimit * 60 + STAT(GAMESTARTTIME) - timeout_last));
                timer_sub = "Timeout";
        } else if (autocvar_hud_panel_timer_increment || timelimit == 0) {
                // Time elapsed timer
                if((warmup_stage && warmup_timeleft <= 0) || time < STAT(GAMESTARTTIME))
-                       timer = seconds_tostring(0);
+                       timer = 0;
                else
-                       timer = seconds_tostring(floor(time - STAT(GAMESTARTTIME)));
+                       timer = floor(time - STAT(GAMESTARTTIME));
        } else {
                // Time left timer
                if(warmup_stage) {
                        if(warmup_timeleft <= 0)
-                               timer = seconds_tostring(floor(timelimit * 60));
+                               timer = floor(timelimit * 60);
                        else
-                               timer = seconds_tostring(warmup_timeleft);
+                               timer = warmup_timeleft;
                } else {
                        if (time < STAT(GAMESTARTTIME))
-                               timer = seconds_tostring(floor(timelimit * 60));
+                               timer = floor(timelimit * 60);
                        //else if (overtimes > 0)
-                       //      timer = seconds_tostring(floor(time - STAT(OVERTIMESTARTTIME)));
+                       //      timer = floor(time - STAT(OVERTIMESTARTTIME));
                        else
-                               timer = seconds_tostring(timeleft);
+                               timer = timeleft;
                }
        }
        
@@ -111,7 +110,7 @@ void HUD_Timer()
        else if (overtimes > 1)
                timer_sub = sprintf("Overtime #%d", overtimes);
        
-       drawstring_aspect(pos, timer, mySize, timer_color, panel_fg_alpha, DRAWFLAG_NORMAL);
+       drawstring_aspect(pos, seconds_tostring(timer), mySize, timer_color, panel_fg_alpha, DRAWFLAG_NORMAL);
        
        if(timer_sub != "") {
                pos.y += mySize.y;
index 5641215ae950cdee1d5a0fe8c31c4851a601743e..5cba8ab711d13816ac5eedf27ef08e9f2da82ba9 100644 (file)
@@ -36,6 +36,7 @@ vector Rotate(vector v, float a);
 
 #define IS_DEAD(s) (((s).classname == "csqcmodel") ? (s).csqcmodel_isdead : (GetResource((s), RES_HEALTH) <= 0))
 
+float timer;
 
 // decolorizes and team colors the player name when needed
 string playername(string thename, float teamid);
index 7482c663d5f4c7674b45f18f6cd86ca039d5577f..b3778f468dd4ebc5058e7b62eca33cef08c394b6 100644 (file)
@@ -14,6 +14,7 @@ ENDCLASS(Inventory)
 .Inventory inventory;
 
 REGISTER_NET_LINKED(ENT_CLIENT_INVENTORY)
+REGISTER_NET_TEMP(TE_CSQC_WEAPONPICKUP)
 
 const int Inventory_groups_minor = 8; // must be a multiple of 8 (one byte) to optimize bandwidth usage
 const int Inventory_groups_major = 4; // must be >= ceil(REGISTRY_COUNT(Items) / Inventory_groups_minor)
@@ -37,15 +38,21 @@ STATIC_INIT(Inventory)
 #endif
 
 #ifdef CSQC
+#include <client/miscfunctions.qh>
+#include <client/hud/hud.qh>
+
 //Inventory g_inventory;
 Inventory inventoryslots[255];
+float last_pickup_timer;
+entity last_pickup_item;
+int last_pickup_times;
 NET_HANDLE(ENT_CLIENT_INVENTORY, bool isnew)
 {
     make_pure(this);
     //g_inventory = this;
        
-       float entnum = ReadByte();
-       inventoryslots[entnum-1] = this;
+       float entnum = ReadByte() - 1;
+       inventoryslots[entnum] = this;
        
     const int majorBits = Readbits(Inventory_groups_major);
     for (int i = 0; i < Inventory_groups_major; ++i) {
@@ -61,11 +68,31 @@ NET_HANDLE(ENT_CLIENT_INVENTORY, bool isnew)
             .int fld = inv_items[it.m_id];
             int prev = this.(fld);
             int next = this.(fld) = ReadByte();
+                       
+                       if(entnum == current_player) {
+                               if(last_pickup_item != it) last_pickup_times = 0;
+                               last_pickup_timer = timer;
+                               last_pickup_item = it;
+                               last_pickup_times++;
+                       }
+                       
             LOG_DEBUGF("%s: %.0f -> %.0f", it.m_name, prev, next);
         }
     }
     return true;
 }
+
+NET_HANDLE(TE_CSQC_WEAPONPICKUP, bool isnew)
+{
+       const Weapon it = REGISTRY_GET(Weapons, ReadByte());
+       
+       if(last_pickup_item != it) last_pickup_times = 0;
+       last_pickup_timer = timer;
+       last_pickup_item = it;
+       last_pickup_times++;
+       
+       return true;
+}
 #endif
 
 #ifdef SVQC
index 93da11a478efbb8b60e0751a0f78bdd4fd8375b8..111321b1c0a96f33d89b340463cca713915b82d4 100644 (file)
@@ -233,7 +233,7 @@ void Item_RespawnCountdown(entity this)
        else
        {
                this.nextthink = time + 1;
-               this.item_respawncounter = floor((time - timeout_total_time) - (this.scheduledrespawntime - ITEM_RESPAWN_TICKS)) + 1;
+               this.item_respawncounter = floor((time - game_starttime) - (this.scheduledrespawntime - ITEM_RESPAWN_TICKS)) + 1;
                //this.item_respawncounter += 1;
                //LOG_INFOF("Respawncounter: %d", this.item_respawncounter);
                if(this.item_respawncounter < 1) return;
@@ -290,10 +290,10 @@ void Item_RespawnThink(entity this)
        if(this.origin != this.oldorigin)
                ItemUpdate(this);
        
-       if(!game_timeout && time - timeout_total_time >= this.wait)
+       if(!game_timeout && time - game_starttime >= this.wait)
                Item_Respawn(this);
        
-       //LOG_INFOF("time until respawn %d", (this.wait) - (time - timeout_total_time));
+       //LOG_INFOF("time until respawn %d", (this.wait) - (time - game_starttime));
 }
 
 void Item_ScheduleRespawnIn(entity e, float t)
@@ -305,7 +305,7 @@ void Item_ScheduleRespawnIn(entity e, float t)
                //e.nextthink = time - timeout_total_time + max(0, t - ITEM_RESPAWN_TICKS);
                //e.scheduledrespawntime = e.nextthink + ITEM_RESPAWN_TICKS;
                e.nextthink = time;
-               e.scheduledrespawntime = time - timeout_total_time + t;
+               e.scheduledrespawntime = time - game_starttime + t;
                e.item_respawncounter = 0;
                
                if(Item_ItemsTime_Allow(e.itemdef) || (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS))
@@ -319,8 +319,8 @@ void Item_ScheduleRespawnIn(entity e, float t)
        {
                setthink(e, Item_RespawnThink);
                e.nextthink = time;
-               e.scheduledrespawntime = time - timeout_total_time + t;
-               e.wait = time - timeout_total_time + t;
+               e.scheduledrespawntime = time - game_starttime + t;
+               e.wait = time - game_starttime + t;
 
                if(Item_ItemsTime_Allow(e.itemdef) || (STAT(WEAPONS, e) & WEPSET_SUPERWEAPONS))
                {
@@ -492,6 +492,15 @@ bool Item_GiveAmmoTo(entity item, entity player, int res_type, float ammomax)
        return true;
 }
 
+void Item_NotifyWeapon(entity player, int wep)
+{
+       if(IS_REAL_CLIENT(player)) {
+               msg_entity = player;
+               WriteHeader(MSG_ONE, TE_CSQC_WEAPONPICKUP);
+               WriteByte(MSG_ONE, wep);
+       }
+}
+
 bool Item_GiveTo(entity item, entity player)
 {
        // if nothing happens to player, just return without taking the item
@@ -526,23 +535,31 @@ bool Item_GiveTo(entity item, entity player)
        pickedup |= Item_GiveAmmoTo(item, player, RES_FUEL, g_pickup_fuel_max);
        if (item.itemdef.instanceOfWeaponPickup)
        {
-               WepSet w;
+               WepSet w, wp;
                w = STAT(WEAPONS, item);
-               w &= ~STAT(WEAPONS, player);
+               wp = w & ~STAT(WEAPONS, player);
 
                if (w || (item.spawnshieldtime && item.pickup_anyway > 0))
                {
                        pickedup = true;
                        FOREACH(Weapons, it != WEP_Null, {
-                               if(w & (it.m_wepset))
+                               Weapon wep = it;
+                               
+                               if(w & (wep.m_wepset)) {
+                                       // z411 Seriously find a better way to do this
+                                       Item_NotifyWeapon(player, wep.m_id);
+                                       FOREACH_CLIENT(IS_SPEC(it) && it.enemy == player, { Item_NotifyWeapon(it, wep.m_id); });
+                               }
+                               
+                               if(wp & (wep.m_wepset))
                                {
                                        for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
                                        {
                                                .entity weaponentity = weaponentities[slot];
                                                if(player.(weaponentity).m_weapon != WEP_Null || slot == 0)
-                                                       W_DropEvent(wr_pickup, player, it.m_id, item, weaponentity);
+                                                       W_DropEvent(wr_pickup, player, wep.m_id, item, weaponentity);
                                        }
-                                       W_GiveWeapon(player, it.m_id);
+                                       W_GiveWeapon(player, wep.m_id);
                                }
                        });
                }
index 7cd56faa758925ee1c37ddce9459361aa3184409..77c030c206d30202fa449abda458ed13bfd97881 100644 (file)
@@ -34,9 +34,10 @@ void W_GiveWeapon(entity e, int wep)
 
        STAT(WEAPONS, e) |= WepSet_FromWeapon(REGISTRY_GET(Weapons, wep));
 
-       if (IS_PLAYER(e)) {
-           Send_Notification(NOTIF_ONE, e, MSG_MULTI, ITEM_WEAPON_GOT, wep);
-    }
+       // z411 We're sending a pickup HUD notification instead
+       //if (IS_PLAYER(e)) {
+       //    Send_Notification(NOTIF_ONE, e, MSG_MULTI, ITEM_WEAPON_GOT, wep);
+    //}
 }
 
 void W_PlayStrengthSound(entity player)