void G_WeightAttack( gentity_t *self, gentity_t *victim ) { float weightDPS; int attackerMass, victimMass, weightDamage; // weigth damage is only dealt between clients if ( !self->client || !victim->client ) { return; } // don't do friendly fire if ( G_OnSameTeam( self, victim ) ) { return; } // ignore invincible targets if ( !victim->takedamage ) { return; } // attacker must be above victim if ( self->client->ps.origin[ 2 ] + self->r.mins[ 2 ] < victim->s.origin[ 2 ] + victim->r.maxs[ 2 ] ) { return; } // victim must be on the ground if ( victim->client->ps.groundEntityNum == ENTITYNUM_NONE ) { return; } // check timer if ( victim->client->nextCrushTime > level.time ) { return; } attackerMass = BG_Class( self->client->pers.classSelection )->mass; victimMass = BG_Class( victim->client->pers.classSelection )->mass; weightDPS = WEIGHTDMG_DMG_MODIFIER * MAX( attackerMass - victimMass, 0 ); if ( weightDPS > WEIGHTDMG_DPS_THRESHOLD ) { weightDamage = ( int )( weightDPS * ( WEIGHTDMG_REPEAT / 1000.0f ) ); if ( weightDamage > 0 ) { G_Damage( victim, self, self, NULL, victim->s.origin, weightDamage, DAMAGE_NO_LOCDAMAGE, ModWeight( self ) ); } } victim->client->nextCrushTime = level.time + WEIGHTDMG_REPEAT; }
void G_ImpactAttack( gentity_t *self, gentity_t *victim ) { float impactVelocity, impactEnergy; vec3_t knockbackDir; int attackerMass, impactDamage; // self must be a client if ( !self->client ) { return; } // ignore invincible targets if ( !victim->takedamage ) { return; } // don't do friendly fire if ( G_OnSameTeam( self, victim ) ) { return; } // attacker must be above victim if ( self->client->ps.origin[ 2 ] + self->r.mins[ 2 ] < victim->s.origin[ 2 ] + victim->r.maxs[ 2 ] ) { return; } // allow the granger airlifting ritual if ( victim->client && victim->client->ps.stats[ STAT_STATE2 ] & SS2_JETPACK_ACTIVE && ( self->client->pers.classSelection == PCL_ALIEN_BUILDER0 || self->client->pers.classSelection == PCL_ALIEN_BUILDER0_UPG ) ) { return; } // calculate impact damage attackerMass = BG_Class( self->client->pers.classSelection )->mass; impactVelocity = fabs( self->client->pmext.fallImpactVelocity[ 2 ] ) * IMPACTDMG_QU_TO_METER; // in m/s impactEnergy = attackerMass * impactVelocity * impactVelocity; // in J impactDamage = ( int )( impactEnergy * IMPACTDMG_JOULE_TO_DAMAGE ); // deal impact damage to both clients and structures, use a threshold for friendly fire if ( impactDamage > 0 ) { // calculate knockback direction VectorSubtract( victim->s.origin, self->client->ps.origin, knockbackDir ); VectorNormalize( knockbackDir ); G_Damage( victim, self, self, knockbackDir, victim->s.origin, impactDamage, DAMAGE_NO_LOCDAMAGE, ModWeight( self ) ); } }
void G_WeightAttack( gentity_t *self, gentity_t *victim ) { float weightDPS, weightDamage; int attackerMass, victimMass; // weigth damage is only dealt between clients if ( !self->client || !victim->client ) { return; } // don't do friendly fire if ( G_OnSameTeam( self, victim ) ) { return; } // attacker must be above victim if ( self->client->ps.origin[ 2 ] + self->r.mins[ 2 ] < victim->s.origin[ 2 ] + victim->r.maxs[ 2 ] ) { return; } // victim must be on the ground if ( victim->client->ps.groundEntityNum == ENTITYNUM_NONE ) { return; } // check timer if ( victim->client->nextCrushTime > level.time ) { return; } attackerMass = BG_Class( self->client->pers.classSelection )->mass; victimMass = BG_Class( victim->client->pers.classSelection )->mass; weightDPS = WEIGHTDMG_DMG_MODIFIER * std::max( attackerMass - victimMass, 0 ); if ( weightDPS > WEIGHTDMG_DPS_THRESHOLD ) { weightDamage = weightDPS * ( WEIGHTDMG_REPEAT / 1000.0f ); victim->entity->Damage(weightDamage, self, Vec3::Load(victim->s.origin), Util::nullopt, DAMAGE_NO_LOCDAMAGE, ModWeight(self)); } victim->client->nextCrushTime = level.time + WEIGHTDMG_REPEAT; }
void G_ImpactAttack( gentity_t *self, gentity_t *victim ) { float impactVelocity, impactEnergy, impactDamage; vec3_t knockbackDir; int attackerMass; // self must be a client if ( !self->client ) { return; } // don't do friendly fire if ( G_OnSameTeam( self, victim ) ) { return; } // attacker must be above victim if ( self->client->ps.origin[ 2 ] + self->r.mins[ 2 ] < victim->s.origin[ 2 ] + victim->r.maxs[ 2 ] ) { return; } // allow the granger airlifting ritual if ( victim->client && victim->client->ps.stats[ STAT_STATE2 ] & SS2_JETPACK_ACTIVE && ( self->client->pers.classSelection == PCL_ALIEN_BUILDER0 || self->client->pers.classSelection == PCL_ALIEN_BUILDER0_UPG ) ) { return; } // calculate impact damage impactVelocity = fabs( self->client->pmext.fallImpactVelocity[ 2 ] ) * QU_TO_METER; // in m/s if (!impactVelocity) return; attackerMass = BG_Class( self->client->pers.classSelection )->mass; impactEnergy = attackerMass * impactVelocity * impactVelocity; // in J impactDamage = impactEnergy * IMPACTDMG_JOULE_TO_DAMAGE; // calculate knockback direction VectorSubtract( victim->s.origin, self->client->ps.origin, knockbackDir ); VectorNormalize( knockbackDir ); victim->entity->Damage((float)impactDamage, self, Vec3::Load(victim->s.origin), Vec3::Load(knockbackDir), DAMAGE_NO_LOCDAMAGE, ModWeight(self)); }