Пример #1
0
/*
=================
CG_RegisterUpgrade

The server says this item is used on this level
=================
*/
void CG_RegisterUpgrade( int upgradeNum )
{
  upgradeInfo_t   *upgradeInfo;
  char            *icon;

  if( upgradeNum <= UP_NONE || upgradeNum >= UP_NUM_UPGRADES )
  {
    CG_Error( "CG_RegisterUpgrade: out of range: %d", upgradeNum );
    return;
  }

  upgradeInfo = &cg_upgrades[ upgradeNum ];

  if( upgradeInfo->registered )
  {
    CG_Printf( "CG_RegisterUpgrade: already registered: (%d) %s\n", upgradeNum,
      BG_Upgrade( upgradeNum )->name );
    return;
  }

  upgradeInfo->registered = qtrue;

  if( !BG_Upgrade( upgradeNum )->name[ 0 ] )
    CG_Error( "Couldn't find upgrade %i", upgradeNum );

  upgradeInfo->humanName = BG_Upgrade( upgradeNum )->humanName;

  //la la la la la, i'm not listening!
  if( upgradeNum == UP_GRENADE )
    upgradeInfo->upgradeIcon = cg_weapons[ WP_GRENADE ].weaponIcon;
  else if( ( icon = BG_Upgrade( upgradeNum )->icon ) )
    upgradeInfo->upgradeIcon = trap_R_RegisterShader( icon );
}
Пример #2
0
static void CG_CompleteItem( void )
{
	int i = 0;

	if( cgs.clientinfo[ cg.clientNum ].team == TEAM_ALIENS )
	{
		return;
	}

	trap_CompleteCallback( "weapon" );

	for( i = 0; i < UP_NUM_UPGRADES; i++ )
	{
		const upgradeAttributes_t *item = BG_Upgrade( i );
		if ( item->usable )
		{
			trap_CompleteCallback( item->name );
		}
	}

	for( i = 0; i < WP_NUM_WEAPONS; i++ )
	{
		const weaponAttributes_t *item = BG_Weapon( i );
		if( item->team == TEAM_HUMANS )
		{
			trap_CompleteCallback( item->name );
		}
	}
}
Пример #3
0
static void CG_CompleteBuy( void )
{
	int i;

	if( cgs.clientinfo[ cg.clientNum ].team != TEAM_HUMANS )
	{
		return;
	}

	for( i = 0; i < UP_NUM_UPGRADES; i++ )
	{
		const upgradeAttributes_t *item = BG_Upgrade( i );
		if ( item->purchasable && item->team == TEAM_HUMANS )
		{
			trap_CompleteCallback( item->name );
		}
	}

	trap_CompleteCallback( "grenade" ); // called "gren" elsewhere, so special-case it

	for( i = 0; i < WP_NUM_WEAPONS; i++ )
	{
		const weaponAttributes_t *item = BG_Weapon( i );
		if ( item->purchasable && item->team == TEAM_HUMANS )
		{
			trap_CompleteCallback( item->name );
		}
	}
}
Пример #4
0
/*
===============
CG_UpgradeSelectable
===============
*/
static qboolean CG_UpgradeSelectable( upgrade_t upgrade )
{
  if( !BG_InventoryContainsUpgrade( upgrade, cg.snap->ps.stats ) )
    return qfalse;

  return BG_Upgrade( upgrade )->usable;
}
Пример #5
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;
}
Пример #6
0
static void CG_Rocket_DFCMArmouryBuyUpgrade( int handle, const char *data )
{
	upgrade_t upgrade = (upgrade_t) atoi( Info_ValueForKey( data, "1" ) );
	const char *Class = "";
	const char *Icon = "";
	const char *action = "";
	playerState_t *ps = &cg.snap->ps;
	int credits = ps->persistant[ PERS_CREDIT ];

	if( BG_InventoryContainsUpgrade( upgrade, cg.predictedPlayerState.stats ) ){
		Class = "active";
		action =  va( "onClick='Cmd.exec(\"sell %s\")'", BG_Upgrade( upgrade )->name );
		//Check mark icon. UTF-8 encoding of \uf00c
		Icon = "<icon class=\"current\">\xEF\x80\x8C</icon>";
	}

	else if ( !BG_UpgradeUnlocked( upgrade ) || BG_UpgradeDisabled( upgrade ) )
	{
		Class = "locked";
		//Padlock icon. UTF-8 encoding of \uf023
		Icon = "<icon>\xEF\x80\xA3</icon>";
	}
	else if ( !trap_Cvar_VariableIntegerValue( "x_freeUpgrades" ) && BG_Upgrade( upgrade )->price > credits )
	{
		Class = "expensive";
		//$1 bill icon. UTF-8 encoding of \uf0d6
		Icon = "<icon>\xEF\x83\x96</icon>";
	}
	else
	{
		Class = "available";
		action =  va( "onClick='Cmd.exec(\"buy +%s\")'", BG_Upgrade( upgrade )->name );
	}

	Rocket_DataFormatterFormattedData( handle, va( "<button class='armourybuy %s' onMouseover='Events.pushevent(\"setDS armouryBuyList upgrades %s\", event)' %s>%s<img src='/%s'/></button>", Class, Info_ValueForKey( data, "2" ), action, Icon, CG_GetShaderNameFromHandle( cg_upgrades[ upgrade ].upgradeIcon)), false );
}
Пример #7
0
static void CG_CompleteBuy_internal( bool negatives )
{
	int i;

	for( i = 0; i < UP_NUM_UPGRADES; i++ )
	{
		const upgradeAttributes_t *item = BG_Upgrade( i );
		if ( item->purchasable && item->team == TEAM_HUMANS )
		{
			trap_CompleteCallback( item->name );

			if ( negatives )
			{
				trap_CompleteCallback( va( "-%s", item->name ) );
			}
		}
	}

	trap_CompleteCallback( "grenade" ); // called "gren" elsewhere, so special-case it

	if ( negatives )
	{
		trap_CompleteCallback( "-grenade" );

		i = BG_GetPlayerWeapon( &cg.snap->ps );

	}

	for( i = 0; i < WP_NUM_WEAPONS; i++ )
	{
		const weaponAttributes_t *item = BG_Weapon( i );
		if ( item->purchasable && item->team == TEAM_HUMANS )
		{
			trap_CompleteCallback( item->name );

			if ( negatives )
			{
				trap_CompleteCallback( va( "-%s", BG_Weapon( i )->name ) );
			}
		}
	}
}
Пример #8
0
/*
==================
G_RewardAttackers

Function to distribute rewards to entities that killed this one.
==================
*/
void G_RewardAttackers( gentity_t *self )
{
	float     value, reward;
	int       playerNum, enemyDamage, maxHealth, damageShare;
	gentity_t *player;
	team_t    ownTeam, playerTeam;
	confidence_reason_t    reason;
	confidence_qualifier_t qualifier;

	// Only reward killing players and buildables
	if ( self->client )
	{
		ownTeam = self->client->pers.teamSelection;
		maxHealth = self->client->ps.stats[ STAT_MAX_HEALTH ];
		value = ( float )BG_GetValueOfPlayer( &self->client->ps );
	}
	else if ( self->s.eType == ET_BUILDABLE )
	{
		ownTeam = self->buildableTeam;
		maxHealth = BG_Buildable( self->s.modelindex )->health;
		value = ( float )BG_Buildable( self->s.modelindex )->value;

		// Give partial credits for buildables in construction
		if ( !self->spawned )
		{
			value *= ( float )( level.time - self->creationTime ) / BG_Buildable( self->s.modelindex )->buildTime;
		}
	}
	else
	{
		return;
	}

	enemyDamage = 0;

	// Sum up damage dealt by enemies
	for ( playerNum = 0; playerNum < level.maxclients; playerNum++ )
	{
		player = &g_entities[ playerNum ];
		playerTeam = player->client->pers.teamSelection;

		// Player must be on the other team
		if ( playerTeam == ownTeam || playerTeam <= TEAM_NONE || playerTeam >= NUM_TEAMS )
		{
			continue;
		}

		enemyDamage += self->credits[ playerNum ];
	}

	if ( enemyDamage <= 0 )
	{
		return;
	}

	// Give individual rewards
	for ( playerNum = 0; playerNum < level.maxclients; playerNum++ )
	{
		player = &g_entities[ playerNum ];
		playerTeam = player->client->pers.teamSelection;
		damageShare = self->credits[ playerNum ];

		// Clear reward array
		self->credits[ playerNum ] = 0;

		// Player must be on the other team
		if ( playerTeam == ownTeam || playerTeam <= TEAM_NONE || playerTeam >= NUM_TEAMS )
		{
			continue;
		}

		// Player must have dealt damage
		if ( damageShare <= 0 )
		{
			continue;
		}

		reward = value * ( damageShare / ( float )maxHealth );

		if ( reward <= 0.0f )
		{
			continue;
		}

		if ( self->s.eType == ET_BUILDABLE )
		{
			G_AddConfidenceToScore( player, reward );

			switch ( self->s.modelindex )
			{
				case BA_A_OVERMIND:
				case BA_H_REACTOR:
					reason = CONF_REAS_DESTR_CRUCIAL;
					break;

				case BA_A_ACIDTUBE:
				case BA_A_TRAPPER:
				case BA_A_HIVE:
				case BA_H_MGTURRET:
				case BA_H_TESLAGEN:
					reason = CONF_REAS_DESTR_AGGRESSIVE;
					break;

				default:
					reason = CONF_REAS_DESTR_SUPPORT;
			}

			qualifier = CONF_QUAL_NONE;

			G_AddConfidence( playerTeam, CONFIDENCE_DESTRUCTION, reason, qualifier, reward, player );
		}
		else
		{
			G_AddCreditsToScore( player, ( int )reward );
			G_AddCreditToClient( player->client, ( short )reward, qtrue );

			// Give confidence for killing non-naked players outside the friendly base
			switch ( self->client->ps.stats[ STAT_CLASS ] )
			{
				case PCL_ALIEN_LEVEL0:
				case PCL_ALIEN_BUILDER0:
				case PCL_ALIEN_BUILDER0_UPG:
					break;

				case PCL_HUMAN:
					// Treat a human just wearing light armor as naked
					if ( ( int )value <= BG_Class( PCL_HUMAN )->value +
					                     ( BG_Upgrade( UP_LIGHTARMOUR )->price / 2 ) )
					{
						break;
					}

				default:
					if ( G_InsideBase( player, qtrue ) || G_InsideBase( self, qfalse ) )
					{
						break;
					}

					qualifier = CONF_QUAL_OUTSIDE_OWN_BASE;

					G_AddConfidence( playerTeam, CONFIDENCE_KILLING, CONF_REAS_KILLING,
					                 qualifier, reward * CONFIDENCE_PER_CREDIT, player );
			}
		}
	}
}
Пример #9
0
/*
===============
CG_HumanText
===============
*/
static void CG_HumanText( char *text, playerState_t *ps )
{
	const char *name;
	upgrade_t upgrade = UP_NONE;

	if ( cg.weaponSelect < 32 )
	{
		name = cg_weapons[ cg.weaponSelect ].humanName;
	}
	else
	{
		name = cg_upgrades[ cg.weaponSelect - 32 ].humanName;
		upgrade = (upgrade_t) ( cg.weaponSelect - 32 );
	}

	if ( !ps->ammo && !ps->clips && !BG_Weapon( ps->weapon )->infiniteAmmo )
	{
		//no ammo
		switch ( ps->weapon )
		{
			case WP_MACHINEGUN:
			case WP_CHAINGUN:
			case WP_SHOTGUN:
			case WP_FLAMER:
				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          _( "Find an Armoury for more ammo\n" ) );
				break;

			case WP_LAS_GUN:
			case WP_PULSE_RIFLE:
			case WP_MASS_DRIVER:
			case WP_LUCIFER_CANNON:
				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          _( "Find an Armoury, Reactor, or Repeater for more ammo\n" ) );
				break;

			default:
				break;
		}
	}
	else
	{
		switch ( ps->weapon )
		{
			case WP_BLASTER:
			case WP_MACHINEGUN:
			case WP_SHOTGUN:
			case WP_LAS_GUN:
			case WP_CHAINGUN:
			case WP_PULSE_RIFLE:
			case WP_FLAMER:
				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          va( _( "Press %s to fire the %s\n" ),
				              CG_KeyNameForCommand( "+attack" ),
				              _( BG_Weapon( ps->weapon )->humanName ) ) );
				break;

			case WP_MASS_DRIVER:
				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          va( _( "Press %s to fire the %s\n" ),
				              CG_KeyNameForCommand( "+attack" ),
				              _( BG_Weapon( ps->weapon )->humanName ) ) );

				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          va( _( "Hold %s to zoom\n" ),
				              CG_KeyNameForCommand( "+attack2" ) ) );
				break;

			case WP_PAIN_SAW:
				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          va( _( "Hold %s to activate the %s\n" ),
				              CG_KeyNameForCommand( "+attack" ),
				              _( BG_Weapon( ps->weapon )->humanName ) ) );
				break;

			case WP_LUCIFER_CANNON:
				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          va( _( "Hold and release %s to fire a charged shot\n" ),
				              CG_KeyNameForCommand( "+attack" ) ) );

				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          va( _( "Press %s to fire the %s\n" ),
				              CG_KeyNameForCommand( "+attack2" ),
				              _( BG_Weapon( ps->weapon )->humanName ) ) );
				break;

			case WP_HBUILD:
				CG_HumanCkitText( text, ps );
				break;

			default:
				break;
		}
	}

	if ( upgrade == UP_NONE ||
	     ( upgrade > UP_NONE && BG_Upgrade( upgrade )->usable ) )
	{
		Q_strcat( text, MAX_TUTORIAL_TEXT,
		          va( _( "Press %s to use the %s\n" ),
		              CG_KeyNameForCommand( "+useitem" ),
		              name ) );
	}

	if ( ps->stats[ STAT_HEALTH ] <= 35 &&
	     BG_InventoryContainsUpgrade( UP_MEDKIT, ps->stats ) )
	{
		Q_strcat( text, MAX_TUTORIAL_TEXT,
		          va( _( "Press %s to use your %s\n" ),
		              CG_KeyNameForCommand( "itemact medkit" ),
		              _( BG_Upgrade( UP_MEDKIT )->humanName ) ) );
	}

	switch ( cg.nearUsableBuildable )
	{
		case BA_H_ARMOURY:
			Q_strcat( text, MAX_TUTORIAL_TEXT,
			          va( _( "Press %s to buy equipment upgrades at the %s\n" ),
			              CG_KeyNameForCommand( "+activate" ),
			              _( BG_Buildable( cg.nearUsableBuildable )->humanName ) ) );
			break;

		case BA_NONE:
			break;

		default:
			Q_strcat( text, MAX_TUTORIAL_TEXT,
			          va( _( "Press %s to use the %s\n" ),
			              CG_KeyNameForCommand( "+activate" ),
			              _( BG_Buildable( cg.nearUsableBuildable )->humanName ) ) );
			break;
	}

	Q_strcat( text, MAX_TUTORIAL_TEXT,
	          va( _( "Press %s and any direction to sprint\n" ),
	              CG_KeyNameForCommand( "+sprint" ) ) );

	if ( BG_InventoryContainsUpgrade( UP_FIREBOMB, ps->stats ) ||
		BG_InventoryContainsUpgrade( UP_GRENADE, ps->stats ) )
	{
		Q_strcat( text, MAX_TUTORIAL_TEXT, va( _( "Press %s to throw a grenade\n" ),
			CG_KeyNameForCommand( "itemact grenade" )
		));
	}
}
Пример #10
0
void G_UpdateUnlockables()
{
	int              itemNum = 0, unlockableNum, unlockThreshold;
	float            momentum;
	unlockable_t     *unlockable;
	int              unlockableType = 0;
	team_t           team;

	for ( unlockableNum = 0; unlockableNum < NUM_UNLOCKABLES; unlockableNum++ )
	{
		unlockable = &unlockables[ unlockableNum ];

		// also iterate over item types, itemNum is a per-type counter
		while ( unlockableType < UNLT_NUM_UNLOCKABLETYPES - 1 &&
		        unlockableNum == unlockablesTypeOffset[ unlockableType + 1 ] )
		{
			unlockableType++;
			itemNum = 0;
		}

		switch ( unlockableType )
		{
			case UNLT_WEAPON:
				team            = BG_Weapon( itemNum )->team;
				unlockThreshold = BG_Weapon( itemNum )->unlockThreshold;
				break;

			case UNLT_UPGRADE:
				team            = TEAM_HUMANS;
				unlockThreshold = BG_Upgrade( itemNum )->unlockThreshold;
				break;

			case UNLT_BUILDABLE:
				team            = BG_Buildable( itemNum )->team;
				unlockThreshold = BG_Buildable( itemNum )->unlockThreshold;
				break;

			case UNLT_CLASS:
				team            = TEAM_ALIENS;
				unlockThreshold = BG_Class( itemNum )->unlockThreshold;
				break;

			default:
				Com_Error( ERR_FATAL, "G_UpdateUnlockables: Unknown unlockable type" );
		}

		unlockThreshold = MAX( unlockThreshold, 0 );
		momentum = level.team[ team ].momentum;

		unlockable->type            = unlockableType;
		unlockable->num             = itemNum;
		unlockable->team            = team;
		unlockable->statusKnown     = true;
		unlockable->unlockThreshold = unlockThreshold;
		unlockable->lockThreshold   = UnlockToLockThreshold( unlockThreshold );

		// calculate the item's locking state
		unlockable->unlocked = (
		    !unlockThreshold || momentum >= unlockThreshold ||
		    ( unlockable->unlocked && momentum >= unlockable->lockThreshold )
		);

		itemNum++;

		/*Com_Printf( "G_UpdateUnlockables: Team %s, Type %s, Item %s, Momentum %d, Threshold %d, "
		            "Unlocked %d, Synchronize %d\n",
		            BG_TeamName( team ), UnlockableTypeName( unlockable ), UnlockableName( unlockable ),
		            momentum, unlockThreshold, unlockable->unlocked, unlockable->synchronize );*/
	}

	// GAME knows about all teams
	unlockablesDataAvailable = true;
	unlockablesTeamKnowledge = TEAM_ALL;

	// generate masks for network transmission
	UpdateUnlockablesMask();
}
Пример #11
0
void BG_ImportUnlockablesFromMask( int team, int mask )
{
	int              unlockableNum, teamUnlockableNum = 0, itemNum = 0, unlockThreshold;
	unlockable_t     *unlockable;
	int unlockableType = 0;
	team_t           currentTeam;
	bool         newStatus;
	int              statusChanges[ NUM_UNLOCKABLES ];
#ifdef BUILD_CGAME
	int statusChangeCount = 0;
#endif

	// maintain a cache to prevent redundant imports
	static int    lastMask = 0;
	static team_t lastTeam = TEAM_NONE;

	// just import if data is unavailable, cached mask is outdated or team has changed
	if ( unlockablesDataAvailable && team == lastTeam && mask == lastMask )
	{
		return;
	}

	// cache input
	lastMask = mask;
	lastTeam = (team_t) team;

	// no status change yet
	memset( statusChanges, 0, sizeof( statusChanges ) );

	for ( unlockableNum = 0; unlockableNum < NUM_UNLOCKABLES; unlockableNum++ )
	{
		unlockable = &unlockables[ unlockableNum ];

		// also iterate over item types, itemNum is a per-type counter
		if ( unlockableType < UNLT_NUM_UNLOCKABLETYPES - 1 &&
		     unlockableNum == unlockablesTypeOffset[ unlockableType + 1 ] )
		{
			unlockableType++;
			itemNum = 0;
		}

		switch ( unlockableType )
		{
			case UNLT_WEAPON:
				currentTeam     = BG_Weapon( itemNum )->team;
				unlockThreshold = BG_Weapon( itemNum )->unlockThreshold;
				break;

			case UNLT_UPGRADE:
				currentTeam     = TEAM_HUMANS;
				unlockThreshold = BG_Upgrade( itemNum )->unlockThreshold;
				break;

			case UNLT_BUILDABLE:
				currentTeam     = BG_Buildable( itemNum )->team;
				unlockThreshold = BG_Buildable( itemNum )->unlockThreshold;
				break;

			case UNLT_CLASS:
				currentTeam     = TEAM_ALIENS;
				unlockThreshold = BG_Class( itemNum )->unlockThreshold;
				break;

			default:
				Com_Error( ERR_FATAL, "BG_ImportUnlockablesFromMask: Unknown unlockable type" );
		}

		unlockThreshold = MAX( unlockThreshold, 0 );

		unlockable->type            = unlockableType;
		unlockable->num             = itemNum;
		unlockable->team            = currentTeam;
		unlockable->unlockThreshold = unlockThreshold;
		unlockable->lockThreshold   = UnlockToLockThreshold( unlockThreshold );

		// retrieve the item's locking state
		if ( !unlockThreshold )
		{
			unlockable->statusKnown = true;
			unlockable->unlocked    = true;
		}
		else if ( currentTeam == team )
		{
			newStatus = mask & ( 1 << teamUnlockableNum );

#ifdef BUILD_CGAME
			// notify client about single status change
			if ( unlockablesTeamKnowledge == team && unlockable->statusKnown &&
			     unlockable->unlocked != newStatus )
			{
				InformUnlockableStatusChange( unlockable, newStatus );

				statusChanges[ unlockableNum ] = newStatus ? 1 : -1;
				statusChangeCount++;
			}
#endif

			unlockable->statusKnown = true;
			unlockable->unlocked    = newStatus;

			teamUnlockableNum++;
		}
		else
		{
			unlockable->statusKnown = false;
			unlockable->unlocked    = false;
		}

		itemNum++;
	}

#ifdef BUILD_CGAME
	// notify client about all status changes
	if ( statusChangeCount )
	{
		InformUnlockableStatusChanges( statusChanges, statusChangeCount );
	}

	// export team and mask into cvar for UI
	trap_Cvar_Set( "ui_unlockables", va( "%d %d", team, mask ) );
#endif

	// we only know the state for one team
	unlockablesDataAvailable = true;
	unlockablesTeamKnowledge = (team_t) team;

	// save mask for later use
	unlockablesMask[ team ] = mask;
}
Пример #12
0
static void CG_Rocket_DFUpgradeName( int handle, const char *data )
{
	Rocket_DataFormatterFormattedData( handle, BG_Upgrade( atoi( Info_ValueForKey( data, "1" ) ) )->humanName, true );
}
Пример #13
0
/*
===============
CG_HumanText
===============
*/
static void CG_HumanText( char *text, playerState_t *ps )
{
	const char *name;
	upgrade_t upgrade = UP_NONE;

	if ( cg.weaponSelect < 32 )
	{
		name = cg_weapons[ cg.weaponSelect ].humanName;
	}
	else
	{
		name = cg_upgrades[ cg.weaponSelect - 32 ].humanName;
		upgrade = cg.weaponSelect - 32;
	}

	if ( !ps->ammo && !ps->clips && !BG_Weapon( ps->weapon )->infiniteAmmo )
	{
		//no ammo
		switch ( ps->weapon )
		{
			case WP_MACHINEGUN:
			case WP_CHAINGUN:
			case WP_SHOTGUN:
			case WP_FLAMER:
				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          va( _( "Find an Armoury and press %s for more ammo\n" ),
				              CG_KeyNameForCommand( "buy ammo" ) ) );
				break;

			case WP_LAS_GUN:
			case WP_PULSE_RIFLE:
			case WP_MASS_DRIVER:
			case WP_LUCIFER_CANNON:
				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          va( _( "Find an Armoury, Reactor, or Repeater and press %s for more ammo\n" ),
				              CG_KeyNameForCommand( "buy ammo" ) ) );
				break;

			default:
				break;
		}
	}
	else
	{
		switch ( ps->weapon )
		{
			case WP_BLASTER:
			case WP_MACHINEGUN:
			case WP_SHOTGUN:
			case WP_LAS_GUN:
			case WP_CHAINGUN:
			case WP_PULSE_RIFLE:
			case WP_FLAMER:
				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          va( _( "Press %s to fire the %s\n" ),
				              CG_KeyNameForCommand( "+attack" ),
				              _( BG_Weapon( ps->weapon )->humanName ) ) );
				break;

			case WP_MASS_DRIVER:
				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          va( _( "Press %s to fire the %s\n" ),
				              CG_KeyNameForCommand( "+attack" ),
				              _( BG_Weapon( ps->weapon )->humanName ) ) );

				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          va( _( "Hold %s to zoom\n" ),
				              CG_KeyNameForCommand( "+attack2" ) ) );
				break;

			case WP_PAIN_SAW:
				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          va( _( "Hold %s to activate the %s\n" ),
				              CG_KeyNameForCommand( "+attack" ),
				              _( BG_Weapon( ps->weapon )->humanName ) ) );
				break;

			case WP_LUCIFER_CANNON:
				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          va( _( "Hold and release %s to fire a charged shot\n" ),
				              CG_KeyNameForCommand( "+attack" ) ) );

				Q_strcat( text, MAX_TUTORIAL_TEXT,
				          va( _( "Press %s to fire the %s\n" ),
				              CG_KeyNameForCommand( "+attack2" ),
				              _( BG_Weapon( ps->weapon )->humanName ) ) );
				break;

			case WP_HBUILD:
				CG_HumanCkitText( text, ps );
				break;

			default:
				break;
		}
	}

	Q_strcat( text, MAX_TUTORIAL_TEXT,
	          va( _( "Use %s and %s to select an upgrade\n" ),
	              CG_KeyNameForCommand( "weapprev" ), CG_KeyNameForCommand( "weapnext" ) ) );

	if ( upgrade == UP_NONE ||
	     ( upgrade > UP_NONE && BG_Upgrade( upgrade )->usable ) )
	{
		Q_strcat( text, MAX_TUTORIAL_TEXT,
		          va( _( "Press %s to use the %s\n" ),
		              CG_KeyNameForCommand( "+useitem" ),
		              name ) );
	}

	if ( ps->stats[ STAT_HEALTH ] <= 35 &&
	     BG_InventoryContainsUpgrade( UP_MEDKIT, ps->stats ) )
	{
		Q_strcat( text, MAX_TUTORIAL_TEXT,
		          va( _( "Press %s to use your %s\n" ),
		              CG_KeyNameForCommand( "itemact medkit" ),
		              _( BG_Upgrade( UP_MEDKIT )->humanName ) ) );
	}

	if ( ps->stats[ STAT_STAMINA ] <= STAMINA_BLACKOUT_LEVEL )
	{
		Q_strcat( text, MAX_TUTORIAL_TEXT,
		          _( "You are blacking out. Stop sprinting to recover stamina\n" ) );
	}
	else if ( ps->stats[ STAT_STAMINA ] <= STAMINA_SLOW_LEVEL )
	{
		Q_strcat( text, MAX_TUTORIAL_TEXT,
		          _( "Your stamina is low. Stop sprinting to recover\n" ) );
	}

	switch ( cg.nearUsableBuildable )
	{
		case BA_H_ARMOURY:
			Q_strcat( text, MAX_TUTORIAL_TEXT,
			          va( _( "Press %s to buy equipment upgrades at the %s. Sell your old weapon first!\n" ),
			              CG_KeyNameForCommand( "+activate" ),
			              _( BG_Buildable( cg.nearUsableBuildable )->humanName ) ) );
			break;

		case BA_H_REPEATER:
		case BA_H_REACTOR:
			Q_strcat( text, MAX_TUTORIAL_TEXT,
			          va( _( "Press %s to refill your energy weapon's ammo at the %s\n" ),
			              CG_KeyNameForCommand( "+activate" ),
			              _( BG_Buildable( cg.nearUsableBuildable )->humanName ) ) );
			break;

		case BA_NONE:
			break;

		default:
			Q_strcat( text, MAX_TUTORIAL_TEXT,
			          va( _( "Press %s to use the %s\n" ),
			              CG_KeyNameForCommand( "+activate" ),
			              _( BG_Buildable( cg.nearUsableBuildable )->humanName ) ) );
			break;
	}

	Q_strcat( text, MAX_TUTORIAL_TEXT,
	          va( _( "Press %s and any direction to sprint\n" ),
	              CG_KeyNameForCommand( "+sprint" ) ) );
}
Пример #14
0
/*
===============
CG_HumanText
===============
*/
static void CG_HumanText( char *text, playerState_t *ps )
{
  char      *name;
  upgrade_t upgrade = UP_NONE;

  if( cg.weaponSelect < 32 )
    name = cg_weapons[ cg.weaponSelect ].humanName;
  else
  {
    name = cg_upgrades[ cg.weaponSelect - 32 ].humanName;
    upgrade = cg.weaponSelect - 32;
  }

  if( !ps->ammo && !ps->clips && !BG_Weapon( ps->weapon )->infiniteAmmo )
  {
    //no ammo
    switch( ps->weapon )
    {
      case WP_MACHINEGUN:
      case WP_CHAINGUN:
      case WP_SHOTGUN:
      case WP_FLAMER:
        Q_strcat( text, MAX_TUTORIAL_TEXT,
            va( "Find an Armoury and press %s for more ammo\n",
              CG_KeyNameForCommand( "buy ammo" ) ) );
        break;

      case WP_LAS_GUN:
      case WP_PULSE_RIFLE:
      case WP_MASS_DRIVER:
      case WP_LUCIFER_CANNON:
        Q_strcat( text, MAX_TUTORIAL_TEXT,
            va( "Find a Reactor or Repeater and press %s for more ammo\n",
              CG_KeyNameForCommand( "buy ammo" ) ) );
        break;

      default:
        break;
    }
  }
  else
  {
    switch( ps->weapon )
    {
      case WP_BLASTER:
      case WP_MACHINEGUN:
      case WP_SHOTGUN:
      case WP_LAS_GUN:
      case WP_CHAINGUN:
      case WP_PULSE_RIFLE:
      case WP_FLAMER:
        Q_strcat( text, MAX_TUTORIAL_TEXT,
            va( "Press %s to fire the %s\n",
              CG_KeyNameForCommand( "+attack" ),
              BG_Weapon( ps->weapon )->humanName ) );
        break;

      case WP_MASS_DRIVER:
        Q_strcat( text, MAX_TUTORIAL_TEXT,
            va( "Press %s to fire the %s\n",
              CG_KeyNameForCommand( "+attack" ),
              BG_Weapon( ps->weapon )->humanName ) );

        Q_strcat( text, MAX_TUTORIAL_TEXT,
            va( "Hold %s to zoom\n",
              CG_KeyNameForCommand( "+button5" ) ) );
        break;

      case WP_PAIN_SAW:
        Q_strcat( text, MAX_TUTORIAL_TEXT,
            va( "Hold %s to activate the %s\n",
              CG_KeyNameForCommand( "+attack" ),
              BG_Weapon( ps->weapon )->humanName ) );
        break;

      case WP_LUCIFER_CANNON:
        Q_strcat( text, MAX_TUTORIAL_TEXT,
            va( "Hold and release %s to fire a charged shot\n",
              CG_KeyNameForCommand( "+attack" ) ) );

        Q_strcat( text, MAX_TUTORIAL_TEXT,
            va( "Press %s to fire the %s\n",
              CG_KeyNameForCommand( "+button5" ),
              BG_Weapon( ps->weapon )->humanName ) );
        break;

      case WP_HBUILD:
        CG_HumanCkitText( text, ps );
        break;

      default:
        break;
    }
  }

  Q_strcat( text, MAX_TUTORIAL_TEXT,
      va( "Press %s and ",
          CG_KeyNameForCommand( "weapprev" ) ) );
  Q_strcat( text, MAX_TUTORIAL_TEXT,
      va( "%s to select an upgrade\n",
          CG_KeyNameForCommand( "weapnext" ) ) );

  if( upgrade == UP_NONE ||
      ( upgrade > UP_NONE && BG_Upgrade( upgrade )->usable ) )
  {
    Q_strcat( text, MAX_TUTORIAL_TEXT,
        va( "Press %s to use the %s\n",
            CG_KeyNameForCommand( "+button2" ),
            name ) );
  }

  if( ps->stats[ STAT_HEALTH ] <= 35 &&
      BG_InventoryContainsUpgrade( UP_MEDKIT, ps->stats ) )
  {
    Q_strcat( text, MAX_TUTORIAL_TEXT,
        va( "Press %s to use your %s\n",
          CG_KeyNameForCommand( "itemact medkit" ),
          BG_Upgrade( UP_MEDKIT )->humanName ) );
  }

  if( ps->stats[ STAT_STAMINA ] <= STAMINA_BLACKOUT_LEVEL )
  {
    Q_strcat( text, MAX_TUTORIAL_TEXT,
        "You are blacking out. Stop sprinting to recover stamina.\n" );
  }
  else if( ps->stats[ STAT_STAMINA ] <= STAMINA_SLOW_LEVEL )
  {
    Q_strcat( text, MAX_TUTORIAL_TEXT,
        "Your stamina is low. Stop sprinting to recover.\n" );
  }

  if( cg.nearUsableBuildable )
  {
    Q_strcat( text, MAX_TUTORIAL_TEXT,
        va( "Press %s to use this structure\n",
          CG_KeyNameForCommand( "+button7" ) ) );
  }

  Q_strcat( text, MAX_TUTORIAL_TEXT,
      va( "Press %s and any direction to sprint\n",
        CG_KeyNameForCommand( "+button8" ) ) );

  Q_strcat( text, MAX_TUTORIAL_TEXT,
      va( "Press %s and back or strafe to dodge\n",
        CG_KeyNameForCommand( "+button6" ) ) );
}
Пример #15
0
/*
===================
CG_DrawItemSelect
===================
*/
void CG_DrawItemSelect( rectDef_t *rect, vec4_t color )
{
  int           i;
  float         x = rect->x;
  float         y = rect->y;
  float         width = rect->w;
  float         height = rect->h;
  float         iconWidth;
  float         iconHeight;
  int           items[ 64 ];
  int           colinfo[ 64 ];
  int           numItems = 0, selectedItem = 0;
  int           length;
  qboolean      vertical;
  centity_t *cent;
  playerState_t *ps;

  cent = &cg_entities[ cg.snap->ps.clientNum ];
  ps = &cg.snap->ps;

  // don't display if dead
  if( cg.predictedPlayerState.stats[ STAT_HEALTH ] <= 0 )
    return;

  if( !( cg.snap->ps.pm_flags & PMF_FOLLOW ) )
  {
    // first make sure that whatever it selected is actually selectable
    if( cg.weaponSelect < 32 )
    {
      if( !CG_WeaponSelectable( cg.weaponSelect ) )
        CG_NextWeapon_f( );
    }
    else
    {
      if( !CG_UpgradeSelectable( cg.weaponSelect - 32 ) )
        CG_NextWeapon_f( );
    }
  }

  // showing weapon select clears pickup item display, but not the blend blob
  cg.itemPickupTime = 0;

  // put all weapons in the items list
  for( i = WP_NONE + 1; i < WP_NUM_WEAPONS; i++ )
  {
    if( !BG_InventoryContainsWeapon( i, cg.snap->ps.stats ) )
      continue;

    if( !ps->ammo && !ps->clips && !BG_Weapon( i )->infiniteAmmo )
      colinfo[ numItems ] = 1;
    else
      colinfo[ numItems ] = 0;

    if( i == cg.weaponSelect )
      selectedItem = numItems;

    if( !cg_weapons[ i ].registered )
    {
      Com_Printf( S_COLOR_YELLOW "WARNING: CG_DrawItemSelect: weapon %d (%s) "
  	"is not registered\n", i, BG_Weapon( i )->name );
      continue;
    }
    items[ numItems ] = i;
    numItems++;
  }

  // put all upgrades in the weapons list
  for( i = UP_NONE + 1; i < UP_NUM_UPGRADES; i++ )
  {
    if( !BG_InventoryContainsUpgrade( i, cg.snap->ps.stats ) )
      continue;
    colinfo[ numItems ] = 0;
    if( !BG_Upgrade( i )->usable )
      colinfo[ numItems ] = 2;

    if( i == cg.weaponSelect - 32 )
      selectedItem = numItems;

    if( !cg_upgrades[ i ].registered )
    {
      Com_Printf( S_COLOR_YELLOW "WARNING: CG_DrawItemSelect: upgrade %d (%s) "
  	"is not registered\n", i, BG_Upgrade( i )->name );
      continue;
    }
    items[ numItems ] = i + 32;
    numItems++;
  }

  // compute the length of the display window and determine orientation
  vertical = height > width;
  if( vertical )
  {
    iconWidth = width * cgDC.aspectScale;
    iconHeight = width;
    length = height / ( width * cgDC.aspectScale );
  }
  else
  {
    iconWidth = height * cgDC.aspectScale;
    iconHeight = height;
    length = width / ( height * cgDC.aspectScale );
  }

  // render icon ring
  for( i = 0; i < length; i++ )
  {
    int item = i - length / 2 + selectedItem;

    if( item < 0 )
      item += length;
    else if( item >= length )
      item -= length;
    if( item >= 0 && item < numItems )
    {
      switch( colinfo[ item ] )
      {
       case 0:
         color = colorCyan;
         break;
       case 1:
         color = colorRed;
         break;
       case 2:
         color = colorMdGrey;
         break;
      }
      color[3] = 0.5;
      trap_R_SetColor( color );

      if( items[ item ] < 32 )
        CG_DrawPic( x, y, iconWidth, iconHeight,
                    cg_weapons[ items[ item ] ].weaponIcon );
      else
        CG_DrawPic( x, y, iconWidth, iconHeight,
                    cg_upgrades[ items[ item ] - 32 ].upgradeIcon );
    }
    if( vertical )
      y += iconHeight;
    else
      x += iconWidth;
  }
  trap_R_SetColor( NULL );
}