Esempio n. 1
0
/**
 * Adds momentum for building a buildable.
 *
 * Will save the reward with the buildable.
 */
float G_AddMomentumForBuilding(gentity_t* buildable) {
    float value, reward;
    team_t team;
    gentity_t* builder;

    if (!buildable || buildable->s.eType != ET_BUILDABLE) {
        return 0.0f;
    }

    value = BG_Buildable(buildable->s.modelindex)->buildPoints;
    team = BG_Buildable(buildable->s.modelindex)->team;

    if (buildable->builtBy->slot != -1) {
        builder = &g_entities[buildable->builtBy->slot];
    } else {
        builder = nullptr;
    }

    reward = AddMomentum(CONF_BUILDING, team, value, builder, false);

    // Save reward with buildable so it can be reverted
    buildable->momentumEarned = reward;

    return reward;
}
Esempio n. 2
0
/*
===============
CG_BuildableInRange
===============
*/
static entityState_t *CG_BuildableInRange( playerState_t *ps, float *healthFraction )
{
	vec3_t        view, point;
	trace_t       trace;
	entityState_t *es;
	int           health;

	AngleVectors( cg.refdefViewAngles, view, nullptr, nullptr );
	VectorMA( cg.refdef.vieworg, 64, view, point );
	CG_Trace( &trace, cg.refdef.vieworg, nullptr, nullptr, point, ps->clientNum, MASK_SHOT, 0 );

	es = &cg_entities[ trace.entityNum ].currentState;

	if ( healthFraction )
	{
		health = es->generic1;
		*healthFraction = ( float ) health / BG_Buildable( es->modelindex )->health;
	}

	if ( es->eType == ET_BUILDABLE &&
	     ps->persistant[ PERS_TEAM ] == BG_Buildable( es->modelindex )->team )
	{
		return es;
	}
	else
	{
		return nullptr;
	}
}
Esempio n. 3
0
/*
==================
CG_Creep
==================
*/
static void CG_Creep( centity_t *cent )
{
  int           msec;
  float         size, frac;
  trace_t       tr;
  vec3_t        temp, origin;
  int           scaleUpTime = BG_Buildable( cent->currentState.modelindex )->buildTime;
  int           time;
  // int creepSize;
  time = cent->currentState.time;

  //should the creep be growing or receding?
  if( time >= 0 )
  {
    msec = cg.time - time;
    if( msec >= 0 && msec < scaleUpTime )
      frac = (float)msec / scaleUpTime;
    else
      frac = 1.0f;
  }
  else if( time < 0 )
  {
    msec = cg.time + time;
    if( msec >= 0 && msec < CREEP_SCALEDOWN_TIME )
      frac = 1.0f - ( (float)msec / CREEP_SCALEDOWN_TIME );
    else
      frac = 0.0f;
  }

  VectorCopy( cent->currentState.origin2, temp );
  VectorScale( temp, -CREEP_DISTANCE, temp );
  VectorAdd( temp, cent->lerpOrigin, temp );

  
  
  CG_Trace( &tr, cent->lerpOrigin, NULL, NULL, temp, cent->currentState.number, MASK_PLAYERSOLID );
  VectorCopy( tr.endpos, origin );
  

//  size = CREEP_SIZE * frac;
size = BG_Buildable( cent->currentState.modelindex )->creepSize * frac;

  if( size > 0.0f && tr.fraction < 1.0f )
    CG_ImpactMark( cgs.media.creepShader, //qhandle_t markShader
								  origin, //const vec3_t origin 
			  cent->currentState.origin2, //const vec3_t dir
									0.0f, //float orientation
									1.0f, //red
									1.0f, //green
									1.0f, //blue
									1.0f, //float alpha
								  qtrue, //qboolean alphaFade
								    size, //float radius
								   qtrue);//qboolean temporary
								   
					   

}
Esempio n. 4
0
/*
==================
CG_BuildableParticleEffects
==================
*/
static void CG_BuildableParticleEffects( centity_t *cent )
{
  entityState_t   *es = &cent->currentState;
  team_t          team = BG_Buildable( es->modelindex )->team;
  int             health = es->generic1;
  float           healthFrac = (float)health / BG_Buildable( es->modelindex )->health;

  if( !( es->eFlags & EF_B_SPAWNED ) )
    return;
	
	
	    //ORGANIC BULB LIGHT / BA_H_LIGHT - VIA PS
    if( es->modelindex == BA_A_ORGANIC_BULB )
  {
    if( !CG_IsParticleSystemValid( &cent->buildablePS ) )
    {
      cent->buildablePS = CG_SpawnNewParticleSystem( cgs.media.organicbulbPS );

      if( CG_IsParticleSystemValid( &cent->buildablePS ) )
      {
        CG_SetAttachmentCent( &cent->buildablePS->attachment, cent );
        CG_AttachToCent( &cent->buildablePS->attachment );
      }
    }
  }

  else if( team == TEAM_HUMANS )
  {
    if( healthFrac < 0.33f && !CG_IsParticleSystemValid( &cent->buildablePS ) )
    {
      cent->buildablePS = CG_SpawnNewParticleSystem( cgs.media.humanBuildableDamagedPS );

      if( CG_IsParticleSystemValid( &cent->buildablePS ) )
      {
        CG_SetAttachmentCent( &cent->buildablePS->attachment, cent );
        CG_AttachToCent( &cent->buildablePS->attachment );
      }
    }
    else if( healthFrac >= 0.33f && CG_IsParticleSystemValid( &cent->buildablePS ) )
      CG_DestroyParticleSystem( &cent->buildablePS );
  }
  else if( team == TEAM_ALIENS )
  {
    if( healthFrac < 0.33f && !CG_IsParticleSystemValid( &cent->buildablePS ) )
    {
      cent->buildablePS = CG_SpawnNewParticleSystem( cgs.media.alienBuildableDamagedPS );

      if( CG_IsParticleSystemValid( &cent->buildablePS ) )
      {
        CG_SetAttachmentCent( &cent->buildablePS->attachment, cent );
        CG_SetParticleSystemNormal( cent->buildablePS, es->origin2 );
        CG_AttachToCent( &cent->buildablePS->attachment );
      }
    }
    else if( healthFrac >= 0.33f && CG_IsParticleSystemValid( &cent->buildablePS ) )
      CG_DestroyParticleSystem( &cent->buildablePS );
  }
}
Esempio n. 5
0
/*
================
G_Bounce

================
*/
static void G_Bounce( gentity_t *ent, trace_t *trace )
{
	vec3_t   velocity;
	float    dot;
	int      hitTime;
	float    minNormal;
	qboolean invert = qfalse;

	// reflect the velocity on the trace plane
	hitTime = level.previousTime + ( level.time - level.previousTime ) * trace->fraction;
	BG_EvaluateTrajectoryDelta( &ent->s.pos, hitTime, velocity );
	dot = DotProduct( velocity, trace->plane.normal );
	VectorMA( velocity, -2 * dot, trace->plane.normal, ent->s.pos.trDelta );

	if ( ent->s.eType == ET_BUILDABLE )
	{
		minNormal = BG_Buildable( ent->s.modelindex )->minNormal;
		invert = BG_Buildable( ent->s.modelindex )->invertNormal;
	}
	else
	{
		minNormal = 0.707f;
	}

	// cut the velocity to keep from bouncing forever
	if ( ( trace->plane.normal[ 2 ] >= minNormal ||
	       ( invert && trace->plane.normal[ 2 ] <= -minNormal ) ) &&
	     trace->entityNum == ENTITYNUM_WORLD )
	{
		VectorScale( ent->s.pos.trDelta, ent->physicsBounce, ent->s.pos.trDelta );
	}
	else
	{
		VectorScale( ent->s.pos.trDelta, 0.3f, ent->s.pos.trDelta );
	}

	if ( VectorLength( ent->s.pos.trDelta ) < 10 )
	{
		VectorMA( trace->endpos, 0.5f, trace->plane.normal, trace->endpos );  // make sure it is off ground
		G_SetOrigin( ent, trace->endpos );
		ent->s.groundEntityNum = trace->entityNum;
		VectorCopy( trace->plane.normal, ent->s.origin2 );
		VectorSet( ent->s.pos.trDelta, 0.0f, 0.0f, 0.0f );
		return;
	}

	VectorCopy( ent->r.currentOrigin, ent->s.pos.trBase );
	VectorAdd( ent->r.currentOrigin, trace->plane.normal, ent->r.currentOrigin );
	ent->s.pos.trTime = level.time;
}
Esempio n. 6
0
/*
===============
CG_HumanCkitText
===============
*/
static void CG_HumanCkitText( char *text, playerState_t *ps )
{
  buildable_t   buildable = ps->stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT;
  entityState_t *es;

  if( buildable > BA_NONE )
  {
    Q_strcat( text, MAX_TUTORIAL_TEXT,
        va( "Press %s to place the %s\n",
          CG_KeyNameForCommand( "+attack" ),
          BG_Buildable( buildable )->humanName ) );

    Q_strcat( text, MAX_TUTORIAL_TEXT,
        va( "Press %s to cancel placing the %s\n",
          CG_KeyNameForCommand( "+button5" ),
          BG_Buildable( buildable )->humanName ) );
  }
  else
  {
    Q_strcat( text, MAX_TUTORIAL_TEXT,
        va( "Press %s to build a structure\n",
          CG_KeyNameForCommand( "+attack" ) ) );
  }

  if( ( es = CG_BuildableInRange( ps, NULL ) ) )
  {
    if( cgs.markDeconstruct )
    {
      if( es->eFlags & EF_B_MARKED )
      {
        Q_strcat( text, MAX_TUTORIAL_TEXT,
            va( "Press %s to unmark this structure\n",
              CG_KeyNameForCommand( "deconstruct" ) ) );
      }
      else
      {
        Q_strcat( text, MAX_TUTORIAL_TEXT,
            va( "Press %s to mark this structure\n",
              CG_KeyNameForCommand( "deconstruct" ) ) );
      }
    }
    else
    {
      Q_strcat( text, MAX_TUTORIAL_TEXT,
          va( "Press %s to destroy this structure\n",
            CG_KeyNameForCommand( "deconstruct" ) ) );
    }
  }
}
Esempio n. 7
0
/**
 * Removes momentum for deconstructing a buildable.
 */
float G_RemoveMomentumForDecon( gentity_t *buildable, gentity_t *deconner )
{
	float     value;
	team_t    team;

	// sanity check buildable
	if ( !buildable || buildable->s.eType != entityType_t::ET_BUILDABLE )
	{
		return 0.0f;
	}
	team = BG_Buildable( buildable->s.modelindex )->team;

	if ( buildable->momentumEarned )
	{
		value = buildable->momentumEarned;
	}
	else
	{
		// assume the buildable has just been placed
		value = G_PredictMomentumForBuilding( buildable );
	}

	// Remove only partial momentum as the lost health fraction awards momentum to the enemy.
	value *= buildable->entity->Get<HealthComponent>()->HealthFraction();

	return AddMomentum( CONF_DECONSTRUCTING, team, -value, deconner, false );
}
Esempio n. 8
0
/*
===============
buildFire
===============
*/
void buildFire( gentity_t *ent, dynMenu_t menu )
{
	//TODO find a solution to move dependency of ent->s.number and &ent->eventTime outside this function
	playerState_t *ps=&ent->client->ps;
	buildable_t buildable = ( ps->stats[ STAT_BUILDABLE ]
	                          & ~SB_VALID_TOGGLEBIT );

	if ( buildable > BA_NONE )
	{
		if ( ps->stats[ STAT_MISC ] > 0 )
		{
			G_AddPlayerEvent( ps, EV_BUILD_DELAY, ps->clientNum, ent->s.number, &ent->eventTime );
			return;
		}

		if ( G_BuildIfValid( ent, buildable ) )
		{
			if ( !g_cheats.integer )
			{
				ps->stats[ STAT_MISC ] +=
				  BG_Buildable( buildable )->buildTime;
			}

			ps->stats[ STAT_BUILDABLE ] = BA_NONE;
		}

		return;
	}

	G_TriggerMenu( ps->clientNum, menu );
}
static void CG_Rocket_DFCMHumanBuildables( int handle, const char *data )
{
	buildable_t buildable = ( buildable_t ) atoi( Info_ValueForKey( data, "1" ) );
	const char *Class = "";
	const char *Icon = "";
	const char *action = "";
	int value, valueMarked;

	value = cg.snap->ps.persistant[ PERS_BP ];
	valueMarked = cg.snap->ps.persistant[ PERS_MARKEDBP ];

	if ( BG_BuildableDisabled( buildable ) || !BG_BuildableUnlocked( buildable ) )
	{
		Class = "locked";
		//Padlock icon. UTF-8 encoding of \uf023
		Icon = "<icon>\xEF\x80\xA3</icon>";
	}
	else if ( BG_Buildable( buildable )->buildPoints > value + valueMarked )
	{
		Class = "expensive";
		//$1 bill icon. UTF-8 encoding of \uf0d6
		Icon = "<icon>\xEF\x83\x96</icon>";
	}
	else
	{
		Class = "available";
		action = va( "onClick='Cmd.exec(\"build %s\") Events.pushevent(\"hide %s\", event)'", BG_Buildable( buildable )->name, rocketInfo.menu[ ROCKETMENU_HUMANBUILD ].id );
	}

	Rocket_DataFormatterFormattedData( handle, va( "<button class='%s' onMouseover='Events.pushevent(\"setDS humanBuildList default %s\", event)' %s>%s<img src='/%s'/></button>", Class, Info_ValueForKey( data, "2" ), action, Icon, CG_GetShaderNameFromHandle( cg_buildables[ buildable ].buildableIcon ) ), false );
}
Esempio n. 10
0
/*
===============
buildFire
===============
*/
void buildFire( gentity_t *ent, dynMenu_t menu )
{
  buildable_t buildable = ( ent->client->ps.stats[ STAT_BUILDABLE ]
                            & ~SB_VALID_TOGGLEBIT );

  if( buildable > BA_NONE )
  {
    if( ent->client->ps.stats[ STAT_BUILD_TIMER ] > 0 )
    {
      G_AddEvent( ent, EV_BUILD_DELAY, ent->client->ps.clientNum );
      return;
    }

    if( G_BuildIfValid( ent, buildable ) )
    {
      if( !g_cheats.integer )
      {
        ent->client->ps.stats[ STAT_BUILD_TIMER ] +=
          BG_Buildable( buildable )->buildTime;
      }

      ent->client->ps.stats[ STAT_BUILDABLE ] = BA_NONE;
    }

    return;
  }

  G_TriggerMenu( ent->client->ps.clientNum, menu );
}
Esempio n. 11
0
/*
================
G_SelectSpawnBuildable

find the nearest buildable of the right type that is
spawned/healthy/unblocked etc.
================
*/
static gentity_t *G_SelectSpawnBuildable( vec3_t preference, buildable_t buildable )
{
    gentity_t *search, *spot;

    search = spot = NULL;

    while( ( search = G_Find( search, FOFS( classname ),
                              BG_Buildable( buildable )->entityName ) ) != NULL )
    {
        if( !search->spawned )
            continue;

        if( search->health <= 0 )
            continue;

        if( !search->s.groundEntityNum )
            continue;

        if( search->clientSpawnTime > 0 )
            continue;

        if( G_CheckSpawnPoint( search->s.number, search->s.origin,
                               search->s.origin2, buildable, NULL ) != NULL )
            continue;

        if( !spot || DistanceSquared( preference, search->s.origin ) <
                DistanceSquared( preference, spot->s.origin ) )
            spot = search;
    }

    return spot;
}
Esempio n. 12
0
/**
 * Predicts the momentum reward for building a buildable.
 *
 * Is used for the buildlog entry, which is written before the actual reward
 *happens.
 * Also used to calculate the deconstruction penalty for preplaced buildables.
 */
float G_PredictMomentumForBuilding(gentity_t* buildable) {
    if (!buildable || buildable->s.eType != ET_BUILDABLE) {
        return 0.0f;
    }

    return BG_Buildable(buildable->s.modelindex)->buildPoints *
           MomentumMod(CONF_BUILDING);
}
Esempio n. 13
0
/*
===============
G_FindZapChainTargets
===============
*/
static void G_FindZapChainTargets( zap_t *zap )
{
	gentity_t *ent = zap->targets[ 0 ]; // the source
	int       entityList[ MAX_GENTITIES ];
	vec3_t    range = { LEVEL2_AREAZAP_CHAIN_RANGE,
	                    LEVEL2_AREAZAP_CHAIN_RANGE,
	                    LEVEL2_AREAZAP_CHAIN_RANGE
	                  };
	vec3_t    mins, maxs;
	int       i, num;
	gentity_t *enemy;
	trace_t   tr;
	float     distance;

	VectorAdd( ent->s.origin, range, maxs );
	VectorSubtract( ent->s.origin, range, mins );

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

	for ( i = 0; i < num; i++ )
	{
		enemy = &g_entities[ entityList[ i ] ];

		// don't chain to self; noclippers can be listed, don't chain to them either
		if ( enemy == ent || ( enemy->client && enemy->client->noclip ) )
		{
			continue;
		}

		distance = Distance( ent->s.origin, enemy->s.origin );

		if ( ( ( enemy->client &&
		         enemy->client->ps.stats[ STAT_TEAM ] == TEAM_HUMANS ) ||
		       ( enemy->s.eType == ET_BUILDABLE &&
		         BG_Buildable( enemy->s.modelindex )->team == TEAM_HUMANS ) ) &&
		     enemy->health > 0 && // only chain to living targets
		     distance <= LEVEL2_AREAZAP_CHAIN_RANGE )
		{
			// world-LOS check: trace against the world, ignoring other BODY entities
			trap_Trace( &tr, ent->s.origin, NULL, NULL,
			            enemy->s.origin, ent->s.number, CONTENTS_SOLID );

			if ( tr.entityNum == ENTITYNUM_NONE )
			{
				zap->targets[ zap->numTargets ] = enemy;
				zap->distances[ zap->numTargets ] = distance;

				if ( ++zap->numTargets >= LEVEL2_AREAZAP_MAX_TARGETS )
				{
					return;
				}
			}
		}
	}
}
Esempio n. 14
0
int G_BuildableDeconValue(gentity_t *ent)
{
	HealthComponent* healthComponent = ent->entity->Get<HealthComponent>();

	if (!healthComponent->Alive()) {
		return 0;
	}

	return (int)roundf((float)BG_Buildable(ent->s.modelindex)->buildPoints
	                   * healthComponent->HealthFraction());
}
Esempio n. 15
0
static void FireBuild( gentity_t *self, dynMenu_t menu )
{
	buildable_t buildable;

	if ( !self->client )
	{
		return;
	}

	buildable = (buildable_t) ( self->client->ps.stats[ STAT_BUILDABLE ] & SB_BUILDABLE_MASK );

	// open build menu
	if ( buildable <= BA_NONE )
	{
		G_TriggerMenu( self->client->ps.clientNum, menu );
		return;
	}

	// can't build just yet
	if ( self->client->ps.stats[ STAT_MISC ] > 0 )
	{
		G_AddEvent( self, EV_BUILD_DELAY, self->client->ps.clientNum );
		return;
	}

	// build
	if ( G_BuildIfValid( self, buildable ) )
	{
		if ( !g_cheats.integer )
		{
			int buildTime = BG_Buildable( buildable )->buildTime;

			switch ( self->client->ps.persistant[ PERS_TEAM ] )
			{
				case TEAM_ALIENS:
					buildTime *= ALIEN_BUILDDELAY_MOD;
					break;

				case TEAM_HUMANS:
					buildTime *= HUMAN_BUILDDELAY_MOD;
					break;

				default:
					break;
			}

			self->client->ps.stats[ STAT_MISC ] += buildTime;
		}

		self->client->ps.stats[ STAT_BUILDABLE ] = BA_NONE;
	}
}
Esempio n. 16
0
static const char *UnlockableHumanName( unlockable_t *unlockable )
{
	switch ( unlockable->type )
	{
		case UNLT_WEAPON:    return BG_Weapon( unlockable->num )->humanName;
		case UNLT_UPGRADE:   return BG_Upgrade( unlockable->num )->humanName;
		case UNLT_BUILDABLE: return BG_Buildable( unlockable->num )->humanName;
		case UNLT_CLASS:     return BG_ClassModelConfig( unlockable->num )->humanName;
	}

	Com_Error( ERR_FATAL, "UnlockableHumanName: Unlockable has unknown type" );
	return nullptr;
}
Esempio n. 17
0
static void CG_CompleteBuild( void )
{
	int i;

	for ( i = 0; i < BA_NUM_BUILDABLES; i++ )
	{
		const buildableAttributes_t *item = BG_Buildable( i );
		if ( item->team == cgs.clientinfo[ cg.clientNum ].team )
		{
			trap_CompleteCallback( item->name );
		}
	}
}
Esempio n. 18
0
/*
==================
CG_PlayerIsBuilder
==================
*/
static qboolean CG_PlayerIsBuilder( buildable_t buildable )
{
  switch( cg.predictedPlayerState.weapon )
  {
    case WP_ABUILD:
    case WP_HBUILD:
      return BG_Buildable( buildable )->team ==
             BG_Weapon( cg.predictedPlayerState.weapon )->team;

    default:
      return qfalse;
  }
}
/*
===============
CG_BuildableAnimation
===============
*/
static void CG_BuildableAnimation( centity_t *cent, int *old, int *now, float *backLerp )
{
  entityState_t *es = &cent->currentState;

  //if no animation is set default to idle anim
  if( cent->buildableAnim == BANIM_NONE )
    cent->buildableAnim = es->torsoAnim;

  //display the first frame of the construction anim if not yet spawned
  if( !( es->generic1 & B_SPAWNED_TOGGLEBIT ) )
  {
    animation_t *anim = &cg_buildables[ es->modelindex ].animations[ BANIM_CONSTRUCT1 ];

    //so that when animation starts for real it has sensible numbers
    cent->lerpFrame.oldFrameTime =
      cent->lerpFrame.frameTime =
      cent->lerpFrame.animationTime =
      cg.time;

    *old      = cent->lerpFrame.oldFrame = anim->firstFrame;
    *now      = cent->lerpFrame.frame    = anim->firstFrame;
    *backLerp = cent->lerpFrame.backlerp = 0.0f;

    //ensure that an animation is triggered once the buildable has spawned
    cent->oldBuildableAnim = BANIM_NONE;
  }
  else
  {
    if( ( cent->oldBuildableAnim ^ es->legsAnim ) & ANIM_TOGGLEBIT )
    {
      if( cg_debugAnim.integer )
        CG_Printf( "%d->%d l:%d t:%d %s(%d)\n",
                   cent->oldBuildableAnim, cent->buildableAnim,
                   es->legsAnim, es->torsoAnim,
                   BG_Buildable( es->modelindex )->humanName, es->number );

      if( cent->buildableAnim == es->torsoAnim || es->legsAnim & ANIM_FORCEBIT )
        cent->buildableAnim = cent->oldBuildableAnim = es->legsAnim;
      else
        cent->buildableAnim = cent->oldBuildableAnim = es->torsoAnim;
    }

    CG_RunBuildableLerpFrame( cent );

    *old      = cent->lerpFrame.oldFrame;
    *now      = cent->lerpFrame.frame;
    *backLerp = cent->lerpFrame.backlerp;
  }
}
void AlienBuildableComponent::Think(int timeDelta) {
	// TODO: Port gentity_t.powered.
	entity.oldEnt->powered = (G_ActiveOvermind() != nullptr);

	// Suicide if creep is gone.
	if (BG_Buildable(entity.oldEnt->s.modelindex)->creepTest && !G_FindCreep(entity.oldEnt)) {
		G_Kill(entity.oldEnt, entity.oldEnt->powerSource ? &g_entities[entity.oldEnt->powerSource->killedBy] : nullptr, MOD_NOCREEP);
	}

	// TODO: Find an elegant way to access per-buildable configuration.
	float creepSize = (float)BG_Buildable((buildable_t)entity.oldEnt->s.modelindex)->creepSize;

	// Slow close humans.
	ForEntities<HumanClassComponent>([&] (Entity& other, HumanClassComponent& humanClassComponent) {
		// TODO: Add LocationComponent.
		if (G_Distance(entity.oldEnt, other.oldEnt) > creepSize) return;

		// TODO: Send (Creep)Slow message instead.
		if (other.oldEnt->flags & FL_NOTARGET) return;
		if (other.oldEnt->client->ps.groundEntityNum == ENTITYNUM_NONE) return;
		other.oldEnt->client->ps.stats[STAT_STATE] |= SS_CREEPSLOWED;
		other.oldEnt->client->lastCreepSlowTime = level.time;
	});
}
Esempio n. 21
0
/*
===============
CG_BuilderText
===============
*/
static void CG_BuilderText( char *text, playerState_t *ps )
{
	buildable_t   buildable = ps->stats[ STAT_BUILDABLE ] & ~SB_VALID_TOGGLEBIT;
	entityState_t *es;

	if ( buildable > BA_NONE )
	{
		const char *item = _( BG_Buildable( buildable )->humanName );
		Q_strcat( text, MAX_TUTORIAL_TEXT,
		          va( _( "Press %s to place the %s\n"),
		              CG_KeyNameForCommand( "+attack" ), item ) );
		Q_strcat( text, MAX_TUTORIAL_TEXT,
		          va( _( "Press %s to cancel placing the %s\n" ),
		              CG_KeyNameForCommand( "+attack2" ), item ) );
	}
	else
	{
		Q_strcat( text, MAX_TUTORIAL_TEXT,
		          va( _( "Press %s to build a structure\n" ),
		              CG_KeyNameForCommand( "+attack" ) ) );
	}

	if ( ( es = CG_BuildableInRange( ps, NULL ) ) )
	{
	        const char *key = CG_KeyNameForCommand( "if alt \"/deconstruct marked\" /deconstruct" );

		if ( cgs.markDeconstruct )
		{
			if ( es->eFlags & EF_B_MARKED )
			{
				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          va( _( "Press %s to unmark this structure for replacement\n" ), key ) );
			}
			else
			{
				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          va( _( "Press %s to mark this structure for replacement\n" ), key ) );
			}
		}
		else
		{
			Q_strcat( text, MAX_TUTORIAL_TEXT,
			          va( _( "Press %s to destroy this structure\n" ), key ) );
		}
	}
}
Esempio n. 22
0
/*
================
G_SelectSpawnBuildable

find the nearest buildable of the right type that is
spawned/healthy/unblocked etc.
================
*/
static gentity_t *G_SelectSpawnBuildable( vec3_t preference, buildable_t buildable )
{
	gentity_t *search = nullptr;
	gentity_t *spot = nullptr;

	while ( ( search = G_IterateEntitiesOfClass( search, BG_Buildable( buildable )->entityName ) ) != nullptr )
	{
		if ( !search->spawned )
		{
			continue;
		}

		if ( G_Dead( search ) )
		{
			continue;
		}

		if ( search->s.groundEntityNum == ENTITYNUM_NONE )
		{
			continue;
		}

		if ( search->clientSpawnTime > 0 )
		{
			continue;
		}

		Entity* blocker = nullptr;
		Vec3    spawnPoint;

		search->entity->CheckSpawnPoint(blocker, spawnPoint);

		if (blocker)
		{
			continue;
		}

		if ( !spot || DistanceSquared( preference, search->s.origin ) <
		     DistanceSquared( preference, spot->s.origin ) )
		{
			spot = search;
		}
	}

	return spot;
}
Esempio n. 23
0
/*
======================================================================

BUILD GUN

======================================================================
*/
void CheckCkitRepair( gentity_t *ent )
{
	vec3_t    viewOrigin, forward, end;
	trace_t   tr;
	gentity_t *traceEnt;
	int       bHealth;
	//TODO find a solution to move dependency of ent->s.number and &ent->eventTime outside this function
	playerState_t *ps=&ent->client->ps;

	if ( ps->weaponTime > 0 ||
	     ps->stats[ STAT_MISC ] > 0 )
	{
		return;
	}

	BG_GetClientViewOrigin( ps, viewOrigin );
	AngleVectors( ps->viewangles, forward, NULL, NULL );
	VectorMA( viewOrigin, 100, forward, end );

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

	if ( tr.fraction < 1.0f && traceEnt->spawned && traceEnt->health > 0 &&
	     traceEnt->s.eType == ET_BUILDABLE && traceEnt->buildableTeam == TEAM_HUMANS )
	{
		bHealth = BG_Buildable( traceEnt->s.modelindex )->health;

		if ( traceEnt->health < bHealth )
		{
			traceEnt->health += HBUILD_HEALRATE;

			if ( traceEnt->health >= bHealth )
			{
				traceEnt->health = bHealth;
				G_AddPlayerEvent( ps, EV_BUILD_REPAIRED, 0, ent->s.number, &ent->eventTime );
			}
			else
			{
				G_AddPlayerEvent( ps, EV_BUILD_REPAIR, 0, ent->s.number, &ent->eventTime );
			}

			ps->weaponTime += BG_Weapon( ps->weapon )->repeatRate1;
		}
	}
}
Esempio n. 24
0
/*
=================
CG_Bleed

This is the spurt of blood when a character gets hit
=================
*/
void CG_Bleed( vec3_t origin, vec3_t normal, int entityNum )
{
  team_t            team;
  qhandle_t         bleedPS;
  particleSystem_t  *ps;

  if( !cg_blood.integer )
    return;

  if( cg_entities[ entityNum ].currentState.eType == ET_PLAYER )
  {
    team = cgs.clientinfo[ entityNum ].team;
    if( team == TEAM_ALIENS )
      bleedPS = cgs.media.alienBleedPS;
    else if( team == TEAM_HUMANS )
      bleedPS = cgs.media.humanBleedPS;
    else
      return;
  }
  else if( cg_entities[ entityNum ].currentState.eType == ET_BUILDABLE )
  {
    //ew
    team = BG_Buildable( cg_entities[ entityNum ].currentState.modelindex, NULL )->team;
    if( team == TEAM_ALIENS )
      bleedPS = cgs.media.alienBuildableBleedPS;
    else if( team == TEAM_HUMANS )
      bleedPS = cgs.media.humanBuildableBleedPS;
    else
      return;
  }
  else
    return;

  ps = CG_SpawnNewParticleSystem( bleedPS );

  if( CG_IsParticleSystemValid( &ps ) )
  {
    CG_SetAttachmentPoint( &ps->attachment, origin );
    CG_SetAttachmentCent( &ps->attachment, &cg_entities[ entityNum ] );
    CG_AttachToPoint( &ps->attachment );

    CG_SetParticleSystemNormal( ps, normal );
  }
}
Esempio n. 25
0
/*
===============
CG_PrevWeapon_f
===============
*/
void CG_PrevWeapon_f( void )
{
  int   i;
  int   original;

  if( !cg.snap )
    return;

  if( cg.snap->ps.pm_flags & PMF_FOLLOW )
  {
    trap_SendClientCommand( "follownext\n" );
    return;
  }
  
  if( BG_Buildable(cg.snap->ps.stats[STAT_BUILDABLE]&~SB_VALID_TOGGLEBIT,NULL)->cuboid )
  {
   CG_CuboidResize(qfalse);
   return;
  }

  cg.weaponSelectTime = cg.time;
  original = cg.weaponSelect;

  for( i = 0; i < 64; i++ )
  {
    cg.weaponSelect--;
    if( cg.weaponSelect == -1 )
      cg.weaponSelect = 63;

    if( cg.weaponSelect < 32 )
    {
      if( CG_WeaponSelectable( cg.weaponSelect ) )
        break;
    }
    else
    {
      if( CG_UpgradeSelectable( cg.weaponSelect - 32 ) )
        break;
    }
  }

  if( i == 64 )
    cg.weaponSelect = original;
}
// TODO: Move this to the client side.
void AlienBuildableComponent::CreepRecede(int timeDelta) {
	alienBuildableLogger.Debug("Starting creep recede.");

	G_AddEvent(entity.oldEnt, EV_BUILD_DESTROY, 0);

	if (entity.oldEnt->spawned) {
		entity.oldEnt->s.time = -level.time;
	} else {
		entity.oldEnt->s.time = -(level.time - (int)(
			(float)CREEP_SCALEDOWN_TIME *
			(1.0f - ((float)(level.time - entity.oldEnt->creationTime) /
					 (float)BG_Buildable(entity.oldEnt->s.modelindex)->buildTime)))
		);
	}

	// Remove buildable when done.
	GetBuildableComponent().REGISTER_THINKER(Remove, ThinkingComponent::SCHEDULER_AFTER, CREEP_SCALEDOWN_TIME);
	GetBuildableComponent().GetThinkingComponent().UnregisterActiveThinker();
}
Esempio n. 27
0
/*
======================================================================

BUILD GUN

======================================================================
*/
void CheckCkitRepair( gentity_t *ent )
{
	vec3_t    viewOrigin, forward, end;
	trace_t   tr;
	gentity_t *traceEnt;
	int       bHealth;

	if ( ent->client->ps.weaponTime > 0 ||
	     ent->client->ps.stats[ STAT_MISC ] > 0 )
	{
		return;
	}

	BG_GetClientViewOrigin( &ent->client->ps, viewOrigin );
	AngleVectors( ent->client->ps.viewangles, forward, NULL, NULL );
	VectorMA( viewOrigin, 100, forward, end );

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

	if ( tr.fraction < 1.0f && traceEnt->spawned && traceEnt->health > 0 &&
	     traceEnt->s.eType == ET_BUILDABLE && traceEnt->buildableTeam == TEAM_HUMANS )
	{
		bHealth = BG_Buildable( traceEnt->s.modelindex )->health;

		if ( traceEnt->health < bHealth )
		{
			traceEnt->health += HBUILD_HEALRATE;

			if ( traceEnt->health >= bHealth )
			{
				traceEnt->health = bHealth;
				G_AddEvent( ent, EV_BUILD_REPAIRED, 0 );
			}
			else
			{
				G_AddEvent( ent, EV_BUILD_REPAIR, 0 );
			}

			ent->client->ps.weaponTime += BG_Weapon( ent->client->ps.weapon )->repeatRate1;
		}
	}
}
Esempio n. 28
0
/*
==================
CG_Creep
==================
*/
static void CG_Creep( centity_t *cent )
{
  int           msec;
  float         size, frac;
  trace_t       tr;
  vec3_t        temp, origin;
  int           scaleUpTime = BG_Buildable( cent->currentState.modelindex )->buildTime;
  int           time;

  time = cent->currentState.time;

  //should the creep be growing or receding?
  if( time >= 0 )
  {
    msec = cg.time - time;
    if( msec >= 0 && msec < scaleUpTime )
      frac = (float)msec / scaleUpTime;
    else
      frac = 1.0f;
  }
  else if( time < 0 )
  {
    msec = cg.time + time;
    if( msec >= 0 && msec < CREEP_SCALEDOWN_TIME )
      frac = 1.0f - ( (float)msec / CREEP_SCALEDOWN_TIME );
    else
      frac = 0.0f;
  }

  VectorCopy( cent->currentState.origin2, temp );
  VectorScale( temp, -CREEP_DISTANCE, temp );
  VectorAdd( temp, cent->lerpOrigin, temp );

  CG_Trace( &tr, cent->lerpOrigin, NULL, NULL, temp, cent->currentState.number, MASK_PLAYERSOLID );

  VectorCopy( tr.endpos, origin );

  size = CREEP_SIZE * frac;

  if( size > 0.0f && tr.fraction < 1.0f )
    CG_ImpactMark( cgs.media.creepShader, origin, cent->currentState.origin2,
                   0.0f, 1.0f, 1.0f, 1.0f, 1.0f, qfalse, size, qtrue );
}
Esempio n. 29
0
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 );
	}
}
Esempio n. 30
0
/*
================
G_SelectSpawnBuildable

find the nearest buildable of the right type that is
spawned/healthy/unblocked etc.
================
*/
static gentity_t *G_SelectSpawnBuildable( vec3_t preference, buildable_t buildable )
{
	gentity_t *search = NULL;
	gentity_t *spot = NULL;

	while ( ( search = G_IterateEntitiesOfClass( search, BG_Buildable( buildable )->entityName ) ) != NULL )
	{
		if ( !search->spawned )
		{
			continue;
		}

		if ( search->health <= 0 )
		{
			continue;
		}

		if ( search->s.groundEntityNum == ENTITYNUM_NONE )
		{
			continue;
		}

		if ( search->clientSpawnTime > 0 )
		{
			continue;
		}

		if ( G_CheckSpawnPoint( search->s.number, search->s.origin,
		                        search->s.origin2, buildable, NULL ) != NULL )
		{
			continue;
		}

		if ( !spot || DistanceSquared( preference, search->s.origin ) <
		     DistanceSquared( preference, spot->s.origin ) )
		{
			spot = search;
		}
	}

	return spot;
}