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

Go to the source code of this file.

Functions

void adaptor_think2use_hittype_splash (entity this)
bool SUB_NoImpactCheck (entity this, entity toucher)
float W_CheckProjectileDamage (entity inflictor, entity projowner, int deathtype, float exception)
void W_DamageOverTime_Think (entity this, float duration, float duration_power, float damage, float edgedamage, float rad, float force, entity cantbe, float think_delay)
 Applies damage over time, called within a think function.
bool W_DualWielding (entity player)
void W_GiveWeapon (entity e, int wep)
void W_LaserPlay (entity this, float rad, float damage, float edgedamage, float burntime, WarpZone_FindRadius_cond_callback_t cb)
 Randomly chooses a player within the radius to shoot a laser towards.
void W_LaserPlay_trace_callback (vector start, vector hit, vector end)
void W_PlayStrengthSound (entity player)
void W_PrepareExplosionByDamage (entity this, entity attacker, void(entity this) explode)
float W_SeekOutEnemy (entity this, float speed_decel, float speed_accel, float speed_max, float turn_rate, bool smart, float smart_mindist, float smart_trace_min, float smart_trace_max)
 Automatically guides a projectile towards its enemy.
bool WarpZone_Projectile_Touch_ImpactFilter_Callback (entity this, entity toucher)

Variables

vector W_LaserPlay_end_org
vector W_LaserPlay_last_hit_org
float wait

Function Documentation

◆ adaptor_think2use_hittype_splash()

void adaptor_think2use_hittype_splash ( entity this)

Definition at line 106 of file common.qc.

107{
108 if (!(IS_ONGROUND(this))) // if onground, we ARE touching something, but HITTYPE_SPLASH is to be networked if the damage causing projectile is not touching ANYTHING
110 adaptor_think2use(this);
111}
const int HITTYPE_SPLASH
automatically set by RadiusDamage
Definition all.qh:32
#define IS_ONGROUND(s)
Definition movetypes.qh:16
int projectiledeathtype
Definition common.qh:33

References entity(), HITTYPE_SPLASH, IS_ONGROUND, and projectiledeathtype.

Referenced by M_Spider_Attack_Web(), W_Arc_Attack_Bolt(), W_Electro_Attack_Orb(), W_Electro_Orb_Follow_Think(), W_Electro_Orb_Stick(), W_Hagar_Attack(), W_Hagar_Attack2(), W_Hagar_Attack2_Load_Release(), W_Hook_Attack2(), W_Mortar_Attack2(), W_RocketMinsta_Attack(), and W_Seeker_Fire_Flac().

◆ SUB_NoImpactCheck()

bool SUB_NoImpactCheck ( entity this,
entity toucher )

Definition at line 113 of file common.qc.

114{
115 // zero hitcontents = this is not the real impact, but either the
116 // mirror-impact of something hitting the projectile instead of the
117 // projectile hitting the something, or a touchareagrid one. Neither of
118 // these stop the projectile from moving, so...
119 // NOTE: this notice is disabled to prevent spam as projectiles can hit content-less objects (other projectiles!)
120#if 0
121 if (trace_dphitcontents == 0)
122 {
123 LOG_TRACEF("A hit from a projectile happened with no hit contents! DEBUG THIS, this should never happen for projectiles! Projectile will self-destruct. (edict: %i, classname: %s, origin: %v)", this, this.classname, this.origin);
124 checkclient(this); // TODO: .health is checked in the engine with this, possibly replace with a QC function?
125 }
126#endif
128 return true;
129
130 if (toucher == NULL && this.size != '0 0 0')
131 {
132 vector tic = this.velocity * sys_frametime;
133 tic += normalize(tic) * vlen(this.maxs - this.mins);
134 traceline(this.origin - tic, this.origin + tic, MOVE_NORMAL, this);
135 if (trace_fraction >= 1)
136 {
137 // NOTE: this notice can occur when projectiles hit non-world objects, better to not spam the console!
138 //LOG_TRACE("Odd... did not hit...?");
139 }
141 {
142 LOG_TRACE("Detected and prevented the sky-grapple bug.");
143 return true;
144 }
145 }
146
147 return false;
148}
string classname
float trace_dphitcontents
const float MOVE_NORMAL
vector mins
vector velocity
vector maxs
vector size
float trace_dphitq3surfaceflags
vector origin
float trace_fraction
float Q3SURFACEFLAG_NOIMPACT
#define LOG_TRACEF(...)
Definition log.qh:75
#define LOG_TRACE(...)
Definition log.qh:74
float vlen(vector v)
vector normalize(vector v)
#define NULL
Definition post.qh:14
#define checkclient
Definition pre.qh:4
vector
Definition self.qh:96
entity entity toucher
Definition self.qh:76
float sys_frametime
Definition common.qh:57

References checkclient, classname, entity(), LOG_TRACE, LOG_TRACEF, maxs, mins, MOVE_NORMAL, normalize(), NULL, origin, Q3SURFACEFLAG_NOIMPACT, size, sys_frametime, toucher, trace_dphitcontents, trace_dphitq3surfaceflags, trace_fraction, vector, velocity, and vlen().

Referenced by WarpZone_Projectile_Touch_ImpactFilter_Callback().

◆ W_CheckProjectileDamage()

float W_CheckProjectileDamage ( entity inflictor,
entity projowner,
int deathtype,
float exception )

Definition at line 45 of file common.qc.

46{
47 bool is_from_contents = (deathtype == DEATH_SLIME.m_id || deathtype == DEATH_LAVA.m_id);
48 bool is_from_owner = (inflictor == projowner);
49 bool is_from_exception = (exception != -1);
50
51 //dprint(strcat("W_CheckProjectileDamage: from_contents ", ftos(is_from_contents), " : from_owner ", ftos(is_from_owner), " : exception ", strcat(ftos(is_from_exception), " (", ftos(exception), "). \n")));
52
54 {
55 return false; // no damage to projectiles at all, not even with the exceptions
56 }
57 else if (autocvar_g_projectiles_damage == -1)
58 {
59 if (is_from_exception)
60 return exception; // if exception is detected, allow it to override
61 else
62 return false; // otherwise, no other damage is allowed
63 }
65 {
66 if (is_from_exception)
67 return exception; // if exception is detected, allow it to override
68 else if (!is_from_contents)
69 return false; // otherwise, only allow damage from contents
70 }
72 {
73 if (is_from_exception)
74 return exception; // if exception is detected, allow it to override
75 else if (!(is_from_contents || is_from_owner))
76 return false; // otherwise, only allow self damage and damage from contents
77 }
78 else if (autocvar_g_projectiles_damage == 2) // allow any damage, but override for exceptions
79 {
80 if (is_from_exception)
81 return exception; // if exception is detected, allow it to override
82 }
83
84 return true; // if none of these return, then allow damage anyway.
85}
int autocvar_g_projectiles_damage
Definition common.qh:5

References autocvar_g_projectiles_damage, and entity().

Referenced by GrapplingHook_Damage(), M_Golem_Attack_Lightning_Damage(), W_Arc_Bolt_Damage(), W_Devastator_Damage(), W_Electro_Orb_Damage(), W_Fireball_Damage(), W_Hagar_Damage(), W_Hook_Damage(), W_MineLayer_Damage(), W_Mortar_Grenade_Damage(), W_OverkillRocketPropelledChainsaw_Damage(), and W_Seeker_Missile_Damage().

◆ W_DamageOverTime_Think()

void W_DamageOverTime_Think ( entity this,
float duration,
float duration_power,
float damage,
float edgedamage,
float rad,
float force,
entity cantbe,
float think_delay )

Applies damage over time, called within a think function.

Definition at line 285 of file common.qc.

289{
290 float dt = time - this.teleport_time;
291 float dmg_remaining_next = bound(0, 1 - dt / duration, 1) ** duration_power;
292
293 float f = this.dmg_last - dmg_remaining_next;
294 this.dmg_last = dmg_remaining_next;
295
296 RadiusDamage(this, this.realowner,
297 f * damage,
298 f * edgedamage,
299 rad,
300 cantbe,
301 NULL,
302 f * force,
304 this.weaponentity_fld,
305 NULL
306 );
307 this.projectiledeathtype |= HITTYPE_SPAM; // ensure it doesn't spam its effect
308
309 if (dt < duration)
310 this.nextthink = time + think_delay;
311 else
312 delete(this);
313}
float teleport_time
Definition player.qh:218
float time
float nextthink
float RadiusDamage(entity inflictor, entity attacker, float coredamage, float edgedamage, float rad, entity cantbe, entity mustbe, float forceintensity, int deathtype,.entity weaponentity, entity directhitentity)
Definition damage.qc:937
const int HITTYPE_SPAM
set manually after first RadiusDamage, stops effect spam
Definition all.qh:36
float bound(float min, float value, float max)
float dmg_last
Definition common.qh:27
entity realowner
entity weaponentity_fld

References bound(), dmg_last, entity(), HITTYPE_SPAM, nextthink, NULL, projectiledeathtype, RadiusDamage(), realowner, teleport_time, time, and weaponentity_fld.

Referenced by W_Electro_ExplodeComboThink(), and W_Hook_ExplodeThink().

◆ W_DualWielding()

bool W_DualWielding ( entity player)

Definition at line 20 of file common.qc.

21{
22 int held_weapons = 0;
23 for (int slot = 0; slot < MAX_WEAPONSLOTS; ++slot)
24 {
25 .entity weaponentity = weaponentities[slot];
26 if (player.(weaponentity) && player.(weaponentity).m_switchweapon != WEP_Null)
27 ++held_weapons;
28 }
29
30 return held_weapons > 1;
31}
const int MAX_WEAPONSLOTS
Definition weapon.qh:16
entity weaponentities[MAX_WEAPONSLOTS]
Definition weapon.qh:17

References entity(), MAX_WEAPONSLOTS, and weaponentities.

Referenced by IMPULSE(), PlayerThink(), W_Devastator_Think(), W_ResetGunAlign(), W_SetupShot_Dir_ProjectileSize_Range(), and weapon_prepareattack_do().

◆ W_GiveWeapon()

void W_GiveWeapon ( entity e,
int wep )

Definition at line 33 of file common.qc.

34{
35 if (!wep)
36 return;
37 STAT(WEAPONS, e) |= WepSet_FromWeapon(REGISTRY_GET(Weapons, wep));
38}
Weapons
Definition guide.qh:113
#define STAT(...)
Definition stats.qh:94
#define REGISTRY_GET(id, i)
Definition registry.qh:62
#define WepSet_FromWeapon(it)
Definition all.qh:48

References entity(), REGISTRY_GET, STAT, Weapons, and WepSet_FromWeapon.

Referenced by Item_GiveTo(), and TEST().

◆ W_LaserPlay()

void W_LaserPlay ( entity this,
float rad,
float damage,
float edgedamage,
float burntime,
WarpZone_FindRadius_cond_callback_t cb )

Randomly chooses a player within the radius to shoot a laser towards.

Definition at line 191 of file common.qc.

192{
193 if (damage <= 0 && edgedamage <= 0)
194 return;
195
197 entity last = NULL;
198 float rad2 = rad * rad;
200 for (entity e = WarpZone_SearchInRadius(this.origin, rad, MOVE_NOMONSTERS, cb); e; e = e.chain)
201 {
202 // adjust the hit location to be a random position inside the entity's bbox
203 vector p = e.origin + e.mins;
204 p.x += random() * (e.maxs.x - e.mins.x);
205 p.y += random() * (e.maxs.y - e.mins.y);
206 p.z += random() * (e.maxs.z - e.mins.z);
207 float dist2 = vlen2(this.origin - WarpZone_UnTransformOrigin(e, p));
208 if (dist2 <= rad2) // there's a chance this is false, so we optimize by only calling sqrt if true
209 {
210 e.dest = p;
211 e.dmg_radius = sqrt(dist2);
212 last = e;
213 RandomSelection_AddEnt(e, 1 / (1 + e.dmg_radius), !StatusEffects_active(STATUSEFFECT_Burning, e));
214 }
215 }
217 {
218 float dist = damage + (edgedamage - damage) * (RandomSelection_chosen_ent.dmg_radius / rad);
220
221 // WarpZone_TraceLine_ThroughZone with callback to draw the line-effect through zones on the way to the end,
222 // but then for the final segment draw towards .dest instead of the trace's end (.WarpZone_findradius_nearest).
223 // This is probably the best we can do
225 if (RandomSelection_chosen_ent.warpzone_transform != '0 0 0' || RandomSelection_chosen_ent.warpzone_shift != '0 0 0')
226 {
227 W_LaserPlay_end_org = RandomSelection_chosen_ent.WarpZone_findradius_nearest;
230 }
232 //trailparticles(this, particleeffectnum(EFFECT_FIREBALL_LASER), this.origin, RandomSelection_chosen_ent.dest);
233 }
234}
var entity(vector mins, vector maxs,.entity tofield) findbox_tofield_OrFallback
const float MOVE_NOMONSTERS
float Fire_AddDamage(entity e, entity o, float d, float t, float dt)
Definition damage.qc:968
const int HITTYPE_BOUNCE
set manually after projectile has bounced
Definition all.qh:33
void Send_Effect(entity eff, vector eff_loc, vector eff_vel, int eff_cnt)
Definition all.qc:155
entity WarpZone_SearchInRadius(vector org, float rad, float nomonsters, WarpZone_FindRadius_cond_callback_t cb)
Modified findradius aware of warpzones, that only includes entities that meet the "cb" criteria.
Definition common.qc:680
vector WarpZone_UnTransformOrigin(entity wz, vector org)
Transforms origin org backwards through warpzone wz, as the inverse of WarpZone_TransformOrigin.
Definition common.qc:526
noref entity WarpZone_SearchInRadius_otherent
Free to use in the callback.
Definition common.qh:71
#define WarpZone_TraceLine_ThroughZone(org, end, nomonsters, forent, zone, cb)
Definition common.qh:47
#define MOVE_NOTHING
Definition common.qh:35
float random(void)
float sqrt(float f)
ERASEABLE void RandomSelection_Init()
Definition random.qc:4
#define RandomSelection_AddEnt(e, weight, priority)
Definition random.qh:14
entity RandomSelection_chosen_ent
Definition random.qh:5
void W_LaserPlay_trace_callback(vector start, vector hit, vector end)
Definition common.qc:182
vector W_LaserPlay_end_org
Definition common.qc:181
vector W_LaserPlay_last_hit_org
Definition common.qc:180
bool StatusEffects_active(StatusEffect this, entity actor)
#define vlen2(v)
Definition vector.qh:4

References entity(), Fire_AddDamage(), HITTYPE_BOUNCE, MOVE_NOMONSTERS, MOVE_NOTHING, NULL, origin, projectiledeathtype, random(), RandomSelection_AddEnt, RandomSelection_chosen_ent, RandomSelection_Init(), realowner, Send_Effect(), sqrt(), StatusEffects_active(), vector, vlen2, W_LaserPlay_end_org, W_LaserPlay_last_hit_org, W_LaserPlay_trace_callback(), WarpZone_SearchInRadius(), WarpZone_SearchInRadius_otherent, WarpZone_TraceLine_ThroughZone, and WarpZone_UnTransformOrigin().

Referenced by napalm_ball_think(), napalm_fountain_think(), W_Fireball_Firemine_Think(), and W_Fireball_Think().

◆ W_LaserPlay_trace_callback()

void W_LaserPlay_trace_callback ( vector start,
vector hit,
vector end )

Definition at line 182 of file common.qc.

183{
184 if (end == W_LaserPlay_end_org) // must be the final trace segment
185 return;
187 Send_Effect(EFFECT_FIREBALL_LASER, start, hit - start, 1);
188 //trailparticles(this, particleeffectnum(EFFECT_FIREBALL_LASER), start, hit);
189}

References Send_Effect(), vector, W_LaserPlay_end_org, and W_LaserPlay_last_hit_org.

Referenced by W_LaserPlay().

◆ W_PlayStrengthSound()

void W_PlayStrengthSound ( entity player)

Definition at line 40 of file common.qc.

41{
43}
#define MUTATOR_CALLHOOK(id,...)
Definition base.qh:143
void W_PlayStrengthSound(entity player)
Definition common.qc:40

References entity(), MUTATOR_CALLHOOK, and W_PlayStrengthSound().

Referenced by MUTATOR_HOOKABLE(), MUTATOR_HOOKFUNCTION(), W_PlayStrengthSound(), W_SetupShot_Dir_ProjectileSize_Range(), and W_Shotgun_Melee_Think().

◆ W_PrepareExplosionByDamage()

void W_PrepareExplosionByDamage ( entity this,
entity attacker,
void(entity this) explode )

Definition at line 87 of file common.qc.

88{
89 this.takedamage = DAMAGE_NO;
90 this.event_damage = func_null;
91
92 MUTATOR_CALLHOOK(PrepareExplosionByDamage, this, attacker);
93
95 {
96 this.owner = attacker;
97 this.realowner = attacker;
98 }
99
100 // do not explode NOW but in the NEXT FRAME!
101 // because recursive calls to RadiusDamage are not allowed
102 this.nextthink = time;
103 setthink(this, explode);
104}
entity owner
Definition main.qh:87
#define IS_CLIENT(s)
Definition player.qh:241
var void func_null()
#define setthink(e, f)
bool autocvar_g_projectiles_keep_owner
Definition common.qh:7
const int DAMAGE_NO
Definition subs.qh:79
float takedamage
Definition subs.qh:78

References autocvar_g_projectiles_keep_owner, DAMAGE_NO, entity(), func_null(), IS_CLIENT, MUTATOR_CALLHOOK, nextthink, owner, realowner, setthink, takedamage, and time.

Referenced by M_Golem_Attack_Lightning_Damage(), nade_damage(), nade_translocate_DestroyDamage(), turret_projectile_damage(), W_Arc_Bolt_Damage(), W_Devastator_Damage(), W_Fireball_Damage(), W_Hagar_Damage(), W_Hook_Damage(), W_MineLayer_Damage(), W_Mortar_Grenade_Damage(), W_OverkillRocketPropelledChainsaw_Damage(), W_Seeker_Missile_Damage(), and walker_rocket_damage().

◆ W_SeekOutEnemy()

float W_SeekOutEnemy ( entity this,
float speed_decel,
float speed_accel,
float speed_max,
float turn_rate,
bool smart,
float smart_mindist,
float smart_trace_min,
float smart_trace_max )

Automatically guides a projectile towards its enemy.

RefSys must be setup

Definition at line 239 of file common.qc.

242{
243 if (this.enemy != NULL
244 && this.enemy.takedamage != DAMAGE_AIM || IS_DEAD(this.enemy))
245 this.enemy = NULL;
246 if (!this.enemy)
247 return 0;
248
249 float spd = vlen(this.velocity);
250 spd = bound(
251 spd - speed_decel * frametime,
252 speed_max,
253 spd + speed_accel * frametime);
254
255 vector eorg = WarpZone_RefSys_TransformOrigin(this.enemy, this, 0.5 * (this.enemy.absmin + this.enemy.absmax));
256 float dist = vlen(eorg - this.origin);
257 vector desireddir = (eorg - this.origin) * 1 / dist;
258 vector olddir = this.velocity * 1 / spd; // get my current direction
259
260 // Do evasive maneuvers for world objects? ( this should be a cpu hog. :P )
261 if (smart && dist > smart_mindist)
262 {
263 // Is it a better idea (shorter distance) to trace to the target itself?
264 if (vdist(this.origin + olddir * this.wait, <, dist))
265 WarpZone_TraceLine(this.origin, this.origin + olddir * this.wait, false, this);
266 else
267 WarpZone_TraceLine(this.origin, eorg, false, this);
268
269 // Setup adaptive tracelength
270 this.wait = bound(
271 smart_trace_min,
273 smart_trace_max);
274
275 // Calc how important it is that we turn and add this to the desired (enemy) dir
276 desireddir = normalize((trace_plane_normal * (1 - trace_fraction)) + (desireddir * trace_fraction));
277 }
278
279 vector newdir = normalize(olddir + desireddir * turn_rate); // take the average of the 2 directions; not the best method but simple & easy
280 this.velocity = newdir * spd; // make me fly in the new direction at my flight speed
281 return dist;
282}
float wait
Definition items.qc:17
#define IS_DEAD(s)
Definition player.qh:244
float frametime
vector trace_endpos
vector trace_plane_normal
vector WarpZone_RefSys_TransformOrigin(entity from, entity to, vector org)
Transform origin org in from's reference into to's reference.
Definition common.qc:787
#define WarpZone_TraceLine(org, end, nomonsters, forent)
Definition common.qh:51
entity WarpZone_trace_transform
Transform accumulator during a trace.
Definition common.qh:40
const int DAMAGE_AIM
Definition subs.qh:81
entity enemy
Definition sv_ctf.qh:152
#define vdist(v, cmp, f)
Vector distance comparison, avoids sqrt().
Definition vector.qh:8

References bound(), DAMAGE_AIM, enemy, entity(), frametime, IS_DEAD, normalize(), NULL, origin, trace_endpos, trace_fraction, trace_plane_normal, vdist, vector, velocity, vlen(), wait, WarpZone_RefSys_TransformOrigin(), WarpZone_trace_transform, WarpZone_TraceLine, and WarpZone_UnTransformOrigin().

Referenced by M_Mage_Attack_Spike_Think(), and W_Seeker_Missile_Think().

◆ WarpZone_Projectile_Touch_ImpactFilter_Callback()

bool WarpZone_Projectile_Touch_ImpactFilter_Callback ( entity this,
entity toucher )

Definition at line 150 of file common.qc.

151{
152 if (toucher && toucher == this.owner)
153 return true;
154
155 if (autocvar_g_projectiles_interact == 1 && toucher.classname == "blasterbolt")
156 {
158 // We'll bounce off it due to limitations so let it deflect us
159 // to hide the problem, see PROJECTILE_MAKETRIGGER.
160 gettouch(toucher)(toucher, this);
161 return true;
162 }
163
164 if (SUB_NoImpactCheck(this, toucher))
165 {
166 if (this.classname == "nade")
167 return false; // no checks here
168 else if (this.classname == "grapplinghook")
169 RemoveHook(this);
170 else
171 delete(this);
172 return true;
173 }
174 if (trace_ent && trace_ent.solid > SOLID_TRIGGER)
176 return false;
177}
float movetype
entity trace_ent
const float SOLID_TRIGGER
void UpdateCSQCProjectile(entity e)
const int MOVETYPE_BOUNCEMISSILE
Definition movetypes.qh:144
const int MOVETYPE_BOUNCE
Definition movetypes.qh:143
#define gettouch(e)
Definition self.qh:78
void RemoveHook(entity this)
Definition hook.qc:48
bool SUB_NoImpactCheck(entity this, entity toucher)
Definition common.qc:113
int autocvar_g_projectiles_interact
Definition common.qh:6

References autocvar_g_projectiles_interact, classname, entity(), gettouch, movetype, MOVETYPE_BOUNCE, MOVETYPE_BOUNCEMISSILE, owner, RemoveHook(), SOLID_TRIGGER, SUB_NoImpactCheck(), toucher, trace_ent, and UpdateCSQCProjectile().

Referenced by WarpZone_Projectile_Touch().

Variable Documentation

◆ W_LaserPlay_end_org

vector W_LaserPlay_end_org

Definition at line 181 of file common.qc.

Referenced by W_LaserPlay(), and W_LaserPlay_trace_callback().

◆ W_LaserPlay_last_hit_org

vector W_LaserPlay_last_hit_org

Definition at line 180 of file common.qc.

Referenced by W_LaserPlay(), and W_LaserPlay_trace_callback().

◆ wait

float wait

Definition at line 236 of file common.qc.