mirror of
https://github.com/YGGverse/hlsdk-portable.git
synced 2025-01-23 13:14:51 +00:00
Merge branch 'opfor' into opforfixed
This commit is contained in:
commit
804c0ab03d
@ -1,356 +0,0 @@
|
||||
/* NEON implementation of sin, cos, exp and log
|
||||
|
||||
Inspired by Intel Approximate Math library, and based on the
|
||||
corresponding algorithms of the cephes math library
|
||||
*/
|
||||
|
||||
/* Copyright (C) 2011 Julien Pommier
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
(this is the zlib license)
|
||||
*/
|
||||
|
||||
#include <arm_neon.h>
|
||||
|
||||
typedef float32x4_t v4sf; // vector of 4 float
|
||||
typedef uint32x4_t v4su; // vector of 4 uint32
|
||||
typedef int32x4_t v4si; // vector of 4 uint32
|
||||
|
||||
#define s4f_x(s4f) vgetq_lane_f32(s4f, 0)
|
||||
#define s4f_y(s4f) vgetq_lane_f32(s4f, 1)
|
||||
#define s4f_z(s4f) vgetq_lane_f32(s4f, 2)
|
||||
#define s4f_w(s4f) vgetq_lane_f32(s4f, 3)
|
||||
|
||||
#define c_inv_mant_mask ~0x7f800000u
|
||||
#define c_cephes_SQRTHF 0.707106781186547524
|
||||
#define c_cephes_log_p0 7.0376836292E-2
|
||||
#define c_cephes_log_p1 - 1.1514610310E-1
|
||||
#define c_cephes_log_p2 1.1676998740E-1
|
||||
#define c_cephes_log_p3 - 1.2420140846E-1
|
||||
#define c_cephes_log_p4 + 1.4249322787E-1
|
||||
#define c_cephes_log_p5 - 1.6668057665E-1
|
||||
#define c_cephes_log_p6 + 2.0000714765E-1
|
||||
#define c_cephes_log_p7 - 2.4999993993E-1
|
||||
#define c_cephes_log_p8 + 3.3333331174E-1
|
||||
#define c_cephes_log_q1 -2.12194440e-4
|
||||
#define c_cephes_log_q2 0.693359375
|
||||
|
||||
/* natural logarithm computed for 4 simultaneous float
|
||||
return NaN for x <= 0
|
||||
*/
|
||||
inline v4sf log_ps(v4sf x) {
|
||||
v4sf one = vdupq_n_f32(1);
|
||||
|
||||
x = vmaxq_f32(x, vdupq_n_f32(0)); /* force flush to zero on denormal values */
|
||||
v4su invalid_mask = vcleq_f32(x, vdupq_n_f32(0));
|
||||
|
||||
v4si ux = vreinterpretq_s32_f32(x);
|
||||
|
||||
v4si emm0 = vshrq_n_s32(ux, 23);
|
||||
|
||||
/* keep only the fractional part */
|
||||
ux = vandq_s32(ux, vdupq_n_s32(c_inv_mant_mask));
|
||||
ux = vorrq_s32(ux, vreinterpretq_s32_f32(vdupq_n_f32(0.5f)));
|
||||
x = vreinterpretq_f32_s32(ux);
|
||||
|
||||
emm0 = vsubq_s32(emm0, vdupq_n_s32(0x7f));
|
||||
v4sf e = vcvtq_f32_s32(emm0);
|
||||
|
||||
e = vaddq_f32(e, one);
|
||||
|
||||
/* part2:
|
||||
if( x < SQRTHF ) {
|
||||
e -= 1;
|
||||
x = x + x - 1.0;
|
||||
} else { x = x - 1.0; }
|
||||
*/
|
||||
v4su mask = vcltq_f32(x, vdupq_n_f32(c_cephes_SQRTHF));
|
||||
v4sf tmp = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(x), mask));
|
||||
x = vsubq_f32(x, one);
|
||||
e = vsubq_f32(e, vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(one), mask)));
|
||||
x = vaddq_f32(x, tmp);
|
||||
|
||||
v4sf z = vmulq_f32(x,x);
|
||||
|
||||
v4sf y = vdupq_n_f32(c_cephes_log_p0);
|
||||
y = vmulq_f32(y, x);
|
||||
y = vaddq_f32(y, vdupq_n_f32(c_cephes_log_p1));
|
||||
y = vmulq_f32(y, x);
|
||||
y = vaddq_f32(y, vdupq_n_f32(c_cephes_log_p2));
|
||||
y = vmulq_f32(y, x);
|
||||
y = vaddq_f32(y, vdupq_n_f32(c_cephes_log_p3));
|
||||
y = vmulq_f32(y, x);
|
||||
y = vaddq_f32(y, vdupq_n_f32(c_cephes_log_p4));
|
||||
y = vmulq_f32(y, x);
|
||||
y = vaddq_f32(y, vdupq_n_f32(c_cephes_log_p5));
|
||||
y = vmulq_f32(y, x);
|
||||
y = vaddq_f32(y, vdupq_n_f32(c_cephes_log_p6));
|
||||
y = vmulq_f32(y, x);
|
||||
y = vaddq_f32(y, vdupq_n_f32(c_cephes_log_p7));
|
||||
y = vmulq_f32(y, x);
|
||||
y = vaddq_f32(y, vdupq_n_f32(c_cephes_log_p8));
|
||||
y = vmulq_f32(y, x);
|
||||
|
||||
y = vmulq_f32(y, z);
|
||||
|
||||
|
||||
tmp = vmulq_f32(e, vdupq_n_f32(c_cephes_log_q1));
|
||||
y = vaddq_f32(y, tmp);
|
||||
|
||||
|
||||
tmp = vmulq_f32(z, vdupq_n_f32(0.5f));
|
||||
y = vsubq_f32(y, tmp);
|
||||
|
||||
tmp = vmulq_f32(e, vdupq_n_f32(c_cephes_log_q2));
|
||||
x = vaddq_f32(x, y);
|
||||
x = vaddq_f32(x, tmp);
|
||||
x = vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(x), invalid_mask)); // negative arg will be NAN
|
||||
return x;
|
||||
}
|
||||
|
||||
#define c_exp_hi 88.3762626647949f
|
||||
#define c_exp_lo -88.3762626647949f
|
||||
|
||||
#define c_cephes_LOG2EF 1.44269504088896341
|
||||
#define c_cephes_exp_C1 0.693359375
|
||||
#define c_cephes_exp_C2 -2.12194440e-4
|
||||
|
||||
#define c_cephes_exp_p0 1.9875691500E-4
|
||||
#define c_cephes_exp_p1 1.3981999507E-3
|
||||
#define c_cephes_exp_p2 8.3334519073E-3
|
||||
#define c_cephes_exp_p3 4.1665795894E-2
|
||||
#define c_cephes_exp_p4 1.6666665459E-1
|
||||
#define c_cephes_exp_p5 5.0000001201E-1
|
||||
|
||||
/* exp() computed for 4 float at once */
|
||||
inline v4sf exp_ps(v4sf x) {
|
||||
v4sf tmp, fx;
|
||||
|
||||
v4sf one = vdupq_n_f32(1);
|
||||
x = vminq_f32(x, vdupq_n_f32(c_exp_hi));
|
||||
x = vmaxq_f32(x, vdupq_n_f32(c_exp_lo));
|
||||
|
||||
/* express exp(x) as exp(g + n*log(2)) */
|
||||
fx = vmlaq_f32(vdupq_n_f32(0.5f), x, vdupq_n_f32(c_cephes_LOG2EF));
|
||||
|
||||
/* perform a floorf */
|
||||
tmp = vcvtq_f32_s32(vcvtq_s32_f32(fx));
|
||||
|
||||
/* if greater, substract 1 */
|
||||
v4su mask = vcgtq_f32(tmp, fx);
|
||||
mask = vandq_u32(mask, vreinterpretq_u32_f32(one));
|
||||
|
||||
|
||||
fx = vsubq_f32(tmp, vreinterpretq_f32_u32(mask));
|
||||
|
||||
tmp = vmulq_f32(fx, vdupq_n_f32(c_cephes_exp_C1));
|
||||
v4sf z = vmulq_f32(fx, vdupq_n_f32(c_cephes_exp_C2));
|
||||
x = vsubq_f32(x, tmp);
|
||||
x = vsubq_f32(x, z);
|
||||
|
||||
static const float cephes_exp_p[6] = { c_cephes_exp_p0, c_cephes_exp_p1, c_cephes_exp_p2, c_cephes_exp_p3, c_cephes_exp_p4, c_cephes_exp_p5 };
|
||||
v4sf y = vld1q_dup_f32(cephes_exp_p+0);
|
||||
v4sf c1 = vld1q_dup_f32(cephes_exp_p+1);
|
||||
v4sf c2 = vld1q_dup_f32(cephes_exp_p+2);
|
||||
v4sf c3 = vld1q_dup_f32(cephes_exp_p+3);
|
||||
v4sf c4 = vld1q_dup_f32(cephes_exp_p+4);
|
||||
v4sf c5 = vld1q_dup_f32(cephes_exp_p+5);
|
||||
|
||||
y = vmulq_f32(y, x);
|
||||
z = vmulq_f32(x,x);
|
||||
y = vaddq_f32(y, c1);
|
||||
y = vmulq_f32(y, x);
|
||||
y = vaddq_f32(y, c2);
|
||||
y = vmulq_f32(y, x);
|
||||
y = vaddq_f32(y, c3);
|
||||
y = vmulq_f32(y, x);
|
||||
y = vaddq_f32(y, c4);
|
||||
y = vmulq_f32(y, x);
|
||||
y = vaddq_f32(y, c5);
|
||||
|
||||
y = vmulq_f32(y, z);
|
||||
y = vaddq_f32(y, x);
|
||||
y = vaddq_f32(y, one);
|
||||
|
||||
/* build 2^n */
|
||||
int32x4_t mm;
|
||||
mm = vcvtq_s32_f32(fx);
|
||||
mm = vaddq_s32(mm, vdupq_n_s32(0x7f));
|
||||
mm = vshlq_n_s32(mm, 23);
|
||||
v4sf pow2n = vreinterpretq_f32_s32(mm);
|
||||
|
||||
y = vmulq_f32(y, pow2n);
|
||||
return y;
|
||||
}
|
||||
|
||||
#define c_minus_cephes_DP1 -0.78515625
|
||||
#define c_minus_cephes_DP2 -2.4187564849853515625e-4
|
||||
#define c_minus_cephes_DP3 -3.77489497744594108e-8
|
||||
#define c_sincof_p0 -1.9515295891E-4
|
||||
#define c_sincof_p1 8.3321608736E-3
|
||||
#define c_sincof_p2 -1.6666654611E-1
|
||||
#define c_coscof_p0 2.443315711809948E-005
|
||||
#define c_coscof_p1 -1.388731625493765E-003
|
||||
#define c_coscof_p2 4.166664568298827E-002
|
||||
#define c_cephes_FOPI 1.27323954473516 // 4 / M_PI
|
||||
|
||||
/* evaluation of 4 sines & cosines at once.
|
||||
|
||||
The code is the exact rewriting of the cephes sinf function.
|
||||
Precision is excellent as long as x < 8192 (I did not bother to
|
||||
take into account the special handling they have for greater values
|
||||
-- it does not return garbage for arguments over 8192, though, but
|
||||
the extra precision is missing).
|
||||
|
||||
Note that it is such that sinf((float)M_PI) = 8.74e-8, which is the
|
||||
surprising but correct result.
|
||||
|
||||
Note also that when you compute sin(x), cos(x) is available at
|
||||
almost no extra price so both sin_ps and cos_ps make use of
|
||||
sincos_ps..
|
||||
*/
|
||||
inline void sincos_ps(v4sf x, v4sf *ysin, v4sf *ycos) { // any x
|
||||
v4sf y;
|
||||
|
||||
v4su emm2;
|
||||
|
||||
v4su sign_mask_sin, sign_mask_cos;
|
||||
sign_mask_sin = vcltq_f32(x, vdupq_n_f32(0));
|
||||
x = vabsq_f32(x);
|
||||
|
||||
/* scale by 4/Pi */
|
||||
y = vmulq_n_f32(x, c_cephes_FOPI);
|
||||
|
||||
/* store the integer part of y in mm0 */
|
||||
emm2 = vcvtq_u32_f32(y);
|
||||
/* j=(j+1) & (~1) (see the cephes sources) */
|
||||
emm2 = vaddq_u32(emm2, vdupq_n_u32(1));
|
||||
emm2 = vandq_u32(emm2, vdupq_n_u32(~1));
|
||||
y = vcvtq_f32_u32(emm2);
|
||||
|
||||
/* get the polynom selection mask
|
||||
there is one polynom for 0 <= x <= Pi/4
|
||||
and another one for Pi/4<x<=Pi/2
|
||||
|
||||
Both branches will be computed.
|
||||
*/
|
||||
v4su poly_mask = vtstq_u32(emm2, vdupq_n_u32(2));
|
||||
|
||||
/* The magic pass: "Extended precision modular arithmetic"
|
||||
x = ((x - y * DP1) - y * DP2) - y * DP3; */
|
||||
x = vfmaq_n_f32(x, y, c_minus_cephes_DP1);
|
||||
x = vfmaq_n_f32(x, y, c_minus_cephes_DP2);
|
||||
x = vfmaq_n_f32(x, y, c_minus_cephes_DP3);
|
||||
|
||||
sign_mask_sin = veorq_u32(sign_mask_sin, vtstq_u32(emm2, vdupq_n_u32(4)));
|
||||
sign_mask_cos = vtstq_u32(vsubq_u32(emm2, vdupq_n_u32(2)), vdupq_n_u32(4));
|
||||
|
||||
/* Evaluate the first polynom (0 <= x <= Pi/4) in y1,
|
||||
and the second polynom (Pi/4 <= x <= 0) in y2 */
|
||||
v4sf z = vmulq_f32(x,x);
|
||||
v4sf y1, y2;
|
||||
|
||||
y1 = vfmaq_n_f32(vdupq_n_f32(c_coscof_p1), z, c_coscof_p0);
|
||||
y2 = vfmaq_n_f32(vdupq_n_f32(c_sincof_p1), z, c_sincof_p0);
|
||||
y1 = vfmaq_f32(vdupq_n_f32(c_coscof_p2), y1, z);
|
||||
y2 = vfmaq_f32(vdupq_n_f32(c_sincof_p2), y2, z);
|
||||
y1 = vmulq_f32(y1, z);
|
||||
y2 = vmulq_f32(y2, z);
|
||||
y1 = vmulq_f32(y1, z);
|
||||
y1 = vfmsq_n_f32(y1, z, 0.5f);
|
||||
y2 = vfmaq_f32(x, y2, x);
|
||||
y1 = vaddq_f32(y1, vdupq_n_f32(1));
|
||||
|
||||
/* select the correct result from the two polynoms */
|
||||
v4sf ys = vbslq_f32(poly_mask, y1, y2);
|
||||
v4sf yc = vbslq_f32(poly_mask, y2, y1);
|
||||
*ysin = vbslq_f32(sign_mask_sin, vnegq_f32(ys), ys);
|
||||
*ycos = vbslq_f32(sign_mask_cos, yc, vnegq_f32(yc));
|
||||
}
|
||||
|
||||
inline v4sf sin_ps(v4sf x) {
|
||||
v4sf ysin, ycos;
|
||||
sincos_ps(x, &ysin, &ycos);
|
||||
return ysin;
|
||||
}
|
||||
|
||||
inline v4sf cos_ps(v4sf x) {
|
||||
v4sf ysin, ycos;
|
||||
sincos_ps(x, &ysin, &ycos);
|
||||
return ycos;
|
||||
}
|
||||
|
||||
static const float asinf_lut[7] = {
|
||||
1.5707961728,
|
||||
-0.2145852647,
|
||||
0.0887556286,
|
||||
-0.0488025043,
|
||||
0.0268999482,
|
||||
-0.0111462294,
|
||||
0.0022959648
|
||||
};
|
||||
|
||||
inline void asincos_ps(float32x4_t x, float32x4_t* yasin, float32x4_t* yacos)
|
||||
{
|
||||
float32x4_t one = vdupq_n_f32(1);
|
||||
float32x4_t negone = vdupq_n_f32(-1);
|
||||
float32x4_t lut[7];
|
||||
float32x4_t xv[5];
|
||||
float32x4_t sat = vdupq_n_f32(0.9999999f);
|
||||
float32x4_t m_pi_2 = vdupq_n_f32(1.570796326);
|
||||
for (int i = 0; i <= 6; i++)
|
||||
lut[i] = vdupq_n_f32(asinf_lut[i]);
|
||||
|
||||
uint32x4_t sign_mask_asin = vcltq_f32(x, vdupq_n_f32(0));
|
||||
x = vabsq_f32(x);
|
||||
uint32x4_t saturate = vcgeq_f32(x, one);
|
||||
x = vbslq_f32(saturate, sat, x);
|
||||
float32x4_t y = vsubq_f32(one, x);
|
||||
y = vsqrtq_f32(y);
|
||||
|
||||
xv[0] = vmulq_f32(x, x);
|
||||
for (int i = 1; i < 5; i++)
|
||||
xv[i] = vmulq_f32(xv[i - 1], x);
|
||||
|
||||
float32x4_t a0 = vaddq_f32(lut[0], vmulq_f32(lut[1], x));
|
||||
float32x4_t a1 = vaddq_f32(vmulq_f32(lut[2], xv[0]), vmulq_f32(lut[3], xv[1]));
|
||||
float32x4_t a2 = vaddq_f32(vmulq_f32(lut[4], xv[2]), vmulq_f32(lut[5], xv[3]));
|
||||
float32x4_t a3 = vmulq_f32(lut[6], xv[4]);
|
||||
float32x4_t phx = vaddq_f32(vaddq_f32(a0, vaddq_f32(a1, a2)), a3);
|
||||
|
||||
float32x4_t arcsinx = vmulq_f32(y, phx);
|
||||
arcsinx = vsubq_f32(m_pi_2, arcsinx);
|
||||
float32x4_t arcnsinx = vmulq_f32(negone, arcsinx);
|
||||
arcsinx = vbslq_f32(sign_mask_asin, arcnsinx, arcsinx);
|
||||
*yasin = arcsinx;
|
||||
*yacos = vsubq_f32(m_pi_2, arcsinx);
|
||||
}
|
||||
|
||||
inline float32x4_t asin_ps(float32x4_t x)
|
||||
{
|
||||
float32x4_t yasin, yacos;
|
||||
asincos_ps(x, &yasin, &yacos);
|
||||
return yasin;
|
||||
}
|
||||
|
||||
inline float32x4_t acos_ps(float32x4_t x)
|
||||
{
|
||||
float32x4_t yasin, yacos;
|
||||
asincos_ps(x, &yasin, &yacos);
|
||||
return yacos;
|
||||
}
|
@ -100,10 +100,11 @@ int CHudSayText::Draw( float flTime )
|
||||
int y = Y_START;
|
||||
|
||||
#if USE_VGUI
|
||||
if( ( gViewPort && gViewPort->AllowedToPrintText() == FALSE ) || !m_HUD_saytext->value )
|
||||
if( ( gViewPort && gViewPort->AllowedToPrintText() == FALSE ) )
|
||||
return 1;
|
||||
#endif
|
||||
|
||||
if ( !m_HUD_saytext->value )
|
||||
return 1;
|
||||
|
||||
// make sure the scrolltime is within reasonable bounds, to guard against the clock being reset
|
||||
flScrollTime = Q_min( flScrollTime, flTime + m_HUD_saytext_time->value );
|
||||
@ -173,8 +174,6 @@ void CHudSayText::SayTextPrint( const char *pszBuf, int iBufSize, int clientInde
|
||||
ConsolePrint( pszBuf );
|
||||
return;
|
||||
}
|
||||
#else
|
||||
ConsolePrint( pszBuf );
|
||||
#endif
|
||||
|
||||
int i;
|
||||
|
@ -10,12 +10,6 @@
|
||||
#include "const.h"
|
||||
#include "com_model.h"
|
||||
#include "studio_util.h"
|
||||
#include "build.h"
|
||||
#if XASH_ARMv8
|
||||
#define XASH_SIMD_NEON 1
|
||||
#include <arm_neon.h>
|
||||
#include "neon_mathfun.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
====================
|
||||
@ -23,59 +17,8 @@ AngleMatrix
|
||||
|
||||
====================
|
||||
*/
|
||||
#if XASH_SIMD_NEON
|
||||
const uint32x4_t AngleMatrix_sign0 = vreinterpretq_f32_u32(vsetq_lane_u32(0x80000000, vdupq_n_u32(0), 0));
|
||||
const uint32x4_t AngleMatrix_sign1 = vreinterpretq_f32_u32(vsetq_lane_u32(0x80000000, vdupq_n_u32(0), 1));
|
||||
const uint32x4_t AngleMatrix_sign2 = vreinterpretq_f32_u32(vsetq_lane_u32(0x80000000, vdupq_n_u32(0), 2));
|
||||
#endif
|
||||
void AngleMatrix( const float *angles, float (*matrix)[4] )
|
||||
{
|
||||
#if XASH_SIMD_NEON
|
||||
float32x4x3_t out_reg;
|
||||
float32x4_t angles_reg = {};
|
||||
memcpy(&angles_reg, angles, sizeof(float) * 3);
|
||||
|
||||
float32x4x2_t sp_sy_sr_0_cp_cy_cr_1;
|
||||
sincos_ps(vmulq_n_f32(angles_reg, (M_PI * 2 / 360)), &sp_sy_sr_0_cp_cy_cr_1.val[0], &sp_sy_sr_0_cp_cy_cr_1.val[1]);
|
||||
|
||||
float32x4x2_t sp_sr_cp_cr_sy_0_cy_1 = vuzpq_f32(sp_sy_sr_0_cp_cy_cr_1.val[0], sp_sy_sr_0_cp_cy_cr_1.val[1]);
|
||||
float32x4x2_t sp_cp_sy_cy_sr_cr_0_1 = vzipq_f32(sp_sy_sr_0_cp_cy_cr_1.val[0], sp_sy_sr_0_cp_cy_cr_1.val[1]);
|
||||
|
||||
float32x4_t _0_sr_cr_0 = vextq_f32(sp_sy_sr_0_cp_cy_cr_1.val[0], sp_cp_sy_cy_sr_cr_0_1.val[1], 3);
|
||||
float32x4_t cp_cr_sr_0 = vcombine_f32(vget_high_f32(sp_sr_cp_cr_sy_0_cy_1.val[0]), vget_high_f32(sp_sy_sr_0_cp_cy_cr_1.val[0]));
|
||||
float32x4_t cy_sy_sy_0 = vcombine_f32(vrev64_f32(vget_high_f32(sp_cp_sy_cy_sr_cr_0_1.val[0])), vget_low_f32(sp_sr_cp_cr_sy_0_cy_1.val[1]));
|
||||
float32x4_t sy_cy_cy_1 = vcombine_f32(vget_high_f32(sp_cp_sy_cy_sr_cr_0_1.val[0]), vget_high_f32(sp_sr_cp_cr_sy_0_cy_1.val[1]));
|
||||
|
||||
float32x4_t _0_srsp_crsp_0 = vmulq_laneq_f32(_0_sr_cr_0, sp_sy_sr_0_cp_cy_cr_1.val[0], 0); // *sp
|
||||
out_reg.val[0] = vmulq_laneq_f32(_0_srsp_crsp_0, sp_sy_sr_0_cp_cy_cr_1.val[1], 1); // *cy
|
||||
out_reg.val[1] = vmulq_laneq_f32(_0_srsp_crsp_0, sp_sy_sr_0_cp_cy_cr_1.val[0], 1); // *sy
|
||||
|
||||
cy_sy_sy_0 = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(cy_sy_sy_0), AngleMatrix_sign1));
|
||||
sy_cy_cy_1 = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(sy_cy_cy_1), AngleMatrix_sign2));
|
||||
out_reg.val[0] = vfmaq_f32(out_reg.val[0], cp_cr_sr_0, cy_sy_sy_0);
|
||||
out_reg.val[1] = vfmaq_f32(out_reg.val[1], cp_cr_sr_0, sy_cy_cy_1);
|
||||
|
||||
float32x4_t cp_cr_0_1 = vcombine_f32(vget_high_f32(sp_sr_cp_cr_sy_0_cy_1.val[0]), vget_high_f32(sp_cp_sy_cy_sr_cr_0_1.val[1]));
|
||||
float32x4_t _1_cp_cr_0 = vextq_f32(cp_cr_0_1, cp_cr_0_1, 3);
|
||||
out_reg.val[2] = vmulq_f32(sp_sr_cp_cr_sy_0_cy_1.val[0], _1_cp_cr_0);
|
||||
out_reg.val[2] = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(out_reg.val[2]), AngleMatrix_sign0));
|
||||
|
||||
memcpy(matrix, &out_reg, sizeof(float) * 3 * 4);
|
||||
/*
|
||||
matrix[0][0] = cp*cy;
|
||||
matrix[0][1] = sr*sp*cy-cr*sy;
|
||||
matrix[0][2] = cr*sp*cy+sr*sy;
|
||||
matrix[0][3] = 0.0;
|
||||
matrix[1][0] = cp*sy;
|
||||
matrix[1][1] = sr*sp*sy+cr*cy;
|
||||
matrix[1][2] = cr*sp*sy-sr*cy;
|
||||
matrix[1][3] = 0.0;
|
||||
matrix[2][0] = -sp*1;
|
||||
matrix[2][1] = sr*cp;
|
||||
matrix[2][2] = cp*cr;
|
||||
matrix[2][3] = cr*0;
|
||||
*/
|
||||
#else
|
||||
float angle;
|
||||
float sr, sp, sy, cr, cp, cy;
|
||||
|
||||
@ -102,7 +45,6 @@ void AngleMatrix( const float *angles, float (*matrix)[4] )
|
||||
matrix[0][3] = 0.0f;
|
||||
matrix[1][3] = 0.0f;
|
||||
matrix[2][3] = 0.0f;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -113,13 +55,6 @@ VectorCompare
|
||||
*/
|
||||
int VectorCompare( const float *v1, const float *v2 )
|
||||
{
|
||||
#if XASH_SIMD_NEON
|
||||
// is this really works?
|
||||
float32x4_t v1_reg = {}, v2_reg = {};
|
||||
memcpy(&v1_reg, v1, sizeof(float) * 3);
|
||||
memcpy(&v2_reg, v2, sizeof(float) * 3);
|
||||
return !vaddvq_u32(vceqq_f32(v1_reg, v2_reg));
|
||||
#else
|
||||
int i;
|
||||
|
||||
for( i = 0; i < 3; i++ )
|
||||
@ -127,7 +62,6 @@ int VectorCompare( const float *v1, const float *v2 )
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -138,23 +72,9 @@ CrossProduct
|
||||
*/
|
||||
void CrossProduct( const float *v1, const float *v2, float *cross )
|
||||
{
|
||||
#if XASH_SIMD_NEON
|
||||
float32x4_t v1_reg = {}, v2_reg = {};
|
||||
memcpy(&v1_reg, v1, sizeof(float) * 3);
|
||||
memcpy(&v2_reg, v2, sizeof(float) * 3);
|
||||
|
||||
float32x4_t yzxy_a = vextq_f32(vextq_f32(v1_reg, v1_reg, 3), v1_reg, 2); // [aj, ak, ai, aj]
|
||||
float32x4_t yzxy_b = vextq_f32(vextq_f32(v2_reg, v2_reg, 3), v2_reg, 2); // [bj, bk, bi, bj]
|
||||
float32x4_t zxyy_a = vextq_f32(yzxy_a, yzxy_a, 1); // [ak, ai, aj, aj]
|
||||
float32x4_t zxyy_b = vextq_f32(yzxy_b, yzxy_b, 1); // [bk, ai, bj, bj]
|
||||
float32x4_t cross_reg = vfmsq_f32(vmulq_f32(yzxy_a, zxyy_b), zxyy_a, yzxy_b); // [ajbk-akbj, akbi-aibk, aibj-ajbi, 0]
|
||||
|
||||
memcpy(cross, &cross_reg, sizeof(float) * 3);
|
||||
#else
|
||||
cross[0] = v1[1] * v2[2] - v1[2] * v2[1];
|
||||
cross[1] = v1[2] * v2[0] - v1[0] * v2[2];
|
||||
cross[2] = v1[0] * v2[1] - v1[1] * v2[0];
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -165,26 +85,9 @@ VectorTransform
|
||||
*/
|
||||
void VectorTransform( const float *in1, float in2[3][4], float *out )
|
||||
{
|
||||
#if XASH_SIMD_NEON
|
||||
float32x4_t in1_reg = {};
|
||||
memcpy(&in1_reg, &in1, sizeof(float) * 3);
|
||||
|
||||
float32x4x4_t in_t;
|
||||
memcpy(&in_t, &in2, sizeof(float) * 3 * 4);
|
||||
//memset(&in_t.val[3], 0, sizeof(in_t.val[3]));
|
||||
in_t = vld4q_f32((const float*)&in_t);
|
||||
|
||||
float32x4_t out_reg = in_t.val[3];
|
||||
out_reg = vfmaq_laneq_f32(out_reg, in_t.val[0], in1_reg, 0);
|
||||
out_reg = vfmaq_laneq_f32(out_reg, in_t.val[1], in1_reg, 1);
|
||||
out_reg = vfmaq_laneq_f32(out_reg, in_t.val[2], in1_reg, 2);
|
||||
|
||||
memcpy(out, &out_reg, sizeof(float) * 3);
|
||||
#else
|
||||
out[0] = DotProduct(in1, in2[0]) + in2[0][3];
|
||||
out[1] = DotProduct(in1, in2[1]) + in2[1][3];
|
||||
out[2] = DotProduct(in1, in2[2]) + in2[2][3];
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -195,29 +98,6 @@ ConcatTransforms
|
||||
*/
|
||||
void ConcatTransforms( float in1[3][4], float in2[3][4], float out[3][4] )
|
||||
{
|
||||
#if XASH_SIMD_NEON
|
||||
float32x4x3_t in1_reg, in2_reg;
|
||||
memcpy(&in1_reg, in1, sizeof(float) * 3 * 4);
|
||||
memcpy(&in2_reg, in2, sizeof(float) * 3 * 4);
|
||||
float32x4x3_t out_reg = {};
|
||||
|
||||
out_reg.val[0] = vcopyq_laneq_f32(out_reg.val[0], 3, in1_reg.val[0], 3); // out[0][3] = in[0][3]
|
||||
out_reg.val[0] = vfmaq_laneq_f32(out_reg.val[0], in2_reg.val[0], in1_reg.val[0], 0); // out[0][n] += in2[0][n] * in1[0][0]
|
||||
out_reg.val[0] = vfmaq_laneq_f32(out_reg.val[0], in2_reg.val[1], in1_reg.val[0], 1); // out[0][n] += in2[1][n] * in1[0][1]
|
||||
out_reg.val[0] = vfmaq_laneq_f32(out_reg.val[0], in2_reg.val[2], in1_reg.val[0], 2); // out[0][n] += in2[2][n] * in1[0][2]
|
||||
|
||||
out_reg.val[1] = vcopyq_laneq_f32(out_reg.val[1], 3, in1_reg.val[1], 3);
|
||||
out_reg.val[1] = vfmaq_laneq_f32(out_reg.val[1], in2_reg.val[0], in1_reg.val[1], 0);
|
||||
out_reg.val[1] = vfmaq_laneq_f32(out_reg.val[1], in2_reg.val[1], in1_reg.val[1], 1);
|
||||
out_reg.val[1] = vfmaq_laneq_f32(out_reg.val[1], in2_reg.val[2], in1_reg.val[1], 2);
|
||||
|
||||
out_reg.val[2] = vcopyq_laneq_f32(out_reg.val[2], 3, in1_reg.val[2], 3);
|
||||
out_reg.val[2] = vfmaq_laneq_f32(out_reg.val[2], in2_reg.val[0], in1_reg.val[2], 0);
|
||||
out_reg.val[2] = vfmaq_laneq_f32(out_reg.val[2], in2_reg.val[1], in1_reg.val[2], 1);
|
||||
out_reg.val[2] = vfmaq_laneq_f32(out_reg.val[2], in2_reg.val[2], in1_reg.val[2], 2);
|
||||
|
||||
memcpy(&out, &out_reg, sizeof(out));
|
||||
#else
|
||||
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] +
|
||||
in1[0][2] * in2[2][0];
|
||||
out[0][1] = in1[0][0] * in2[0][1] + in1[0][1] * in2[1][1] +
|
||||
@ -242,7 +122,6 @@ void ConcatTransforms( float in1[3][4], float in2[3][4], float out[3][4] )
|
||||
in1[2][2] * in2[2][2];
|
||||
out[2][3] = in1[2][0] * in2[0][3] + in1[2][1] * in2[1][3] +
|
||||
in1[2][2] * in2[2][3] + in1[2][3];
|
||||
#endif
|
||||
}
|
||||
|
||||
// angles index are not the same as ROLL, PITCH, YAW
|
||||
@ -253,36 +132,8 @@ AngleQuaternion
|
||||
|
||||
====================
|
||||
*/
|
||||
#if XASH_SIMD_NEON
|
||||
const float32x4_t AngleQuaternion_sign2 = vzipq_f32(vdupq_n_u32(0x80000000), vdupq_n_u32(0x00000000)).val[0]; // { 0x80000000, 0x00000000, 0x80000000, 0x00000000 };
|
||||
#endif
|
||||
void AngleQuaternion( float *angles, vec4_t quaternion )
|
||||
{
|
||||
#if XASH_SIMD_NEON
|
||||
float32x4_t angles_reg = {};
|
||||
memcpy(&angles_reg, angles, sizeof(float) * 3);
|
||||
float32x4x2_t sr_sp_sy_0_cr_cp_cy_1;
|
||||
sincos_ps(vmulq_n_f32(angles_reg, 0.5), &sr_sp_sy_0_cr_cp_cy_1.val[0], &sr_sp_sy_0_cr_cp_cy_1.val[1]);
|
||||
|
||||
float32x4x2_t sr_sy_cr_cy_sp_0_cp_1 = vuzpq_f32(sr_sp_sy_0_cr_cp_cy_1.val[0], sr_sp_sy_0_cr_cp_cy_1.val[1]);
|
||||
float32x4_t cp_cp_cp_cp = vdupq_laneq_f32(sr_sp_sy_0_cr_cp_cy_1.val[1], 1);
|
||||
float32x4_t sp_sp_sp_sp = vdupq_laneq_f32(sr_sp_sy_0_cr_cp_cy_1.val[0], 1);
|
||||
|
||||
float32x4_t sr_sy_cr_cy = sr_sy_cr_cy_sp_0_cp_1.val[0];
|
||||
float32x4_t sy_cr_cy_sr = vextq_f32(sr_sy_cr_cy_sp_0_cp_1.val[0], sr_sy_cr_cy_sp_0_cp_1.val[0], 1);
|
||||
float32x4_t cr_cy_sr_sy = vextq_f32(sr_sy_cr_cy_sp_0_cp_1.val[0], sr_sy_cr_cy_sp_0_cp_1.val[0], 2);
|
||||
float32x4_t cy_sr_sy_cr = vextq_f32(sr_sy_cr_cy_sp_0_cp_1.val[0], sr_sy_cr_cy_sp_0_cp_1.val[0], 3);
|
||||
float32x4_t sp_sp_sp_sp_signed = veorq_u32(sp_sp_sp_sp, AngleQuaternion_sign2);
|
||||
|
||||
float32x4_t left = vmulq_f32(vmulq_f32(sr_sy_cr_cy, cp_cp_cp_cp), cy_sr_sy_cr);
|
||||
|
||||
float32x4_t out_reg = vfmaq_f32(left, vmulq_f32(cr_cy_sr_sy, sp_sp_sp_sp_signed), sy_cr_cy_sr);
|
||||
memcpy(quaternion, &out_reg, sizeof(float) * 4);
|
||||
//quaternion[0] = sr * cp * cy - cr * sp * sy; // X
|
||||
//quaternion[1] = sy * cp * sr + cy * sp * cr; // Y
|
||||
//quaternion[2] = cr * cp * sy - sr * sp * cy; // Z
|
||||
//quaternion[3] = cy * cp * cr + sy * sp * sr; // W
|
||||
#else
|
||||
float angle;
|
||||
float sr, sp, sy, cr, cp, cy;
|
||||
|
||||
@ -301,7 +152,6 @@ void AngleQuaternion( float *angles, vec4_t quaternion )
|
||||
quaternion[1] = cr * sp * cy + sr * cp * sy; // Y
|
||||
quaternion[2] = cr * cp * sy - sr * sp * cy; // Z
|
||||
quaternion[3] = cr * cp * cy + sr * sp * sy; // W
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -312,37 +162,6 @@ QuaternionSlerp
|
||||
*/
|
||||
void QuaternionSlerp( vec4_t p, vec4_t q, float t, vec4_t qt )
|
||||
{
|
||||
#if XASH_SIMD_NEON
|
||||
float32x4_t p_reg = {}, q_reg = {};
|
||||
memcpy(&p_reg, p, sizeof(float) * 4);
|
||||
memcpy(&q_reg, q, sizeof(float) * 4);
|
||||
|
||||
// q = (cos(a/2), xsin(a/2), ysin(a/2), zsin(a/2))
|
||||
// cos(a-b) = cosacosb+sinasinb
|
||||
const uint32x4_t signmask = vdupq_n_u32(0x80000000);
|
||||
const float32x4_t one_minus_epsilon = vdupq_n_f32(1.0f - 0.00001f);
|
||||
|
||||
float32x4_t vcosom = vdupq_n_f32(DotProduct(p, q));
|
||||
uint32x4_t sign = vandq_u32(vreinterpretq_u32_f32(vcosom), signmask);
|
||||
q_reg = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(p_reg), sign));
|
||||
vcosom = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(vcosom), sign));
|
||||
|
||||
float x[4] = {(1.0f - t), t, 1, 0}; // cosom -> 1, sinom -> 0, sinx ~ x
|
||||
float32x4_t x_reg;
|
||||
memcpy(&x_reg, x, sizeof(float) * 4);
|
||||
|
||||
// if ((1.0 - cosom) > 0.000001) x = sin(x * omega)
|
||||
uint32x4_t cosom_less_then_one = vcltq_f32(vcosom, one_minus_epsilon);
|
||||
float32x4_t vomega = acos_ps(vcosom);
|
||||
x_reg = vbslq_f32(cosom_less_then_one, x_reg, sin_ps(vmulq_f32(x_reg, vomega)));
|
||||
|
||||
// qt = (x[0] * p + x[1] * q) / x[2];
|
||||
float32x4_t qt_reg = vmulq_laneq_f32(p_reg, x_reg, 0);
|
||||
qt_reg = vfmaq_laneq_f32(qt_reg, q_reg, x_reg, 1);
|
||||
qt_reg = vdivq_f32(qt_reg, vdupq_laneq_f32(x_reg, 2)); // vdivq_laneq_f32 ?
|
||||
|
||||
memcpy(qt, &qt_reg, sizeof(float) * 4);
|
||||
#else
|
||||
int i;
|
||||
float omega, cosom, sinom, sclp, sclq;
|
||||
|
||||
@ -397,7 +216,6 @@ void QuaternionSlerp( vec4_t p, vec4_t q, float t, vec4_t qt )
|
||||
qt[i] = sclp * p[i] + sclq * qt[i];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
@ -406,60 +224,8 @@ QuaternionMatrix
|
||||
|
||||
====================
|
||||
*/
|
||||
#if XASH_SIMD_NEON
|
||||
const uint32x4_t QuaternionMatrix_sign1 = vsetq_lane_u32(0x80000000, vdupq_n_u32(0x00000000), 0); // { 0x80000000, 0x00000000, 0x00000000, 0x00000000 };
|
||||
const uint32x4_t QuaternionMatrix_sign2 = vsetq_lane_u32(0x80000000, vdupq_n_u32(0x00000000), 1); // { 0x00000000, 0x80000000, 0x00000000, 0x00000000 };
|
||||
const uint32x4_t QuaternionMatrix_sign3 = vsetq_lane_u32(0x00000000, vdupq_n_u32(0x80000000), 2); // { 0x80000000, 0x80000000, 0x00000000, 0x80000000 };
|
||||
const float32x4_t matrix3x4_identity_0 = vsetq_lane_f32(1, vdupq_n_f32(0), 0); // { 1, 0, 0, 0 }
|
||||
const float32x4_t matrix3x4_identity_1 = vsetq_lane_f32(1, vdupq_n_f32(0), 1); // { 0, 1, 0, 0 }
|
||||
const float32x4_t matrix3x4_identity_2 = vsetq_lane_f32(1, vdupq_n_f32(0), 2); // { 0, 0, 1, 0 }
|
||||
#endif
|
||||
|
||||
void QuaternionMatrix( vec4_t quaternion, float (*matrix)[4] )
|
||||
{
|
||||
#if XASH_SIMD_NEON
|
||||
float32x4_t quaternion_reg;
|
||||
memcpy(&quaternion_reg, quaternion, sizeof(float) * 4);
|
||||
|
||||
float32x4_t q1032 = vrev64q_f32(quaternion_reg);
|
||||
float32x4_t q1032_signed = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(q1032), QuaternionMatrix_sign1));
|
||||
float32x4_t q2301 = vextq_f32(quaternion_reg, quaternion_reg, 2);
|
||||
float32x4_t q2301_signed = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(q2301), QuaternionMatrix_sign3));
|
||||
float32x4_t q3210 = vrev64q_f32(q2301);
|
||||
float32x4_t q3210_signed = vreinterpretq_f32_u32(veorq_u32(vreinterpretq_u32_f32(q3210), QuaternionMatrix_sign2));
|
||||
|
||||
float32x4x3_t out_reg;
|
||||
|
||||
out_reg.val[0] = vmulq_laneq_f32(q2301_signed, quaternion_reg, 2);
|
||||
out_reg.val[0] = vfmaq_laneq_f32(out_reg.val[0], q1032_signed, quaternion_reg, 1);
|
||||
out_reg.val[0] = vfmaq_n_f32(matrix3x4_identity_0, out_reg.val[0], 2.0f);
|
||||
|
||||
out_reg.val[1] = vmulq_laneq_f32(q3210_signed, quaternion_reg, 2);
|
||||
out_reg.val[1] = vfmsq_laneq_f32(out_reg.val[1], q1032_signed, quaternion_reg, 0);
|
||||
out_reg.val[1] = vfmaq_n_f32(matrix3x4_identity_1, out_reg.val[1], 2.0f);
|
||||
|
||||
out_reg.val[2] = vmulq_laneq_f32(q3210_signed, quaternion_reg, 1);
|
||||
out_reg.val[2] = vfmaq_laneq_f32(out_reg.val[2], q2301_signed, quaternion_reg, 0);
|
||||
out_reg.val[2] = vfmsq_n_f32(matrix3x4_identity_2, out_reg.val[2], 2.0f);
|
||||
|
||||
memcpy(matrix, &out_reg, sizeof(float) * 3 * 4);
|
||||
/*
|
||||
matrix[0][0] = 1.0 + 2.0 * ( quaternion[1] * -quaternion[1] + -quaternion[2] * quaternion[2] );
|
||||
matrix[0][1] = 0.0 + 2.0 * ( quaternion[1] * quaternion[0] + -quaternion[3] * quaternion[2] );
|
||||
matrix[0][2] = 0.0 + 2.0 * ( quaternion[1] * quaternion[3] + quaternion[0] * quaternion[2] );
|
||||
matrix[0][3] = 0.0 + 2.0 * ( quaternion[1] * quaternion[2] + -quaternion[1] * quaternion[2] );
|
||||
|
||||
matrix[1][0] = 0.0 + 2.0 * ( -quaternion[0] * -quaternion[1] + quaternion[3] * quaternion[2] );
|
||||
matrix[1][1] = 1.0 + 2.0 * ( -quaternion[0] * quaternion[0] + -quaternion[2] * quaternion[2] );
|
||||
matrix[1][2] = 0.0 + 2.0 * ( -quaternion[0] * quaternion[3] + quaternion[1] * quaternion[2] );
|
||||
matrix[1][3] = 0.0 + 2.0 * ( -quaternion[0] * quaternion[2] + quaternion[0] * quaternion[2] );
|
||||
|
||||
matrix[2][0] = 0.0 + 2.0 * ( -quaternion[0] * -quaternion[2] + -quaternion[3] * quaternion[1] );
|
||||
matrix[2][1] = 0.0 + 2.0 * ( -quaternion[0] * -quaternion[3] + quaternion[2] * quaternion[1] );
|
||||
matrix[2][2] = 1.0 + 2.0 * ( -quaternion[0] * quaternion[0] + -quaternion[1] * quaternion[1] );
|
||||
matrix[2][3] = 0.0 + 2.0 * ( -quaternion[0] * -quaternion[1] + -quaternion[0] * quaternion[1] );
|
||||
*/
|
||||
#else
|
||||
matrix[0][0] = 1.0f - 2.0f * quaternion[1] * quaternion[1] - 2.0f * quaternion[2] * quaternion[2];
|
||||
matrix[1][0] = 2.0f * quaternion[0] * quaternion[1] + 2.0f * quaternion[3] * quaternion[2];
|
||||
matrix[2][0] = 2.0f * quaternion[0] * quaternion[2] - 2.0f * quaternion[3] * quaternion[1];
|
||||
@ -471,7 +237,6 @@ void QuaternionMatrix( vec4_t quaternion, float (*matrix)[4] )
|
||||
matrix[0][2] = 2.0f * quaternion[0] * quaternion[2] + 2.0f * quaternion[3] * quaternion[1];
|
||||
matrix[1][2] = 2.0f * quaternion[1] * quaternion[2] - 2.0f * quaternion[3] * quaternion[0];
|
||||
matrix[2][2] = 1.0f - 2.0f * quaternion[0] * quaternion[0] - 2.0f * quaternion[1] * quaternion[1];
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -933,7 +933,7 @@ void CBigMomma::StartTask( Task_t *pTask )
|
||||
TaskComplete();
|
||||
break;
|
||||
case TASK_WAIT_NODE:
|
||||
m_flWaitFinished = gpGlobals->time + GetNodeDelay();
|
||||
m_flWait = gpGlobals->time + GetNodeDelay();
|
||||
if( m_hTargetEnt->pev->spawnflags & SF_INFOBM_WAIT )
|
||||
ALERT( at_aiconsole, "BM: Wait at node %s forever\n", STRING( pev->netname ) );
|
||||
else
|
||||
|
@ -7,18 +7,19 @@
|
||||
#include "monsters.h"
|
||||
#include "player.h"
|
||||
#include "soundent.h"
|
||||
#include "decals.h"
|
||||
|
||||
class CMortarShell : public CGrenade
|
||||
{
|
||||
public:
|
||||
void Precache();
|
||||
void BurnThink();
|
||||
void MortarExplodeTouch(CBaseEntity *pOther);
|
||||
void EXPORT BurnThink();
|
||||
void EXPORT MortarExplodeTouch(CBaseEntity *pOther);
|
||||
void Spawn();
|
||||
void FlyThink();
|
||||
void EXPORT FlyThink();
|
||||
int Save(CSave &save);
|
||||
int Restore(CRestore &restore);
|
||||
static CMortarShell *CreateMortarShell(Vector p_VecOrigin, Vector p_VecAngles, CBaseEntity *pOwner, int velocity);
|
||||
static CMortarShell *CreateMortarShell(Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner, int velocity);
|
||||
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
int m_iTrail;
|
||||
@ -48,114 +49,123 @@ void CMortarShell::Precache()
|
||||
void CMortarShell::Spawn()
|
||||
{
|
||||
Precache();
|
||||
SET_MODEL(ENT(pev), "models/mortarshell.mdl");
|
||||
UTIL_SetSize(pev, g_vecZero, g_vecZero);
|
||||
|
||||
pev->solid = SOLID_BBOX;
|
||||
pev->movetype = MOVETYPE_BOUNCE;
|
||||
pev->solid = SOLID_BBOX;
|
||||
|
||||
SET_MODEL(edict(), "models/mortarshell.mdl");
|
||||
|
||||
UTIL_SetSize(pev, g_vecZero, g_vecZero);
|
||||
UTIL_SetOrigin(pev, pev->origin);
|
||||
pev->classname = MAKE_STRING("mortar_shell");
|
||||
|
||||
SetThink(&CMortarShell::BurnThink);
|
||||
SetTouch(&CMortarShell::MortarExplodeTouch);
|
||||
|
||||
pev->dmg = gSkillData.plrDmgRPG*2;
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
UTIL_MakeVectors(pev->angles);
|
||||
|
||||
pev->velocity = -(gpGlobals->v_forward * m_velocity);
|
||||
pev->gravity = 1;
|
||||
|
||||
pev->dmg = gSkillData.plrDmgRPG * 2;
|
||||
|
||||
pev->nextthink = gpGlobals->time + 0.01;
|
||||
m_flIgniteTime = gpGlobals->time;
|
||||
m_iSoundedOff = FALSE;
|
||||
}
|
||||
|
||||
void CMortarShell::MortarExplodeTouch(CBaseEntity *pOther)
|
||||
{
|
||||
pev->enemy = pOther->edict();
|
||||
|
||||
const Vector direction = pev->velocity.Normalize();
|
||||
|
||||
const Vector vecSpot = pev->origin - direction * 32;
|
||||
|
||||
TraceResult tr;
|
||||
Vector vecSpot;
|
||||
UTIL_TraceLine(vecSpot, vecSpot + direction * 64, ignore_monsters, edict(), &tr);
|
||||
|
||||
pev->model = iStringNull;//invisible
|
||||
pev->solid = SOLID_NOT;// intangible
|
||||
pev->model = 0;
|
||||
|
||||
pev->solid = SOLID_NOT;
|
||||
pev->takedamage = DAMAGE_NO;
|
||||
|
||||
vecSpot = pev->origin + Vector( 0, 0, 8 );
|
||||
UTIL_TraceLine( vecSpot, vecSpot + Vector( 0, 0, -40 ), ignore_monsters, dont_ignore_glass, ENT(pev), &tr );
|
||||
|
||||
// Pull out of the wall a bit
|
||||
if( tr.flFraction != 1.0 )
|
||||
if (tr.flFraction != 1.0f)
|
||||
{
|
||||
pev->origin = tr.vecEndPos + ( tr.vecPlaneNormal * ( pev->dmg - 24 ) * 0.6 );
|
||||
pev->origin = 0.6f * ((pev->dmg - 24.0f) * tr.vecPlaneNormal) + tr.vecEndPos;
|
||||
}
|
||||
|
||||
int iContents = UTIL_PointContents( pev->origin );
|
||||
const int contents = UTIL_PointContents(pev->origin);
|
||||
|
||||
MESSAGE_BEGIN( MSG_PAS, SVC_TEMPENTITY, pev->origin );
|
||||
WRITE_BYTE( TE_EXPLOSION ); // This makes a dynamic light and the explosion sprites/sound
|
||||
WRITE_COORD( pev->origin.x ); // Send to PAS because of the sound
|
||||
WRITE_COORD( pev->origin.y );
|
||||
WRITE_COORD( pev->origin.z );
|
||||
if( iContents != CONTENTS_WATER )
|
||||
{
|
||||
WRITE_SHORT( g_sModelIndexFireball );
|
||||
}
|
||||
MESSAGE_BEGIN(MSG_PAS, SVC_TEMPENTITY, pev->origin);
|
||||
WRITE_BYTE(TE_EXPLOSION);
|
||||
WRITE_COORD(pev->origin.x);
|
||||
WRITE_COORD(pev->origin.y);
|
||||
WRITE_COORD(pev->origin.z);
|
||||
|
||||
if (contents == CONTENTS_WATER)
|
||||
WRITE_SHORT(g_sModelIndexWExplosion);
|
||||
else
|
||||
{
|
||||
WRITE_SHORT( g_sModelIndexWExplosion );
|
||||
}
|
||||
WRITE_BYTE( (pev->dmg - 50) * 5); // scale * 10
|
||||
WRITE_BYTE( 10 ); // framerate
|
||||
WRITE_BYTE( TE_EXPLFLAG_NONE );
|
||||
WRITE_SHORT(g_sModelIndexFireball);
|
||||
|
||||
WRITE_BYTE(static_cast<int>((pev->dmg - 50.0) * 5.0));
|
||||
WRITE_BYTE(10);
|
||||
WRITE_BYTE(TE_EXPLFLAG_NONE);
|
||||
MESSAGE_END();
|
||||
|
||||
CSoundEnt::InsertSound( bits_SOUND_COMBAT, pev->origin, NORMAL_EXPLOSION_VOLUME, 3.0 );
|
||||
entvars_t *pevOwner;
|
||||
if( pev->owner )
|
||||
pevOwner = VARS( pev->owner );
|
||||
CSoundEnt::InsertSound(bits_SOUND_COMBAT, pev->origin, 1024, 3.0);
|
||||
|
||||
entvars_t* pOwner = VARS(pev->owner);
|
||||
pev->owner = NULL;
|
||||
|
||||
RadiusDamage(pev, pOwner, pev->dmg, CLASS_NONE, 64);
|
||||
|
||||
if (RANDOM_FLOAT(0, 1) >= 0.5)
|
||||
UTIL_DecalTrace(&tr, DECAL_SCORCH2);
|
||||
else
|
||||
pevOwner = NULL;
|
||||
UTIL_DecalTrace(&tr, DECAL_SCORCH1);
|
||||
|
||||
pev->owner = NULL; // can't traceline attack owner if this is set
|
||||
|
||||
RadiusDamage( pev, pevOwner, pev->dmg, CLASS_NONE, DMG_BLAST );
|
||||
|
||||
if( RANDOM_FLOAT( 0, 1 ) < 0.5 )
|
||||
{
|
||||
UTIL_DecalTrace( &tr, 11 );
|
||||
}
|
||||
else
|
||||
{
|
||||
UTIL_DecalTrace( &tr, 12 );
|
||||
}
|
||||
|
||||
switch( RANDOM_LONG( 0, 2 ) )
|
||||
switch (RANDOM_LONG(0, 2))
|
||||
{
|
||||
case 0:
|
||||
EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/debris1.wav", 0.55, ATTN_NORM );
|
||||
EMIT_SOUND(edict(), CHAN_VOICE, "weapons/debris1.wav", 0.55, ATTN_NORM);
|
||||
break;
|
||||
case 1:
|
||||
EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/debris2.wav", 0.55, ATTN_NORM );
|
||||
EMIT_SOUND(edict(), CHAN_VOICE, "weapons/debris2.wav", 0.55, ATTN_NORM);
|
||||
break;
|
||||
case 2:
|
||||
EMIT_SOUND( ENT( pev ), CHAN_VOICE, "weapons/debris3.wav", 0.55, ATTN_NORM );
|
||||
EMIT_SOUND(edict(), CHAN_VOICE, "weapons/debris3.wav", 0.55, ATTN_NORM);
|
||||
break;
|
||||
}
|
||||
|
||||
pev->effects |= EF_NODRAW;
|
||||
SetThink( &CGrenade::Smoke );
|
||||
|
||||
SetThink(&CMortarShell::Smoke);
|
||||
|
||||
pev->velocity = g_vecZero;
|
||||
|
||||
pev->nextthink = gpGlobals->time + 0.3;
|
||||
|
||||
if( iContents != CONTENTS_WATER )
|
||||
if (contents != CONTENTS_WATER)
|
||||
{
|
||||
int sparkCount = RANDOM_LONG( 0, 3 );
|
||||
for( int i = 0; i < sparkCount; i++ )
|
||||
Create( "spark_shower", pev->origin, tr.vecPlaneNormal, NULL );
|
||||
const int sparkCount = RANDOM_LONG(0, 3);
|
||||
|
||||
for (int i = 0; i < sparkCount; ++i)
|
||||
{
|
||||
CBaseEntity::Create("spark_shower", pev->origin, tr.vecPlaneNormal);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CMortarShell::BurnThink()
|
||||
{
|
||||
UTIL_VecToAngles(pev->velocity);
|
||||
pev->angles = pev->velocity;
|
||||
pev->angles = UTIL_VecToAngles(pev->velocity);
|
||||
|
||||
pev->angles.x -= 90;
|
||||
|
||||
MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, pev->origin);
|
||||
WRITE_BYTE(110);
|
||||
WRITE_BYTE(TE_SPRITE_SPRAY);
|
||||
WRITE_COORD(pev->origin.x);
|
||||
WRITE_COORD(pev->origin.y);
|
||||
WRITE_COORD(pev->origin.z);
|
||||
@ -168,8 +178,10 @@ void CMortarShell::BurnThink()
|
||||
WRITE_BYTE(120);
|
||||
MESSAGE_END();
|
||||
|
||||
if(!((m_flIgniteTime + 0.2) >= gpGlobals->time))
|
||||
if (gpGlobals->time > m_flIgniteTime + 0.2)
|
||||
{
|
||||
SetThink(&CMortarShell::FlyThink);
|
||||
}
|
||||
|
||||
pev->nextthink = gpGlobals->time + 0.01;
|
||||
}
|
||||
@ -177,36 +189,35 @@ void CMortarShell::BurnThink()
|
||||
void CMortarShell::FlyThink()
|
||||
{
|
||||
pev->angles = UTIL_VecToAngles(pev->velocity);
|
||||
pev->angles.x -= 90;
|
||||
pev->angles.x -= 90.0f;
|
||||
|
||||
if(pev->velocity.z < 20 && !m_iSoundedOff)
|
||||
if(pev->velocity.z < 20.0f && !m_iSoundedOff)
|
||||
{
|
||||
m_iSoundedOff = TRUE;
|
||||
EMIT_SOUND_DYN(ENT(pev), 2, "weapons/ofmortar.wav", 1, 0, 0, 100);
|
||||
EMIT_SOUND(ENT(pev), CHAN_VOICE, "weapons/ofmortar.wav", RANDOM_FLOAT(0.8, 0.9), ATTN_NONE);
|
||||
}
|
||||
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
}
|
||||
|
||||
CMortarShell *CMortarShell::CreateMortarShell(Vector p_VecOrigin, Vector p_VecAngles, CBaseEntity *pOwner, int velocity)
|
||||
CMortarShell *CMortarShell::CreateMortarShell(Vector vecOrigin, Vector vecAngles, CBaseEntity *pOwner, int velocity)
|
||||
{
|
||||
CMortarShell *rocket = GetClassPtr( (CMortarShell *)NULL );
|
||||
rocket->Spawn();
|
||||
CMortarShell *pShell = GetClassPtr( (CMortarShell *)NULL );
|
||||
UTIL_SetOrigin(pShell->pev, vecOrigin);
|
||||
|
||||
rocket->pev->gravity = 1;
|
||||
UTIL_SetOrigin( rocket->pev, p_VecOrigin );
|
||||
rocket->pev->angles = UTIL_VecToAngles(p_VecAngles);
|
||||
UTIL_MakeVectors(p_VecAngles);
|
||||
rocket->pev->velocity = rocket->pev->velocity - gpGlobals->v_forward * velocity;
|
||||
if (pOwner)
|
||||
rocket->pev->owner = ENT(pOwner->pev);
|
||||
pShell->pev->angles = vecAngles;
|
||||
pShell->m_velocity = velocity;
|
||||
|
||||
return rocket;
|
||||
pShell->Spawn();
|
||||
|
||||
pShell->pev->owner = pOwner->edict();
|
||||
|
||||
return pShell;
|
||||
}
|
||||
|
||||
#define SF_MORTAR_ACTIVE (1 << 0)
|
||||
#define SF_MORTAR_LINE_OF_SIGHT (1 << 4)
|
||||
#define SF_MORTAR_CAN_CONTROL (1 << 5)
|
||||
#define SF_MORTAR_CONTROLLABLE (1 << 5)
|
||||
|
||||
class COp4Mortar : public CBaseMonster
|
||||
{
|
||||
@ -224,44 +235,56 @@ public:
|
||||
void EXPORT MortarThink();
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
int ObjectCaps() { return 0; }
|
||||
void PlaySound();
|
||||
|
||||
float m_FireDelay;
|
||||
BOOL m_tracking;
|
||||
float m_minRange;
|
||||
float m_maxRange;
|
||||
float m_lastupdate;
|
||||
float m_zeroYaw;
|
||||
float m_lastFire;
|
||||
float m_trackDelay;
|
||||
float m_flExplodeTime;
|
||||
int m_hmax;
|
||||
int m_hmin;
|
||||
int d_x;
|
||||
int d_y;
|
||||
float m_lastupdate;
|
||||
int m_direction;
|
||||
Vector m_start;
|
||||
Vector m_end;
|
||||
int m_velocity;
|
||||
int m_hmin;
|
||||
int m_hmax;
|
||||
float m_fireLast;
|
||||
float m_maxRange;
|
||||
float m_minRange;
|
||||
int m_iEnemyType;
|
||||
int m_iUpdateTime;
|
||||
float m_fireDelay;
|
||||
float m_trackDelay;
|
||||
BOOL m_tracking;
|
||||
float m_zeroYaw;
|
||||
Vector m_vGunAngle;
|
||||
Vector m_vIdealGunVector;
|
||||
Vector m_vIdealGunAngle;
|
||||
|
||||
float m_lastTimePlayedSound;
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(op4mortar, COp4Mortar)
|
||||
|
||||
TYPEDESCRIPTION COp4Mortar::m_SaveData[] =
|
||||
{
|
||||
DEFINE_FIELD( COp4Mortar, m_tracking, FIELD_BOOLEAN ),
|
||||
DEFINE_FIELD( COp4Mortar, m_FireDelay, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( COp4Mortar, m_minRange, FIELD_FLOAT),
|
||||
DEFINE_FIELD( COp4Mortar, m_maxRange, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( COp4Mortar, m_lastFire, FIELD_FLOAT),
|
||||
DEFINE_FIELD( COp4Mortar, m_trackDelay, FIELD_FLOAT ),
|
||||
DEFINE_FIELD( COp4Mortar, m_hmax, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( COp4Mortar, m_hmin, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( COp4Mortar, m_velocity, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( COp4Mortar, m_iEnemyType, FIELD_INTEGER ),
|
||||
DEFINE_FIELD( COp4Mortar, m_vGunAngle, FIELD_VECTOR ),
|
||||
DEFINE_FIELD(COp4Mortar, d_x, FIELD_INTEGER),
|
||||
DEFINE_FIELD(COp4Mortar, d_y, FIELD_INTEGER),
|
||||
DEFINE_FIELD(COp4Mortar, m_lastupdate, FIELD_FLOAT),
|
||||
DEFINE_FIELD(COp4Mortar, m_direction, FIELD_INTEGER),
|
||||
DEFINE_FIELD(COp4Mortar, m_start, FIELD_VECTOR),
|
||||
DEFINE_FIELD(COp4Mortar, m_end, FIELD_VECTOR),
|
||||
DEFINE_FIELD(COp4Mortar, m_velocity, FIELD_INTEGER),
|
||||
DEFINE_FIELD(COp4Mortar, m_hmin, FIELD_INTEGER),
|
||||
DEFINE_FIELD(COp4Mortar, m_hmax, FIELD_INTEGER),
|
||||
DEFINE_FIELD(COp4Mortar, m_fireLast, FIELD_FLOAT),
|
||||
DEFINE_FIELD(COp4Mortar, m_maxRange, FIELD_FLOAT),
|
||||
DEFINE_FIELD(COp4Mortar, m_minRange, FIELD_FLOAT),
|
||||
DEFINE_FIELD(COp4Mortar, m_iEnemyType, FIELD_INTEGER),
|
||||
DEFINE_FIELD(COp4Mortar, m_fireDelay, FIELD_FLOAT),
|
||||
DEFINE_FIELD(COp4Mortar, m_trackDelay, FIELD_FLOAT),
|
||||
DEFINE_FIELD(COp4Mortar, m_tracking, FIELD_BOOLEAN),
|
||||
DEFINE_FIELD(COp4Mortar, m_zeroYaw, FIELD_FLOAT),
|
||||
DEFINE_FIELD(COp4Mortar, m_vGunAngle, FIELD_VECTOR),
|
||||
DEFINE_FIELD(COp4Mortar, m_vIdealGunVector, FIELD_VECTOR),
|
||||
DEFINE_FIELD(COp4Mortar, m_vIdealGunAngle, FIELD_VECTOR),
|
||||
};
|
||||
|
||||
IMPLEMENT_SAVERESTORE( COp4Mortar, CBaseMonster )
|
||||
@ -277,85 +300,120 @@ void COp4Mortar::Precache()
|
||||
|
||||
void COp4Mortar::Spawn()
|
||||
{
|
||||
float angle;
|
||||
|
||||
Precache();
|
||||
UTIL_SetOrigin(pev, pev->origin);
|
||||
SET_MODEL(ENT(pev), "models/mortar.mdl");
|
||||
|
||||
UTIL_SetOrigin(pev, pev->origin);
|
||||
|
||||
SET_MODEL(edict(), "models/mortar.mdl");
|
||||
|
||||
pev->health = 1;
|
||||
pev->sequence = LookupSequence("idle");
|
||||
|
||||
ResetSequenceInfo();
|
||||
|
||||
pev->frame = 0;
|
||||
pev->framerate = 1;
|
||||
|
||||
m_tracking = FALSE;
|
||||
m_lastupdate = gpGlobals->time + 0.5;
|
||||
m_vGunAngle = Vector(0,0,0);
|
||||
m_iUpdateTime = 0;
|
||||
|
||||
if(m_FireDelay < 0.5)
|
||||
m_FireDelay = 5;
|
||||
if (m_fireDelay < 0.5)
|
||||
m_fireDelay = 5;
|
||||
|
||||
if(m_minRange == 0)
|
||||
if (m_minRange == 0)
|
||||
m_minRange = 128;
|
||||
|
||||
if(m_maxRange == 0)
|
||||
m_maxRange = 3072;
|
||||
if (m_maxRange == 0)
|
||||
m_maxRange = 2048;
|
||||
|
||||
InitBoneControllers();
|
||||
angle = pev->angles.y + 180;
|
||||
|
||||
m_zeroYaw = UTIL_AngleMod(angle);
|
||||
m_vGunAngle = g_vecZero;
|
||||
|
||||
m_lastupdate = gpGlobals->time;
|
||||
|
||||
m_zeroYaw = UTIL_AngleMod(pev->angles.y + 180.0);
|
||||
|
||||
m_fireLast = gpGlobals->time;
|
||||
m_trackDelay = gpGlobals->time;
|
||||
|
||||
m_hEnemy = NULL;
|
||||
|
||||
if (pev->spawnflags & SF_MORTAR_ACTIVE)
|
||||
SetThink(&COp4Mortar::MortarThink);
|
||||
else
|
||||
SetThink(NULL);
|
||||
pev->nextthink = gpGlobals->time + 0.01;
|
||||
SetThink(&COp4Mortar::MortarThink);
|
||||
}
|
||||
|
||||
m_flExplodeTime = gpGlobals->time + 5;
|
||||
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
void COp4Mortar::PlaySound()
|
||||
{
|
||||
if (gpGlobals->time > m_lastTimePlayedSound + 0.12f)
|
||||
{
|
||||
EMIT_SOUND(ENT(pev), CHAN_VOICE, "player/pl_grate1.wav", 1.0f, ATTN_NORM);
|
||||
m_lastTimePlayedSound = gpGlobals->time + 0.12f;
|
||||
}
|
||||
}
|
||||
|
||||
void COp4Mortar::UpdatePosition(float direction, int controller)
|
||||
{
|
||||
if(m_vGunAngle.y > 90)
|
||||
m_vGunAngle.y = 90;
|
||||
|
||||
if(m_vGunAngle.y < -90)
|
||||
m_vGunAngle.y = -90;
|
||||
|
||||
if(m_vGunAngle.x > 90)
|
||||
m_vGunAngle.x = 90;
|
||||
|
||||
if(m_vGunAngle.x < 0)
|
||||
m_vGunAngle.x = 0;
|
||||
|
||||
if(controller == 1)
|
||||
m_vGunAngle.y += direction/2;
|
||||
else
|
||||
m_vGunAngle.x += direction/2;
|
||||
|
||||
if(m_iUpdateTime >= 15)
|
||||
if (gpGlobals->time - m_lastupdate >= 0.06)
|
||||
{
|
||||
EMIT_SOUND_DYN(ENT(pev), 2, "player/pl_grate1.wav", 1, 0.8, 0, 100);
|
||||
m_iUpdateTime = 0;
|
||||
switch (controller)
|
||||
{
|
||||
case 0:
|
||||
d_x = 3 * direction;
|
||||
break;
|
||||
|
||||
case 1:
|
||||
d_y = 3 * direction;
|
||||
break;
|
||||
}
|
||||
|
||||
m_vGunAngle.x = d_x + m_vGunAngle.x;
|
||||
m_vGunAngle.y = d_y + m_vGunAngle.y;
|
||||
|
||||
if (m_hmin > m_vGunAngle.y)
|
||||
{
|
||||
m_vGunAngle.y = m_hmin;
|
||||
d_y = 0;
|
||||
}
|
||||
|
||||
if (m_vGunAngle.y > m_hmax)
|
||||
{
|
||||
m_vGunAngle.y = m_hmax;
|
||||
d_y = 0;
|
||||
}
|
||||
|
||||
if (m_vGunAngle.x < 10)
|
||||
{
|
||||
m_vGunAngle.x = 10;
|
||||
d_x = 0;
|
||||
}
|
||||
else if (m_vGunAngle.x > 90)
|
||||
{
|
||||
m_vGunAngle.x = 90;
|
||||
d_x = 0;
|
||||
}
|
||||
|
||||
if (0 != d_x || 0 != d_y)
|
||||
{
|
||||
PlaySound();
|
||||
}
|
||||
|
||||
SetBoneController(0, m_vGunAngle.x);
|
||||
SetBoneController(1, m_vGunAngle.y);
|
||||
|
||||
d_x = 0;
|
||||
d_y = 0;
|
||||
|
||||
m_lastupdate = gpGlobals->time;
|
||||
}
|
||||
|
||||
SetBoneController(1, m_vGunAngle.y);
|
||||
SetBoneController(0, m_vGunAngle.x);
|
||||
|
||||
m_lastupdate = gpGlobals->time + 0.1;
|
||||
m_iUpdateTime++;
|
||||
}
|
||||
|
||||
void COp4Mortar::MortarThink()
|
||||
{
|
||||
Vector pos, angle, vecTarget;
|
||||
const float flInterval = StudioFrameAdvance();
|
||||
|
||||
if(m_fSequenceFinished)
|
||||
if (m_fSequenceFinished)
|
||||
{
|
||||
if(pev->sequence != LookupSequence("idle"))
|
||||
if (pev->sequence != LookupSequence("idle"))
|
||||
{
|
||||
pev->frame = 0;
|
||||
pev->sequence = LookupSequence("idle");
|
||||
@ -363,55 +421,75 @@ void COp4Mortar::MortarThink()
|
||||
}
|
||||
}
|
||||
|
||||
DispatchAnimEvents();
|
||||
StudioFrameAdvance();
|
||||
DispatchAnimEvents(flInterval);
|
||||
|
||||
//GlowShellUpdate();
|
||||
|
||||
pev->nextthink = gpGlobals->time + 0.1;
|
||||
|
||||
if(pev->spawnflags & SF_MORTAR_ACTIVE)
|
||||
if ((pev->spawnflags & SF_MORTAR_ACTIVE) != 0)
|
||||
{
|
||||
if(m_hEnemy == 0 || !m_hEnemy->IsAlive())
|
||||
if (!m_hEnemy)
|
||||
{
|
||||
m_hEnemy = FindTarget();
|
||||
}
|
||||
}
|
||||
|
||||
if(m_hEnemy != 0)
|
||||
{
|
||||
vecTarget = Vector( m_hEnemy->pev->origin.x, m_hEnemy->pev->origin.y, m_hEnemy->pev->absmax.z);
|
||||
CBaseEntity* pEnemy = m_hEnemy;
|
||||
|
||||
if((pev->origin - m_hEnemy->pev->origin).Length() <= m_maxRange)
|
||||
if (pEnemy)
|
||||
{
|
||||
GetAttachment(0, pos, angle);
|
||||
const float distance = (pEnemy->pev->origin - pev->origin).Length();
|
||||
|
||||
m_vIdealGunVector = VecCheckThrow(pev, pos, vecTarget, 700, 1);
|
||||
m_vIdealGunVector.x =- m_vIdealGunVector.x;
|
||||
m_vIdealGunVector.y =- m_vIdealGunVector.y;
|
||||
|
||||
m_vIdealGunAngle = UTIL_VecToAngles(m_vIdealGunVector);
|
||||
|
||||
m_trackDelay = gpGlobals->time;
|
||||
}
|
||||
AIUpdatePosition();
|
||||
}
|
||||
|
||||
if(m_hEnemy != 0 && gpGlobals->time - m_lastFire > 5 && (m_hEnemy->pev->origin - pev->origin).Length() > 710)
|
||||
{
|
||||
EMIT_SOUND_DYN(ENT(pev), 2, "weapons/mortarhit.wav", 1, 0.8, 0, 100);
|
||||
UTIL_ScreenShake(pev->origin, 12, 100, 2, 1000);
|
||||
|
||||
float speed = m_vIdealGunVector.Length();
|
||||
|
||||
angle = m_vIdealGunAngle;
|
||||
|
||||
if(speed > 0)
|
||||
{
|
||||
if(CMortarShell::CreateMortarShell(pev->origin, angle, this, floor(speed)))
|
||||
if (pEnemy->IsAlive() && m_minRange <= distance && distance <= m_maxRange)
|
||||
{
|
||||
pev->frame = 0;
|
||||
pev->sequence = LookupSequence("fire");
|
||||
ResetSequenceInfo();
|
||||
m_lastFire = gpGlobals->time;
|
||||
if (gpGlobals->time - m_trackDelay > 0.5)
|
||||
{
|
||||
Vector vecPos, vecAngle;
|
||||
GetAttachment(0, vecPos, vecAngle);
|
||||
|
||||
m_vIdealGunVector = VecCheckThrow(pev, vecPos, pEnemy->pev->origin, m_velocity / 2);
|
||||
|
||||
m_vIdealGunAngle = UTIL_VecToAngles(m_vIdealGunVector);
|
||||
|
||||
m_trackDelay = gpGlobals->time;
|
||||
}
|
||||
|
||||
AIUpdatePosition();
|
||||
|
||||
const float idealDistance = m_vIdealGunVector.Length();
|
||||
|
||||
if (idealDistance > 1.0)
|
||||
{
|
||||
if (gpGlobals->time - m_fireLast > m_fireDelay)
|
||||
{
|
||||
EMIT_SOUND(edict(), CHAN_VOICE, "weapons/mortarhit.wav", VOL_NORM, ATTN_NORM);
|
||||
UTIL_ScreenShake(pev->origin, 12.0, 100.0, 2.0, 1000.0);
|
||||
|
||||
Vector vecPos, vecAngle;
|
||||
GetAttachment(0, vecPos, vecAngle);
|
||||
|
||||
vecAngle = m_vGunAngle;
|
||||
|
||||
vecAngle.y = UTIL_AngleMod(pev->angles.y + m_vGunAngle.y);
|
||||
|
||||
if (CMortarShell::CreateMortarShell(vecPos, vecAngle, this, idealDistance))
|
||||
{
|
||||
pev->sequence = LookupSequence("fire");
|
||||
pev->frame = 0;
|
||||
ResetSequenceInfo();
|
||||
}
|
||||
|
||||
m_fireLast = gpGlobals->time;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_fireLast = gpGlobals->time;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_hEnemy = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -419,32 +497,102 @@ void COp4Mortar::MortarThink()
|
||||
|
||||
CBaseEntity *COp4Mortar::FindTarget()
|
||||
{
|
||||
CBaseEntity *pPlayer;
|
||||
Vector BarretEnd;
|
||||
Vector BarretAngle;
|
||||
Vector targetPosition;
|
||||
TraceResult tr;
|
||||
CBaseEntity *pIdealTarget = NULL;
|
||||
CBaseEntity* pPlayerTarget = UTIL_FindEntityByClassname(NULL, "player");
|
||||
|
||||
if((pPlayer = UTIL_FindEntityByClassname(0, "player")) == NULL )
|
||||
return NULL;
|
||||
if (!pPlayerTarget)
|
||||
return pPlayerTarget;
|
||||
|
||||
m_pLink = 0;
|
||||
m_pLink = NULL;
|
||||
|
||||
GetAttachment(0, BarretEnd, BarretAngle);
|
||||
CBaseEntity* pIdealTarget = NULL;
|
||||
float flIdealDist = m_maxRange;
|
||||
|
||||
float dist = (pPlayer->pev->origin - pev->origin).Length();
|
||||
Vector barrelEnd, barrelAngle;
|
||||
GetAttachment(0, barrelEnd, barrelAngle);
|
||||
|
||||
if(pPlayer->IsAlive())
|
||||
if (pPlayerTarget->IsAlive())
|
||||
{
|
||||
if(m_maxRange >= dist)
|
||||
{
|
||||
targetPosition = pPlayer->pev->origin + pev->view_ofs;
|
||||
UTIL_TraceLine(BarretEnd, targetPosition, ignore_monsters, dont_ignore_glass, ENT(pev), &tr);
|
||||
const float distance = (pPlayerTarget->pev->origin - pev->origin).Length();
|
||||
|
||||
if((!(pev->spawnflags & SF_MORTAR_LINE_OF_SIGHT) || tr.pHit == ENT(pPlayer->pev)) && !m_iEnemyType)
|
||||
if (distance >= m_minRange && m_maxRange >= distance)
|
||||
{
|
||||
TraceResult tr;
|
||||
UTIL_TraceLine(barrelEnd, pPlayerTarget->pev->origin + pPlayerTarget->pev->view_ofs, dont_ignore_monsters, edict(), &tr);
|
||||
|
||||
if ((pev->spawnflags & SF_MORTAR_LINE_OF_SIGHT) == 0 || tr.pHit == pPlayerTarget->pev->pContainingEntity)
|
||||
{
|
||||
pIdealTarget = pPlayer;
|
||||
if (0 == m_iEnemyType)
|
||||
return pPlayerTarget;
|
||||
|
||||
flIdealDist = distance;
|
||||
pIdealTarget = pPlayerTarget;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const Vector maxRange(m_maxRange, m_maxRange, m_maxRange);
|
||||
|
||||
CBaseEntity* pList[100];
|
||||
const int count = UTIL_EntitiesInBox(pList, ARRAYSIZE(pList), pev->origin - maxRange, pev->origin + maxRange, FL_MONSTER | FL_CLIENT);
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
CBaseEntity* pEntity = pList[i];
|
||||
|
||||
if (this == pEntity)
|
||||
continue;
|
||||
|
||||
if ((pEntity->pev->spawnflags & SF_MONSTER_PRISONER) != 0)
|
||||
continue;
|
||||
|
||||
if (pEntity->pev->health <= 0)
|
||||
continue;
|
||||
|
||||
CBaseMonster* pMonster = pEntity->MyMonsterPointer();
|
||||
|
||||
if (!pMonster)
|
||||
continue;
|
||||
|
||||
if (pMonster->IRelationship(pPlayerTarget) != R_AL)
|
||||
continue;
|
||||
|
||||
if ((pEntity->pev->flags & FL_NOTARGET) != 0)
|
||||
continue;
|
||||
|
||||
if (!FVisible(pEntity))
|
||||
continue;
|
||||
|
||||
if (pEntity->IsPlayer() && (pev->spawnflags & SF_MORTAR_ACTIVE) != 0)
|
||||
{
|
||||
if (pMonster->FInViewCone(this))
|
||||
{
|
||||
pev->spawnflags &= ~SF_MORTAR_ACTIVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (CBaseEntity* pEntity = m_pLink; pEntity; pEntity = pEntity->m_pLink)
|
||||
{
|
||||
const float distance = (pEntity->pev->origin - pev->origin).Length();
|
||||
|
||||
if (distance >= m_minRange && m_maxRange >= distance && (!pIdealTarget || flIdealDist > distance))
|
||||
{
|
||||
TraceResult tr;
|
||||
UTIL_TraceLine(barrelEnd, pEntity->pev->origin + pEntity->pev->view_ofs, dont_ignore_monsters, edict(), &tr);
|
||||
|
||||
if ((pev->spawnflags & SF_MORTAR_LINE_OF_SIGHT) != 0)
|
||||
{
|
||||
if (tr.pHit == pEntity->edict())
|
||||
{
|
||||
flIdealDist = distance;
|
||||
}
|
||||
if (tr.pHit == pEntity->edict())
|
||||
pIdealTarget = pEntity;
|
||||
}
|
||||
else
|
||||
{
|
||||
flIdealDist = distance;
|
||||
pIdealTarget = pEntity;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -459,40 +607,40 @@ int COp4Mortar::TakeDamage(entvars_t *pevInflictor, entvars_t *pevAttacker, floa
|
||||
|
||||
void COp4Mortar::KeyValue(KeyValueData *pvkd)
|
||||
{
|
||||
if(strcmp(pvkd->szKeyName, "m_hmax"))
|
||||
if(FStrEq(pvkd->szKeyName, "h_max"))
|
||||
{
|
||||
m_hmax = atoi(pvkd->szValue);
|
||||
pvkd->fHandled = 1;
|
||||
pvkd->fHandled = TRUE;
|
||||
}
|
||||
else if(strcmp(pvkd->szKeyName, "m_hmin"))
|
||||
else if(FStrEq(pvkd->szKeyName, "h_min"))
|
||||
{
|
||||
m_hmin = atoi(pvkd->szValue);
|
||||
pvkd->fHandled = 1;
|
||||
pvkd->fHandled = TRUE;
|
||||
}
|
||||
else if(strcmp(pvkd->szKeyName, "mortar_velocity"))
|
||||
else if(FStrEq(pvkd->szKeyName, "mortar_velocity"))
|
||||
{
|
||||
m_velocity = atoi(pvkd->szValue);
|
||||
pvkd->fHandled = 1;
|
||||
pvkd->fHandled = TRUE;
|
||||
}
|
||||
else if(strcmp(pvkd->szKeyName, "mindist"))
|
||||
else if(FStrEq(pvkd->szKeyName, "mindist"))
|
||||
{
|
||||
m_minRange = atoi(pvkd->szValue);
|
||||
pvkd->fHandled = 1;
|
||||
pvkd->fHandled = TRUE;
|
||||
}
|
||||
else if(strcmp(pvkd->szKeyName, "maxdist"))
|
||||
else if(FStrEq(pvkd->szKeyName, "maxdist"))
|
||||
{
|
||||
m_maxRange = atoi(pvkd->szValue);
|
||||
pvkd->fHandled = 1;
|
||||
pvkd->fHandled = TRUE;
|
||||
}
|
||||
else if(strcmp(pvkd->szKeyName, "enemytype"))
|
||||
else if(FStrEq(pvkd->szKeyName, "enemytype"))
|
||||
{
|
||||
m_iEnemyType = atoi(pvkd->szValue);
|
||||
pvkd->fHandled = 1;
|
||||
pvkd->fHandled = TRUE;
|
||||
}
|
||||
else if(strcmp(pvkd->szKeyName, "firedelay"))
|
||||
else if(FStrEq(pvkd->szKeyName, "firedelay"))
|
||||
{
|
||||
m_FireDelay = atoi(pvkd->szValue);
|
||||
pvkd->fHandled = 1;
|
||||
m_fireDelay = atoi(pvkd->szValue);
|
||||
pvkd->fHandled = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -502,58 +650,109 @@ void COp4Mortar::KeyValue(KeyValueData *pvkd)
|
||||
|
||||
void COp4Mortar::Use(CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value)
|
||||
{
|
||||
SetThink(NULL);
|
||||
|
||||
if((pev->spawnflags & SF_MORTAR_CAN_CONTROL) && (pActivator->pev->origin - pev->origin).Length() < 170)
|
||||
if (useType == USE_TOGGLE && (!pActivator || pActivator->IsPlayer()))
|
||||
{
|
||||
EMIT_SOUND_DYN(ENT(pev), 2, "weapons/mortarhit.wav", 1, 0, 0, 100);
|
||||
UTIL_ScreenShake(pev->origin, 12, 100, 2, 1000);
|
||||
|
||||
Vector pos, angle;
|
||||
GetAttachment(0, pos, angle);
|
||||
angle = m_vGunAngle;
|
||||
float anglemod = pev->angles.y + m_vGunAngle.y;
|
||||
|
||||
angle.y = UTIL_AngleMod(anglemod);
|
||||
|
||||
if((CMortarShell::CreateMortarShell(pos, angle, this, 2000 - (m_vGunAngle.x * 12.25))) != NULL)
|
||||
if ((pev->spawnflags & SF_MORTAR_ACTIVE) == 0 && (pev->spawnflags & SF_MORTAR_CONTROLLABLE) != 0)
|
||||
{
|
||||
pev->frame = 0;
|
||||
pev->sequence = LookupSequence("fire");
|
||||
ResetSequenceInfo();
|
||||
//Player fired a mortar
|
||||
EMIT_SOUND(edict(), CHAN_VOICE, "weapons/mortarhit.wav", VOL_NORM, ATTN_NONE);
|
||||
UTIL_ScreenShake(pev->origin, 12.0, 100.0, 2.0, 1000.0);
|
||||
|
||||
Vector pos, angle;
|
||||
GetAttachment(0, pos, angle);
|
||||
|
||||
angle = m_vGunAngle;
|
||||
|
||||
angle.y = UTIL_AngleMod(pev->angles.y + m_vGunAngle.y);
|
||||
|
||||
if (CMortarShell::CreateMortarShell(pos, angle, pActivator ? pActivator : this, m_velocity))
|
||||
{
|
||||
pev->sequence = LookupSequence("fire");
|
||||
pev->frame = 0;
|
||||
ResetSequenceInfo();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//Toggle AI active state
|
||||
if (ShouldToggle(useType, (pev->spawnflags & SF_MORTAR_ACTIVE) != 0))
|
||||
{
|
||||
pev->spawnflags ^= SF_MORTAR_ACTIVE;
|
||||
|
||||
m_fireLast = 0;
|
||||
m_hEnemy = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void COp4Mortar::AIUpdatePosition()
|
||||
{
|
||||
if(m_hEnemy != 0 && (m_hEnemy->pev->origin - pev->origin).Length() < 710)
|
||||
return;
|
||||
|
||||
if(m_vIdealGunAngle.x == 270 && m_vIdealGunAngle.y == 0)
|
||||
if (fabs(m_vGunAngle.x - m_vIdealGunAngle.x) >= 3.0)
|
||||
{
|
||||
m_vIdealGunAngle.x = 0;
|
||||
m_vIdealGunAngle.y = 0;
|
||||
const float angle = UTIL_AngleDiff(m_vGunAngle.x, m_vIdealGunAngle.x);
|
||||
|
||||
if (angle != 0)
|
||||
{
|
||||
const float absolute = fabs(angle);
|
||||
if (absolute <= 3.0)
|
||||
d_x = static_cast<int>(-absolute);
|
||||
else
|
||||
d_x = angle > 0 ? -3 : 3;
|
||||
}
|
||||
}
|
||||
|
||||
if(m_vIdealGunAngle.x <= 0)
|
||||
m_vIdealGunAngle.x = 0;
|
||||
const float yawAngle = UTIL_AngleMod(m_zeroYaw + m_vGunAngle.y);
|
||||
|
||||
if(m_vIdealGunAngle.x > 90)
|
||||
m_vIdealGunAngle.x = 90;
|
||||
if (fabs(yawAngle - m_vIdealGunAngle.y) >= 3.0)
|
||||
{
|
||||
const float angle = UTIL_AngleDiff(yawAngle, m_vIdealGunAngle.y);
|
||||
|
||||
if(m_vIdealGunAngle.y > 165 && m_vIdealGunAngle.y < 270)
|
||||
m_vIdealGunAngle.y = -90;
|
||||
if (angle != 0)
|
||||
{
|
||||
const float absolute = fabs(angle);
|
||||
if (absolute <= 3.0)
|
||||
d_y = static_cast<int>(-absolute);
|
||||
else
|
||||
d_y = angle > 0 ? -3 : 3;
|
||||
}
|
||||
}
|
||||
|
||||
else if(m_vIdealGunAngle.y > 90 && m_vIdealGunAngle.y < 165)
|
||||
m_vIdealGunAngle.y = 90;
|
||||
m_vGunAngle.x += d_x;
|
||||
m_vGunAngle.y += d_y;
|
||||
|
||||
if (m_hmin > m_vGunAngle.y)
|
||||
{
|
||||
m_vGunAngle.y = m_hmin;
|
||||
d_y = 0;
|
||||
}
|
||||
|
||||
SetBoneController(0, m_vIdealGunAngle.x);
|
||||
SetBoneController(1, m_vIdealGunAngle.y);
|
||||
if (m_vGunAngle.y > m_hmax)
|
||||
{
|
||||
m_vGunAngle.y = m_hmax;
|
||||
d_y = 0;
|
||||
}
|
||||
|
||||
m_vGunAngle = m_vIdealGunAngle;
|
||||
if (m_vGunAngle.x < 10.0)
|
||||
{
|
||||
m_vGunAngle.x = 10.0;
|
||||
d_x = 0;
|
||||
}
|
||||
else if (m_vGunAngle.x > 90.0)
|
||||
{
|
||||
m_vGunAngle.x = 90.0;
|
||||
d_x = 0;
|
||||
}
|
||||
|
||||
if (0 != d_x || 0 != d_y)
|
||||
{
|
||||
PlaySound();
|
||||
}
|
||||
|
||||
SetBoneController(0, m_vGunAngle.x);
|
||||
SetBoneController(1, m_vGunAngle.y);
|
||||
|
||||
d_y = 0;
|
||||
d_x = 0;
|
||||
}
|
||||
|
||||
//========================================================
|
||||
@ -571,9 +770,9 @@ public:
|
||||
int ObjectCaps() { return FCAP_CONTINUOUS_USE; }
|
||||
|
||||
static TYPEDESCRIPTION m_SaveData[];
|
||||
float m_direction;
|
||||
float m_lastpush;
|
||||
int m_direction;
|
||||
int m_controller;
|
||||
float m_lastpush;
|
||||
};
|
||||
|
||||
LINK_ENTITY_TO_CLASS(func_op4mortarcontroller, COp4MortarController)
|
||||
@ -620,7 +819,7 @@ void COp4MortarController::KeyValue(KeyValueData *pvkd)
|
||||
if(FStrEq(pvkd->szKeyName, "mortar_axis"))
|
||||
{
|
||||
m_controller = atoi(pvkd->szValue);
|
||||
pvkd->fHandled = 1;
|
||||
pvkd->fHandled = TRUE;
|
||||
}
|
||||
else
|
||||
CBaseToggle::KeyValue(pvkd);
|
||||
|
@ -31,16 +31,6 @@
|
||||
#define SPRING_DAMPING 0.1f
|
||||
#define ROPE_IGNORE_SAMPLES 4 // integrator may be hanging if less than
|
||||
|
||||
//#define SetAbsOrigin(x) pev->origin = x;
|
||||
#define SetAbsAngles(x) pev->angles = x;
|
||||
#define SetAbsVelociy(x) pev->velocity = x;
|
||||
#define SetNextThink(x) pev->nextthink = x;
|
||||
#define SetEffects(x) pev->effects = x;
|
||||
#define SetSolidType(x) pev->solid = x;
|
||||
#define AddFlags(x) pev->flags |= x;
|
||||
#define SetMoveType(x) pev->movetype = x;
|
||||
#define AddEffectsFlags(x) pev->effects |= x;
|
||||
|
||||
/**
|
||||
* Data for a single rope joint.
|
||||
*/
|
||||
@ -74,17 +64,22 @@ public:
|
||||
|
||||
static CRopeSample* CreateSample();
|
||||
|
||||
RopeSampleData* GetData() {
|
||||
if (swapped)
|
||||
return &data2;
|
||||
else
|
||||
return &data;
|
||||
RopeSampleData& GetData()
|
||||
{
|
||||
return data;
|
||||
}
|
||||
RopeSampleData* GetData2() {
|
||||
|
||||
RopeSampleData& GetSourceData() {
|
||||
if (swapped)
|
||||
return &data;
|
||||
return data2;
|
||||
else
|
||||
return &data2;
|
||||
return data;
|
||||
}
|
||||
RopeSampleData& GetTargetData() {
|
||||
if (swapped)
|
||||
return data;
|
||||
else
|
||||
return data2;
|
||||
}
|
||||
|
||||
void Swap()
|
||||
@ -92,6 +87,11 @@ public:
|
||||
swapped = !swapped;
|
||||
}
|
||||
|
||||
void ResetSwap()
|
||||
{
|
||||
swapped = FALSE;
|
||||
}
|
||||
|
||||
private:
|
||||
RopeSampleData data;
|
||||
RopeSampleData data2;
|
||||
@ -257,7 +257,7 @@ void CRope::Activate()
|
||||
|
||||
void CRope::InitRope()
|
||||
{
|
||||
AddFlags( FL_ALWAYSTHINK );
|
||||
pev->flags |= FL_ALWAYSTHINK;
|
||||
|
||||
for( int uiSample = 0; uiSample < m_NumSamples; ++uiSample )
|
||||
{
|
||||
@ -334,7 +334,7 @@ void CRope::InitRope()
|
||||
InitializeRopeSim();
|
||||
|
||||
SetThink(&CRope::RopeThink);
|
||||
SetNextThink( gpGlobals->time + 0.01 );
|
||||
pev->nextthink = gpGlobals->time + 0.01;
|
||||
}
|
||||
|
||||
void CRope::RopeThink()
|
||||
@ -364,7 +364,7 @@ void CRope::RopeThink()
|
||||
Creak();
|
||||
}
|
||||
|
||||
SetNextThink( gpGlobals->time + 0.001 );
|
||||
pev->nextthink = gpGlobals->time + 0.001;
|
||||
}
|
||||
|
||||
void CRope::InitializeRopeSim()
|
||||
@ -376,26 +376,26 @@ void CRope::InitializeRopeSim()
|
||||
CRopeSegment* pSegment = seg[ uiSeg ];
|
||||
CRopeSample* pSample = pSegment->GetSample();
|
||||
|
||||
RopeSampleData *data = pSample->GetData();
|
||||
RopeSampleData& data = pSample->GetData();
|
||||
|
||||
data->mPosition = pSegment->pev->origin;
|
||||
data.mPosition = pSegment->pev->origin;
|
||||
|
||||
data->mVelocity = g_vecZero;
|
||||
data->mForce = g_vecZero;
|
||||
data->mMassReciprocal = 1;
|
||||
data->mApplyExternalForce = false;
|
||||
data->mExternalForce = g_vecZero;
|
||||
data.mVelocity = g_vecZero;
|
||||
data.mForce = g_vecZero;
|
||||
data.mMassReciprocal = 1;
|
||||
data.mApplyExternalForce = false;
|
||||
data.mExternalForce = g_vecZero;
|
||||
|
||||
Vector vecOrigin, vecAngles;
|
||||
pSegment->GetAttachment( 0, vecOrigin, vecAngles );
|
||||
data->restLength = ( pSegment->pev->origin - vecOrigin ).Length();
|
||||
data.restLength = ( pSegment->pev->origin - vecOrigin ).Length();
|
||||
}
|
||||
|
||||
{
|
||||
//Zero out the anchored segment's mass so it stays in place.
|
||||
CRopeSample *pSample = m_Samples[ 0 ];
|
||||
|
||||
pSample->GetData()->mMassReciprocal = 0;
|
||||
pSample->GetData().mMassReciprocal = 0;
|
||||
}
|
||||
|
||||
CRopeSegment* pSegment = seg[ m_iSegments - 1 ];
|
||||
@ -414,19 +414,19 @@ void CRope::InitializeRopeSim()
|
||||
|
||||
CRopeSample* pSample = m_Samples[ m_NumSamples - 1 ];
|
||||
|
||||
RopeSampleData *data = pSample->GetData();
|
||||
RopeSampleData& data = pSample->GetData();
|
||||
|
||||
data->mPosition = vecOrigin;
|
||||
data.mPosition = vecOrigin;
|
||||
|
||||
m_LastEndPos = vecOrigin;
|
||||
|
||||
data->mVelocity = g_vecZero;
|
||||
data.mVelocity = g_vecZero;
|
||||
|
||||
data->mForce = g_vecZero;
|
||||
data.mForce = g_vecZero;
|
||||
|
||||
data->mMassReciprocal = 0.2;
|
||||
data.mMassReciprocal = 0.2;
|
||||
|
||||
data->mApplyExternalForce = false;
|
||||
data.mApplyExternalForce = false;
|
||||
|
||||
int uiNumSegs = ROPE_IGNORE_SAMPLES;
|
||||
|
||||
@ -453,6 +453,7 @@ void CRope::RunSimOnSamples()
|
||||
|
||||
int uiIndex = 0;
|
||||
|
||||
bool swapped = false;
|
||||
while( true )
|
||||
{
|
||||
++uiIndex;
|
||||
@ -472,13 +473,15 @@ void CRope::RunSimOnSamples()
|
||||
{
|
||||
m_Samples[i]->Swap();
|
||||
}
|
||||
swapped = !swapped;
|
||||
}
|
||||
|
||||
//CRopeSample **swap = ppSampleSource;
|
||||
//ppSampleSource = ppSampleTarget;
|
||||
//ppSampleTarget = swap;
|
||||
|
||||
//std::swap( ppSampleSource, ppSampleTarget );
|
||||
|
||||
if (swapped)
|
||||
{
|
||||
for (int i=0; i<m_NumSamples; ++i)
|
||||
{
|
||||
m_Samples[i]->ResetSwap();
|
||||
}
|
||||
}
|
||||
|
||||
mLastTime = gpGlobals->time;
|
||||
@ -503,12 +506,12 @@ void CRope::ComputeForces( CRopeSample** ppSystem )
|
||||
int uiIndex;
|
||||
for( uiIndex = 0; uiIndex < m_NumSamples; ++uiIndex )
|
||||
{
|
||||
ComputeSampleForce( *ppSystem[ uiIndex ]->GetData() );
|
||||
ComputeSampleForce( ppSystem[ uiIndex ]->GetSourceData() );
|
||||
}
|
||||
|
||||
for( uiIndex = 0; uiIndex < m_iSegments; ++uiIndex )
|
||||
{
|
||||
ComputeSpringForce( *ppSystem[ uiIndex ]->GetData(), *ppSystem[ uiIndex+1 ]->GetData() );
|
||||
ComputeSpringForce( ppSystem[ uiIndex ]->GetSourceData(), ppSystem[ uiIndex+1 ]->GetSourceData() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -576,16 +579,16 @@ void CRope::RK4Integrate( const float flDeltaTime )
|
||||
|
||||
for( int uiIndex = 0; uiIndex < m_NumSamples; ++uiIndex, ++pTemp1, ++pTemp2 )
|
||||
{
|
||||
RopeSampleData *data = m_Samples[ uiIndex ]->GetData();
|
||||
RopeSampleData& data = m_Samples[ uiIndex ]->GetSourceData();
|
||||
|
||||
pTemp2->mForce = data->mMassReciprocal * data->mForce * flDeltas[ 0 ];
|
||||
pTemp2->mVelocity = data->mVelocity * flDeltas[ 0 ];
|
||||
pTemp2->restLength = data->restLength;
|
||||
pTemp2->mForce = data.mMassReciprocal * data.mForce * flDeltas[ 0 ];
|
||||
pTemp2->mVelocity = data.mVelocity * flDeltas[ 0 ];
|
||||
pTemp2->restLength = data.restLength;
|
||||
|
||||
pTemp1->mMassReciprocal = data->mMassReciprocal;
|
||||
pTemp1->mVelocity = data->mVelocity + pTemp2->mForce;
|
||||
pTemp1->mPosition = data->mPosition + pTemp2->mVelocity;
|
||||
pTemp1->restLength = data->restLength;
|
||||
pTemp1->mMassReciprocal = data.mMassReciprocal;
|
||||
pTemp1->mVelocity = data.mVelocity + pTemp2->mForce;
|
||||
pTemp1->mPosition = data.mPosition + pTemp2->mVelocity;
|
||||
pTemp1->restLength = data.restLength;
|
||||
}
|
||||
|
||||
ComputeForces( g_pTempList[ 0 ] );
|
||||
@ -598,16 +601,16 @@ void CRope::RK4Integrate( const float flDeltaTime )
|
||||
|
||||
for( int uiIndex = 0; uiIndex < m_NumSamples; ++uiIndex, ++pTemp1, ++pTemp2 )
|
||||
{
|
||||
RopeSampleData *data = m_Samples[ uiIndex ]->GetData();
|
||||
RopeSampleData& data = m_Samples[ uiIndex ]->GetSourceData();
|
||||
|
||||
pTemp2->mForce = data->mMassReciprocal * pTemp1->mForce * flDeltas[ uiStep - 1 ];
|
||||
pTemp2->mForce = data.mMassReciprocal * pTemp1->mForce * flDeltas[ uiStep - 1 ];
|
||||
pTemp2->mVelocity = pTemp1->mVelocity * flDeltas[ uiStep - 1 ];
|
||||
pTemp2->restLength = data->restLength;
|
||||
pTemp2->restLength = data.restLength;
|
||||
|
||||
pTemp1->mMassReciprocal = data->mMassReciprocal;
|
||||
pTemp1->mVelocity = data->mVelocity + pTemp2->mForce;
|
||||
pTemp1->mPosition = data->mPosition + pTemp2->mVelocity;
|
||||
pTemp1->restLength = data->restLength;
|
||||
pTemp1->mMassReciprocal = data.mMassReciprocal;
|
||||
pTemp1->mVelocity = data.mVelocity + pTemp2->mForce;
|
||||
pTemp1->mPosition = data.mPosition + pTemp2->mVelocity;
|
||||
pTemp1->restLength = data.restLength;
|
||||
}
|
||||
|
||||
ComputeForces( g_pTempList[ 0 ] );
|
||||
@ -619,9 +622,9 @@ void CRope::RK4Integrate( const float flDeltaTime )
|
||||
|
||||
for( int uiIndex = 0; uiIndex < m_NumSamples; ++uiIndex, ++pTemp1, ++pTemp2 )
|
||||
{
|
||||
RopeSampleData *data = m_Samples[ uiIndex ]->GetData();
|
||||
RopeSampleData& data = m_Samples[ uiIndex ]->GetSourceData();
|
||||
|
||||
pTemp2->mForce = data->mMassReciprocal * pTemp1->mForce * flDeltas[ 3 ];
|
||||
pTemp2->mForce = data.mMassReciprocal * pTemp1->mForce * flDeltas[ 3 ];
|
||||
|
||||
pTemp2->mVelocity = pTemp1->mVelocity * flDeltas[ 3 ];
|
||||
}
|
||||
@ -634,16 +637,16 @@ void CRope::RK4Integrate( const float flDeltaTime )
|
||||
|
||||
for( int uiIndex = 0; uiIndex < m_NumSamples; ++uiIndex, ++pTemp1, ++pTemp2, ++pTemp3, ++pTemp4 )
|
||||
{
|
||||
RopeSampleData *pSource = m_Samples[ uiIndex ]->GetData();
|
||||
RopeSampleData *pTarget = m_Samples[ uiIndex ]->GetData2();
|
||||
RopeSampleData& pSource = m_Samples[ uiIndex ]->GetSourceData();
|
||||
RopeSampleData& pTarget = m_Samples[ uiIndex ]->GetTargetData();
|
||||
|
||||
const Vector vecPosChange = 1.0f / 6.0f * ( pTemp1->mVelocity + ( pTemp2->mVelocity + pTemp3->mVelocity ) * 2 + pTemp4->mVelocity );
|
||||
|
||||
const Vector vecVelChange = 1.0f / 6.0f * ( pTemp1->mForce + ( pTemp2->mForce + pTemp3->mForce ) * 2 + pTemp4->mForce );
|
||||
|
||||
pTarget->mPosition = pSource->mPosition + ( vecPosChange );//* flDeltaTime );
|
||||
pTarget.mPosition = pSource.mPosition + ( vecPosChange );//* flDeltaTime );
|
||||
|
||||
pTarget->mVelocity = pSource->mVelocity + ( vecVelChange );//* flDeltaTime );
|
||||
pTarget.mVelocity = pSource.mVelocity + ( vecVelChange );//* flDeltaTime );
|
||||
}
|
||||
}
|
||||
|
||||
@ -686,30 +689,31 @@ void CRope::TraceModels( CRopeSegment** ppPrimarySegs, CRopeSegment** ppHiddenSe
|
||||
Vector vecAngles;
|
||||
|
||||
GetAlignmentAngles(
|
||||
m_Samples[ 0 ]->GetData()->mPosition,
|
||||
m_Samples[ 1 ]->GetData()->mPosition,
|
||||
m_Samples[ 0 ]->GetData().mPosition,
|
||||
m_Samples[ 1 ]->GetData().mPosition,
|
||||
vecAngles );
|
||||
|
||||
( *ppPrimarySegs )->SetAbsAngles( vecAngles );
|
||||
( *ppPrimarySegs )->pev->angles = vecAngles;
|
||||
}
|
||||
|
||||
TraceResult tr;
|
||||
|
||||
if( mObjectAttached )
|
||||
{
|
||||
for( int uiSeg = 1; uiSeg < m_iSegments; ++uiSeg )
|
||||
for( unsigned int uiSeg = 1; uiSeg < m_iSegments; ++uiSeg )
|
||||
{
|
||||
CRopeSample* pSample = m_Samples[ uiSeg ];
|
||||
|
||||
Vector vecDist = pSample->GetData()->mPosition - ppHiddenSegs[ uiSeg ]->pev->origin;
|
||||
Vector vecDist = pSample->GetData().mPosition - ppHiddenSegs[ uiSeg ]->pev->origin;
|
||||
|
||||
vecDist = vecDist.Normalize();
|
||||
|
||||
// HACK: this code relies on integer underflow. uiSeg must be unsigned!
|
||||
const float flTraceDist = ( uiSeg - mAttachedObjectsSegment + 2 ) < 5 ? 50 : 10;
|
||||
|
||||
const Vector vecTraceDist = vecDist * flTraceDist;
|
||||
|
||||
const Vector vecEnd = pSample->GetData()->mPosition + vecTraceDist;
|
||||
const Vector vecEnd = pSample->GetData().mPosition + vecTraceDist;
|
||||
|
||||
UTIL_TraceLine( ppHiddenSegs[ uiSeg ]->pev->origin, vecEnd, ignore_monsters, edict(), &tr );
|
||||
|
||||
@ -728,17 +732,17 @@ void CRope::TraceModels( CRopeSegment** ppPrimarySegs, CRopeSegment** ppHiddenSe
|
||||
|
||||
Vector vecNormal = tr.vecPlaneNormal.Normalize() * 20000.0;
|
||||
|
||||
RopeSampleData *data = ppPrimarySegs[ uiSeg ]->GetSample()->GetData();
|
||||
RopeSampleData& data = ppPrimarySegs[ uiSeg ]->GetSample()->GetData();
|
||||
|
||||
data->mApplyExternalForce = true;
|
||||
data.mApplyExternalForce = true;
|
||||
|
||||
data->mExternalForce = vecNormal;
|
||||
data.mExternalForce = vecNormal;
|
||||
|
||||
data->mVelocity = g_vecZero;
|
||||
data.mVelocity = g_vecZero;
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector vecOrigin = pSample->GetData()->mPosition;
|
||||
Vector vecOrigin = pSample->GetData().mPosition;
|
||||
|
||||
TruncateEpsilon( vecOrigin );
|
||||
|
||||
@ -748,16 +752,16 @@ void CRope::TraceModels( CRopeSegment** ppPrimarySegs, CRopeSegment** ppHiddenSe
|
||||
}
|
||||
else
|
||||
{
|
||||
for( int uiSeg = 1; uiSeg < m_iSegments; ++uiSeg )
|
||||
for( unsigned int uiSeg = 1; uiSeg < m_iSegments; ++uiSeg )
|
||||
{
|
||||
UTIL_TraceLine(
|
||||
ppHiddenSegs[ uiSeg ]->pev->origin,
|
||||
m_Samples[ uiSeg ]->GetData()->mPosition,
|
||||
m_Samples[ uiSeg ]->GetData().mPosition,
|
||||
ignore_monsters, edict(), &tr );
|
||||
|
||||
if( tr.flFraction == 1.0 )
|
||||
{
|
||||
Vector vecOrigin = m_Samples[ uiSeg ]->GetData()->mPosition;
|
||||
Vector vecOrigin = m_Samples[ uiSeg ]->GetData().mPosition;
|
||||
|
||||
TruncateEpsilon( vecOrigin );
|
||||
|
||||
@ -774,9 +778,9 @@ void CRope::TraceModels( CRopeSegment** ppPrimarySegs, CRopeSegment** ppHiddenSe
|
||||
|
||||
ppPrimarySegs[ uiSeg ]->SetAbsOrigin( vecOrigin );
|
||||
|
||||
ppPrimarySegs[ uiSeg ]->GetSample()->GetData()->mApplyExternalForce = true;
|
||||
ppPrimarySegs[ uiSeg ]->GetSample()->GetData().mApplyExternalForce = true;
|
||||
|
||||
ppPrimarySegs[ uiSeg ]->GetSample()->GetData()->mExternalForce = vecNormal * 40000.0;
|
||||
ppPrimarySegs[ uiSeg ]->GetSample()->GetData().mExternalForce = vecNormal * 40000.0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -790,26 +794,26 @@ void CRope::TraceModels( CRopeSegment** ppPrimarySegs, CRopeSegment** ppHiddenSe
|
||||
|
||||
GetAlignmentAngles( pSegment->pev->origin, pSegment2->pev->origin, vecAngles );
|
||||
|
||||
pSegment->SetAbsAngles( vecAngles );
|
||||
pSegment->pev->angles = vecAngles;
|
||||
}
|
||||
|
||||
if( m_iSegments > 1 )
|
||||
{
|
||||
CRopeSample *pSample = m_Samples[ m_NumSamples - 1 ];
|
||||
|
||||
UTIL_TraceLine( m_LastEndPos, pSample->GetData()->mPosition, ignore_monsters, edict(), &tr );
|
||||
UTIL_TraceLine( m_LastEndPos, pSample->GetData().mPosition, ignore_monsters, edict(), &tr );
|
||||
|
||||
if( tr.flFraction == 1.0 )
|
||||
{
|
||||
m_LastEndPos = pSample->GetData()->mPosition;
|
||||
m_LastEndPos = pSample->GetData().mPosition;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_LastEndPos = tr.vecEndPos;
|
||||
|
||||
pSample->GetData()->mApplyExternalForce = true;
|
||||
pSample->GetData().mApplyExternalForce = true;
|
||||
|
||||
pSample->GetData()->mExternalForce = tr.vecPlaneNormal.Normalize() * 40000.0;
|
||||
pSample->GetData().mExternalForce = tr.vecPlaneNormal.Normalize() * 40000.0;
|
||||
}
|
||||
|
||||
CRopeSegment *pSegment = ppPrimarySegs[ m_NumSamples - 2 ];
|
||||
@ -818,7 +822,7 @@ void CRope::TraceModels( CRopeSegment** ppPrimarySegs, CRopeSegment** ppHiddenSe
|
||||
|
||||
GetAlignmentAngles( pSegment->pev->origin, m_LastEndPos, vecAngles );
|
||||
|
||||
pSegment->SetAbsAngles( vecAngles );
|
||||
pSegment->pev->angles = vecAngles;
|
||||
}
|
||||
}
|
||||
|
||||
@ -829,22 +833,22 @@ void CRope::SetRopeSegments( const int uiNumSegments,
|
||||
{
|
||||
TraceModels( ppPrimarySegs, ppHiddenSegs );
|
||||
|
||||
ppPrimarySegs[ 0 ]->SetSolidType( SOLID_TRIGGER );
|
||||
ppPrimarySegs[ 0 ]->SetEffects( 0 );
|
||||
ppPrimarySegs[ 0 ]->pev->solid = SOLID_TRIGGER;
|
||||
ppPrimarySegs[ 0 ]->pev->effects = 0;
|
||||
|
||||
ppHiddenSegs[ 0 ]->SetSolidType( SOLID_NOT );
|
||||
ppHiddenSegs[ 0 ]->SetEffects( EF_NODRAW );
|
||||
ppHiddenSegs[ 0 ]->pev->solid = SOLID_NOT;
|
||||
ppHiddenSegs[ 0 ]->pev->effects = EF_NODRAW;
|
||||
|
||||
for( int uiIndex = 1; uiIndex < uiNumSegments; ++uiIndex )
|
||||
{
|
||||
CRopeSegment* pPrim = ppPrimarySegs[ uiIndex ];
|
||||
CRopeSegment* pHidden = ppHiddenSegs[ uiIndex ];
|
||||
|
||||
pPrim->SetSolidType( SOLID_TRIGGER );
|
||||
pPrim->SetEffects( 0 );
|
||||
pPrim->pev->solid = SOLID_TRIGGER;
|
||||
pPrim->pev->effects = 0;
|
||||
|
||||
pHidden->SetSolidType( SOLID_NOT );
|
||||
pHidden->SetEffects( EF_NODRAW );
|
||||
pHidden->pev->solid = SOLID_NOT;
|
||||
pHidden->pev->effects = EF_NODRAW;
|
||||
|
||||
Vector vecOrigin = pPrim->pev->origin;
|
||||
|
||||
@ -974,7 +978,7 @@ Vector CRope::GetAttachedObjectsVelocity() const
|
||||
if( !mObjectAttached )
|
||||
return g_vecZero;
|
||||
|
||||
return seg[ mAttachedObjectsSegment ]->GetSample()->GetData()->mVelocity;
|
||||
return seg[ mAttachedObjectsSegment ]->GetSample()->GetData().mVelocity;
|
||||
}
|
||||
|
||||
void CRope::ApplyForceFromPlayer( const Vector& vecForce )
|
||||
@ -1002,11 +1006,11 @@ void CRope::ApplyForceToSegment( const Vector& vecForce, const int uiSegment )
|
||||
{
|
||||
//Apply force to the last sample.
|
||||
|
||||
RopeSampleData *data = m_Samples[ uiSegment - 1 ]->GetData();
|
||||
RopeSampleData& data = m_Samples[ uiSegment - 1 ]->GetData();
|
||||
|
||||
data->mExternalForce = data->mExternalForce + vecForce;
|
||||
data.mExternalForce = data.mExternalForce + vecForce;
|
||||
|
||||
data->mApplyExternalForce = true;
|
||||
data.mApplyExternalForce = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1043,7 +1047,7 @@ bool CRope::ShouldCreak() const
|
||||
{
|
||||
CRopeSample* pSample = seg[ mAttachedObjectsSegment ]->GetSample();
|
||||
|
||||
if( pSample->GetData()->mVelocity.Length() > 20.0 )
|
||||
if( pSample->GetData().mVelocity.Length() > 20.0 )
|
||||
return RANDOM_LONG( 1, 5 ) == 1;
|
||||
}
|
||||
|
||||
@ -1093,7 +1097,7 @@ float CRope::GetRopeLength() const
|
||||
|
||||
Vector CRope::GetRopeOrigin() const
|
||||
{
|
||||
return m_Samples[ 0 ]->GetData()->mPosition;
|
||||
return m_Samples[ 0 ]->GetData().mPosition;
|
||||
}
|
||||
|
||||
bool CRope::IsValidSegmentIndex( const int uiSegment ) const
|
||||
@ -1106,7 +1110,7 @@ Vector CRope::GetSegmentOrigin( const int uiSegment ) const
|
||||
if( !IsValidSegmentIndex( uiSegment ) )
|
||||
return g_vecZero;
|
||||
|
||||
return m_Samples[ uiSegment ]->GetData()->mPosition;
|
||||
return m_Samples[ uiSegment ]->GetData().mPosition;
|
||||
}
|
||||
|
||||
Vector CRope::GetSegmentAttachmentPoint( const int uiSegment ) const
|
||||
@ -1142,8 +1146,8 @@ Vector CRope::GetSegmentDirFromOrigin( const int uiSegmentIndex ) const
|
||||
|
||||
//There is one more sample than there are segments, so this is fine.
|
||||
const Vector vecResult =
|
||||
m_Samples[ uiSegmentIndex + 1 ]->GetData()->mPosition -
|
||||
m_Samples[ uiSegmentIndex ]->GetData()->mPosition;
|
||||
m_Samples[ uiSegmentIndex + 1 ]->GetData().mPosition -
|
||||
m_Samples[ uiSegmentIndex ]->GetData().mPosition;
|
||||
|
||||
return vecResult.Normalize();
|
||||
}
|
||||
@ -1156,7 +1160,7 @@ Vector CRope::GetAttachedObjectsPosition() const
|
||||
Vector vecResult;
|
||||
|
||||
if( mAttachedObjectsSegment < m_iSegments )
|
||||
vecResult = m_Samples[ mAttachedObjectsSegment ]->GetData()->mPosition;
|
||||
vecResult = m_Samples[ mAttachedObjectsSegment ]->GetData().mPosition;
|
||||
|
||||
vecResult = vecResult +
|
||||
( mAttachedObjectsOffset * GetSegmentDirFromOrigin( mAttachedObjectsSegment ) );
|
||||
@ -1194,7 +1198,7 @@ void CRopeSample::Spawn()
|
||||
{
|
||||
pev->classname = MAKE_STRING( "rope_sample" );
|
||||
|
||||
AddEffectsFlags( EF_NODRAW );
|
||||
pev->effects |= EF_NODRAW;
|
||||
}
|
||||
|
||||
CRopeSample* CRopeSample::CreateSample()
|
||||
@ -1238,14 +1242,14 @@ void CRopeSegment::Spawn()
|
||||
|
||||
SET_MODEL( edict(), STRING( mModelName ) );
|
||||
|
||||
SetMoveType( MOVETYPE_NOCLIP );
|
||||
SetSolidType( SOLID_TRIGGER );
|
||||
SetEffects( EF_NODRAW );
|
||||
pev->movetype = MOVETYPE_NOCLIP;
|
||||
pev->solid = SOLID_TRIGGER;
|
||||
pev->effects = EF_NODRAW;
|
||||
SetAbsOrigin( pev->origin );
|
||||
|
||||
UTIL_SetSize( pev, Vector( -30, -30, -30 ), Vector( 30, 30, 30 ) );
|
||||
|
||||
SetNextThink( gpGlobals->time + 0.5 );
|
||||
pev->nextthink = gpGlobals->time + 0.5;
|
||||
}
|
||||
|
||||
void CRopeSegment::Touch( CBaseEntity* pOther )
|
||||
@ -1267,9 +1271,9 @@ void CRopeSegment::Touch( CBaseEntity* pOther )
|
||||
{
|
||||
if( mCanBeGrabbed )
|
||||
{
|
||||
RopeSampleData *data = m_Sample->GetData();
|
||||
RopeSampleData& data = m_Sample->GetData();
|
||||
|
||||
pOther->pev->origin = data->mPosition;
|
||||
pOther->pev->origin = data.mPosition;
|
||||
|
||||
pPlayer->SetOnRopeState( true );
|
||||
pPlayer->SetRope( GetMasterRope() );
|
||||
@ -1280,9 +1284,9 @@ void CRopeSegment::Touch( CBaseEntity* pOther )
|
||||
if( vecVelocity.Length() > 0.5 )
|
||||
{
|
||||
//Apply some external force to move the rope. - Solokiller
|
||||
data->mApplyExternalForce = true;
|
||||
data.mApplyExternalForce = true;
|
||||
|
||||
data->mExternalForce = data->mExternalForce + vecVelocity * 750;
|
||||
data.mExternalForce = data.mExternalForce + vecVelocity * 750;
|
||||
}
|
||||
|
||||
if( GetMasterRope()->IsSoundAllowed() )
|
||||
@ -1326,7 +1330,7 @@ CRopeSegment* CRopeSegment::CreateSegment( CRopeSample* pSample, string_t iszMod
|
||||
|
||||
pSegment->mCauseDamage = false;
|
||||
pSegment->mCanBeGrabbed = true;
|
||||
pSegment->mDefaultMass = pSample->GetData()->mMassReciprocal;
|
||||
pSegment->mDefaultMass = pSample->GetData().mMassReciprocal;
|
||||
pSegment->SetMasterRope(rope);
|
||||
|
||||
return pSegment;
|
||||
@ -1334,9 +1338,9 @@ CRopeSegment* CRopeSegment::CreateSegment( CRopeSample* pSample, string_t iszMod
|
||||
|
||||
void CRopeSegment::ApplyExternalForce( const Vector& vecForce )
|
||||
{
|
||||
m_Sample->GetData()->mApplyExternalForce = true;
|
||||
m_Sample->GetData().mApplyExternalForce = true;
|
||||
|
||||
m_Sample->GetData()->mExternalForce = m_Sample->GetData()->mExternalForce + vecForce;
|
||||
m_Sample->GetData().mExternalForce = m_Sample->GetData().mExternalForce + vecForce;
|
||||
}
|
||||
|
||||
void CRopeSegment::SetCauseDamageOnTouch( const bool bCauseDamage )
|
||||
|
@ -280,7 +280,7 @@ void CSporelauncher::Reload(void)
|
||||
m_fInSpecialReload = 2;
|
||||
|
||||
// Play reload sound.
|
||||
EMIT_SOUND_DYN(ENT(m_pPlayer->pev), CHAN_ITEM, "weapons/splauncher_reload.wav", 1, ATTN_NORM, 0, 100);
|
||||
EMIT_SOUND(m_pPlayer->edict(), CHAN_ITEM, "weapons/splauncher_reload.wav", 0.7f, ATTN_NORM);
|
||||
|
||||
SendWeaponAnim(SPLAUNCHER_RELOAD_LOAD);
|
||||
|
||||
@ -328,12 +328,12 @@ void CSporelauncher::WeaponIdle(void)
|
||||
{
|
||||
int iAnim;
|
||||
float flRand = UTIL_SharedRandomFloat(m_pPlayer->random_seed, 0, 1);
|
||||
if (flRand <= 0.4)
|
||||
if (flRand <= 0.75f)
|
||||
{
|
||||
iAnim = SPLAUNCHER_IDLE;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 2.0f;
|
||||
}
|
||||
else if (flRand <= 0.8)
|
||||
else if (flRand <= 0.95f)
|
||||
{
|
||||
iAnim = SPLAUNCHER_IDLE2;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 4.0f;
|
||||
@ -342,6 +342,7 @@ void CSporelauncher::WeaponIdle(void)
|
||||
{
|
||||
iAnim = SPLAUNCHER_FIDGET;
|
||||
m_flTimeWeaponIdle = UTIL_WeaponTimeBase() + 4.0f;
|
||||
EMIT_SOUND(m_pPlayer->edict(), CHAN_ITEM, "weapons/splauncher_pet.wav", 0.7f, ATTN_NORM);
|
||||
}
|
||||
|
||||
SendWeaponAnim(iAnim);
|
||||
|
@ -37,6 +37,8 @@
|
||||
#include "pm_shared.h"
|
||||
#include "hltv.h"
|
||||
|
||||
#include "ropes.h"
|
||||
|
||||
// #define DUCKFIX
|
||||
|
||||
extern DLL_GLOBAL ULONG g_ulModelIndexPlayer;
|
||||
|
@ -17,7 +17,7 @@
|
||||
#define PLAYER_H
|
||||
|
||||
#include "pm_materials.h"
|
||||
#include "ropes.h"
|
||||
class CRope;
|
||||
|
||||
#define PLAYER_FATAL_FALL_SPEED 1024// approx 60 feet
|
||||
#define PLAYER_MAX_SAFE_FALL_SPEED 580// approx 20 feet
|
||||
|
Loading…
x
Reference in New Issue
Block a user