seta hud_panel_itemstime 2 "enable this panel, 1 = show when spectating, 2 = even playing in warmup stage"
//seta hud_panel_quickmenu 1 "enable this panel"
//seta hud_panel_scoreboard 1 "enable this panel"
-seta hud_panel_scoreboard_accuracy 1 "show weapon accuracy stats panel on scoreboard; colors can be configured with accuracy_color* cvars"
+seta hud_panel_scoreboard_accuracy 1 "show weapon accuracy stats panel in the scoreboard; colors can be configured with accuracy_color* cvars"
seta hud_panel_scoreboard_ctf_leaderboard 1 "show a capture time rankings leaderboard in the scoreboard if allowed by the server"
+seta hud_panel_scoreboard_itemstats 1 "show item stats panel in the scoreboard"
seta hud_panel_strafehud 3 "enable this panel, 1 = show if not observing, 2 = show always, 3 = show only in race/cts if not observing"
seta hud_panel_weapons_dynamichud 1 "apply the dynamic hud effects to this panel"
seta hud_panel_scoreboard_spectators_showping 1 "show ping of spectators"
seta hud_panel_scoreboard_spectators_aligned 0 "align spectators in columns"
seta hud_panel_scoreboard_minwidth 0.6 "minimum width of the scoreboard"
+seta hud_panel_scoreboard_team_size_position 0 "where to show the team size (0 = do not show, 1 = left of scoreboard, 2 = right of scoreboard), will move team scores to the other side if necessary"
seta hud_panel_scoreboard_playerid 0 "show player id (server entity number) next to player's name"
seta hud_panel_scoreboard_playerid_prefix "#" "player id prefix"
seta hud_panel_scoreboard_playerid_suffix " " "player id suffix"
seta hud_panel_scoreboard_accuracy_showdelay 2 "how long to delay displaying accuracy below the scoreboard if it's too far down"
seta hud_panel_scoreboard_accuracy_showdelay_minpos 0.75 "delay displaying the accuracy panel only if its position is lower than this percentage of the screen height from the top"
-seta hud_panel_scoreboard_team_size_position 0 "where to show the team size (0 = do not show, 1 = left of scoreboard, 2 = right of scoreboard), will move team scores to the other side if necessary"
+
+seta hud_panel_scoreboard_itemstats_filter 1 "filter out less interesting items (ammo and smaller health/armor)"
+seta hud_panel_scoreboard_itemstats_showdelay 2.2 "how long to delay displaying item stats below the scoreboard if it's too far down"
+seta hud_panel_scoreboard_itemstats_showdelay_minpos 0.75 "delay displaying the item stats panel only if its position is lower than this percentage of the screen height from the top"
seta _hud_panel_strafehud_demo "0" "strafehud changes angle during configure"
seta hud_panel_strafehud_mode "0" "strafehud mode which controls whether the strafehud is centered at \"0\" = view angle, \"1\" = velocity angle"
seta hud_panel_scoreboard_bg_teams_color_team "" "override panel team color in team tables"
seta hud_panel_scoreboard_accuracy_doublerows "" "use two rows instead of one"
seta hud_panel_scoreboard_accuracy_nocolors "" "don't use colors displaying accuracy stats"
+seta hud_panel_scoreboard_itemstats_doublerows "" "use two rows instead of one"
seta hud_panel_strafehud_pos "" "position of this base of the panel"
seta hud_panel_strafehud_size "" "size of this panel"
seta hud_panel_scoreboard_bg_teams_color_team "0"
seta hud_panel_scoreboard_accuracy_doublerows "0"
seta hud_panel_scoreboard_accuracy_nocolors "0"
+seta hud_panel_scoreboard_itemstats_doublerows "0"
seta hud_panel_strafehud_pos "0.320000 0.570000"
seta hud_panel_strafehud_size "0.360000 0.020000"
seta hud_panel_scoreboard_bg_teams_color_team "0"
seta hud_panel_scoreboard_accuracy_doublerows "1"
seta hud_panel_scoreboard_accuracy_nocolors "0"
+seta hud_panel_scoreboard_itemstats_doublerows "0"
seta hud_panel_strafehud_pos "0.330000 0.570000"
seta hud_panel_strafehud_size "0.340000 0.020000"
seta hud_panel_scoreboard_bg_teams_color_team "0.7"
seta hud_panel_scoreboard_accuracy_doublerows "1"
seta hud_panel_scoreboard_accuracy_nocolors "0"
+seta hud_panel_scoreboard_itemstats_doublerows "0"
seta hud_panel_strafehud_pos "0.380000 0.550000"
seta hud_panel_strafehud_size "0.240000 0.025000"
seta hud_panel_scoreboard_bg_teams_color_team "0.7"
seta hud_panel_scoreboard_accuracy_doublerows "1"
seta hud_panel_scoreboard_accuracy_nocolors "0"
+seta hud_panel_scoreboard_itemstats_doublerows "0"
seta hud_panel_strafehud_pos "0.330000 0.700000"
seta hud_panel_strafehud_size "0.340000 0.015000"
seta hud_panel_scoreboard_bg_teams_color_team "0.7"
seta hud_panel_scoreboard_accuracy_doublerows "1"
seta hud_panel_scoreboard_accuracy_nocolors "0"
+seta hud_panel_scoreboard_itemstats_doublerows "0"
seta hud_panel_strafehud_pos "0.320000 0.540000"
seta hud_panel_strafehud_size "0.360000 0.025000"
seta hud_panel_scoreboard_bg_teams_color_team "0.7"
seta hud_panel_scoreboard_accuracy_doublerows "1"
seta hud_panel_scoreboard_accuracy_nocolors "0"
+seta hud_panel_scoreboard_itemstats_doublerows "0"
seta hud_panel_strafehud_pos "0.360000 0.570000"
seta hud_panel_strafehud_size "0.280000 0.025000"
if ( HUD_Radar_Clickable() )
{
- if (hud_panel_radar_bottom >= 0.96 * vid_conheight)
+ if (hud_panel_radar_bottom >= vid_conheight)
return;
panel_pos.x = 0.5 * (vid_conwidth - panel_size.x);
}
else if(!autocvar__hud_configure && scoreboard_fade_alpha)
{
- // move the panel below the scoreboard
- if (scoreboard_bottom >= 0.96 * vid_conheight)
- return;
vector target_pos = vec2(0.5 * (vid_conwidth - panel_size.x), scoreboard_bottom);
if(target_pos.y > panel_pos.y)
{
panel_pos = panel_pos + (target_pos - panel_pos) * sqrt(scoreboard_fade_alpha);
panel_size.y = min(panel_size.y, vid_conheight - scoreboard_bottom);
}
+
+ // move the panel below the scoreboard
+ if (panel_pos.y >= vid_conheight)
+ return;
}
if (autocvar_hud_panel_centerprint_dynamichud)
#include <common/scores.qh>
#include <common/stats.qh>
#include <common/teams.qh>
+#include <common/items/inventory.qh>
// Scoreboard (#24)
float autocvar_hud_panel_scoreboard_accuracy_showdelay = 2;
float autocvar_hud_panel_scoreboard_accuracy_showdelay_minpos = 0.75;
+bool autocvar_hud_panel_scoreboard_itemstats = true;
+bool autocvar_hud_panel_scoreboard_itemstats_doublerows = false;
+bool autocvar_hud_panel_scoreboard_itemstats_filter = true;
+float autocvar_hud_panel_scoreboard_itemstats_showdelay = 2.2; // slightly more delayed than accuracy
+float autocvar_hud_panel_scoreboard_itemstats_showdelay_minpos = 0.75;
+
bool autocvar_hud_panel_scoreboard_dynamichud = false;
float autocvar_hud_panel_scoreboard_maxheight = 0.6;
panel_size.y += panel_bg_padding * 2;
HUD_Panel_DrawBg();
- vector end_pos = panel_pos + eY * (panel_size.y + 0.5* hud_fontsize.y);
+ vector end_pos = panel_pos + eY * (panel_size.y + 0.5 * hud_fontsize.y);
if(panel.current_panel_bg != "0")
end_pos.y += panel_bg_border * 2;
float average_accuracy;
vector Scoreboard_AccuracyStats_Draw(vector pos, vector rgb, vector bg_size)
{
- if (frametime)
- {
- if (scoreboard_fade_alpha == 1)
- scoreboard_acc_fade_alpha = min(1, scoreboard_acc_fade_alpha + frametime * 10);
- else
- scoreboard_acc_fade_alpha = 1; // sync fading with the scoreboard
- }
- vector initial_pos = pos;
+ scoreboard_acc_fade_alpha = min(scoreboard_fade_alpha, scoreboard_acc_fade_alpha + frametime * 10);
WepSet weapons_stat = WepSet_GetFromStat();
WepSet weapons_inmap = WepSet_GetFromStat_InMap();
HUD_Panel_DrawBg();
panel_bg_alpha = panel_bg_alpha_save;
- vector end_pos = panel_pos + eY * (panel_size.y + hud_fontsize.y);
+ vector end_pos = panel_pos + eY * (panel_size.y + 0.5 * hud_fontsize.y);
if(panel.current_panel_bg != "0")
end_pos.y += panel_bg_border * 2;
panel_size.x += panel_bg_padding * 2; // restore initial width
- if (scoreboard_acc_fade_alpha == 1)
- return end_pos;
- return initial_pos + (end_pos - initial_pos) * scoreboard_acc_fade_alpha;
+ return end_pos;
+}
+
+.bool uninteresting;
+STATIC_INIT(default_order_items_label)
+{
+ IL_EACH(default_order_items, true, {
+ if(!(it.instanceOfPowerup
+ || it == ITEM_HealthMega || it == ITEM_HealthBig
+ || it == ITEM_ArmorMega || it == ITEM_ArmorBig
+ ))
+ {
+ it.uninteresting = true;
+ }
+ });
+}
+
+vector Scoreboard_ItemStats_Draw(vector pos, vector rgb, vector bg_size)
+{
+ scoreboard_itemstats_fade_alpha = min(scoreboard_fade_alpha, scoreboard_itemstats_fade_alpha + frametime * 10);
+
+ int disowned_cnt = 0;
+ int uninteresting_cnt = 0;
+ IL_EACH(default_order_items, true, {
+ int q = g_inventory.inv_items[it.m_id];
+ //q = 1; // debug: display all items
+ if (autocvar_hud_panel_scoreboard_itemstats_filter && it.uninteresting)
+ ++uninteresting_cnt;
+ else if (!q)
+ ++disowned_cnt;
+ });
+ int items_cnt = REGISTRY_COUNT(Items) - uninteresting_cnt;
+ int n = items_cnt - disowned_cnt;
+ if (n <= 0) return pos;
+
+ int rows = (autocvar_hud_panel_scoreboard_itemstats_doublerows && n >= floor(REGISTRY_COUNT(Items) / 2)) ? 2 : 1;
+ int columnns = max(6, ceil(n / rows));
+
+ float height = 40;
+ float fontsize = height * 1/3;
+ float item_height = height * 2/3;
+
+ drawstring(pos + eX * panel_bg_padding, _("Item stats"), hud_fontsize, '1 1 1', panel_fg_alpha * scoreboard_itemstats_fade_alpha, DRAWFLAG_NORMAL);
+ pos.y += 1.25 * hud_fontsize.y;
+ if(panel.current_panel_bg != "0")
+ pos.y += panel_bg_border;
+
+ panel_pos = pos;
+ panel_size.y = height * rows;
+ panel_size.y += panel_bg_padding * 2;
+
+ float panel_bg_alpha_save = panel_bg_alpha;
+ panel_bg_alpha *= scoreboard_itemstats_fade_alpha;
+ HUD_Panel_DrawBg();
+ panel_bg_alpha = panel_bg_alpha_save;
+
+ vector end_pos = panel_pos + eY * (panel_size.y + 0.5 * hud_fontsize.y);
+ if(panel.current_panel_bg != "0")
+ end_pos.y += panel_bg_border * 2;
+
+ if(panel_bg_padding)
+ {
+ panel_pos += '1 1 0' * panel_bg_padding;
+ panel_size -= '2 2 0' * panel_bg_padding;
+ }
+
+ pos = panel_pos;
+ vector tmp = panel_size;
+
+ float item_width = tmp.x / columnns / rows;
+
+ if (sbt_bg_alpha)
+ drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, sbt_bg_alpha * scoreboard_itemstats_fade_alpha, DRAWFLAG_NORMAL);
+
+ if(sbt_highlight)
+ {
+ // column highlighting
+ for (int i = 0; i < columnns; ++i)
+ if ((i % 2) == 0)
+ drawfill(pos + '1 0 0' * item_width * rows * i, '0 1 0' * height * rows + '1 0 0' * item_width * rows, '0 0 0', sbt_highlight_alpha * scoreboard_itemstats_fade_alpha, DRAWFLAG_NORMAL);
+
+ // row highlighting
+ for (int i = 0; i < rows; ++i)
+ drawfill(pos + '0 1 0' * item_height + '0 1 0' * height * i, '1 0 0' * panel_size.x + '0 1 0' * fontsize, rgb, sbt_highlight_alpha * scoreboard_itemstats_fade_alpha, DRAWFLAG_NORMAL);
+ }
+
+ if (rows == 2)
+ pos.x += item_width / 2;
+
+ float oldposx = pos.x;
+ vector tmpos = pos;
+
+ int column = 0;
+ IL_EACH(default_order_items, !(autocvar_hud_panel_scoreboard_itemstats_filter && it.uninteresting), {
+ int n = g_inventory.inv_items[it.m_id];
+ //n = 1 + floor(i * 3 + 4.8) % 7; // debug: display a value for each item
+ if (n <= 0) continue;
+ drawpic_aspect_skin(tmpos, it.m_icon, '1 0 0' * item_width + '0 1 0' * item_height, '1 1 1', panel_fg_alpha * scoreboard_itemstats_fade_alpha, DRAWFLAG_NORMAL);
+ string s = ftos(n);
+ float padding = (item_width - stringwidth(s, false, '1 0 0' * fontsize)) / 2; // center
+ drawstring(tmpos + '1 0 0' * padding + '0 1 0' * item_height, s, '1 1 0' * fontsize, '1 1 1', panel_fg_alpha * scoreboard_itemstats_fade_alpha, DRAWFLAG_NORMAL);
+ tmpos.x += item_width * rows;
+ pos.x += item_width * rows;
+ if (rows == 2 && column == columnns - 1) {
+ tmpos.x = oldposx;
+ tmpos.y += height;
+ pos.y += height;
+ }
+ ++column;
+ });
+
+ panel_size.x += panel_bg_padding * 2; // restore initial width
+
+ return end_pos;
}
vector MapStats_DrawKeyValue(vector pos, string key, string value) {
panel_size.y += panel_bg_padding * 2;
HUD_Panel_DrawBg();
- vector end_pos = panel_pos + eY * (panel_size.y + hud_fontsize.y);
+ vector end_pos = panel_pos + eY * (panel_size.y + 0.5 * hud_fontsize.y);
if(panel.current_panel_bg != "0")
end_pos.y += panel_bg_border * 2;
HUD_Panel_DrawBg();
- vector end_pos = panel_pos + eY * (panel_size.y + hud_fontsize.y);
+ vector end_pos = panel_pos + eY * (panel_size.y + 0.5 * hud_fontsize.y);
if(panel.current_panel_bg != "0")
end_pos.y += panel_bg_border * 2;
return true;
}
+bool have_item_stats;
+bool Scoreboard_ItemStats_WouldDraw(float ypos)
+{
+ if (MUTATOR_CALLHOOK(DrawScoreboardItemStats))
+ return false;
+ if (!autocvar_hud_panel_scoreboard_itemstats || !g_inventory || warmup_stage || ypos > 0.91 * vid_conheight)
+ return false;
+
+ if (time < scoreboard_time + autocvar_hud_panel_scoreboard_itemstats_showdelay
+ && ypos > autocvar_hud_panel_scoreboard_itemstats_showdelay_minpos * vid_conheight
+ && !intermission)
+ {
+ return false;
+ }
+
+ if (!have_item_stats)
+ {
+ IL_EACH(default_order_items, true, {
+ if (!(autocvar_hud_panel_scoreboard_itemstats_filter && it.uninteresting))
+ {
+ int q = g_inventory.inv_items[it.m_id];
+ //q = 1; // debug: display all items
+ if (q)
+ {
+ have_item_stats = true;
+ break;
+ }
+ }
+ });
+ if (!have_item_stats)
+ return false;
+ }
+
+ return true;
+}
+
void Scoreboard_Draw()
{
if(!autocvar__hud_configure)
// frametime checks allow to toggle the scoreboard even when the game is paused
if(scoreboard_active) {
- if (scoreboard_fade_alpha < 1)
+ if (scoreboard_fade_alpha == 0)
scoreboard_time = time;
if(hud_configure_menu_open == 1)
scoreboard_fade_alpha = 1;
if (!scoreboard_fade_alpha)
{
scoreboard_acc_fade_alpha = 0;
+ scoreboard_itemstats_fade_alpha = 0;
return;
}
}
Scoreboard_UpdatePlayerTeams();
+ float initial_pos_y = panel_pos.y;
vector pos = panel_pos;
entity pl, tm;
string str;
if (Scoreboard_AccuracyStats_WouldDraw(pos.y))
pos = Scoreboard_AccuracyStats_Draw(pos, panel_bg_color, bg_size);
+ if (Scoreboard_ItemStats_WouldDraw(pos.y))
+ pos = Scoreboard_ItemStats_Draw(pos, panel_bg_color, bg_size);
if(MUTATOR_CALLHOOK(ShowRankings)) {
string ranktitle = M_ARGV(0, string);
drawcolorcodedstring(pos + '0.5 0 0' * (panel_size.x - stringwidth(str, true, hud_fontsize)), str, hud_fontsize, panel_fg_alpha, DRAWFLAG_NORMAL);
}
- scoreboard_bottom = pos.y + 2 * hud_fontsize.y;
+ pos.y += 2 * hud_fontsize.y;
+ if (scoreboard_fade_alpha < 1)
+ scoreboard_bottom = initial_pos_y + (pos.y - initial_pos_y) * scoreboard_fade_alpha;
+ else if (pos.y != scoreboard_bottom)
+ {
+ if (pos.y > scoreboard_bottom)
+ scoreboard_bottom = min(pos.y, scoreboard_bottom + frametime * 10 * (pos.y - initial_pos_y));
+ else
+ scoreboard_bottom = max(pos.y, scoreboard_bottom - frametime * 10 * (pos.y - initial_pos_y));
+ }
}
bool scoreboard_active;
float scoreboard_fade_alpha;
float scoreboard_acc_fade_alpha;
+float scoreboard_itemstats_fade_alpha;
void Cmd_Scoreboard_SetFields(int argc);
void Scoreboard_Draw();
/** Return true to not show accuracy stats in the scoreboard */
MUTATOR_HOOKABLE(DrawScoreboardAccuracy, EV_NO_ARGS);
+/** Return true to not show item pickup stats in the scoreboard */
+MUTATOR_HOOKABLE(DrawScoreboardItemStats, EV_NO_ARGS);
+
/** Called when drawing info messages, allows adding new info messages. Return true to hide the standard join message */
#define EV_DrawInfoMessages(i, o) \
/** pos */ i(vector, MUTATOR_ARGV_0_vector) \
return spectatee_status == -1 && ISGAMETYPE(CTS); // hide the score panel while observing
}
+MUTATOR_HOOKFUNCTION(cl_cts, DrawScoreboardItemStats)
+{
+ return ISGAMETYPE(CTS); // hide the item stats panel
+}
+
MUTATOR_HOOKFUNCTION(cl_cts, DrawDeathScoreboard)
{
return ISGAMETYPE(CTS); // no scoreboard shown while dead
// generated file; do not modify
#include <common/gamemodes/gamemode/invasion/invasion.qc>
+#ifdef CSQC
+ #include <common/gamemodes/gamemode/invasion/cl_invasion.qc>
+#endif
#ifdef SVQC
#include <common/gamemodes/gamemode/invasion/sv_invasion.qc>
#endif
// generated file; do not modify
#include <common/gamemodes/gamemode/invasion/invasion.qh>
+#ifdef CSQC
+ #include <common/gamemodes/gamemode/invasion/cl_invasion.qh>
+#endif
#ifdef SVQC
#include <common/gamemodes/gamemode/invasion/sv_invasion.qh>
#endif
--- /dev/null
+#include "cl_invasion.qh"
+
+#include <common/mutators/base.qh>
+
+REGISTER_MUTATOR(cl_inv, true);
+
+MUTATOR_HOOKFUNCTION(cl_inv, DrawScoreboardItemStats)
+{
+ return ISGAMETYPE(INVASION); // hide the item stats panel
+}
--- /dev/null
+#pragma once
{
return ISGAMETYPE(NEXBALL); // accuracy is not a factor in this gamemode
}
+
+MUTATOR_HOOKFUNCTION(cl_nb, DrawScoreboardItemStats)
+{
+ return ISGAMETYPE(NEXBALL); // hide the item stats panel
+}
return spectatee_status == -1 && ISGAMETYPE(RACE); // hide the score panel while observing
}
+MUTATOR_HOOKFUNCTION(cl_race, DrawScoreboardItemStats)
+{
+ return ISGAMETYPE(RACE); // hide the item stats panel
+}
+
MUTATOR_HOOKFUNCTION(cl_race, ShowRankings)
{
if(ISGAMETYPE(RACE))
REGISTER_REGISTRY(Items)
#define REGISTER_ITEM(id, class) REGISTER(Items, ITEM, id, m_id, NEW(class))
+#ifdef CSQC
+// Copy Items registry here before it gets sorted alphabetically by REGISTRY_SORT
+// so we can keep items sorted by categories (as they appear in the code)
+IntrusiveList default_order_items;
+STATIC_INIT(default_order_items)
+{
+ default_order_items = IL_NEW();
+ FOREACH(Items, true, {
+ IL_PUSH(default_order_items, it);
+ });
+}
+#endif
+
REGISTRY_SORT(Items)
REGISTRY_CHECK(Items)
#ifdef CSQC
Inventory g_inventory;
+void Inventory_remove(entity this)
+{
+ if(g_inventory == this)
+ g_inventory = NULL;
+}
+
NET_HANDLE(ENT_CLIENT_INVENTORY, bool isnew)
{
make_pure(this);
g_inventory = this;
+ this.entremove = Inventory_remove;
const int majorBits = Readbits(Inventory_groups_major);
for (int i = 0; i < Inventory_groups_major; ++i) {
if (!(majorBits & BIT(i))) {
setcefc(inv, Inventory_customize);
Net_LinkEntity((inv.owner = this).inventory = inv, false, 0, Inventory_Send);
}
-void Inventory_delete(entity e) { delete(e.inventory.inventory); delete(e.inventory); }
+void Inventory_delete(entity e) { delete(e.inventory); }
void Inventory_update(entity e) { e.inventory.SendFlags = 0xFFFFFF; }
+void Inventory_clear(entity store)
+{
+ // NOTE: you will need to perform Inventory_update after this to update the storage entity
+ // (unless store is the storage entity)
+ FOREACH(Items, true, {
+ .int fld = inv_items[it.m_id];
+ store.(fld) = 0;
+ });
+}
+
void InventoryStorage_attach(entity e) { e.inventory_store = NEW(Inventory); e.inventory_store.drawonlytoclient = e; }
-void InventoryStorage_detach(entity e) { delete(e.inventory_store); }
+void InventoryStorage_delete(entity e) { delete(e.inventory_store); }
#endif
void Inventory_new(PlayerState this);
void Inventory_delete(entity this);
+void Inventory_clear(PlayerState this);
void InventoryStorage_attach(PlayerState this);
-void InventoryStorage_detach(PlayerState this);
+void InventoryStorage_delete(PlayerState this);
void PlayerState_attach(entity this)
{
PlayerState ps = PS(this);
if (!ps) return; // initial connect
PS(this) = NULL;
+ Inventory_clear(this.inventory_store); // no need to network updates, as there is no inventory attached
if (ps.m_client != this) return; // don't own state, spectator
ps.ps_push(ps, this);
W_HitPlotClose(this);
ClientData_Detach(this);
entcs_detach(this);
- InventoryStorage_detach(this);
+ InventoryStorage_delete(this);
delete(CS(this));
this._cs = NULL;
#include <common/command/_mod.qh>
#include <common/constants.qh>
#include <common/gamemodes/_mod.qh>
+#include <common/items/inventory.qh>
#include <common/mapinfo.qh>
#include <common/net_linked.qh>
#include <common/notifications/all.qh>
shuffleteams();
shuffleteams_on_reset_map = false;
}
+
+ FOREACH_CLIENT(IS_PLAYER(it),
+ {
+ entity store = PS(it);
+ if (store)
+ {
+ Inventory_clear(store.inventory);
+ Inventory_update(store);
+ }
+ });
+
MUTATOR_CALLHOOK(reset_map_global);
FOREACH_ENTITY_FLOAT_ORDERED(pure_data, false,