From: z411 Date: Mon, 19 Oct 2020 21:41:20 +0000 (-0300) Subject: Implemented HUD pickup message X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=4d244eb035099d1d107336391fca64558f8b1504;p=xonotic%2Fxonotic-data.pk3dir.git Implemented HUD pickup message --- diff --git a/qcsrc/client/hud/panel/chat.qc b/qcsrc/client/hud/panel/chat.qc index d46aa81b8..6807c2183 100644 --- a/qcsrc/client/hud/panel/chat.qc +++ b/qcsrc/client/hud/panel/chat.qc @@ -2,6 +2,7 @@ #include #include +#include // 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); + } } diff --git a/qcsrc/client/hud/panel/timer.qc b/qcsrc/client/hud/panel/timer.qc index 65abb0d27..cfac04ecb 100644 --- a/qcsrc/client/hud/panel/timer.qc +++ b/qcsrc/client/hud/panel/timer.qc @@ -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; diff --git a/qcsrc/client/miscfunctions.qh b/qcsrc/client/miscfunctions.qh index 5641215ae..5cba8ab71 100644 --- a/qcsrc/client/miscfunctions.qh +++ b/qcsrc/client/miscfunctions.qh @@ -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); diff --git a/qcsrc/common/items/inventory.qh b/qcsrc/common/items/inventory.qh index 7482c663d..b3778f468 100644 --- a/qcsrc/common/items/inventory.qh +++ b/qcsrc/common/items/inventory.qh @@ -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 +#include + //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 diff --git a/qcsrc/server/items/items.qc b/qcsrc/server/items/items.qc index 93da11a47..111321b1c 100644 --- a/qcsrc/server/items/items.qc +++ b/qcsrc/server/items/items.qc @@ -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); } }); } diff --git a/qcsrc/server/weapons/common.qc b/qcsrc/server/weapons/common.qc index 7cd56faa7..77c030c20 100644 --- a/qcsrc/server/weapons/common.qc +++ b/qcsrc/server/weapons/common.qc @@ -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)