openmohaa/code/client/cl_uistd.cpp
smallmodel 6fe1e86b31
Automatically scale UI elements for high resolutions
This fixes UI elements being tiny on high resolutions like 4K. Now most UI elements will scale automatically with resolutions above 1920x1080.
2024-11-30 22:40:00 +01:00

1641 lines
50 KiB
C++

/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110EV_DEFAULT301 USA
===========================================================================
*/
#include "cl_ui.h"
#include "../qcommon/localization.h"
Event EV_Layout_PlayerStat
(
"playerstat",
EV_DEFAULT,
"i",
"playerstatValue",
"set playerstat for layout\n"
);
// Added in 2.0
Event EV_Layout_PlayerStatAlpha
(
"playerstatalpha",
EV_DEFAULT,
"i",
"playerstatValue",
"set playerstat to control alpha for layout\n"
);
Event EV_Layout_PlayerStatConfigstring
(
"playerstatconfigstring",
EV_DEFAULT,
"i",
"playerstatValue",
"set playerstat for layout - will print out the corresponding configstring\n"
);
Event EV_Layout_MaxPlayerStat
(
"maxplayerstat",
EV_DEFAULT,
"i",
"maxPlayerstatValue",
"set the playerstat that holds the max value for that stat. Used for statbars\n"
);
Event EV_Layout_ItemIndex
(
"itemstat",
EV_DEFAULT,
"i",
"itemstatValue",
"set itemstat for layout\n"
);
Event EV_Layout_InventoryRenderModelIndex
(
"invmodelhand",
EV_DEFAULT,
"i",
"handindex",
"set the specified hand index to render a 3d model from\n"
);
Event EV_Layout_Statbar
(
"statbar",
EV_DEFAULT,
"sII",
"orientation min max",
"make this label present the stat using a graphical bar. Optionally specify a min and max value"
);
Event EV_Layout_StatbarTileShader
(
"statbar_tileshader",
EV_DEFAULT,
"s",
"shader",
"set the tile shader for this statbar"
);
Event EV_Layout_StatbarTileShader_Flash
(
"statbar_tileshader_flash",
EV_DEFAULT,
"s",
"shader",
"set the flash tile shader for this statbar"
);
Event EV_Layout_StatbarShader
(
"statbar_shader",
EV_DEFAULT,
"s",
"shader",
"set the shader for this statbar"
);
Event EV_Layout_StatbarShader_Flash
(
"statbar_shader_flash",
EV_DEFAULT,
"s",
"shader",
"set the flash shader for this statbar"
);
// Added in 2.0
Event EV_Layout_StatbarShader_Marker
(
"statbar_shader_marker",
EV_DEFAULT,
"s",
"shader",
"set the marker shader for this statbar\nThis is drawn at the end of the status bar"
);
Event EV_Layout_Statbar_EndAngles
(
"statbar_endangles",
EV_DEFAULT,
"ff",
"startang endang",
"Sets the start and end angles for a circular stat bar"
);
Event EV_Layout_Statbar_NeedleWidth
(
"statbar_needlewidth",
EV_DEFAULT,
"f",
"width",
"Sets the width of the needle for a needle statbar"
);
Event EV_Layout_Statbar_RotatorSize
(
"statbar_rotatorsize",
EV_DEFAULT,
"f",
"width",
"Sets the width of the needle for a needle statbar"
);
Event EV_Layout_DrawModelName
(
"invmodelname",
EV_DEFAULT,
"s",
"name",
"set the name of the 3d model to render\n"
);
Event EV_Layout_RenderModel
(
"rendermodel",
EV_DEFAULT,
"b",
"bool",
"Render the model specified by the cvar."
);
Event EV_Layout_RenderModelOffset
(
"modeloffset",
EV_DEFAULT,
"v",
"offset",
"Render model offset"
);
Event EV_Layout_RenderModelRotateOffset
(
"modelrotateoffset",
EV_DEFAULT,
"v",
"offset",
"Render model rotation offset"
);
Event EV_Layout_RenderModelAngles
(
"modelangles",
EV_DEFAULT,
"v",
"angles",
"Render model angles"
);
Event EV_Layout_RenderModelScale
(
"modelscale",
EV_DEFAULT,
"f",
"scale",
"Render model scale"
);
Event EV_Layout_RenderModelAnim
(
"modelanim",
EV_DEFAULT,
"s",
"anim",
"Render model anim"
);
Event EV_ClearInvItemReference
(
"clearinvitemref",
EV_DEFAULT,
NULL,
NULL,
"used internally when the inventory is reset\n"
);
CLASS_DECLARATION(UILabel, UIFakkLabel, NULL) {
{&EV_Layout_PlayerStat, &UIFakkLabel::LayoutPlayerStat },
{&EV_Layout_PlayerStatAlpha, &UIFakkLabel::LayoutPlayerStatAlpha },
{&EV_Layout_PlayerStatConfigstring, &UIFakkLabel::LayoutPlayerStatConfigstring },
{&EV_Layout_MaxPlayerStat, &UIFakkLabel::LayoutMaxPlayerStat },
{&EV_Layout_ItemIndex, &UIFakkLabel::LayoutItemIndex },
{&EV_Layout_InventoryRenderModelIndex, &UIFakkLabel::InventoryRenderModelIndex },
{&EV_Layout_Statbar, &UIFakkLabel::LayoutStatbar },
{&EV_Layout_StatbarTileShader, &UIFakkLabel::LayoutStatbarTileShader },
{&EV_Layout_StatbarShader, &UIFakkLabel::LayoutStatbarShader },
{&EV_Layout_StatbarTileShader_Flash, &UIFakkLabel::LayoutStatbarTileShader_Flash},
{&EV_Layout_StatbarShader_Marker, &UIFakkLabel::LayoutStatbarShader_Marker },
{&EV_Layout_StatbarShader_Flash, &UIFakkLabel::LayoutStatbarShader_Flash },
{&EV_Layout_Statbar_EndAngles, &UIFakkLabel::LayoutStatbarEndAngles },
{&EV_Layout_Statbar_NeedleWidth, &UIFakkLabel::LayoutStatbarNeedleWidth },
{&EV_Layout_Statbar_RotatorSize, &UIFakkLabel::LayoutStatbarRotatorSize },
{&EV_Layout_DrawModelName, &UIFakkLabel::LayoutModelName },
{&EV_Layout_RenderModel, &UIFakkLabel::LayoutRenderModel },
{&EV_Layout_RenderModelOffset, &UIFakkLabel::LayoutRenderModelOffset },
{&EV_Layout_RenderModelRotateOffset, &UIFakkLabel::LayoutRenderModelRotateOffset},
{&EV_Layout_RenderModelAngles, &UIFakkLabel::LayoutRenderModelAngles },
{&EV_Layout_RenderModelScale, &UIFakkLabel::LayoutRenderModelScale },
{&EV_Layout_RenderModelAnim, &UIFakkLabel::LayoutRenderModelAnim },
{&EV_ClearInvItemReference, &UIFakkLabel::ClearInvItemReference },
{NULL, NULL }
};
UIFakkLabel::UIFakkLabel()
{
m_statbar_min = m_statbar_max = -1.0;
m_stat = -1;
m_stat_alpha = -1;
m_stat_configstring = -1;
m_maxstat = -1;
m_itemindex = -1;
m_inventoryrendermodelindex = -1;
m_rendermodel = false;
m_statbar_or = L_STATBAR_NONE;
m_statbar_material = NULL;
m_statbar_material_flash = NULL;
m_statbar_material_marker = NULL;
m_lastitemindex = -1;
}
void UIFakkLabel::LayoutPlayerStat(Event *ev)
{
m_stat = ev->GetInteger(1);
}
void UIFakkLabel::LayoutPlayerStatAlpha(Event *ev)
{
m_stat_alpha = ev->GetInteger(1);
}
void UIFakkLabel::LayoutPlayerStatConfigstring(Event *ev)
{
m_stat_configstring = ev->GetInteger(1);
}
void UIFakkLabel::LayoutMaxPlayerStat(Event *ev)
{
m_maxstat = ev->GetInteger(1);
}
void UIFakkLabel::LayoutItemIndex(Event *ev)
{
m_itemindex = ev->GetInteger(1);
}
void UIFakkLabel::InventoryRenderModelIndex(Event *ev)
{
m_inventoryrendermodelindex = ev->GetInteger(1);
}
void UIFakkLabel::LayoutModelName(Event *ev)
{
m_sDrawModelName = ev->GetString(1);
}
void UIFakkLabel::ClearInvItemReference(Event *ev)
{
m_lastitem = NULL;
m_lastitemindex = -1;
}
void UIFakkLabel::LayoutStatbar(Event *ev)
{
str _or = ev->GetString(1);
if (ev->NumArgs() > 1) {
m_statbar_min = ev->GetFloat(2);
m_statbar_max = ev->GetFloat(3);
}
if (!str::icmp(_or, "horizontal")) {
m_statbar_or = L_STATBAR_HORIZONTAL;
} else if (!str::icmp(_or, "vertical_stagger_even")) {
m_statbar_or = L_STATBAR_VERTICAL_STAGGER_EVEN;
} else if (!str::icmp(_or, "vertical_stagger_odd")) {
m_statbar_or = L_STATBAR_VERTICAL_STAGGER_ODD;
} else if (!str::icmp(_or, "vertical")) {
m_statbar_or = L_STATBAR_VERTICAL;
} else if (!str::icmp(_or, "vertical_reverse")) {
m_statbar_or = L_STATBAR_VERTICAL_REVERSE;
} else if (!str::icmp(_or, "circular")) {
m_statbar_or = L_STATBAR_CIRCULAR;
if (!m_statbar_material) {
m_statbar_material = uWinMan.RegisterShader("blank");
}
} else if (!str::icmp(_or, "needle")) {
m_statbar_or = L_STATBAR_NEEDLE;
if (!m_statbar_material) {
m_statbar_material = uWinMan.RegisterShader("blank");
}
} else if (!str::icmp(_or, "rotator")) {
m_statbar_or = L_STATBAR_ROTATOR;
if (!m_statbar_material) {
m_statbar_material = uWinMan.RegisterShader("blank");
}
} else if (!str::icmp(_or, "compass")) {
m_statbar_or = L_STATBAR_COMPASS;
if (!m_statbar_material) {
m_statbar_material = uWinMan.RegisterShader("blank");
}
} else if (!str::icmp(_or, "spinner")) {
m_statbar_or = L_STATBAR_SPINNER;
if (!m_statbar_material) {
m_statbar_material = uWinMan.RegisterShader("blank");
}
} else if (!str::icmp(_or, "headingspinner")) {
m_statbar_or = L_STATBAR_HEADING_SPINNER;
if (!m_statbar_material) {
m_statbar_material = uWinMan.RegisterShader("blank");
}
} else {
warning("LayoutPlayerStat", "Invalid statbar orientation: \"%s\"", _or.c_str());
}
}
void UIFakkLabel::LayoutStatbarShader(Event *ev)
{
m_statbar_material = uWinMan.RegisterShader(ev->GetString(1));
}
void UIFakkLabel::LayoutStatbarTileShader(Event *ev)
{
m_statbar_material = uWinMan.RegisterShader(ev->GetString(1));
AddFlag(WF_TILESHADER);
}
void UIFakkLabel::LayoutStatbarShader_Flash(Event *ev)
{
m_statbar_material_flash = uWinMan.RegisterShader(ev->GetString(1));
}
void UIFakkLabel::LayoutStatbarShader_Marker(Event *ev)
{
m_statbar_material_marker = uWinMan.RegisterShader(ev->GetString(1));
}
void UIFakkLabel::LayoutStatbarEndAngles(Event *ev)
{
m_angles[0] = ev->GetFloat(1);
m_angles[1] = ev->GetFloat(2);
}
void UIFakkLabel::LayoutStatbarNeedleWidth(Event *ev)
{
m_angles[2] = ev->GetFloat(1);
}
void UIFakkLabel::LayoutStatbarRotatorSize(Event *ev)
{
m_angles[2] = ev->GetFloat(1);
if (ev->NumArgs() > 1) {
m_scale = ev->GetFloat(2);
} else {
m_scale = m_angles[2];
}
}
void UIFakkLabel::LayoutStatbarTileShader_Flash(Event *ev)
{
m_statbar_material_flash = uWinMan.RegisterShader(ev->GetString(1));
AddFlag(WF_TILESHADER);
}
void UIFakkLabel::LayoutRenderModel(Event *ev)
{
m_rendermodel = ev->GetBoolean(1);
}
void UIFakkLabel::LayoutRenderModelOffset(Event *ev)
{
Vector vec = ev->GetVector(1);
VectorCopy(vec, m_offset);
}
void UIFakkLabel::LayoutRenderModelRotateOffset(Event *ev)
{
Vector vec = ev->GetVector(1);
VectorCopy(vec, m_rotateoffset);
}
void UIFakkLabel::LayoutRenderModelAngles(Event *ev)
{
Vector vec = ev->GetVector(1);
VectorCopy(vec, m_angles);
}
void UIFakkLabel::LayoutRenderModelScale(Event *ev)
{
m_scale = ev->GetFloat(1);
}
void UIFakkLabel::LayoutRenderModelAnim(Event *ev)
{
m_anim = ev->GetString(1);
}
void UIFakkLabel::DrawStatbar(float frac)
{
vec4_t col;
float alpha;
qhandle_t hMat;
float w, h;
float fvWidth, fvHeight;
col[0] = col[1] = col[2] = col[3] = 1.0;
switch (m_statbar_or) {
case L_STATBAR_CIRCULAR:
DrawStatCircle(frac);
return;
case L_STATBAR_NEEDLE:
DrawStatNeedle(frac);
return;
case L_STATBAR_ROTATOR:
DrawStatRotator(frac);
return;
case L_STATBAR_COMPASS:
DrawStatCompass(frac);
return;
case L_STATBAR_SPINNER:
case L_STATBAR_HEADING_SPINNER:
DrawStatSpinner(frac);
return;
default:
break;
}
if (!frac) {
return;
}
if (frac != m_lastfrac) {
m_flashtime = uid.time;
}
m_lastfrac = frac;
alpha = 1.0 - ((float)uid.time - m_flashtime) / 1500.0;
alpha = Q_clamp_float(alpha, 0, 1);
col[3] = alpha;
if (m_statbar_material) {
if (m_flags & WF_TILESHADER) {
switch (m_statbar_or) {
case L_STATBAR_HORIZONTAL:
{
float width = frac * m_frame.size.width;
fvWidth = m_frame.size.width / m_vVirtualScale[0] / uii.Rend_GetShaderWidth(m_statbar_material->GetMaterial());
fvHeight = m_frame.size.height / m_vVirtualScale[1] / uii.Rend_GetShaderHeight(m_statbar_material->GetMaterial());
re.DrawStretchPic(0.0, 0.0, width, m_frame.size.height, 0, 0, fvWidth, fvHeight, m_statbar_material->GetMaterial());
//re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material->GetMaterial());
if (alpha != 0.0 && m_statbar_material_flash) {
re.SetColor(col);
fvWidth = m_frame.size.width / m_vVirtualScale[0] / uii.Rend_GetShaderWidth(m_statbar_material_flash->GetMaterial());
fvHeight = m_frame.size.height / m_vVirtualScale[1] / uii.Rend_GetShaderHeight(m_statbar_material_flash->GetMaterial());
re.DrawStretchPic(0.0, 0.0, width, m_frame.size.height, 0, 0, fvWidth, fvHeight, m_statbar_material_flash->GetMaterial());
//re.DrawTilePic(0.0, 0.0, width, m_frame.size.height, m_statbar_material_flash->GetMaterial());
}
if (m_statbar_material_marker) {
hMat = m_statbar_material_marker->GetMaterial();
w = re.GetShaderWidth(hMat);
h = re.GetShaderHeight(hMat);
re.DrawStretchPic(
m_frame.size.width * frac - w * 0.5,
m_frame.size.height * 0.5 - h * 0.5,
w,
h,
0,
0,
1,
1,
hMat
);
}
break;
}
case L_STATBAR_VERTICAL:
case L_STATBAR_VERTICAL_REVERSE:
case L_STATBAR_VERTICAL_STAGGER_EVEN:
case L_STATBAR_VERTICAL_STAGGER_ODD:
{
float y = m_frame.size.height * (1.0 - frac);
fvWidth = m_frame.size.width / m_vVirtualScale[0] / uii.Rend_GetShaderWidth(m_statbar_material->GetMaterial());
fvHeight = m_frame.size.height / m_vVirtualScale[1] / uii.Rend_GetShaderHeight(m_statbar_material->GetMaterial());
re.DrawStretchPic(0.0, y, m_frame.size.width, m_frame.size.height, 0, 0, fvWidth, fvHeight, m_statbar_material->GetMaterial());
//re.DrawTilePic(0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material->GetMaterial());
if (alpha != 0.0 && m_statbar_material_flash) {
re.SetColor(col);
fvWidth = m_frame.size.width / m_vVirtualScale[0] / uii.Rend_GetShaderWidth(m_statbar_material_flash->GetMaterial());
fvHeight = m_frame.size.height / m_vVirtualScale[1] / uii.Rend_GetShaderHeight(m_statbar_material_flash->GetMaterial());
re.DrawStretchPic(0.0, y, m_frame.size.width, m_frame.size.height, 0, 0, fvWidth, fvHeight, m_statbar_material_flash->GetMaterial());
//re.DrawTilePic(
// 0.0, y, m_frame.size.width, m_frame.size.height, m_statbar_material_flash->GetMaterial()
//);
}
if (m_statbar_material_marker) {
hMat = m_statbar_material_marker->GetMaterial();
w = re.GetShaderWidth(hMat);
h = re.GetShaderHeight(hMat);
re.DrawStretchPic(
m_frame.size.width * frac - w * 0.5,
m_frame.size.height * 0.5 - h * 0.5,
w,
h,
0,
0,
1,
1,
hMat
);
}
break;
}
default:
break;
}
} else {
switch (m_statbar_or) {
case L_STATBAR_HORIZONTAL:
{
float width = frac * m_frame.size.width;
re.DrawStretchPic(
0.0, 0.0, width, m_frame.size.height, 0.0, 0.0, 1.0, 1.0, m_statbar_material->GetMaterial()
);
if (alpha != 0.0 && m_statbar_material_flash) {
re.SetColor(col);
re.DrawStretchPic(
0.0,
0.0,
width,
m_frame.size.height,
0.0,
0.0,
1.0,
1.0,
m_statbar_material_flash->GetMaterial()
);
}
if (m_statbar_material_marker) {
hMat = m_statbar_material_marker->GetMaterial();
w = re.GetShaderWidth(hMat);
h = re.GetShaderHeight(hMat);
re.DrawStretchPic(
m_frame.size.width * frac - w * 0.5,
m_frame.size.height * 0.5 - h * 0.5,
w,
h,
0,
0,
1,
1,
hMat
);
}
break;
}
case L_STATBAR_VERTICAL:
case L_STATBAR_VERTICAL_STAGGER_EVEN:
case L_STATBAR_VERTICAL_STAGGER_ODD:
{
float y = m_frame.size.height * (1.0 - frac);
float height = m_frame.size.height * frac;
re.DrawStretchPic(
0.0, y, m_frame.size.width, height, 0.0, 1.0 - frac, 1.0, 1.0, m_statbar_material->GetMaterial()
);
if (alpha != 0.0 && m_statbar_material_flash) {
re.SetColor(col);
re.DrawStretchPic(
0.0,
y,
m_frame.size.width,
height,
0.0,
1.0 - frac,
1.0,
1.0,
m_statbar_material_flash->GetMaterial()
);
}
if (m_statbar_material_marker) {
hMat = m_statbar_material_marker->GetMaterial();
w = re.GetShaderWidth(hMat);
h = re.GetShaderHeight(hMat);
re.DrawStretchPic(
m_frame.size.width * frac - w * 0.5,
m_frame.size.height * 0.5 - h * 0.5,
w,
h,
0,
0,
1,
1,
hMat
);
}
break;
}
case L_STATBAR_VERTICAL_REVERSE:
{
float height = m_frame.size.height * frac;
re.DrawStretchPic(
0.0, 0.0, m_frame.size.width, height, 0.0, 0.0, 1.0, frac, m_statbar_material->GetMaterial()
);
if (alpha != 0.0 && m_statbar_material_flash) {
re.SetColor(col);
re.DrawStretchPic(
0.0,
0.0,
m_frame.size.width,
height,
0.0,
0.0,
1.0,
frac,
m_statbar_material_flash->GetMaterial()
);
}
break;
}
default:
break;
}
}
} else {
switch (m_statbar_or) {
case L_STATBAR_VERTICAL:
case L_STATBAR_VERTICAL_STAGGER_EVEN:
case L_STATBAR_VERTICAL_STAGGER_ODD:
DrawBox(
0.0,
m_frame.size.height * (1.0 - frac),
m_frame.size.width,
m_frame.size.height,
m_foreground_color,
1.0
);
break;
case L_STATBAR_HORIZONTAL:
DrawBox(0.0, 0.0, frac * m_frame.size.width, m_frame.size.height, m_foreground_color, 1.0);
break;
default:
break;
}
}
}
void UIFakkLabel::DrawStatCircle(float frac)
{
vec4_t col;
float alpha;
float fCurrAng, fEndAng, fNextAng;
vec2_t vVerts[3];
vec2_t vTexCoords[3];
col[0] = 1.f;
col[1] = 1.f;
col[2] = 1.f;
col[3] = 1.f;
if (m_lastfrac != frac) {
m_flashtime = uid.time;
}
m_lastfrac = frac;
alpha = 1.f - (uid.time - m_flashtime) / 1500.f;
if (alpha < 0.f) {
alpha = 0.f;
} else if (alpha > 1.f) {
alpha = 1.f;
}
col[3] = alpha;
vVerts[0][0] = m_frame.size.width * 0.5f;
vVerts[0][1] = m_frame.size.height * 0.5f;
vTexCoords[0][0] = 0.5f;
vTexCoords[0][1] = 0.5f;
if (ui_health_start->value && ui_health_end->value) {
m_angles[0] = ui_health_start->value;
m_angles[1] = ui_health_end->value;
}
fCurrAng = m_angles[0];
fEndAng = frac * (m_angles[1] - fCurrAng) + fCurrAng;
if (m_angles[1] > fCurrAng) {
StatCircleTexCoord(fCurrAng, vTexCoords[1]);
vVerts[1][0] = m_frame.size.width * vTexCoords[1][0];
vVerts[1][1] = m_frame.size.height * vTexCoords[1][1];
if ((int)fCurrAng - (((int)fCurrAng - 45) % 90 + 90) % 90
== (int)fEndAng - (((int)fEndAng - 45) % 90 + 90) % 90) {
StatCircleTexCoord(fEndAng, vTexCoords[2]);
vVerts[2][0] = m_frame.size.width * vTexCoords[2][0];
vVerts[2][1] = m_frame.size.height * vTexCoords[2][1];
if (alpha && m_statbar_material_flash) {
re.SetColor(m_foreground_color);
}
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha && m_statbar_material_flash) {
re.SetColor(col);
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
} else {
while (fCurrAng > fEndAng) {
fNextAng = ((int)fCurrAng - (((int)fCurrAng - 45) % 90 + 90) % 90) + 90.0;
if (fNextAng > fEndAng) {
fNextAng = fEndAng;
}
StatCircleTexCoord(fNextAng, vTexCoords[2]);
vVerts[2][0] = m_frame.size.width * vTexCoords[2][0];
vVerts[2][1] = m_frame.size.height * vTexCoords[2][1];
if (alpha && m_statbar_material_flash) {
re.SetColor(m_foreground_color);
}
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha && m_statbar_material_flash) {
re.SetColor(col);
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
vTexCoords[1][0] = vTexCoords[2][0];
vTexCoords[1][1] = vTexCoords[2][1];
vVerts[1][0] = vVerts[2][0];
vVerts[1][1] = vVerts[2][1];
fCurrAng = fNextAng;
}
}
} else {
StatCircleTexCoord(fCurrAng, vTexCoords[2]);
vVerts[2][0] = m_frame.size.width * vTexCoords[2][0];
vVerts[2][1] = m_frame.size.height * vTexCoords[2][1];
if ((int)fCurrAng - (((int)fCurrAng - 45) % 90 + 90) % 90
== (int)fEndAng - (((int)fEndAng - 45) % 90 + 90) % 90) {
StatCircleTexCoord(fEndAng, vTexCoords[1]);
vVerts[1][0] = m_frame.size.width * vTexCoords[1][0];
vVerts[1][1] = m_frame.size.height * vTexCoords[1][1];
if (alpha && m_statbar_material_flash) {
re.SetColor(m_foreground_color);
}
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha && m_statbar_material_flash) {
re.SetColor(col);
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
} else {
while (fCurrAng > fEndAng) {
fNextAng = ((int)fCurrAng - (((int)fCurrAng + 45) % 90 + 90) % 90);
if (fNextAng == fCurrAng) {
fNextAng -= 90.f;
}
if (fNextAng < fEndAng) {
fNextAng = fEndAng;
}
StatCircleTexCoord(fNextAng, vTexCoords[1]);
vVerts[1][0] = m_frame.size.width * vTexCoords[1][0];
vVerts[1][1] = m_frame.size.height * vTexCoords[1][1];
if (alpha && m_statbar_material_flash) {
re.SetColor(m_foreground_color);
}
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha && m_statbar_material_flash) {
re.SetColor(col);
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
vTexCoords[2][0] = vTexCoords[1][0];
vTexCoords[2][1] = vTexCoords[1][1];
vVerts[2][0] = vVerts[1][0];
vVerts[2][1] = vVerts[1][1];
fCurrAng = fNextAng;
}
}
}
}
void UIFakkLabel::DrawStatNeedle(float frac)
{
vec4_t col;
float alpha;
float fTargAng;
float fSinVal;
float fCosVal;
vec2_t vCenter;
vec2_t vVerts[3];
vec2_t vTexCoords[3];
vec2_t vNeedleDir;
vec2_t vSideDir;
col[0] = 1.f;
col[1] = 1.f;
col[2] = 1.f;
col[3] = 1.f;
if (m_lastfrac != frac) {
m_flashtime = uid.time;
}
m_lastfrac = frac;
alpha = 1.f - (uid.time - m_flashtime) / 1500.f;
if (alpha < 0.f) {
alpha = 0.f;
} else if (alpha > 1.f) {
alpha = 1.f;
}
col[3] = alpha;
fTargAng = DEG2RAD(frac * (m_angles[1] - m_angles[0]) + m_angles[0]);
fSinVal = sin(fTargAng);
fCosVal = cos(fTargAng);
vSideDir[0] = m_frame.size.width * 0.5f;
vSideDir[1] = m_frame.size.height * 0.5f;
vCenter[0] = m_frame.size.width + fSinVal * vSideDir[0];
vCenter[1] = m_frame.size.height + -fCosVal * vSideDir[1];
vNeedleDir[0] = m_angles[2] * fCosVal;
vNeedleDir[1] = m_angles[2] * fSinVal;
vVerts[0][0] = vCenter[0] - vNeedleDir[0];
vVerts[0][1] = vCenter[1] - vNeedleDir[1];
vVerts[1][0] = vCenter[0] + vNeedleDir[0];
vVerts[1][1] = vCenter[1] + vNeedleDir[1];
vVerts[2][0] = vSideDir[0] - vNeedleDir[1] - vNeedleDir[0];
vVerts[2][1] = vSideDir[1] + vNeedleDir[0] - vNeedleDir[1];
vTexCoords[0][0] = 0.f;
vTexCoords[0][1] = 0.f;
vTexCoords[1][0] = 1.f;
vTexCoords[1][1] = 0.f;
vTexCoords[2][0] = 0.f;
vTexCoords[2][1] = 1.f;
if (alpha != 0.f) {
re.SetColor(m_foreground_color);
}
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
re.SetColor(col);
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
vVerts[0][0] = vVerts[2][0];
vVerts[0][1] = vVerts[2][1];
vVerts[2][0] = m_angles[2] * vCenter[0] + m_frame.size.width * 0.5f - m_angles[2] * vCenter[1];
vVerts[2][1] = m_angles[2] * vCenter[1] + m_frame.size.height * 0.5f - m_angles[2] * -vCenter[0];
vTexCoords[0][0] = vTexCoords[2][0];
vTexCoords[0][1] = vTexCoords[2][1];
if (alpha != 0.f && m_statbar_material_flash) {
re.SetColor(m_foreground_color);
}
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
}
void UIFakkLabel::DrawStatRotator(float frac)
{
vec4_t col;
float alpha;
float fTargAng;
float fSinVal, fCosVal;
vec2_t vCenter;
vec2_t vVerts[3];
vec2_t vTexCoords[3];
vec2_t vNeedleDir;
vec2_t vSize;
col[0] = 1.f;
col[1] = 1.f;
col[2] = 1.f;
col[3] = 1.f;
if (m_lastfrac != frac) {
m_flashtime = uid.time;
}
m_lastfrac = frac;
alpha = 1.f - (uid.time - m_flashtime) / 1500.f;
if (alpha < 0.f) {
alpha = 0.f;
} else if (alpha > 1.f) {
alpha = 1.f;
}
col[3] = alpha;
fTargAng = DEG2RAD(frac * (m_angles[1] - m_angles[0]) + m_angles[0]);
fSinVal = sin(fTargAng);
fCosVal = cos(fTargAng);
vNeedleDir[0] = fSinVal;
vNeedleDir[1] = -fCosVal;
vSize[0] = (m_frame.size.width + m_frame.size.height) / m_frame.size.width * m_angles[2] * getVirtualScale()[0];
vSize[1] = (m_frame.size.width + m_frame.size.height) / m_frame.size.height * m_scale * getVirtualScale()[1];
vCenter[0] = (m_frame.size.width * 0.5f - vSize[0]) * vNeedleDir[0] + m_frame.size.width * 0.5f;
vCenter[1] = (m_frame.size.height * 0.5f - vSize[1]) * vNeedleDir[1] + m_frame.size.height * 0.5f;
vVerts[0][0] = vCenter[0] - vSize[0];
vVerts[0][1] = vCenter[1] - vSize[1];
vVerts[1][0] = vCenter[0] + vSize[0];
vVerts[1][1] = vCenter[1] - vSize[1];
vVerts[2][0] = vCenter[0] - vSize[0];
vVerts[2][1] = vCenter[1] + vSize[1];
vTexCoords[0][0] = 0.f;
vTexCoords[0][1] = 0.f;
vTexCoords[1][0] = 1.f;
vTexCoords[1][1] = 0.f;
vTexCoords[2][0] = 0.f;
vTexCoords[2][1] = 1.f;
if (alpha != 0.f && m_statbar_material_flash) {
re.SetColor(m_foreground_color);
}
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
vVerts[0][0] = vVerts[2][0];
vVerts[0][1] = vVerts[2][1];
vVerts[2][0] = vCenter[0] + vSize[0];
vVerts[2][1] = vCenter[1] + vSize[1];
vTexCoords[0][0] = vTexCoords[2][0];
vTexCoords[0][1] = vTexCoords[2][1];
vTexCoords[2][0] = 1.f;
vTexCoords[2][1] = 1.f;
if (alpha != 0.f && m_statbar_material_flash) {
re.SetColor(m_foreground_color);
}
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
}
void UIFakkLabel::DrawStatCompass(float frac)
{
vec4_t col;
float fTargAng;
float fSinVal, fCosVal;
vec2_t vCenter;
vec2_t vVerts[3];
vec2_t vTexCoords[3];
vec2_t vCompassDir;
vec2_t vSideDir;
col[0] = col[1] = col[2] = col[3] = 1.0;
if (!cge) {
return;
}
static int iLastCompassTime = -9999, iLastTimeDelta = 0;
static float fLastPitch = 0, fLastYaw = 0, fLastYawDelta = 0;
static float fYawOffset = 0, fYawSpeed = 0;
static float fNeedleOffset = 0, fNeedleSpeed = 0;
int iTimeCount, iTimeDelta;
float fYawDelta, fYawDeltaDiff;
vec3_t vViewAngles;
cge->CG_EyeAngles(&vViewAngles);
vViewAngles[1] -= cl.snap.ps.stats[STAT_COMPASSNORTH] / 182.0f;
iTimeCount = uid.time - iLastCompassTime;
if (iTimeCount <= 1000) {
fYawDelta = AngleSubtract(vViewAngles[1], fLastYaw);
if (fYawDelta > 0.1) {
if ((fYawDelta > 0.0 && fLastYawDelta < fYawDelta) || (fYawDelta < 0.0 && fLastYawDelta > fYawDelta)) {
fYawSpeed += (fYawDelta - fLastYawDelta) * 0.75;
fYawOffset += (fYawDelta - fLastYawDelta) * 0.75;
}
if (fYawSpeed > 90.0) {
fYawSpeed = 90.0;
} else if (fYawSpeed < 0.05) {
fYawSpeed = 0.05;
}
}
while (iTimeCount > 0) {
iTimeDelta = iTimeCount;
if (iTimeCount > 15) {
iTimeDelta = 15;
}
iTimeCount -= iTimeDelta;
if (fabs(fYawOffset) >= 0.1 || fabs(fYawSpeed) >= 0.01) {
fYawOffset += fYawSpeed * iTimeDelta;
if (fYawOffset > 0.0) {
fYawSpeed -= iTimeDelta * 0.00175;
} else if (fYawOffset < 0.0) {
fYawSpeed += iTimeDelta * 0.00175;
}
if (fYawOffset > 40.0) {
fYawOffset = 40.0;
fYawSpeed = 0.0;
} else if (fYawOffset < -40.0) {
fYawOffset = -40.0;
fYawSpeed = 0.0;
}
fYawSpeed -= iTimeDelta * 0.003;
if (fYawSpeed > 0.0) {
fYawSpeed -= iTimeDelta * 0.0004;
} else {
fYawSpeed += iTimeDelta * 0.0004;
if (fYawSpeed > 0.0) {
fYawSpeed = 0.0;
}
}
} else {
iTimeCount = 0;
fYawOffset = 0.0;
fYawSpeed = 0.0;
}
}
fLastYawDelta = fYawDelta;
iLastTimeDelta = uid.time - iLastCompassTime;
} else {
fLastYawDelta = 0;
fYawOffset = 0;
fYawSpeed = 0;
iLastTimeDelta = 0;
}
fLastPitch = vViewAngles[0];
fLastYaw = vViewAngles[1];
iLastCompassTime = uid.time;
if (iLastTimeDelta) {
if (fabs(fLastYawDelta) > 0.1) {
fNeedleOffset -= fLastYawDelta;
}
iTimeCount = iLastTimeDelta;
while (iTimeCount > 0) {
iTimeDelta = iTimeCount;
if (iTimeCount > 15) {
iTimeDelta = 15;
}
iTimeCount -= iTimeDelta;
if (fabs(fNeedleOffset) >= 0.1 || fabs(fNeedleSpeed) >= 0.01) {
fNeedleOffset += iTimeDelta * fNeedleSpeed;
if (fNeedleOffset > 180.0) {
fNeedleOffset -= 360.0;
} else if (fNeedleOffset < -180.0) {
fNeedleOffset += 360.0;
}
if (fNeedleOffset > 0.0) {
fNeedleSpeed -= iTimeDelta * 0.00175;
} else if (fNeedleOffset < 0.0) {
fNeedleSpeed += iTimeDelta * 0.00175;
}
fNeedleSpeed -= fNeedleSpeed * 0.0025 * iTimeDelta;
if (fNeedleSpeed > 0.0) {
fNeedleSpeed -= iTimeDelta * 0.00035;
if (fNeedleSpeed < 0.0) {
fNeedleSpeed = 0.0;
}
} else {
fNeedleSpeed += iTimeDelta * 0.00035;
if (fNeedleSpeed > 0.0) {
fNeedleSpeed = 0.0;
}
}
} else {
iTimeCount = 0;
fNeedleOffset = 0.0;
fNeedleSpeed = 0.0;
}
}
} else {
fNeedleOffset = 0.0;
fNeedleSpeed = 0.0;
}
fSinVal = sin(anglemod(fNeedleOffset + fLastYaw) / (180 / M_PI));
fCosVal = cos(anglemod(fNeedleOffset + fLastYaw) / (180 / M_PI));
vCompassDir[0] = fSinVal;
vCompassDir[1] = -fCosVal;
vCenter[0] = m_frame.size.width * 0.5;
vCenter[1] = m_frame.size.height * 0.5;
vTexCoords[0][0] = 0.0;
vTexCoords[0][1] = 0.0;
vTexCoords[1][0] = 1.0;
vTexCoords[1][1] = 0.0;
vTexCoords[2][0] = 0.0;
vTexCoords[2][1] = 1.0;
vVerts[0][0] = vCenter[0] + vCompassDir[0] * vCenter[0] - fCosVal * vCenter[1];
vVerts[1][0] = vCenter[0] + vCompassDir[0] * vCenter[0] + fCosVal * vCenter[1];
vVerts[2][0] = vCenter[0] - vCompassDir[0] * vCenter[0] - fCosVal * vCenter[1];
vVerts[0][1] = vCenter[1] + vCompassDir[1] * vCenter[1] - fSinVal * vCenter[0];
vVerts[1][1] = vCenter[1] + vCompassDir[1] * vCenter[1] + fSinVal * vCenter[0];
vVerts[2][1] = vCenter[1] - vCompassDir[1] * vCenter[1] - fSinVal * vCenter[0];
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
vVerts[0][0] = vVerts[2][0];
vVerts[0][1] = vVerts[2][1];
vTexCoords[0][0] = vTexCoords[2][0];
vTexCoords[0][1] = vTexCoords[2][1];
vTexCoords[2][0] = 1.0;
vTexCoords[2][1] = 1.0;
vVerts[2][0] = vCenter[0] + fCosVal * vCenter[1] - vCompassDir[0] * vCenter[0];
vVerts[2][1] = vCenter[1] * fSinVal + vCenter[0] - vCompassDir[1] * vCenter[1];
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
}
void UIFakkLabel::DrawStatSpinner(float frac)
{
vec4_t col;
float alpha;
float fTargAng;
float fSinVal, fCosVal;
vec2_t vCenter;
vec2_t vVerts[3];
vec2_t vTexCoords[3];
vec2_t vCompassDir;
vec2_t vSideDir;
col[0] = 1.f;
col[1] = 1.f;
col[2] = 1.f;
col[3] = 1.f;
if (m_lastfrac != frac) {
m_flashtime = uid.time;
}
m_lastfrac = frac;
alpha = 1.f - (uid.time - m_flashtime) / 1500.f;
if (alpha < 0.f) {
alpha = 0.f;
} else if (alpha > 1.f) {
alpha = 1.f;
}
col[3] = alpha;
if (m_statbar_or == L_STATBAR_HEADING_SPINNER) {
if (cge) {
vec3_t vViewAngles;
float fAngAlpha;
cge->CG_EyeAngles(&vViewAngles);
frac = (AngleSubtract(vViewAngles[1], frac * 360.f + 180.f) + 180.f) / 360.f;
if (frac < 0.f || frac > 1.f) {
frac = 0.f;
}
}
}
fTargAng = DEG2RAD(frac * (m_angles[1] - m_angles[0]) + m_angles[0]);
fSinVal = sin(fTargAng);
fCosVal = cos(fTargAng);
vSideDir[0] = fCosVal;
vSideDir[1] = fSinVal;
vCompassDir[0] = fSinVal;
vCompassDir[1] = -fCosVal;
vCenter[0] = m_frame.size.width * 0.5f;
vCenter[1] = m_frame.size.height * 0.5f;
vVerts[0][0] = (fSinVal * vCenter[0] + vCenter[0]) - (fCosVal * vCenter[1]);
vVerts[0][1] = (vCompassDir[1] * vCenter[1] + vCenter[1]) - (vSideDir[1] * vCenter[0]);
vVerts[1][0] = (fSinVal * vCenter[0] + vCenter[0]) + (fCosVal * vCenter[1]);
vVerts[1][1] = (vSideDir[1] * vCenter[0]) + (vCompassDir[1] * vCenter[1] + vCenter[1]);
vVerts[2][0] = vCenter[0] - fSinVal * vCenter[0] - fCosVal * vCenter[1];
vVerts[2][1] = vCenter[1] - vCompassDir[1] * vCenter[1] - vSideDir[1] * vCenter[0];
vTexCoords[0][0] = 0.f;
vTexCoords[0][1] = 0.f;
vTexCoords[1][0] = 1.f;
vTexCoords[1][1] = 0.f;
vTexCoords[2][0] = 0.f;
vTexCoords[2][1] = 1.f;
if (alpha != 0.f && m_statbar_material_flash) {
re.SetColor(m_foreground_color);
}
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
vVerts[0][0] = vVerts[2][0];
vVerts[0][1] = vVerts[2][1];
vVerts[2][0] = vCenter[1] * fCosVal + vCenter[0] - vCompassDir[0] * vCenter[0];
vVerts[2][1] = vCenter[0] * vSideDir[1] + vCenter[1] - vCompassDir[1] * vCenter[1];
vTexCoords[0][0] = vTexCoords[2][0];
vTexCoords[0][1] = vTexCoords[2][1];
vTexCoords[2][0] = 1.f;
vTexCoords[2][1] = 1.f;
if (alpha != 0.f && m_statbar_material_flash) {
re.SetColor(m_foreground_color);
}
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material->GetMaterial());
if (alpha != 0.f && m_statbar_material_flash) {
re.DrawTrianglePic(vVerts, vTexCoords, m_statbar_material_flash->GetMaterial());
}
}
void UIFakkLabel::StatCircleTexCoord(float fAng, vec3_t vTexCoord)
{
int iSector;
float fSinVal, fCosVal;
iSector = (AngleMod(fAng) + 45.f) / 90;
fSinVal = sin(DEG2RAD(fAng));
fCosVal = cos(DEG2RAD(fAng));
if (iSector >= 0) {
if (iSector == 0) {
vTexCoord[0] = 0.f;
vTexCoord[1] = 0.5f / fCosVal * fSinVal + 0.5f;
} else if (iSector == 1) {
vTexCoord[0] = 1.f;
vTexCoord[1] = -0.5f / fSinVal * fCosVal + 0.5f;
} else if (iSector == 2) {
vTexCoord[0] = fSinVal * (-0.5f * fCosVal) + 0.5f;
vTexCoord[1] = 1.f;
} else if (iSector == 4) {
vTexCoord[0] = 0.5f / fCosVal * fSinVal + 0.5f;
vTexCoord[1] = 0.f;
} else {
vTexCoord[0] = 0.f;
vTexCoord[1] = 0.5f / fSinVal * fCosVal + 0.5f;
}
} else {
vTexCoord[0] = 0.f;
vTexCoord[1] = 0.5f / fSinVal * fCosVal + 0.5f;
}
}
void UIFakkLabel::Draw(void)
{
if (m_stat_alpha != -1) {
float frac;
frac = (cl.snap.ps.stats[m_stat_alpha] + 1) / 100.0;
frac = Q_clamp_float(frac, 0, 1);
m_alpha = frac;
}
if (m_stat == -1 && m_itemindex == -1 && m_inventoryrendermodelindex == -1 && m_stat_configstring == -1
&& !m_rendermodel && m_statbar_or == L_STATBAR_NONE) {
if (!m_sDrawModelName.length()) {
UILabel::Draw();
return;
}
}
if (m_stat_configstring != -1) {
m_font->setColor(m_foreground_color);
if (m_bOutlinedText) {
m_font->PrintOutlinedJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(cl.snap.ps.stats[m_stat_configstring]))),
UBlack,
getVirtualScale()
);
} else {
m_font->PrintJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(cl.snap.ps.stats[m_stat_configstring]))),
getVirtualScale()
);
}
return;
}
if (m_stat != -1) {
int delta = cl.snap.ps.stats[m_stat];
if (m_statbar_or == L_STATBAR_NONE) {
m_font->setColor(m_foreground_color);
if (m_bOutlinedText) {
m_font->PrintOutlinedJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
va("%d", delta),
UBlack,
getVirtualScale()
);
} else {
m_font->PrintJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
va("%d", delta),
getVirtualScale()
);
}
return;
}
if (m_statbar_or == L_STATBAR_VERTICAL_STAGGER_EVEN || m_statbar_or == L_STATBAR_VERTICAL_STAGGER_ODD) {
int stat;
if (m_maxstat < 0) {
stat = m_statbar_max;
} else {
stat = cl.snap.ps.stats[m_maxstat];
}
delta = stat - cl.snap.ps.stats[m_stat];
if (delta & 1) {
if (m_statbar_or == L_STATBAR_VERTICAL_STAGGER_EVEN) {
delta--;
} else {
delta++;
}
}
delta = stat - delta;
if (m_maxstat >= 0 || m_statbar_min <= delta) {
if (delta < 0) {
delta = 0;
}
} else {
delta = m_statbar_min;
}
}
float frac;
if (m_maxstat >= 0) {
frac = (float)delta / (float)cl.snap.ps.stats[m_maxstat];
} else {
frac = (float)delta / (float)(m_statbar_max - m_statbar_min);
}
if (frac > 1.0) {
frac = 1.0;
} else if (frac < 0.0) {
frac = 0.0;
}
DrawStatbar(frac);
return;
}
float scale;
qhandle_t handle;
vec3_t origin;
vec3_t mins;
vec3_t maxs;
vec3_t angles;
vec3_t offset;
vec3_t rotateoffset;
vec4_t color;
str sAnimName;
float height;
if (m_itemindex != -1) {
if (m_itemindex < 0) {
return;
}
if (cl.snap.ps.activeItems[m_itemindex] < 0 || cl.snap.ps.activeItems[m_itemindex] >= MAX_WEAPONS) {
// Fixed in OPM
// Make sure to not overflow configstrings
return;
}
m_font->setColor(m_foreground_color);
if (m_bOutlinedText) {
m_font->PrintOutlinedJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
UBlack,
getVirtualScale()
);
} else {
m_font->PrintJustified(
getClientFrame(),
m_iFontAlignmentHorizontal,
m_iFontAlignmentVertical,
Sys_LV_CL_ConvertString(va("%s", CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_itemindex]))),
getVirtualScale()
);
}
return;
}
if (m_inventoryrendermodelindex == -1 && !m_sDrawModelName.length() && !m_rendermodel) {
float frac = 0.0;
if (m_statbar_or == L_STATBAR_NONE) {
return;
}
if (m_cvarname.length()) {
frac = Cvar_VariableValue(m_cvarname) / (m_statbar_max - m_statbar_min);
}
if (frac > 1.0) {
frac = 1.0;
}
if (frac < 0.0) {
frac = 0.0;
}
DrawStatbar(frac);
return;
}
VectorSet4(color, 255, 255, 255, 255);
if (m_rendermodel) {
if (!m_cvarname.length()) {
return;
}
handle = re.RegisterModel(Cvar_VariableString(m_cvarname));
if (!handle) {
return;
}
VectorCopy(m_angles, angles);
VectorCopy(m_rotateoffset, rotateoffset);
VectorCopy(m_offset, offset);
scale = m_scale;
sAnimName = m_anim;
// Added in 2.11
// Tunak easter egg
if (Cvar_Get("tunak", "0", 0)->integer) {
// Since 2.15, those animations start has 'zz' prefix
if (strstr(m_anim, "american")) {
sAnimName = "zzamericanspecialidle";
} else {
// Added in 2.15
sAnimName = "zzgermanspecialidle";
}
}
} else {
if (m_sDrawModelName.length()) {
if (!m_lastitem) {
m_lastitem = CL_GetInvItemByName(&client_inv, m_sDrawModelName);
}
} else {
if (m_inventoryrendermodelindex >= 0
&& m_lastitemindex != cl.snap.ps.activeItems[m_inventoryrendermodelindex]) {
m_lastitem = CL_GetInvItemByName(
&client_inv, CL_ConfigString(CS_WEAPONS + cl.snap.ps.activeItems[m_inventoryrendermodelindex])
);
m_lastitemindex = cl.snap.ps.activeItems[m_inventoryrendermodelindex];
}
}
if (!m_lastitem) {
return;
}
VectorCopy(m_lastitem->hudprops.rotateoffset, rotateoffset);
VectorCopy(m_lastitem->hudprops.offset, offset);
scale = m_lastitem->hudprops.scale;
handle = re.RegisterModel(m_lastitem->hudprops.model);
VectorCopy(m_lastitem->hudprops.angledeltas, angles);
if (m_lastitem->hudprops.move == INV_MOVE_BOB) {
float frac = uid.time / 600.0;
angles[0] += sin(frac) * m_lastitem->hudprops.angledeltas[0];
angles[1] += sin(frac) * m_lastitem->hudprops.angledeltas[1];
angles[2] += sin(frac) * m_lastitem->hudprops.angledeltas[2];
} else if (m_lastitem->hudprops.model == INV_MOVE_SPIN) {
float frac = uid.time / 600.0;
angles[0] += frac * m_lastitem->hudprops.angledeltas[0];
angles[1] += frac * m_lastitem->hudprops.angledeltas[1];
angles[2] += frac * m_lastitem->hudprops.angledeltas[2];
}
}
if (m_rendermodel) {
VectorSet(mins, -16, -16, 0);
VectorSet(maxs, 16, 16, 96);
} else {
re.ModelBounds(handle, mins, maxs);
}
origin[1] = (mins[1] + maxs[1]) * 0.5;
origin[2] = (mins[2] + maxs[2]) * -0.5;
height = maxs[2] - mins[2];
if (height < maxs[1] - mins[1]) {
height = maxs[1] - mins[1];
}
if (height < maxs[0] - mins[0]) {
height = maxs[0] - mins[0];
}
origin[0] = height * scale * 0.5 / 0.268f;
CL_Draw3DModel(
m_screenframe.pos.x,
m_screenframe.pos.y,
m_screenframe.size.width,
m_screenframe.size.height,
handle,
origin,
rotateoffset,
offset,
angles,
color,
sAnimName
);
set2D();
}