1 REGISTER_MUTATOR(itemstime, true);
4 void IT_Write(entity e, int i, float f) {
5 if (!IS_REAL_CLIENT(e)) return;
7 WriteByte(MSG_ONE, SVC_TEMPENTITY);
8 WriteMutator(MSG_ONE, itemstime);
10 WriteFloat(MSG_ONE, f);
15 const float ITEMSTIME_MAXITEMS = 10;
16 float ItemsTime_time[ITEMSTIME_MAXITEMS];
17 float ItemsTime_availableTime[ITEMSTIME_MAXITEMS];
18 MUTATOR_HOOKFUNCTION(itemstime, CSQC_Parse_TempEntity) {
19 if (MUTATOR_RETURNVALUE) return false;
20 if (!ReadMutatorEquals(mutator_argv_int_0, itemstime)) return false;
22 float f = ReadFloat();
23 ItemsTime_time[i] = f;
29 float it_armor_large_time;
30 float it_health_mega_time;
31 float it_invisible_time;
33 float it_extralife_time;
34 float it_strength_time;
36 float it_fuelregen_time;
37 float it_jetpack_time;
38 float it_superweapons_time;
40 void Item_ItemsTime_Init()
42 it_armor_large_time = -1;
43 it_health_mega_time = -1;
44 it_invisible_time = -1;
46 it_extralife_time = -1;
47 it_strength_time = -1;
49 it_fuelregen_time = -1;
51 it_superweapons_time = -1;
54 STATIC_INIT(ItemsTime_Init) {
56 Item_ItemsTime_Init();
59 void Item_ItemsTime_ResetTimes()
61 it_armor_large_time = (it_armor_large_time == -1) ? -1 : 0;
62 it_health_mega_time = (it_health_mega_time == -1) ? -1 : 0;
63 it_invisible_time = (it_invisible_time == -1) ? -1 : 0;
64 it_speed_time = (it_speed_time == -1) ? -1 : 0;
65 it_extralife_time = (it_extralife_time == -1) ? -1 : 0;
66 it_strength_time = (it_strength_time == -1) ? -1 : 0;
67 it_shield_time = (it_shield_time == -1) ? -1 : 0;
68 it_fuelregen_time = (it_fuelregen_time == -1) ? -1 : 0;
69 it_jetpack_time = (it_jetpack_time == -1) ? -1 : 0;
70 it_superweapons_time = (it_superweapons_time == -1) ? -1 : 0;
73 void Item_ItemsTime_ResetTimesForPlayer(entity e)
75 IT_Write(e, item_armor_large_time , (it_armor_large_time == -1) ? -1 : 0);
76 IT_Write(e, item_health_mega_time , (it_health_mega_time == -1) ? -1 : 0);
77 IT_Write(e, item_invisible_time , (it_invisible_time == -1) ? -1 : 0);
78 IT_Write(e, item_speed_time , (it_speed_time == -1) ? -1 : 0);
79 IT_Write(e, item_extralife_time , (it_extralife_time == -1) ? -1 : 0);
80 IT_Write(e, item_strength_time , (it_strength_time == -1) ? -1 : 0);
81 IT_Write(e, item_shield_time , (it_shield_time == -1) ? -1 : 0);
82 IT_Write(e, item_fuelregen_time , (it_fuelregen_time == -1) ? -1 : 0);
83 IT_Write(e, item_jetpack_time , (it_jetpack_time == -1) ? -1 : 0);
84 IT_Write(e, item_superweapons_time, (it_superweapons_time == -1) ? -1 : 0);
87 void Item_ItemsTime_SetTimesForPlayer(entity e)
89 IT_Write(e, item_armor_large_time , it_armor_large_time );
90 IT_Write(e, item_health_mega_time , it_health_mega_time );
91 IT_Write(e, item_invisible_time , it_invisible_time );
92 IT_Write(e, item_speed_time , it_speed_time );
93 IT_Write(e, item_extralife_time , it_extralife_time );
94 IT_Write(e, item_strength_time , it_strength_time );
95 IT_Write(e, item_shield_time , it_shield_time );
96 IT_Write(e, item_fuelregen_time , it_fuelregen_time );
97 IT_Write(e, item_jetpack_time , it_jetpack_time );
98 IT_Write(e, item_superweapons_time, it_superweapons_time);
101 void Item_ItemsTime_SetTime(entity e, float t)
103 if (!autocvar_sv_itemstime)
110 case IT_STRENGTH://"item-invis"
111 it_invisible_time = t;
113 case IT_NAILS://"item-extralife"
114 it_extralife_time = t;
116 case IT_INVINCIBLE://"item-speed"
125 case ITEM_HealthMega.m_itemid:
126 // if (e.itemdef == ITEM_HealthMega) // e.items == IT_HEALTH unequivocally identifies it
127 it_health_mega_time = t;
129 case ITEM_ArmorMega.m_itemid:
130 if (e.itemdef == ITEM_ArmorMega) // e.items == IT_ARMOR doesn't unequivocally identifies it
131 it_armor_large_time = t;
133 case IT_STRENGTH://"item-strength"
134 it_strength_time = t;
136 case IT_INVINCIBLE://"item-shield"
140 if (e.weapons & WEPSET_SUPERWEAPONS)
141 it_superweapons_time = t;
146 case IT_FUEL_REGEN://"item-fuelregen"
147 it_fuelregen_time = t;
149 case IT_JETPACK://"item-jetpack"
155 void Item_ItemsTime_SetTimesForAllPlayers()
158 FOR_EACH_REALCLIENT(e) if (warmup_stage || !IS_PLAYER(e))
159 Item_ItemsTime_SetTimesForPlayer(e);
162 float Item_ItemsTime_UpdateTime(entity e, float t)
164 bool isavailable = (t == 0);
165 if (e.weapons & WEPSET_SUPERWEAPONS)
167 for (entity head = world; (head = nextent(head)); )
169 if (clienttype(head) != CLIENTTYPE_NOTACLIENT || !(head.weapons & WEPSET_SUPERWEAPONS) || head.classname == "weapon_info")
174 if (head.scheduledrespawntime <= time)
176 else if (t == 0 || head.scheduledrespawntime < t)
177 t = head.scheduledrespawntime;
182 for (entity head = world; (head = nextent(head)); )
184 if (head.itemdef != e.itemdef)
189 if (head.scheduledrespawntime <= time)
191 else if (t == 0 || head.scheduledrespawntime < t)
192 t = head.scheduledrespawntime;
196 t = -t; // let know the client there's another available item
200 MUTATOR_HOOKFUNCTION(itemstime, reset_map_global) {
201 Item_ItemsTime_ResetTimes();
204 MUTATOR_HOOKFUNCTION(itemstime, MakePlayerObserver) {
205 Item_ItemsTime_SetTimesForPlayer(self);
208 MUTATOR_HOOKFUNCTION(itemstime, PlayerSpawn) {
209 if (warmup_stage) return;
210 Item_ItemsTime_ResetTimesForPlayer(self);
217 string GetItemsTimePicture(float i)
221 case 0: return "item_large_armor";
222 case 1: return "item_mega_health";
223 case 2: return "strength";
224 case 3: return "shield";
225 case 4: return "item_mega_health";
226 case 5: return "strength";
227 case 6: return "shield";
228 case 7: return "fuelregen";
229 case 8: return "jetpack";
230 case 9: return "superweapons";
235 void DrawItemsTimeItem(vector myPos, vector mySize, float ar, float itemcode, float item_time, bool item_available, float item_availableTime)
238 vector color = '0 0 0';
241 if(autocvar_hud_panel_itemstime_hidespawned == 2)
243 else if(item_available)
245 float BLINK_FACTOR = 0.15;
246 float BLINK_BASE = 0.85;
247 float BLINK_FREQ = 5;
248 picalpha = BLINK_BASE + BLINK_FACTOR * cos(time * BLINK_FREQ);
252 t = floor(item_time - time + 0.999);
260 vector picpos, numpos;
261 if(autocvar_hud_panel_itemstime_iconalign)
264 picpos = myPos + eX * (ar - 1) * mySize_y;
268 numpos = myPos + eX * mySize_y;
272 if(t > 0 && autocvar_hud_panel_itemstime_progressbar)
274 vector p_pos, p_size;
275 if(autocvar_hud_panel_itemstime_progressbar_reduced)
278 p_size = eX * ((ar - 1)/ar) * mySize_x + eY * mySize_y;
285 HUD_Panel_DrawProgressBar(p_pos, p_size, autocvar_hud_panel_itemstime_progressbar_name, t/autocvar_hud_panel_itemstime_progressbar_maxtime, 0, autocvar_hud_panel_itemstime_iconalign, color, autocvar_hud_progressbar_alpha * panel_fg_alpha, DRAWFLAG_NORMAL);
288 if(t > 0 && autocvar_hud_panel_itemstime_text)
289 drawstring_aspect(numpos, ftos(t), eX * ((ar - 1)/ar) * mySize_x + eY * mySize_y, color, panel_fg_alpha, DRAWFLAG_NORMAL);
291 picpos.x = myPos.x + mySize.x / 2 - mySize.y / 2;
292 if(item_availableTime)
293 drawpic_aspect_skin_expanding(picpos, GetItemsTimePicture(itemcode), '1 1 0' * mySize_y, '1 1 1', panel_fg_alpha * picalpha, DRAWFLAG_NORMAL, item_availableTime);
294 drawpic_aspect_skin(picpos, GetItemsTimePicture(itemcode), '1 1 0' * mySize_y, '1 1 1', panel_fg_alpha * picalpha, DRAWFLAG_NORMAL);
299 if(!autocvar__hud_configure)
302 (autocvar_hud_panel_itemstime == 1 && spectatee_status != 0)
303 || (autocvar_hud_panel_itemstime == 2 && (spectatee_status != 0 || warmup_stage))
308 // do not show here mutator-dependent items
309 ItemsTime_time[0] = time + 0;
310 ItemsTime_time[1] = time + 8;
311 ItemsTime_time[2] = -1; // mutator-dependent
312 ItemsTime_time[3] = -1; // mutator-dependent
313 ItemsTime_time[4] = -1; // mutator-dependent
314 ItemsTime_time[5] = time + 0;
315 ItemsTime_time[6] = time + 4;
316 ItemsTime_time[7] = time + 49;
317 ItemsTime_time[8] = -1;
318 ItemsTime_time[9] = time + 28;
323 if(autocvar_hud_panel_itemstime_hidespawned == 1)
324 for (i = 0; i < ITEMSTIME_MAXITEMS; ++i)
325 count += (ItemsTime_time[i] > time || -ItemsTime_time[i] > time);
326 else if(autocvar_hud_panel_itemstime_hidespawned == 2)
327 for (i = 0; i < ITEMSTIME_MAXITEMS; ++i)
328 count += (ItemsTime_time[i] > time);
330 for (i = 0; i < ITEMSTIME_MAXITEMS; ++i)
331 count += (ItemsTime_time[i] != -1);
335 HUD_Panel_UpdateCvars();
343 pos += '1 1 0' * panel_bg_padding;
344 mySize -= '2 2 0' * panel_bg_padding;
348 float ar = max(2, autocvar_hud_panel_itemstime_ratio) + 1;
349 rows = HUD_GetRowCount(count, mySize, ar);
350 columns = ceil(count/rows);
352 vector itemstime_size = eX * mySize.x*(1/columns) + eY * mySize.y*(1/rows);
354 vector offset = '0 0 0';
356 if(autocvar_hud_panel_itemstime_dynamicsize)
358 if(autocvar__hud_configure)
359 if(menu_enabled != 2)
360 HUD_Panel_DrawBg(1); // also draw the bg of the entire panel
362 // reduce panel to avoid spacing items
363 if(itemstime_size.x / itemstime_size.y < ar)
365 newSize = rows * itemstime_size.x / ar;
366 pos.y += (mySize.y - newSize) / 2;
368 itemstime_size.y = mySize.y / rows;
372 newSize = columns * itemstime_size.y * ar;
373 pos.x += (mySize.x - newSize) / 2;
375 itemstime_size.x = mySize.x / columns;
377 panel_pos = pos - '1 1 0' * panel_bg_padding;
378 panel_size = mySize + '2 2 0' * panel_bg_padding;
382 if(itemstime_size.x/itemstime_size.y > ar)
384 newSize = ar * itemstime_size.y;
385 offset.x = itemstime_size.x - newSize;
387 itemstime_size.x = newSize;
391 newSize = 1/ar * itemstime_size.x;
392 offset.y = itemstime_size.y - newSize;
394 itemstime_size.y = newSize;
400 float row = 0, column = 0;
402 for (i = 0; i < ITEMSTIME_MAXITEMS; ++i) {
403 if (ItemsTime_time[i] == -1)
406 float item_time = ItemsTime_time[i];
409 item_available = true;
410 item_time = -item_time;
413 item_available = (item_time <= time);
415 if(ItemsTime_time[i] >= 0)
417 if(time <= ItemsTime_time[i])
418 ItemsTime_availableTime[i] = 0;
419 else if(ItemsTime_availableTime[i] == 0)
420 ItemsTime_availableTime[i] = time;
422 else if(ItemsTime_availableTime[i] == 0)
423 ItemsTime_availableTime[i] = time;
425 float f = (time - ItemsTime_availableTime[i]) * 2;
426 f = (f > 1) ? 0 : bound(0, f, 1);
428 if(autocvar_hud_panel_itemstime_hidespawned == 1)
429 if(!(ItemsTime_time[i] > time || -ItemsTime_time[i] > time))
432 if(autocvar_hud_panel_itemstime_hidespawned == 2)
433 if(!(ItemsTime_time[i] > time))
436 DrawItemsTimeItem(pos + eX * column * (itemstime_size.x + offset.x) + eY * row * (itemstime_size.y + offset.y), itemstime_size, ar, i, item_time, item_available, f);