// Explode a missile without an impact void G_ExplodeMissile( gentity_t *ent ) { vector3 dir = { 0.0f, 0.0f, 1.0f }, origin = { 0.0f }; BG_EvaluateTrajectory( &ent->s.pos, level.time, &origin ); VectorSnap( &origin ); G_SetOrigin( ent, &origin ); ent->s.eType = ET_GENERAL; G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( &dir ) ); ent->freeAfterEvent = qtrue; ent->takedamage = qfalse; if ( ent->splashDamage || ent->splashRadius ) { if ( G_RadiusDamage( &ent->r.currentOrigin, ent->parent, (float)ent->splashDamage, (float)ent->splashRadius, ent, ent, ent->splashMethodOfDeath ) ) { if ( ent->parent ) g_entities[ent->parent->s.number].client->accuracy_hits++; else if ( ent->activator ) g_entities[ent->activator->s.number].client->accuracy_hits++; } } trap->SV_LinkEntity( (sharedEntity_t *)ent ); }
void DetPackBlow(gentity_t *self) { vec3_t v; self->pain = 0; self->die = 0; self->takedamage = qfalse; if ( self->target_ent ) {//we were attached to something, do *direct* damage to it! G_Damage( self->target_ent, self, &g_entities[self->r.ownerNum], v, self->r.currentOrigin, self->damage, 0, MOD_DET_PACK_SPLASH ); } G_RadiusDamage( self->r.currentOrigin, self->parent, self->splashDamage, self->splashRadius, self, self, MOD_DET_PACK_SPLASH ); v[0] = 0; v[1] = 0; v[2] = 1; if (self->count == -1) { VectorCopy(self->pos2, v); } G_PlayEffect(EFFECT_EXPLOSION_DETPACK, self->r.currentOrigin, v); self->think = G_FreeEntity; self->nextthink = level.time; }
void NoghriGasCloudThink( gentity_t *self ) { self->nextthink = level.time + FRAMETIME; AddSightEvent( self->owner, self->currentOrigin, 200, AEL_DANGER, 50 ); if ( self->fx_time < level.time ) { vec3_t up = {0,0,1}; G_PlayEffect( "noghri_stick/gas_cloud", self->currentOrigin, up ); self->fx_time = level.time + 250; } if ( level.time - self->s.time <= 2500 ) { if ( !Q_irand( 0, 3-g_spskill->integer ) ) { G_RadiusDamage( self->currentOrigin, self->owner, Q_irand( 1, 4 ), self->splashRadius, self->owner, self->splashMethodOfDeath ); } } if ( level.time - self->s.time > 3000 ) { G_FreeEntity( self ); } }
//--------------------------------------------------------- void thermalDetonatorExplode( gentity_t *ent ) //--------------------------------------------------------- { if ( !ent->count ) { G_Sound( ent, CHAN_WEAPON, G_SoundIndex( "sound/weapons/thermal/warning.wav" ) ); ent->count = 1; ent->genericValue5 = level.time + 500; ent->think = thermalThinkStandard; ent->nextthink = level.time; ent->r.svFlags |= SVF_BROADCAST;//so everyone hears/sees the explosion? } else { vec3_t origin; vec3_t dir={0,0,1}; BG_EvaluateTrajectory( &ent->s.pos, level.time, origin ); origin[2] += 8; SnapVector( origin ); G_SetOrigin( ent, origin ); ent->s.eType = ET_GENERAL; G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( dir ) ); ent->freeAfterEvent = qtrue; if (G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, ent, ent, ent->splashMethodOfDeath)) { g_entities[ent->r.ownerNum].client->accuracy_hits++; } trap_LinkEntity( ent ); } }
/* ================ G_ExplodeMissile Explode a missile without an impact ================ */ void G_ExplodeMissile( gentity_t *ent ) { vec3_t dir; vec3_t origin; BG_EvaluateTrajectory( &ent->s.pos, level.time, origin ); SnapVector( origin ); G_SetOrigin( ent, origin ); // we don't have a valid direction, so just point straight up dir[0] = dir[1] = 0; dir[2] = 1; ent->s.eType = ET_GENERAL; G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( dir ) ); ent->freeAfterEvent = qtrue; // splash damage if ( ent->splashDamage ) { if( G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, ent , ent->splashMethodOfDeath ) ) { g_entities[ent->r.ownerNum].player->accuracy_hits++; } } trap_LinkEntity( ent ); }
void G_ExplodeMissile( gentity_t *ent ) { vec3_t dir; vec3_t origin; const missileAttributes_t *ma = BG_Missile( ent->s.modelindex ); BG_EvaluateTrajectory( &ent->s.pos, level.time, origin ); SnapVector( origin ); G_SetOrigin( ent, origin ); // we don't have a valid direction, so just point straight up dir[ 0 ] = dir[ 1 ] = 0; dir[ 2 ] = 1; // turn the missile into an event carrier ent->s.eType = ET_INVISIBLE; ent->freeAfterEvent = true; G_AddEvent( ent, EV_MISSILE_HIT_ENVIRONMENT, DirToByte( dir ) ); // splash damage if ( ent->splashDamage ) { G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->splashDamage * MissileTimeSplashDmgMod( ent ), ent->splashRadius, ent, ( ma->doKnockback ? DAMAGE_KNOCKBACK : 0 ), ent->splashMethodOfDeath ); } trap_LinkEntity( ent ); }
/* ================ G_ExplodeMissile Explode a missile without an impact ================ */ void G_ExplodeMissile( gentity_t *ent ) { vec3_t dir; vec3_t origin; EvaluateTrajectory( &ent->s.pos, level.time, origin ); SnapVector( origin ); G_SetOrigin( ent, origin ); // we don't have a valid direction, so just point straight up dir[0] = dir[1] = 0; dir[2] = 1; if ( ent->owner )//&& ent->owner->s.number == 0 ) { //Add the event AddSoundEvent( ent->owner, ent->currentOrigin, 256, AEL_DISCOVERED, qfalse, qtrue );//FIXME: are we on ground or not? AddSightEvent( ent->owner, ent->currentOrigin, 512, AEL_DISCOVERED, 100 ); } /* ent->s.eType = ET_GENERAL; G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( dir ) ); ent->freeAfterEvent = qtrue;*/ // splash damage if ( ent->splashDamage ) { G_RadiusDamage( ent->currentOrigin, ent->owner, ent->splashDamage, ent->splashRadius, NULL , ent->splashMethodOfDeath ); } G_FreeEntity(ent); //gi.linkentity( ent ); }
/* ================ G_ExplodeMissile Explode a missile without an impact ================ */ void G_ExplodeMissile( gentity_t *ent ) { vec3_t dir; vec3_t origin; BG_EvaluateTrajectory( &ent->s.pos, level.time, origin ); SnapVector( origin ); G_SetOrigin( ent, origin ); // we don't have a valid direction, so just point straight up dir[ 0 ] = dir[ 1 ] = 0; dir[ 2 ] = 1; ent->s.eType = ET_GENERAL; if ( ent->s.weapon != WP_LOCKBLOB_LAUNCHER && ent->s.weapon != WP_FLAMER ) { G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( dir ) ); } ent->freeAfterEvent = qtrue; // splash damage if ( ent->splashDamage ) { G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->splashDamage * G_DoMissileTimePowerReduce( ent ), ent->splashRadius, ent, ent->splashMethodOfDeath ); } trap_LinkEntity( ent ); }
/* ================ G_ExplodeMissile Explode a missile without an impact ================ */ void G_ExplodeMissile(gentity_t *ent) { vec3_t dir; vec3_t origin; BG_EvaluateTrajectory(&ent->s.pos, level.time, origin); SnapVector(origin); G_SetOrigin(ent, origin); // we don't have a valid direction, so just point straight up dir[0] = dir[1] = 0; dir[2] = 1; ent->s.eType = ET_GENERAL; //TA: tired... can't be f****d... hack if (ent->s.weapon != WP_LOCKBLOB_LAUNCHER) G_AddEvent(ent, EV_MISSILE_MISS, DirToByte(dir)); /* if( ent->s.weapon == WP_BOMB ) { G_Explodefragnade(ent, origin); return; }*/ ent->freeAfterEvent = qtrue; // splash damage if (ent->splashDamage) G_RadiusDamage(ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, ent, ent->splashMethodOfDeath); trap_LinkEntity(ent); }
/* ================ G_ExplodeMissile Explode a missile without an impact ================ */ void G_ExplodeMissile(gentity_t * ent) { vec3_t dir; vec3_t origin; BG_EvaluateTrajectory(&ent->s.pos, level.time, origin); SnapVector(origin); G_SetOrigin(ent, origin); // we don't have a valid direction, so just point straight up dir[0] = dir[1] = 0; dir[2] = 1; // Tr3B: don't change the entity type because it is required by the EV_PROJECTILE_* events // the ent->freeAfterEvent = qtrue; will do the same effect //ent->s.eType = ET_GENERAL; G_AddEvent(ent, EV_PROJECTILE_MISS, DirToByte(dir)); ent->s.modelindex = 0; ent->freeAfterEvent = qtrue; // splash damage if(ent->splashDamage) { if(G_RadiusDamage(ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, ent, ent->splashMethodOfDeath)) { g_entities[ent->r.ownerNum].client->accuracy_hits++; } } trap_LinkEntity(ent); }
//QUAKED target_explosion (1 0 0) (-8 -8 -8) (8 8 8) //Spawns an explosion temporary entity when used. // //"delay" wait this long before going off //"dmg" how much radius damage should be done, defaults to 0 static void target_explosion_explode( edict_t *self ) { float save; int radius; G_RadiusDamage( self, self->activator, NULL, NULL, MOD_EXPLOSIVE ); if( ( self->projectileInfo.radius * 1/8 ) > 255 ) { radius = ( self->projectileInfo.radius * 1/16 ) & 0xFF; if( radius < 1 ) radius = 1; G_SpawnEvent( EV_EXPLOSION2, radius, self->s.origin ); } else { radius = ( self->projectileInfo.radius * 1/8 ) & 0xFF; if( radius < 1 ) radius = 1; G_SpawnEvent( EV_EXPLOSION1, radius, self->s.origin ); } save = self->delay; self->delay = 0; G_UseTargets( self, self->activator ); self->delay = save; }
/* ================ G_ExplodeMissile Explode a missile without an impact ================ */ void G_ExplodeMissile( gentity_t *ent ) { vec3_t dir; vec3_t origin; BG_EvaluateTrajectory( &ent->s.pos, level.time, origin ); SnapVector( origin ); G_SetOrigin( ent, origin ); // we don't have a valid direction, so just point straight up dir[0] = dir[1] = 0; dir[2] = 1; ent->s.eType = ET_GENERAL; G_AddEvent( ent, EV_MISSILE_MISS, DirToByte( dir ) ); ent->freeAfterEvent = qtrue; ent->takedamage = qfalse; // splash damage if ( ent->splashDamage ) { //[Asteroids] //NOTE: vehicle missiles don't have an ent->parent set, so check that here and set it if ( ent->s.eType == ET_MISSILE//missile && (ent->s.eFlags&EF_JETPACK_ACTIVE)//vehicle missile && ent->r.ownerNum < MAX_CLIENTS )//valid client owner { //set my parent to my owner for purposes of damage credit... ent->parent = &g_entities[ent->r.ownerNum]; } //[/Asteroids] G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, ent, ent, ent->splashMethodOfDeath ); } trap_LinkEntity( ent ); }
//------------------------------------------------------------------------------------------------------------ void auto_turret_die ( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int meansOfDeath ) //------------------------------------------------------------------------------------------------------------ { vec3_t forward = { 0,0, 1 }, pos; // Turn off the thinking of the base & use it's targets g_entities[self->r.ownerNum].think = NULL; g_entities[self->r.ownerNum].use = NULL; // clear my data self->die = NULL; self->takedamage = qfalse; self->s.health = self->health = 0; self->s.loopSound = 0; self->s.shouldtarget = qfalse; //self->s.owner = MAX_CLIENTS; //not owned by any client VectorCopy( self->r.currentOrigin, pos ); pos[2] += self->r.maxs[2]*0.5f; G_PlayEffect( EFFECT_EXPLOSION_TURRET, pos, forward ); G_PlayEffectID( G_EffectIndex( "turret/explode" ), pos, forward ); if ( self->splashDamage > 0 && self->splashRadius > 0 ) { G_RadiusDamage( self->r.currentOrigin, attacker, self->splashDamage, self->splashRadius, attacker, NULL, MOD_UNKNOWN ); } self->s.weapon = 0; // crosshair code uses this to mark crosshair red if ( self->s.modelindex2 ) { // switch to damage model if we should self->s.modelindex = self->s.modelindex2; if (self->target_ent && self->target_ent->s.modelindex2) { self->target_ent->s.modelindex = self->target_ent->s.modelindex2; } VectorCopy( self->r.currentAngles, self->s.apos.trBase ); VectorClear( self->s.apos.trDelta ); if ( self->target ) { G_UseTargets( self, attacker ); } } else { ObjectDie( self, inflictor, attacker, damage, meansOfDeath ); } }
/* * W_Touch_Rocket */ static void W_Touch_Rocket( edict_t *ent, edict_t *other, cplane_t *plane, int surfFlags ) { int mod_splash; vec3_t dir; int hitType; if( surfFlags & SURF_NOIMPACT ) { G_FreeEdict( ent ); return; } hitType = G_Projectile_HitStyle( ent, other ); if( hitType == PROJECTILE_TOUCH_NOT ) { return; } if( other->takedamage ) { int directHitDamage = ent->projectileInfo.maxDamage; VectorNormalize2( ent->velocity, dir ); if( hitType == PROJECTILE_TOUCH_DIRECTSPLASH ) { // use hybrid direction from splash and projectile G_SplashFrac4D( ENTNUM( other ), ent->s.origin, ent->projectileInfo.radius, dir, NULL, NULL, ent->timeDelta ); } else { VectorNormalize2( ent->velocity, dir ); if( hitType == PROJECTILE_TOUCH_DIRECTAIRHIT ) { directHitDamage += DIRECTAIRTHIT_DAMAGE_BONUS; } else if( hitType == PROJECTILE_TOUCH_DIRECTHIT ) { directHitDamage += DIRECTHIT_DAMAGE_BONUS; } } G_Damage( other, ent, ent->r.owner, dir, ent->velocity, ent->s.origin, directHitDamage, ent->projectileInfo.maxKnockback, ent->projectileInfo.stun, 0, ent->style ); } if( ent->s.effects & EF_STRONG_WEAPON ) { mod_splash = MOD_ROCKET_SPLASH_S; } else { mod_splash = MOD_ROCKET_SPLASH_W; } G_RadiusDamage( ent, ent->r.owner, plane, other, mod_splash ); // spawn the explosion if( !( surfFlags & SURF_NOIMPACT ) ) { edict_t *event; vec3_t explosion_origin; VectorMA( ent->s.origin, -0.02, ent->velocity, explosion_origin ); event = G_SpawnEvent( EV_ROCKET_EXPLOSION, DirToByte( plane ? plane->normal : NULL ), explosion_origin ); event->s.firemode = ( ent->s.effects & EF_STRONG_WEAPON ) ? FIRE_MODE_STRONG : FIRE_MODE_WEAK; event->s.weapon = ( ( ent->projectileInfo.radius * 1 / 8 ) > 255 ) ? 255 : ( ent->projectileInfo.radius * 1 / 8 ); } // free the rocket at next frame G_FreeEdict( ent ); }
//---------------------------------------------- void WP_flechette_alt_blow( gentity_t *ent ) //---------------------------------------------- { EvaluateTrajectory( &ent->s.pos, level.time, ent->currentOrigin ); // Not sure if this is even necessary, but correct origins are cool? G_RadiusDamage( ent->currentOrigin, ent->owner, ent->splashDamage, ent->splashRadius, NULL, MOD_EXPLOSIVE_SPLASH ); G_PlayEffect( "flechette/alt_blow", ent->currentOrigin ); G_FreeEntity( ent ); }
void TouchTieBomb( gentity_t *self, gentity_t *other, trace_t *trace ) { // Stop the effect. G_StopEffect( G_EffectIndex( "ships/tiebomber_bomb_falling" ), self->playerModel, gi.G2API_AddBolt( &self->ghoul2[0], "model_root" ), self->s.number ); self->e_ThinkFunc = thinkF_G_FreeEntity; self->nextthink = level.time + FRAMETIME; G_PlayEffect( G_EffectIndex( "ships/tiebomber_explosion2" ), self->currentOrigin, self->currentAngles ); G_RadiusDamage( self->currentOrigin, self, 900, 500, self, MOD_EXPLOSIVE_SPLASH ); }
/* * @brief Kills the specified entity via explosion, potentially taking nearby * entities with it. */ void G_Explode(g_entity_t *ent, int16_t damage, int16_t knockback, vec_t radius, uint32_t mod) { gi.WriteByte(SV_CMD_TEMP_ENTITY); gi.WriteByte(TE_EXPLOSION); gi.WritePosition(ent->s.origin); gi.Multicast(ent->s.origin, MULTICAST_PHS, NULL); G_RadiusDamage(ent, ent, NULL, damage, knockback, radius, mod ? mod : MOD_EXPLOSIVE); G_FreeEntity(ent); }
static void W_Plasma_Explosion( edict_t *ent, edict_t *ignore, cplane_t *plane, int surfFlags ) { edict_t *event; int radius = ( ( ent->projectileInfo.radius * 1 / 8 ) > 127 ) ? 127 : ( ent->projectileInfo.radius * 1 / 8 ); event = G_SpawnEvent( EV_PLASMA_EXPLOSION, DirToByte( plane ? plane->normal : NULL ), ent->s.origin ); event->s.firemode = ( ent->s.effects & EF_STRONG_WEAPON ) ? FIRE_MODE_STRONG : FIRE_MODE_WEAK; event->s.weapon = radius & 127; G_RadiusDamage( ent, ent->r.owner, plane, ignore, ent->style ); G_FreeEdict( ent ); }
static int GLua_Sys_RadiusDamage(lua_State *L) { vec3_t org; gentity_t *attacker = 0, *ignore = 0, *missile = 0; GLuaVec_t *org2; org2 = GLua_CheckVector(L,1); ConvertVec(org2, org); if (!lua_isnoneornil(L,2)) attacker = GLua_CheckEntity(L,2); if (!lua_isnoneornil(L,5)) ignore = GLua_CheckEntity(L,5); if (!lua_isnoneornil(L,6)) missile = GLua_CheckEntity(L,6); G_RadiusDamage(org, attacker, lua_tonumber(L,3), lua_tonumber(L,4), ignore, missile, lua_tonumber(L,7)); return 0; }
/** * \brief Handles grenade shrapnels. * * Handles grenade shrapnels. * * @param ent the grenade */ void grenadeSpewShrapnel( gentity_t *ent ) { gentity_t *tent = NULL; tent = G_TempEntity( ent->r.currentOrigin, EV_GRENADE_SHRAPNEL_EXPLODE ); tent->s.eventParm = DirToByte(ent->pos1); // just do radius dmg for altfire G_RadiusDamage( ent->r.currentOrigin, ent->parent, ent->splashDamage, ent->splashRadius, ent, 0, ent->splashMethodOfDeath ); G_FreeEntity(ent); }
/** * \brief Exploding a grenade. * * Handles all damage and visual effects for a exploding grenade. * * @param ent the grenade */ static void grenadeExplode( gentity_t *ent ) { vec3_t pos; VectorSet( pos, ent->r.currentOrigin[0], ent->r.currentOrigin[1], ent->r.currentOrigin[2] + 8 ); G_TempEntity( pos, EV_GRENADE_EXPLODE ); /* splash damage (doesn't apply to person directly hit) */ if ( ent->splashDamage ) { G_RadiusDamage( pos, ent->parent, ent->splashDamage, ent->splashRadius, NULL, 0, ent->splashMethodOfDeath ); } G_FreeEntity( ent ); }
//lightning strike trigger lightning strike event void Do_Strike(gentity_t *ent) { trace_t localTrace; vec3_t strikeFrom; vec3_t strikePoint; vec3_t fxAng; //maybe allow custom fx direction at some point? VectorSet(fxAng, 90.0f, 0.0f, 0.0f); //choose a random point to strike within the bounds of the trigger strikePoint[0] = flrand(ent->r.absmin[0], ent->r.absmax[0]); strikePoint[1] = flrand(ent->r.absmin[1], ent->r.absmax[1]); //consider the bottom mins the ground level strikePoint[2] = ent->r.absmin[2]; //set the from point strikeFrom[0] = strikePoint[0]; strikeFrom[1] = strikePoint[1]; strikeFrom[2] = ent->r.absmax[2]-4.0f; //now trace for damaging stuff, and do the effect trap->Trace(&localTrace, strikeFrom, NULL, NULL, strikePoint, ent->s.number, MASK_PLAYERSOLID, 0, 0, 0); VectorCopy(localTrace.endpos, strikePoint); if (localTrace.startsolid || localTrace.allsolid) { //got a bad spot, think again next frame to try another strike ent->nextthink = level.time; return; } if (ent->radius) { //do a radius damage at the end pos G_RadiusDamage(strikePoint, ent, ent->damage, ent->radius, ent, NULL, MOD_SUICIDE); } else { //only damage individuals gentity_t *trHit = &g_entities[localTrace.entityNum]; if (trHit->inuse && trHit->takedamage) { //damage it then G_Damage(trHit, ent, ent, NULL, trHit->r.currentOrigin, ent->damage, 0, MOD_SUICIDE); } } G_PlayEffectID(ent->genericValue2, strikeFrom, fxAng); }
/* * W_Touch_GunbladeBlast */ static void W_Touch_GunbladeBlast( edict_t *ent, edict_t *other, cplane_t *plane, int surfFlags ) { vec3_t dir; int hitType; if( surfFlags & SURF_NOIMPACT ) { G_FreeEdict( ent ); return; } hitType = G_Projectile_HitStyle( ent, other ); if( hitType == PROJECTILE_TOUCH_NOT ) return; if( other->takedamage ) { VectorNormalize2( ent->velocity, dir ); if( hitType == PROJECTILE_TOUCH_DIRECTSPLASH ) // use hybrid direction from splash and projectile { G_SplashFrac4D( ENTNUM( other ), ent->s.origin, ent->projectileInfo.radius, dir, NULL, NULL, ent->timeDelta ); } else { VectorNormalize2( ent->velocity, dir ); } G_Damage( other, ent, ent->r.owner, dir, ent->velocity, ent->s.origin, ent->projectileInfo.maxDamage, ent->projectileInfo.maxKnockback, ent->projectileInfo.stun, 0, ent->style ); } G_RadiusDamage( ent, ent->r.owner, plane, other, MOD_GUNBLADE_S ); // add explosion event if( ( !other->takedamage || ISBRUSHMODEL( other->s.modelindex ) ) ) { edict_t *event; event = G_SpawnEvent( EV_GUNBLADEBLAST_IMPACT, DirToByte( plane ? plane->normal : NULL ), ent->s.origin ); event->s.weapon = ( ( ent->projectileInfo.radius * 1/8 ) > 127 ) ? 127 : ( ent->projectileInfo.radius * 1/8 ); event->s.skinnum = ( ( ent->projectileInfo.maxKnockback * 1/8 ) > 255 ) ? 255 : ( ent->projectileInfo.maxKnockback * 1/8 ); } // free at next frame G_FreeEdict( ent ); }
// This version shares is in the thinkFunc format //----------------------------------------------------------------------------- void WP_Explode( gentity_t *self ) //----------------------------------------------------------------------------- { gentity_t *attacker = self; vec3_t forwardVec={0,0,1}; // stop chain reaction runaway loops self->takedamage = qfalse; self->s.loopSound = 0; // VectorCopy( self->currentOrigin, self->s.pos.trBase ); if ( !self->client ) { AngleVectors( self->s.angles, forwardVec, NULL, NULL ); } if ( self->fxID > 0 ) { G_PlayEffect( self->fxID, self->currentOrigin, forwardVec ); } if ( self->owner ) { attacker = self->owner; } else if ( self->activator ) { attacker = self->activator; } if ( self->splashDamage > 0 && self->splashRadius > 0 ) { G_RadiusDamage( self->currentOrigin, attacker, self->splashDamage, self->splashRadius, 0/*don't ignore attacker*/, MOD_EXPLOSIVE_SPLASH ); } if ( self->target ) { G_UseTargets( self, attacker ); } G_SetOrigin( self, self->currentOrigin ); self->nextthink = level.time + 50; self->e_ThinkFunc = thinkF_G_FreeEntity; }
bool G_RocketpodSafeShot( int passEntityNum, vec3_t origin, vec3_t dir ) { trace_t tr; vec3_t mins, maxs, end; float size; const missileAttributes_t *attr = BG_Missile( MIS_ROCKET ); size = attr->size; VectorSet( mins, -size, -size, -size); VectorSet( maxs, size, size, size ); VectorMA( origin, 8192, dir, end ); trap_Trace( &tr, origin, mins, maxs, end, passEntityNum, MASK_SHOT, 0 ); return !G_RadiusDamage( tr.endpos, nullptr, attr->splashDamage, attr->splashRadius, nullptr, 0, MOD_ROCKETPOD, TEAM_HUMANS ); }
/* =============== AIFunc_LoperAttack3() Loper's ground electrical attack =============== */ char *AIFunc_LoperAttack3( cast_state_t *cs ) { gentity_t *ent; qboolean hitClient = qfalse; // ent = &g_entities[cs->entityNum]; // // done with this attack? if ( cs->thinkFuncChangeTime < level.time - LOPER_GROUND_DELAY ) { cs->pauseTime = level.time + 600; // don't move until effect is done ent->client->ps.legsTimer = 600; // stay down until effect is done return AIFunc_DefaultStart( cs ); } // ready to inflict damage? if ( cs->thinkFuncChangeTime < level.time - 900 ) { // // draw the client-side lightning effect ent->client->ps.eFlags |= EF_MONSTER_EFFECT3; //ent->s.effect3Time = level.time + 500;//cs->thinkFuncChangeTime + LOPER_GROUND_DELAY - 200; // // are we waiting to inflict damage? if ( cs->weaponFireTimes[WP_MONSTER_ATTACK3] < level.time - 100 ) { // check for damage hitClient = G_RadiusDamage( cs->bs->origin, ent, LOPER_GROUND_DAMAGE, LOPER_GROUND_RANGE, ent, MOD_LOPER_GROUND ); // cs->weaponFireTimes[WP_MONSTER_ATTACK3] = level.time; // TODO: client-side visual effect // TODO: throw them backwards (away from us) } else { hitClient = qtrue; // so we don't abort } // if ( !hitClient && cs->thinkFuncChangeTime < ( level.time - 1500 ) ) { // we're done with this attack cs->pauseTime = level.time + 600; // don't move until effect is done ent->client->ps.legsTimer = 600; // stay down until effect is done return AIFunc_DefaultStart( cs ); } } // if ( ent->client->ps.legsTimer < 1000 ) { ent->client->ps.legsTimer = 1000; // stay down until effect is done } return NULL; }
//---------------------------------------------------------- void fx_runner_think( gentity_t *ent ) { vec3_t temp; EvaluateTrajectory( &ent->s.pos, level.time, ent->currentOrigin ); EvaluateTrajectory( &ent->s.apos, level.time, ent->currentAngles ); // call the effect with the desired position and orientation G_AddEvent( ent, EV_PLAY_EFFECT, ent->fxID ); // Assume angles, we'll do a cross product on the other end to finish up AngleVectors( ent->currentAngles, ent->pos3, NULL, NULL ); MakeNormalVectors( ent->pos3, ent->pos4, temp ); // there IS a reason this is done...it's so that it doesn't break every effect in the game... ent->nextthink = level.time + ent->delay + random() * ent->random; if ( ent->spawnflags & 4 ) // damage { G_RadiusDamage( ent->currentOrigin, ent, ent->splashDamage, ent->splashRadius, ent, MOD_UNKNOWN ); } if ( ent->target2 ) { // let our target know that we have spawned an effect G_UseTargets2( ent, ent, ent->target2 ); } if ( !(ent->spawnflags & 2 ) && !ent->s.loopSound ) // NOT ONESHOT...this is an assy thing to do { if ( VALIDSTRING( ent->soundSet ) == true ) { ent->s.loopSound = CAS_GetBModelSound( ent->soundSet, BMS_MID ); if ( ent->s.loopSound < 0 ) { ent->s.loopSound = 0; } } } }
/* * W_Touch_Projectile - Generic projectile touch func. Only for replacement in tests */ static void W_Touch_Projectile( edict_t *ent, edict_t *other, cplane_t *plane, int surfFlags ) { vec3_t dir, normal; int hitType; if( surfFlags & SURF_NOIMPACT ) { G_FreeEdict( ent ); return; } hitType = G_Projectile_HitStyle( ent, other ); if( hitType == PROJECTILE_TOUCH_NOT ) return; if( other->takedamage ) { VectorNormalize2( ent->velocity, dir ); if( hitType == PROJECTILE_TOUCH_DIRECTSPLASH ) // use hybrid direction from splash and projectile { G_SplashFrac4D( ENTNUM( other ), ent->s.origin, ent->projectileInfo.radius, dir, NULL, NULL, ent->timeDelta ); } else { VectorNormalize2( ent->velocity, dir ); } G_Damage( other, ent, ent->r.owner, dir, ent->velocity, ent->s.origin, ent->projectileInfo.maxDamage, ent->projectileInfo.maxKnockback, ent->projectileInfo.stun, 0, ent->style ); } G_RadiusDamage( ent, ent->r.owner, plane, other, MOD_EXPLOSIVE ); if( !plane->normal ) VectorSet( normal, 0, 0, 1 ); else VectorCopy( plane->normal, normal ); G_Gametype_ScoreEvent( NULL, "projectilehit", va( "%i %i %f %f %f", ent->s.number, surfFlags, normal[0], normal[1], normal[2] ) ); }
/* ============== alarmExplosion copied from propExplosion ============== */ void alarmExplosion(gentity_t *ent) { // death sound G_AddEvent(ent, EV_GENERAL_SOUND, ent->sound1to2); G_AddEvent(ent, EV_ENTDEATH, ent->s.eType); G_RadiusDamage(ent->s.origin, ent, ent->damage, ent->damage, ent, MOD_EXPLOSIVE); // return // old way. (using grenade) /* gentity_t *bolt; extern void G_ExplodeMissile( gentity_t *ent ); bolt = G_Spawn(); bolt->classname = "props_explosion"; bolt->nextthink = level.time + FRAMETIME; bolt->think = G_ExplodeMissile; bolt->s.eType = ET_MISSILE; bolt->r.svFlags = SVF_USE_CURRENT_ORIGIN; bolt->s.weapon = WP_NONE; bolt->s.eFlags = EF_BOUNCE_HALF; bolt->r.ownerNum = ent->s.number; bolt->parent = ent; bolt->damage = ent->health; bolt->splashDamage = ent->health; bolt->splashRadius = ent->health * 1.5; bolt->methodOfDeath = MOD_GRENADE; bolt->splashMethodOfDeath = MOD_GRENADE_SPLASH; bolt->clipmask = MASK_SHOT; VectorCopy (ent->r.currentOrigin, bolt->s.pos.trBase ); VectorCopy (ent->r.currentOrigin, bolt->r.currentOrigin); */ }
/* * W_Grenade_ExplodeDir */ static void W_Grenade_ExplodeDir( edict_t *ent, vec3_t normal ) { vec3_t origin; int radius; edict_t *event; vec3_t up = { 0, 0, 1 }; vec_t *dir = normal ? normal : up; G_RadiusDamage( ent, ent->r.owner, NULL, ent->enemy, ( ent->s.effects & EF_STRONG_WEAPON ) ? MOD_GRENADE_SPLASH_S : MOD_GRENADE_SPLASH_W ); radius = ( ( ent->projectileInfo.radius * 1 / 8 ) > 127 ) ? 127 : ( ent->projectileInfo.radius * 1 / 8 ); VectorMA( ent->s.origin, -0.02, ent->velocity, origin ); event = G_SpawnEvent( EV_GRENADE_EXPLOSION, ( dir ? DirToByte( dir ) : 0 ), ent->s.origin ); event->s.firemode = ( ent->s.effects & EF_STRONG_WEAPON ) ? FIRE_MODE_STRONG : FIRE_MODE_WEAK; event->s.weapon = radius; G_FreeEdict( ent ); }