#include "weapons/projectile.qc" // TODO
+#include "../common/anim.qc"
#include "../common/animdecide.qc"
#include "../common/effects/effectinfo.qc"
+ #include "../common/ent_cs.qc"
#include "../common/mapinfo.qc"
#include "../common/movetypes/include.qc"
#include "../common/net_notice.qc"
#include "../common/minigames/minigames.qc"
#include "../common/minigames/cl_minigames.qc"
- #include "../common/buffs/all.qc"
#include "../common/deathtypes/all.qc"
#include "../common/effects/all.qc"
#include "../common/gamemodes/all.qc"
#include "../common/items/all.qc"
#include "../common/monsters/all.qc"
#include "../common/mutators/all.qc"
- #include "../common/nades/all.qc"
#include "../common/turrets/all.qc"
#include "../common/vehicles/all.qc"
#include "../common/weapons/all.qc"
#include "mutators/events.qh"
+#include "../common/anim.qh"
#include "../common/constants.qh"
#include "../common/debug.qh"
#include "../common/mapinfo.qh"
#include "../common/gamemodes/all.qh"
- #include "../common/nades/all.qh"
+ #include "../common/physics.qh"
#include "../common/stats.qh"
#include "../common/triggers/target/music.qh"
#include "../common/teams.qh"
#include "../lib/warpzone/client.qh"
#include "../lib/warpzone/common.qh"
- float frametime = (time - prevtime) * getstatf(STAT_MOVEVARS_TIMESCALE);
+#define EFMASK_CHEAP (EF_ADDITIVE | EF_DOUBLESIDED | EF_FULLBRIGHT | EF_NODEPTHTEST | EF_NODRAW | EF_NOSHADOW | EF_SELECTABLE | EF_TELEPORT_BIT)
+
+float autocvar_cl_viewmodel_scale;
+
+bool autocvar_cl_bobmodel;
+float autocvar_cl_bobmodel_speed;
+float autocvar_cl_bobmodel_side;
+float autocvar_cl_bobmodel_up;
+
+float autocvar_cl_followmodel;
+float autocvar_cl_followmodel_side_speed;
+float autocvar_cl_followmodel_side_highpass;
+float autocvar_cl_followmodel_side_highpass1;
+float autocvar_cl_followmodel_side_limit;
+float autocvar_cl_followmodel_side_lowpass;
+float autocvar_cl_followmodel_up_speed;
+float autocvar_cl_followmodel_up_highpass;
+float autocvar_cl_followmodel_up_highpass1;
+float autocvar_cl_followmodel_up_limit;
+float autocvar_cl_followmodel_up_lowpass;
+
+float autocvar_cl_leanmodel;
+float autocvar_cl_leanmodel_side_speed;
+float autocvar_cl_leanmodel_side_highpass;
+float autocvar_cl_leanmodel_side_highpass1;
+float autocvar_cl_leanmodel_side_lowpass;
+float autocvar_cl_leanmodel_side_limit;
+float autocvar_cl_leanmodel_up_speed;
+float autocvar_cl_leanmodel_up_highpass;
+float autocvar_cl_leanmodel_up_highpass1;
+float autocvar_cl_leanmodel_up_lowpass;
+float autocvar_cl_leanmodel_up_limit;
+
+#define lowpass(value, frac, ref_store, ret) do \
+{ \
+ float __frac = bound(0, frac, 1); \
+ ret = ref_store = ref_store * (1 - __frac) + (value) * __frac; \
+} while (0)
+
+#define lowpass_limited(value, frac, limit, ref_store, ret) do \
+{ \
+ float __ignore; lowpass(value, frac, ref_store, __ignore); \
+ ret = ref_store = bound((value) - (limit), ref_store, (value) + (limit)); \
+} while (0)
+
+#define highpass(value, frac, ref_store, ret) do \
+{ \
+ float __f; lowpass(value, frac, ref_store, __f); \
+ ret = (value) - __f; \
+} while (0)
+
+#define highpass_limited(value, frac, limit, ref_store, ret) do \
+{ \
+ float __f; lowpass_limited(value, frac, limit, ref_store, __f); \
+ ret = (value) - __f; \
+} while (0)
+
+#define lowpass3(value, fracx, fracy, fracz, ref_store, ref_out) do \
+{ \
+ lowpass(value.x, fracx, ref_store.x, ref_out.x); \
+ lowpass(value.y, fracy, ref_store.y, ref_out.y); \
+ lowpass(value.z, fracz, ref_store.z, ref_out.z); \
+} while (0)
+
+#define highpass3(value, fracx, fracy, fracz, ref_store, ref_out) do \
+{ \
+ highpass(value.x, fracx, ref_store.x, ref_out.x); \
+ highpass(value.y, fracy, ref_store.y, ref_out.y); \
+ highpass(value.z, fracz, ref_store.z, ref_out.z); \
+} while (0)
+
+#define highpass3_limited(value, fracx, limitx, fracy, limity, fracz, limitz, ref_store, ref_out) do \
+{ \
+ highpass_limited(value.x, fracx, limitx, ref_store.x, ref_out.x); \
+ highpass_limited(value.y, fracy, limity, ref_store.y, ref_out.y); \
+ highpass_limited(value.z, fracz, limitz, ref_store.z, ref_out.z); \
+} while (0)
+
+void viewmodel_animate(entity this)
+{
+ static float prevtime;
- entity view = CSQCModel_server2csqc(player_localentnum);
++ float frametime = (time - prevtime) * STAT(MOVEVARS_TIMESCALE);
+ prevtime = time;
+
+ if (autocvar_chase_active) return;
+ if (getstati(STAT_HEALTH) <= 0) return;
+
- entity me = CSQCModel_server2csqc(player_localentnum);
++ entity view = CSQCModel_server2csqc(player_localentnum - 1);
+
+ bool clonground = !(view.anim_implicit_state & ANIMIMPLICITSTATE_INAIR);
+ static bool oldonground;
+ static float hitgroundtime;
+ static float lastongroundtime;
+ if (clonground)
+ {
+ float f = time; // cl.movecmd[0].time
+ if (!oldonground)
+ hitgroundtime = f;
+ lastongroundtime = f;
+ }
+ oldonground = clonground;
+
+ vector gunorg = '0 0 0', gunangles = '0 0 0';
+ static vector gunorg_prev = '0 0 0', gunangles_prev = '0 0 0';
+
+ bool teleported = view.csqcmodel_teleported;
+
+ // 1. if we teleported, clear the frametime... the lowpass will recover the previous value then
+ if (teleported)
+ {
+ // try to fix the first highpass; result is NOT
+ // perfect! TODO find a better fix
+ gunangles_prev = view_angles;
+ gunorg_prev = view_origin;
+ }
+
+ static vector gunorg_highpass = '0 0 0';
+
+ // 2. for the gun origin, only keep the high frequency (non-DC) parts, which is "somewhat like velocity"
+ gunorg_highpass += gunorg_prev;
+ highpass3_limited(view_origin,
+ frametime * autocvar_cl_followmodel_side_highpass1, autocvar_cl_followmodel_side_limit,
+ frametime * autocvar_cl_followmodel_side_highpass1, autocvar_cl_followmodel_side_limit,
+ frametime * autocvar_cl_followmodel_up_highpass1, autocvar_cl_followmodel_up_limit,
+ gunorg_highpass, gunorg);
+ gunorg_prev = view_origin;
+ gunorg_highpass -= gunorg_prev;
+
+ static vector gunangles_highpass = '0 0 0';
+
+ // in the highpass, we _store_ the DIFFERENCE to the actual view angles...
+ gunangles_highpass += gunangles_prev;
+ PITCH(gunangles_highpass) += 360 * floor((PITCH(view_angles) - PITCH(gunangles_highpass)) / 360 + 0.5);
+ YAW(gunangles_highpass) += 360 * floor((YAW(view_angles) - YAW(gunangles_highpass)) / 360 + 0.5);
+ ROLL(gunangles_highpass) += 360 * floor((ROLL(view_angles) - ROLL(gunangles_highpass)) / 360 + 0.5);
+ highpass3_limited(view_angles,
+ frametime * autocvar_cl_leanmodel_up_highpass1, autocvar_cl_leanmodel_up_limit,
+ frametime * autocvar_cl_leanmodel_side_highpass1, autocvar_cl_leanmodel_side_limit,
+ 0, 0,
+ gunangles_highpass, gunangles);
+ gunangles_prev = view_angles;
+ gunangles_highpass -= gunangles_prev;
+
+ // 3. calculate the RAW adjustment vectors
+ gunorg.x *= (autocvar_cl_followmodel ? -autocvar_cl_followmodel_side_speed : 0);
+ gunorg.y *= (autocvar_cl_followmodel ? -autocvar_cl_followmodel_side_speed : 0);
+ gunorg.z *= (autocvar_cl_followmodel ? -autocvar_cl_followmodel_up_speed : 0);
+
+ PITCH(gunangles) *= (autocvar_cl_leanmodel ? -autocvar_cl_leanmodel_up_speed : 0);
+ YAW(gunangles) *= (autocvar_cl_leanmodel ? -autocvar_cl_leanmodel_side_speed : 0);
+ ROLL(gunangles) = 0;
+
+ static vector gunorg_adjustment_highpass;
+ static vector gunorg_adjustment_lowpass;
+ static vector gunangles_adjustment_highpass;
+ static vector gunangles_adjustment_lowpass;
+
+ // 4. perform highpass/lowpass on the adjustment vectors (turning velocity into acceleration!)
+ // trick: we must do the lowpass LAST, so the lowpass vector IS the final vector!
+ highpass3(gunorg,
+ frametime * autocvar_cl_followmodel_side_highpass,
+ frametime * autocvar_cl_followmodel_side_highpass,
+ frametime * autocvar_cl_followmodel_up_highpass,
+ gunorg_adjustment_highpass, gunorg);
+ lowpass3(gunorg,
+ frametime * autocvar_cl_followmodel_side_lowpass,
+ frametime * autocvar_cl_followmodel_side_lowpass,
+ frametime * autocvar_cl_followmodel_up_lowpass,
+ gunorg_adjustment_lowpass, gunorg);
+ // we assume here: PITCH = 0, YAW = 1, ROLL = 2
+ highpass3(gunangles,
+ frametime * autocvar_cl_leanmodel_up_highpass,
+ frametime * autocvar_cl_leanmodel_side_highpass,
+ 0,
+ gunangles_adjustment_highpass, gunangles);
+ lowpass3(gunangles,
+ frametime * autocvar_cl_leanmodel_up_lowpass,
+ frametime * autocvar_cl_leanmodel_side_lowpass,
+ 0,
+ gunangles_adjustment_lowpass, gunangles);
+ float xyspeed = bound(0, vlen(vec2(view.velocity)), 400);
+
+ // vertical view bobbing code
+ // TODO: cl_bob
+
+ // horizontal view bobbing code
+ // TODO: cl_bob2
+
+ // fall bobbing code
+ // causes the view to swing down and back up when touching the ground
+ // TODO: cl_bobfall
+
+ // gun model bobbing code
+ if (autocvar_cl_bobmodel)
+ {
+ // calculate for swinging gun model
+ // the gun bobs when running on the ground, but doesn't bob when you're in the air.
+ // Sajt: I tried to smooth out the transitions between bob and no bob, which works
+ // for the most part, but for some reason when you go through a message trigger or
+ // pick up an item or anything like that it will momentarily jolt the gun.
+ vector forward, right, up;
+ float bspeed;
+ float t = 1;
+ float s = time * autocvar_cl_bobmodel_speed;
+ if (clonground)
+ {
+ if (time - hitgroundtime < 0.2)
+ {
+ // just hit the ground, speed the bob back up over the next 0.2 seconds
+ t = time - hitgroundtime;
+ t = bound(0, t, 0.2);
+ t *= 5;
+ }
+ }
+ else
+ {
+ // recently left the ground, slow the bob down over the next 0.2 seconds
+ t = time - lastongroundtime;
+ t = 0.2 - bound(0, t, 0.2);
+ t *= 5;
+ }
+ bspeed = xyspeed * 0.01;
+ MAKEVECTORS(makevectors, gunangles, forward, right, up);
+ float bobr = bspeed * autocvar_cl_bobmodel_side * autocvar_cl_viewmodel_scale * sin(s) * t;
+ gunorg += bobr * right;
+ float bobu = bspeed * autocvar_cl_bobmodel_up * autocvar_cl_viewmodel_scale * cos(s * 2) * t;
+ gunorg += bobu * up;
+ }
+ this.origin += view_forward * gunorg.x + view_right * gunorg.y + view_up * gunorg.z;
+ gunangles.x = -gunangles.x; // pitch was inverted, now that actually matters
+ this.angles += gunangles;
+}
+
+.vector viewmodel_origin, viewmodel_angles;
+
+void viewmodel_draw(entity this)
+{
+ int mask = (intermission || (getstati(STAT_HEALTH) <= 0) || autocvar_chase_active) ? 0 : MASK_NORMAL;
+ float a = this.alpha;
+ int c = stof(getplayerkeyvalue(current_player, "colors"));
+ vector g = this.glowmod; // TODO: completely clientside: colormapPaletteColor(c & 0x0F, true) * 2;
- float eta = (getstatf(STAT_WEAPON_NEXTTHINK) - time); // TODO: / W_WeaponRateFactor();
++ entity me = CSQCModel_server2csqc(player_localentnum - 1);
+ int fx = ((me.csqcmodel_effects & EFMASK_CHEAP)
+ | EF_NODEPTHTEST)
+ &~ (EF_FULLBRIGHT); // can mask team color, so get rid of it
+ for (entity e = this; e; e = e.weaponchild)
+ {
+ e.drawmask = mask;
+ e.alpha = a;
+ e.colormap = c;
+ e.glowmod = g;
+ e.csqcmodel_effects = fx;
+ WITH(entity, self, e, CSQCModel_Effects_Apply());
+ }
+ {
+ static string name_last;
+ string name = Weapons_from(activeweapon).mdl;
+ if (name != name_last)
+ {
+ name_last = name;
+ CL_WeaponEntity_SetModel(this, name);
+ this.viewmodel_origin = this.origin;
+ this.viewmodel_angles = this.angles;
+ }
+ anim_update(this);
+ if (!this.animstate_override)
+ anim_set(this, this.anim_idle, true, false, false);
+ }
++ float eta = (STAT(WEAPON_NEXTTHINK) - time); // TODO: / W_WeaponRateFactor();
+ float f = 0; // 0..1; 0: fully active
+ switch (this.state)
+ {
+ case WS_RAISE:
+ {
+ // entity newwep = Weapons_from(activeweapon);
+ float delay = 0.2; // TODO: newwep.switchdelay_raise;
+ f = eta / max(eta, delay);
+ break;
+ }
+ case WS_DROP:
+ {
+ // entity oldwep = Weapons_from(activeweapon);
+ float delay = 0.2; // TODO: newwep.switchdelay_drop;
+ f = 1 - eta / max(eta, delay);
+ break;
+ }
+ case WS_CLEAR:
+ {
+ f = 1;
+ break;
+ }
+ }
+ this.origin = this.viewmodel_origin;
+ this.angles = this.viewmodel_angles;
+ this.angles_x = (-90 * f * f);
+ viewmodel_animate(this);
+ setorigin(this, this.origin);
+}
+
+entity viewmodel;
+STATIC_INIT(viewmodel) {
+ viewmodel = new(viewmodel);
+ viewmodel.draw = viewmodel_draw;
+}
+
entity porto;
vector polyline[16];
void Porto_Draw(entity this)
break;
}
- vector traceorigin = getplayerorigin(player_localentnum-1) + (eZ * getstati(STAT_VIEWHEIGHT));
+ vector traceorigin = entcs_receiver(player_localentnum - 1).origin + (eZ * getstati(STAT_VIEWHEIGHT));
- vecs = decompressShotOrigin(getstati(STAT_SHOTORG));
+ vecs = decompressShotOrigin(STAT(SHOTORG));
traceline(traceorigin, traceorigin + view_forward * MAX_SHOT_DISTANCE, mv, ta);
trueaimpoint = trace_endpos;
return true;
if(MUTATOR_CALLHOOK(WantEventchase, self))
return true;
- if(autocvar_cl_eventchase_nexball && gametype == MAPINFO_TYPE_NEXBALL && !(WepSet_GetFromStat() & WepSet_FromWeapon(WEP_NEXBALL.m_id)))
+ if(autocvar_cl_eventchase_nexball && gametype == MAPINFO_TYPE_NEXBALL && !(WepSet_GetFromStat() & WEPSET(NEXBALL)))
return true;
if(autocvar_cl_eventchase_death && (getstati(STAT_HEALTH) <= 0))
{
{
// accumulate damage with each stat update
static float damage_total_prev = 0;
- float damage_total = getstati(STAT_DAMAGE_DEALT_TOTAL);
+ float damage_total = STAT(DAMAGE_DEALT_TOTAL);
float unaccounted_damage_new = COMPARE_INCREASING(damage_total, damage_total_prev);
damage_total_prev = damage_total;
static float damage_dealt_time_prev = 0;
- float damage_dealt_time = getstatf(STAT_HIT_TIME);
+ float damage_dealt_time = STAT(HIT_TIME);
if (damage_dealt_time != damage_dealt_time_prev)
{
unaccounted_damage += unaccounted_damage_new;
}
static float typehit_time_prev = 0;
- float typehit_time = getstatf(STAT_TYPEHIT_TIME);
+ float typehit_time = STAT(TYPEHIT_TIME);
if (COMPARE_INCREASING(typehit_time, typehit_time_prev) > autocvar_cl_hitsound_antispam_time)
{
sound(world, CH_INFO, SND_TYPEHIT, VOL_BASE, ATTN_NONE);
if(autocvar_crosshair_pickup)
{
- float stat_pickup_time = getstatf(STAT_LAST_PICKUP);
+ float stat_pickup_time = STAT(LAST_PICKUP);
if(pickup_crosshair_time < stat_pickup_time)
{
ring_scale = autocvar_crosshair_ring_size;
float weapon_clipload, weapon_clipsize;
- weapon_clipload = getstati(STAT_WEAPON_CLIPLOAD);
- weapon_clipsize = getstati(STAT_WEAPON_CLIPSIZE);
+ weapon_clipload = STAT(WEAPON_CLIPLOAD);
+ weapon_clipsize = STAT(WEAPON_CLIPSIZE);
float ok_ammo_charge, ok_ammo_chargepool;
- ok_ammo_charge = getstatf(STAT_OK_AMMO_CHARGE);
- ok_ammo_chargepool = getstatf(STAT_OK_AMMO_CHARGEPOOL);
+ ok_ammo_charge = STAT(OK_AMMO_CHARGE);
+ ok_ammo_chargepool = STAT(OK_AMMO_CHARGEPOOL);
float vortex_charge, vortex_chargepool;
- vortex_charge = getstatf(STAT_VORTEX_CHARGE);
- vortex_chargepool = getstatf(STAT_VORTEX_CHARGEPOOL);
+ vortex_charge = STAT(VORTEX_CHARGE);
+ vortex_chargepool = STAT(VORTEX_CHARGEPOOL);
- float arc_heat = getstatf(STAT_ARC_HEAT);
+ float arc_heat = STAT(ARC_HEAT);
if(vortex_charge_movingavg == 0) // this should only happen if we have just loaded up the game
vortex_charge_movingavg = vortex_charge;
}
else if (autocvar_crosshair_ring && activeweapon == WEP_MINE_LAYER.m_id && minelayer_maxmines && autocvar_crosshair_ring_minelayer)
{
- ring_value = bound(0, getstati(STAT_LAYED_MINES) / minelayer_maxmines, 1); // if you later need to use the count of bullets in another place, then add a float for it. For now, no need to.
+ ring_value = bound(0, STAT(LAYED_MINES) / minelayer_maxmines, 1); // if you later need to use the count of bullets in another place, then add a float for it. For now, no need to.
ring_alpha = autocvar_crosshair_ring_minelayer_alpha;
ring_rgb = wcross_color;
ring_image = "gfx/crosshair_ring.tga";
}
- else if (activeweapon == WEP_HAGAR.m_id && getstati(STAT_HAGAR_LOAD) && autocvar_crosshair_ring_hagar)
+ else if (activeweapon == WEP_HAGAR.m_id && STAT(HAGAR_LOAD) && autocvar_crosshair_ring_hagar)
{
- ring_value = bound(0, getstati(STAT_HAGAR_LOAD) / hagar_maxrockets, 1);
+ ring_value = bound(0, STAT(HAGAR_LOAD) / hagar_maxrockets, 1);
ring_alpha = autocvar_crosshair_ring_hagar_alpha;
ring_rgb = wcross_color;
ring_image = "gfx/crosshair_ring.tga";
wcross_color = stov(autocvar_crosshair_dot_color);
CROSSHAIR_DRAW(wcross_resolution * autocvar_crosshair_dot_size, "gfx/crosshairdot.tga", f * autocvar_crosshair_dot_alpha);
- // FIXME why don't we use wcross_alpha here?cl_notice_run();
+ // FIXME why don't we use wcross_alpha here?
wcross_color = wcross_color_old;
}
}
void HUD_Draw()
{
- if(getstati(STAT_FROZEN))
- drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, ((getstatf(STAT_REVIVE_PROGRESS)) ? ('0.25 0.90 1' + ('1 0 0' * getstatf(STAT_REVIVE_PROGRESS)) + ('0 1 1' * getstatf(STAT_REVIVE_PROGRESS) * -1)) : '0.25 0.90 1'), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
- else if (getstatf(STAT_HEALING_ORB)>time)
- drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, NADE_TYPE_HEAL.m_color, autocvar_hud_colorflash_alpha*getstatf(STAT_HEALING_ORB_ALPHA), DRAWFLAG_ADDITIVE);
+ vector rgb = '0 0 0';
+ float a = 1;
+ if (MUTATOR_CALLHOOK(HUD_Draw_overlay))
+ {
+ rgb = MUTATOR_ARGV(0, vector);
+ a = MUTATOR_ARGV(0, float);
+ }
+ else if(STAT(FROZEN))
+ {
+ rgb = ((STAT(REVIVE_PROGRESS)) ? ('0.25 0.90 1' + ('1 0 0' * STAT(REVIVE_PROGRESS)) + ('0 1 1' * STAT(REVIVE_PROGRESS) * -1)) : '0.25 0.90 1');
+ }
+ drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, rgb, autocvar_hud_colorflash_alpha * a, DRAWFLAG_ADDITIVE);
if(!intermission)
- if(getstatf(STAT_NADE_TIMER) && autocvar_cl_nade_timer) // give nade top priority, as it's a matter of life and death
+ if(STAT(NADE_TIMER) && autocvar_cl_nade_timer) // give nade top priority, as it's a matter of life and death
{
- DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", getstatf(STAT_NADE_TIMER), '0.25 0.90 1' + ('1 0 0' * getstatf(STAT_NADE_TIMER)) - ('0 1 1' * getstatf(STAT_NADE_TIMER)), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
+ DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", STAT(NADE_TIMER), '0.25 0.90 1' + ('1 0 0' * STAT(NADE_TIMER)) - ('0 1 1' * STAT(NADE_TIMER)), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
drawstring_aspect(eY * 0.64 * vid_conheight, ((autocvar_cl_nade_timer == 2) ? _("Nade timer") : ""), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL);
}
- else if(getstatf(STAT_REVIVE_PROGRESS))
+ else if(STAT(REVIVE_PROGRESS))
{
- DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", getstatf(STAT_REVIVE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
+ DrawCircleClippedPic(eX * 0.5 * vid_conwidth + eY * 0.6 * vid_conheight, 0.1 * vid_conheight, "gfx/crosshair_ring.tga", STAT(REVIVE_PROGRESS), '0.25 0.90 1', autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE);
drawstring_aspect(eY * 0.64 * vid_conheight, _("Revival progress"), eX * vid_conwidth + eY * 0.025 * vid_conheight, '1 1 1', 1, DRAWFLAG_NORMAL);
}
float oldr_useportalculling;
float oldr_useinfinitefarclip;
- const int BUTTON_3 = 4;
- const int BUTTON_4 = 8;
- float cl_notice_run();
+ void cl_notice_run();
float prev_myteam;
int lasthud;
float vh_notice_time;
++framecount;
- hud = getstati(STAT_HUD);
+ stats_get();
+ hud = STAT(HUD);
if(hud != HUD_NORMAL && lasthud == HUD_NORMAL)
vh_notice_time = time + autocvar_cl_vehicles_notify_time;
else
view_quality = 1;
- button_attack2 = (input_buttons & BUTTON_3);
- button_zoom = (input_buttons & BUTTON_4);
+ button_attack2 = PHYS_INPUT_BUTTON_ATCK2(self);
+ button_zoom = PHYS_INPUT_BUTTON_ZOOM(self);
vf_size = getpropertyvec(VF_SIZE);
vf_min = getpropertyvec(VF_MIN);
prev_myteam = myteam;
}
- ticrate = getstatf(STAT_MOVEVARS_TICRATE) * getstatf(STAT_MOVEVARS_TIMESCALE);
+ ticrate = STAT(MOVEVARS_TICRATE) * STAT(MOVEVARS_TIMESCALE);
float is_dead = (getstati(STAT_HEALTH) <= 0);
if(autocvar_chase_active <= 0) // greater than 0 means it's enabled manually, and this code is skipped
{
float vehicle_chase = (hud != HUD_NORMAL && (autocvar_cl_eventchase_vehicle || spectatee_status > 0));
- float ons_roundlost = (gametype == MAPINFO_TYPE_ONSLAUGHT && getstati(STAT_ROUNDLOST));
+ float ons_roundlost = (gametype == MAPINFO_TYPE_ONSLAUGHT && STAT(ROUNDLOST));
entity gen = world;
if(ons_roundlost)
ColorTranslateMode = autocvar_cl_stripcolorcodes;
- // next WANTED weapon (for HUD)
- switchweapon = getstati(STAT_SWITCHWEAPON);
-
// currently switching-to weapon (for crosshair)
- switchingweapon = getstati(STAT_SWITCHINGWEAPON);
+ switchingweapon = STAT(SWITCHINGWEAPON);
// actually active weapon (for zoom)
activeweapon = getstati(STAT_ACTIVEWEAPON);
mousepos = mousepos*0.5 + getmousepos();
*/
- for(entity e = NULL; (e = nextent(e)); ) if (e.draw) {
- WITH(entity, self, e, e.draw(e));
- }
+ FOREACH_ENTITY(it.draw, LAMBDA(WITH(entity, self, it, it.draw(it))));
addentities(MASK_NORMAL | MASK_ENGINE | MASK_ENGINEVIEWMODELS);
renderscene();
}
}
- if(autocvar_hud_damage && !getstati(STAT_FROZEN))
+ if(autocvar_hud_damage && !STAT(FROZEN))
{
splash_size.x = max(vid_conwidth, vid_conheight);
splash_size.y = max(vid_conwidth, vid_conheight);
}
// edge detection postprocess handling done second (used by hud_powerup)
- float sharpen_intensity = 0, strength_finished = getstatf(STAT_STRENGTH_FINISHED), invincible_finished = getstatf(STAT_INVINCIBLE_FINISHED);
+ float sharpen_intensity = 0, strength_finished = STAT(STRENGTH_FINISHED), invincible_finished = STAT(INVINCIBLE_FINISHED);
if (strength_finished - time > 0) { sharpen_intensity += (strength_finished - time); }
if (invincible_finished - time > 0) { sharpen_intensity += (invincible_finished - time); }
} else */
// draw 2D entities
- for (entity e = NULL; (e = nextent(e)); ) if (e.draw2d) {
- WITH(entity, self, e, e.draw2d(e));
- }
+ FOREACH_ENTITY(it.draw2d, LAMBDA(WITH(entity, self, it, it.draw2d(it))));
Draw_ShowNames_All();
Debug_Draw();
#include "../../common/constants.qh"
#include "../../common/movetypes/movetypes.qh"
- #include "../../common/nades/all.qh"
#include "../../lib/csqcmodel/interpolate.qh"
}
}
+ bool Projectile_isnade(int proj); // TODO: remove
+
void Projectile_Draw(entity this)
{
vector rot;
{
// self.move_flags &= ~FL_ONGROUND;
if (self.move_movetype == MOVETYPE_NONE || self.move_movetype == MOVETYPE_FLY)
- Movetype_Physics_NoMatchServer();
+ Movetype_Physics_NoMatchServer(self);
// the trivial movetypes do not have to match the
// server's ticrate as they are ticrate independent
// NOTE: this assumption is only true if MOVETYPE_FLY
// projectiles detonate on impact. If they continue
// moving, we might still be ticrate dependent.
else
- Movetype_Physics_MatchServer(autocvar_cl_projectiles_sloppy);
+ Movetype_Physics_MatchServer(self, autocvar_cl_projectiles_sloppy);
if (!(self.move_flags & FL_ONGROUND))
if (self.velocity != '0 0 0')
self.move_angles = self.angles = vectoangles(self.velocity);
}
else
{
- InterpolateOrigin_Do();
+ InterpolateOrigin_Do(self);
}
if (self.count & 0x80)
break;
}
- if (Nade_FromProjectile(self.cnt) != NADE_TYPE_Null)
+ if (Projectile_isnade(self.cnt))
rot = self.avelocity;
self.angles = AnglesTransform_ToAngles(AnglesTransform_Multiply(AnglesTransform_FromAngles(self.angles), rot * (t - self.spawntime)));
break;
}
- if (Nade_FromProjectile(self.cnt) != NADE_TYPE_Null)
+ if (Projectile_isnade(self.cnt))
trailorigin += v_up * 4;
if (drawn)
}
if (!(self.count & 0x80))
- InterpolateOrigin_Undo();
+ InterpolateOrigin_Undo(self);
if (f & 1)
{
self.traileffect = 0;
switch (self.cnt)
{
- #define CASE(id) case PROJECTILE_##id: setmodel(self, MDL_PROJECTILE_##id);
- CASE(ELECTRO) self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
- CASE(ROCKET) self.traileffect = EFFECT_TR_ROCKET.m_id; self.scale = 2; break;
- CASE(CRYLINK) self.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
- CASE(CRYLINK_BOUNCING) self.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
- CASE(ELECTRO_BEAM) self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
- CASE(GRENADE) self.traileffect = EFFECT_TR_GRENADE.m_id; break;
- CASE(GRENADE_BOUNCING) self.traileffect = EFFECT_TR_GRENADE.m_id; break;
- CASE(MINE) self.traileffect = EFFECT_TR_GRENADE.m_id; break;
- CASE(BLASTER) self.traileffect = EFFECT_Null.m_id; break;
- CASE(HLAC) self.traileffect = EFFECT_Null.m_id; break;
- CASE(PORTO_RED) self.traileffect = EFFECT_TR_WIZSPIKE.m_id; self.scale = 4; break;
- CASE(PORTO_BLUE) self.traileffect = EFFECT_TR_WIZSPIKE.m_id; self.scale = 4; break;
- CASE(HOOKBOMB) self.traileffect = EFFECT_TR_KNIGHTSPIKE.m_id; break;
- CASE(HAGAR) self.traileffect = EFFECT_HAGAR_ROCKET.m_id; self.scale = 0.75; break;
- CASE(HAGAR_BOUNCING) self.traileffect = EFFECT_HAGAR_ROCKET.m_id; self.scale = 0.75; break;
- CASE(FIREBALL) self.modelindex = 0; self.traileffect = EFFECT_FIREBALL.m_id; break; // particle effect is good enough
- CASE(FIREMINE) self.modelindex = 0; self.traileffect = EFFECT_FIREMINE.m_id; break; // particle effect is good enough
- CASE(TAG) self.traileffect = EFFECT_TR_ROCKET.m_id; break;
- CASE(FLAC) self.scale = 0.4; self.traileffect = EFFECT_FLAC_TRAIL.m_id; break;
- CASE(SEEKER) self.traileffect = EFFECT_SEEKER_TRAIL.m_id; break;
-
- CASE(MAGE_SPIKE) self.traileffect = EFFECT_TR_VORESPIKE.m_id; break;
- CASE(SHAMBLER_LIGHTNING) self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
-
- CASE(RAPTORBOMB) self.gravity = 1; self.avelocity = '0 0 180'; self.traileffect = EFFECT_Null.m_id; break;
- CASE(RAPTORBOMBLET) self.gravity = 1; self.avelocity = '0 0 180'; self.traileffect = EFFECT_Null.m_id; break;
- CASE(RAPTORCANNON) self.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
-
- CASE(SPIDERROCKET) self.traileffect = EFFECT_SPIDERBOT_ROCKET_TRAIL.m_id; break;
- CASE(WAKIROCKET) self.traileffect = EFFECT_RACER_ROCKET_TRAIL.m_id; break;
- CASE(WAKICANNON) self.traileffect = EFFECT_Null.m_id; break;
-
- CASE(BUMBLE_GUN) self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
- CASE(BUMBLE_BEAM) self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
-
- CASE(RPC) self.traileffect = EFFECT_TR_ROCKET.m_id; break;
-
- CASE(ROCKETMINSTA_LASER) self.traileffect = EFFECT_ROCKETMINSTA_LASER(self.team).m_id; break;
-#undef CASE
+ #define HANDLE(id) case PROJECTILE_##id: setmodel(self, MDL_PROJECTILE_##id);
+ HANDLE(ELECTRO) self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
+ HANDLE(ROCKET) self.traileffect = EFFECT_TR_ROCKET.m_id; self.scale = 2; break;
+ HANDLE(CRYLINK) self.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
+ HANDLE(CRYLINK_BOUNCING) self.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
+ HANDLE(ELECTRO_BEAM) self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
+ HANDLE(GRENADE) self.traileffect = EFFECT_TR_GRENADE.m_id; break;
+ HANDLE(GRENADE_BOUNCING) self.traileffect = EFFECT_TR_GRENADE.m_id; break;
+ HANDLE(MINE) self.traileffect = EFFECT_TR_GRENADE.m_id; break;
+ HANDLE(BLASTER) self.traileffect = EFFECT_Null.m_id; break;
+ HANDLE(HLAC) self.traileffect = EFFECT_Null.m_id; break;
+ HANDLE(PORTO_RED) self.traileffect = EFFECT_TR_WIZSPIKE.m_id; self.scale = 4; break;
+ HANDLE(PORTO_BLUE) self.traileffect = EFFECT_TR_WIZSPIKE.m_id; self.scale = 4; break;
+ HANDLE(HOOKBOMB) self.traileffect = EFFECT_TR_KNIGHTSPIKE.m_id; break;
+ HANDLE(HAGAR) self.traileffect = EFFECT_HAGAR_ROCKET.m_id; self.scale = 0.75; break;
+ HANDLE(HAGAR_BOUNCING) self.traileffect = EFFECT_HAGAR_ROCKET.m_id; self.scale = 0.75; break;
- HANDLE(NAPALM_FOUNTAIN) // fallthrough // sself.modelindex = 0; self.traileffect = _particleeffectnum("torch_small"); break;
+ HANDLE(FIREBALL) self.modelindex = 0; self.traileffect = EFFECT_FIREBALL.m_id; break; // particle effect is good enough
+ HANDLE(FIREMINE) self.modelindex = 0; self.traileffect = EFFECT_FIREMINE.m_id; break; // particle effect is good enough
+ HANDLE(TAG) self.traileffect = EFFECT_TR_ROCKET.m_id; break;
+ HANDLE(FLAC) self.scale = 0.4; self.traileffect = EFFECT_FLAC_TRAIL.m_id; break;
+ HANDLE(SEEKER) self.traileffect = EFFECT_SEEKER_TRAIL.m_id; break;
+
+ HANDLE(MAGE_SPIKE) self.traileffect = EFFECT_TR_VORESPIKE.m_id; break;
+ HANDLE(SHAMBLER_LIGHTNING) self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
+
+ HANDLE(RAPTORBOMB) self.gravity = 1; self.avelocity = '0 0 180'; self.traileffect = EFFECT_Null.m_id; break;
+ HANDLE(RAPTORBOMBLET) self.gravity = 1; self.avelocity = '0 0 180'; self.traileffect = EFFECT_Null.m_id; break;
+ HANDLE(RAPTORCANNON) self.traileffect = EFFECT_TR_CRYLINKPLASMA.m_id; break;
+
+ HANDLE(SPIDERROCKET) self.traileffect = EFFECT_SPIDERBOT_ROCKET_TRAIL.m_id; break;
+ HANDLE(WAKIROCKET) self.traileffect = EFFECT_RACER_ROCKET_TRAIL.m_id; break;
+ HANDLE(WAKICANNON) self.traileffect = EFFECT_Null.m_id; break;
+
+ HANDLE(BUMBLE_GUN) self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
+ HANDLE(BUMBLE_BEAM) self.traileffect = EFFECT_TR_NEXUIZPLASMA.m_id; break;
+
+ HANDLE(RPC) self.traileffect = EFFECT_TR_ROCKET.m_id; break;
+
+ HANDLE(ROCKETMINSTA_LASER) self.traileffect = EFFECT_ROCKETMINSTA_LASER(self.team).m_id; break;
+#undef HANDLE
default:
if (MUTATOR_CALLHOOK(Ent_Projectile, self))
break;
- if (Nade_FromProjectile(self.cnt) != NADE_TYPE_Null)
- {
- setmodel(self, MDL_PROJECTILE_NADE);
- entity trail = Nade_TrailEffect(self.cnt, self.team);
- if (trail.eent_eff_name) self.traileffect = trail.m_id;
- break;
- }
error("Received invalid CSQC projectile, can't work with this!");
break;
}
self.move_movetype = MOVETYPE_BOUNCE;
self.move_touch = func_null;
break;
- case PROJECTILE_NAPALM_FOUNTAIN:
case PROJECTILE_FIREBALL:
loopsound(self, CH_SHOTS_SINGLE, SND(FIREBALL_FLY2), VOL_BASE, ATTEN_NORM);
self.mins = '-16 -16 -16';
break;
}
- if (Nade_FromProjectile(self.cnt) != NADE_TYPE_Null)
- {
- entity nade_type = Nade_FromProjectile(self.cnt);
- self.mins = '-16 -16 -16';
- self.maxs = '16 16 16';
- self.colormod = nade_type.m_color;
- self.move_movetype = MOVETYPE_BOUNCE;
- self.move_touch = func_null;
- self.scale = 1.5;
- self.avelocity = randomvec() * 720;
-
- if (nade_type == NADE_TYPE_TRANSLOCATE || nade_type == NADE_TYPE_SPAWN)
- self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_PLAYERCLIP | DPCONTENTS_BOTCLIP;
- else
- self.dphitcontentsmask = DPCONTENTS_SOLID | DPCONTENTS_BODY;
- }
-
MUTATOR_CALLHOOK(EditProjectile, self);
setsize(self, self.mins, self.maxs);
}
if (!(self.count & 0x80))
- InterpolateOrigin_Note();
+ InterpolateOrigin_Note(this);
self.classname = "csqcprojectile";
self.draw = Projectile_Draw;
// Full list of all stat constants, included in a single location for easy reference
// 255 is the current limit (MAX_CL_STATS - 1), engine will need to be modified if you wish to add more stats
- const int MAX_CL_STATS = 256;
- // -Wdouble-declaration
- // const int STAT_HEALTH = 0;
- // 1 empty?
- const int STAT_WEAPON = 2;
- // -Wdouble-declaration
- // const int STAT_AMMO = 3;
- // -Wdouble-declaration
- // const int STAT_ARMOR = 4;
- // -Wdouble-declaration
- // const int STAT_WEAPONFRAME = 5;
- // -Wdouble-declaration
- // const int STAT_SHELLS = 6;
- // -Wdouble-declaration
- // const int STAT_NAILS = 7;
- // -Wdouble-declaration
- // const int STAT_ROCKETS = 8;
- // -Wdouble-declaration
- // const int STAT_CELLS = 9;
- // -Wdouble-declaration
- // const int STAT_ACTIVEWEAPON = 10;
- // -Wdouble-declaration
- // const int STAT_TOTALSECRETS = 11;
- // -Wdouble-declaration
- // const int STAT_TOTALMONSTERS = 12;
- // -Wdouble-declaration
- // const int STAT_SECRETS = 13;
- // -Wdouble-declaration
- // const int STAT_MONSTERS = 14;
- // -Wdouble-declaration
- // const int STAT_ITEMS = 15;
- // -Wdouble-declaration
- // const int STAT_VIEWHEIGHT = 16;
- // 17 empty?
- // 18 empty?
- // 19 empty?
- // 20 empty?
- const int STAT_VIEWZOOM = 21;
- // 22 empty?
- // 23 empty?
- // 24 empty?
- // 25 empty?
- // 26 empty?
- // 27 empty?
- // 28 empty?
- // 29 empty?
- // 30 empty?
- // 31 empty?
- const int STAT_KH_KEYS = 32;
- const int STAT_CTF_STATE = 33;
- // 34 empty?
- const int STAT_WEAPONS = 35;
- const int STAT_SWITCHWEAPON = 36;
- const int STAT_GAMESTARTTIME = 37;
- const int STAT_STRENGTH_FINISHED = 38;
- const int STAT_INVINCIBLE_FINISHED = 39;
- // 40 empty?
- const int STAT_ARC_HEAT = 41;
- const int STAT_PRESSED_KEYS = 42;
- const int STAT_ALLOW_OLDVORTEXBEAM = 43; // this stat could later contain some other bits of info, like, more server-side particle config
- const int STAT_FUEL = 44;
- const int STAT_NB_METERSTART = 45;
- const int STAT_SHOTORG = 46; // compressShotOrigin
- const int STAT_LEADLIMIT = 47;
- const int STAT_WEAPON_CLIPLOAD = 48;
- const int STAT_WEAPON_CLIPSIZE = 49;
- const int STAT_VORTEX_CHARGE = 50;
- const int STAT_LAST_PICKUP = 51;
- const int STAT_HUD = 52;
- const int STAT_VORTEX_CHARGEPOOL = 53;
- const int STAT_HIT_TIME = 54;
- const int STAT_DAMAGE_DEALT_TOTAL = 55;
- const int STAT_TYPEHIT_TIME = 56;
- const int STAT_LAYED_MINES = 57;
- const int STAT_HAGAR_LOAD = 58;
- const int STAT_SWITCHINGWEAPON = 59;
- const int STAT_SUPERWEAPONS_FINISHED = 60;
- const int STAT_VEHICLESTAT_HEALTH = 61;
- const int STAT_VEHICLESTAT_SHIELD = 62;
- const int STAT_VEHICLESTAT_ENERGY = 63;
- const int STAT_VEHICLESTAT_AMMO1 = 64;
- const int STAT_VEHICLESTAT_RELOAD1 = 65;
- const int STAT_VEHICLESTAT_AMMO2 = 66;
- const int STAT_VEHICLESTAT_RELOAD2 = 67;
- const int STAT_VEHICLESTAT_W2MODE = 68;
- const int STAT_NADE_TIMER = 69;
- const int STAT_SECRETS_TOTAL = 70;
- const int STAT_SECRETS_FOUND = 71;
- const int STAT_RESPAWN_TIME = 72;
- const int STAT_ROUNDSTARTTIME = 73;
- const int STAT_WEAPONS2 = 74;
- const int STAT_WEAPONS3 = 75;
- const int STAT_MONSTERS_TOTAL = 76;
- const int STAT_MONSTERS_KILLED = 77;
- const int STAT_BUFFS = 78;
- const int STAT_NADE_BONUS = 79;
- const int STAT_NADE_BONUS_TYPE = 80;
- const int STAT_NADE_BONUS_SCORE = 81;
- const int STAT_HEALING_ORB = 82;
- const int STAT_HEALING_ORB_ALPHA = 83;
- const int STAT_PLASMA = 84;
- const int STAT_OK_AMMO_CHARGE = 85;
- const int STAT_OK_AMMO_CHARGEPOOL = 86;
- const int STAT_FROZEN = 87;
- const int STAT_REVIVE_PROGRESS = 88;
- const int STAT_WEAPON_NEXTTHINK = 89;
- // 90 empty?
- // 91 empty?
- // 92 empty?
- // 93 empty?
- // 94 empty?
- // 95 empty?
- // 96 empty?
- // 97 empty?
- // 98 empty?
- const int STAT_ROUNDLOST = 99;
+ const int MAX_CL_STATS = 256;
+ #ifndef CSQC
+ const int STAT_HEALTH = 0; // .health
+ const int STAT_ARMOR = 4; // .armorvalue
+ const int STAT_SHELLS = 6; // .ammo_shells
+ const int STAT_NAILS = 7; // .ammo_nails
+ const int STAT_ROCKETS = 8; // .ammo_rockets
+ const int STAT_CELLS = 9; // .ammo_cells
+ const int STAT_ACTIVEWEAPON = 10; // .weapon
+ const int STAT_ITEMS = 15; // .items | .items2 << 23 | serverflags << 28
+ const int STAT_VIEWHEIGHT = 16; // .view_ofs_z
+ #endif
+
+ REGISTER_STAT(WEAPONS, vectori)
+ REGISTER_STAT(WEAPONSINMAP, vectori)
+
+ REGISTER_STAT(PL_VIEW_OFS, vector, autocvar_sv_player_viewoffset)
+ REGISTER_STAT(PL_CROUCH_VIEW_OFS, vector, autocvar_sv_player_crouch_viewoffset)
+
+ REGISTER_STAT(PL_MIN, vector, autocvar_sv_player_mins)
+ REGISTER_STAT(PL_CROUCH_MIN, vector, autocvar_sv_player_crouch_mins)
+
+ REGISTER_STAT(PL_MAX, vector, autocvar_sv_player_maxs)
+ REGISTER_STAT(PL_CROUCH_MAX, vector, autocvar_sv_player_crouch_maxs)
+
+ REGISTER_STAT(KH_KEYS, int)
++
+ /** weapon requested to switch to; next WANTED weapon (for HUD) */
+ REGISTER_STAT(SWITCHWEAPON, int)
++/** weapon currently being switched to (is copied from switchweapon once switch is possible) */
++REGISTER_STAT(SWITCHINGWEAPON, int)
++REGISTER_STAT(WEAPON_NEXTTHINK, float)
++
+ REGISTER_STAT(GAMESTARTTIME, float)
+ REGISTER_STAT(STRENGTH_FINISHED, float)
+ REGISTER_STAT(INVINCIBLE_FINISHED, float)
+ /** arc heat in [0,1] */
+ REGISTER_STAT(ARC_HEAT, float)
+ REGISTER_STAT(PRESSED_KEYS, int)
+ /** this stat could later contain some other bits of info, like, more server-side particle config */
+ REGISTER_STAT(ALLOW_OLDVORTEXBEAM, bool)
+ REGISTER_STAT(FUEL, int)
+ REGISTER_STAT(NB_METERSTART, float)
+ /** compressShotOrigin */
+ REGISTER_STAT(SHOTORG, int)
+ REGISTER_STAT(LEADLIMIT, float)
+ REGISTER_STAT(WEAPON_CLIPLOAD, int)
+ REGISTER_STAT(WEAPON_CLIPSIZE, int)
+
+ REGISTER_STAT(VORTEX_CHARGE, float)
+ REGISTER_STAT(LAST_PICKUP, float)
+ REGISTER_STAT(HUD, int)
+ REGISTER_STAT(VORTEX_CHARGEPOOL, float)
+ REGISTER_STAT(HIT_TIME, float)
+ REGISTER_STAT(DAMAGE_DEALT_TOTAL, int)
+ REGISTER_STAT(TYPEHIT_TIME, float)
+ REGISTER_STAT(LAYED_MINES, int)
+ REGISTER_STAT(HAGAR_LOAD, int)
-REGISTER_STAT(SWITCHINGWEAPON, int)
+ REGISTER_STAT(SUPERWEAPONS_FINISHED, float)
+ REGISTER_STAT(VEHICLESTAT_HEALTH, int)
+ REGISTER_STAT(VEHICLESTAT_SHIELD, int)
+ REGISTER_STAT(VEHICLESTAT_ENERGY, int)
+ REGISTER_STAT(VEHICLESTAT_AMMO1, int)
+ REGISTER_STAT(VEHICLESTAT_RELOAD1, int)
+ REGISTER_STAT(VEHICLESTAT_AMMO2, int)
+ REGISTER_STAT(VEHICLESTAT_RELOAD2, int)
+ REGISTER_STAT(VEHICLESTAT_W2MODE, int)
+ REGISTER_STAT(NADE_TIMER, float)
+ REGISTER_STAT(SECRETS_TOTAL, float)
+ REGISTER_STAT(SECRETS_FOUND, float)
+ REGISTER_STAT(RESPAWN_TIME, float)
+ REGISTER_STAT(ROUNDSTARTTIME, float)
+ REGISTER_STAT(MONSTERS_TOTAL, int)
+ REGISTER_STAT(MONSTERS_KILLED, int)
+ REGISTER_STAT(BUFFS, int)
+ REGISTER_STAT(NADE_BONUS, float)
+ REGISTER_STAT(NADE_BONUS_TYPE, int)
+ REGISTER_STAT(NADE_BONUS_SCORE, float)
+ REGISTER_STAT(HEALING_ORB, float)
+ REGISTER_STAT(HEALING_ORB_ALPHA, float)
+ REGISTER_STAT(PLASMA, int)
+ REGISTER_STAT(OK_AMMO_CHARGE, float)
+ REGISTER_STAT(OK_AMMO_CHARGEPOOL, float)
+ REGISTER_STAT(FROZEN, int)
+ REGISTER_STAT(REVIVE_PROGRESS, float)
+ REGISTER_STAT(ROUNDLOST, int)
+ REGISTER_STAT(BUFF_TIME, float)
+ REGISTER_STAT(CTF_FLAGSTATUS, int)
+
+ #ifdef SVQC
+ int autocvar_g_multijump;
+ float autocvar_g_multijump_add;
+ float autocvar_g_multijump_speed;
+ float autocvar_g_multijump_maxspeed;
+ float autocvar_g_multijump_dodging = 1;
+ #endif
+ REGISTER_STAT(MULTIJUMP_DODGING, int, autocvar_g_multijump_dodging)
+ REGISTER_STAT(MULTIJUMP_MAXSPEED, float, autocvar_g_multijump_maxspeed)
+ REGISTER_STAT(MULTIJUMP_ADD, int, autocvar_g_multijump_add)
+ REGISTER_STAT(MULTIJUMP_SPEED, float, autocvar_g_multijump_speed)
+ .int multijump_count;
+ REGISTER_STAT(MULTIJUMP_COUNT, int, this.multijump_count)
+ REGISTER_STAT(MULTIJUMP, int, autocvar_g_multijump)
+ REGISTER_STAT(DOUBLEJUMP, int, autocvar_sv_doublejump)
+
+ #ifdef SVQC
+ bool g_bugrigs;
+ bool g_bugrigs_planar_movement;
+ bool g_bugrigs_planar_movement_car_jumping;
+ float g_bugrigs_reverse_spinning;
+ float g_bugrigs_reverse_speeding;
+ float g_bugrigs_reverse_stopping;
+ float g_bugrigs_air_steering;
+ float g_bugrigs_angle_smoothing;
+ float g_bugrigs_friction_floor;
+ float g_bugrigs_friction_brake;
+ float g_bugrigs_friction_air;
+ float g_bugrigs_accel;
+ float g_bugrigs_speed_ref;
+ float g_bugrigs_speed_pow;
+ float g_bugrigs_steer;
+ #endif
+ REGISTER_STAT(BUGRIGS, int, g_bugrigs)
+ REGISTER_STAT(BUGRIGS_ACCEL, float, g_bugrigs_accel)
+ REGISTER_STAT(BUGRIGS_AIR_STEERING, int, g_bugrigs_air_steering)
+ REGISTER_STAT(BUGRIGS_ANGLE_SMOOTHING, int, g_bugrigs_angle_smoothing)
+ REGISTER_STAT(BUGRIGS_CAR_JUMPING, int, g_bugrigs_planar_movement_car_jumping)
+ REGISTER_STAT(BUGRIGS_FRICTION_AIR, float, g_bugrigs_friction_air)
+ REGISTER_STAT(BUGRIGS_FRICTION_BRAKE, float, g_bugrigs_friction_brake)
+ REGISTER_STAT(BUGRIGS_FRICTION_FLOOR, float, g_bugrigs_friction_floor)
+ REGISTER_STAT(BUGRIGS_PLANAR_MOVEMENT, int, g_bugrigs_planar_movement)
+ REGISTER_STAT(BUGRIGS_REVERSE_SPEEDING, int, g_bugrigs_reverse_speeding)
+ REGISTER_STAT(BUGRIGS_REVERSE_SPINNING, int, g_bugrigs_reverse_spinning)
+ REGISTER_STAT(BUGRIGS_REVERSE_STOPPING, int, g_bugrigs_reverse_stopping)
+ REGISTER_STAT(BUGRIGS_SPEED_POW, float, g_bugrigs_speed_pow)
+ REGISTER_STAT(BUGRIGS_SPEED_REF, float, g_bugrigs_speed_ref)
+ REGISTER_STAT(BUGRIGS_STEER, float, g_bugrigs_steer)
+
+ REGISTER_STAT(GAMEPLAYFIX_DOWNTRACEONGROUND, int, cvar("sv_gameplayfix_downtracesupportsongroundflag"))
+ REGISTER_STAT(GAMEPLAYFIX_EASIERWATERJUMP, int, cvar("sv_gameplayfix_easierwaterjump"))
+ REGISTER_STAT(GAMEPLAYFIX_STEPDOWN, int, cvar("sv_gameplayfix_stepdown"))
+ REGISTER_STAT(GAMEPLAYFIX_STEPMULTIPLETIMES, int, cvar("sv_gameplayfix_stepmultipletimes"))
+ REGISTER_STAT(GAMEPLAYFIX_UNSTICKPLAYERS, int, cvar("sv_gameplayfix_unstickplayers"))
+ REGISTER_STAT(GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND, int, autocvar_sv_gameplayfix_upwardvelocityclearsongroundflag)
+
+ REGISTER_STAT(MOVEVARS_JUMPSTEP, int, cvar("sv_jumpstep"))
+ REGISTER_STAT(NOSTEP, int, cvar("sv_nostep"))
+
+ REGISTER_STAT(MOVEVARS_FRICTION, float)
+ REGISTER_STAT(MOVEVARS_FRICTION_SLICK, float, autocvar_sv_friction_slick)
+ REGISTER_STAT(MOVEVARS_FRICTION_ONLAND, float, autocvar_sv_friction_on_land)
+
+ REGISTER_STAT(MOVEVARS_JUMPSPEEDCAP_DISABLE_ONRAMPS, int, autocvar_sv_jumpspeedcap_max_disable_on_ramps)
+ REGISTER_STAT(MOVEVARS_TRACK_CANJUMP, int)
+ /** cvar loopback */
+ REGISTER_STAT(MOVEVARS_CL_TRACK_CANJUMP, int)
+
+ #ifdef SVQC
+ int g_dodging;
+ float autocvar_sv_dodging_delay;
+ float autocvar_sv_dodging_wall_distance_threshold;
+ bool autocvar_sv_dodging_frozen;
+ bool autocvar_sv_dodging_frozen_doubletap;
+ float autocvar_sv_dodging_height_threshold;
+ float autocvar_sv_dodging_horiz_speed;
+ float autocvar_sv_dodging_horiz_speed_frozen;
+ float autocvar_sv_dodging_ramp_time;
+ float autocvar_sv_dodging_up_speed;
+ bool autocvar_sv_dodging_wall_dodging;
+ #endif
+
+ REGISTER_STAT(DODGING, int, g_dodging)
+ REGISTER_STAT(DODGING_DELAY, float, autocvar_sv_dodging_delay)
+ REGISTER_STAT(DODGING_DISTANCE_THRESHOLD, float, autocvar_sv_dodging_wall_distance_threshold)
+ REGISTER_STAT(DODGING_FROZEN, int, autocvar_sv_dodging_frozen)
+ REGISTER_STAT(DODGING_FROZEN_NO_DOUBLETAP, int, autocvar_sv_dodging_frozen_doubletap)
+ REGISTER_STAT(DODGING_HEIGHT_THRESHOLD, float, autocvar_sv_dodging_height_threshold)
+ REGISTER_STAT(DODGING_HORIZ_SPEED, float, autocvar_sv_dodging_horiz_speed)
+ REGISTER_STAT(DODGING_HORIZ_SPEED_FROZEN, float, autocvar_sv_dodging_horiz_speed_frozen)
+ REGISTER_STAT(DODGING_RAMP_TIME, float, autocvar_sv_dodging_ramp_time)
+ /** cvar loopback */
+ REGISTER_STAT(DODGING_TIMEOUT, float)
+ REGISTER_STAT(DODGING_UP_SPEED, float, autocvar_sv_dodging_up_speed)
+ REGISTER_STAT(DODGING_WALL, int, autocvar_sv_dodging_wall_dodging)
+
+ REGISTER_STAT(JETPACK_ACCEL_SIDE, float, autocvar_g_jetpack_acceleration_side)
+ REGISTER_STAT(JETPACK_ACCEL_UP, float, autocvar_g_jetpack_acceleration_up)
+ REGISTER_STAT(JETPACK_ANTIGRAVITY, float, autocvar_g_jetpack_antigravity)
+ REGISTER_STAT(JETPACK_FUEL, float, autocvar_g_jetpack_fuel)
+ REGISTER_STAT(JETPACK_MAXSPEED_SIDE, float, autocvar_g_jetpack_maxspeed_side)
+ REGISTER_STAT(JETPACK_MAXSPEED_UP, float, autocvar_g_jetpack_maxspeed_up)
- /* The following stats change depending on the gamemode, so can share the same ID */
- // IDs 100 to 104 reserved for gamemodes
+ REGISTER_STAT(MOVEVARS_HIGHSPEED, float, autocvar_g_movement_highspeed)
- // freeze tag, clan arena, jailbreak
- const int STAT_REDALIVE = 100;
- const int STAT_BLUEALIVE = 101;
- const int STAT_YELLOWALIVE = 102;
- const int STAT_PINKALIVE = 103;
+ // freeze tag, clan arena
+ REGISTER_STAT(REDALIVE, int)
+ REGISTER_STAT(BLUEALIVE, int)
+ REGISTER_STAT(YELLOWALIVE, int)
+ REGISTER_STAT(PINKALIVE, int)
// domination
- const int STAT_DOM_TOTAL_PPS = 100;
- const int STAT_DOM_PPS_RED = 101;
- const int STAT_DOM_PPS_BLUE = 102;
- const int STAT_DOM_PPS_YELLOW = 103;
- const int STAT_DOM_PPS_PINK = 104;
+ REGISTER_STAT(DOM_TOTAL_PPS, float)
+ REGISTER_STAT(DOM_PPS_RED, float)
+ REGISTER_STAT(DOM_PPS_BLUE, float)
+ REGISTER_STAT(DOM_PPS_YELLOW, float)
+ REGISTER_STAT(DOM_PPS_PINK, float)
- // vip
- const int STAT_VIP = 100;
- const int STAT_VIP_RED = 101;
- const int STAT_VIP_BLUE = 102;
- const int STAT_VIP_YELLOW = 103;
- const int STAT_VIP_PINK = 104;
+ REGISTER_STAT(TELEPORT_MAXSPEED, float, autocvar_g_teleport_maxspeed)
+ REGISTER_STAT(TELEPORT_TELEFRAG_AVOID, int, autocvar_g_telefrags_avoid)
- // key hunt
- const int STAT_KH_REDKEY_TEAM = 100;
- const int STAT_KH_BLUEKEY_TEAM = 101;
- const int STAT_KH_YELLOWKEY_TEAM = 102;
- const int STAT_KH_PINKKEY_TEAM = 103;
+ #ifdef SVQC
+ #include "movetypes/movetypes.qh"
+ #endif
+
+ REGISTER_STAT(MOVEVARS_AIRACCEL_QW_STRETCHFACTOR, float)
+ REGISTER_STAT(MOVEVARS_AIRCONTROL_PENALTY, float)
+ REGISTER_STAT(MOVEVARS_AIRSPEEDLIMIT_NONQW, float)
+ REGISTER_STAT(MOVEVARS_AIRSTRAFEACCEL_QW, float)
+ REGISTER_STAT(MOVEVARS_AIRCONTROL_POWER, float)
+ noref bool autocvar_sv_gameplayfix_nogravityonground;
+ REGISTER_STAT(MOVEFLAGS, int, MOVEFLAG_VALID
+ | (autocvar_sv_gameplayfix_q2airaccelerate ? MOVEFLAG_Q2AIRACCELERATE : 0)
+ | (autocvar_sv_gameplayfix_nogravityonground ? MOVEFLAG_NOGRAVITYONGROUND : 0)
+ | (autocvar_sv_gameplayfix_gravityunaffectedbyticrate ? MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE : 0))
- /* Gamemode-specific stats end here */
+ REGISTER_STAT(MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL, float)
+ REGISTER_STAT(MOVEVARS_WARSOWBUNNY_ACCEL, float)
+ REGISTER_STAT(MOVEVARS_WARSOWBUNNY_TOPSPEED, float)
+ REGISTER_STAT(MOVEVARS_WARSOWBUNNY_TURNACCEL, float)
+ REGISTER_STAT(MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO, float)
- const int STAT_PL_VIEW_OFS1 = 105;
- const int STAT_PL_VIEW_OFS2 = 106;
- const int STAT_PL_VIEW_OFS3 = 107;
- const int STAT_PL_MIN1 = 108;
- const int STAT_PL_MIN2 = 109;
- const int STAT_PL_MIN3 = 110;
- const int STAT_PL_MAX1 = 111;
- const int STAT_PL_MAX2 = 112;
- const int STAT_PL_MAX3 = 113;
- const int STAT_PL_CROUCH_MIN1 = 114;
- const int STAT_PL_CROUCH_MIN2 = 115;
- const int STAT_PL_CROUCH_MIN3 = 116;
- const int STAT_PL_CROUCH_MAX1 = 117;
- const int STAT_PL_CROUCH_MAX2 = 118;
- const int STAT_PL_CROUCH_MAX3 = 119;
- const int STAT_PL_CROUCH_VIEW_OFS1 = 117;
- const int STAT_PL_CROUCH_VIEW_OFS2 = 118;
- const int STAT_PL_CROUCH_VIEW_OFS3 = 119;
- const int STAT_WEAPONSINMAP = 120;
- const int STAT_WEAPONSINMAP2 = 121;
- const int STAT_WEAPONSINMAP3 = 122;
- const int STAT_BUFF_TIME = 123;
- const int STAT_CTF_FLAGSTATUS = 124;
- // 125 empty?
- // 126 empty?
- // 127 empty?
- // 128 empty?
- // 129 empty?
- // 130 empty?
- // 131 empty?
- // 132 empty?
- // 133 empty?
- // 134 empty?
- // 135 empty?
- // 136 empty?
- // 137 empty?
- // 138 empty?
- // 139 empty?
- // 140 reserved
- // 141 reserved
- // 142 reserved
- // 143 reserved
- // 144 reserved
- // 145 reserved
- // 146 reserved
- // 147 reserved
- // 148 reserved
- // 149 reserved
- // 150 reserved
- // 151 reserved
- // 152 reserved
- // 153 reserved
- // 154 reserved
- // 155 reserved
- // 156 empty?
- // 157 empty?
- // 158 empty?
- // 159 empty?
- // 160 empty?
- // 161 empty?
- // 162 empty?
- // 162 empty?
- // 163 empty?
- // 164 empty?
- // 165 empty?
- const int STAT_MULTIJUMP_DODGING = 166;
- const int STAT_MULTIJUMP_MAXSPEED = 167;
- const int STAT_GAMEPLAYFIX_UPVELOCITYCLEARSONGROUND = 168;
- const int STAT_BUGRIGS_REVERSE_STOPPING = 169;
- const int STAT_BUGRIGS_REVERSE_SPINNING = 170;
- const int STAT_BUGRIGS_CAR_JUMPING = 171;
- const int STAT_BUGRIGS_FRICTION_AIR = 172;
- const int STAT_BUGRIGS_STEER = 173;
- const int STAT_BUGRIGS_SPEED_POW = 174;
- const int STAT_BUGRIGS_SPEED_REF = 175;
- const int STAT_BUGRIGS_ACCEL = 176;
- const int STAT_BUGRIGS_FRICTION_BRAKE = 177;
- const int STAT_BUGRIGS_AIR_STEERING = 178;
- const int STAT_BUGRIGS_FRICTION_FLOOR = 179;
- const int STAT_BUGRIGS_REVERSE_SPEEDING = 180;
- const int STAT_BUGRIGS_PLANAR_MOVEMENT = 181;
- const int STAT_BUGRIGS_ANGLE_SMOOTHING = 182;
- const int STAT_BUGRIGS = 183;
- const int STAT_GAMEPLAYFIX_STEPDOWN = 184;
- const int STAT_MOVEVARS_JUMPSTEP = 185;
- const int STAT_NOSTEP = 186;
- const int STAT_GAMEPLAYFIX_UNSTICKPLAYERS = 187;
- const int STAT_GAMEPLAYFIX_STEPMULTIPLETIMES = 188;
- const int STAT_GAMEPLAYFIX_DOWNTRACEONGROUND = 189;
- const int STAT_GAMEPLAYFIX_EASIERWATERJUMP = 190;
- const int STAT_MOVEVARS_FRICTION_SLICK = 191;
- const int STAT_MOVEVARS_FRICTION_ONLAND = 192;
- const int STAT_MOVEVARS_JUMPSPEEDCAP_DISABLE_ONRAMPS = 193;
- const int STAT_MOVEVARS_TRACK_CANJUMP = 194;
- // 195 empty?
- const int STAT_DOUBLEJUMP = 196;
- const int STAT_MOVEVARS_CL_TRACK_CANJUMP = 197;
- const int STAT_MULTIJUMP_ADD = 198;
- const int STAT_MULTIJUMP_SPEED = 199;
- const int STAT_MULTIJUMP = 200;
- const int STAT_DODGING_TIMEOUT = 201;
- const int STAT_DODGING_WALL = 202;
- const int STAT_DODGING_UP_SPEED = 203;
- const int STAT_DODGING_RAMP_TIME = 204;
- const int STAT_DODGING_HEIGHT_THRESHOLD = 205;
- const int STAT_DODGING_DISTANCE_THRESHOLD = 206;
- const int STAT_DODGING_HORIZ_SPEED = 207;
- const int STAT_DODGING_DELAY = 208;
- const int STAT_DODGING_FROZEN_NO_DOUBLETAP = 209;
- const int STAT_DODGING_HORIZ_SPEED_FROZEN = 210;
- const int STAT_DODGING = 211;
- const int STAT_DODGING_FROZEN = 212;
- const int STAT_JETPACK_MAXSPEED_UP = 213;
- const int STAT_JETPACK_MAXSPEED_SIDE = 214;
- const int STAT_JETPACK_FUEL = 215;
- const int STAT_JETPACK_ANTIGRAVITY = 216;
- const int STAT_JETPACK_ACCEL_SIDE = 217;
- const int STAT_JETPACK_ACCEL_UP = 218;
- const int STAT_MOVEVARS_HIGHSPEED = 219;
- const int STAT_MOVEVARS_AIRACCEL_QW_STRETCHFACTOR = 220;
- const int STAT_MOVEVARS_AIRCONTROL_PENALTY = 221;
- const int STAT_MOVEVARS_AIRSPEEDLIMIT_NONQW = 222;
- const int STAT_MOVEVARS_AIRSTRAFEACCEL_QW = 223;
- const int STAT_MOVEVARS_AIRCONTROL_POWER = 224;
- const int STAT_MOVEFLAGS = 225;
- const int STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL = 226;
- const int STAT_MOVEVARS_WARSOWBUNNY_ACCEL = 227;
- const int STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED = 228;
- const int STAT_MOVEVARS_WARSOWBUNNY_TURNACCEL = 229;
- const int STAT_MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO = 230;
- const int STAT_MOVEVARS_AIRSTOPACCELERATE = 231;
- const int STAT_MOVEVARS_AIRSTRAFEACCELERATE = 232;
- const int STAT_MOVEVARS_MAXAIRSTRAFESPEED = 233;
- const int STAT_MOVEVARS_AIRCONTROL = 234;
- // -Wdouble-declaration
- // const int STAT_FRAGLIMIT = 235;
- // -Wdouble-declaration
- // const int STAT_TIMELIMIT = 236;
- const int STAT_MOVEVARS_WALLFRICTION = 237;
- const int STAT_MOVEVARS_FRICTION = 238;
- const int STAT_MOVEVARS_WATERFRICTION = 239;
- // -Wdouble-declaration
- // const int STAT_MOVEVARS_TICRATE = 240;
- // -Wdouble-declaration
- // const int STAT_MOVEVARS_TIMESCALE = 241;
- // -Wdouble-declaration
- // const int STAT_MOVEVARS_GRAVITY = 242;
- const int STAT_MOVEVARS_STOPSPEED = 243;
- const int STAT_MOVEVARS_MAXSPEED = 244;
- const int STAT_MOVEVARS_SPECTATORMAXSPEED = 245;
- const int STAT_MOVEVARS_ACCELERATE = 246;
- const int STAT_MOVEVARS_AIRACCELERATE = 247;
- const int STAT_MOVEVARS_WATERACCELERATE = 248;
- const int STAT_MOVEVARS_ENTGRAVITY = 249;
- const int STAT_MOVEVARS_JUMPVELOCITY = 250;
- const int STAT_MOVEVARS_EDGEFRICTION = 251;
- const int STAT_MOVEVARS_MAXAIRSPEED = 252;
- const int STAT_MOVEVARS_STEPHEIGHT = 253;
- const int STAT_MOVEVARS_AIRACCEL_QW = 254;
- const int STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION = 255;
+ REGISTER_STAT(MOVEVARS_AIRSTOPACCELERATE, float)
+ REGISTER_STAT(MOVEVARS_AIRSTRAFEACCELERATE, float)
+ REGISTER_STAT(MOVEVARS_MAXAIRSTRAFESPEED, float)
+ REGISTER_STAT(MOVEVARS_AIRCONTROL, float)
+ REGISTER_STAT(FRAGLIMIT, float, autocvar_fraglimit)
+ REGISTER_STAT(TIMELIMIT, float, autocvar_timelimit)
+ #ifdef SVQC
+ float autocvar_sv_wallfriction;
+ #endif
+ REGISTER_STAT(MOVEVARS_WALLFRICTION, int, autocvar_sv_wallfriction)
+ REGISTER_STAT(MOVEVARS_TICRATE, float, autocvar_sys_ticrate)
+ REGISTER_STAT(MOVEVARS_TIMESCALE, float, autocvar_slowmo)
+ REGISTER_STAT(MOVEVARS_GRAVITY, float, autocvar_sv_gravity)
+ REGISTER_STAT(MOVEVARS_STOPSPEED, float)
+ REGISTER_STAT(MOVEVARS_MAXSPEED, float)
+ REGISTER_STAT(MOVEVARS_ACCELERATE, float)
+ REGISTER_STAT(MOVEVARS_AIRACCELERATE, float)
+ .float gravity;
+ // FIXME: Was 0 on server, 1 on client. Still want that?
+ REGISTER_STAT(MOVEVARS_ENTGRAVITY, float, (this.gravity) ? this.gravity : 1)
+ REGISTER_STAT(MOVEVARS_JUMPVELOCITY, float)
+ REGISTER_STAT(MOVEVARS_MAXAIRSPEED, float)
+ REGISTER_STAT(MOVEVARS_STEPHEIGHT, float, autocvar_sv_stepheight)
+ REGISTER_STAT(MOVEVARS_AIRACCEL_QW, float)
+ REGISTER_STAT(MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, float)
#endif
#elif defined(CSQC)
- void _Movetype_LinkEdict(float touch_triggers);
+ void _Movetype_LinkEdict(entity this, float touch_triggers);
#define SUB_ANGLES(s) (s).move_angles
#define SUB_VELOCITY move_velocity
void SUB_SETORIGIN(entity s, vector v)
{SELFPARAM();
s.move_origin = v;
- WITH(entity, self, s, _Movetype_LinkEdict(true));
+ _Movetype_LinkEdict(s, true);
}
#endif
- void SUB_Remove();
void SUB_SetFade (entity ent, float when, float fading_time);
void SUB_VanishOrRemove (entity ent);
.vector destvec;
.vector destvec2;
-// player animation state
-.float animstate_startframe;
-.float animstate_numframes;
-.float animstate_framerate;
-.float animstate_starttime;
-.float animstate_endtime;
-.float animstate_override;
-.float animstate_looping;
-
.float delay;
.float wait;
.float lip;
#include "../../lib/warpzone/common.qh"
#include "../../lib/warpzone/client.qh"
#include "../util.qh"
- #include "../buffs/all.qh"
#include "../../client/autocvars.qh"
#include "../deathtypes/all.qh"
#include "../../lib/csqcmodel/interpolate.qh"
#include "../../lib/csqcmodel/cl_model.qh"
#elif defined(MENUQC)
#elif defined(SVQC)
- #include "../../lib/warpzone/anglestransform.qh"
- #include "../../lib/warpzone/common.qh"
- #include "../../lib/warpzone/util_server.qh"
- #include "../../lib/warpzone/server.qh"
- #include "../constants.qh"
- #include "../stats.qh"
- #include "../teams.qh"
- #include "../util.qh"
- #include "../buffs/all.qh"
- #include "../monsters/all.qh"
- #include "config.qh"
- #include "../../server/weapons/csqcprojectile.qh"
- #include "../../server/weapons/tracing.qh"
- #include "../../server/t_items.qh"
- #include "../../server/autocvars.qh"
- #include "../../server/constants.qh"
- #include "../../server/defs.qh"
- #include "../notifications.qh"
- #include "../deathtypes/all.qh"
- #include "../../server/mutators/all.qh"
- #include "../mapinfo.qh"
- #include "../../server/command/common.qh"
- #include "../../lib/csqcmodel/sv_model.qh"
- #include "../../server/portals.qh"
- #include "../../server/g_hook.qh"
+ #include "../../lib/warpzone/anglestransform.qh"
+ #include "../../lib/warpzone/common.qh"
+ #include "../../lib/warpzone/util_server.qh"
+ #include "../../lib/warpzone/server.qh"
+ #include "../constants.qh"
+ #include "../stats.qh"
+ #include "../teams.qh"
+ #include "../util.qh"
+ #include "../monsters/all.qh"
+ #include "config.qh"
+ #include "../../server/weapons/csqcprojectile.qh"
+ #include "../../server/weapons/tracing.qh"
+ #include "../../server/t_items.qh"
+ #include "../../server/autocvars.qh"
+ #include "../../server/constants.qh"
+ #include "../../server/defs.qh"
+ #include "../notifications.qh"
+ #include "../deathtypes/all.qh"
+ #include "../../server/mutators/all.qh"
+ #include "../mapinfo.qh"
+ #include "../../server/command/common.qh"
+ #include "../../lib/csqcmodel/sv_model.qh"
+ #include "../../server/portals.qh"
+ #include "../../server/g_hook.qh"
#endif
#ifndef MENUQC
-#include "calculations.qc"
+ #include "calculations.qc"
#endif
#define IMPLEMENTATION
#include "all.inc"
// WEAPON PLUGIN SYSTEM
- WepSet WepSet_FromWeapon(int a)
-WepSet _WepSet_FromWeapon(int a) {
++WepSet _WepSet_FromWeapon(int a)
+{
a -= WEP_FIRST;
if (Weapons_MAX > 24)
- if (a >= 24) {
- a -= 24;
- if (Weapons_MAX > 48)
- if (a >= 24) {
+ if (a >= 24)
+ {
a -= 24;
- return '0 0 1' * power2of(a);
+ if (Weapons_MAX > 48)
+ if (a >= 24)
+ {
+ a -= 24;
+ return '0 0 1' * power2of(a);
+ }
+ return '0 1 0' * power2of(a);
}
- return '0 1 0' * power2of(a);
- }
return '1 0 0' * power2of(a);
}
#ifdef SVQC
- void WepSet_AddStat()
- {
- addstat(STAT_WEAPONS, AS_INT, weapons_x);
- if (Weapons_MAX > 24) addstat(STAT_WEAPONS2, AS_INT, weapons_y);
- if (Weapons_MAX > 48) addstat(STAT_WEAPONS3, AS_INT, weapons_z);
- }
- void WepSet_AddStat_InMap()
- {
- addstat(STAT_WEAPONSINMAP, AS_INT, weaponsinmap_x);
- if (Weapons_MAX > 24) addstat(STAT_WEAPONSINMAP2, AS_INT, weaponsinmap_y);
- if (Weapons_MAX > 48) addstat(STAT_WEAPONSINMAP3, AS_INT, weaponsinmap_z);
- }
-void WriteWepSet(float dst, WepSet w)
-{
- if (Weapons_MAX > 48)
- WriteInt72_t(dst, w);
- else if (Weapons_MAX > 24)
- WriteInt48_t(dst, w);
- else
- WriteInt24_t(dst, w.x);
-}
+ void WriteWepSet(float dst, WepSet w)
+ {
+ if (Weapons_MAX > 48) WriteInt72_t(dst, w);
+ else if (Weapons_MAX > 24) WriteInt48_t(dst, w);
+ else WriteInt24_t(dst, w.x);
+ }
#endif
#ifdef CSQC
-WepSet WepSet_GetFromStat()
-{
- return STAT(WEAPONS);
-}
-WepSet WepSet_GetFromStat_InMap()
-{
- return STAT(WEAPONSINMAP);
-}
-WepSet ReadWepSet()
-{
- if (Weapons_MAX > 48)
- return ReadInt72_t();
- if (Weapons_MAX > 24)
- return ReadInt48_t();
- return ReadInt24_t() * '1 0 0';
-}
+ WepSet WepSet_GetFromStat()
+ {
- WepSet w = '0 0 0';
- w.x = getstati(STAT_WEAPONS);
- if (Weapons_MAX > 24) w.y = getstati(STAT_WEAPONS2);
- if (Weapons_MAX > 48) w.z = getstati(STAT_WEAPONS3);
- return w;
++ return STAT(WEAPONS);
+ }
+ WepSet WepSet_GetFromStat_InMap()
+ {
- WepSet w = '0 0 0';
- w_x = getstati(STAT_WEAPONSINMAP);
- if (Weapons_MAX > 24) w_y = getstati(STAT_WEAPONSINMAP2);
- if (Weapons_MAX > 48) w_z = getstati(STAT_WEAPONSINMAP3);
- return w;
++ return STAT(WEAPONSINMAP);
+ }
+ WepSet ReadWepSet()
+ {
+ if (Weapons_MAX > 48) return ReadInt72_t();
+ if (Weapons_MAX > 24) return ReadInt48_t();
+ return ReadInt24_t() * '1 0 0';
+ }
#endif
string W_FixWeaponOrder(string order, float complete)
string W_NameWeaponOrder_MapFunc(string s)
{
entity wi;
- if(s == "0" || stof(s))
+ if (s == "0" || stof(s))
{
wi = get_weaponinfo(stof(s));
- if(wi != WEP_Null)
- return wi.netname;
+ if (wi != WEP_Null) return wi.netname;
}
return s;
}
string W_UndeprecateName(string s)
{
- switch ( s )
+ switch (s)
{
- case "nex" : return "vortex";
- case "rocketlauncher" : return "devastator";
- case "laser" : return "blaster";
- case "minstanex" : return "vaporizer";
+ case "nex": return "vortex";
+ case "rocketlauncher": return "devastator";
+ case "laser": return "blaster";
+ case "minstanex": return "vaporizer";
case "grenadelauncher": return "mortar";
- case "uzi" : return "machinegun";
- default : return s;
+ case "uzi": return "machinegun";
+ default: return s;
}
}
string W_NameWeaponOrder(string order)
string W_NumberWeaponOrder_MapFunc(string s)
{
int i;
- if(s == "0" || stof(s))
- return s;
+ if (s == "0" || stof(s)) return s;
s = W_UndeprecateName(s);
- for(i = WEP_FIRST; i <= WEP_LAST; ++i)
- if(s == get_weaponinfo(i).netname)
- return ftos(i);
+ for (i = WEP_FIRST; i <= WEP_LAST; ++i)
+ if (s == get_weaponinfo(i).netname) return ftos(i);
return s;
}
string W_NumberWeaponOrder(string order)
e1 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[i]);
e2 = get_weaponinfo(W_FixWeaponOrder_BuildImpulseList_buf[j]);
d = (e1.impulse + 9) % 10 - (e2.impulse + 9) % 10;
- if(d != 0)
- return -d; // high impulse first!
- return
- strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[i]), 0)
- -
- strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "), sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[j]), 0)
- ; // low char index first!
+ if (d != 0) return -d; // high impulse first!
+ return strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "),
+ sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[i]), 0)
+ -
+ strstrofs(strcat(" ", W_FixWeaponOrder_BuildImpulseList_order, " "),
+ sprintf(" %d ", W_FixWeaponOrder_BuildImpulseList_buf[j]), 0)
+ ; // low char index first!
}
string W_FixWeaponOrder_BuildImpulseList(string o)
{
int i;
W_FixWeaponOrder_BuildImpulseList_order = o;
- for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+ for (i = WEP_FIRST; i <= WEP_LAST; ++i)
W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST] = i;
- heapsort(WEP_LAST - WEP_FIRST + 1, W_FixWeaponOrder_BuildImpulseList_swap, W_FixWeaponOrder_BuildImpulseList_cmp, world);
+ heapsort(WEP_LAST - WEP_FIRST + 1, W_FixWeaponOrder_BuildImpulseList_swap, W_FixWeaponOrder_BuildImpulseList_cmp,
+ world);
o = "";
- for(i = WEP_FIRST; i <= WEP_LAST; ++i)
+ for (i = WEP_FIRST; i <= WEP_LAST; ++i)
o = strcat(o, " ", ftos(W_FixWeaponOrder_BuildImpulseList_buf[i - WEP_FIRST]));
W_FixWeaponOrder_BuildImpulseList_order = string_null;
return substring(o, 1, -1);
string W_FixWeaponOrder_ForceComplete(string order)
{
- if(order == "")
- order = W_NumberWeaponOrder(cvar_defstring("cl_weaponpriority"));
+ if (order == "") order = W_NumberWeaponOrder(cvar_defstring("cl_weaponpriority"));
return W_FixWeaponOrder(order, 1);
}
WepSet result;
remaining = e.weapons;
result = '0 0 0';
- for(i = 0; i < n; ++i)
+ for (i = 0; i < n; ++i)
{
RandomSelection_Init();
- for(j = WEP_FIRST; j <= WEP_LAST; ++j)
- if(remaining & WepSet_FromWeapon(j))
- RandomSelection_Add(world, j, string_null, 1, 1);
+ for (j = WEP_FIRST; j <= WEP_LAST; ++j)
+ if (remaining & WepSet_FromWeapon(j)) RandomSelection_Add(world, j, string_null, 1, 1);
result |= WepSet_FromWeapon(RandomSelection_chosen_float);
remaining &= ~WepSet_FromWeapon(RandomSelection_chosen_float);
}
case ammo_cells: return ITEM_Cells.m_icon;
case ammo_plasma: return ITEM_Plasma.m_icon;
case ammo_fuel: return ITEM_JetpackFuel.m_icon;
- default: return ""; // wtf, no ammo type?
+ default: return ""; // wtf, no ammo type?
}
}
#ifdef CSQC
-.int GetAmmoFieldFromNum(int i)
-{
- switch(i)
+ .int GetAmmoFieldFromNum(int i)
{
- case 0: return ammo_shells;
- case 1: return ammo_nails;
- case 2: return ammo_rockets;
- case 3: return ammo_cells;
- case 4: return ammo_plasma;
- case 5: return ammo_fuel;
- default: return ammo_none;
+ switch (i)
+ {
+ case 0: return ammo_shells;
+ case 1: return ammo_nails;
+ case 2: return ammo_rockets;
+ case 3: return ammo_cells;
+ case 4: return ammo_plasma;
+ case 5: return ammo_fuel;
+ default: return ammo_none;
+ }
}
-}
-int GetAmmoStat(.int ammotype)
-{
- switch(ammotype)
+ int GetAmmoStat(.int ammotype)
{
- case ammo_shells: return STAT_SHELLS;
- case ammo_nails: return STAT_NAILS;
- case ammo_rockets: return STAT_ROCKETS;
- case ammo_cells: return STAT_CELLS;
- case ammo_plasma: return STAT_PLASMA.m_id;
- case ammo_fuel: return STAT_FUEL.m_id;
- default: return -1;
+ switch (ammotype)
+ {
+ case ammo_shells: return STAT_SHELLS;
+ case ammo_nails: return STAT_NAILS;
+ case ammo_rockets: return STAT_ROCKETS;
+ case ammo_cells: return STAT_CELLS;
- case ammo_plasma: return STAT_PLASMA;
- case ammo_fuel: return STAT_FUEL;
++ case ammo_plasma: return STAT_PLASMA.m_id;
++ case ammo_fuel: return STAT_FUEL.m_id;
+ default: return -1;
+ }
}
-}
#endif
string W_Sound(string w_snd)
{
string output = strcat("weapons/", w_snd);
#ifdef SVQC
- MUTATOR_CALLHOOK(WeaponSound, w_snd, output);
- return weapon_sound_output;
+ MUTATOR_CALLHOOK(WeaponSound, w_snd, output);
+ return weapon_sound_output;
#else
- return output;
+ return output;
#endif
}
{
string output = strcat("models/weapons/", w_mdl);
#ifdef SVQC
- MUTATOR_CALLHOOK(WeaponModel, w_mdl, output);
- return weapon_model_output;
+ MUTATOR_CALLHOOK(WeaponModel, w_mdl, output);
+ return weapon_model_output;
#else
- return output;
+ return output;
+#endif
+}
+
+#ifndef MENUQC
+vector shotorg_adjustfromclient(vector vecs, float y_is_right, float algn)
+{
+ switch (algn)
+ {
+ default:
+ case 3:
+ // right alignment
+ break;
+ case 4:
+ // left
+ vecs.y = -vecs.y;
+ break;
+ case 1:
+ case 2:
+ // center
+ vecs.y = 0;
+ vecs.z -= 2;
+ break;
+ }
+ return vecs;
+}
+
+vector shotorg_adjust_values(vector vecs, bool y_is_right, bool visual, int algn)
+{
+#ifdef SVQC
+ string s;
#endif
+ if (visual)
+ {
+ vecs = shotorg_adjustfromclient(vecs, y_is_right, algn);
+ }
+#ifdef SVQC
+ else if (autocvar_g_shootfromeye)
+ {
+ vecs.y = vecs.z = 0;
+ }
+ else if (autocvar_g_shootfromcenter)
+ {
+ vecs.y = 0;
+ vecs.z -= 2;
+ }
+ else if ((s = autocvar_g_shootfromfixedorigin) != "")
+ {
+ vector v = stov(s);
+ if (y_is_right) v.y = -v.y;
+ if (v.x != 0) vecs.x = v.x;
+ vecs.y = v.y;
+ vecs.z = v.z;
+ }
+#endif
+ else // just do the same as top
+ {
+ vecs = shotorg_adjustfromclient(vecs, y_is_right, algn);
+ }
+
+ return vecs;
}
+#define shotorg_adjust shotorg_adjust_values
+
+/**
+ * supported formats:
+ *
+ * 1. simple animated model, muzzle flash handling on h_ model:
+ * h_tuba.dpm, h_tuba.dpm.framegroups - invisible model controlling the animation
+ * tags:
+ * shot = muzzle end (shot origin, also used for muzzle flashes)
+ * shell = casings ejection point (must be on the right hand side of the gun)
+ * weapon = attachment for v_tuba.md3
+ * v_tuba.md3 - first and third person model
+ * g_tuba.md3 - pickup model
+ *
+ * 2. simple animated model, muzzle flash handling on v_ model:
+ * h_tuba.dpm, h_tuba.dpm.framegroups - invisible model controlling the animation
+ * tags:
+ * weapon = attachment for v_tuba.md3
+ * v_tuba.md3 - first and third person model
+ * tags:
+ * shot = muzzle end (shot origin, also used for muzzle flashes)
+ * shell = casings ejection point (must be on the right hand side of the gun)
+ * g_tuba.md3 - pickup model
+ *
+ * 3. fully animated model, muzzle flash handling on h_ model:
+ * h_tuba.dpm, h_tuba.dpm.framegroups - animated first person model
+ * tags:
+ * shot = muzzle end (shot origin, also used for muzzle flashes)
+ * shell = casings ejection point (must be on the right hand side of the gun)
+ * handle = corresponding to the origin of v_tuba.md3 (used for muzzle flashes)
+ * v_tuba.md3 - third person model
+ * g_tuba.md3 - pickup model
+ *
+ * 4. fully animated model, muzzle flash handling on v_ model:
+ * h_tuba.dpm, h_tuba.dpm.framegroups - animated first person model
+ * tags:
+ * shot = muzzle end (shot origin)
+ * shell = casings ejection point (must be on the right hand side of the gun)
+ * v_tuba.md3 - third person model
+ * tags:
+ * shot = muzzle end (for muzzle flashes)
+ * g_tuba.md3 - pickup model
+ *
+ * writes:
+ * this.origin, this.angles
+ * this.weaponchild
+ * this.movedir, this.view_ofs
+ * attachment stuff
+ * anim stuff
+ * to free:
+ * call again with ""
+ * remove the ent
+ */
+void CL_WeaponEntity_SetModel(entity this, string name)
+{
+ if (name == "")
+ {
+ this.model = "";
+ if (this.weaponchild) remove(this.weaponchild);
+ this.weaponchild = NULL;
+ this.movedir = '0 0 0';
+ this.spawnorigin = '0 0 0';
+ this.oldorigin = '0 0 0';
+ this.anim_fire1 = '0 1 0.01';
+ this.anim_fire2 = '0 1 0.01';
+ this.anim_idle = '0 1 0.01';
+ this.anim_reload = '0 1 0.01';
+ }
+ else
+ {
+ // if there is a child entity, hide it until we're sure we use it
+ if (this.weaponchild) this.weaponchild.model = "";
+ _setmodel(this, W_Model(strcat("v_", name, ".md3")));
+ int v_shot_idx; // used later
+ (v_shot_idx = gettagindex(this, "shot")) || (v_shot_idx = gettagindex(this, "tag_shot"));
+
+ _setmodel(this, W_Model(strcat("h_", name, ".iqm")));
+ // preset some defaults that work great for renamed zym files (which don't need an animinfo)
+ this.anim_fire1 = animfixfps(this, '0 1 0.01', '0 0 0');
+ this.anim_fire2 = animfixfps(this, '1 1 0.01', '0 0 0');
+ this.anim_idle = animfixfps(this, '2 1 0.01', '0 0 0');
+ this.anim_reload = animfixfps(this, '3 1 0.01', '0 0 0');
+
+ // if we have a "weapon" tag, let's attach the v_ model to it ("invisible hand" style model)
+ // if we don't, this is a "real" animated model
+ string t;
+ if ((t = "weapon", gettagindex(this, t)) || (t = "tag_weapon", gettagindex(this, t)))
+ {
+ if (!this.weaponchild)
+ {
+ this.weaponchild = new(weaponchild);
+#ifdef CSQC
+ this.weaponchild.drawmask = MASK_NORMAL;
+ this.weaponchild.renderflags |= RF_VIEWMODEL;
+#endif
+ }
+ _setmodel(this.weaponchild, W_Model(strcat("v_", name, ".md3")));
+ setattachment(this.weaponchild, this, t);
+ }
+ else
+ {
+ if (this.weaponchild) remove(this.weaponchild);
+ this.weaponchild = NULL;
+ }
+
+ setorigin(this, '0 0 0');
+ this.angles = '0 0 0';
+ this.frame = 0;
+#ifdef SVQC
+ this.viewmodelforclient = NULL;
+#else
+ this.renderflags &= ~RF_VIEWMODEL;
+#endif
+ if (v_shot_idx) // v_ model attached to invisible h_ model
+ {
+ this.movedir = gettaginfo(this.weaponchild, v_shot_idx);
+ }
+ else
+ {
+ int idx;
+ if ((idx = gettagindex(this, "shot")) || (idx = gettagindex(this, "tag_shot")))
+ {
+ this.movedir = gettaginfo(this, idx);
+ }
+ else
+ {
+ LOG_WARNINGF("weapon model %s does not support the 'shot' tag, will display shots TOTALLY wrong\n",
+ this.model);
+ this.movedir = '0 0 0';
+ }
+ }
+ {
+ int idx = 0;
+ // v_ model attached to invisible h_ model
+ if (this.weaponchild
+ && ((idx = gettagindex(this.weaponchild, "shell")) || (idx = gettagindex(this.weaponchild, "tag_shell"))))
+ {
+ this.spawnorigin = gettaginfo(this.weaponchild, idx);
+ }
+ else if ((idx = gettagindex(this, "shell")) || (idx = gettagindex(this, "tag_shell")))
+ {
+ this.spawnorigin = gettaginfo(this, idx);
+ }
+ else
+ {
+ LOG_WARNINGF("weapon model %s does not support the 'shell' tag, will display casings wrong\n",
+ this.model);
+ this.spawnorigin = this.movedir;
+ }
+ }
+ if (v_shot_idx)
+ {
+ this.oldorigin = '0 0 0'; // use regular attachment
+ }
+ else
+ {
+ int idx;
+ if (this.weaponchild)
+ (idx = gettagindex(this, "weapon")) || (idx = gettagindex(this, "tag_weapon"));
+ else
+ (idx = gettagindex(this, "handle")) || (idx = gettagindex(this, "tag_handle"));
+ if (idx)
+ {
+ this.oldorigin = this.movedir - gettaginfo(this, idx);
+ }
+ else
+ {
+ LOG_WARNINGF(
+ "weapon model %s does not support the 'handle' tag "
+ "and neither does the v_ model support the 'shot' tag, "
+ "will display muzzle flashes TOTALLY wrong\n",
+ this.model);
+ this.oldorigin = '0 0 0'; // there is no way to recover from this
+ }
+ }
+
+#ifdef SVQC
+ this.viewmodelforclient = this.owner;
+#else
+ this.renderflags |= RF_VIEWMODEL;
+#endif
+ }
+
+ this.view_ofs = '0 0 0';
+
+ if (this.movedir.x >= 0)
+ {
+#ifdef SVQC
+ int algn = this.owner.cvar_cl_gunalign;
+#else
+ int algn = autocvar_cl_gunalign;
+#endif
+ vector v = this.movedir;
+ this.movedir = shotorg_adjust(v, false, false, algn);
+ this.view_ofs = shotorg_adjust(v, false, true, algn) - v;
+ }
+ int compressed_shotorg = compressShotOrigin(this.movedir);
+ // make them match perfectly
+#ifdef SVQC
+ this.movedir = decompressShotOrigin(this.owner.stat_shotorg = compressed_shotorg);
+#else
+ this.movedir = decompressShotOrigin(compressed_shotorg);
+#endif
+
+ this.spawnorigin += this.view_ofs; // offset the casings origin by the same amount
+
+ // check if an instant weapon switch occurred
+ setorigin(this, this.view_ofs);
+ // reset animstate now
+ this.wframe = WFRAME_IDLE;
+ setanim(this, this.anim_idle, true, false, true);
+}
+#endif
+
+#ifndef MENUQC
+
+REGISTER_NET_TEMP(wframe)
+#ifdef CSQC
+NET_HANDLE(wframe, bool isNew)
+{
+ vector a;
+ a.x = ReadCoord();
+ a.y = ReadCoord();
+ a.z = ReadCoord();
+ bool restartanim = ReadByte();
+ anim_set(viewmodel, a, !restartanim, restartanim, restartanim);
+ viewmodel.state = ReadByte();
+ viewmodel.alpha = ReadByte() / 255;
+ return true;
+}
+#endif
+
+#ifdef SVQC
+void wframe_send(entity actor, entity weaponentity, vector a, bool restartanim)
+{
+ if (!IS_REAL_CLIENT(actor)) return;
+ int channel = MSG_ONE;
+ msg_entity = actor;
+ WriteHeader(channel, wframe);
+ WriteCoord(channel, a.x);
+ WriteCoord(channel, a.y);
+ WriteCoord(channel, a.z);
+ WriteByte(channel, restartanim);
+ WriteByte(channel, weaponentity.state);
+ WriteByte(channel, weaponentity.alpha * 255);
+}
+#endif
+
+REGISTER_NET_TEMP(wglow)
+#ifdef CSQC
+NET_HANDLE(wglow, bool isNew)
+{
+ vector g = '0 0 0';
+ g.x = ReadCoord();
+ g.y = ReadCoord();
+ g.z = ReadCoord();
+ viewmodel.glowmod = g;
+ return true;
+}
+#endif
+
+#ifdef SVQC
+void wglow_send(entity actor, vector g)
+{
+ if (!IS_REAL_CLIENT(actor)) return;
+ int channel = MSG_ONE;
+ msg_entity = actor;
+ WriteHeader(channel, wglow);
+ WriteCoord(channel, g.x);
+ WriteCoord(channel, g.y);
+ WriteCoord(channel, g.z);
+}
+#endif
+
+#endif
+
#endif
#define WEAPONS_ALL_H
#include "../command/all.qh"
+ #include "../stats.qh"
#include "config.qh"
// weapon sets
typedef vector WepSet;
- #define WEPSET(id) WepSet_FromWeapon(WEP_##id.m_id)
- WepSet WepSet_FromWeapon(int a);
#ifdef SVQC
- void WepSet_AddStat();
- void WepSet_AddStat_InMap();
void WriteWepSet(float dest, WepSet w);
#endif
REGISTRY(Weapons, 72) // Increase as needed. Can be up to 72.
#define Weapons_from(i) _Weapons_from(i, WEP_Null)
#define get_weaponinfo(i) Weapons_from(i)
- REGISTER_REGISTRY(RegisterWeapons)
+ REGISTER_REGISTRY(Weapons)
STATIC_INIT(WeaponPickup) { FOREACH(Weapons, true, LAMBDA(it.m_pickup = NEW(WeaponPickup, it))); }
+ .WepSet m_wepset;
+ #define WEPSET(id) (WEP_##id.m_wepset)
+ #define WepSet_FromWeapon(i) (Weapons_from(i).m_wepset)
+ WepSet _WepSet_FromWeapon(int i);
+ STATIC_INIT(WepSets)
+ {
+ FOREACH(Weapons, true, LAMBDA(it.m_wepset = _WepSet_FromWeapon(it.m_id)));
+ }
GENERIC_COMMAND(dumpweapons, "Dump all weapons into weapons_dump.txt") // WEAPONTODO: make this work with other progs than just server
{
#define REGISTER_WEAPON(id, inst) \
/* WepSet WEPSET_##id; */ \
- REGISTER(RegisterWeapons, WEP, Weapons, id, m_id, inst)
+ REGISTER(Weapons, WEP, id, m_id, inst)
// create cvars for weapon settings
#define WEP_ADD_CVAR_NONE(wepname,name) [[last]] float autocvar_g_balance_##wepname##_##name;
{
FOREACH(Weapons, true, LAMBDA(
it.m_id = i;
- WepSet set = WepSet_FromWeapon(it.m_id);
+ WepSet set = it.m_wepset;
WEPSET_ALL |= set;
if ((it.spawnflags) & WEP_FLAG_SUPERWEAPON) WEPSET_SUPERWEAPONS |= set;
it.weapon = it.m_id;
weaponorder_byid = strzone(substring(weaponorder_byid, 1, strlen(weaponorder_byid) - 1));
}
- .int switchweapon; // weapon requested to switch to
- .int switchingweapon; // weapon currently being switched to (is copied from switchweapon once switch is possible)
+#ifndef MENUQC
+
+.entity weaponchild;
+.entity exteriorweaponentity;
+.vector weaponentity_glowmod;
+
+//.int weapon; // current weapon
++#ifdef SVQC
++.int switchweapon = _STAT(SWITCHWEAPON);
++.int switchingweapon = _STAT(SWITCHINGWEAPON);
++#endif
+.string weaponname; // name of .weapon
+
+.vector spawnorigin; // for casings
+
+// weapon animation vectors:
+.vector anim_fire1;
+.vector anim_fire2;
+.vector anim_idle;
+.vector anim_reload;
+
+// static frame globals
+
+ENUMCLASS(WFRAME)
+CASE(WFRAME, DONTCHANGE)
+CASE(WFRAME, FIRE1)
+CASE(WFRAME, FIRE2)
+CASE(WFRAME, IDLE)
+CASE(WFRAME, RELOAD)
+ENUMCLASS_END(WFRAME)
+
+.WFRAME wframe;
+
+vector shotorg_adjust_values(vector vecs, bool y_is_right, bool visual, int algn);
+void CL_WeaponEntity_SetModel(entity this, string name);
+#endif
+
#endif
#ifndef WEAPON_H
#define WEAPON_H
#include "../items/item/pickup.qh"
+ #include "../stats.qh"
const int MAX_WEAPONSLOTS = 2;
.entity weaponentities[MAX_WEAPONSLOTS];
return 0;
}
+// weapon states (actor.(weaponentity).state)
+/** no weapon selected */
+const int WS_CLEAR = 0;
+/** raise frame */
+const int WS_RAISE = 1;
+/** deselecting frame */
+const int WS_DROP = 2;
+/** fire state */
+const int WS_INUSE = 3;
+/** idle frame */
+const int WS_READY = 4;
+
+ #ifdef SVQC
+ .int ammo_shells;
+ .int ammo_nails;
+ .int ammo_rockets;
+ .int ammo_cells;
+ .int ammo_plasma = _STAT(PLASMA);
+ .int ammo_fuel = _STAT(FUEL);
+ .int ammo_none;
+ #else
.int ammo_shells;
.int ammo_nails;
.int ammo_rockets;
.int ammo_plasma;
.int ammo_fuel;
.int ammo_none;
+ #endif
/** fields which are explicitly/manually set are marked with "M", fields set automatically are marked with "A" */
CLASS(Weapon, Object)
.float beam_heat; // (beam) amount of heat produced
.float arc_overheat; // (dropped arc/player) time during which it's too hot
.float arc_cooldown; // (dropped arc/player) cooling speed
- .float arc_heat_percent; // (player) arc heat in [0,1] (stat)
+ .float arc_heat_percent = _STAT(ARC_HEAT);
.float arc_smoke_sound;
#endif
#ifdef CSQC
weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, autocvar_g_balance_arc_primary_animtime, w_ready);
else
#endif
- weapon_thinkf(actor, weaponentity, WFRAME_FIRE1, WEP_CVAR(arc, beam_animtime), w_ready);
+ weapon_thinkf(actor, weaponentity, WFRAME_DONTCHANGE, WEP_CVAR(arc, beam_animtime), w_ready);
}
if((!actor.arc_beam) || wasfreed(actor.arc_beam))
if(!self.beam_usevieworigin)
{
- InterpolateOrigin_Do();
+ InterpolateOrigin_Do(self);
}
// origin = beam starting origin
// self.iflags = IFLAG_ORIGIN | IFLAG_ANGLES | IFLAG_V_ANGLE; // why doesn't this work?
self.iflags = IFLAG_ORIGIN;
- InterpolateOrigin_Undo();
+ InterpolateOrigin_Undo(self);
}
if(sf & ARC_SF_START) // starting location
else
{
// use player origin so that third person display still works
- self.origin = getplayerorigin(player_localnum) + ('0 0 1' * getstati(STAT_VIEWHEIGHT));
+ self.origin = entcs_receiver(player_localnum).origin + ('0 0 1' * getstati(STAT_VIEWHEIGHT));
}
}
if(!self.beam_usevieworigin)
{
- InterpolateOrigin_Note();
+ InterpolateOrigin_Note(this);
}
return true;
}
#include "warpzone/mathlib.qc"
#include "accumulate.qh"
+ #include "arraylist.qh"
#include "bits.qh"
#include "bool.qh"
#include "color.qh"
#include "cvar.qh"
#include "defer.qh"
#include "draw.qh"
+#include "enumclass.qh"
#include "file.qh"
#include "functional.qh"
#include "i18n.qh"
#include "noise.qc"
#include "oo.qh"
#include "p2mathlib.qc"
- #include "player.qh"
#include "progname.qh"
#include "random.qc"
#include "registry.qh"
#include "sort.qh"
#include "spawnfunc.qh"
#include "static.qh"
+ #include "stats.qh"
#include "string.qh"
#include "struct.qh"
#include "test.qc"
#ifndef VECTOR_H
#define VECTOR_H
+ noref vector _vlen2;
+ #define vlen2(v) \
+ (_vlen2 = (v), \
+ _vlen2.x * _vlen2.x \
+ + _vlen2.y * _vlen2.y \
+ + _vlen2.z * _vlen2.z)
+
+ noref float _vdist_f;
+ /** Vector distance comparison, avoids sqrt() */
+ #define vdist(v, cmp, f) (vlen2(v) cmp (_vdist_f = (f), _vdist_f * _vdist_f))
+ /*
+ #define vdist(v, cmp, f) (vlen(v) cmp (f))
+ */
+
+ #define cross(a, b) ((a) >< (b))
+ /*
+ vector cross(vector a, vector b)
+ {
+ return
+ '1 0 0' * (a.y * b.z - a.z * b.y)
+ + '0 1 0' * (a.z * b.x - a.x * b.z)
+ + '0 0 1' * (a.x * b.y - a.y * b.x);
+ }
+ */
+
const vector eX = '1 0 0';
const vector eY = '0 1 0';
const vector eZ = '0 0 1';
return v;
}
- float vlen2d(vector v)
- {
- return sqrt(v.x * v.x + v.y * v.y);
- }
-
float vlen_maxnorm2d(vector v)
{
return max(v.x, v.y, -v.x, -v.y);
/** requires the same as boxesoverlap, but is a stronger condition */
float boxinsidebox(vector smins, vector smaxs, vector bmins, vector bmaxs) { return smins.x >= bmins.x && smaxs.x <= bmaxs.x && smins.y >= bmins.y && smaxs.y <= bmaxs.y && smins.z >= bmins.z && smaxs.z <= bmaxs.z; }
+#define PITCH(v) (v).x
+#define YAW(v) (v).y
+#define ROLL(v) (v).z
+
+#define MAKEVECTORS(f, angles, forward, right, up) do { \
+ f(angles); \
+ forward = v_forward; \
+ right = v_right; \
+ up = v_up; \
+} while (0)
- vector vec2(vector v)
- {
- v.z = 0;
- return v;
- }
+ noref vector _vec2;
+ #define vec2(v) (_vec2 = (v), _vec2.z = 0, _vec2)
- vector vec3(float x, float y, float z)
- {
- vector v;
- v.x = x;
- v.y = y;
- v.z = z;
- return v;
- }
+ noref vector _vec3;
+ #define vec3(x, y, z) (_vec3_x = (x), _vec3_y = (y), _vec3_z = (z), _vec3)
vector rotate(vector v, float a)
{
return r;
}
- vector yinvert(vector v)
- {
- v.y = 1 - v.y;
- return v;
- }
+ noref vector _yinvert;
+ #define yinvert(v) (_yinvert = (v), _yinvert.y = 1 - _yinvert.y, _yinvert)
#ifndef MENUQC
vector get_corner_position(entity box, int corner)
#include "anticheat.qh"
#include "cl_impulse.qh"
#include "cl_player.qh"
- #include "ent_cs.qh"
#include "ipban.qh"
#include "miscfunctions.qh"
#include "portals.qh"
#include "bot/bot.qh"
#include "bot/navigation.qh"
+ #include "../common/ent_cs.qh"
#include "../common/vehicles/all.qh"
#include "../common/triggers/teleporters.qh"
precache_model(modelname);
_setmodel(e, modelname);
player_setupanimsformodel();
- UpdatePlayerSounds();
}
/*
self.event_damage = func_null;
}
+ int player_getspecies(entity this)
+ {
+ get_model_parameters(this.model, this.skin);
+ int s = get_model_parameters_species;
+ get_model_parameters(string_null, 0);
+ if (s < 0) return SPECIES_HUMAN;
+ return s;
+ }
+
.float model_randomizer;
void FixPlayermodel(entity player)
{
if(chmdl || oldskin != player.skin) // model or skin has changed
{
- player.species = player_getspecies(); // update species
- UpdatePlayerSounds(); // update skin sounds
+ player.species = player_getspecies(player); // update species
}
if(!teamplay)
this.bot_attack = true;
this.monster_attack = true;
- this.spider_slowness = 0;
-
this.BUTTON_ATCK = this.BUTTON_JUMP = this.BUTTON_ATCK2 = false;
if (this.killcount == FRAGS_SPECTATOR) {
else
stuffcmd(self, "set _teams_available 0\n");
- attach_entcs(self);
+ entcs_attach(self);
bot_relinkplayerlist();
Send_Notification(NOTIF_ONE_ONLY, self, MSG_CENTER, CENTER_MOTD, getwelcomemessage());
}
- if(autocvar_g_bugrigs || (g_weaponarena_weapons == WEPSET(TUBA)))
+ if(g_weaponarena_weapons == WEPSET(TUBA))
stuffcmd(self, "cl_cmd settemp chase_active 1\n");
}
self.model_randomizer = random();
if(IS_REAL_CLIENT(self))
- sv_notice_join();
+ sv_notice_join(self);
for (entity e = world; (e = findfloat(e, init_for_player_needed, 1)); ) {
WITH(entity, self, e, e.init_for_player(this));
bot_clientdisconnect();
- detach_entcs(self);
+ entcs_detach(self);
if(autocvar_sv_eventlog)
GameLogEcho(strcat(":part:", ftos(self.playerid)));
if(self.weaponorder_byimpulse)
strunzone(self.weaponorder_byimpulse);
- ClearPlayerSounds();
-
if(self.personal)
remove(self.personal);
self.switchweapon = spectatee.switchweapon;
self.switchingweapon = spectatee.switchingweapon;
self.weapon = spectatee.weapon;
+ self.weapon_nextthink = spectatee.weapon_nextthink;
self.vortex_charge = spectatee.vortex_charge;
self.vortex_chargepool_ammo = spectatee.vortex_chargepool_ammo;
self.hagar_load = spectatee.hagar_load;
}
+void wglow_send(entity actor, vector g);
+
/*
=============
PlayerPreThink
if(frametime)
{
- if(self.weapon == WEP_VORTEX.m_id && WEP_CVAR(vortex, charge))
+ vector g;
+ if (IS_SPEC(self))
+ {
+ g = self.enemy.weaponentity_glowmod;
+ }
+ else if(self.weapon == WEP_VORTEX.m_id && WEP_CVAR(vortex, charge))
{
- self.weaponentity_glowmod_x = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_half * min(1, self.vortex_charge / WEP_CVAR(vortex, charge_animlimit));
- self.weaponentity_glowmod_y = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_half * min(1, self.vortex_charge / WEP_CVAR(vortex, charge_animlimit));
- self.weaponentity_glowmod_z = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_half * min(1, self.vortex_charge / WEP_CVAR(vortex, charge_animlimit));
+ g.x = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_half * min(1, self.vortex_charge / WEP_CVAR(vortex, charge_animlimit));
+ g.y = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_half * min(1, self.vortex_charge / WEP_CVAR(vortex, charge_animlimit));
+ g.z = autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_half * min(1, self.vortex_charge / WEP_CVAR(vortex, charge_animlimit));
if(self.vortex_charge > WEP_CVAR(vortex, charge_animlimit))
{
- self.weaponentity_glowmod_x = self.weaponentity_glowmod.x + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_full * (self.vortex_charge - WEP_CVAR(vortex, charge_animlimit)) / (1 - WEP_CVAR(vortex, charge_animlimit));
- self.weaponentity_glowmod_y = self.weaponentity_glowmod.y + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_full * (self.vortex_charge - WEP_CVAR(vortex, charge_animlimit)) / (1 - WEP_CVAR(vortex, charge_animlimit));
- self.weaponentity_glowmod_z = self.weaponentity_glowmod.z + autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_full * (self.vortex_charge - WEP_CVAR(vortex, charge_animlimit)) / (1 - WEP_CVAR(vortex, charge_animlimit));
+ g.x += autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_red_full * (self.vortex_charge - WEP_CVAR(vortex, charge_animlimit)) / (1 - WEP_CVAR(vortex, charge_animlimit));
+ g.y += autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_green_full * (self.vortex_charge - WEP_CVAR(vortex, charge_animlimit)) / (1 - WEP_CVAR(vortex, charge_animlimit));
+ g.z += autocvar_g_weapon_charge_colormod_hdrmultiplier * autocvar_g_weapon_charge_colormod_blue_full * (self.vortex_charge - WEP_CVAR(vortex, charge_animlimit)) / (1 - WEP_CVAR(vortex, charge_animlimit));
}
}
else
- self.weaponentity_glowmod = colormapPaletteColor(self.clientcolors & 0x0F, true) * 2;
-
+ g = colormapPaletteColor(self.clientcolors & 0x0F, true) * 2;
+ if (g != self.weaponentity_glowmod)
+ wglow_send(self, self.weaponentity_glowmod = g);
player_powerups();
}
if (!self.crouch)
{
self.crouch = true;
- self.view_ofs = self.stat_pl_crouch_view_ofs;
- setsize (self, self.stat_pl_crouch_min, self.stat_pl_crouch_max);
+ self.view_ofs = STAT(PL_CROUCH_VIEW_OFS, self);
+ setsize (self, STAT(PL_CROUCH_MIN, self), STAT(PL_CROUCH_MAX, self));
// setanim(self, self.anim_duck, false, true, true); // this anim is BROKEN anyway
}
}
{
if (self.crouch)
{
- tracebox(self.origin, self.stat_pl_min, self.stat_pl_max, self.origin, false, self);
+ tracebox(self.origin, STAT(PL_MIN, self), STAT(PL_MAX, self), self.origin, false, self);
if (!trace_startsolid)
{
self.crouch = false;
- self.view_ofs = self.stat_pl_view_ofs;
- setsize (self, self.stat_pl_min, self.stat_pl_max);
+ self.view_ofs = STAT(PL_VIEW_OFS, self);
+ setsize (self, STAT(PL_MIN, self), STAT(PL_MAX, self));
}
}
}
#include "teamplay.qh"
#include "weapons/throwing.qh"
#include "command/common.qh"
+#include "../common/anim.qh"
#include "../common/animdecide.qh"
#include "../common/csqcmodel_settings.qh"
#include "../common/deathtypes/all.qh"
setself(this);
}
- float player_getspecies()
- {SELFPARAM();
- float s;
- get_model_parameters(self.model, self.skin);
- s = get_model_parameters_species;
- get_model_parameters(string_null, 0);
- if(s < 0)
- return SPECIES_HUMAN;
- return s;
- }
-
void player_setupanimsformodel()
{SELFPARAM();
// load animation info
animbits |= ANIMSTATE_DUCK;
animdecide_setstate(self, animbits, false);
animdecide_setimplicitstate(self, (self.flags & FL_ONGROUND));
-
- .entity weaponentity = weaponentities[0]; // TODO: unhardcode
- {
- if (self.(weaponentity))
- {
- updateanim(self.(weaponentity));
- if (!self.(weaponentity).animstate_override)
- setanim(self.(weaponentity), self.(weaponentity).anim_idle, true, false, false);
- }
- }
}
void PlayerCorpseDamage (entity inflictor, entity attacker, float damage, int deathtype, vector hitloc, vector force)
PlayerScore_Add(self, SP_DMGTAKEN, realdmg);
}
}
-
+
bool abot = (IS_BOT_CLIENT(attacker));
bool vbot = (IS_BOT_CLIENT(self));
}
}
- float Say(entity source, float teamsay, entity privatesay, string msgin, float floodcontrol)
- // message "": do not say, just test flood control
- // return value:
- // 1 = accept
- // 0 = reject
- // -1 = fake accept
+ void MoveToTeam(entity client, int team_colour, int type)
+ {
+ int lockteams_backup = lockteams; // backup any team lock
+ lockteams = 0; // disable locked teams
+ TeamchangeFrags(client); // move the players frags
+ SetPlayerColors(client, team_colour - 1); // set the players colour
+ Damage(client, client, client, 100000, DEATH_AUTOTEAMCHANGE.m_id, client.origin, '0 0 0'); // kill the player
+ lockteams = lockteams_backup; // restore the team lock
+ LogTeamchange(client.playerid, client.team, type);
+ }
+
+ /**
+ * message "": do not say, just test flood control
+ * return value:
+ * 1 = accept
+ * 0 = reject
+ * -1 = fake accept
+ */
+ int Say(entity source, float teamsay, entity privatesay, string msgin, bool floodcontrol)
{
string msgstr, colorstr, cmsgstr, namestr, fullmsgstr, sourcemsgstr, fullcmsgstr, sourcecmsgstr, colorprefix;
float flood;
return ret;
}
-
- float GetVoiceMessageVoiceType(string type)
- {
- if(type == "taunt")
- return VOICETYPE_TAUNT;
- if(type == "teamshoot")
- return VOICETYPE_LASTATTACKER;
- return VOICETYPE_TEAMRADIO;
- }
-
- .string GetVoiceMessageSampleField(string type)
- {
- GetPlayerSoundSampleField_notFound = 0;
- switch(type)
- {
- #define _VOICEMSG(m) case #m: return playersound_##m;
- ALLVOICEMSGS
- #undef _VOICEMSG
- }
- GetPlayerSoundSampleField_notFound = 1;
- return playersound_taunt;
- }
-
- .string GetPlayerSoundSampleField(string type)
- {
- GetPlayerSoundSampleField_notFound = 0;
- switch(type)
- {
- #define _VOICEMSG(m) case #m: return playersound_##m;
- ALLPLAYERSOUNDS
- #undef _VOICEMSG
- }
- GetPlayerSoundSampleField_notFound = 1;
- return playersound_taunt;
- }
-
- void PrecacheGlobalSound(string samplestring)
- {
- float n, i;
- tokenize_console(samplestring);
- n = stof(argv(1));
- if(n > 0)
- {
- for(i = 1; i <= n; ++i)
- precache_sound(strcat(argv(0), ftos(i), ".wav"));
- }
- else
- {
- precache_sound(strcat(argv(0), ".wav"));
- }
- }
-
- void PrecachePlayerSounds(string f)
- {
- int fh = fopen(f, FILE_READ);
- if (fh < 0)
- return;
- for (string s; (s = fgets(fh)); )
- {
- int n = tokenize_console(s);
- if (n != 3)
- {
- if (n != 0) LOG_TRACEF("Invalid sound info line: %s\n", s);
- continue;
- }
- PrecacheGlobalSound(strcat(argv(1), " ", argv(2)));
- }
- fclose(fh);
-
- if (!allvoicesamples)
- {
- #define _VOICEMSG(m) allvoicesamples = strcat(allvoicesamples, " ", #m);
- ALLVOICEMSGS
- #undef _VOICEMSG
- allvoicesamples = strzone(substring(allvoicesamples, 1, strlen(allvoicesamples) - 1));
- }
- }
-
- void ClearPlayerSounds()
- {SELFPARAM();
- #define _VOICEMSG(m) if(self.playersound_##m) { strunzone(self.playersound_##m); self.playersound_##m = string_null; }
- ALLPLAYERSOUNDS
- ALLVOICEMSGS
- #undef _VOICEMSG
- }
-
- float LoadPlayerSounds(string f, float first)
- {SELFPARAM();
- float fh;
- string s;
- var .string field;
- fh = fopen(f, FILE_READ);
- if(fh < 0)
- {
- LOG_TRACE("Player sound file not found: ", f, "\n");
- return 0;
- }
- while((s = fgets(fh)))
- {
- if(tokenize_console(s) != 3)
- continue;
- field = GetPlayerSoundSampleField(argv(0));
- if(GetPlayerSoundSampleField_notFound)
- field = GetVoiceMessageSampleField(argv(0));
- if(GetPlayerSoundSampleField_notFound)
- continue;
- if (self.(field))
- strunzone(self.(field));
- self.(field) = strzone(strcat(argv(1), " ", argv(2)));
- }
- fclose(fh);
- return 1;
- }
-
- void UpdatePlayerSounds()
- {SELFPARAM();
- if(self.modelindex == self.modelindex_for_playersound)
- if(self.skin == self.skin_for_playersound)
- return;
- self.modelindex_for_playersound = self.modelindex;
- self.skin_for_playersound = self.skin;
- ClearPlayerSounds();
- LoadPlayerSounds("sound/player/default.sounds", 1);
- if(!autocvar_g_debug_defaultsounds)
- if(!LoadPlayerSounds(get_model_datafilename(self.model, self.skin, "sounds"), 0))
- LoadPlayerSounds(get_model_datafilename(self.model, 0, "sounds"), 0);
- }
-
- void FakeGlobalSound(string sample, float chan, float voicetype)
- {SELFPARAM();
- float n;
- float tauntrand;
-
- if(sample == "")
- return;
-
- tokenize_console(sample);
- n = stof(argv(1));
- if(n > 0)
- sample = strcat(argv(0), ftos(floor(random() * n + 1)), ".wav"); // randomization
- else
- sample = strcat(argv(0), ".wav"); // randomization
-
- switch(voicetype)
- {
- case VOICETYPE_LASTATTACKER_ONLY:
- break;
- case VOICETYPE_LASTATTACKER:
- if(self.pusher)
- {
- msg_entity = self;
- if(IS_REAL_CLIENT(msg_entity))
- soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTEN_NONE);
- }
- break;
- case VOICETYPE_TEAMRADIO:
- msg_entity = self;
- if(msg_entity.cvar_cl_voice_directional == 1)
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_MIN);
- else
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE);
- break;
- case VOICETYPE_AUTOTAUNT:
- if(!sv_autotaunt)
- break;
- if(!sv_taunt)
- break;
- if(autocvar_sv_gentle)
- break;
- tauntrand = random();
- msg_entity = self;
- if (tauntrand < msg_entity.cvar_cl_autotaunt)
- {
- if (msg_entity.cvar_cl_voice_directional >= 1)
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTEN_MAX));
- else
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE);
- }
- break;
- case VOICETYPE_TAUNT:
- if(IS_PLAYER(self))
- if(self.deadflag == DEAD_NO)
- animdecide_setaction(self, ANIMACTION_TAUNT, true);
- if(!sv_taunt)
- break;
- if(autocvar_sv_gentle)
- break;
- msg_entity = self;
- if (msg_entity.cvar_cl_voice_directional >= 1)
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTEN_MAX));
- else
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE);
- break;
- case VOICETYPE_PLAYERSOUND:
- msg_entity = self;
- soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTEN_NORM);
- break;
- default:
- backtrace("Invalid voice type!");
- break;
- }
- }
-
- void GlobalSound(string sample, float chan, float voicetype)
- {SELFPARAM();
- float n;
- float tauntrand;
-
- if(sample == "")
- return;
-
- tokenize_console(sample);
- n = stof(argv(1));
- if(n > 0)
- sample = strcat(argv(0), ftos(floor(random() * n + 1)), ".wav"); // randomization
- else
- sample = strcat(argv(0), ".wav"); // randomization
-
- switch(voicetype)
- {
- case VOICETYPE_LASTATTACKER_ONLY:
- if(self.pusher)
- {
- msg_entity = self.pusher;
- if(IS_REAL_CLIENT(msg_entity))
- {
- if(msg_entity.cvar_cl_voice_directional == 1)
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_MIN);
- else
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE);
- }
- }
- break;
- case VOICETYPE_LASTATTACKER:
- if(self.pusher)
- {
- msg_entity = self.pusher;
- if(IS_REAL_CLIENT(msg_entity))
- {
- if(msg_entity.cvar_cl_voice_directional == 1)
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_MIN);
- else
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE);
- }
- msg_entity = self;
- if(IS_REAL_CLIENT(msg_entity))
- soundto(MSG_ONE, self, chan, sample, VOL_BASE, ATTEN_NONE);
- }
- break;
- case VOICETYPE_TEAMRADIO:
- FOR_EACH_REALCLIENT(msg_entity)
- if(!teamplay || msg_entity.team == self.team)
- {
- if(msg_entity.cvar_cl_voice_directional == 1)
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_MIN);
- else
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE);
- }
- break;
- case VOICETYPE_AUTOTAUNT:
- if(!sv_autotaunt)
- break;
- if(!sv_taunt)
- break;
- if(autocvar_sv_gentle)
- break;
- tauntrand = random();
- FOR_EACH_REALCLIENT(msg_entity)
- if (tauntrand < msg_entity.cvar_cl_autotaunt)
- {
- if (msg_entity.cvar_cl_voice_directional >= 1)
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTEN_MAX));
- else
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE);
- }
- break;
- case VOICETYPE_TAUNT:
- if(IS_PLAYER(self))
- if(self.deadflag == DEAD_NO)
- animdecide_setaction(self, ANIMACTION_TAUNT, true);
- if(!sv_taunt)
- break;
- if(autocvar_sv_gentle)
- break;
- FOR_EACH_REALCLIENT(msg_entity)
- {
- if (msg_entity.cvar_cl_voice_directional >= 1)
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, bound(ATTEN_MIN, msg_entity.cvar_cl_voice_directional_taunt_attenuation, ATTEN_MAX));
- else
- soundto(MSG_ONE, self, chan, sample, VOL_BASEVOICE, ATTEN_NONE);
- }
- break;
- case VOICETYPE_PLAYERSOUND:
- _sound(self, chan, sample, VOL_BASE, ATTEN_NORM);
- break;
- default:
- backtrace("Invalid voice type!");
- break;
- }
- }
-
- void PlayerSound(.string samplefield, float chan, float voicetype)
- {SELFPARAM();
- GlobalSound(self.(samplefield), chan, voicetype);
- }
-
- void VoiceMessage(string type, string msg)
- {SELFPARAM();
- float voicetype, ownteam;
- float flood;
- var .string sample = GetVoiceMessageSampleField(type);
-
- if(GetPlayerSoundSampleField_notFound)
- {
- sprint(self, strcat("Invalid voice. Use one of: ", allvoicesamples, "\n"));
- return;
- }
-
- voicetype = GetVoiceMessageVoiceType(type);
- ownteam = (voicetype == VOICETYPE_TEAMRADIO);
-
- flood = Say(self, ownteam, world, msg, 1);
-
- if (IS_SPEC(self) || IS_OBSERVER(self) || flood < 0)
- FakeGlobalSound(self.(sample), CH_VOICE, voicetype);
- else if (flood > 0)
- GlobalSound(self.(sample), CH_VOICE, voicetype);
- }
-
- void MoveToTeam(entity client, float team_colour, float type)
- {
- float lockteams_backup;
-
- lockteams_backup = lockteams; // backup any team lock
-
- lockteams = 0; // disable locked teams
-
- TeamchangeFrags(client); // move the players frags
- SetPlayerColors(client, team_colour - 1); // set the players colour
- Damage(client, client, client, 100000, DEATH_AUTOTEAMCHANGE.m_id, client.origin, '0 0 0'); // kill the player
-
- lockteams = lockteams_backup; // restore the team lock
-
- LogTeamchange(client.playerid, client.team, type);
- }
#define SERVER_DEFS_H
#include "../common/weapons/all.qh"
+ #include "../common/stats.qh"
#define INDEPENDENT_ATTACK_FINISHED 1
float team1_score, team2_score, team3_score, team4_score;
- float maxclients;
-
// flag set on worldspawn so that the code knows if it is dedicated or not
float server_is_dedicated;
.float pain_frame; //"
.float crouch; // Crouching or not?
- .float strength_finished;
- .float invincible_finished;
- .float superweapons_finished;
+ .float strength_finished = _STAT(STRENGTH_FINISHED);
+ .float invincible_finished = _STAT(INVINCIBLE_FINISHED);
+ .float superweapons_finished = _STAT(SUPERWEAPONS_FINISHED);
.float cnt; // used in too many places
.float count;
.float fade_time;
.float fade_rate;
-// weapon animation vectors:
-.vector anim_fire1;
-.vector anim_fire2;
-.vector anim_idle;
-.vector anim_reload;
-
void() player_setupanimsformodel;
-void setanim(entity e, vector anim, float looping, float override, float restart);
.string mdl;
.entity item_pickupsound_ent;
.entity item_model_ent;
-// definitions for weaponsystem
-// more WEAPONTODO: move these to their proper files
-.entity exteriorweaponentity;
-.vector weaponentity_glowmod;
-
-//.int weapon; // current weapon
-.int switchweapon = _STAT(SWITCHWEAPON);
-.int switchingweapon = _STAT(SWITCHINGWEAPON); // weapon currently being switched to (is copied from switchweapon once switch is possible)
-.string weaponname; // name of .weapon
-
// WEAPONTODO
.float autoswitch;
float client_hasweapon(entity cl, float wpn, float andammo, float complain);
void w_clear(Weapon thiswep, entity actor, .entity weaponentity, int fire);
void w_ready(Weapon thiswep, entity actor, .entity weaponentity, int fire);
// VorteX: standalone think for weapons, so normal think on weaponentity can be reserved by weaponflashes (which needs update even player dies)
--.float weapon_nextthink;
++.float weapon_nextthink = _STAT(WEAPON_NEXTTHINK);
.void(Weapon thiswep, entity actor, .entity weaponentity, int fire) weapon_think;
-// weapon states (self.weaponentity.state)
-const int WS_CLEAR = 0; // no weapon selected
-const int WS_RAISE = 1; // raise frame
-const int WS_DROP = 2; // deselecting frame
-const int WS_INUSE = 3; // fire state
-const int WS_READY = 4; // idle frame
-
// there is 2 weapon tics that can run in one server frame
const int W_TICSPERFRAME = 2;
float playerid_last;
.float noalign; // if set to 1, the item or spawnpoint won't be dropped to the floor
-.vector spawnorigin;
-
.vector death_origin;
.vector killer_origin;
.float cvar_cl_clippedspectating;
.float cvar_cl_autoscreenshot;
.float cvar_cl_jetpack_jump;
- .float cvar_cl_movement_track_canjump;
+ .float cvar_cl_movement_track_canjump = _STAT(MOVEVARS_CL_TRACK_CANJUMP);
.float cvar_cl_newusekeysupported;
.string cvar_g_xonoticversion;
// WEAPONTODO: remove this
WepSet weaponsInMap;
- .WepSet weaponsinmap;
+ #define weapons _STAT(WEAPONS)
+ #define weaponsinmap _STAT(WEAPONSINMAP)
.float respawn_countdown; // next number to count
float next_pingtime;
- // player sounds, voice messages
- // TODO implemented fall and falling
- #define ALLPLAYERSOUNDS \
- _VOICEMSG(death) \
- _VOICEMSG(drown) \
- _VOICEMSG(fall) \
- _VOICEMSG(falling) \
- _VOICEMSG(gasp) \
- _VOICEMSG(jump) \
- _VOICEMSG(pain100) \
- _VOICEMSG(pain25) \
- _VOICEMSG(pain50) \
- _VOICEMSG(pain75)
-
- #define ALLVOICEMSGS \
- _VOICEMSG(attack) \
- _VOICEMSG(attackinfive) \
- _VOICEMSG(coverme) \
- _VOICEMSG(defend) \
- _VOICEMSG(freelance) \
- _VOICEMSG(incoming) \
- _VOICEMSG(meet) \
- _VOICEMSG(needhelp) \
- _VOICEMSG(seenflag) \
- _VOICEMSG(taunt) \
- _VOICEMSG(teamshoot)
-
- #define _VOICEMSG(m) .string playersound_##m;
- ALLPLAYERSOUNDS
- ALLVOICEMSGS
- #undef _VOICEMSG
-
- // reserved sound names for the future (some models lack sounds for them):
- // _VOICEMSG(flagcarriertakingdamage) \
- // _VOICEMSG(getflag) \
- // reserved sound names for the future (ALL models lack sounds for them):
- // _VOICEMSG(affirmative) \
- // _VOICEMSG(attacking) \
- // _VOICEMSG(defending) \
- // _VOICEMSG(roaming) \
- // _VOICEMSG(onmyway) \
- // _VOICEMSG(droppedflag) \
- // _VOICEMSG(negative) \
- // _VOICEMSG(seenenemy) \
- // /**/
-
- string globalsound_fall;
- string globalsound_metalfall;
- string globalsound_step;
- string globalsound_metalstep;
-
- const float VOICETYPE_PLAYERSOUND = 10;
- const float VOICETYPE_TEAMRADIO = 11;
- const float VOICETYPE_LASTATTACKER = 12;
- const float VOICETYPE_LASTATTACKER_ONLY = 13;
- const float VOICETYPE_AUTOTAUNT = 14;
- const float VOICETYPE_TAUNT = 15;
-
- void PrecachePlayerSounds(string f);
- void PrecacheGlobalSound(string samplestring);
- void UpdatePlayerSounds();
- void ClearPlayerSounds();
- void PlayerSound(.string samplefield, float channel, float voicetype);
- void GlobalSound(string samplestring, float channel, float voicetype);
- void FakeGlobalSound(string samplestring, float channel, float voicetype);
- void VoiceMessage(string type, string message);
- float GetPlayerSoundSampleField_notFound;
- .string GetVoiceMessageSampleField(string type);
-
// autotaunt system
.float cvar_cl_autotaunt;
.float cvar_cl_voice_directional;
string clientstuff;
.float phase;
- .int pressedkeys;
+ .int pressedkeys = _STAT(PRESSED_KEYS);
.string fog;
float game_starttime; //point in time when the countdown to game start is over
float round_starttime; //point in time when the countdown to round start is over
- .float stat_game_starttime;
- .float stat_round_starttime;
+ .float stat_game_starttime = _STAT(GAMESTARTTIME);
+ .float stat_round_starttime = _STAT(ROUNDSTARTTIME);
void W_Porto_Remove (entity p);
.string message2;
- .float stat_allow_oldvortexbeam;
+ .bool stat_allow_oldvortexbeam = _STAT(ALLOW_OLDVORTEXBEAM);
// reset to 0 on weapon switch
// may be useful to all weapons
void SUB_DontUseTargets();
void SUB_UseTargets();
- .void() reset; // if set, an entity is reset using this
+ .void(entity this) reset; // if set, an entity is reset using this
.void() reset2; // if set, an entity is reset using this (after calling ALL the reset functions for other entities)
void ClientData_Touch(entity e);
.float floodcontrol_voice;
.float floodcontrol_voiceteam;
- .float stat_shotorg; // networked stat for trueaim HUD
+ .float stat_shotorg = _STAT(SHOTORG); // networked stat for trueaim HUD
string matchid;
- .float last_pickup;
+ .float last_pickup = _STAT(LAST_PICKUP);
- .float hit_time;
- .float typehit_time;
+ .float hit_time = _STAT(HIT_TIME);
+ .float typehit_time = _STAT(TYPEHIT_TIME);
- .float damage_dealt_total;
+ .float damage_dealt_total = _STAT(DAMAGE_DEALT_TOTAL);
- .float stat_leadlimit;
+ .float stat_leadlimit = _STAT(LEADLIMIT);
bool radar_showennemies;
.float weapon_load[Weapons_MAX];
.int ammo_none; // used by the reloading system, must always be 0
- .float clip_load;
+ .float clip_load = _STAT(WEAPON_CLIPLOAD);
.float old_clip_load;
- .float clip_size;
+ .float clip_size = _STAT(WEAPON_CLIPSIZE);
- .float minelayer_mines;
- .float vortex_charge;
+ .float minelayer_mines = _STAT(LAYED_MINES);
+ .float vortex_charge = _STAT(VORTEX_CHARGE);
.float vortex_charge_rottime;
- .float vortex_chargepool_ammo;
- .float hagar_load;
+ .float vortex_chargepool_ammo = _STAT(VORTEX_CHARGEPOOL);
+ .float hagar_load = _STAT(HAGAR_LOAD);
.int grab; // 0 = can't grab, 1 = owner can grab, 2 = owner and team mates can grab, 3 = anyone can grab
.float player_blocked;
.float weapon_blocked; // weapon use disabled
- .float frozen; // for freeze attacks
- .float revive_progress;
+ .float frozen = _STAT(FROZEN); // for freeze attacks
+ .float revive_progress = _STAT(REVIVE_PROGRESS);
.float revival_time; // time at which player was last revived
.float revive_speed; // NOTE: multiplier (anything above 1 is instaheal)
.entity iceblock;
.entity muzzle_flash;
.float misc_bulletcounter; // replaces uzi & hlac bullet counter.
- .float stat_respawn_time; // shows respawn time, and is negative when awaiting respawn
+ .float stat_respawn_time = _STAT(RESPAWN_TIME); // shows respawn time, and is negative when awaiting respawn
void PlayerUseKey();
void() SUB_CalcMoveDone;
void() SUB_CalcAngleMoveDone;
//void() SUB_UseTargets;
- void() SUB_Remove;
spawnfunc(info_null);
- /*
- ==================
- SUB_Remove
-void setanim(entity e, vector anim, float looping, float override, float restart);
--
- Remove self
- ==================
- */
- void SUB_Remove ();
-void updateanim(entity e);
-
-
--
/*
==================
SUB_Friction
#include "scores.qh"
#include "teamplay.qh"
#include "weapons/weaponstats.qh"
- #include "../common/buffs/all.qh"
#include "../common/constants.qh"
#include "../common/deathtypes/all.qh"
#include "../common/mapinfo.qh"
MapInfo_FilterGametype(MapInfo_CurrentGametype(), MapInfo_CurrentFeatures(), MapInfo_RequiredFlags(), MapInfo_ForbiddenFlags(), 0);
}
+ void __init_dedicated_server_shutdown() {
+ MapInfo_Shutdown();
+ }
+
void Map_MarkAsRecent(string m);
float world_already_spawned;
void Nagger_Init();
void ClientInit_Spawn();
void WeaponStats_Init();
void WeaponStats_Shutdown();
- void Physics_AddStats();
spawnfunc(worldspawn)
{
float fd, l, j, n;
compressShortVector_init();
- entity head;
- head = nextent(world);
maxclients = 0;
- while(head)
+ for (entity head = nextent(world); head; head = nextent(head))
{
++maxclients;
- head = nextent(head);
}
server_is_dedicated = (stof(cvar_defstring("is_dedicated")) ? true : false);
WeaponStats_Init();
- WepSet_AddStat();
- WepSet_AddStat_InMap();
- addstat(STAT_SWITCHWEAPON, AS_INT, switchweapon);
- addstat(STAT_SWITCHINGWEAPON, AS_INT, switchingweapon);
- addstat(STAT_WEAPON_NEXTTHINK, AS_FLOAT, weapon_nextthink);
- addstat(STAT_GAMESTARTTIME, AS_FLOAT, stat_game_starttime);
- addstat(STAT_ROUNDSTARTTIME, AS_FLOAT, stat_round_starttime);
- addstat(STAT_ALLOW_OLDVORTEXBEAM, AS_INT, stat_allow_oldvortexbeam);
Nagger_Init();
- addstat(STAT_STRENGTH_FINISHED, AS_FLOAT, strength_finished);
- addstat(STAT_INVINCIBLE_FINISHED, AS_FLOAT, invincible_finished);
- addstat(STAT_SUPERWEAPONS_FINISHED, AS_FLOAT, superweapons_finished);
- addstat(STAT_PRESSED_KEYS, AS_FLOAT, pressedkeys);
- addstat(STAT_FUEL, AS_INT, ammo_fuel);
- addstat(STAT_PLASMA, AS_INT, ammo_plasma);
- addstat(STAT_SHOTORG, AS_INT, stat_shotorg);
- addstat(STAT_LEADLIMIT, AS_FLOAT, stat_leadlimit);
- addstat(STAT_WEAPON_CLIPLOAD, AS_INT, clip_load);
- addstat(STAT_WEAPON_CLIPSIZE, AS_INT, clip_size);
- addstat(STAT_LAST_PICKUP, AS_FLOAT, last_pickup);
- addstat(STAT_HIT_TIME, AS_FLOAT, hit_time);
- addstat(STAT_DAMAGE_DEALT_TOTAL, AS_INT, damage_dealt_total);
- addstat(STAT_TYPEHIT_TIME, AS_FLOAT, typehit_time);
- addstat(STAT_LAYED_MINES, AS_INT, minelayer_mines);
-
- addstat(STAT_VORTEX_CHARGE, AS_FLOAT, vortex_charge);
- addstat(STAT_VORTEX_CHARGEPOOL, AS_FLOAT, vortex_chargepool_ammo);
-
- addstat(STAT_HAGAR_LOAD, AS_INT, hagar_load);
-
- addstat(STAT_ARC_HEAT, AS_FLOAT, arc_heat_percent);
-
- // freeze attacks
- addstat(STAT_FROZEN, AS_INT, frozen);
- addstat(STAT_REVIVE_PROGRESS, AS_FLOAT, revive_progress);
-
- // physics
- Physics_AddStats();
-
- // new properties
- addstat(STAT_MOVEVARS_JUMPVELOCITY, AS_FLOAT, stat_sv_jumpvelocity);
- addstat(STAT_MOVEVARS_AIRACCEL_QW_STRETCHFACTOR, AS_FLOAT, stat_sv_airaccel_qw_stretchfactor);
- addstat(STAT_MOVEVARS_MAXAIRSTRAFESPEED, AS_FLOAT, stat_sv_maxairstrafespeed);
- addstat(STAT_MOVEVARS_MAXAIRSPEED, AS_FLOAT, stat_sv_maxairspeed);
- addstat(STAT_MOVEVARS_AIRSTRAFEACCELERATE, AS_FLOAT, stat_sv_airstrafeaccelerate);
- addstat(STAT_MOVEVARS_WARSOWBUNNY_TURNACCEL, AS_FLOAT, stat_sv_warsowbunny_turnaccel);
- addstat(STAT_MOVEVARS_AIRACCEL_SIDEWAYS_FRICTION, AS_FLOAT, stat_sv_airaccel_sideways_friction);
- addstat(STAT_MOVEVARS_AIRCONTROL, AS_FLOAT, stat_sv_aircontrol);
- addstat(STAT_MOVEVARS_AIRCONTROL_POWER, AS_FLOAT, stat_sv_aircontrol_power);
- addstat(STAT_MOVEVARS_AIRCONTROL_PENALTY, AS_FLOAT, stat_sv_aircontrol_penalty);
- addstat(STAT_MOVEVARS_WARSOWBUNNY_AIRFORWARDACCEL, AS_FLOAT, stat_sv_warsowbunny_airforwardaccel);
- addstat(STAT_MOVEVARS_WARSOWBUNNY_TOPSPEED, AS_FLOAT, stat_sv_warsowbunny_topspeed);
- addstat(STAT_MOVEVARS_WARSOWBUNNY_ACCEL, AS_FLOAT, stat_sv_warsowbunny_accel);
- addstat(STAT_MOVEVARS_WARSOWBUNNY_BACKTOSIDERATIO, AS_FLOAT, stat_sv_warsowbunny_backtosideratio);
- addstat(STAT_MOVEVARS_FRICTION, AS_FLOAT, stat_sv_friction);
- addstat(STAT_MOVEVARS_ACCELERATE, AS_FLOAT, stat_sv_accelerate);
- addstat(STAT_MOVEVARS_STOPSPEED, AS_FLOAT, stat_sv_stopspeed);
- addstat(STAT_MOVEVARS_AIRACCELERATE, AS_FLOAT, stat_sv_airaccelerate);
- addstat(STAT_MOVEVARS_AIRSTOPACCELERATE, AS_FLOAT, stat_sv_airstopaccelerate);
-
- // secrets
- addstat(STAT_SECRETS_TOTAL, AS_FLOAT, stat_secrets_total);
- addstat(STAT_SECRETS_FOUND, AS_FLOAT, stat_secrets_found);
-
- // monsters
- addstat(STAT_MONSTERS_TOTAL, AS_FLOAT, stat_monsters_total);
- addstat(STAT_MONSTERS_KILLED, AS_FLOAT, stat_monsters_killed);
-
- // misc
- addstat(STAT_RESPAWN_TIME, AS_FLOAT, stat_respawn_time);
-
next_pingtime = time + 5;
detect_maptype();
void FixIntermissionClient(entity e)
{
- string s;
if(!e.autoscreenshot) // initial call
{
e.autoscreenshot = time + 0.8; // used for autoscreenshot
if(e.(weaponentity))
{
e.(weaponentity).effects = EF_NODRAW;
- if (e.(weaponentity).(weaponentity))
- e.(weaponentity).(weaponentity).effects = EF_NODRAW;
+ if (e.(weaponentity).weaponchild)
+ e.(weaponentity).weaponchild.effects = EF_NODRAW;
}
}
if(IS_REAL_CLIENT(e))
{
stuffcmd(e, "\nscr_printspeed 1000000\n");
- s = autocvar_sv_intermission_cdtrack;
- if(s != "")
- stuffcmd(e, strcat("\ncd loop ", s, "\n"));
+ string list = autocvar_sv_intermission_cdtrack;
+ for(string it; (it = car(list)); list = cdr(list))
+ RandomSelection_Add(world, 0, it, 1, 1);
+ if(RandomSelection_chosen_string && RandomSelection_chosen_string != "")
+ stuffcmd(e, strcat("\ncd loop ", RandomSelection_chosen_string, "\n"));
msg_entity = e;
WriteByte(MSG_ONE, SVC_INTERMISSION);
}
);
}
- float WinningCondition_Race(float fraglimit)
- {
- float wc;
- entity p;
- float n, c;
-
- n = 0;
- c = 0;
- FOR_EACH_PLAYER(p)
- {
- ++n;
- if(p.race_completed)
- ++c;
- }
- if(n && (n == c))
- return WINNING_YES;
- wc = WinningCondition_Scores(fraglimit, 0);
-
- // ALWAYS initiate overtime, unless EVERYONE has finished the race!
- if(wc == WINNING_YES || wc == WINNING_STARTSUDDENDEATHOVERTIME)
- // do NOT support equality when the laps are all raced!
- return WINNING_STARTSUDDENDEATHOVERTIME;
- else
- return WINNING_NEVER;
- }
-
- float WinningCondition_QualifyingThenRace(float limit)
- {
- float wc;
- wc = WinningCondition_Scores(limit, 0);
-
- // NEVER initiate overtime
- if(wc == WINNING_YES || wc == WINNING_STARTSUDDENDEATHOVERTIME)
- {
- return WINNING_YES;
- }
-
- return wc;
- }
-
float WinningCondition_RanOutOfSpawns()
{
entity head;
{
LOG_INFO("NOTE: crashed before even initializing the world, not saving persistent data\n");
}
+ else
+ {
+ __init_dedicated_server_shutdown();
+ }
}
#include "cl_client.qc"
#include "cl_impulse.qc"
#include "cl_player.qc"
- #include "ent_cs.qc"
#include "g_damage.qc"
#include "g_hook.qc"
// #include "g_lights.qc" // TODO: was never used
#include "weapons/weaponstats.qc"
#include "weapons/weaponsystem.qc"
+#include "../common/anim.qc"
#include "../common/animdecide.qc"
#include "../common/campaign_file.qc"
#include "../common/campaign_setup.qc"
#include "../common/effects/effectinfo.qc"
+ #include "../common/ent_cs.qc"
#include "../common/mapinfo.qc"
#include "../common/minigames/minigames.qc"
#include "../common/minigames/sv_minigames.qc"
#include "../common/viewloc.qc"
#include "../common/deathtypes/all.qc"
- #include "../common/buffs/all.qc"
#include "../common/effects/all.qc"
#include "../common/gamemodes/all.qc"
#include "../common/items/all.qc"
#include "../common/monsters/all.qc"
- #include "../common/nades/all.qc"
#include "../common/turrets/all.qc"
#include "../common/vehicles/all.qc"
#include "../common/weapons/all.qc"