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_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"
+
// hud panel aliases
alias quickmenu "cl_cmd hud quickmenu ${* ?}"
//return true;
if(HUD_Radar_Clickable())
return true;
- if(HUD_MinigameMenu_IsOpened() || active_minigame)
+ if(HUD_MinigameMenu_IsOpened())
return true;
if(QuickMenu_IsOpened())
return true;
bool autocvar_hud_panel_scoreboard_accuracy = true;
bool autocvar_hud_panel_scoreboard_accuracy_doublerows = false;
bool autocvar_hud_panel_scoreboard_accuracy_nocolors = false;
+float autocvar_hud_panel_scoreboard_accuracy_showdelay = 2;
+float autocvar_hud_panel_scoreboard_accuracy_showdelay_minpos = 0.75;
+
bool autocvar_hud_panel_scoreboard_ctf_leaderboard = true;
bool autocvar_hud_panel_scoreboard_dynamichud = false;
field_pos.x += fieldpadding + (max(fieldsize, min_fieldsize) - fieldsize) * 0.5;
drawstring(field_pos, field, hud_fontsize, sbt_field_rgb, sbt_fg_alpha, DRAWFLAG_NORMAL);
}
+ if(pl.eliminated)
+ {
+ h_size.x = column_width + hud_fontsize.x * 0.25;
+ h_size.y = hud_fontsize.y;
+ drawfill(pos - hud_fontsize.x * 0.25 * eX, h_size, '0 0 0', 0.5 * panel_fg_alpha, DRAWFLAG_NORMAL);
+ }
pos.x += column_width;
pos.x += hud_fontsize.x;
}
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;
+
WepSet weapons_stat = WepSet_GetFromStat();
WepSet weapons_inmap = WepSet_GetFromStat_InMap();
int disownedcnt = 0;
float weapon_height = 29;
float height = hud_fontsize.y + weapon_height;
- drawstring(pos + eX * panel_bg_padding, sprintf(_("Accuracy stats (average %d%%)"), average_accuracy), hud_fontsize, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring(pos + eX * panel_bg_padding, sprintf(_("Accuracy stats (average %d%%)"), average_accuracy), hud_fontsize, '1 1 1', panel_fg_alpha * scoreboard_acc_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_acc_fade_alpha;
HUD_Panel_DrawBg();
+ panel_bg_alpha = panel_bg_alpha_save;
vector end_pos = panel_pos + eY * (panel_size.y + hud_fontsize.y);
if(panel.current_panel_bg != "0")
float weapon_width = tmp.x / columnns / rows;
if (sbt_bg_alpha)
- drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, sbt_bg_alpha, DRAWFLAG_NORMAL);
+ drawpic_tiled(pos, "gfx/scoreboard/scoreboard_bg", bg_size, tmp, rgb, sbt_bg_alpha * scoreboard_acc_fade_alpha, DRAWFLAG_NORMAL);
if(sbt_highlight)
{
// column highlighting
for (int i = 0; i < columnns; ++i)
if ((i % 2) == 0)
- drawfill(pos + eX * weapon_width * rows * i, vec2(weapon_width * rows, height * rows), '0 0 0', sbt_highlight_alpha, DRAWFLAG_NORMAL);
+ drawfill(pos + eX * weapon_width * rows * i, vec2(weapon_width * rows, height * rows), '0 0 0', sbt_highlight_alpha * scoreboard_acc_fade_alpha, DRAWFLAG_NORMAL);
// row highlighting
for (int i = 0; i < rows; ++i)
- drawfill(pos + eY * (weapon_height + height * i), vec2(tmp.x, hud_fontsize.y), rgb, sbt_highlight_alpha, DRAWFLAG_NORMAL);
+ drawfill(pos + eY * (weapon_height + height * i), vec2(tmp.x, hud_fontsize.y), rgb, sbt_highlight_alpha * scoreboard_acc_fade_alpha, DRAWFLAG_NORMAL);
}
average_accuracy = 0;
weapon_alpha = 0.2 * sbt_fg_alpha;
// weapon icon
- drawpic_aspect_skin(tmpos, it.model2, vec2(weapon_width, weapon_height), '1 1 1', weapon_alpha, DRAWFLAG_NORMAL);
+ drawpic_aspect_skin(tmpos, it.model2, vec2(weapon_width, weapon_height), '1 1 1', weapon_alpha * scoreboard_acc_fade_alpha, DRAWFLAG_NORMAL);
// the accuracy
if (weapon_stats >= 0) {
weapons_with_stats += 1;
if(!autocvar_hud_panel_scoreboard_accuracy_nocolors)
rgb = Accuracy_GetColor(weapon_stats);
- drawstring(tmpos + vec2(padding, weapon_height), s, hud_fontsize, rgb, sbt_fg_alpha, DRAWFLAG_NORMAL);
+ drawstring(tmpos + vec2(padding, weapon_height), s, hud_fontsize, rgb, sbt_fg_alpha * scoreboard_acc_fade_alpha, DRAWFLAG_NORMAL);
}
tmpos.x += weapon_width * rows;
pos.x += weapon_width * rows;
average_accuracy = floor((average_accuracy * 100 / weapons_with_stats) + 0.5);
panel_size.x += panel_bg_padding * 2; // restore initial width
- return end_pos;
+
+ if (scoreboard_acc_fade_alpha == 1)
+ return end_pos;
+ return initial_pos + (end_pos - initial_pos) * scoreboard_acc_fade_alpha;
}
vector MapStats_DrawKeyValue(vector pos, string key, string value) {
return end_pos;
}
+float scoreboard_time;
+bool have_weapon_stats;
+bool Scoreboard_AccuracyStats_WouldDraw(float ypos)
+{
+ if (gametype == MAPINFO_TYPE_CTS || gametype == MAPINFO_TYPE_RACE || gametype == MAPINFO_TYPE_NEXBALL)
+ return false;
+ if (!autocvar_hud_panel_scoreboard_accuracy || warmup_stage || ypos > 0.91 * vid_conheight)
+ return false;
+
+ if (time < scoreboard_time + autocvar_hud_panel_scoreboard_accuracy_showdelay
+ && ypos > autocvar_hud_panel_scoreboard_accuracy_showdelay_minpos * vid_conheight
+ && !intermission)
+ {
+ return false;
+ }
+
+ if (!have_weapon_stats)
+ {
+ FOREACH(Weapons, it != WEP_Null, {
+ int weapon_stats = weapon_accuracy[i - WEP_FIRST];
+ if (weapon_stats >= 0)
+ {
+ have_weapon_stats = true;
+ break;
+ }
+ });
+ if (!have_weapon_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)
+ scoreboard_time = time;
if(hud_configure_menu_open == 1)
scoreboard_fade_alpha = 1;
float scoreboard_fadeinspeed = autocvar_hud_panel_scoreboard_fadeinspeed;
}
if (!scoreboard_fade_alpha)
+ {
+ scoreboard_acc_fade_alpha = 0;
return;
+ }
}
else
scoreboard_fade_alpha = 0;
pos = Scoreboard_MakeTable(pos, tm, panel_bg_color, bg_size);
}
- bool show_accuracy = (gametype != MAPINFO_TYPE_CTS && gametype != MAPINFO_TYPE_RACE && gametype != MAPINFO_TYPE_NEXBALL);
-
- if (show_accuracy && autocvar_hud_panel_scoreboard_accuracy && !warmup_stage)
+ if (Scoreboard_AccuracyStats_WouldDraw(pos.y))
pos = Scoreboard_AccuracyStats_Draw(pos, panel_bg_color, bg_size);
if(gametype == MAPINFO_TYPE_CTS || gametype == MAPINFO_TYPE_RACE || (autocvar_hud_panel_scoreboard_ctf_leaderboard && gametype == MAPINFO_TYPE_CTF && STAT(CTF_SHOWLEADERBOARD))) {
bool scoreboard_active;
float scoreboard_fade_alpha;
+float scoreboard_acc_fade_alpha;
void Cmd_Scoreboard_SetFields(int argc);
void Scoreboard_Draw();
// this function must match W_SetupShot!
float zoomscript_caught;
+bool minigame_wasactive;
+
vector wcross_origin;
float wcross_scale_prev, wcross_alpha_prev;
vector wcross_color_prev;
HUD_Panel_Mouse();
else
{
- if (HUD_MinigameMenu_IsOpened() || active_minigame)
+ if (HUD_MinigameMenu_IsOpened())
HUD_Minigame_Mouse();
if (QuickMenu_IsOpened())
QuickMenu_Mouse();
}
}
+ if(active_minigame && HUD_MinigameMenu_IsOpened())
+ {
+ if(!minigame_wasactive)
+ {
+ localcmd("+button14\n");
+ minigame_wasactive = true;
+ }
+ }
+ else if(minigame_wasactive)
+ {
+ localcmd("-button14\n");
+ minigame_wasactive = false;
+ }
+
ColorTranslateMode = autocvar_cl_stripcolorcodes;
for(int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
this.active = ACTIVE_ACTIVE;
+ this.draggable = drag_undraggable;
+
// damage when blocked
setblocked(this, generic_plat_blocked);
if(this.dmg && (this.message == ""))
precache_sound(this.noise);
this.active = ACTIVE_ACTIVE;
+ this.draggable = drag_undraggable;
this.pos1 = this.origin;
this.pos2 = this.pos1 + this.movedir*(fabs(this.movedir*this.size) - this.lip);
this.angles = '0 0 0';
this.classname = "plat";
+ this.draggable = drag_undraggable;
if (!InitMovingBrushTrigger(this))
return;
this.effects |= EF_LOWPRECISION;
bool _Movetype_TestEntityPosition(vector ofs) // SV_TestEntityPosition
{
entity this = _Movetype_TestEntityPosition_ent;
-// vector org = this.origin + ofs;
+ vector org = this.origin + ofs;
int cont = this.dphitcontentsmask;
this.dphitcontentsmask = DPCONTENTS_SOLID;
- tracebox(this.origin, this.mins, this.maxs, this.origin, ((this.move_movetype == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), this);
+ tracebox(org, this.mins, this.maxs, org, ((this.move_movetype == MOVETYPE_FLY_WORLDONLY) ? MOVE_WORLDONLY : MOVE_NOMONSTERS), this);
this.dphitcontentsmask = cont;
if(trace_startsolid)
return false;
}
-bool _Movetype_UnstickEntity(entity this) // SV_UnstickEntity
+int _Movetype_UnstickEntity(entity this) // SV_UnstickEntity
{
_Movetype_TestEntityPosition_ent = this;
if (!_Movetype_TestEntityPosition(' 0 0 0')) {
- return true;
+ return UNSTICK_FINE;
}
#define X(v) if (_Movetype_TestEntityPosition(v))
X('-1 0 0') X(' 1 0 0')
{
LOG_DEBUGF("Can't unstick an entity (edict: %d, classname: %s, origin: %s)",
etof(this), this.classname, vtos(this.origin));
- return false;
+ return UNSTICK_STUCK;
}
}
LOG_DEBUGF("Sucessfully unstuck an entity (edict: %d, classname: %s, origin: %s)",
etof(this), this.classname, vtos(this.origin));
_Movetype_LinkEdict(this, true);
- return true;
+ return UNSTICK_FIXED;
+}
+
+void _Movetype_CheckStuck(entity this) // SV_CheckStuck
+{
+ int unstick = _Movetype_UnstickEntity(this); // sets test position entity
+ switch(unstick)
+ {
+ case UNSTICK_FINE:
+ this.oldorigin = this.origin;
+ break;
+ case UNSTICK_FIXED:
+ break; // already sorted
+ case UNSTICK_STUCK:
+ vector offset = this.oldorigin - this.origin;
+ if(!_Movetype_TestEntityPosition(offset))
+ _Movetype_LinkEdict(this, false);
+ // couldn't unstick, should we warn about this?
+ break;
+ }
}
vector _Movetype_ClipVelocity(vector vel, vector norm, float f) // SV_ClipVelocity
.float move_suspendedinair;
.float move_didgravity;
+// unsticking
+const int UNSTICK_FINE = 0;
+const int UNSTICK_FIXED = 1;
+const int UNSTICK_STUCK = 2;
+
void _Movetype_WallFriction(entity this, vector stepnormal);
int _Movetype_FlyMove(entity this, float dt, bool applygravity, vector stepnormal, float stepheight);
void _Movetype_CheckVelocity(entity this);
void _Movetype_CheckWaterTransition(entity ent);
+void _Movetype_CheckStuck(entity this);
float _Movetype_CheckWater(entity ent);
void _Movetype_LinkEdict_TouchAreaGrid(entity this);
void _Movetype_LinkEdict(entity this, float touch_triggers);
void _Movetype_LinkEdict(entity this, float touch_triggers);
void _Movetype_LinkEdict_TouchAreaGrid(entity this);
-float _Movetype_UnstickEntity(entity this);
+int _Movetype_UnstickEntity(entity this);
const int MAX_CLIP_PLANES = 5;
const int MOVETYPE_ANGLECLIP = 2;
#endif
+const int MOVETYPE_QCPLAYER = 150; // QC-driven player physics, no think functions!
+
const int FL_ONSLICK = BIT(20);
const int MOVETYPE_FAKEPUSH = 13;
return;
if (GAMEPLAYFIX_UNSTICKPLAYERS(this))
- _Movetype_UnstickEntity(this);
+ _Movetype_CheckStuck(this);
bool applygravity = (!_Movetype_CheckWater(this) && this.move_movetype == MOVETYPE_WALK && !(this.flags & FL_WATERJUMP));
{
// this has been disabled so that you can't jump when you are stepping
// up while already jumping (also known as the Quake2 double jump bug)
+ // LordHavoc: disabled this check so you can walk on monsters/players
+ //if (PRVM_serveredictfloat(ent, solid) == SOLID_BSP)
+ if(GAMEPLAYFIX_STEPDOWN(this) == 2)
+ {
+ SET_ONGROUND(this);
+ this.groundentity = trace_ent;
+ }
}
else
{
// client side physics
bool Physics_Valid(string thecvar)
{
- return autocvar_g_physics_clientselect && thecvar != "" && thecvar && thecvar != "default" && strhasword(autocvar_g_physics_clientselect_options, thecvar);
+ return thecvar != "" && thecvar && thecvar != "default" && strhasword(autocvar_g_physics_clientselect_options, thecvar);
}
float Physics_ClientOption(entity this, string option, float defaultval)
{
+ if(!autocvar_g_physics_clientselect)
+ return defaultval;
+
if(IS_REAL_CLIENT(this) && Physics_Valid(CS(this).cvar_cl_physics))
{
string s = strcat("g_physics_", CS(this).cvar_cl_physics, "_", option);
if(cvar_type(s) & CVAR_TYPEFLAG_EXISTS)
return cvar(s);
}
- if(autocvar_g_physics_clientselect && autocvar_g_physics_clientselect_default && autocvar_g_physics_clientselect_default != "")
+ if(autocvar_g_physics_clientselect_default && autocvar_g_physics_clientselect_default != "" && autocvar_g_physics_clientselect_default != "default")
{
+ // NOTE: not using Physics_Valid here, so the default can be forced to something normally unavailable
string s = strcat("g_physics_", autocvar_g_physics_clientselect_default, "_", option);
if(cvar_type(s) & CVAR_TYPEFLAG_EXISTS)
return cvar(s);
#define PHYS_INPUT_BUTTON_ZOOMSCRIPT(s) PHYS_INPUT_BUTTON_BUTTON9(s)
#define PHYS_INPUT_BUTTON_JETPACK(s) PHYS_INPUT_BUTTON_BUTTON10(s)
#define PHYS_INPUT_BUTTON_DODGE(s) PHYS_INPUT_BUTTON_BUTTON11(s)
+#define PHYS_INPUT_BUTTON_MINIGAME(s) PHYS_INPUT_BUTTON_BUTTON14(s)
#ifdef CSQC
STATIC_INIT(PHYS_INPUT_BUTTON)
#include "item/container.qh"
#include "item/borderimage.qh"
- METHOD(Item, destroy, void(Item this))
+ METHOD(MenuItem, destroy, void(MenuItem this))
{
// free memory associated with this
}
- METHOD(Item, relinquishFocus, void(Item this))
+ METHOD(MenuItem, relinquishFocus, void(MenuItem this))
{
entity par = this.parent;
if (!par) return;
if (par.instanceOfContainer) par.setFocus(par, NULL);
}
- METHOD(Item, resizeNotify, void(Item this, vector relOrigin, vector relSize, vector absOrigin, vector absSize))
+ METHOD(MenuItem, resizeNotify, void(MenuItem this, vector relOrigin, vector relSize, vector absOrigin, vector absSize))
{
this.origin = absOrigin;
this.size = absSize;
}
int autocvar_menu_showboxes;
- METHOD(Item, draw, void(Item this))
+ METHOD(MenuItem, draw, void(MenuItem this))
{
if (!autocvar_menu_showboxes) return;
vector rgb = '1 0 1';
}
}
- METHOD(Item, showNotify, void(Item this))
+ METHOD(MenuItem, showNotify, void(MenuItem this))
{}
- METHOD(Item, hideNotify, void(Item this))
+ METHOD(MenuItem, hideNotify, void(MenuItem this))
{}
- METHOD(Item, keyDown, float(Item this, float scan, float ascii, float shift))
+ METHOD(MenuItem, keyDown, float(MenuItem this, float scan, float ascii, float shift))
{
return 0; // unhandled
}
- METHOD(Item, keyUp, float(Item this, float scan, float ascii, float shift))
+ METHOD(MenuItem, keyUp, float(MenuItem this, float scan, float ascii, float shift))
{
return 0; // unhandled
}
- METHOD(Item, mouseMove, float(Item this, vector pos))
+ METHOD(MenuItem, mouseMove, float(MenuItem this, vector pos))
{
return 0; // unhandled
}
- METHOD(Item, mousePress, bool(Item this, vector pos))
+ METHOD(MenuItem, mousePress, bool(MenuItem this, vector pos))
{
return false; // unhandled
}
- METHOD(Item, mouseDrag, float(Item this, vector pos))
+ METHOD(MenuItem, mouseDrag, float(MenuItem this, vector pos))
{
return 0; // unhandled
}
- METHOD(Item, mouseRelease, float(Item this, vector pos))
+ METHOD(MenuItem, mouseRelease, float(MenuItem this, vector pos))
{
return 0; // unhandled
}
void m_play_focus_sound();
- METHOD(Item, focusEnter, void(Item this))
+ METHOD(MenuItem, focusEnter, void(MenuItem this))
{
if (this.allowFocusSound) m_play_focus_sound();
}
- METHOD(Item, focusLeave, void(Item this))
+ METHOD(MenuItem, focusLeave, void(MenuItem this))
{}
- METHOD(Item, toString, string(Item this))
+ METHOD(MenuItem, toString, string(MenuItem this))
{
return string_null;
}
#include "draw.qh"
#include "menu.qh"
-CLASS(Item, Object)
- METHOD(Item, draw, void(Item));
- METHOD(Item, keyDown, float(Item, float, float, float));
- METHOD(Item, keyUp, float(Item, float, float, float));
- METHOD(Item, mouseMove, float(Item, vector));
- METHOD(Item, mousePress, bool(Item this, vector pos));
- METHOD(Item, mouseDrag, float(Item, vector));
- METHOD(Item, mouseRelease, float(Item, vector));
- METHOD(Item, focusEnter, void(Item));
- METHOD(Item, focusLeave, void(Item));
- METHOD(Item, resizeNotify, void(Item, vector, vector, vector, vector));
- METHOD(Item, relinquishFocus, void(Item));
- METHOD(Item, showNotify, void(Item));
- METHOD(Item, hideNotify, void(Item));
- METHOD(Item, toString, string(Item));
- METHOD(Item, destroy, void(Item));
- ATTRIB(Item, focused, float, 0);
- ATTRIB(Item, focusable, float, 0);
- ATTRIB(Item, allowFocusSound, float, 0);
- ATTRIB(Item, parent, entity);
- ATTRIB(Item, preferredFocusPriority, float, 0);
- ATTRIB(Item, origin, vector, '0 0 0');
- ATTRIB(Item, size, vector, '0 0 0');
- ATTRIB(Item, tooltip, string);
-ENDCLASS(Item)
+CLASS(MenuItem, Object)
+ METHOD(MenuItem, draw, void(MenuItem));
+ METHOD(MenuItem, keyDown, float(MenuItem, float, float, float));
+ METHOD(MenuItem, keyUp, float(MenuItem, float, float, float));
+ METHOD(MenuItem, mouseMove, float(MenuItem, vector));
+ METHOD(MenuItem, mousePress, bool(MenuItem this, vector pos));
+ METHOD(MenuItem, mouseDrag, float(MenuItem, vector));
+ METHOD(MenuItem, mouseRelease, float(MenuItem, vector));
+ METHOD(MenuItem, focusEnter, void(MenuItem));
+ METHOD(MenuItem, focusLeave, void(MenuItem));
+ METHOD(MenuItem, resizeNotify, void(MenuItem, vector, vector, vector, vector));
+ METHOD(MenuItem, relinquishFocus, void(MenuItem));
+ METHOD(MenuItem, showNotify, void(MenuItem));
+ METHOD(MenuItem, hideNotify, void(MenuItem));
+ METHOD(MenuItem, toString, string(MenuItem));
+ METHOD(MenuItem, destroy, void(MenuItem));
+ ATTRIB(MenuItem, focused, float, 0);
+ ATTRIB(MenuItem, focusable, float, 0);
+ ATTRIB(MenuItem, allowFocusSound, float, 0);
+ ATTRIB(MenuItem, parent, entity);
+ ATTRIB(MenuItem, preferredFocusPriority, float, 0);
+ ATTRIB(MenuItem, origin, vector, '0 0 0');
+ ATTRIB(MenuItem, size, vector, '0 0 0');
+ ATTRIB(MenuItem, tooltip, string);
+ENDCLASS(MenuItem)
#include <menu/item.qh>
-CLASS(Container, Item)
+CLASS(Container, MenuItem)
METHOD(Container, draw, void(entity));
METHOD(Container, keyUp, float(entity, float, float, float));
METHOD(Container, keyDown, float(entity, float, float, float));
#pragma once
#include "../item.qh"
-CLASS(Image, Item)
+CLASS(Image, MenuItem)
METHOD(Image, configureImage, void(entity, string));
METHOD(Image, draw, void(entity));
METHOD(Image, toString, string(entity));
}
// skipping SUPER(InputBox).draw(me);
- Item_draw(me);
+ MenuItem_draw(me);
}
void InputBox_showNotify(entity me)
#pragma once
#include "../item.qh"
-CLASS(Label, Item)
+CLASS(Label, MenuItem)
METHOD(Label, configureLabel, void(entity, string, float, float));
METHOD(Label, draw, void(entity));
METHOD(Label, resizeNotify, void(entity, vector, vector, vector, vector));
#pragma once
#include "../item.qh"
-CLASS(ListBox, Item)
+CLASS(ListBox, MenuItem)
METHOD(ListBox, resizeNotify, void(entity, vector, vector, vector, vector));
METHOD(ListBox, configureListBox, void(entity, float, float));
METHOD(ListBox, draw, void(entity));
#pragma once
#include "../item.qh"
-CLASS(XonoticCrosshairPreview, Item)
+CLASS(XonoticCrosshairPreview, MenuItem)
METHOD(XonoticCrosshairPreview, configureXonoticCrosshairPreview, void(entity));
METHOD(XonoticCrosshairPreview, draw, void(entity));
ATTRIB(XonoticCrosshairPreview, src, string);
#pragma once
#include "../item.qh"
-CLASS(XonoticPicker, Item)
+CLASS(XonoticPicker, MenuItem)
METHOD(XonoticPicker, configureXonoticPicker, void(entity));
METHOD(XonoticPicker, mousePress, bool(XonoticPicker this, vector pos));
METHOD(XonoticPicker, mouseRelease, float(entity, vector));
}
// Find e and pick
if(e && pick)
- if(Drag_IsDraggable(e))
+ if(Drag_IsDraggable(e, this))
{
if(ischeat)
IS_CHEAT(this, 0, 0, CHRAME_DRAG);
}
}
-float Drag_IsDraggable(entity draggee)
+bool drag_undraggable(entity draggee, entity dragger)
+{
+ // stuff probably shouldn't need this, we should figure out why they do!
+ // exceptions of course are observers and weapon entities, where things mess up
+ return false;
+}
+
+float Drag_IsDraggable(entity draggee, entity dragger)
{
// TODO add more checks for bad stuff here
if(draggee == NULL)
return false;
- if(draggee.classname == "func_bobbing")
- return false;
if(draggee.classname == "door") // FIXME find out why these must be excluded, or work around the problem (trying to drag these causes like 4 fps)
- return false;
- if(draggee.classname == "plat")
- return false;
- if(draggee.classname == "func_button")
- return false;
+ return false; // probably due to BSP collision
// if(draggee.model == "")
// return false;
- if(IS_SPEC(draggee))
- return false;
- if(IS_OBSERVER(draggee))
- return false;
- if(draggee.classname == "exteriorweaponentity")
- return false;
- if(draggee.classname == "weaponentity")
- return false;
- return true;
+ return ((draggee.draggable) ? draggee.draggable(draggee, dragger) : true);
}
float Drag_MayChangeAngles(entity draggee)
dragger.dragentity = NULL;
return false;
}
- if(!Drag_CanDrag(dragger) || !Drag_IsDraggable(dragger.dragentity))
+ if(!Drag_CanDrag(dragger) || !Drag_IsDraggable(dragger.dragentity, dragger))
{
Drag_Finish(dragger);
return false;
const float CHRAME_DRAG = 8;
+bool drag_undraggable(entity draggee, entity dragger);
+
+.bool(entity this, entity dragger) draggable;
void Drag_MoveDrag(entity from, entity to); // call this from CopyBody
void DragBox_Think(entity this);
float Drag(entity this, float force_allow_pick, float ischeat);
void Drag_Begin(entity dragger, entity draggee, vector touchpoint);
void Drag_Finish(entity dragger);
-float Drag_IsDraggable(entity draggee);
+bool Drag_IsDraggable(entity draggee, entity dragger);
float Drag_MayChangeAngles(entity draggee);
void Drag_MoveForward(entity dragger);
void Drag_SetSpeed(entity dragger, float s);
this.crouch = false;
STAT(REVIVE_PROGRESS, this) = 0;
this.revival_time = 0;
+ this.draggable = drag_undraggable;
this.items = 0;
STAT(WEAPONS, this) = '0 0 0';
this.event_damage = PlayerDamage;
this.event_heal = PlayerHeal;
+ this.draggable = func_null;
+
if(!this.bot_attack)
IL_PUSH(g_bot_targets, this);
this.bot_attack = true;
if (IS_REAL_CLIENT(this))
sv_notice_join(this);
+ this.move_qcphysics = true;
+
// update physics stats (players can spawn before physics runs)
Physics_UpdateStats(this);
if ( !IS_DEAD(this.owner) && IS_PLAYER(this.owner) )
{
- if ( CS(this.owner).active_minigame )
+ if ( CS(this.owner).active_minigame && PHYS_INPUT_BUTTON_MINIGAME(this.owner) )
this.mdl = "models/sprites/minigame_busy.iqm";
else if (PHYS_INPUT_BUTTON_CHAT(this.owner))
this.mdl = "models/misc/chatbubble.spr";
void Player_Physics(entity this)
{
- set_movetype(this, this.move_movetype);
+ this.movetype = (this.move_qcphysics) ? MOVETYPE_QCPLAYER : this.move_movetype;
if(!this.move_qcphysics)
return;
store.impulse = this.impulse;
this.impulse = 0;
- bool typing = this.buttonchat;
+ bool typing = this.buttonchat || this.button14;
store.button0 = (typing) ? 0 : this.button0;
//button1?!
setthink(view, CL_Weaponentity_Think);
view.nextthink = time;
view.viewmodelforclient = actor;
+ view.draggable = drag_undraggable;
setcefc(view, CL_Weaponentity_CustomizeEntityForClient);
wepent_link(view);
entity exterior = actor.exteriorweaponentity = new(exteriorweaponentity);
exterior.solid = SOLID_NOT;
exterior.owner = actor;
+ exterior.draggable = drag_undraggable;
exterior.weaponentity_fld = weaponentity;
setorigin(exterior, '0 0 0');
setthink(exterior, CL_ExteriorWeaponentity_Think);