コード例 #1
0
ファイル: g_entity_trigger.c プロジェクト: jdolan/quetoo
/**
 * @brief
 */
static void G_trigger_hurt_Touch(g_entity_t *self, g_entity_t *other,
                                 const cm_bsp_plane_t *plane,
                                 const cm_bsp_texinfo_t *surf) {

	if (!other->locals.take_damage) { // deal with items that land on us

		if (other->locals.item) {
			if (other->locals.item->type == ITEM_FLAG) {
				G_ResetDroppedFlag(other);
			} else if (other->locals.item->type == ITEM_TECH) {
				G_ResetDroppedTech(other);
			} else {
				G_FreeEntity(other);
			}
		}

		gi.Debug("%s\n", etos(other));
		return;
	}

	if (self->locals.timestamp > g_level.time) {
		return;
	}

	if (self->locals.spawn_flags & 16) {
		self->locals.timestamp = g_level.time + 1000;
	} else {
		self->locals.timestamp = g_level.time + 100;
	}

	const int16_t d = self->locals.damage;

	int32_t dflags = DMG_NO_ARMOR;

	if (self->locals.spawn_flags & 8) {
		dflags = DMG_NO_GOD;
	}

	G_Damage(other, self, NULL, NULL, NULL, NULL, d, d, dflags, MOD_TRIGGER_HURT);
}
コード例 #2
0
void env_afx_hurt_touch( gentity_t *self, gentity_t *other, trace_t *trace )
{
	int dflags;

	if ( !other->takedamage )
	{
		return;
	}

	if ( self->timestamp > level.time )
	{
		return;
	}

	if ( self->spawnflags & 16 )
	{
		self->timestamp = level.time + 1000;
	}
	else
	{
		self->timestamp = level.time + FRAMETIME;
	}

	// play sound
	if ( !( self->spawnflags & 4 ) )
	{
		G_Sound( other, CHAN_AUTO, self->soundIndex );
	}

	if ( self->spawnflags & 8 )
	{
		dflags = DAMAGE_NO_PROTECTION;
	}
	else
	{
		dflags = 0;
	}

	G_Damage( other, self, self, NULL, NULL, self->damage, dflags, MOD_TRIGGER_HURT );
}
コード例 #3
0
/*
===============
meleeAttack
===============
*/
void meleeAttack( gentity_t *ent, float range, float width, int damage, meansOfDeath_t mod )
{
  trace_t   tr;
  vec3_t    end;
  gentity_t *tent;
  gentity_t *traceEnt;
  vec3_t    mins, maxs;

  VectorSet( mins, -width, -width, -width );
  VectorSet( maxs, width, width, width );

  // set aiming directions
  AngleVectors( ent->client->ps.viewangles, forward, right, up );

  CalcMuzzlePoint( ent, forward, right, up, muzzle );

  VectorMA( muzzle, range, forward, end );

  G_UnlaggedOn( muzzle, range );
  trap_Trace( &tr, muzzle, mins, maxs, end, ent->s.number, MASK_SHOT );
  G_UnlaggedOff( );

  if( tr.surfaceFlags & SURF_NOIMPACT )
    return;

  traceEnt = &g_entities[ tr.entityNum ];

  // 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 )
    G_Damage( traceEnt, ent, ent, forward, tr.endpos, damage, DAMAGE_NO_KNOCKBACK, mod );
}
コード例 #4
0
ファイル: g_missile.c プロジェクト: SinSiXX/Rogue-Reborn
/*
================
ProximityMine_ExplodeOnPlayer
================
*/
static void ProximityMine_ExplodeOnPlayer(gentity_t * mine)
{
	gentity_t      *player;

	player = mine->enemy;
	player->client->ps.eFlags &= ~EF_TICKING;

	if(player->client->invulnerabilityTime > level.time)
	{
		G_Damage(player, mine->parent, mine->parent, vec3_origin, mine->s.origin, 1000, DAMAGE_NO_KNOCKBACK, MOD_JUICED);
		player->client->invulnerabilityTime = 0;
		G_TempEntity(player->client->ps.origin, EV_JUICED);
	}
	else
	{
		G_SetOrigin(mine, player->s.pos.trBase);
		// make sure the explosion gets to the client
		mine->r.svFlags &= ~SVF_NOCLIENT;
		mine->splashMethodOfDeath = MOD_PROXIMITY_MINE;
		G_ExplodeMissile(mine);
	}
}
コード例 #5
0
ファイル: g_weapon.c プロジェクト: massivehaxxor/new-edge
/*
======================================================================
TESLA GENERATOR
======================================================================
*/
void teslaFire( gentity_t *self )
{
  trace_t tr;
  vec3_t origin, target;
  gentity_t *tent;

  if( !self->enemy )
    return;

  // Move the muzzle from the entity origin up a bit to fire over turrets
  VectorMA( muzzle, self->r.maxs[ 2 ], self->s.origin2, origin );

  // Don't aim for the center, aim at the top of the bounding box
  VectorCopy( self->enemy->s.origin, target );
  target[ 2 ] += self->enemy->r.maxs[ 2 ];

  // Trace to the target entity
  trap_Trace( &tr, origin, NULL, NULL, target, self->s.number, MASK_SHOT );
  if( tr.entityNum != self->enemy->s.number )
    return;

  // Client side firing effect
  self->s.eFlags |= EF_FIRING;

  // Deal damage
  if( self->enemy->takedamage )
  {
    vec3_t dir;

    VectorSubtract( target, origin, dir );
    G_Damage( self->enemy, self, self, dir, tr.endpos,
              TESLAGEN_DMG, 0, MOD_TESLAGEN );
  }

  // Send tesla zap trail
  tent = G_TempEntity( tr.endpos, EV_TESLATRAIL );
  tent->s.generic1 = self->s.number; // src
  tent->s.clientNum = self->enemy->s.number; // dest
}
コード例 #6
0
ファイル: g_target.c プロジェクト: GenaSG/etlegacy
void G_KillEnts(const char *target, gentity_t *ignore, gentity_t *killer, meansOfDeath_t mod)
{
	gentity_t *targ = NULL;

	while ((targ = G_FindByTargetname(targ, target)))
	{
		// make sure it isn't going to respawn or show any events
		targ->nextthink = 0;

		if (targ == ignore)
		{
			continue;
		}

		// script_movers should die!
		if (targ->s.eType == ET_MOVER && !Q_stricmp(targ->classname, "script_mover") && targ->die)
		{
			G_Damage(targ, killer, killer, NULL, NULL, 100000, DAMAGE_NO_PROTECTION, MOD_TELEFRAG);
			continue;
		}

		if (targ->s.eType == ET_CONSTRUCTIBLE)
		{
			if (killer)
			{
				G_AddKillSkillPointsForDestruction(killer, mod, &targ->constructibleStats);
			}
			targ->die(targ, killer, killer, targ->health, 0);
			continue;
		}

		trap_UnlinkEntity(targ);
		targ->nextthink = level.time + FRAMETIME;

		targ->use   = NULL;
		targ->touch = NULL;
		targ->think = G_FreeEntity;
	}
}
コード例 #7
0
/*
=================
G_KillBox

Kills all entities that would touch the proposed new positioning
of ent.  Ent should be unlinked before calling this!
=================
*/
void G_KillBox (gentity_t *ent) {
	int			i, num;
	int			touch[MAX_GENTITIES];
	gentity_t	*hit;
	vec3_t		mins, maxs;

	VectorAdd( ent->client->ps.origin, ent->r.mins, mins );
	VectorAdd( ent->client->ps.origin, ent->r.maxs, maxs );
	num = trap_EntitiesInBox( mins, maxs, touch, MAX_GENTITIES );

	for (i=0 ; i<num ; i++) {
		hit = &g_entities[touch[i]];
		if ( !hit->client ) {
			continue;
		}

		// nail it
		G_Damage ( hit, ent, ent, NULL, NULL,
			100000, DAMAGE_NO_PROTECTION, MOD_TELEFRAG);
	}

}
コード例 #8
0
ファイル: g_script.c プロジェクト: ETrun/ETrun
void script_mover_blocked(gentity_t *ent, gentity_t *other) {
	// remove it, we must not stop for anything or it will screw up script timing
	if (!other->client && other->s.eType != ET_CORPSE) {
		// /me slaps nerve
		// except CTF flags!!!!
		if (other->s.eType == ET_ITEM && other->item->giType == IT_TEAM) {
			Team_DroppedFlagThink(other);
			return;
		}
		G_TempEntity(other->s.origin, EV_ITEM_POP);
		G_FreeEntity(other);
		return;
	}

	// FIXME: we could have certain entities stop us, thereby "pausing" movement
	// until they move out the way. then we can just call the GotoMarker() again,
	// telling it that we are just now calling it for the first time, so it should
	// start us on our way again (theoretically speaking).

	// kill them
	G_Damage(other, ent, ent, NULL, NULL, 9999, 0, MOD_CRUSH);
}
コード例 #9
0
ファイル: g_weapon.c プロジェクト: wtfbbqhax/thz
/*
===============
lasGunFire
===============
*/
void lasGunFire( gentity_t *ent )
{
  trace_t   tr;
  vec3_t    end;
  gentity_t *tent;
  gentity_t *traceEnt;

  VectorMA( muzzle, 8192 * 16, forward, end );

  trap_Trace( &tr, muzzle, NULL, NULL, end, ent->s.number, MASK_SHOT );
  if( tr.surfaceFlags & SURF_NOIMPACT )
    return;

  traceEnt = &g_entities[ tr.entityNum ];

  // snap the endpos to integers, but nudged towards the line
  SnapVectorTowards( tr.endpos, muzzle );

  // send 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
  }
  else
  {
    tent = G_TempEntity( tr.endpos, EV_MISSILE_MISS );
    tent->s.eventParm = DirToByte( tr.plane.normal );
    tent->s.weapon = ent->s.weapon;
    tent->s.generic1 = ent->s.generic1; //weaponMode
  }

  if( traceEnt->takedamage )
    G_Damage( traceEnt, ent, ent, forward, tr.endpos, LASGUN_DAMAGE, 0, MOD_LASGUN );
}
コード例 #10
0
ファイル: g_trigger.c プロジェクト: Exosum/ETrun
/*QUAKED trigger_hurt (.5 .5 .5) ? START_OFF - SILENT NO_PROTECTION SLOW ONCE
Any entity that touches this will be hurt.
It does dmg points of damage each server frame
Targeting the trigger will toggle its on / off state.

SILENT			supresses playing the sound
SLOW			changes the damage rate to once per second
NO_PROTECTION	*nothing* stops the damage

"dmg"			default 5 (whole numbers only)

"life"	time this brush will exist if value is zero will live for ever ei 0.5 sec 2.sec
default is zero

the entity must be used first before it will count down its life
*/
void hurt_touch(gentity_t *self, gentity_t *other, trace_t *trace) {
	int dflags;

	// Nico, silent GCC
	(void)trace;

	if (!other->takedamage) {
		return;
	}

	if (self->timestamp > level.time) {
		return;
	}

	// Nico, make hurt triggers slow
	if (self->spawnflags & 16) {
		self->timestamp = level.time + 1000;
	} else {
		self->timestamp = level.time + FRAMETIME;
	}

	// play sound
	if (!(self->spawnflags & 4)) {
		G_Sound(other, self->noise_index);
	}

	if (self->spawnflags & 8) {
		dflags = DAMAGE_NO_PROTECTION;
	} else {
		dflags = 0;
	}

	G_Damage(other, self, self, NULL, NULL, self->damage, dflags, MOD_TRIGGER_HURT);

	if (self->spawnflags & 32) {
		self->touch = NULL;
	}
}
コード例 #11
0
/*
===============
AIFunc_LoperAttack1()

  Loper's close range melee attack
===============
*/
char *AIFunc_LoperAttack1( cast_state_t *cs ) {
	trace_t *tr;
	gentity_t *ent;
	int anim;
	//
	ent = &g_entities[cs->entityNum];
	//
	// draw the client-side lightning effect
	//ent->client->ps.eFlags |= EF_MONSTER_EFFECT;
	//
	// have we inflicted the damage?
	if ( cs->weaponFireTimes[WP_MONSTER_ATTACK1] > cs->thinkFuncChangeTime ) {
		// has the animation finished?
		if ( !ent->client->ps.legsTimer ) {
			return AIFunc_DefaultStart( cs );
		}
		return NULL;    // just wait for anim to finish
	}
	// ready to inflict damage?
	anim = ( ent->client->ps.legsAnim & ~ANIM_TOGGLEBIT ) - BG_AnimationIndexForString( "legs_extra", cs->entityNum );
	if ( cs->thinkFuncChangeTime < level.time - loperHitTimes[anim] ) {
		// check for damage
		// TTimo: gcc: suggests () around assignment used as truth value
		if ( ( tr = CheckMeleeAttack( &g_entities[cs->entityNum], LOPER_MELEE_RANGE, qfalse ) ) ) {
			G_Damage( &g_entities[tr->entityNum], ent, ent, vec3_origin, tr->endpos,
					  LOPER_MELEE_DAMAGE, 0, MOD_LOPER_HIT );
			// sound
			if ( anim == 0 ) {
				G_AddEvent( ent, EV_GENERAL_SOUND, G_SoundIndex( aiDefaults[ent->aiCharacter].soundScripts[ORDERSDENYSOUNDSCRIPT] ) );
			} else {
				G_AddEvent( ent, EV_GENERAL_SOUND, G_SoundIndex( aiDefaults[ent->aiCharacter].soundScripts[MISC1SOUNDSCRIPT] ) );
			}
		}
		cs->weaponFireTimes[WP_MONSTER_ATTACK1] = level.time;
	}

	return NULL;
}
コード例 #12
0
/*
================
G_ProcessFlare

If an player is close to the entity, hurt!
================
*/
void G_ProcessFlare(gentity_t *ent) {
    int i, total_entities, entityList[MAX_GENTITIES];
    vec3_t range, mins, maxs;
    gentity_t *target;

    if (level.time > ent->s.time + 30000)
    {
        ent->nextthink = level.time + 100;
        ent->think = G_ExplodeMissile;
        return;
    }

    // Set the next time to run this check (can be overwritten below)
    ent->nextthink = level.time + FLARE_CHECK_FREQUENCY;

    // Grab all entities around us
    VectorSet(range, FLARE_DETECT, FLARE_DETECT, FLARE_DETECT);
    VectorAdd(ent->s.origin, range, maxs);
    VectorSubtract(ent->s.origin, range, mins);

    total_entities = trap_EntitiesInBox(mins, maxs, entityList, MAX_GENTITIES);

    // Loop entities looking for an enemy body
    for(i=0; i<total_entities; i++) {
        target = &g_entities[entityList[i]];
        if(target->client) {
            if (G_Visible( ent, target, MASK_SHOT ))
            {
                // Found an enemy, hurt time!
                G_Damage( target, ent, ent->parent, NULL, ent->s.origin, ent->damage, 0, ent->methodOfDeath );

                //ent->nextthink = level.time + MINE_BOOM_TIME;
                //ent->think = G_ExplodeMissile;
                return;
            }
        }
    }
}
コード例 #13
0
ファイル: g_weapon.c プロジェクト: Kaperstone/warsow
/*
* W_Fire_Blade
*/
void W_Fire_Blade( edict_t *self, int range, vec3_t start, vec3_t angles, float damage, int knockback, int stun, int mod, int timeDelta )
{
	edict_t *event, *other = NULL;
	vec3_t end;
	trace_t	trace;
	int mask = MASK_SHOT;
	vec3_t dir;
	int dmgflags = 0;

	if( GS_Instagib() )
		damage = 9999;

	AngleVectors( angles, dir, NULL, NULL );
	VectorMA( start, range, dir, end );

	if( GS_RaceGametype() )
		mask = MASK_SOLID;

	G_Trace4D( &trace, start, NULL, NULL, end, self, MASK_SHOT, timeDelta );
	if( trace.ent == -1 )  //didn't touch anything
		return;

	// find out what touched
	other = &game.edicts[trace.ent];
	if( !other->takedamage ) // it was the world
	{
		// wall impact
		VectorMA( trace.endpos, -0.02, dir, end );
		event = G_SpawnEvent( EV_BLADE_IMPACT, 0, end );
		event->s.ownerNum = ENTNUM( self );
		VectorScale( trace.plane.normal, 1024, event->s.origin2 );
		event->r.svflags = SVF_TRANSMITORIGIN2;
		return;
	}

	// it was a player
	G_Damage( other, self, self, dir, dir, other->s.origin, damage, knockback, stun, dmgflags, mod );
}
コード例 #14
0
void shipboundary_touch( gentity_t *self, gentity_t *other, trace_t *trace )
{
	gentity_t *ent;

	if (!other || !other->inuse || !other->client ||
		other->s.number < MAX_CLIENTS ||
		!other->m_pVehicle)
	{ //only let vehicles touch
		return;
	}

	if ( other->client->ps.hyperSpaceTime && level.time - other->client->ps.hyperSpaceTime < HYPERSPACE_TIME )
	{//don't interfere with hyperspacing ships
		return;
	}

	ent = G_Find (NULL, FOFS(targetname), self->target);
	if (!ent || !ent->inuse)
	{ //this is bad
		trap->Error(ERR_DROP, "trigger_shipboundary has invalid target '%s'\n", self->target);
		return;
	}

	if (!other->client->ps.m_iVehicleNum || other->m_pVehicle->m_iRemovedSurfaces)
	{ //if a vehicle touches a boundary without a pilot in it or with parts missing, just blow the thing up
		G_Damage(other, other, other, NULL, other->client->ps.origin, 99999, DAMAGE_NO_PROTECTION, MOD_SUICIDE);
		return;
	}

	//make sure this sucker is linked so the prediction knows where to go
	trap->LinkEntity((sharedEntity_t *)ent);

	other->client->ps.vehTurnaroundIndex = ent->s.number;
	other->client->ps.vehTurnaroundTime = level.time + (self->genericValue1*2);

	//keep up the detailed checks for another 2 seconds
	self->genericValue7 = level.time + 2000;
}
コード例 #15
0
ファイル: g_weapon.c プロジェクト: ElderPlayerX/Afterwards
/*
================
ShotgunPellet
================
*/
void ShotgunPellet( vec3_t start, vec3_t end, gentity_t *ent ) {
	trace_t		tr;
	int			passent;
	gentity_t	*traceEnt;
	vec3_t		tr_start, tr_end;

	passent = ent->s.number;
	VectorCopy( start, tr_start );
	VectorCopy( end, tr_end );

	trap_Trace (&tr, tr_start, NULL, NULL, tr_end, passent, MASK_SHOT);
	traceEnt = &g_entities[ tr.entityNum ];

	// send bullet impact
	if ( tr.surfaceFlags & SURF_NOIMPACT ) {
		return;
	}

	if ( traceEnt->takedamage ) {
		shotEnt = traceEnt;
		G_Damage( traceEnt, ent, ent, forward, tr.endpos, weLi[ent->s.weapon].damage, 0, weLi[ent->s.weapon].mod);
	}
}
コード例 #16
0
ファイル: g_mover.c プロジェクト: AHPlankton/Quake-III-Arena
/*
================
Blocked_Door
================
*/
void Blocked_Door( gentity_t *ent, gentity_t *other ) {
	// remove anything other than a client
	if ( !other->client ) {
		// except CTF flags!!!!
		if( other->s.eType == ET_ITEM && other->item->giType == IT_TEAM ) {
			Team_DroppedFlagThink( other );
			return;
		}
		G_TempEntity( other->s.origin, EV_ITEM_POP );
		G_FreeEntity( other );
		return;
	}

	if ( ent->damage ) {
		G_Damage( other, ent, ent, NULL, NULL, ent->damage, 0, MOD_CRUSH );
	}
	if ( ent->spawnflags & 4 ) {
		return;		// crushers don't reverse
	}

	// reverse direction
	Use_BinaryMover( ent, ent, other );
}
コード例 #17
0
ファイル: g_weapon.cpp プロジェクト: Picmip/qfusion
void W_Fire_RandomBucket( edict_t *self, vec3_t start, vec3_t fv, vec3_t rv, vec3_t uv, int *seed, int count, 
	int hspread, int vspread, int range, float damage, int kick, int stun, int dflags, int mod, int timeDelta )
{
	int i;
	float r;
	float u;
	trace_t trace;

	for( i = 0; i < count; i++ ) {
		r = Q_crandom( seed ) * hspread;
		u = Q_crandom( seed ) * vspread;

		GS_TraceBullet( &trace, start, fv, rv, uv, r, u, range, ENTNUM( self ), timeDelta );
		if( trace.ent != -1 ) {
			if( game.edicts[trace.ent].takedamage ) {
				G_Damage( &game.edicts[trace.ent], self, self, fv, fv, trace.endpos, damage, kick, stun, dflags, mod );
			} else {
				if( !( trace.surfFlags & SURF_NOIMPACT ) ) {
				}
			}
		}
	}
}
コード例 #18
0
ファイル: g_weapon.c プロジェクト: SHOVELL/Unvanquished
// this should match CG_ShotgunPattern
void ShotgunPattern( vec3_t origin, vec3_t origin2, int seed, gentity_t *ent )
{
	int       i;
	float     r, u;
	vec3_t    end;
	vec3_t    forward, right, up;
	trace_t   tr;
	gentity_t *traceEnt;

	// derive the right and up vectors from the forward vector, because
	// the client won't have any other information
	VectorNormalize2( origin2, forward );
	PerpendicularVector( right, forward );
	CrossProduct( forward, right, up );

	// generate the "random" spread pattern
	for ( i = 0; i < SHOTGUN_PELLETS; i++ )
	{
		r = Q_crandom( &seed ) * SHOTGUN_SPREAD * 16;
		u = Q_crandom( &seed ) * SHOTGUN_SPREAD * 16;
		VectorMA( origin, SHOTGUN_RANGE, forward, end );
		VectorMA( end, r, right, end );
		VectorMA( end, u, up, end );

		trap_Trace( &tr, origin, NULL, NULL, end, ent->s.number, MASK_SHOT );
		traceEnt = &g_entities[ tr.entityNum ];

		// send bullet impact
		if ( !( tr.surfaceFlags & SURF_NOIMPACT ) )
		{
			if ( traceEnt->takedamage )
			{
				G_Damage( traceEnt, ent, ent, forward, tr.endpos,  SHOTGUN_DMG, 0, MOD_SHOTGUN );
			}
		}
	}
}
コード例 #19
0
ファイル: g_weapon.c プロジェクト: massivehaxxor/new-edge
/*
===============
G_CrushAttack
Should only be called if there was an impact between a tyrant and another player
===============
*/
void G_CrushAttack( gentity_t *ent, gentity_t *victim )
{
  vec3_t dir;
  float jump;
  int damage;

  if( !victim->takedamage ||
      ent->client->ps.origin[ 2 ] + ent->r.mins[ 2 ] <
      victim->s.origin[ 2 ] + victim->r.maxs[ 2 ] ||
      ( victim->client &&
        victim->client->ps.groundEntityNum == ENTITYNUM_NONE ) )
    return;

  // Deal velocity based damage to target
  jump = BG_Class( ent->client->ps.stats[ STAT_CLASS ] )->jumpMagnitude;
  damage = ( ent->client->pmext.fallVelocity + jump ) *
           -LEVEL4_CRUSH_DAMAGE_PER_V;

  if( damage < 0 )
    damage = 0;
    
  // Players also get damaged periodically
  if( victim->client &&
      ent->client->lastCrushTime + LEVEL4_CRUSH_REPEAT < level.time )
  {
    ent->client->lastCrushTime = level.time;
    damage += LEVEL4_CRUSH_DAMAGE;
  }
  
  if( damage < 1 )
    return;

  // Crush the victim over a period of time
  VectorSubtract( victim->s.origin, ent->client->ps.origin, dir );
  G_Damage( victim, ent, ent, dir, victim->s.origin, damage,
            DAMAGE_NO_LOCDAMAGE, MOD_LEVEL4_CRUSH );
}
コード例 #20
0
ファイル: g_breakable.cpp プロジェクト: 3ddy/Jedi-Academy
//-----------------------------------------------------
void funcGlassDie( gentity_t *self, gentity_t *inflictor, gentity_t *attacker, int damage, int mod,int dFlags,int hitLoc )
{
	vec3_t		verts[4], normal;

	// if a missile is stuck to us, blow it up so we don't look dumb....we could, alternately, just let the missile drop off??
	for ( int i = 0; i < MAX_GENTITIES; i++ )
	{
		if ( g_entities[i].s.groundEntityNum == self->s.number && ( g_entities[i].s.eFlags & EF_MISSILE_STICK ))
		{
			G_Damage( &g_entities[i], self, self, NULL, NULL, 99999, 0, MOD_CRUSH ); //?? MOD?
		}
	}

	// Really naughty cheating.  Put in an EVENT at some point...
	cgi_R_GetBModelVerts( cgs.inlineDrawModel[self->s.modelindex], verts, normal );
	CG_DoGlass( verts, normal, self->pos1, self->pos2, self->splashRadius );

	self->takedamage = qfalse;//stop chain reaction runaway loops

	G_SetEnemy( self, self->enemy );

	//NOTE: MUST do this BEFORE clearing contents, or you may not open the area portal!!!
	gi.AdjustAreaPortalState( self, qtrue );

	//So chunks don't get stuck inside me
	self->s.solid = 0;
	self->contents = 0;
	self->clipmask = 0;
	gi.linkentity(self); 

	if ( self->target && attacker != NULL )
	{
		G_UseTargets( self, attacker );
	}

	G_FreeEntity( self );
}
コード例 #21
0
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;
}
コード例 #22
0
ファイル: g_utils.c プロジェクト: Gireen/Unvanquished
/*
====================
G_KillBrushModel
====================
*/
void G_KillBrushModel( gentity_t *ent, gentity_t *activator )
{
  gentity_t *e;
  vec3_t mins, maxs;
  trace_t tr;

  for( e = &g_entities[ 0 ]; e < &g_entities[ level.num_entities ]; ++e )
  {
    if( !e->takedamage || !e->r.linked || !e->clipmask || ( e->client && e->client->noclip ) )
      continue;

    VectorAdd( e->r.currentOrigin, e->r.mins, mins );
    VectorAdd( e->r.currentOrigin, e->r.maxs, maxs );

    if( !trap_EntityContact( mins, maxs, ent ) )
      continue;

    trap_Trace( &tr, e->r.currentOrigin, e->r.mins, e->r.maxs,
                e->r.currentOrigin, e->s.number, e->clipmask );

    if( tr.entityNum != ENTITYNUM_NONE )
      G_Damage( e, ent, activator, NULL, NULL, 100000, DAMAGE_NO_PROTECTION, MOD_CRUSH );
  }
}
コード例 #23
0
ファイル: g_weapon.cpp プロジェクト: Picmip/qfusion
//Sunflower spiral with Fibonacci numbers
void W_Fire_SunflowerBucket( edict_t *self, vec3_t start, vec3_t fv, vec3_t rv, vec3_t uv, int *seed, int count, 
	int hspread, int vspread, int range, float damage, int kick, int stun, int dflags, int mod, int timeDelta ) {
	int i;
	float r;
	float u;
	float fi;
	trace_t trace;

	for( i = 0; i < count; i++ ) {
		fi = i * 2.4; //magic value creating Fibonacci numbers
		r = cos( (float)*seed + fi ) * hspread * sqrt( fi );
		u = sin( (float)*seed + fi ) * vspread * sqrt( fi );

		GS_TraceBullet( &trace, start, fv, rv, uv, r, u, range, ENTNUM( self ), timeDelta );
		if( trace.ent != -1 ) {
			if( game.edicts[trace.ent].takedamage ) {
				G_Damage( &game.edicts[trace.ent], self, self, fv, fv, trace.endpos, damage, kick, stun, dflags, mod );
			} else {
				if( !( trace.surfFlags & SURF_NOIMPACT ) ) {
				}
			}
		}
	}
}
コード例 #24
0
ファイル: g_weapon.c プロジェクト: themuffinator/fnq3
void G_BurnMeGood( gentity_t *self, gentity_t *body ) {
	// add the new damage
	body->flameQuota += 5;
	body->flameQuotaTime = level.time;

	// JPW NERVE -- yet another flamethrower damage model, trying to find a feels-good damage combo that isn't overpowered
	if ( body->lastBurnedFrameNumber != level.framenum ) {
		G_Damage( body, self->parent, self->parent, vec3_origin, self->r.currentOrigin, 5, 0, MOD_FLAMETHROWER ); // was 2 dmg in release ver, hit avg. 2.5 times per frame
		body->lastBurnedFrameNumber = level.framenum;
	}
	// jpw

	// make em burn
	if ( body->client && ( body->health <= 0 || body->flameQuota > 0 ) ) { // JPW NERVE was > FLAME_THRESHOLD
		if ( body->s.onFireEnd < level.time ) {
			body->s.onFireStart = level.time;
		}

		body->s.onFireEnd = level.time + FIRE_FLASH_TIME;
		body->flameBurnEnt = self->r.ownerNum;
		// add to playerState for client-side effect
		body->client->ps.onFireStart = level.time;
	}
}
コード例 #25
0
ファイル: g_weapon.cpp プロジェクト: Picmip/qfusion
/*
* 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 ) {
		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] ) );
}
コード例 #26
0
ファイル: g_weapon.cpp プロジェクト: Picmip/qfusion
/*
* W_Fire_Bullet
*/
void W_Fire_Bullet( edict_t *self, vec3_t start, vec3_t fv, vec3_t rv, vec3_t uv, int seed, int range, 
	int hspread, int vspread, float damage, int knockback, int stun, int mod, int timeDelta ) {
	edict_t *event;
	float r, u;
	double alpha, s;
	trace_t trace;
	int dmgflags = DAMAGE_STUN_CLAMP | DAMAGE_KNOCKBACK_SOFT;

	if( GS_Instagib() ) {
		damage = 9999;
	}

	// send the event
	event = G_SpawnEvent( EV_FIRE_BULLET, seed, start );
	event->s.ownerNum = ENTNUM( self );
	VectorCopy( fv, event->s.origin2 );
	VectorCopy( rv, event->s.origin3 );
	event->s.weapon = WEAP_MACHINEGUN;
	event->s.firemode = ( mod == MOD_MACHINEGUN_S ) ? FIRE_MODE_STRONG : FIRE_MODE_WEAK;

	// circle shape
	alpha = M_PI * Q_crandom( &seed ); // [-PI ..+PI]
	s = fabs( Q_crandom( &seed ) ); // [0..1]
	r = s * cos( alpha ) * hspread;
	u = s * sin( alpha ) * vspread;

	GS_TraceBullet( &trace, start, fv, rv, uv, r, u, range, ENTNUM( self ), timeDelta );
	if( trace.ent != -1 ) {
		if( game.edicts[trace.ent].takedamage ) {
			G_Damage( &game.edicts[trace.ent], self, self, fv, fv, trace.endpos, damage, knockback, stun, dmgflags, mod );
		} else {
			if( !( trace.surfFlags & SURF_NOIMPACT ) ) {
			}
		}
	}
}
コード例 #27
0
ファイル: g_fx.cpp プロジェクト: LTolosa/Jedi-Outcast
//------------------------------------------
void fx_target_beam_fire( gentity_t *ent )
{
	trace_t		trace;
	vec3_t		dir, org, end;
	int			ignore;
	qboolean	open;

	if ( !ent->enemy || !ent->enemy->inuse )
	{//info_null most likely
		ignore = ent->s.number;
		ent->enemy = NULL;
		VectorCopy( ent->s.origin2, org );
	}
	else
	{
		ignore = ent->enemy->s.number;
		VectorCopy( ent->enemy->currentOrigin, org );
	}

	VectorCopy( org, ent->s.origin2 );
	VectorSubtract( org, ent->s.origin, dir );
	VectorNormalize( dir );

	gi.trace( &trace, ent->s.origin, NULL, NULL, org, ENTITYNUM_NONE, MASK_SHOT );//ignore
	if ( ent->spawnflags & 2 )
	{
		open = qtrue;
		VectorCopy( org, end );
	}
	else
	{
		open = qfalse;
		VectorCopy( trace.endpos, end );
	}

	if ( trace.fraction < 1.0 )
	{
		if ( trace.entityNum < ENTITYNUM_WORLD )
		{
			gentity_t *victim = &g_entities[trace.entityNum];
			if ( victim && victim->takedamage )
			{
				if ( ent->spawnflags & 4 ) // NO_KNOCKBACK
				{
					G_Damage( victim, ent, ent->activator, dir, trace.endpos, ent->damage, DAMAGE_NO_KNOCKBACK, MOD_UNKNOWN );
				}
				else
				{
					G_Damage( victim, ent, ent->activator, dir, trace.endpos, ent->damage, 0, MOD_UNKNOWN );
				}
			}
		}
	}

	G_AddEvent( ent, EV_TARGET_BEAM_DRAW, ent->fxID );
	VectorCopy( end, ent->s.origin2 );

	if ( open )
	{
		VectorScale( dir, -1, ent->pos1 );
	}
	else
	{
		VectorCopy( trace.plane.normal, ent->pos1 );
	}

	ent->e_ThinkFunc = thinkF_fx_target_beam_think;
	ent->nextthink = level.time + FRAMETIME;
}
コード例 #28
0
ファイル: g_weapon.c プロジェクト: jangroothuijse/openpromode
void Weapon_LightningFire( gentity_t *ent ) {
	trace_t		tr;
	vec3_t		end;
#if 1
	vec3_t impactpoint, bouncedir;
#endif
	gentity_t	*traceEnt, *tent;
	int			damage, i, passent;

	damage = 8 * s_quadFactor;

	passent = ent->s.number;
	for (i = 0; i < 10; i++) {
		VectorMA( muzzle, LIGHTNING_RANGE, forward, end );

		trap_Trace( &tr, muzzle, NULL, NULL, end, passent, MASK_SHOT );

#if 1
		// if not the first trace (the lightning bounced of an invulnerability sphere)
		if (i) {
			// add bounced off lightning bolt temp entity
			// the first lightning bolt is a cgame only visual
			//
			tent = G_TempEntity( muzzle, EV_LIGHTNINGBOLT );
			VectorCopy( tr.endpos, end );
			SnapVector( end );
			VectorCopy( end, tent->s.origin2 );
		}
#endif
		if ( tr.entityNum == ENTITYNUM_NONE ) {
			return;
		}

		traceEnt = &g_entities[ tr.entityNum ];

		if ( traceEnt->takedamage) {
#if 1
			if ( traceEnt->client && traceEnt->client->invulnerabilityTime > level.time ) {
				if (G_InvulnerabilityEffect( traceEnt, forward, tr.endpos, impactpoint, bouncedir )) {
					G_BounceProjectile( muzzle, impactpoint, bouncedir, end );
					VectorCopy( impactpoint, muzzle );
					VectorSubtract( end, impactpoint, forward );
					VectorNormalize(forward);
					// the player can hit him/herself with the bounced lightning
					passent = ENTITYNUM_NONE;
				}
				else {
					VectorCopy( tr.endpos, muzzle );
					passent = traceEnt->s.number;
				}
				continue;
			}
			else {
				G_Damage( traceEnt, ent, ent, forward, tr.endpos,
					damage, 0, MOD_LIGHTNING);
			}
#else
				G_Damage( traceEnt, ent, ent, forward, tr.endpos,
					damage, 0, MOD_LIGHTNING);
#endif
		}

		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;
			if( LogAccuracyHit( traceEnt, ent ) ) {
				ent->client->accuracy_hits++;
			}
		} else if ( !( tr.surfaceFlags & SURF_NOIMPACT ) ) {
			tent = G_TempEntity( tr.endpos, EV_MISSILE_MISS );
			tent->s.eventParm = DirToByte( tr.plane.normal );
		}

		break;
	}
}
コード例 #29
0
ファイル: g_weapon.c プロジェクト: jangroothuijse/openpromode
void Bullet_Fire (gentity_t *ent, float spread, int damage ) {
	trace_t		tr;
	vec3_t		end;
#if 1
	vec3_t		impactpoint, bouncedir;
#endif
	float		r, f, d;
	float		u;
	gentity_t	*tent;
	gentity_t	*traceEnt;
	int			i, passent;

	vec3_t		forward, right, up;

	AngleVectors (ent->client->ps.viewangles, forward, right, up);
	CalcMuzzlePoint ( ent, forward, right, up, muzzle );
	ent->client->accuracy_shots++;
	f = ((float)(ent->client->accuracy_shots % SPIRAL_SIZE)) / SPIRAL_SIZE; // 0 >= f >= 1
	d = (f+(1/SPIRAL_SIZE)) * 2.0 * M_PI;

	damage *= s_quadFactor;

	//Com_Printf("f: %f, d: %f\n, a: %i", f, d, ent->client->accuracy_shots);

	u = sin(d) * (f * spread);
	r = cos(d) * (f * spread);

	//Com_Printf("end1 : [%f, %f, %f]\n", end[0], end[1], end[2]);

	VectorMA (muzzle, 8192, forward, end);

	//Com_Printf("end2 : [%f, %f, %f]\n", end[0], end[1], end[2]);
	//Com_Printf("right : [%f, %f, %f]\n", right[0], right[1], right[2]);
	VectorMA (end, r, right, end);

	//Com_Printf("end3 : [%f, %f, %f]\n", end[0], end[1], end[2]);
	//Com_Printf("up : [%f, %f, %f]\n", up[0], up[1], up[2]);

	VectorMA (end, u, up, end);

	//Com_Printf("end4 : [%f, %f, %f]\n", end[0], end[1], end[2]);

	passent = ent->s.number;
	for (i = 0; i < 10; i++) {

		trap_Trace (&tr, muzzle, NULL, NULL, end, passent, MASK_SHOT);
		if ( tr.surfaceFlags & SURF_NOIMPACT ) {
			return;
		}

		traceEnt = &g_entities[ tr.entityNum ];

		// snap the endpos to integers, but nudged towards the line
		SnapVectorTowards( tr.endpos, muzzle );

		// send bullet impact
		if ( traceEnt->takedamage && traceEnt->client ) {
			tent = G_TempEntity( tr.endpos, EV_BULLET_HIT_FLESH );
			tent->s.eventParm = traceEnt->s.number;
			if( LogAccuracyHit( traceEnt, ent ) ) {
				ent->client->accuracy_hits++;
			}
		} else {
			tent = G_TempEntity( tr.endpos, EV_BULLET_HIT_WALL );
			tent->s.eventParm = DirToByte( tr.plane.normal );
		}
		tent->s.otherEntityNum = ent->s.number;

		if ( traceEnt->takedamage) {
#if 1
			if ( traceEnt->client && traceEnt->client->invulnerabilityTime > level.time ) {
				if (G_InvulnerabilityEffect( traceEnt, forward, tr.endpos, impactpoint, bouncedir )) {
					G_BounceProjectile( muzzle, impactpoint, bouncedir, end );
					VectorCopy( impactpoint, muzzle );
					// the player can hit him/herself with the bounced rail
					passent = ENTITYNUM_NONE;
				}
				else {
					VectorCopy( tr.endpos, muzzle );
					passent = traceEnt->s.number;
				}
				continue;
			}
			else {
#endif
				G_Damage( traceEnt, ent, ent, forward, tr.endpos,
					damage, 0, MOD_MACHINEGUN);
#if 1
			}
#endif
		}
		break;
	}
}
コード例 #30
0
ファイル: g_weapon.c プロジェクト: jangroothuijse/openpromode
void weapon_railgun_fire (gentity_t *ent) {
	vec3_t		end;
	trace_t		trace;
	gentity_t	*tent;
	gentity_t	*traceEnt;
	int			damage;
	int			i;
	int			hits;
	int			unlinked;
	int			passent;
	gentity_t	*unlinkedEntities[MAX_RAIL_HITS];

	if (0) {
		tent = fire_bfg (ent, muzzle, forward);
		tent->damage *= s_quadFactor;
		tent->splashDamage *= s_quadFactor;
		return;
	}

	damage = 80 * s_quadFactor;

	VectorMA (muzzle, 8192, forward, end);

	// trace only against the solids, so the railgun will go through people
	unlinked = 0;
	hits = 0;
	passent = ent->s.number;
	do {
		trap_Trace (&trace, muzzle, NULL, NULL, end, passent, MASK_SHOT );
		if ( trace.entityNum >= ENTITYNUM_MAX_NORMAL ) {
			break;
		}
		traceEnt = &g_entities[ trace.entityNum ];
		if ( traceEnt->takedamage ) {

			if( LogAccuracyHit( traceEnt, ent ) ) {
				hits++;
			}
			G_Damage (traceEnt, ent, ent, forward, trace.endpos, damage, 0, MOD_RAILGUN);

		}
		if ( trace.contents & CONTENTS_SOLID ) {
			break;		// we hit something solid enough to stop the beam
		}
		// unlink this entity, so the next trace will go past it
		trap_UnlinkEntity( traceEnt );
		unlinkedEntities[unlinked] = traceEnt;
		unlinked++;
	} while ( unlinked < MAX_RAIL_HITS );

	// link back in any entities we unlinked
	for ( i = 0 ; i < unlinked ; i++ ) {
		trap_LinkEntity( unlinkedEntities[i] );
	}

	// the final trace endpos will be the terminal point of the rail trail

	// snap the endpos to integers to save net bandwidth, but nudged towards the line
	SnapVectorTowards( trace.endpos, muzzle );

	// send railgun beam effect
	tent = G_TempEntity( trace.endpos, EV_RAILTRAIL );

	// set player number for custom colors on the railtrail
	tent->s.clientNum = ent->s.clientNum;

	VectorCopy( muzzle, tent->s.origin2 );
	// move origin a bit to come closer to the drawn gun muzzle
	VectorMA( tent->s.origin2, 4, right, tent->s.origin2 );
	VectorMA( tent->s.origin2, -1, up, tent->s.origin2 );

	// no explosion at end if SURF_NOIMPACT, but still make the trail
	if ( trace.surfaceFlags & SURF_NOIMPACT ) {
		tent->s.eventParm = 255;	// don't make the explosion at the end
	} else {
		tent->s.eventParm = DirToByte( trace.plane.normal );
	}
	tent->s.clientNum = ent->s.clientNum;

	// give the shooter a reward sound if they have made two railgun hits in a row
	if ( hits == 0 ) {
		// complete miss
		ent->client->accurateCount = 0;
	} else {
		// check for "impressive" reward sound
		ent->client->accurateCount += hits;
		if ( ent->client->accurateCount >= 2 ) {
			ent->client->accurateCount -= 2;
			ent->client->ps.persistant[PERS_IMPRESSIVE_COUNT]++;
			// add the sprite over the player's head
			ent->client->ps.eFlags &= ~(EF_AWARD_IMPRESSIVE | EF_AWARD_EXCELLENT | EF_AWARD_GAUNTLET | EF_AWARD_ASSIST | EF_AWARD_DEFEND | EF_AWARD_CAP );
			ent->client->ps.eFlags |= EF_AWARD_IMPRESSIVE;
			ent->client->rewardTime = level.time + REWARD_SPRITE_TIME;
		}
		ent->client->accuracy_hits++;
	}

}