Exemple #1
0
void BG_PrecacheSabersForSiegeTeam(int team)
{
	siegeTeam_t *t;
	saberInfo_t saber;
	char *saberName;
	int sNum;

	t = BG_SiegeFindThemeForTeam(team);

	if (t)
	{
		int i = 0;

		while (i < t->numClasses)
		{
			sNum = 0;

			while (sNum < MAX_SABERS)
			{
				switch (sNum)
				{
				case 0:
					saberName = &t->classes[i]->saber1[0];
					break;
				case 1:
					saberName = &t->classes[i]->saber2[0];
					break;
				default:
					saberName = NULL;
					break;
				}

				if (saberName && saberName[0])
				{
					WP_SaberParseParms(saberName, &saber);
					if (!Q_stricmp(saberName, saber.name))
					{ //found the matching saber
						if (saber.model[0])
						{
							BG_ModelCache(saber.model, NULL);
						}
					}
				}

				sNum++;
			}

			i++;
		}
	}
}
Exemple #2
0
void WP_SetSaber( int entNum, saberInfo_t *sabers, int saberNum, const char *saberName )
{
	if ( !sabers )
	{
		return;
	}
	if ( Q_stricmp( "none", saberName ) == 0 || Q_stricmp( "remove", saberName ) == 0 )
	{
		if (saberNum != 0)
		{ //can't remove saber 0 ever
			WP_RemoveSaber( sabers, saberNum );
		}
		return;
	}

	if ( entNum < MAX_CLIENTS &&
		!WP_SaberValidForPlayerInMP( saberName ) )
	{
		WP_SaberParseParms( "Kyle", &sabers[saberNum] );//get saber info
	}
	else
	{
		WP_SaberParseParms( saberName, &sabers[saberNum] );//get saber info
	}
	if (sabers[1].twoHanded)
	{//not allowed to use a 2-handed saber as second saber
		WP_RemoveSaber( sabers, 1 );
		return;
	}
	else if (sabers[0].twoHanded &&
		sabers[1].model[0])
	{ //you can't use a two-handed saber with a second saber, so remove saber 2
		WP_RemoveSaber( sabers, 1 );
		return;
	}
}
Exemple #3
0
void WP_SetSaber( gentity_t *ent, int saberNum, char *saberName )
{
	if ( !ent || !ent->client )
	{
		return;
	}
	if ( Q_stricmp( "none", saberName ) == 0 || Q_stricmp( "remove", saberName ) == 0 )
	{
		WP_RemoveSaber( ent, saberNum );
		return;
	}
	if ( ent->weaponModel[saberNum] > 0 )
	{
		gi.G2API_RemoveGhoul2Model(ent->ghoul2, ent->weaponModel[saberNum]);
		ent->weaponModel[saberNum] = -1;
	}
	WP_SaberParseParms( saberName, &ent->client->ps.saber[saberNum] );//get saber info
	if ( ent->client->ps.saber[saberNum].style )
	{
		ent->client->ps.saberStylesKnown |= (1<<ent->client->ps.saber[saberNum].style);
	}
	if ( saberNum == 1 && ent->client->ps.saber[1].twoHanded )
	{//not allowed to use a 2-handed saber as second saber
		WP_RemoveSaber( ent, saberNum );
		return;
	}
	G_ModelIndex( ent->client->ps.saber[saberNum].model );
	WP_SaberInitBladeData( ent );
	//int boltNum = ent->handRBolt;
	if ( saberNum == 1 )
	{
		ent->client->ps.dualSabers = qtrue;
		//boltNum = ent->handLBolt;
	}
	WP_SaberAddG2SaberModels( ent, saberNum );
	ent->client->ps.saber[saberNum].SetLength( 0.0f );
	ent->client->ps.saber[saberNum].Activate();

	if ( ent->client->ps.saber[saberNum].style != SS_NONE )
	{//change to the style we're supposed to be using
		ent->client->ps.saberAnimLevel = ent->client->ps.saber[saberNum].style;
		ent->client->ps.saberStylesKnown |= (1<<ent->client->ps.saberAnimLevel);
		if ( ent->s.number < MAX_CLIENTS )
		{
			cg.saberAnimLevelPending = ent->client->ps.saberAnimLevel; 
		}
	}
}
void Pickup_Saber( gentity_t *self, qboolean hadSaber, qboolean saberSolo, char *saberType, char *saberColor )
{
	//G_RemoveWeaponModels( ent );//???
	if ( Q_stricmp( "player", saberType ) == 0 )
	{//"player" means use cvar info
		G_SetSabersFromCVars( self );
	}
	else 
	{
		saberInfo_t	newSaber={0};
		if ( WP_SaberParseParms( saberType, &newSaber ) )
		{//successfully found a saber .sab entry to use
			//FIXME: what about dual sabers?
			int	saberNum = 0;
			if ( saberSolo//only supposed to use this one saber when grab this pickup
				|| newSaber.twoHanded //new saber is two-handed
				|| (hadSaber && self->client->ps.saber[0].twoHanded) )//old saber is two-handed
			{//replace the old right-hand saber and remove the left hand one
				WP_RemoveSaber( self, 1 );
			}
			else
			{//add it as a second saber
				saberNum = 1;
			}
			WP_SetSaber( self, saberNum, saberType );
			WP_SaberInitBladeData( self );
			if ( self->client->ps.saber[saberNum].style )
			{
				self->client->ps.saberStylesKnown |= (1<<self->client->ps.saber[saberNum].style);
			}
			if ( saberColor != NULL )
			{//NPC_targetname = saberColor
				saber_colors_t saber_color = TranslateSaberColor( saberColor );
				for ( int bladeNum = 0; bladeNum < MAX_BLADES; bladeNum++ )
				{
					self->client->ps.saber[saberNum].blade[bladeNum].color = saber_color;
				}
			}
		}
		WP_SaberFreeStrings(newSaber);
	}
}
Exemple #5
0
qboolean Pickup_Saber( gentity_t *self, qboolean hadSaber, gentity_t *pickUpSaber )
{
	//NOTE: loopAnim = saberSolo, alt_fire = saberLeftHand, NPC_type = saberType, NPC_targetname = saberColor
	qboolean foundIt = qfalse;

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

	//G_RemoveWeaponModels( ent );//???
	if ( Q_stricmp( "player", pickUpSaber->NPC_type ) == 0 )
	{//"player" means use cvar info
		G_SetSabersFromCVars( self );
		foundIt = qtrue;
	}
	else 
	{
		saberInfo_t	newSaber={0};
		qboolean swapSabers = qfalse;

		if ( self->client->ps.weapon == WP_SABER
			&& self->client->ps.weaponTime > 0 )
		{//can't pick up a new saber while the old one is busy (also helps to work as a debouncer so you don't swap out sabers rapidly when touching more than one at a time)
			return qfalse;
		}

		if ( pickUpSaber->count == 1
			&& g_saberPickuppableDroppedSabers->integer )
		{
			swapSabers = qtrue;
		}

		if ( WP_SaberParseParms( pickUpSaber->NPC_type, &newSaber ) )
		{//successfully found a saber .sab entry to use
			int	saberNum = 0;
			qboolean removeLeftSaber = qfalse;
			if ( pickUpSaber->alt_fire )
			{//always go in the left hand
				if ( !hadSaber )
				{//can't have a saber only in your left hand!
					return qfalse;
				}
				saberNum = 1;
				//just in case...
				removeLeftSaber = qtrue;
			}
			else if ( !hadSaber )
			{//don't have a saber at all yet, put it in our right hand
				saberNum = 0;
				//just in case...
				removeLeftSaber = qtrue;
			}
			else if ( pickUpSaber->loopAnim//only supposed to use this one saber when grab this pickup
				|| (newSaber.saberFlags&SFL_TWO_HANDED) //new saber is two-handed
				|| (hadSaber && (self->client->ps.saber[0].saberFlags&SFL_TWO_HANDED)) )//old saber is two-handed
			{//replace the old right-hand saber and remove the left hand one
				saberNum = 0;
				removeLeftSaber = qtrue;
			}
			else
			{//have, at least, a saber in our right hand and the new one could go in either left or right hand
				if ( self->client->ps.dualSabers )
				{//I already have 2 sabers
					vec3_t dir2Saber, rightDir;
					//to determine which one to replace, see which side of me it's on
					VectorSubtract( pickUpSaber->currentOrigin, self->currentOrigin, dir2Saber );
					dir2Saber[2] = 0;
					AngleVectors( self->currentAngles, NULL, rightDir, NULL );
					rightDir[2] = 0;
					if ( DotProduct( rightDir, dir2Saber ) > 0 )
					{
						saberNum = 0;
					}
					else
					{
						saberNum = 1;
						//just in case...
						removeLeftSaber = qtrue;
					}
				}
				else
				{//just add it as a second saber
					saberNum = 1;
					//just in case...
					removeLeftSaber = qtrue;
				}
			}
			if ( saberNum == 0 )
			{//want to reach out with right hand
				if ( self->client->ps.torsoAnim == BOTH_BUTTON_HOLD )
				{//but only if already playing the pickup with left hand anim...
					NPC_SetAnim( self, SETANIM_TORSO, BOTH_SABERPULL, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD );
				}
				if ( swapSabers )
				{//drop first one where the one we're picking up is
					G_DropSaberItem( self->client->ps.saber[saberNum].name, self->client->ps.saber[saberNum].blade[0].color, pickUpSaber->currentOrigin, (float *)vec3_origin, pickUpSaber->currentAngles, pickUpSaber );
					if ( removeLeftSaber )
					{//drop other one at my origin
						G_DropSaberItem( self->client->ps.saber[1].name, self->client->ps.saber[1].blade[0].color, self->currentOrigin, (float *)vec3_origin, self->currentAngles, pickUpSaber );
					}
				}
			}
			else
			{
				if ( swapSabers )
				{
					G_DropSaberItem( self->client->ps.saber[saberNum].name, self->client->ps.saber[saberNum].blade[0].color, pickUpSaber->currentOrigin, (float *)vec3_origin, pickUpSaber->currentAngles, pickUpSaber );
				}
			}
			if ( removeLeftSaber )
			{
				WP_RemoveSaber( self, 1 );
			}
			WP_SetSaber( self, saberNum, pickUpSaber->NPC_type );
			WP_SaberInitBladeData( self );
			if ( self->client->ps.saber[saberNum].stylesLearned )
			{
				self->client->ps.saberStylesKnown |= self->client->ps.saber[saberNum].stylesLearned;
			}
			if ( self->client->ps.saber[saberNum].singleBladeStyle )
			{
				self->client->ps.saberStylesKnown |= self->client->ps.saber[saberNum].singleBladeStyle;
			}
			if ( pickUpSaber->NPC_targetname != NULL )
			{//NPC_targetname = saberColor
				saber_colors_t saber_color = TranslateSaberColor( pickUpSaber->NPC_targetname );
				for ( int bladeNum = 0; bladeNum < MAX_BLADES; bladeNum++ )
				{
					self->client->ps.saber[saberNum].blade[bladeNum].color = saber_color;
				}
			}
			if ( self->client->ps.torsoAnim == BOTH_BUTTON_HOLD 
				|| self->client->ps.torsoAnim == BOTH_SABERPULL )
			{//don't let them attack right away, force them to finish the anim
				self->client->ps.weaponTime = self->client->ps.torsoAnimTimer;
			}
			foundIt = qtrue;
		}
		WP_SaberFreeStrings(newSaber);
	}
	return foundIt;
}
Exemple #6
0
/*
================
G_BounceItem

================
*/
void G_BounceItem( gentity_t *ent, trace_t *trace ) {
	vec3_t	velocity;
	float	dot;
	int		hitTime;
	qboolean droppedSaber = qtrue;

	if ( ent->item
		&& ent->item->giType == IT_WEAPON
		&& ent->item->giTag == WP_SABER 
		&& (ent->flags&FL_DROPPED_ITEM) )
	{
		droppedSaber = qtrue;
	}

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

	// cut the velocity to keep from bouncing forever
	VectorScale( ent->s.pos.trDelta, ent->physicsBounce, ent->s.pos.trDelta );

	if ( droppedSaber )
	{//a dropped saber item
		//FIXME: use NPC_type (as saberType) to get proper bounce sound?
		WP_SaberFallSound( NULL, ent );
	}

	// check for stop
	if ( trace->plane.normal[2] > 0 && ent->s.pos.trDelta[2] < 40 ) 
	{//stop
		G_SetOrigin( ent, trace->endpos );
		ent->s.groundEntityNum = trace->entityNum;
		if ( droppedSaber )
		{//a dropped saber item
			//stop rotation
			VectorClear( ent->s.apos.trDelta );
			ent->currentAngles[PITCH] = SABER_PITCH_HACK;
			ent->currentAngles[ROLL] = 0;
			if ( ent->NPC_type 
				&& ent->NPC_type[0] )
			{//we have a valid saber for this
				saberInfo_t saber;
				if ( WP_SaberParseParms( ent->NPC_type, &saber ) )
				{
					if ( (saber.saberFlags&SFL_BOLT_TO_WRIST) )
					{
						ent->currentAngles[PITCH] = 0;
					}
				}
			}
			pitch_roll_for_slope( ent, trace->plane.normal, ent->currentAngles, qtrue );
			G_SetAngles( ent, ent->currentAngles );
		}
		return;
	}
	//bounce
	if ( droppedSaber )
	{//a dropped saber item
		//change rotation
		VectorCopy( ent->currentAngles, ent->s.apos.trBase );
		ent->s.apos.trType = TR_LINEAR;
		ent->s.apos.trTime = level.time;
		VectorSet( ent->s.apos.trDelta, Q_irand( -300, 300 ), Q_irand( -300, 300 ), Q_irand( -300, 300 ) );
	}

	VectorAdd( ent->currentOrigin, trace->plane.normal, ent->currentOrigin);
	VectorCopy( ent->currentOrigin, ent->s.pos.trBase );
	ent->s.pos.trTime = level.time;
}
Exemple #7
0
void FinishSpawningItem( gentity_t *ent ) {
	trace_t		tr;
	vec3_t		dest;
	gitem_t		*item;
	int			itemNum;

	itemNum=1;
	for ( item = bg_itemlist + 1 ; item->classname ; item++,itemNum++) 
	{
		if (!strcmp(item->classname,ent->classname))
		{
			break;
		}
	}

	// Set bounding box for item
	VectorSet( ent->mins, item->mins[0],item->mins[1] ,item->mins[2]);
	VectorSet( ent->maxs, item->maxs[0],item->maxs[1] ,item->maxs[2]);

	if ((!ent->mins[0] && !ent->mins[1] && !ent->mins[2]) && 
		(!ent->maxs[0] && !ent->maxs[1] && !ent->maxs[2]))
	{
		VectorSet (ent->mins, -ITEM_RADIUS, -ITEM_RADIUS, -2);//to match the comments in the items.dat file!
		VectorSet (ent->maxs, ITEM_RADIUS, ITEM_RADIUS, ITEM_RADIUS);
	}

	if ((item->quantity) && (item->giType == IT_AMMO))
	{
		ent->count = item->quantity;
	}

	if ((item->quantity) && (item->giType == IT_BATTERY))
	{
		ent->count = item->quantity; 
	}

	ent->s.radius = 20;
	VectorSet( ent->s.modelScale, 1.0f, 1.0f, 1.0f );

	if ( ent->item->giType == IT_WEAPON
		&& ent->item->giTag == WP_SABER
		&& ent->NPC_type
		&& ent->NPC_type[0] )
	{
		saberInfo_t itemSaber;
		if ( Q_stricmp( "player", ent->NPC_type ) == 0
			&& g_saber->string
			&& g_saber->string[0]
			&& Q_stricmp( "none", g_saber->string )
			&& Q_stricmp( "NULL", g_saber->string ) )
		{//player's saber
			WP_SaberParseParms( g_saber->string, &itemSaber );
		}
		else
		{//specific saber
			WP_SaberParseParms( ent->NPC_type, &itemSaber );
		}
		//NOTE:  should I keep this string around for any reason?  Will I ever need it later?
		//ent->??? = G_NewString( itemSaber.model );
		gi.G2API_InitGhoul2Model( ent->ghoul2, itemSaber.model, G_ModelIndex( itemSaber.model ), NULL_HANDLE, NULL_HANDLE, 0, 0);
		WP_SaberFreeStrings(itemSaber);
	}
	else
	{
		gi.G2API_InitGhoul2Model( ent->ghoul2, ent->item->world_model, G_ModelIndex( ent->item->world_model ), NULL_HANDLE, NULL_HANDLE, 0, 0);
	}

	// Set crystal ammo amount based on skill level
/*	if ((itemNum == ITM_AMMO_CRYSTAL_BORG) ||
		(itemNum == ITM_AMMO_CRYSTAL_DN) ||
		(itemNum == ITM_AMMO_CRYSTAL_FORGE) ||
		(itemNum == ITM_AMMO_CRYSTAL_SCAVENGER) ||
		(itemNum == ITM_AMMO_CRYSTAL_STASIS))
	{
		CrystalAmmoSettings(ent);
	}
*/
	ent->s.eType = ET_ITEM;
	ent->s.modelindex = ent->item - bg_itemlist;		// store item number in modelindex
	ent->s.modelindex2 = 0; // zero indicates this isn't a dropped item

	ent->contents = CONTENTS_TRIGGER|CONTENTS_ITEM;//CONTENTS_BODY;//CONTENTS_TRIGGER|
	ent->e_TouchFunc = touchF_Touch_Item;
	// useing an item causes it to respawn
	ent->e_UseFunc = useF_Use_Item;
	ent->svFlags |= SVF_PLAYER_USABLE;//so player can pick it up

	// Hang in air?
	ent->s.origin[2] += 1;//just to get it off the damn ground because coplanar = insolid
	if ( (ent->spawnflags&ITMSF_SUSPEND)
		|| (ent->flags&FL_DROPPED_ITEM) ) 
	{
		// suspended
		G_SetOrigin( ent, ent->s.origin );
	} 
	else 
	{
		// drop to floor
		VectorSet( dest, ent->s.origin[0], ent->s.origin[1], MIN_WORLD_COORD );
		gi.trace( &tr, ent->s.origin, ent->mins, ent->maxs, dest, ent->s.number, MASK_SOLID|CONTENTS_PLAYERCLIP, (EG2_Collision)0, 0 );
		if ( tr.startsolid ) 
		{
			if ( &g_entities[tr.entityNum] != NULL )
			{
				gi.Printf (S_COLOR_RED"FinishSpawningItem: removing %s startsolid at %s (in a %s)\n", ent->classname, vtos(ent->s.origin), g_entities[tr.entityNum].classname );
			}
			else
			{
				gi.Printf (S_COLOR_RED"FinishSpawningItem: removing %s startsolid at %s (in a %s)\n", ent->classname, vtos(ent->s.origin) );
			}
			assert( 0 && "item starting in solid");
			if (!g_entities[ENTITYNUM_WORLD].s.radius){	//not a region
				delayedShutDown = level.time + 100;
			}
			G_FreeEntity( ent );
			return;
		}

		// allow to ride movers
		ent->s.groundEntityNum = tr.entityNum;

		G_SetOrigin( ent, tr.endpos );
	}

/* ? don't need this
	// team slaves and targeted items aren't present at start
	if ( ( ent->flags & FL_TEAMSLAVE ) || ent->targetname ) {
		ent->s.eFlags |= EF_NODRAW;
		ent->contents = 0;
		return;
	}
*/
	if ( ent->spawnflags & ITMSF_INVISIBLE ) // invisible
	{
		ent->s.eFlags |= EF_NODRAW;
		ent->contents = 0;
	}

	if ( ent->spawnflags & ITMSF_NOTSOLID ) // not solid
	{
		ent->contents = 0;
	}

	if ( (ent->spawnflags&ITMSF_STATIONARY) )
	{//can't be pushed around
		ent->flags |= FL_NO_KNOCKBACK;
	}

	if ( (ent->flags&FL_DROPPED_ITEM) ) 
	{//go away after 30 seconds
		ent->e_ThinkFunc = thinkF_G_FreeEntity;
		ent->nextthink = level.time + 30000;
	}

	gi.linkentity (ent);
}