Xonotic QuakeC
The free, fast arena FPS with crisp movement and a wide array of weapons
sv_weapon.qc File Reference
#include "sv_weapon.qh"
Include dependency graph for sv_weapon.qc:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Functions

vector trigger_push_calculatevelocity (vector org, entity tgt, float ht, entity pushed_entity)
void W_Nexball_Attack (Weapon thiswep, entity actor,.entity weaponentity, float t)
void W_Nexball_Attack2 (Weapon thiswep, entity actor,.entity weaponentity)
void W_Nexball_Think (entity this)
void W_Nexball_Touch (entity this, entity toucher)

Function Documentation

◆ trigger_push_calculatevelocity()

vector trigger_push_calculatevelocity ( vector org,
entity tgt,
float ht,
entity pushed_entity )

Definition at line 32 of file jumppads.qc.

33{
34 float grav, sdist, zdist, vs, vz, jumpheight;
35 vector sdir, torg;
36
37 torg = tgt.origin + (tgt.mins + tgt.maxs) * 0.5;
38
39 grav = PHYS_GRAVITY(NULL);
40 if(pushed_entity && pushed_entity.gravity)
41 grav *= pushed_entity.gravity;
42
43 // Q3 has frametime-dependent gravity, but its trigger_push velocity calculation doesn't account for that.
44 // This discrepancy can be simulated accurately which ensures that all entities will arrive
45 // where they would in Q3 with gravity 800 at 125fps, even if entity-specific gravity is applied.
46 // This can be hard-coded because we don't support the Q3 world.gravity field at this time.
47 // See physicsCPMA.cfg for maths and test results.
49 grav /= 750/800; // exact float, unlike 800/750
50
51 zdist = torg.z - org.z;
52 sdist = vlen(torg - org - zdist * '0 0 1');
53 sdir = normalize(torg - org - zdist * '0 0 1');
54
55 // how high do we need to push the player?
56 jumpheight = fabs(ht);
57 if(zdist > 0)
58 jumpheight = jumpheight + zdist;
59
60 /*
61 STOP.
62
63 You will not understand the following equations anyway...
64 But here is what I did to get them.
65
66 I used the functions
67
68 s(t) = t * vs
69 z(t) = t * vz - 1/2 grav t^2
70
71 and solved for:
72
73 s(ti) = sdist
74 z(ti) = zdist
75 max(z, ti) = jumpheight
76
77 From these three equations, you will find the three parameters vs, vz
78 and ti.
79 */
80
81 // push them so high...
82 vz = sqrt(fabs(2 * grav * jumpheight)); // NOTE: sqrt(positive)!
83
84 // we start with downwards velocity only if it's a downjump and the jump apex should be outside the jump!
85 if(ht < 0)
86 if(zdist < 0)
87 vz = -vz;
88
89 vector solution;
90 solution = solve_quadratic(0.5 * grav, -vz, zdist); // equation "z(ti) = zdist"
91 // ALWAYS solvable because jumpheight >= zdist
92 if(!solution.z)
93 solution_y = solution.x; // just in case it is not solvable due to roundoff errors, assume two equal solutions at their center (this is mainly for the usual case with ht == 0)
94 if(zdist == 0)
95 solution_x = solution.y; // solution_x is 0 in this case, so don't use it, but rather use solution_y (which will be sqrt(0.5 * jumpheight / grav), actually)
96
97 float flighttime;
98 if(zdist < 0)
99 {
100 // down-jump
101 if(ht < 0)
102 {
103 // almost straight line type
104 // jump apex is before the jump
105 // we must take the larger one
106 flighttime = solution.y;
107 }
108 else
109 {
110 // regular jump
111 // jump apex is during the jump
112 // we must take the larger one too
113 flighttime = solution.y;
114 }
115 }
116 else
117 {
118 // up-jump
119 if(ht < 0)
120 {
121 // almost straight line type
122 // jump apex is after the jump
123 // we must take the smaller one
124 flighttime = solution.x;
125 }
126 else
127 {
128 // regular jump
129 // jump apex is during the jump
130 // we must take the larger one
131 flighttime = solution.y;
132 }
133 }
134 vs = sdist / flighttime;
135
136 // finally calculate the velocity
137 return sdir * vs + '0 0 1' * vz;
138}
#define Q3COMPAT_COMMON
Definition stats.qh:368
ERASEABLE vector solve_quadratic(float a, float b, float c)
ax^2 + bx + c = 0
Definition math.qh:304
float vlen(vector v)
float sqrt(float f)
vector normalize(vector v)
float fabs(float f)
#define PHYS_GRAVITY(s)
Definition movetypes.qh:53
#define NULL
Definition post.qh:14
vector
Definition self.qh:92
vector org
Definition self.qh:92

References entity(), fabs(), normalize(), NULL, org, PHYS_GRAVITY, Q3COMPAT_COMMON, solve_quadratic(), sqrt(), trigger_push_calculatevelocity(), vector, and vlen().

Referenced by trigger_push_calculatevelocity(), W_Nexball_Attack2(), and W_Porto_Fail().

◆ W_Nexball_Attack()

void W_Nexball_Attack ( Weapon thiswep,
entity actor,
.entity weaponentity,
float t )

Definition at line 109 of file sv_weapon.qc.

110{
111 entity ball;
112 float mul, mi, ma;
113 if(!(ball = actor.ballcarried))
114 return;
115
116 W_SetupShot(actor, weaponentity, false, 4, SND_NB_SHOOT1, CH_WEAPON_A, 0, WEP_PORTO.m_id); // TODO: use ballstealer weapon here? we don't want duplicates in the scoreboard
119 {
120 if(STAT(NB_METERSTART, actor))
121 STAT(NB_METERSTART, actor) = 0; // Shot failed, hide the power meter
122 return;
123 }
124
125 //Calculate multiplier
126 if(t < 0)
127 mul = 1;
128 else
129 {
131 ma = max(mi, autocvar_g_nexball_basketball_meter_maxpower); // avoid confusion
132 //One triangle wave period with 1 as max
134 if(mul > 1)
135 mul = 2 - mul;
136 mul = mi + (ma - mi) * mul; // range from the minimal power to the maximal power
137 }
138
140
141
142 //TODO: use the speed_up cvar too ??
143}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
float trace_startsolid
float MOVE_WORLDONLY
#define STAT(...)
Definition stats.qh:82
float max(float f,...)
const int CH_WEAPON_A
Definition sound.qh:7
float autocvar_g_nexball_basketball_meter_minpower
Definition sv_nexball.qc:22
float autocvar_g_nexball_basketball_meter_maxpower
Definition sv_nexball.qc:21
float autocvar_g_balance_nexball_primary_speed
Definition sv_nexball.qc:43
void DropBall(entity ball, vector org, vector vel)
const vector BALL_MAXS
Definition sv_nexball.qh:26
float g_nexball_meter_period
Definition sv_nexball.qh:54
const vector BALL_MINS
Definition sv_nexball.qh:25
vector W_CalculateProjectileVelocity(entity actor, vector pvelocity, vector mvelocity, float forceAbsolute)
Definition tracing.qc:176
vector w_shotdir
Definition tracing.qh:20
vector w_shotorg
Definition tracing.qh:19
#define W_SetupShot(ent, wepent, antilag, recoil, snd, chan, maxdamage, deathtype)
Definition tracing.qh:34

References autocvar_g_balance_nexball_primary_speed, autocvar_g_nexball_basketball_meter_maxpower, autocvar_g_nexball_basketball_meter_minpower, BALL_MAXS, BALL_MINS, CH_WEAPON_A, DropBall(), entity(), g_nexball_meter_period, max(), MOVE_WORLDONLY, NULL, STAT, trace_startsolid, W_CalculateProjectileVelocity(), W_SetupShot, w_shotdir, and w_shotorg.

◆ W_Nexball_Attack2()

void W_Nexball_Attack2 ( Weapon thiswep,
entity actor,
.entity weaponentity )

Definition at line 145 of file sv_weapon.qc.

146{
147 if(actor.ballcarried.enemy)
148 {
149 entity _ball = actor.ballcarried;
150 W_SetupShot(actor, weaponentity, false, 4, SND_NB_SHOOT1, CH_WEAPON_A, 0, WEP_PORTO.m_id | HITTYPE_SECONDARY); // TODO: use the ball stealer weapon here? probably don't want duplicates
151 DropBall(_ball, w_shotorg, trigger_push_calculatevelocity(_ball.origin, _ball.enemy, 32, _ball));
153 _ball.nextthink = time;
154 return;
155 }
156
158 return;
159
160 W_SetupShot(actor, weaponentity, false, 2, SND_NB_SHOOT2, CH_WEAPON_A, 0, WEP_PORTO.m_id);
161 entity missile = new(ballstealer);
162
163 missile.owner = actor;
164
165 set_movetype(missile, MOVETYPE_FLY);
166 PROJECTILE_MAKETRIGGER(missile);
167
168 //setmodel(missile, "models/elaser.mdl"); // precision set below
169 setsize(missile, '0 0 0', '0 0 0');
170 setorigin(missile, w_shotorg);
171
173 missile.angles = vectoangles(missile.velocity);
174 settouch(missile, W_Nexball_Touch);
175 setthink(missile, SUB_Remove);
176 missile.nextthink = time + autocvar_g_balance_nexball_secondary_lifetime; //FIXME: use a distance instead?
177
178 missile.effects = EF_BRIGHTFIELD | EF_LOWPRECISION;
179 missile.flags = FL_PROJECTILE;
180 IL_PUSH(g_projectiles, missile);
181 IL_PUSH(g_bot_dodge, missile);
182
183 CSQCProjectile(missile, true, PROJECTILE_ELECTRO, true);
184}
IntrusiveList g_bot_dodge
Definition api.qh:150
const int FL_PROJECTILE
Definition constants.qh:85
float time
const int EF_BRIGHTFIELD
void CSQCProjectile(entity e, float clientanimate, int type, float docull)
const int HITTYPE_SECONDARY
Definition all.qh:29
void SUB_Remove(entity this)
Remove entity.
Definition defer.qh:13
float EF_LOWPRECISION
ERASEABLE entity IL_PUSH(IntrusiveList this, entity it)
Push to tail.
vector vectoangles(vector v)
void set_movetype(entity this, int mt)
Definition movetypes.qc:4
const int MOVETYPE_FLY
Definition movetypes.qh:134
const int PROJECTILE_ELECTRO
Definition projectiles.qh:3
#define setthink(e, f)
#define settouch(e, f)
Definition self.qh:73
IntrusiveList g_projectiles
Definition common.qh:58
#define PROJECTILE_MAKETRIGGER(e)
Definition common.qh:34
float autocvar_g_balance_nexball_secondary_lifetime
Definition sv_nexball.qc:46
float autocvar_g_balance_nexball_secondary_speed
Definition sv_nexball.qc:48
float autocvar_g_nexball_tackling
Definition sv_nexball.qc:38
void W_Nexball_Think(entity this)
Definition sv_weapon.qc:62
vector trigger_push_calculatevelocity(vector org, entity tgt, float ht, entity pushed_entity)
Definition jumppads.qc:32
void W_Nexball_Touch(entity this, entity toucher)
Definition sv_weapon.qc:77
#define W_SetupProjVelocity_Basic(ent, pspeed, pspread)
Definition tracing.qh:49

References autocvar_g_balance_nexball_secondary_lifetime, autocvar_g_balance_nexball_secondary_speed, autocvar_g_nexball_tackling, CH_WEAPON_A, CSQCProjectile(), DropBall(), EF_BRIGHTFIELD, EF_LOWPRECISION, entity(), FL_PROJECTILE, g_bot_dodge, g_projectiles, HITTYPE_SECONDARY, IL_PUSH(), MOVETYPE_FLY, PROJECTILE_ELECTRO, PROJECTILE_MAKETRIGGER, set_movetype(), setthink, settouch, SUB_Remove(), time, trigger_push_calculatevelocity(), vectoangles(), W_Nexball_Think(), W_Nexball_Touch(), W_SetupProjVelocity_Basic, W_SetupShot, and w_shotorg.

◆ W_Nexball_Think()

void W_Nexball_Think ( entity this)

Definition at line 62 of file sv_weapon.qc.

63{
64 //dprint("W_Nexball_Think\n");
65 //vector new_dir = steerlib_arrive(this.enemy.origin, 2500);
66 vector new_dir = normalize(this.enemy.origin + '0 0 50' - this.origin);
67 vector old_dir = normalize(this.velocity);
68 float _speed = vlen(this.velocity);
69 vector new_vel = normalize(old_dir + (new_dir * autocvar_g_nexball_safepass_turnrate)) * _speed;
70 //vector new_vel = (new_dir * autocvar_g_nexball_safepass_turnrate
71
72 this.velocity = new_vel;
73
74 this.nextthink = time;
75}
vector velocity
float nextthink
entity enemy
Definition sv_ctf.qh:153
float autocvar_g_nexball_safepass_turnrate
Definition sv_nexball.qc:34

References autocvar_g_nexball_safepass_turnrate, enemy, entity(), nextthink, normalize(), time, vector, velocity, and vlen().

Referenced by W_Nexball_Attack2().

◆ W_Nexball_Touch()

void W_Nexball_Touch ( entity this,
entity toucher )

Definition at line 77 of file sv_weapon.qc.

78{
79 entity ball, attacker;
80 attacker = this.owner;
81 //this.think = func_null;
82 //this.enemy = NULL;
83
85 // TODO: mutator hook to prevent picking up objectives
86 if(attacker.team != toucher.team || autocvar_g_nexball_basketball_teamsteal)
87 if((ball = toucher.ballcarried) && !IS_DEAD(toucher) && (IS_PLAYER(attacker)))
88 {
89 toucher.velocity = toucher.velocity + normalize(this.velocity) * toucher.damageforcescale * autocvar_g_balance_nexball_secondary_force;
91 if(!attacker.ballcarried && !IS_DEAD(attacker))
92 {
93 LogNB("stole", attacker);
95
96 if(SAME_TEAM(attacker, toucher) && time > CS(attacker).teamkill_complain)
97 {
98 CS(attacker).teamkill_complain = time + 5;
99 CS(attacker).teamkill_soundtime = time + 0.4;
100 CS(attacker).teamkill_soundsource = toucher;
101 }
102
103 GiveBall(attacker, toucher.ballcarried);
104 }
105 }
106 delete(this);
107}
entity owner
Definition main.qh:87
#define IS_DEAD(s)
Definition player.qh:245
#define IS_PLAYER(s)
Definition player.qh:243
float teamkill_complain
Definition damage.qh:54
#define UNSET_ONGROUND(s)
Definition movetypes.qh:18
entity entity toucher
Definition self.qh:72
#define PROJECTILE_TOUCH(e, t)
Definition common.qh:28
const int CH_TRIGGER
Definition sound.qh:12
const float VOL_BASE
Definition sound.qh:36
#define _sound(e, c, s, v, a)
Definition sound.qh:43
const float ATTEN_NORM
Definition sound.qh:30
ClientState CS(Client this)
Definition state.qh:47
void LogNB(string mode, entity actor)
Definition sv_nexball.qc:77
void GiveBall(entity plyr, entity ball)
float autocvar_g_balance_nexball_secondary_force
Definition sv_nexball.qc:45
float autocvar_g_nexball_basketball_teamsteal
Definition sv_nexball.qh:44
#define SAME_TEAM(a, b)
Definition teams.qh:241

References _sound, ATTEN_NORM, autocvar_g_balance_nexball_secondary_force, autocvar_g_nexball_basketball_teamsteal, CH_TRIGGER, CS(), entity(), GiveBall(), IS_DEAD, IS_PLAYER, LogNB(), normalize(), owner, PROJECTILE_TOUCH, SAME_TEAM, teamkill_complain, time, toucher, UNSET_ONGROUND, velocity, and VOL_BASE.

Referenced by W_Nexball_Attack2().