From: Martin Taibr Date: Mon, 1 Jul 2019 16:22:58 +0000 (+0200) Subject: Merge branch 'master' into martin-t/globals X-Git-Tag: xonotic-v0.8.5~1258^2~5 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fxonotic-data.pk3dir.git;a=commitdiff_plain;h=991de5e6922cd3c283de56c3249624f0f1bfe767;hp=-c Merge branch 'master' into martin-t/globals --- 991de5e6922cd3c283de56c3249624f0f1bfe767 diff --combined qcsrc/client/csqcmodel_hooks.qc index 06f66557a0,a064195560..1dfc006c35 --- a/qcsrc/client/csqcmodel_hooks.qc +++ b/qcsrc/client/csqcmodel_hooks.qc @@@ -341,10 -341,10 +341,10 @@@ void CSQCPlayer_FallbackFrame_PostUpdat // player "pops in" if(isnew) { - #define FIX_FRAMETIME(f,ft) MACRO_BEGIN { \ - if(IS_DEAD_FRAME(this.f) && this.ft != 0 && this.death_time != 0) \ - this.ft = this.death_time; \ - } MACRO_END + #define FIX_FRAMETIME(f,ft) MACRO_BEGIN \ + if(IS_DEAD_FRAME(this.f) && this.ft != 0 && this.death_time != 0) \ + this.ft = this.death_time; \ + MACRO_END FIX_FRAMETIME(frame, frame1time); FIX_FRAMETIME(frame2, frame2time); #ifdef CSQCMODEL_HAVE_TWO_FRAMES @@@ -441,7 -441,7 +441,7 @@@ void CSQCModel_AutoTagIndex_Apply(entit LOG_TRACE("h_ model lacks weapon attachment, but v_ model is attached to it"); } } - else if(this.tag_entity.isplayermodel) + else if((this.tag_entity.isplayermodel & ISPLAYER_MODEL)) { skeleton_loadinfo(this.tag_entity); this.tag_index = this.tag_entity.bone_weapon; @@@ -540,11 -540,8 +540,11 @@@ void CSQCModel_Effects_Apply(entity thi tref = EFFECT_TR_BLOOD.m_id; if(this.csqcmodel_modelflags & MF_ROTATE) { + // This will be hard to replace with MAKE_VECTORS because it's called as part of the predraw function + // as documented in csprogs.h in the engine. The globals can then be read in many places in the engine. + // However MR_ROTATE is currently only used in one place - might be possible to get rid of it entirely. this.renderflags |= RF_USEAXIS; - MAKEVECTORS(makevectors, this.angles + '0 100 0' * fmod(time, 3.6), v_forward, v_right, v_up); + makevectors(this.angles + '0 100 0' * fmod(time, 3.6)); } if(this.csqcmodel_modelflags & MF_TRACER) tref = EFFECT_TR_WIZSPIKE.m_id; @@@ -604,12 -601,17 +604,17 @@@ void CSQCModel_Hook_PreDraw(entity this if(!this.modelindex || this.model == "null" || this.alpha < 0) { this.drawmask = 0; + if(this.snd_looping > 0) + { + sound(this, this.snd_looping, SND_Null, VOL_BASE, autocvar_cl_jetpack_attenuation); + this.snd_looping = 0; + } return; } else this.drawmask = MASK_NORMAL; - if(this.isplayermodel && this.drawmask) // this checks if it's a player MODEL! + if((this.isplayermodel & ISPLAYER_MODEL) && this.drawmask) // this checks if it's a player MODEL! { CSQCPlayer_ModelAppearance_Apply(this, (this.isplayermodel & ISPLAYER_LOCAL)); CSQCPlayer_LOD_Apply(this); @@@ -700,7 -702,7 +705,7 @@@ void CSQCModel_Hook_PreUpdate(entity th this.iflags |= IFLAG_V_ANGLE_X; // revert to values from server CSQCModel_Effects_PreUpdate(this); - if(this.isplayermodel) + if((this.isplayermodel & ISPLAYER_MODEL)) { if(!isplayer) CSQCPlayer_FallbackFrame_PreUpdate(this); @@@ -716,7 -718,7 +721,7 @@@ void CSQCModel_Hook_PostUpdate(entity t this.isplayermodel = BITSET(this.isplayermodel, ISPLAYER_MODEL, is_playermodel); // save values set by server - if(this.isplayermodel) + if((this.isplayermodel & ISPLAYER_MODEL)) { CSQCPlayer_ModelAppearance_PostUpdate(this); if(isplayer) diff --combined qcsrc/client/view.qc index 3f76cb5906,322abb87e0..13c766f471 --- a/qcsrc/client/view.qc +++ b/qcsrc/client/view.qc @@@ -76,54 -76,46 +76,46 @@@ float autocvar_cl_leanmodel_lowpass = 0 ret = ref_store = ref_store * (1 - frac) + (value) * frac; #define lowpass_limited(value, frac, limit, ref_store, ret) MACRO_BEGIN \ - { \ float __ignore; lowpass(value, frac, ref_store, __ignore); \ ret = ref_store = bound((value) - (limit), ref_store, (value) + (limit)); \ - } MACRO_END + MACRO_END #define highpass(value, frac, ref_store, ret) MACRO_BEGIN \ - { \ float __f = 0; lowpass(value, frac, ref_store, __f); \ ret = (value) - __f; \ - } MACRO_END + MACRO_END #define highpass_limited(value, frac, limit, ref_store, ret) MACRO_BEGIN \ - { \ float __f = 0; lowpass_limited(value, frac, limit, ref_store, __f); \ ret = (value) - __f; \ - } MACRO_END + MACRO_END #define lowpass2(value, frac, ref_store, ref_out) MACRO_BEGIN \ - { \ lowpass(value.x, frac, ref_store.x, ref_out.x); \ lowpass(value.y, frac, ref_store.y, ref_out.y); \ - } MACRO_END + MACRO_END #define highpass2(value, frac, ref_store, ref_out) MACRO_BEGIN \ - { \ highpass(value.x, frac, ref_store.x, ref_out.x); \ highpass(value.y, frac, ref_store.y, ref_out.y); \ - } MACRO_END + MACRO_END #define highpass2_limited(value, frac, limit, ref_store, ref_out) MACRO_BEGIN \ - { \ highpass_limited(value.x, frac, limit, ref_store.x, ref_out.x); \ highpass_limited(value.y, frac, limit, ref_store.y, ref_out.y); \ - } MACRO_END + MACRO_END #define lowpass3(value, frac, ref_store, ref_out) MACRO_BEGIN \ - { \ lowpass(value.x, frac, ref_store.x, ref_out.x); \ lowpass(value.y, frac, ref_store.y, ref_out.y); \ lowpass(value.z, frac, ref_store.z, ref_out.z); \ - } MACRO_END + MACRO_END #define highpass3(value, frac, ref_store, ref_out) MACRO_BEGIN \ - { \ highpass(value.x, frac, ref_store.x, ref_out.x); \ highpass(value.y, frac, ref_store.y, ref_out.y); \ highpass(value.z, frac, ref_store.z, ref_out.z); \ - } MACRO_END + MACRO_END void calc_followmodel_ofs(entity view) { @@@ -141,7 -133,8 +133,7 @@@ vel = view.velocity; else { - vector forward = '0 0 0', right = '0 0 0', up = '0 0 0'; - MAKEVECTORS(makevectors, view_angles, forward, right, up); + MAKE_VECTORS_NEW(view_angles, forward, right, up); vel.x = view.velocity * forward; vel.y = view.velocity * right * -1; vel.z = view.velocity * up; @@@ -166,7 -159,8 +158,7 @@@ if (autocvar_cl_followmodel_velocity_absolute) { vector fixed_gunorg; - vector forward = '0 0 0', right = '0 0 0', up = '0 0 0'; - MAKEVECTORS(makevectors, view_angles, forward, right, up); + MAKE_VECTORS_NEW(view_angles, forward, right, up); fixed_gunorg.x = gunorg * forward; fixed_gunorg.y = gunorg * right * -1; fixed_gunorg.z = gunorg * up; @@@ -423,14 -417,14 +415,14 @@@ void Porto_Draw(entity this vector pos = view_origin; vector dir = view_forward; - makevectors(((autocvar_chase_active) ? warpzone_save_view_angles : view_angles)); - pos += v_right * -wepent.movedir.y - + v_up * wepent.movedir.z; + MAKE_VECTORS_NEW(autocvar_chase_active ? warpzone_save_view_angles : view_angles, forward, right, up); + pos += right * -wepent.movedir.y + + up * wepent.movedir.z; if (wepent.angles_held_status) { - makevectors(wepent.angles_held); - dir = v_forward; + MAKE_VECTORS(wepent.angles_held, forward, right, up); + dir = forward; } wepent.polyline[0] = pos; @@@ -457,8 -451,8 +449,8 @@@ { vector ang = vectoangles2(trace_plane_normal, dir); ang.x = -ang.x; - makevectors(ang); - if (!CheckWireframeBox(this, pos - 48 * v_right - 48 * v_up + 16 * v_forward, 96 * v_right, 96 * v_up, 96 * v_forward)) + MAKE_VECTORS(ang, forward, right, up); + if (!CheckWireframeBox(this, pos - 48 * right - 48 * up + 16 * forward, 96 * right, 96 * up, 96 * forward)) { n = max(2, idx); break; @@@ -577,15 -571,15 +569,15 @@@ vector GetCurrentFov(float fov curspeed = 0; else { - makevectors(view_angles); + MAKE_VECTORS_NEW(view_angles, forward, right, up); v = pmove_vel; if(csqcplayer) v = csqcplayer.velocity; switch(autocvar_cl_velocityzoom_type) { - case 3: curspeed = max(0, v_forward * v); break; - case 2: curspeed = (v_forward * v); break; + case 3: curspeed = max(0, forward * v); break; + case 2: curspeed = (forward * v); break; case 1: default: curspeed = vlen(v); break; } } @@@ -1354,21 -1348,22 +1346,22 @@@ void HUD_Crosshair(entity this } #define CROSSHAIR_DO_BLUR(M,sz,wcross_name,wcross_alpha) \ - MACRO_BEGIN { \ + MACRO_BEGIN \ + vector scaled_sz = sz * wcross_size; \ if(wcross_blur > 0) \ { \ for(i = -2; i <= 2; ++i) \ for(j = -2; j <= 2; ++j) \ - M(i,j,sz,wcross_name,wcross_alpha*0.04); \ + M(i,j,sz,scaled_sz,wcross_name,wcross_alpha*0.04); \ } \ else \ { \ - M(0,0,sz,wcross_name,wcross_alpha); \ + M(0,0,sz,scaled_sz,wcross_name,wcross_alpha); \ } \ - } MACRO_END + MACRO_END - #define CROSSHAIR_DRAW_SINGLE(i,j,sz,wcross_name,wcross_alpha) \ - drawpic(wcross_origin - ('0.5 0 0' * (sz * wcross_size.x + i * wcross_blur) + '0 0.5 0' * (sz * wcross_size.y + j * wcross_blur)), wcross_name, sz * wcross_size, wcross_color, wcross_alpha, DRAWFLAG_NORMAL) + #define CROSSHAIR_DRAW_SINGLE(i,j,sz,scaled_sz,wcross_name,wcross_alpha) \ + drawpic(wcross_origin - ('0.5 0 0' * (scaled_sz.x + i * wcross_blur) + '0 0.5 0' * (scaled_sz.y + j * wcross_blur)), wcross_name, scaled_sz, wcross_color, wcross_alpha, DRAWFLAG_NORMAL) #define CROSSHAIR_DRAW(sz,wcross_name,wcross_alpha) \ CROSSHAIR_DO_BLUR(CROSSHAIR_DRAW_SINGLE,sz,wcross_name,wcross_alpha) @@@ -1589,6 -1584,15 +1582,15 @@@ void HUD_Mouse(entity player return; } + if (cursor_active == -1) // starting to display the cursor + { + // since HUD_Mouse is called by CSQC_UpdateView before CSQC_InputEvent, + // in the first frame mousepos is the mouse position of the last time + // the cursor was displayed, thus we ignore it to avoid a glictch + cursor_active = 1; + return; + } + if(!autocvar_hud_cursormode) update_mousepos(); @@@ -1806,18 -1810,18 +1808,18 @@@ void CSQC_UpdateView(entity this, floa else if(eventchase_current_distance != chase_distance) eventchase_current_distance = chase_distance; - makevectors(view_angles); + MAKE_VECTORS_NEW(view_angles, forward, right, up); - vector eventchase_target_origin = (current_view_origin - (v_forward * eventchase_current_distance)); + vector eventchase_target_origin = (current_view_origin - (forward * eventchase_current_distance)); WarpZone_TraceBox(current_view_origin, autocvar_cl_eventchase_mins, autocvar_cl_eventchase_maxs, eventchase_target_origin, MOVE_WORLDONLY, this); // If the boxtrace fails, revert back to line tracing. if(!local_player.viewloc) if(trace_startsolid) { - eventchase_target_origin = (current_view_origin - (v_forward * eventchase_current_distance)); + eventchase_target_origin = (current_view_origin - (forward * eventchase_current_distance)); WarpZone_TraceLine(current_view_origin, eventchase_target_origin, MOVE_WORLDONLY, this); - setproperty(VF_ORIGIN, (trace_endpos - (v_forward * autocvar_cl_eventchase_mins.z))); + setproperty(VF_ORIGIN, (trace_endpos - (forward * autocvar_cl_eventchase_mins.z))); } else { setproperty(VF_ORIGIN, trace_endpos); } @@@ -1944,7 -1948,7 +1946,7 @@@ // Render the Scene view_origin = getpropertyvec(VF_ORIGIN); view_angles = getpropertyvec(VF_ANGLES); - MAKEVECTORS(makevectors, view_angles, view_forward, view_right, view_up); + MAKE_VECTORS(view_angles, view_forward, view_right, view_up); #ifdef BLURTEST if(time > blurtest_time0 && time < blurtest_time1) @@@ -2017,13 -2021,13 +2019,13 @@@ { if(!minigame_wasactive) { - localcmd("+button14\n"); + localcmd("+button12\n"); minigame_wasactive = true; } } else if(minigame_wasactive) { - localcmd("-button14\n"); + localcmd("-button12\n"); minigame_wasactive = false; } @@@ -2184,7 -2188,7 +2186,7 @@@ R_EndPolygon(); } - if(autocvar_cl_reticle) + if(autocvar_cl_reticle && !MUTATOR_CALLHOOK(DrawReticle)) { string reticle_image = string_null; bool wep_zoomed = false; @@@ -2495,14 -2499,14 +2497,14 @@@ setproperty(VF_ORIGIN, '0 0 0'); setproperty(VF_ANGLES, '0 0 0'); setproperty(VF_PERSPECTIVE, 1); - makevectors('0 0 0'); + MAKE_VECTORS_NEW('0 0 0', forward, right, up); vector v1, v2; cvar_set("vid_conwidth", "800"); cvar_set("vid_conheight", "600"); - v1 = cs_project(v_forward); + v1 = cs_project(forward); cvar_set("vid_conwidth", "640"); cvar_set("vid_conheight", "480"); - v2 = cs_project(v_forward); + v2 = cs_project(forward); if(v1 == v2) cs_project_is_b0rked = 1; else diff --combined qcsrc/common/debug.qh index 2242dc0a27,55b634a624..05064ca967 --- a/qcsrc/common/debug.qh +++ b/qcsrc/common/debug.qh @@@ -205,8 -205,7 +205,7 @@@ GENERIC_COMMAND(bufstr_get, "Examine a { int bufhandle = stof(argv(1)); int string_index = stof(argv(2)); - string s = bufstr_get(bufhandle, string_index); - LOG_INFOF("%s", s); + LOG_INFO(bufstr_get(bufhandle, string_index)); return; } @@@ -296,7 -295,7 +295,7 @@@ MUTATOR_HOOKFUNCTION(trace, SV_StartFra it.solid = SOLID_BBOX; }); vector forward = '0 0 0'; vector right = '0 0 0'; vector up = '0 0 0'; - MAKEVECTORS(makevectors, it.v_angle, forward, right, up); + MAKE_VECTORS(it.v_angle, forward, right, up); vector pos = it.origin + it.view_ofs; traceline(pos, pos + forward * max_shot_distance, MOVE_NORMAL, it); FOREACH_ENTITY(true, { @@@ -407,7 -406,7 +406,7 @@@ CLASS(DebugText3d, Object CONSTRUCT(DebugText3d); this.origin = pos; this.message = strzone(msg); - SetResourceAmount(this, RESOURCE_HEALTH, align); + SetResource(this, RES_HEALTH, align); this.hit_time = time; this.fade_rate = fade_rate_; this.velocity = vel; @@@ -432,7 -431,7 +431,7 @@@ if (screen_pos.z < 0) return; // behind camera screen_pos.z = 0; - float align = GetResourceAmount(this, RESOURCE_HEALTH); + float align = GetResource(this, RES_HEALTH); string msg; vector msg_pos; diff --combined qcsrc/common/mutators/mutator/damagetext/cl_damagetext.qc index df0467dbf3,5e59fd9f32..c2fdb62291 --- a/qcsrc/common/mutators/mutator/damagetext/cl_damagetext.qc +++ b/qcsrc/common/mutators/mutator/damagetext/cl_damagetext.qc @@@ -74,9 -74,9 +74,9 @@@ CLASS(DamageText, Object if (this.m_screen_coords) { screen_pos = this.origin + since_hit * autocvar_cl_damagetext_2d_velocity; } else { - makevectors(view_angles); + MAKE_VECTORS_NEW(view_angles, forward, right, up); vector world_offset = since_hit * autocvar_cl_damagetext_velocity_world + autocvar_cl_damagetext_offset_world; - vector world_pos = this.origin + world_offset.x * v_forward + world_offset.y * v_right + world_offset.z * v_up; + vector world_pos = this.origin + world_offset.x * forward + world_offset.y * right + world_offset.z * up; screen_pos = project_3d_to_2d(world_pos) + since_hit * autocvar_cl_damagetext_velocity_screen + autocvar_cl_damagetext_offset_screen; } screen_pos.y += size / 2; @@@ -237,7 -237,7 +237,7 @@@ NET_HANDLE(damagetext, bool isNew if (can_use_3d && !prefer_2d) { // world coords - // using 1 as minimum because of shotgun (same as menu) + // 1 as min because shotgun sends damagetext per pellet (see https://gitlab.com/xonotic/xonotic-data.pk3dir/issues/1994). for (entity e = findradius(entcs.origin, max(autocvar_cl_damagetext_accumulate_range, 1)); e; e = e.chain) { if (e.instanceOfDamageText && !e.m_screen_coords // we're using origin for both world coords and screen coords so avoid mismatches diff --combined qcsrc/common/mutators/mutator/spawn_near_teammate/sv_spawn_near_teammate.qc index 8952bd6e57,73435841d8..2243c9872c --- a/qcsrc/common/mutators/mutator/spawn_near_teammate/sv_spawn_near_teammate.qc +++ b/qcsrc/common/mutators/mutator/spawn_near_teammate/sv_spawn_near_teammate.qc @@@ -91,11 -91,11 +91,11 @@@ MUTATOR_HOOKFUNCTION(spawn_near_teammat if (PHYS_INPUT_BUTTON_CHAT(it)) continue; if (DIFF_TEAM(player, it)) continue; - if (autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health && GetResourceAmount(it, RESOURCE_HEALTH) < autocvar_g_balance_health_regenstable) continue; + if (autocvar_g_spawn_near_teammate_ignore_spawnpoint_check_health && GetResource(it, RES_HEALTH) < autocvar_g_balance_health_regenstable) continue; if (IS_DEAD(it)) continue; if (time < it.msnt_timer) continue; if (time < it.spawnshieldtime) continue; - if (forbidWeaponUse(it)) continue; + if (weaponLocked(it)) continue; if (it == player) continue; tested++; // i consider a teammate to be available when he passes the checks above @@@ -103,15 -103,10 +103,15 @@@ vector horiz_vel = vec2(it.velocity); // when walking slowly sideways, we assume the player wants a clear shot ahead - spawn behind him according to where he's looking // when running fast, spawn behind him according to his direction of movement to prevent colliding with the newly spawned player + vector forward = '0 0 0'; vector right = '0 0 0'; vector up = '0 0 0'; if (vdist(horiz_vel, >, autocvar_sv_maxspeed + 50)) - fixedmakevectors(vectoangles(horiz_vel)); + { + FIXED_MAKE_VECTORS(vectoangles(horiz_vel), forward, right, up); + } else - fixedmakevectors(it.angles); // .angles is the angle of the model - usually/always 0 pitch + { + FIXED_MAKE_VECTORS(it.angles, forward, right, up); + } // test different spots close to mate - trace upwards so it works on uneven surfaces // don't spawn in front of player or directly behind to avoid players shooting each other @@@ -122,22 -117,22 +122,22 @@@ switch(i) { case 0: - tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - v_forward * 64 + v_right * 128 + v_up * 64, MOVE_NOMONSTERS, it); + tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - forward * 64 + right * 128 + up * 64, MOVE_NOMONSTERS, it); break; case 1: - tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - v_forward * 64 - v_right * 128 + v_up * 64, MOVE_NOMONSTERS, it); + tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - forward * 64 - right * 128 + up * 64, MOVE_NOMONSTERS, it); break; case 2: - tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin + v_right * 192 + v_up * 64, MOVE_NOMONSTERS, it); + tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin + right * 192 + up * 64, MOVE_NOMONSTERS, it); break; case 3: - tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - v_right * 192 + v_up * 64, MOVE_NOMONSTERS, it); + tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - right * 192 + up * 64, MOVE_NOMONSTERS, it); break; case 4: - tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - v_forward * 128 + v_right * 64 + v_up * 64, MOVE_NOMONSTERS, it); + tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - forward * 128 + right * 64 + up * 64, MOVE_NOMONSTERS, it); break; case 5: - tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - v_forward * 128 - v_right * 64 + v_up * 64, MOVE_NOMONSTERS, it); + tracebox(it.origin, STAT(PL_MIN, player), STAT(PL_MAX, player), it.origin - forward * 128 - right * 64 + up * 64, MOVE_NOMONSTERS, it); break; } @@@ -147,7 -142,7 +147,7 @@@ // 400 is about the height of a typical laser jump (in overkill) // not traceline because we need space for the whole player, not just his origin - tracebox(horizontal_trace_endpos, STAT(PL_MIN, player), STAT(PL_MAX, player), horizontal_trace_endpos - '0 0 400', MOVE_NORMAL, it); + tracebox(horizontal_trace_endpos, STAT(PL_MIN, player), STAT(PL_MAX, player), horizontal_trace_endpos - 400 * up, MOVE_NORMAL, it); vector vectical_trace_endpos = trace_endpos; //te_lightning1(NULL, horizontal_trace_endpos, vectical_trace_endpos); if (trace_startsolid) goto skip; // inside another player @@@ -157,9 -152,8 +157,9 @@@ if (tracebox_hits_trigger_hurt(horizontal_trace_endpos, STAT(PL_MIN, player), STAT(PL_MAX, player), vectical_trace_endpos)) goto skip; // make sure the spawned player will have floor ahead (or at least a wall - he shouldn't fall as soon as he starts moving) - vector floor_test_start = vectical_trace_endpos + v_up * STAT(PL_MAX, player).z + v_forward * STAT(PL_MAX, player).x; // top front of player's bbox - highest point we know is not inside solid - traceline(floor_test_start, floor_test_start + v_forward * 100 - v_up * 128, MOVE_NOMONSTERS, it); + // top front of player's bbox - highest point we know is not inside solid + vector floor_test_start = vectical_trace_endpos + up * STAT(PL_MAX, player).z + forward * STAT(PL_MAX, player).x; + traceline(floor_test_start, floor_test_start + forward * 100 - up * 128, MOVE_NOMONSTERS, it); //te_beam(NULL, floor_test_start, trace_endpos); if (trace_fraction == 1.0) goto skip; @@@ -177,7 -171,7 +177,7 @@@ // here, we know we found a good spot RandomSelection_Add(it, 0, string_null, vectical_trace_endpos, 1, 1); - //te_lightning1(NULL, vectical_trace_endpos, vectical_trace_endpos + v_forward * 10); + //te_lightning1(NULL, vectical_trace_endpos, vectical_trace_endpos + forward * 10); LABEL(skip) if (i % 2 == 1 && RandomSelection_chosen_ent) diff --combined qcsrc/common/weapons/weapon/shockwave.qc index 5a8b1f4474,cdd0a0f92a..8fe3a4866e --- a/qcsrc/common/weapons/weapon/shockwave.qc +++ b/qcsrc/common/weapons/weapon/shockwave.qc @@@ -658,12 -658,14 +658,12 @@@ void Draw_Shockwave(entity this if(a < ALPHA_MIN_VISIBLE) { delete(this); } // WEAPONTODO: save this only once when creating the entity - vector sw_color = entcs_GetColor(this.sv_entnum - 1); // GetTeamRGB(entcs_GetTeam(this.sv_entnum)); + vector sw_color = entcs_GetColor(this.sv_entnum - 1); // Team_ColorRGB(entcs_GetTeam(this.sv_entnum)); // WEAPONTODO: trace to find what we actually hit vector endpos = (this.sw_shotorg + (this.sw_shotdir * this.sw_distance)); - vectorvectors(this.sw_shotdir); - vector right = v_right; // save this for when we do makevectors later - vector up = v_up; // save this for when we do makevectors later + VECTOR_VECTORS_NEW(this.sw_shotdir, _forward, right, up); // WEAPONTODO: combine and simplify these calculations vector min_end = ((this.sw_shotorg + (this.sw_shotdir * SW_DISTTOMIN)) + (up * this.sw_spread_min)); diff --combined qcsrc/lib/_all.inc index e2dead33b2,ab74531605..3bbb17ccf8 --- a/qcsrc/lib/_all.inc +++ b/qcsrc/lib/_all.inc @@@ -112,11 -112,9 +112,11 @@@ #include "counting.qh" #include "cvar.qh" #include "defer.qh" +#include "deglobalization.qh" #include "draw.qh" #include "enumclass.qh" #include "file.qh" +#include "float.qh" #include "functional.qh" #include "i18n.qh" #include "intrusivelist.qh" @@@ -164,14 -162,14 +164,14 @@@ void make_safe_for_remove(entity this) #define objerror_safe(e) make_safe_for_remove(e) #endif - #define objerror(this, msg) MACRO_BEGIN { \ + #define objerror(this, msg) MACRO_BEGIN \ LOG_WARN("======OBJECT ERROR======"); \ entity _e = (this); \ eprint(_e); \ objerror_safe(_e); \ delete(_e); \ LOG_WARNF("%s OBJECT ERROR in %s:\n%s\nTip: read above for entity information", PROGNAME, __FUNC__, msg); \ - } MACRO_END + MACRO_END #ifdef MENUQC void _m_init(); diff --combined qcsrc/lib/deglobalization.qh index bd43ab1194,0000000000..55dbbe525d mode 100644,000000..100644 --- a/qcsrc/lib/deglobalization.qh +++ b/qcsrc/lib/deglobalization.qh @@@ -1,90 -1,0 +1,90 @@@ +#include "lib/float.qh" +#include "lib/misc.qh" +#include "lib/static.qh" +#include "lib/vector.qh" + +// These macros wrap functions which use globals so mutation only occurs inside them and is not visible from outside. +// Functions for which all usages are replaced with these macros can be hidden by #defines inside our `*defs.qh` files +// to prevent anyone from using them accidentally in the future + +// TODO stuff in the engine that uses the v_forward/v_right/v_up globals and is not wrapped yet: +// - RF_USEAXIS, addentities, predraw, +// - CL_GetEntityMatrix (in engine but is called from other functions so transitively any of them can use the globals - e.g. V_CalcRefdef, maybe others) +// - however RF_USEAXIS is only used if MF_ROTATE is used which is only set in one place +// - e.camera_transform / CL_VM_TransformView (in engine) +// - this is the only used function that both sets and gets the globals (aim does too but isn't used in our code) + +// convenience for deglobalization code - don't use these just to hide that globals are still used +#define CLEAR_V_GLOBALS() v_forward = VEC_NAN; v_right = VEC_NAN; v_up = VEC_NAN +#define GET_V_GLOBALS(forward, right, up) forward = v_forward; right = v_right; up = v_up +#define SET_V_GLOBALS(forward, right, up) v_forward = forward; v_right = right; v_up = up + +#ifdef GAMEQC +STATIC_INIT(globals) { + // set to NaN to more easily detect uninitialized use + // TODO when all functions are wrapped and the raw functions are not used anymore, + // uncomment the defines in *progs.qh files that hide the raw functions + // and assert that the global vectors are NaN before calling the raw functions here + // to make sure nobody (even builtins) is accidentally using them - NaN is the most likely value to expose remaining usages + + CLEAR_V_GLOBALS(); +} +#endif + +/// Same as the `makevectors` builtin but uses the provided locals instead of the `v_*` globals. +/// Always use this instead of raw `makevectors` to make the data flow clear. +/// Note that you might prefer `FIXED_MAKE_VECTORS` for new code. - #define MAKE_VECTORS(angles, forward, right, up) MACRO_BEGIN { \ ++#define MAKE_VECTORS(angles, forward, right, up) MACRO_BEGIN \ + _makevectors_hidden(angles); \ + GET_V_GLOBALS(forward, right, up); \ + CLEAR_V_GLOBALS(); \ - } MACRO_END ++MACRO_END + +/// Same as `MAKE_VECTORS` but also creates the locals for convenience. +#define MAKE_VECTORS_NEW(angles, forward, right, up) \ + vector forward = '0 0 0', right = '0 0 0', up = '0 0 0'; \ + MAKE_VECTORS(angles, forward, right, up); + +/// Returns all 4 vectors by assigning to them (instead of returning a value) for consistency (and sanity) - #define SKEL_GET_BONE_ABS(skel, bonenum, forward, right, up, origin) MACRO_BEGIN { \ ++#define SKEL_GET_BONE_ABS(skel, bonenum, forward, right, up, origin) MACRO_BEGIN \ + origin = _skel_get_boneabs_hidden(skel, bonenum) \ + GET_V_GLOBALS(forward, right, up); \ + CLEAR_V_GLOBALS(); \ - } MACRO_END ++MACRO_END + +#define SKEL_GET_BONE_ABS_NEW(skel, bonenum, forward, right, up, origin) \ + vector forward = '0 0 0', right = '0 0 0', up = '0 0 0', origin = '0 0 0'; \ + SKEL_GET_BONE_ABS(skel, bonenum, forward, right, up, origin) + - #define SKEL_SET_BONE(skel, bonenum, org, forward, right, up) MACRO_BEGIN { \ ++#define SKEL_SET_BONE(skel, bonenum, org, forward, right, up) MACRO_BEGIN \ + SET_V_GLOBALS(forward, right, up); \ + _skel_set_bone_hidden(skel, bonenum, org); \ + CLEAR_V_GLOBALS(); \ - } MACRO_END ++MACRO_END + - #define ADD_DYNAMIC_LIGHT(org, radius, lightcolours, forward, right, up) MACRO_BEGIN { \ ++#define ADD_DYNAMIC_LIGHT(org, radius, lightcolours, forward, right, up) MACRO_BEGIN \ + SET_V_GLOBALS(forward, right, up); \ + _adddynamiclight_hidden(org, radius, lightcolours); \ + CLEAR_V_GLOBALS(); \ - } MACRO_END ++MACRO_END + - #define VECTOR_VECTORS(forward_in, forward, right, up) MACRO_BEGIN { \ ++#define VECTOR_VECTORS(forward_in, forward, right, up) MACRO_BEGIN \ + _vectorvectors_hidden(forward_in); \ + GET_V_GLOBALS(forward, right, up); \ + CLEAR_V_GLOBALS(); \ - } MACRO_END ++MACRO_END + +#define VECTOR_VECTORS_NEW(forward_in, forward, right, up) \ + vector forward = '0 0 0', right = '0 0 0', up = '0 0 0'; \ + VECTOR_VECTORS(forward_in, forward, right, up); + +/// Note that this only avoids the v_* globals, not the gettaginfo_* ones - #define GET_TAG_INFO(ent, tagindex, forward, right, up, origin) MACRO_BEGIN { \ ++#define GET_TAG_INFO(ent, tagindex, forward, right, up, origin) MACRO_BEGIN \ + origin = _gettaginfo_hidden(ent, tagindex); \ + GET_V_GLOBALS(forward, right, up); \ + CLEAR_V_GLOBALS(); \ - } MACRO_END ++MACRO_END + +#define GET_TAG_INFO_NEW(ent, tagindex, forward, right, up, origin) \ + vector forward = '0 0 0', right = '0 0 0', up = '0 0 0', origin = '0 0 0'; \ + GET_TAG_INFO(ent, tagindex, forward, right, up, origin); diff --combined qcsrc/lib/warpzone/anglestransform.qh index 070c81a53f,b287651a10..c11a63185f --- a/qcsrc/lib/warpzone/anglestransform.qh +++ b/qcsrc/lib/warpzone/anglestransform.qh @@@ -6,8 -6,6 +6,8 @@@ #if POSITIVE_PITCH_IS_DOWN #define fixedmakevectors makevectors + #define FIXED_MAKE_VECTORS MAKE_VECTORS + #define FIXED_MAKE_VECTORS_NEW MAKE_VECTORS_NEW noref vector _fixedvectoangles; #define fixedvectoangles(a) (_fixedvectoangles = vectoangles(a), _fixedvectoangles.x *= -1, _fixedvectoangles) noref vector _fixedvectoangles2; @@@ -19,14 -17,6 +19,14 @@@ a.x = -a.x; makevectors(a); } - #define FIXED_MAKE_VECTORS(angles, forward, right, up) MACRO_BEGIN { \ ++ #define FIXED_MAKE_VECTORS(angles, forward, right, up) MACRO_BEGIN \ + fixedmakevectors(angles); \ + GET_V_GLOBALS(forward, right, up); \ + CLEAR_V_GLOBALS(); \ - } MACRO_END ++ MACRO_END + #define FIXED_MAKE_VECTORS_NEW(angles, forward, right, up) \ + VECS_NEW(forward, right, up); \ + FIXED_MAKE_VECTORS(angles, forward, right, up); #define fixedvectoangles2 vectoangles2 #define fixedvectoangles vectoangles #endif diff --combined qcsrc/lib/warpzone/server.qc index 1f24709487,9958a5df4a..780968375e --- a/qcsrc/lib/warpzone/server.qc +++ b/qcsrc/lib/warpzone/server.qc @@@ -10,6 -10,7 +10,7 @@@ #include #include #include + #include #endif #ifdef WARPZONELIB_KEEPDEBUG @@@ -28,12 -29,12 +29,12 @@@ .float warpzone_teleport_finishtime; .entity warpzone_teleport_zone; - #define WarpZone_StoreProjectileData(e_) MACRO_BEGIN { \ + #define WarpZone_StoreProjectileData(e_) MACRO_BEGIN \ entity e = e_; \ e.warpzone_oldorigin = e.origin; \ e.warpzone_oldvelocity = e.velocity; \ e.warpzone_oldangles = e.angles; \ - } MACRO_END + MACRO_END void WarpZone_TeleportPlayer(entity teleporter, entity player, vector to, vector to_angles, vector to_velocity) { @@@ -42,11 -43,17 +43,17 @@@ player.lastteleporttime = time; #endif setorigin(player, to); // NOTE: this also aborts the move, when this is called by touch + player.angles = to_angles; #ifdef SVQC player.oldorigin = to; // for DP's unsticking player.fixangle = true; + if (IS_BOT_CLIENT(player)) + { + // FIXME find a way to smooth view's angles change for bots too + player.v_angle = player.angles; + bot_aim_reset(player); + } #endif - player.angles = to_angles; player.velocity = to_velocity; BITXOR_ASSIGN(player.effects, EF_TELEPORT_BIT); @@@ -595,15 -602,15 +602,15 @@@ void WarpZone_InitStep_UpdateTransform( if(area > 0) { org = org - ((org - point) * norm) * norm; // project to plane - makevectors(ang); - if(norm * v_forward < 0) + MAKE_VECTORS_NEW(ang, forward, right, up); + if(norm * forward < 0) { LOG_INFO("Position target of trigger_warpzone near ", vtos(this.aiment.origin), " points into trigger_warpzone. BEWARE."); norm = -1 * norm; } - ang = vectoangles2(norm, v_up); // keep rotation, but turn exactly against plane + ang = vectoangles2(norm, up); // keep rotation, but turn exactly against plane ang.x = -ang.x; - if(norm * v_forward < 0.99) + if(norm * forward < 0.99) LOG_INFO("trigger_warpzone near ", vtos(this.aiment.origin), " has been turned to match plane orientation (", vtos(this.aiment.angles), " -> ", vtos(ang)); if(vdist(org - this.aiment.origin, >, 0.5)) LOG_INFO("trigger_warpzone near ", vtos(this.aiment.origin), " has been moved to match the plane (", vtos(this.aiment.origin), " -> ", vtos(org), ")."); diff --combined qcsrc/server/weapons/weaponsystem.qc index 362e60cb9e,b75881127a..936b64f2ba --- a/qcsrc/server/weapons/weaponsystem.qc +++ b/qcsrc/server/weapons/weaponsystem.qc @@@ -373,6 -373,10 +373,6 @@@ void weapon_thinkf(entity actor, .entit restartanim = fr != WFRAME_IDLE; } - vector of = v_forward; - vector or = v_right; - vector ou = v_up; - vector a = '0 0 0'; this.wframe = fr; if (fr == WFRAME_IDLE) a = this.anim_idle; @@@ -382,6 -386,10 +382,6 @@@ a = this.anim_reload; a.z *= g_weaponratefactor; - v_forward = of; - v_right = or; - v_up = ou; - if (this.weapon_think == w_ready && func != w_ready && this.state == WS_RAISE) backtrace( "Tried to override initial weapon think function - should this really happen?"); @@@ -427,13 -435,20 +427,20 @@@ } } - bool forbidWeaponUse(entity player) + bool weaponUseForbidden(entity player) + { + if (round_handler_IsActive() && !round_handler_IsRoundStarted()) return true; + if (MUTATOR_CALLHOOK(ForbidWeaponUse, player)) return true; + return false; + } + + bool weaponLocked(entity player) { if (time < game_starttime && !sv_ready_restart_after_countdown) return true; if (player.player_blocked) return true; if (game_stopped) return true; if (STAT(FROZEN, player)) return true; - if (MUTATOR_CALLHOOK(ForbidWeaponUse, player)) return true; + if (MUTATOR_CALLHOOK(LockWeapon, player)) return true; return false; } @@@ -446,15 -461,15 +453,15 @@@ void W_WeaponFrame(Player actor, .entit entity this = actor.(weaponentity); if (frametime) this.weapon_frametime = frametime; - if (!this || GetResourceAmount(actor, RESOURCE_HEALTH) < 1) return; // Dead player can't use weapons and injure impulse commands + if (!this || GetResource(actor, RES_HEALTH) < 1) return; // Dead player can't use weapons and injure impulse commands int button_atck = PHYS_INPUT_BUTTON_ATCK(actor); int button_atck2 = PHYS_INPUT_BUTTON_ATCK2(actor); - if (round_handler_IsActive() && !round_handler_IsRoundStarted()) + if (weaponUseForbidden(actor)) button_atck = button_atck2 = 0; // forbid primary and secondary fire, switching is allowed - if (forbidWeaponUse(actor)) + if (weaponLocked(actor)) { if (this.state != WS_CLEAR) { @@@ -492,7 -507,10 +499,7 @@@ return; } - makevectors(actor.v_angle); - vector fo = v_forward; // save them in case the weapon think functions change it - vector ri = v_right; - vector up = v_up; + MAKE_VECTORS_NEW(actor.v_angle, fo, ri, up); // Change weapon if (this.m_weapon != this.m_switchweapon) @@@ -580,7 -598,7 +587,7 @@@ bool block_weapon = false; { bool key_pressed = PHYS_INPUT_BUTTON_HOOK(actor) && !actor.vehicle; - if (round_handler_IsActive() && !round_handler_IsRoundStarted()) + if (weaponUseForbidden(actor)) key_pressed = false; Weapon off = actor.offhand; @@@ -681,9 -699,9 +688,9 @@@ void W_DecreaseAmmo(Weapon wep, entity w_ent.clip_load -= ammo_use; w_ent.(weapon_load[w_ent.m_weapon.m_id]) = w_ent.clip_load; } - else if (wep.ammo_type != RESOURCE_NONE) + else if (wep.ammo_type != RES_NONE) { - float ammo = GetResourceAmount(actor, wep.ammo_type); + float ammo = GetResource(actor, wep.ammo_type); if (ammo < ammo_use) { backtrace(sprintf( @@@ -696,7 -714,7 +703,7 @@@ ammo )); } - SetResourceAmount(actor, wep.ammo_type, ammo - ammo_use); + SetResource(actor, wep.ammo_type, ammo - ammo_use); } } @@@ -716,17 -734,17 +723,17 @@@ void W_ReloadedAndReady(Weapon thiswep w_ent.clip_load = w_ent.old_clip_load; // restore the ammo counter, in case we still had ammo in the weapon before reloading // if the gun uses no ammo, max out weapon load, else decrease ammo as we increase weapon load - if (!w_ent.reload_ammo_min || (actor.items & IT_UNLIMITED_WEAPON_AMMO) || wpn.ammo_type == RESOURCE_NONE) + if (!w_ent.reload_ammo_min || (actor.items & IT_UNLIMITED_WEAPON_AMMO) || wpn.ammo_type == RES_NONE) { w_ent.clip_load = w_ent.reload_ammo_amount; } else { // make sure we don't add more ammo than we have - float ammo = GetResourceAmount(actor, wpn.ammo_type); + float ammo = GetResource(actor, wpn.ammo_type); float load = min(w_ent.reload_ammo_amount - w_ent.clip_load, ammo); w_ent.clip_load += load; - SetResourceAmount(actor, wpn.ammo_type, ammo - load); + SetResource(actor, wpn.ammo_type, ammo - load); } w_ent.(weapon_load[w_ent.m_weapon.m_id]) = w_ent.clip_load; @@@ -768,9 -786,9 +775,9 @@@ void W_Reload(entity actor, .entity wea if (this.clip_load >= this.reload_ammo_amount) return; // no ammo, so nothing to load - if (e.ammo_type != RESOURCE_NONE) + if (e.ammo_type != RES_NONE) { - if (!GetResourceAmount(actor, e.ammo_type) && this.reload_ammo_min) + if (!GetResource(actor, e.ammo_type) && this.reload_ammo_min) { if (!(actor.items & IT_UNLIMITED_WEAPON_AMMO)) {