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); } }
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; }
int Pickup_Weapon (gentity_t *ent, gentity_t *other) { int quantity; qboolean hadWeapon = qfalse; /* if ( ent->count || (ent->activator && !ent->activator->s.number) ) { quantity = ent->count; } else { quantity = ent->item->quantity; } */ // dropped items are always picked up if ( ent->flags & FL_DROPPED_ITEM ) { quantity = ent->count; } else {//wasn't dropped quantity = ent->item->quantity?ent->item->quantity:50; } // add the weapon if ( other->client->ps.stats[STAT_WEAPONS] & ( 1 << ent->item->giTag ) ) { hadWeapon = qtrue; } other->client->ps.stats[STAT_WEAPONS] |= ( 1 << ent->item->giTag ); if ( ent->item->giTag == WP_SABER && !hadWeapon ) { WP_SaberInitBladeData( other ); } if ( other->s.number ) {//NPC if ( other->s.weapon == WP_NONE ) {//NPC with no weapon picked up a weapon, change to this weapon //FIXME: clear/set the alt-fire flag based on the picked up weapon and my class? other->client->ps.weapon = ent->item->giTag; other->client->ps.weaponstate = WEAPON_RAISING; ChangeWeapon( other, ent->item->giTag ); if ( ent->item->giTag == WP_SABER ) { other->client->ps.saberActive = qtrue; G_CreateG2AttachedWeaponModel( other, other->client->ps.saberModel ); } else { G_CreateG2AttachedWeaponModel( other, weaponData[ent->item->giTag].weaponMdl ); } } } if ( quantity ) { // Give ammo Add_Ammo( other, ent->item->giTag, quantity ); } return 5; }
/* =========== ClientBegin called when a client has finished connecting, and is ready to be placed into the level. This will happen every level load, and on transition between teams, but doesn't happen on respawns ============ */ void ClientBegin( int clientNum, qboolean allowTeamReset ) { gentity_t *ent; gclient_t *client; gentity_t *tent; int flags, i; char userinfo[MAX_INFO_VALUE], *modelname; ent = g_entities + clientNum; if ((ent->r.svFlags & SVF_BOT) && g_gametype.integer >= GT_TEAM) { if (allowTeamReset) { const char *team = "Red"; int preSess; //SetTeam(ent, ""); ent->client->sess.sessionTeam = PickTeam(-1); trap_GetUserinfo(clientNum, userinfo, MAX_INFO_STRING); if (ent->client->sess.sessionTeam == TEAM_SPECTATOR) { ent->client->sess.sessionTeam = TEAM_RED; } if (ent->client->sess.sessionTeam == TEAM_RED) { team = "Red"; } else { team = "Blue"; } Info_SetValueForKey( userinfo, "team", team ); trap_SetUserinfo( clientNum, userinfo ); ent->client->ps.persistant[ PERS_TEAM ] = ent->client->sess.sessionTeam; preSess = ent->client->sess.sessionTeam; G_ReadSessionData( ent->client ); ent->client->sess.sessionTeam = preSess; G_WriteClientSessionData(ent->client); ClientUserinfoChanged( clientNum ); ClientBegin(clientNum, qfalse); return; } } client = level.clients + clientNum; if ( ent->r.linked ) { trap_UnlinkEntity( ent ); } G_InitGentity( ent ); ent->touch = 0; ent->pain = 0; ent->client = client; client->pers.connected = CON_CONNECTED; client->pers.enterTime = level.time; client->pers.teamState.state = TEAM_BEGIN; // save eflags around this, because changing teams will // cause this to happen with a valid entity, and we // want to make sure the teleport bit is set right // so the viewpoint doesn't interpolate through the // world to the new position flags = client->ps.eFlags; i = 0; while (i < NUM_FORCE_POWERS) { if (ent->client->ps.fd.forcePowersActive & (1 << i)) { WP_ForcePowerStop(ent, i); } i++; } i = TRACK_CHANNEL_1; while (i < NUM_TRACK_CHANNELS) { if (ent->client->ps.fd.killSoundEntIndex[i-50] && ent->client->ps.fd.killSoundEntIndex[i-50] < MAX_GENTITIES && ent->client->ps.fd.killSoundEntIndex[i-50] > 0) { G_MuteSound(ent->client->ps.fd.killSoundEntIndex[i-50], CHAN_VOICE); } i++; } i = 0; memset( &client->ps, 0, sizeof( client->ps ) ); client->ps.eFlags = flags; client->ps.hasDetPackPlanted = qfalse; //first-time force power initialization WP_InitForcePowers( ent ); //init saber ent WP_SaberInitBladeData( ent ); // First time model setup for that player. trap_GetUserinfo( clientNum, userinfo, sizeof(userinfo) ); modelname = Info_ValueForKey (userinfo, "model"); SetupGameGhoul2Model(client, modelname); if (ent->client->ghoul2) { ent->bolt_Head = trap_G2API_AddBolt(ent->client->ghoul2, 0, "cranium"); ent->bolt_Waist = trap_G2API_AddBolt(ent->client->ghoul2, 0, "thoracic"); ent->bolt_LArm = trap_G2API_AddBolt(ent->client->ghoul2, 0, "lradius"); ent->bolt_RArm = trap_G2API_AddBolt(ent->client->ghoul2, 0, "rradius"); ent->bolt_LLeg = trap_G2API_AddBolt(ent->client->ghoul2, 0, "ltibia"); ent->bolt_RLeg = trap_G2API_AddBolt(ent->client->ghoul2, 0, "rtibia"); ent->bolt_Motion = trap_G2API_AddBolt(ent->client->ghoul2, 0, "Motion"); } // locate ent at a spawn point ClientSpawn( ent ); if ( client->sess.sessionTeam != TEAM_SPECTATOR ) { // send event tent = G_TempEntity( ent->client->ps.origin, EV_PLAYER_TELEPORT_IN ); tent->s.clientNum = ent->s.clientNum; if ( g_gametype.integer != GT_TOURNAMENT ) { trap_SendServerCommand( -1, va("print \"%s" S_COLOR_WHITE " %s\n\"", client->pers.netname, G_GetStripEdString("SVINGAME", "PLENTER")) ); } } G_LogPrintf( "ClientBegin: %i\n", clientNum ); // count current clients and rank for scoreboard CalculateRanks(); G_ClearClientLog(clientNum); }