void painSawFire( gentity_t *ent ) { trace_t tr; vec3_t temp; gentity_t *tent, *traceEnt; G_WideTrace( &tr, ent, PAINSAW_RANGE, PAINSAW_WIDTH, PAINSAW_HEIGHT, &traceEnt ); if ( !traceEnt || !traceEnt->takedamage ) { return; } // hack to line up particle system with weapon model tr.endpos[ 2 ] -= 5.0f; // send blood impact if ( traceEnt->s.eType == ET_PLAYER || traceEnt->s.eType == ET_BUILDABLE ) { BloodSpurt( ent, traceEnt, &tr ); } else { VectorCopy( tr.endpos, temp ); tent = G_NewTempEntity( temp, EV_MISSILE_MISS ); tent->s.eventParm = DirToByte( tr.plane.normal ); tent->s.weapon = ent->s.weapon; tent->s.generic1 = ent->s.generic1; //weaponMode } G_Damage( traceEnt, ent, ent, forward, tr.endpos, PAINSAW_DAMAGE, DAMAGE_NO_KNOCKBACK, MOD_PAINSAW ); }
/* =============== CheckPounceAttack =============== */ qboolean CheckPounceAttack( gentity_t *ent ) { trace_t tr; gentity_t *traceEnt; int damage, timeMax, pounceRange, pounceWidth, payload; if( ent->client->pmext.pouncePayload <= 0 ) return qfalse; // In case the goon lands on his target, he get's one shot after landing payload = ent->client->pmext.pouncePayload; if( !( ent->client->ps.pm_flags & PMF_CHARGE/* || ent->client->ps.weapon == WP_ALEVEL5 */) ) ent->client->pmext.pouncePayload = 0; // Calculate muzzle point AngleVectors( ent->client->ps.viewangles, forward, right, up ); CalcMuzzlePoint( ent, forward, right, up, muzzle ); // Trace from muzzle to see what we hit if( ent->client->ps.weapon == WP_ALEVEL5) { pounceRange = LEVEL5_POUNCE_RANGE; pounceWidth = LEVEL5_POUNCE_WIDTH; } else { pounceRange = ent->client->ps.weapon == WP_ALEVEL3 ? LEVEL3_POUNCE_RANGE : LEVEL3_POUNCE_UPG_RANGE; pounceWidth = LEVEL3_POUNCE_WIDTH; } G_WideTrace( &tr, ent, pounceRange, pounceWidth, pounceWidth, &traceEnt ); if( traceEnt == NULL ) return qfalse; // Send blood impact if( traceEnt->takedamage ) WideBloodSpurt( ent, traceEnt, &tr, MOD_LEVEL3_POUNCE ); if( !traceEnt->takedamage ) return qfalse; // Deal damage if( ent->client->ps.weapon == WP_ALEVEL5) { timeMax = LEVEL5_POUNCE_TIME; damage = payload * LEVEL5_POUNCE_DMG / timeMax; ent->client->pmext.pouncePayload = 0; G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, DAMAGE_NO_LOCDAMAGE, MOD_LEVEL5_POUNCE ); } else { timeMax = ent->client->ps.weapon == WP_ALEVEL3 ? LEVEL3_POUNCE_TIME : LEVEL3_POUNCE_TIME_UPG; damage = payload * LEVEL3_POUNCE_DMG / timeMax; ent->client->pmext.pouncePayload = 0; G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, DAMAGE_NO_LOCDAMAGE, MOD_LEVEL3_POUNCE ); } return qtrue; }
/* =============== CheckPounceAttack =============== */ qboolean CheckPounceAttack( gentity_t *ent ) { trace_t tr; gentity_t *tent; gentity_t *traceEnt; int damage; if( ent->client->ps.groundEntityNum != ENTITYNUM_NONE ) { ent->client->allowedToPounce = qfalse; ent->client->pmext.pouncePayload = 0; } if( !ent->client->allowedToPounce ) return qfalse; if( ent->client->ps.weaponTime ) return qfalse; G_WideTrace( &tr, ent, LEVEL3_POUNCE_RANGE, LEVEL3_POUNCE_WIDTH, &traceEnt ); if( traceEnt == NULL ) return qfalse; // send blood impact if( traceEnt->takedamage && traceEnt->client ) { tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT ); tent->s.otherEntityNum = traceEnt->s.number; tent->s.eventParm = DirToByte( tr.plane.normal ); tent->s.weapon = ent->s.weapon; tent->s.generic1 = ent->s.generic1; //weaponMode } if( !traceEnt->takedamage ) return qfalse; /* damage = (int)( ( ((float)ent->client->pmext.pouncePayload / (float)LEVEL3_POUNCE_SPEED ) * LEVEL3_POUNCE_DMG ) * (( (float)ent->client->ps.stats[ STAT_FALLDIST ] - MIN_FALL_DISTANCE ) / ( MAX_FALL_DISTANCE - MIN_FALL_DISTANCE ))); */ //original damage = (int)( ( (float)ent->client->pmext.pouncePayload / (float)LEVEL3_POUNCE_SPEED ) * LEVEL3_POUNCE_DMG ); //extra added // client->ps.stats[ STAT_FALLDIST ] ent->client->pmext.pouncePayload = 0; G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, 0|DAMAGE_NO_LOCDAMAGE, MOD_LEVEL3_POUNCE ); //now like gpp: has knockback ent->client->allowedToPounce = qfalse; return qtrue; }
/* =============== CheckVenomAttack =============== */ qboolean CheckVenomAttack( gentity_t *ent ) { trace_t tr; gentity_t *traceEnt; int damage = LEVEL0_BITE_DMG; if( ent->client->ps.weaponTime ) return qfalse; // Calculate muzzle point AngleVectors( ent->client->ps.viewangles, forward, right, up ); CalcMuzzlePoint( ent, forward, right, up, muzzle ); G_WideTrace( &tr, ent, LEVEL0_BITE_RANGE, LEVEL0_BITE_WIDTH, LEVEL0_BITE_WIDTH, &traceEnt ); if( traceEnt == NULL ) return qfalse; if( !traceEnt->takedamage ) return qfalse; if( traceEnt->health <= 0 ) return qfalse; // only allow bites to work against buildings as they are constructing if( traceEnt->s.eType == ET_BUILDABLE ) { if( traceEnt->buildableTeam == TEAM_ALIENS ) return qfalse; if ( !( traceEnt->s.modelindex == BA_H_MGTURRET || traceEnt->s.modelindex == BA_H_MGTURRET2 || traceEnt->s.modelindex == BA_H_TESLAGEN || !traceEnt->spawned ) ) damage = (int)(damage * g_DretchBuildingDamage.value); else damage = (int)(damage * g_DretchTurretDamage.value); if (damage <= 0) return qfalse; } if( traceEnt->client ) { if( traceEnt->client->ps.stats[ STAT_TEAM ] == TEAM_ALIENS ) return qfalse; if( traceEnt->client->ps.stats[ STAT_HEALTH ] <= 0 ) return qfalse; } // send blood impact WideBloodSpurt( ent, traceEnt, &tr, MOD_LEVEL0_BITE ); G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK, MOD_LEVEL0_BITE ); ent->client->ps.weaponTime += LEVEL0_BITE_REPEAT; return qtrue; }
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; }
/* =============== CheckPounceAttack =============== */ qboolean CheckPounceAttack( gentity_t *ent ) { trace_t tr; gentity_t *tent; gentity_t *traceEnt; int damage; if( ent->client->ps.groundEntityNum != ENTITYNUM_NONE ) { ent->client->allowedToPounce = qfalse; ent->client->pmext.pouncePayload = 0; } if( !ent->client->allowedToPounce ) return qfalse; if( ent->client->ps.weaponTime ) return qfalse; G_WideTrace( &tr, ent, LEVEL3_POUNCE_RANGE, LEVEL3_POUNCE_WIDTH, &traceEnt ); if( traceEnt == NULL ) return qfalse; // send blood impact if( traceEnt->takedamage && traceEnt->client ) { tent = G_TempEntity( tr.endpos, EV_MISSILE_HIT ); tent->s.otherEntityNum = traceEnt->s.number; tent->s.eventParm = DirToByte( tr.plane.normal ); tent->s.weapon = ent->s.weapon; tent->s.generic1 = ent->s.generic1; //weaponMode } if( !traceEnt->takedamage ) return qfalse; damage = (int)( ( (float)ent->client->pmext.pouncePayload / (float)LEVEL3_POUNCE_SPEED ) * LEVEL3_POUNCE_DMG ); ent->client->pmext.pouncePayload = 0; G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK|DAMAGE_NO_LOCDAMAGE, MOD_LEVEL3_POUNCE ); ent->client->allowedToPounce = qfalse; return qtrue; }
/* =============== meleeAttack =============== */ void meleeAttack( gentity_t *ent, float range, float width, float height, int damage, meansOfDeath_t mod ) { trace_t tr; gentity_t *traceEnt; G_WideTrace( &tr, ent, range, width, height, &traceEnt ); if ( traceEnt == NULL || !traceEnt->takedamage ) { return; } WideBloodSpurt( ent, traceEnt, &tr ); G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK, mod ); }
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 void FirePainsaw( gentity_t *self ) { trace_t tr; gentity_t *target; G_WideTrace( &tr, self, PAINSAW_RANGE, PAINSAW_WIDTH, PAINSAW_HEIGHT, &target ); if ( !target || !target->takedamage ) { return; } // not really a "ranged" weapon, but this is still the right call SendRangedHitEvent( self, target, &tr ); G_Damage( target, self, self, forward, tr.endpos, PAINSAW_DAMAGE, DAMAGE_NO_KNOCKBACK, MOD_PAINSAW ); }
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; }
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; }
/* =============== meleeAttack =============== */ void meleeAttack( gentity_t *ent, float range, float width, float height, int damage, meansOfDeath_t mod ) { trace_t tr; gentity_t *traceEnt; if( mod == MOD_LEVEL2_CLAW && damage == LEVEL2_CLAW_UPG_DMG ) G_CombatStats_Fire( ent, CSW_LEVEL2_UPG, damage ); else G_CombatStats_FireMOD( ent, mod, damage ); G_WideTrace( &tr, ent, range, width, height, &traceEnt ); if( traceEnt == NULL || !traceEnt->takedamage ) return; WideBloodSpurt( ent, traceEnt, &tr, mod ); G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK, mod ); }
static void FirePainsaw( gentity_t *self ) { trace_t tr; gentity_t *target; G_WideTrace( &tr, self, PAINSAW_RANGE, PAINSAW_WIDTH, PAINSAW_HEIGHT, &target ); if ( !G_Alive( target ) ) { return; } // not really a "ranged" weapon, but this is still the right call SendRangedHitEvent( self, target, &tr ); target->entity->Damage((float)PAINSAW_DAMAGE, self, Vec3::Load(tr.endpos), Vec3::Load(forward), 0, (meansOfDeath_t)MOD_PAINSAW); }
static void FireAreaZap( gentity_t *ent ) { trace_t tr; gentity_t *traceEnt; G_WideTrace( &tr, ent, LEVEL2_AREAZAP_RANGE, LEVEL2_AREAZAP_WIDTH, LEVEL2_AREAZAP_WIDTH, &traceEnt ); if ( traceEnt == NULL ) { return; } if ( ( traceEnt->client && traceEnt->client->pers.team == TEAM_HUMANS ) || ( traceEnt->s.eType == ET_BUILDABLE && BG_Buildable( traceEnt->s.modelindex )->team == TEAM_HUMANS ) ) { CreateNewZap( ent, traceEnt ); } }
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; }
/* =============== areaZapFire =============== */ void areaZapFire( gentity_t *ent ) { trace_t tr; gentity_t *traceEnt; G_CombatStats_Fire( ent, CSW_LEVEL2_ALT, LEVEL2_AREAZAP_DMG ); G_WideTrace( &tr, ent, LEVEL2_AREAZAP_RANGE, LEVEL2_AREAZAP_WIDTH, LEVEL2_AREAZAP_WIDTH, &traceEnt ); if( traceEnt == NULL ) return; if( ( traceEnt->client && traceEnt->client->ps.stats[ STAT_TEAM ] == TEAM_HUMANS ) || ( traceEnt->s.eType == ET_BUILDABLE && BG_Buildable( traceEnt->s.modelindex )->team == TEAM_HUMANS ) || ( traceEnt->client && traceEnt->client->ps.stats[ STAT_TEAM ] == TEAM_ALIENS && traceEnt->client->ps.stats[ STAT_CLASS ] == PCL_ALIEN_LEVEL2_UPG ) ) { G_CreateNewZap( ent, traceEnt ); } }
/* =============== G_MedkitTarget Look for a possible healing target (a client) in the front. =============== */ gentity_t *G_MedkitTarget( gentity_t *ent ) { trace_t tr; gentity_t *targetEnt = NULL; if( g_humanMedkitRange.value <= 0 || g_humanMedkitWidth.value <= 0 ) return NULL; // Calculate muzzle point AngleVectors( ent->client->ps.viewangles, forward, right, up ); CalcMuzzlePoint( ent, forward, right, up, muzzle ); G_WideTrace( &tr, ent, g_humanMedkitRange.value, g_humanMedkitWidth.value, g_humanMedkitWidth.value, &targetEnt ); if( ( targetEnt != NULL ) && ( targetEnt->client != NULL ) ) return targetEnt; else return NULL; }
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; }