From: TimePath Date: Sun, 29 Nov 2015 02:45:20 +0000 (+1100) Subject: Merge branch 'master' into TimePath/stats X-Git-Tag: xonotic-v0.8.2~1609^2~2 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=1cbef966e133966c5b5f0f5b58fbd1a5851ed35b;p=xonotic%2Fxonotic-data.pk3dir.git Merge branch 'master' into TimePath/stats # Conflicts: # qcsrc/client/hud/panel/ammo.qc # qcsrc/client/hud/panel/powerups.qc # qcsrc/client/view.qc # qcsrc/common/mutators/mutator/nades/nades.qc # qcsrc/common/physics.qc # qcsrc/common/physics.qh # qcsrc/common/weapons/weapon/vortex.qc # qcsrc/lib/registry.qh # qcsrc/lib/stats.qh --- 1cbef966e133966c5b5f0f5b58fbd1a5851ed35b diff --cc qcsrc/client/view.qc index 87adec58b,0f1a43e2f..c98400df5 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@@ -360,9 -360,9 +360,9 @@@ float TrueAimCheck( 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; @@@ -1005,19 -1005,27 +1005,27 @@@ void HUD_Crosshair( void HUD_Draw() { - if(STAT(FROZEN)) - drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, ((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'), autocvar_hud_colorflash_alpha, DRAWFLAG_ADDITIVE); - else if (STAT(HEALING_ORB)>time) - drawfill('0 0 0', eX * vid_conwidth + eY * vid_conheight, NADE_TYPE_HEAL.m_color, autocvar_hud_colorflash_alpha*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(getstati(STAT_FROZEN)) ++ else if(STAT(FROZEN)) + { - rgb = ((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'); ++ 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); } diff --cc qcsrc/common/mutators/mutator/buffs/all.qh index 000000000,db22d3141..76ecff8be mode 000000,100644..100644 --- a/qcsrc/common/mutators/mutator/buffs/all.qh +++ b/qcsrc/common/mutators/mutator/buffs/all.qh @@@ -1,0 -1,73 +1,73 @@@ + #ifndef BUFFS_ALL_H + #define BUFFS_ALL_H + // Welcome to the stuff behind the scenes + // Below, you will find the list of buffs + // Add new buffs here! + // Note: Buffs also need spawnfuncs, which are set below + + #include "../../../teams.qh" + #include "../../../util.qh" + + REGISTER_WAYPOINT(Buff, _("Buff"), '1 0.5 0', 1); + REGISTER_RADARICON(Buff, 1); + + REGISTRY(Buffs, BITS(4)) + #define Buffs_from(i) _Buffs_from(i, BUFF_Null) + REGISTER_REGISTRY(Buffs) + REGISTRY_CHECK(Buffs) + + #define REGISTER_BUFF(id) \ + REGISTER(Buffs, BUFF_##id, m_id, NEW(Buff)); \ + REGISTER_INIT_POST(BUFF_##id) { \ + this.netname = this.m_name; \ + this.m_itemid = BIT(this.m_id - 1); \ + this.m_sprite = strzone(strcat("buff-", this.m_name)); \ + } \ + REGISTER_INIT(BUFF_##id) + + #include "../../../items/item/pickup.qh" + CLASS(Buff, Pickup) + /** bit index */ + ATTRIB(Buff, m_itemid, int, 0) + ATTRIB(Buff, m_name, string, "buff") + ATTRIB(Buff, m_color, vector, '1 1 1') + ATTRIB(Buff, m_prettyName, string, "Buff") + ATTRIB(Buff, m_skin, int, 0) + ATTRIB(Buff, m_sprite, string, "") + METHOD(Buff, display, void(entity this, void(string name, string icon) returns)) { + returns(this.m_prettyName, sprintf("/gfx/hud/%s/buff_%s", cvar_string("menu_skin"), this.m_name)); + } + #ifdef SVQC + METHOD(Buff, m_time, float(Buff this)) + { return cvar(strcat("g_buffs_", this.netname, "_time")); } + #endif + ENDCLASS(Buff) + + #ifdef SVQC - .int buffs; ++ // .int buffs = _STAT(BUFFS); + void buff_Init(entity ent); + void buff_Init_Compat(entity ent, entity replacement); + #define BUFF_SPAWNFUNC(e, b, t) spawnfunc(item_buff_##e) { \ + self.buffs = b.m_itemid; \ + self.team = t; \ + buff_Init(self); \ + } + #define BUFF_SPAWNFUNCS(e, b) \ + BUFF_SPAWNFUNC(e, b, 0) \ + BUFF_SPAWNFUNC(e##_team1, b, NUM_TEAM_1) \ + BUFF_SPAWNFUNC(e##_team2, b, NUM_TEAM_2) \ + BUFF_SPAWNFUNC(e##_team3, b, NUM_TEAM_3) \ + BUFF_SPAWNFUNC(e##_team4, b, NUM_TEAM_4) + #define BUFF_SPAWNFUNC_Q3TA_COMPAT(o, r) spawnfunc(item_##o) { buff_Init_Compat(self, r); } + #else + #define BUFF_SPAWNFUNC(e, b, t) + #define BUFF_SPAWNFUNCS(e, b) + #define BUFF_SPAWNFUNC_Q3TA_COMPAT(o, r) + #endif + + REGISTER_BUFF(Null); + BUFF_SPAWNFUNCS(random, BUFF_Null) + + #include "all.inc" + + #endif diff --cc qcsrc/common/mutators/mutator/buffs/buffs.qc index fbddd037b,9eb113a96..dbabdd2e2 --- a/qcsrc/common/mutators/mutator/buffs/buffs.qc +++ b/qcsrc/common/mutators/mutator/buffs/buffs.qc @@@ -75,9 -75,8 +75,8 @@@ const vector BUFF_MAX = ('16 16 20') #include "../../../triggers/target/music.qh" #include "../../../gamemodes/all.qh" - #include "../../../buffs/all.qh" -.float buff_time; +.float buff_time = _STAT(BUFF_TIME); void buffs_DelayedInit(); REGISTER_MUTATOR(buffs, cvar("g_buffs")) diff --cc qcsrc/common/mutators/mutator/buffs/module.inc index 89d31a1b3,5f24f627e..be0097714 --- a/qcsrc/common/mutators/mutator/buffs/module.inc +++ b/qcsrc/common/mutators/mutator/buffs/module.inc @@@ -1,3 -2,45 +2,45 @@@ #ifdef SVQC #include "buffs.qc" #endif + + #ifdef IMPLEMENTATION + + string BUFF_NAME(int i) + { + Buff b = Buffs_from(i); + return sprintf("%s%s", rgb_to_hexcolor(b.m_color), b.m_prettyName); + } + + #ifndef MENUQC + REGISTER_MUTATOR(buffs_flight, true); + MUTATOR_HOOKFUNCTION(buffs_flight, IsFlying) + { + noref entity e = MUTATOR_ARGV(0, entity); + return BUFFS_STAT(e) & BUFF_FLIGHT.m_itemid; + } + #endif + + #ifdef CSQC + REGISTER_MUTATOR(cl_buffs, true); + MUTATOR_HOOKFUNCTION(cl_buffs, HUD_Powerups_add) + { - int allBuffs = getstati(STAT_BUFFS, 0, 24); ++ int allBuffs = STAT(BUFFS); + FOREACH(Buffs, it.m_itemid & allBuffs, LAMBDA( - addPowerupItem(it.m_prettyName, strcat("buff_", it.m_name), it.m_color, bound(0, getstatf(STAT_BUFF_TIME) - time, 99), 60); ++ addPowerupItem(it.m_prettyName, strcat("buff_", it.m_name), it.m_color, bound(0, STAT(BUFF_TIME) - time, 99), 60); + )); + } + MUTATOR_HOOKFUNCTION(cl_buffs, WP_Format) + { + entity this = MUTATOR_ARGV(0, entity); + string s = MUTATOR_ARGV(0, string); + if (s == WP_Buff.netname || s == RADARICON_Buff.netname) + { + Buff b = Buffs_from(this.wp_extra); + MUTATOR_ARGV(0, vector) = b.m_color; + MUTATOR_ARGV(0, string) = b.m_prettyName; + return true; + } + } + + #endif + #endif diff --cc qcsrc/common/mutators/mutator/nades/nades.qc index 0c3018699,12a53ff13..ec57e94c1 --- a/qcsrc/common/mutators/mutator/nades/nades.qc +++ b/qcsrc/common/mutators/mutator/nades/nades.qc @@@ -1,50 -1,124 +1,124 @@@ - #ifndef MUTATOR_NADES_H - #define MUTATOR_NADES_H + #include "nades.qh" - #ifdef SVQC - #include "../../../../server/mutators/mutator/gamemode_freezetag.qc" + #ifdef IMPLEMENTATION + + #ifndef MENUQC + entity Nade_TrailEffect(int proj, int nade_team) + { + switch (proj) + { + case PROJECTILE_NADE: return EFFECT_NADE_TRAIL(nade_team); + case PROJECTILE_NADE_BURN: return EFFECT_NADE_TRAIL_BURN(nade_team); + } + + FOREACH(Nades, true, LAMBDA( + for (int j = 0; j < 2; j++) + { + if (it.m_projectile[j] == proj) + { + string trail = it.m_trail[j].eent_eff_name; + if (trail) return it.m_trail[j]; + break; + } + } + )); + + return EFFECT_Null; + } #endif - .entity nade; - .entity fake_nade; - .float nade_timer = _STAT(NADE_TIMER); - .float nade_refire; - .float bonus_nades = _STAT(NADE_BONUS); - .float nade_special_time; - .float bonus_nade_score = _STAT(NADE_BONUS_SCORE); - .int nade_type = _STAT(NADE_BONUS_TYPE); - .string pokenade_type; - .entity nade_damage_target; - .float cvar_cl_nade_type; - .string cvar_cl_pokenade_type; - .float toss_time; - .float stat_healing_orb = _STAT(HEALING_ORB); - .float stat_healing_orb_alpha = _STAT(HEALING_ORB_ALPHA); - .float nade_show_particles; - - // Remove nades that are being thrown - void nades_Clear(entity player); - - // Give a bonus grenade to a player - void(entity player, float score) nades_GiveBonus; - - /** - * called to adjust nade damage and force on hit - */ - #define EV_Nade_Damage(i, o) \ - /** weapon */ i(entity, MUTATOR_ARGV_0_entity) \ - /** force */ i(vector, MUTATOR_ARGV_0_vector) \ - /**/ o(vector, MUTATOR_ARGV_0_vector) \ - /** damage */ i(float, MUTATOR_ARGV_0_float) \ - /**/ o(float, MUTATOR_ARGV_0_float) \ - /**/ - MUTATOR_HOOKABLE(Nade_Damage, EV_Nade_Damage); + #ifdef CSQC + REGISTER_MUTATOR(cl_nades, true); + MUTATOR_HOOKFUNCTION(cl_nades, HUD_Draw_overlay) + { - if (getstatf(STAT_HEALING_ORB) <= time) return false; ++ if (STAT(HEALING_ORB) <= time) return false; + MUTATOR_ARGV(0, vector) = NADE_TYPE_HEAL.m_color; - MUTATOR_ARGV(0, float) = getstatf(STAT_HEALING_ORB_ALPHA); ++ MUTATOR_ARGV(0, float) = STAT(HEALING_ORB_ALPHA); + return true; + } + MUTATOR_HOOKFUNCTION(cl_nades, Ent_Projectile) + { + if (self.cnt == PROJECTILE_NAPALM_FOUNTAIN) + { + self.modelindex = 0; + self.traileffect = EFFECT_FIREBALL.m_id; + return true; + } + 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; + return true; + } + } + MUTATOR_HOOKFUNCTION(cl_nades, EditProjectile) + { + if (self.cnt == PROJECTILE_NAPALM_FOUNTAIN) + { + loopsound(self, CH_SHOTS_SINGLE, SND(FIREBALL_FLY2), VOL_BASE, ATTEN_NORM); + self.mins = '-16 -16 -16'; + self.maxs = '16 16 16'; + } + + entity nade_type = Nade_FromProjectile(self.cnt); + if (nade_type == NADE_TYPE_Null) return; + 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; + } + bool Projectile_isnade(int p) + { + return Nade_FromProjectile(p) != NADE_TYPE_Null; + } + void DrawAmmoNades(vector myPos, vector mySize, bool draw_expanding, float expand_time) + { - float bonusNades = getstatf(STAT_NADE_BONUS); - float bonusProgress = getstatf(STAT_NADE_BONUS_SCORE); - float bonusType = getstati(STAT_NADE_BONUS_TYPE); ++ float bonusNades = STAT(NADE_BONUS); ++ float bonusProgress = STAT(NADE_BONUS_SCORE); ++ float bonusType = STAT(NADE_BONUS_TYPE); + Nade def = Nades_from(bonusType); + vector nadeColor = def.m_color; + string nadeIcon = def.m_icon; + + vector iconPos, textPos; + + if(autocvar_hud_panel_ammo_iconalign) + { + iconPos = myPos + eX * 2 * mySize.y; + textPos = myPos; + } + else + { + iconPos = myPos; + textPos = myPos + eX * mySize.y; + } + + if(bonusNades > 0 || bonusProgress > 0) + { + DrawNadeProgressBar(myPos, mySize, bonusProgress, nadeColor); + + if(autocvar_hud_panel_ammo_text) + drawstring_aspect(textPos, ftos(bonusNades), eX * (2/3) * mySize.x + eY * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); + + if(draw_expanding) + drawpic_aspect_skin_expanding(iconPos, nadeIcon, '1 1 0' * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL, expand_time); + drawpic_aspect_skin(iconPos, nadeIcon, '1 1 0' * mySize.y, '1 1 1', panel_fg_alpha, DRAWFLAG_NORMAL); + } + } #endif - #ifdef IMPLEMENTATION + #ifdef SVQC - #include "../../../nades/all.qh" #include "../../../gamemodes/all.qh" #include "../../../monsters/spawn.qh" #include "../../../monsters/sv_monsters.qh" diff --cc qcsrc/common/mutators/mutator/nades/nades.qh index 000000000,2e4829354..312cf4ae2 mode 000000,100644..100644 --- a/qcsrc/common/mutators/mutator/nades/nades.qh +++ b/qcsrc/common/mutators/mutator/nades/nades.qh @@@ -1,0 -1,103 +1,103 @@@ + #ifndef NADES_ALL_H + #define NADES_ALL_H + + #include "../../../teams.qh" + + // use slots 70-100 + const int PROJECTILE_NADE = 71; + const int PROJECTILE_NADE_BURN = 72; + const int PROJECTILE_NADE_NAPALM = 73; + const int PROJECTILE_NADE_NAPALM_BURN = 74; + const int PROJECTILE_NAPALM_FOUNTAIN = 75; + const int PROJECTILE_NADE_ICE = 76; + const int PROJECTILE_NADE_ICE_BURN = 77; + const int PROJECTILE_NADE_TRANSLOCATE = 78; + const int PROJECTILE_NADE_SPAWN = 79; + const int PROJECTILE_NADE_HEAL = 80; + const int PROJECTILE_NADE_HEAL_BURN = 81; + const int PROJECTILE_NADE_MONSTER = 82; + const int PROJECTILE_NADE_MONSTER_BURN = 83; + + REGISTRY(Nades, BITS(4)) + #define Nades_from(i) _Nades_from(i, NADE_TYPE_Null) + REGISTER_REGISTRY(Nades) + REGISTRY_CHECK(Nades) + + #define REGISTER_NADE(id) REGISTER(Nades, NADE_TYPE, id, m_id, NEW(Nade)) + + CLASS(Nade, Object) + ATTRIB(Nade, m_id, int, 0) + ATTRIB(Nade, m_color, vector, '0 0 0') + ATTRIB(Nade, m_name, string, _("Grenade")) + ATTRIB(Nade, m_icon, string, "nade_normal") + ATTRIBARRAY(Nade, m_projectile, int, 2) + ATTRIBARRAY(Nade, m_trail, entity, 2) + METHOD(Nade, display, void(entity this, void(string name, string icon) returns)) { + returns(this.m_name, sprintf("/gfx/hud/%s/%s", cvar_string("menu_skin"), this.m_icon)); + } + ENDCLASS(Nade) + + REGISTER_NADE(Null); + + Nade Nade_FromProjectile(int proj) + { + FOREACH(Nades, true, LAMBDA( + for (int j = 0; j < 2; j++) + { + if (it.m_projectile[j] == proj) return it; + } + )); + return NADE_TYPE_Null; + } + + #ifndef MENUQC + #include "effects.inc" + #endif + + #include "nades.inc" + + .float healer_lifetime; + .float healer_radius; + + #ifdef SVQC + + .entity nade; + .entity fake_nade; -.float nade_timer; ++.float nade_timer = _STAT(NADE_TIMER); + .float nade_refire; -.float bonus_nades; ++.float bonus_nades = _STAT(NADE_BONUS); + .float nade_special_time; -.float bonus_nade_score; -.float nade_type; ++.float bonus_nade_score = _STAT(NADE_BONUS_SCORE); ++.int nade_type = _STAT(NADE_BONUS_TYPE); + .string pokenade_type; + .entity nade_damage_target; + .float cvar_cl_nade_type; + .string cvar_cl_pokenade_type; + .float toss_time; -.float stat_healing_orb; -.float stat_healing_orb_alpha; ++.float stat_healing_orb = _STAT(HEALING_ORB); ++.float stat_healing_orb_alpha = _STAT(HEALING_ORB_ALPHA); + .float nade_show_particles; + + bool healer_send(entity this, entity to, int sf); + + // Remove nades that are being thrown + void nades_Clear(entity player); + + // Give a bonus grenade to a player + void(entity player, float score) nades_GiveBonus; + + /** + * called to adjust nade damage and force on hit + */ + #define EV_Nade_Damage(i, o) \ + /** weapon */ i(entity, MUTATOR_ARGV_0_entity) \ + /** force */ i(vector, MUTATOR_ARGV_0_vector) \ + /**/ o(vector, MUTATOR_ARGV_0_vector) \ + /** damage */ i(float, MUTATOR_ARGV_0_float) \ + /**/ o(float, MUTATOR_ARGV_0_float) \ + /**/ + MUTATOR_HOOKABLE(Nade_Damage, EV_Nade_Damage); + + #endif + + #endif diff --cc qcsrc/common/physics.qc index 71bc63e1b,63e7ae7e9..0526742b4 --- a/qcsrc/common/physics.qc +++ b/qcsrc/common/physics.qc @@@ -1382,20 -1476,20 +1366,20 @@@ void PM_walk(entity this, float maxspd_ v >= PHYS_STOPSPEED * (1 - PHYS_INPUT_TIMELENGTH * PHYS_FRICTION) */ } - float addspeed = wishspeed - self.velocity * wishdir; + const float addspeed = wishspeed - this.velocity * wishdir; if (addspeed > 0) { - float accelspeed = min(PHYS_ACCELERATE * PHYS_INPUT_TIMELENGTH * wishspeed, addspeed); - self.velocity += accelspeed * wishdir; + const float accelspeed = min(PHYS_ACCELERATE * PHYS_INPUT_TIMELENGTH * wishspeed, addspeed); + this.velocity += accelspeed * wishdir; } - float g = PHYS_GRAVITY(this) * PHYS_ENTGRAVITY(self) * PHYS_INPUT_TIMELENGTH; - const float g = PHYS_GRAVITY * PHYS_ENTGRAVITY(this) * PHYS_INPUT_TIMELENGTH; ++ const float g = PHYS_GRAVITY(this) * PHYS_ENTGRAVITY(this) * PHYS_INPUT_TIMELENGTH; if (!(GAMEPLAYFIX_NOGRAVITYONGROUND)) - self.velocity_z -= g * (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1); - if (self.velocity * self.velocity) + this.velocity_z -= g * (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE ? 0.5 : 1); + if (vdist(this.velocity, >, 0)) PM_ClientMovement_Move(); if (GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE) - if (!IS_ONGROUND(self) || !GAMEPLAYFIX_NOGRAVITYONGROUND) - self.velocity_z -= g * 0.5; + if (!IS_ONGROUND(this) || !GAMEPLAYFIX_NOGRAVITYONGROUND) + this.velocity_z -= g * 0.5; } void PM_air(float buttons_prev, float maxspd_mod) @@@ -1513,10 -1607,10 +1497,10 @@@ void PM_Main(entity this maxspeed_mod *= PHYS_HIGHSPEED; #ifdef SVQC - Physics_UpdateStats(maxspeed_mod); + Physics_UpdateStats(this, maxspeed_mod); - if (self.PlayerPhysplug) - if (self.PlayerPhysplug()) + if (this.PlayerPhysplug) + if (this.PlayerPhysplug()) return; #endif diff --cc qcsrc/common/physics.qh index 682e58712,639776593..fb396d159 --- a/qcsrc/common/physics.qh +++ b/qcsrc/common/physics.qh @@@ -159,11 -72,16 +159,11 @@@ bool IsFlying(entity a) #define PHYS_DEAD(s) s.csqcmodel_isdead - #define GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE boolean(moveflags & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE) - #define GAMEPLAYFIX_NOGRAVITYONGROUND cvar("sv_gameplayfix_nogravityonground") - #define GAMEPLAYFIX_Q2AIRACCELERATE cvar("sv_gameplayfix_q2airaccelerate") - #define GAMEPLAYFIX_EASIERWATERJUMP getstati(STAT_GAMEPLAYFIX_EASIERWATERJUMP) - #define GAMEPLAYFIX_DOWNTRACEONGROUND getstati(STAT_GAMEPLAYFIX_DOWNTRACEONGROUND) - #define GAMEPLAYFIX_STEPMULTIPLETIMES getstati(STAT_GAMEPLAYFIX_STEPMULTIPLETIMES) - #define GAMEPLAYFIX_UNSTICKPLAYERS getstati(STAT_GAMEPLAYFIX_UNSTICKPLAYERS) - #define GAMEPLAYFIX_STEPDOWN getstati(STAT_GAMEPLAYFIX_STEPDOWN) + #define GAMEPLAYFIX_GRAVITYUNAFFECTEDBYTICRATE (boolean(moveflags & MOVEFLAG_GRAVITYUNAFFECTEDBYTICRATE)) + #define GAMEPLAYFIX_NOGRAVITYONGROUND (boolean(moveflags & MOVEFLAG_NOGRAVITYONGROUND)) + #define GAMEPLAYFIX_Q2AIRACCELERATE (boolean(moveflags & MOVEFLAG_Q2AIRACCELERATE)) - #define IS_DUCKED(s) !!(s.flags & FL_DUCKED) + #define IS_DUCKED(s) boolean(s.flags & FL_DUCKED) #define SET_DUCKED(s) s.flags |= FL_DUCKED #define UNSET_DUCKED(s) s.flags &= ~FL_DUCKED @@@ -175,9 -93,32 +175,9 @@@ #define SET_ONGROUND(s) s.flags |= FL_ONGROUND #define UNSET_ONGROUND(s) s.flags &= ~FL_ONGROUND - #define WAS_ONGROUND(s) !!(s.lastflags & FL_ONGROUND) + #define WAS_ONGROUND(s) boolean(s.lastflags & FL_ONGROUND) #define ITEMS_STAT(s) (s).items - #define BUFFS_STAT(s) getstati(STAT_BUFFS) - - #define PHYS_AMMO_FUEL(s) getstati(STAT_FUEL) - - #define PHYS_FROZEN(s) getstati(STAT_FROZEN) - - #define PHYS_DOUBLEJUMP getstati(STAT_DOUBLEJUMP) - - #define PHYS_BUGRIGS getstati(STAT_BUGRIGS) - #define PHYS_BUGRIGS_ANGLE_SMOOTHING getstati(STAT_BUGRIGS_ANGLE_SMOOTHING) - #define PHYS_BUGRIGS_PLANAR_MOVEMENT getstati(STAT_BUGRIGS_PLANAR_MOVEMENT) - #define PHYS_BUGRIGS_REVERSE_SPEEDING getstati(STAT_BUGRIGS_REVERSE_SPEEDING) - #define PHYS_BUGRIGS_FRICTION_FLOOR getstatf(STAT_BUGRIGS_FRICTION_FLOOR) - #define PHYS_BUGRIGS_AIR_STEERING getstati(STAT_BUGRIGS_AIR_STEERING) - #define PHYS_BUGRIGS_FRICTION_BRAKE getstatf(STAT_BUGRIGS_FRICTION_BRAKE) - #define PHYS_BUGRIGS_ACCEL getstatf(STAT_BUGRIGS_ACCEL) - #define PHYS_BUGRIGS_SPEED_REF getstatf(STAT_BUGRIGS_SPEED_REF) - #define PHYS_BUGRIGS_SPEED_POW getstatf(STAT_BUGRIGS_SPEED_POW) - #define PHYS_BUGRIGS_STEER getstatf(STAT_BUGRIGS_STEER) - #define PHYS_BUGRIGS_FRICTION_AIR getstatf(STAT_BUGRIGS_FRICTION_AIR) - #define PHYS_BUGRIGS_CAR_JUMPING getstatf(STAT_BUGRIGS_CAR_JUMPING) - #define PHYS_BUGRIGS_REVERSE_SPINNING getstatf(STAT_BUGRIGS_REVERSE_SPINNING) - #define PHYS_BUGRIGS_REVERSE_STOPPING getstatf(STAT_BUGRIGS_REVERSE_STOPPING) #define PHYS_JUMPSPEEDCAP_MIN cvar_string("cl_jumpspeedcap_min") #define PHYS_JUMPSPEEDCAP_MAX cvar_string("cl_jumpspeedcap_max") @@@ -238,9 -296,32 +238,9 @@@ #define SET_ONGROUND(s) s.flags |= FL_ONGROUND #define UNSET_ONGROUND(s) s.flags &= ~FL_ONGROUND - #define WAS_ONGROUND(s) !!((s).lastflags & FL_ONGROUND) + #define WAS_ONGROUND(s) boolean((s).lastflags & FL_ONGROUND) #define ITEMS_STAT(s) s.items - #define BUFFS_STAT(s) (s).buffs - - #define PHYS_AMMO_FUEL(s) s.ammo_fuel - - #define PHYS_FROZEN(s) s.frozen - - #define PHYS_DOUBLEJUMP autocvar_sv_doublejump - - #define PHYS_BUGRIGS g_bugrigs - #define PHYS_BUGRIGS_ANGLE_SMOOTHING g_bugrigs_angle_smoothing - #define PHYS_BUGRIGS_PLANAR_MOVEMENT g_bugrigs_planar_movement - #define PHYS_BUGRIGS_REVERSE_SPEEDING g_bugrigs_reverse_speeding - #define PHYS_BUGRIGS_FRICTION_FLOOR g_bugrigs_friction_floor - #define PHYS_BUGRIGS_AIR_STEERING g_bugrigs_air_steering - #define PHYS_BUGRIGS_FRICTION_BRAKE g_bugrigs_friction_brake - #define PHYS_BUGRIGS_ACCEL g_bugrigs_accel - #define PHYS_BUGRIGS_SPEED_REF g_bugrigs_speed_ref - #define PHYS_BUGRIGS_SPEED_POW g_bugrigs_speed_pow - #define PHYS_BUGRIGS_STEER g_bugrigs_steer - #define PHYS_BUGRIGS_FRICTION_AIR g_bugrigs_friction_air - #define PHYS_BUGRIGS_CAR_JUMPING g_bugrigs_planar_movement_car_jumping - #define PHYS_BUGRIGS_REVERSE_SPINNING g_bugrigs_reverse_spinning - #define PHYS_BUGRIGS_REVERSE_STOPPING g_bugrigs_reverse_stopping #define PHYS_JUMPSPEEDCAP_MIN autocvar_sv_jumpspeedcap_min #define PHYS_JUMPSPEEDCAP_MAX autocvar_sv_jumpspeedcap_max diff --cc qcsrc/common/weapons/all.qh index baa11371a,8d62426da..eb7a48f7f --- a/qcsrc/common/weapons/all.qh +++ b/qcsrc/common/weapons/all.qh @@@ -7,9 -7,9 +7,7 @@@ // 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 diff --cc qcsrc/common/weapons/weapon/vortex.qc index 072bc1cbe,8a90679b8..5e31fbdbe --- a/qcsrc/common/weapons/weapon/vortex.qc +++ b/qcsrc/common/weapons/weapon/vortex.qc @@@ -91,7 -91,8 +91,8 @@@ NET_HANDLE(TE_CSQC_VORTEXBEAMPARTICLE, charge = sqrt(charge); // divide evenly among trail spacing and alpha particles_alphamin = particles_alphamax = particles_fade = charge; - if (autocvar_cl_particles_oldvortexbeam && (STAT(ALLOW_OLDVORTEXBEAM) || isdemo())) + if(!MUTATOR_CALLHOOK(Particles_VortexBeam, shotorg, endpos)) - if(autocvar_cl_particles_oldvortexbeam && (getstati(STAT_ALLOW_OLDVORTEXBEAM) || isdemo())) ++ if(autocvar_cl_particles_oldvortexbeam && (STAT(ALLOW_OLDVORTEXBEAM) || isdemo())) WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum(EFFECT_VORTEX_BEAM_OLD), shotorg, endpos, 1, PARTICLES_USEALPHA | PARTICLES_USEFADE); else WarpZone_TrailParticles_WithMultiplier(world, particleeffectnum(EFFECT_VORTEX_BEAM), shotorg, endpos, 1, PARTICLES_USEALPHA | PARTICLES_USEFADE); diff --cc qcsrc/dpdefs/csprogsdefs.qh index 79cfe76c6,b9bcec58e..ce39bca1b --- a/qcsrc/dpdefs/csprogsdefs.qh +++ b/qcsrc/dpdefs/csprogsdefs.qh @@@ -33,14 -27,6 +33,12 @@@ #undef pointparticles #undef setmodel +#undef STAT_FRAGLIMIT +#undef STAT_TIMELIMIT +#undef STAT_MOVEVARS_TICRATE +#undef STAT_MOVEVARS_TIMESCALE +#undef STAT_MOVEVARS_GRAVITY + #pragma noref 0 - #define ReadFloat() ReadCoord() - #endif diff --cc qcsrc/lib/registry.qh index 8ad8be56e,40a39395b..f2bdd1e26 --- a/qcsrc/lib/registry.qh +++ b/qcsrc/lib/registry.qh @@@ -29,48 -43,39 +43,49 @@@ REGISTRY(Registries, BITS(8) * } \ * REGISTER_INIT(FOO, id) * - * Don't forget to forward declare `initfunc` and call `REGISTER_REGISTRY`: - * void RegisterFoos(); - * REGISTER_REGISTRY(RegisterFoos) * - * @param initfunc The global constructor to accumulate into + * @param registry The registry to add each entity to. * @param ns Short for namespace, prefix for each global (ns##_##id) - * @param array The array to add each entity to. Also requires `array##_first` and `array##_last` to be defined * @param id The identifier of the current entity being registered - * @param fld The field to store the current count into + * @param fld The field to store the locally unique unique entity id * @param inst An expression to create a new instance, invoked for every registration */ - #define REGISTER(initfunc, ns, array, id, fld, inst) \ - entity ns##_##id; \ - REGISTER_INIT(ns, id) {} \ - REGISTER_INIT_POST(ns, id) {} \ - void Register_##ns##_##id() \ + #define REGISTER(...) EVAL(OVERLOAD(REGISTER, __VA_ARGS__)) + #define REGISTER_5(registry, ns, id, fld, inst) REGISTER_4(registry, ns##_##id, fld, inst) + #define REGISTER_4(registry, id, fld, inst) \ + entity id; \ + REGISTER_INIT(id) {} \ + REGISTER_INIT_POST(id) {} \ + void Register_##id() \ { \ - if (array##_COUNT >= array##_MAX) LOG_FATALF("Registry capacity exceeded (%s)", ftos(array##_MAX)); \ - entity this = inst; \ - ns##_##id = this; \ + if (registry##_COUNT >= registry##_MAX) LOG_FATALF("Registry capacity exceeded (%s)", ftos(registry##_MAX)); \ + entity this = id = inst; \ this.registered_id = #id; \ - REGISTRY_PUSH(array, fld, this); \ - Register_##ns##_##id##_init(this); \ - Register_##ns##_##id##_init_post(this); \ - this.fld = registry##_COUNT; \ - _R_SET(_##registry, registry##_COUNT, this); \ - ++registry##_COUNT; \ - if (!registry##_first) registry##_first = this; \ - if (registry##_last) registry##_last.REGISTRY_NEXT = this; \ - registry##_last = this; \ ++ REGISTRY_PUSH(registry, fld, this); \ + Register_##id##_init(this); \ + Register_##id##_init_post(this); \ } \ - ACCUMULATE_FUNCTION(initfunc, Register_##ns##_##id) \ - REGISTER_INIT(ns, id) - - #define REGISTRY_PUSH(array, fld, it) do { \ - it.fld = array##_COUNT; \ - _##array[array##_COUNT++] = it; \ - if (!array##_first) array##_first = it; \ - if (array##_last) array##_last.REGISTRY_NEXT = it; \ - array##_last = it; \ + ACCUMULATE_FUNCTION(Register##registry, Register_##id) \ + REGISTER_INIT(id) + ++#define REGISTRY_PUSH(registry, fld, it) do { \ ++ it.fld = registry##_COUNT; \ ++ _R_SET(_##registry, registry##_COUNT, it); \ ++ ++registry##_COUNT; \ ++ if (!registry##_first) registry##_first = it; \ ++ if (registry##_last) registry##_last.REGISTRY_NEXT = it; \ ++ registry##_last = it; \ +} while (0) + +#define REGISTRY_RESERVE(registry, fld, id, suffix) do { \ + entity e = new(registry_reserved); \ - e.registered_id = #id #suffix; \ ++ e.registered_id = #id "/" #suffix; \ + REGISTRY_PUSH(registry, fld, e); \ +} while (0) + + #define REGISTER_INIT(id) [[accumulate]] void Register_##id##_init(entity this) + #define REGISTER_INIT_POST(id) [[accumulate]] void Register_##id##_init_post(entity this) + /** internal next pointer */ #define REGISTRY_NEXT enemy .entity REGISTRY_NEXT; diff --cc qcsrc/lib/stats.qh index 32927f4bd,12dc425cd..da796b910 --- a/qcsrc/lib/stats.qh +++ b/qcsrc/lib/stats.qh @@@ -20,19 -16,13 +20,19 @@@ typedef vector vectori #define getstat_int(id) getstati(id, 0, 24) #define getstat_bool(id) boolean(getstati(id)) #define getstat_float(id) getstatf(id) + #define getstat_vector(id) vec3(getstat_float(id + 0), getstat_float(id + 1), getstat_float(id + 2)) + #define getstat_vectori(id) vec3(getstat_int(id + 0), getstat_int(id + 1), getstat_int(id + 2)) #define _STAT(id) g_stat_##id - #define REGISTER_STAT(id, type) \ - type _STAT(id); \ - REGISTER(Stats, STAT, id, m_id, new(stat)) \ + #define REGISTER_STAT_2(id, T) \ + T _STAT(id); \ - REGISTER(RegisterStats, STAT, Stats, id, m_id, new(stat)) \ ++ REGISTER(Stats, STAT_##id, m_id, new(stat)) \ { \ make_pure(this); \ + if (#T == "vector" || #T == "vectori") { \ - REGISTRY_RESERVE(Stats, m_id, id, _y); \ - REGISTRY_RESERVE(Stats, m_id, id, _z); \ ++ REGISTRY_RESERVE(Stats, m_id, STAT_##id, y); \ ++ REGISTRY_RESERVE(Stats, m_id, STAT_##id, z); \ + } \ } \ [[accumulate]] void stats_get() \ { \ @@@ -61,46 -40,26 +61,46 @@@ const int AS_INT = 2; const int AS_FLOAT = 8; + .int __stat_null; + /** Prevent engine stats being sent */ + STATIC_INIT(stats_clear) + { + int r = 32; + for (int i = 0, n = 256 - r; i < n; ++i) { + addstat(r + i, AS_INT, __stat_null); + } + } + #define _STAT(id) stat_##id - #define REGISTER_STAT(id, type) \ - .type _STAT(id); \ - REGISTER(Stats, STAT, id, m_id, new(stat)) \ + #define REGISTER_STAT_2(id, T) \ + .T _STAT(id); \ - REGISTER(RegisterStats, STAT, Stats, id, m_id, new(stat)) \ ++ REGISTER(Stats, STAT_##id, m_id, new(stat)) \ { \ make_pure(this); \ + if (#T == "vector" || #T == "vectori") { \ - REGISTRY_RESERVE(Stats, m_id, id, _y); \ - REGISTRY_RESERVE(Stats, m_id, id, _z); \ ++ REGISTRY_RESERVE(Stats, m_id, STAT_##id, y); \ ++ REGISTRY_RESERVE(Stats, m_id, STAT_##id, z); \ + } \ } \ [[accumulate]] void stats_add() \ { \ - addstat_##type(STAT_##id.m_id, _STAT(id)); \ + addstat_##T(STAT_##id.m_id, _STAT(id)); \ } + void GlobalStats_update(entity this) {} + #define REGISTER_STAT_3(x, T, expr) \ + REGISTER_STAT(x, T); \ + [[accumulate]] void GlobalStats_update(entity this) { STAT(x, this) = (expr); } \ + STATIC_INIT(worldstat_##x) { entity this = world; STAT(x, this) = (expr); } #else - #define REGISTER_STAT(id, type) + #define REGISTER_STAT_2(id, type) + #define REGISTER_STAT_3(x, T, expr) #endif -const int STATS_ENGINE_RESERVE = 32 + (8 * 3); // Not sure how to handle vector stats yet, reserve them too +const int STATS_ENGINE_RESERVE = 32; -REGISTRY(Stats, 220 - STATS_ENGINE_RESERVE) +REGISTRY(Stats, 256 - STATS_ENGINE_RESERVE) - REGISTER_REGISTRY(RegisterStats) - REGISTRY_SORT(Stats, 0) + REGISTER_REGISTRY(Stats) + REGISTRY_SORT(Stats) REGISTRY_CHECK(Stats) STATIC_INIT(RegisterStats_renumber) { diff --cc qcsrc/server/g_damage.qc index 5d9436f68,dc306eee0..dcd75023e --- a/qcsrc/server/g_damage.qc +++ b/qcsrc/server/g_damage.qc @@@ -262,6 -259,8 +259,8 @@@ float Obituary_WeaponDeath return false; } -.int buffs; // TODO: remove ++.int buffs = _STAT(BUFFS); // TODO: remove + void Obituary(entity attacker, entity inflictor, entity targ, int deathtype) { // Sanity check