qboolean G_CheckPounceAttack( gentity_t *self ) { trace_t tr; gentity_t *traceEnt; int damage, timeMax, pounceRange, payload; if ( self->client->pmext.pouncePayload <= 0 ) { return qfalse; } // In case the goon lands on his target, he gets one shot after landing payload = self->client->pmext.pouncePayload; if ( !( self->client->ps.pm_flags & PMF_CHARGE ) ) { self->client->pmext.pouncePayload = 0; } // Calculate muzzle point AngleVectors( self->client->ps.viewangles, forward, right, up ); G_CalcMuzzlePoint( self, forward, right, up, muzzle ); // Trace from muzzle to see what we hit pounceRange = self->client->ps.weapon == WP_ALEVEL3 ? LEVEL3_POUNCE_RANGE : LEVEL3_POUNCE_UPG_RANGE; G_WideTrace( &tr, self, pounceRange, LEVEL3_POUNCE_WIDTH, LEVEL3_POUNCE_WIDTH, &traceEnt ); if ( traceEnt == NULL ) { return qfalse; } // Send blood impact if ( traceEnt->takedamage ) { SendMeleeHitEvent( self, traceEnt, &tr ); } if ( !traceEnt->takedamage ) { return qfalse; } // Deal damage timeMax = self->client->ps.weapon == WP_ALEVEL3 ? LEVEL3_POUNCE_TIME : LEVEL3_POUNCE_TIME_UPG; damage = payload * LEVEL3_POUNCE_DMG / timeMax; self->client->pmext.pouncePayload = 0; G_Damage( traceEnt, self, self, forward, tr.endpos, damage, DAMAGE_NO_LOCDAMAGE, MOD_LEVEL3_POUNCE ); return qtrue; }
void G_ChargeAttack( gentity_t *self, gentity_t *victim ) { int damage; int i; vec3_t forward; if ( !self->client || self->client->ps.stats[ STAT_MISC ] <= 0 || !( self->client->ps.stats[ STAT_STATE ] & SS_CHARGING ) || self->client->ps.weaponTime ) { return; } VectorSubtract( victim->s.origin, self->s.origin, forward ); VectorNormalize( forward ); if ( !victim->takedamage ) { return; } // For buildables, track the last MAX_TRAMPLE_BUILDABLES_TRACKED buildables // hit, and do not do damage if the current buildable is in that list // in order to prevent dancing over stuff to kill it very quickly if ( !victim->client ) { for ( i = 0; i < MAX_TRAMPLE_BUILDABLES_TRACKED; i++ ) { if ( self->client->trampleBuildablesHit[ i ] == victim - g_entities ) { return; } } self->client->trampleBuildablesHit[ self->client->trampleBuildablesHitPos++ % MAX_TRAMPLE_BUILDABLES_TRACKED ] = victim - g_entities; } SendMeleeHitEvent( self, victim, NULL ); damage = LEVEL4_TRAMPLE_DMG * self->client->ps.stats[ STAT_MISC ] / LEVEL4_TRAMPLE_DURATION; G_Damage( victim, self, self, forward, victim->s.origin, damage, DAMAGE_NO_LOCDAMAGE, MOD_LEVEL4_TRAMPLE ); self->client->ps.weaponTime += LEVEL4_TRAMPLE_REPEAT; }
static gentity_t *FireMelee( gentity_t *self, float range, float width, float height, int damage, meansOfDeath_t mod ) { trace_t tr; gentity_t *traceEnt; G_WideTrace( &tr, self, range, width, height, &traceEnt ); if ( traceEnt != NULL && traceEnt->takedamage ) { SendMeleeHitEvent( self, traceEnt, &tr ); G_Damage( traceEnt, self, self, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK, mod ); } return traceEnt; }
qboolean G_CheckVenomAttack( gentity_t *self ) { trace_t tr; gentity_t *traceEnt; int damage = LEVEL0_BITE_DMG; if ( self->client->ps.weaponTime ) { return qfalse; } // Calculate muzzle point AngleVectors( self->client->ps.viewangles, forward, right, up ); G_CalcMuzzlePoint( self, forward, right, up, muzzle ); G_WideTrace( &tr, self, LEVEL0_BITE_RANGE, LEVEL0_BITE_WIDTH, LEVEL0_BITE_WIDTH, &traceEnt ); if ( !traceEnt || !traceEnt->takedamage || traceEnt->health <= 0 || G_OnSameTeam( self, traceEnt ) ) { return qfalse; } // only allow bites to work against turrets or buildables in construction if ( traceEnt->s.eType == ET_BUILDABLE && traceEnt->spawned ) { switch ( traceEnt->s.modelindex ) { case BA_H_MGTURRET: case BA_H_TESLAGEN: break; default: return qfalse; } } SendMeleeHitEvent( self, traceEnt, &tr ); G_Damage( traceEnt, self, self, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK, MOD_LEVEL0_BITE ); self->client->ps.weaponTime += LEVEL0_BITE_REPEAT; return qtrue; }
bool G_CheckPounceAttack( gentity_t *self ) { trace_t tr; gentity_t *traceEnt; int damage, timeMax, pounceRange, payload; if ( self->client->pmext.pouncePayload <= 0 ) { return false; } // In case the goon lands on his target, he gets one shot after landing payload = self->client->pmext.pouncePayload; if ( !( self->client->ps.pm_flags & PMF_CHARGE ) ) { self->client->pmext.pouncePayload = 0; } // Calculate muzzle point AngleVectors( self->client->ps.viewangles, forward, right, up ); G_CalcMuzzlePoint( self, forward, right, up, muzzle ); // Trace from muzzle to see what we hit pounceRange = self->client->ps.weapon == WP_ALEVEL3 ? LEVEL3_POUNCE_RANGE : LEVEL3_POUNCE_UPG_RANGE; G_WideTrace( &tr, self, pounceRange, LEVEL3_POUNCE_WIDTH, LEVEL3_POUNCE_WIDTH, &traceEnt ); if ( !G_Alive( traceEnt ) ) { return false; } timeMax = self->client->ps.weapon == WP_ALEVEL3 ? LEVEL3_POUNCE_TIME : LEVEL3_POUNCE_TIME_UPG; damage = payload * LEVEL3_POUNCE_DMG / timeMax; self->client->pmext.pouncePayload = 0; traceEnt->entity->Damage((float)damage, self, Vec3::Load(tr.endpos), Vec3::Load(forward), DAMAGE_NO_LOCDAMAGE, MOD_LEVEL3_POUNCE); SendMeleeHitEvent( self, traceEnt, &tr ); return true; }
static gentity_t *FireMelee( gentity_t *self, float range, float width, float height, int damage, meansOfDeath_t mod ) { trace_t tr; gentity_t *traceEnt; G_WideTrace( &tr, self, range, width, height, &traceEnt ); if ( !G_Alive( traceEnt ) ) { return nullptr; } traceEnt->entity->Damage((float)damage, self, Vec3::Load(tr.endpos), Vec3::Load(forward), 0, (meansOfDeath_t)mod); SendMeleeHitEvent( self, traceEnt, &tr ); return traceEnt; }
bool G_CheckVenomAttack( gentity_t *self ) { trace_t tr; gentity_t *traceEnt; int damage = LEVEL0_BITE_DMG; if ( self->client->ps.weaponTime ) { return false; } // Calculate muzzle point AngleVectors( self->client->ps.viewangles, forward, right, up ); G_CalcMuzzlePoint( self, forward, right, up, muzzle ); G_WideTrace( &tr, self, LEVEL0_BITE_RANGE, LEVEL0_BITE_WIDTH, LEVEL0_BITE_WIDTH, &traceEnt ); if ( !traceEnt || !traceEnt->takedamage || traceEnt->health <= 0 || G_OnSameTeam( self, traceEnt ) ) { return false; } // only allow bites to work against buildables in construction if ( traceEnt->s.eType == ET_BUILDABLE && traceEnt->spawned ) { return false; } SendMeleeHitEvent( self, traceEnt, &tr ); G_Damage( traceEnt, self, self, forward, tr.endpos, damage, 0, MOD_LEVEL0_BITE ); self->client->ps.weaponTime += LEVEL0_BITE_REPEAT; return true; }
bool G_CheckVenomAttack( gentity_t *self ) { trace_t tr; gentity_t *traceEnt; if ( self->client->ps.weaponTime ) { return false; } // Calculate muzzle point AngleVectors( self->client->ps.viewangles, forward, right, up ); G_CalcMuzzlePoint( self, forward, right, up, muzzle ); G_WideTrace( &tr, self, LEVEL0_BITE_RANGE, LEVEL0_BITE_WIDTH, LEVEL0_BITE_WIDTH, &traceEnt ); if ( !G_Alive( traceEnt ) || G_OnSameTeam( self, traceEnt ) ) { return false; } // only allow bites to work against buildables in construction if ( traceEnt->s.eType == ET_BUILDABLE && traceEnt->spawned ) { return false; } traceEnt->entity->Damage((float)LEVEL0_BITE_DMG, self, Vec3::Load(tr.endpos), Vec3::Load(forward), 0, (meansOfDeath_t)MOD_LEVEL0_BITE); SendMeleeHitEvent( self, traceEnt, &tr ); self->client->ps.weaponTime += LEVEL0_BITE_REPEAT; return true; }