void UI_SaberAttachToChar( itemDef_t *item ) { int numSabers = 1; int saberNum = 0; if ( trap_G2API_HasGhoul2ModelOnIndex(&(item->ghoul2),2) ) {//remove any extra models trap_G2API_RemoveGhoul2Model(&(item->ghoul2), 2); } if ( trap_G2API_HasGhoul2ModelOnIndex(&(item->ghoul2),1) ) {//remove any extra models trap_G2API_RemoveGhoul2Model(&(item->ghoul2), 1); } if ( uiInfo.movesTitleIndex == 4 /*MD_DUAL_SABERS*/ ) { numSabers = 2; } for ( saberNum = 0; saberNum < numSabers; saberNum++ ) { //bolt sabers char modelPath[MAX_QPATH]; char skinPath[MAX_QPATH]; char saber[MAX_QPATH]; UI_GetSaberForMenu( saber, saberNum ); if ( UI_SaberModelForSaber( saber, modelPath ) ) {//successfully found a model int g2Saber = trap_G2API_InitGhoul2Model( &(item->ghoul2), modelPath, 0, 0, 0, 0, 0 ); //add the model if ( g2Saber ) { int boltNum; //get the customSkin, if any if ( UI_SaberSkinForSaber( saber, skinPath ) ) { int g2skin = trap_R_RegisterSkin(skinPath); trap_G2API_SetSkin( item->ghoul2, g2Saber, 0, g2skin );//this is going to set the surfs on/off matching the skin file } else { trap_G2API_SetSkin( item->ghoul2, g2Saber, 0, 0 );//turn off custom skin } if ( saberNum == 0 ) { boltNum = trap_G2API_AddBolt( item->ghoul2, 0, "*r_hand"); } else { boltNum = trap_G2API_AddBolt( item->ghoul2, 0, "*l_hand"); } trap_G2API_AttachG2Model( item->ghoul2, g2Saber, item->ghoul2, boltNum, 0); } } } }
/* ------------------------- Mark1_dying ------------------------- */ void Mark1_dying( gentity_t *self ) { int num,newBolt; if (self->client->ps.torsoTimer>0) { if (TIMER_Done(self,"dyingExplosion")) { num = Q_irand( 1, 3); // Find place to generate explosion if (num == 1) { num = Q_irand( 8, 10); newBolt = trap_G2API_AddBolt( self->ghoul2, 0, va("*flash%d",num) ); NPC_Mark1_Part_Explode(self,newBolt); } else { num = Q_irand( 1, 6); newBolt = trap_G2API_AddBolt( self->ghoul2, 0, va("*torso_tube%d",num) ); NPC_Mark1_Part_Explode(self,newBolt); NPC_SetSurfaceOnOff( self, va("torso_tube%d",num), TURN_OFF ); } TIMER_Set( self, "dyingExplosion", Q_irand( 300, 1000 ) ); } // See which weapons are there // Randomly fire blaster if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm" )) // Is the blaster still on the model? { if (Q_irand( 1, 5) == 1) { SaveNPCGlobals(); SetNPCGlobals( self ); Mark1Dead_FireBlaster(); RestoreNPCGlobals(); } } // Randomly fire rocket if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "r_arm" )) // Is the rocket still on the model? { if (Q_irand( 1, 10) == 1) { SaveNPCGlobals(); SetNPCGlobals( self ); Mark1Dead_FireRocket(); RestoreNPCGlobals(); } } } }
void Rancor_SetBolts( gentity_t *self ) { if ( self && self->client ) { renderInfo_t *ri = &self->client->renderInfo; ri->handRBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*r_hand" ); ri->handLBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*l_hand" ); ri->headBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*head_eyes" ); ri->torsoBolt = trap_G2API_AddBolt( self->ghoul2, 0, "jaw_bone" ); } }
/* ------------------------- Mark1Dead_FireBlaster - Shoot the left weapon, the multi-blaster ------------------------- */ void Mark1Dead_FireBlaster (void) { vec3_t muzzle1,muzzle_dir; gentity_t *missile; mdxaBone_t boltMatrix; int bolt; bolt = trap_G2API_AddBolt(NPC->ghoul2, 0, "*flash1"); trap_G2API_GetBoltMatrix( NPC->ghoul2, 0, bolt, &boltMatrix, NPC->r.currentAngles, NPC->r.currentOrigin, level.time, NULL, NPC->modelScale ); BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, muzzle1 ); BG_GiveMeVectorFromMatrix( &boltMatrix, NEGATIVE_Y, muzzle_dir ); G_PlayEffectID( G_EffectIndex("bryar/muzzle_flash"), muzzle1, muzzle_dir ); missile = CreateMissile( muzzle1, muzzle_dir, 1600, 10000, NPC, qfalse ); G_Sound( NPC, CHAN_AUTO, G_SoundIndex("sound/chars/mark1/misc/mark1_fire")); missile->classname = "bryar_proj"; missile->s.weapon = WP_BRYAR_PISTOL; missile->damage = 1; missile->dflags = DAMAGE_DEATH_KNOCKBACK; missile->methodOfDeath = MOD_BRYAR_PISTOL; missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER; }
/* ------------------------- NPC_Mark2_Pain - look at what was hit and see if it should be removed from the model. ------------------------- */ void NPC_Mark2_Pain(gentity_t *self, gentity_t *attacker, int damage) { int newBolt,i; int hitLoc = gPainHitLoc; NPC_Pain( self, attacker, damage ); for (i=0;i<3;i++) { if ((hitLoc==HL_GENERIC1+i) && (self->locationDamage[HL_GENERIC1+i] > AMMO_POD_HEALTH)) // Blow it up? { if (self->locationDamage[hitLoc] >= AMMO_POD_HEALTH) { newBolt = trap_G2API_AddBolt( self->ghoul2, 0, va("torso_canister%d",(i+1)) ); if ( newBolt != -1 ) { NPC_Mark2_Part_Explode(self,newBolt); } NPC_SetSurfaceOnOff( self, va("torso_canister%d",(i+1)), TURN_OFF ); break; } } } G_Sound( self, CHAN_AUTO, G_SoundIndex( "sound/chars/mark2/misc/mark2_pain" )); // If any pods were blown off, kill him if (self->count > 0) { G_Damage( self, NULL, NULL, NULL, NULL, self->health, DAMAGE_NO_PROTECTION, MOD_UNKNOWN ); } }
/* ------------------------- ImperialProbe_FireBlaster ------------------------- */ void ImperialProbe_FireBlaster(void) { vec3_t muzzle1,enemy_org1,delta1,angleToEnemy1; static vec3_t forward, vright, up; // static vec3_t muzzle; int genBolt1; gentity_t *missile; mdxaBone_t boltMatrix; genBolt1 = trap_G2API_AddBolt(NPC->ghoul2, 0, "*flash"); //FIXME: use {0, NPC->client->ps.legsYaw, 0} trap_G2API_GetBoltMatrix( NPC->ghoul2, 0, genBolt1, &boltMatrix, NPC->r.currentAngles, NPC->r.currentOrigin, level.time, NULL, NPC->modelScale ); BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, muzzle1 ); G_PlayEffectID( G_EffectIndex("bryar/muzzle_flash"), muzzle1, vec3_origin ); G_Sound( NPC, CHAN_AUTO, G_SoundIndex( "sound/chars/probe/misc/fire" )); if (NPC->health) { CalcEntitySpot( NPC->enemy, SPOT_CHEST, enemy_org1 ); enemy_org1[0]+= Q_irand(0,10); enemy_org1[1]+= Q_irand(0,10); VectorSubtract (enemy_org1, muzzle1, delta1); vectoangles ( delta1, angleToEnemy1 ); AngleVectors (angleToEnemy1, forward, vright, up); } else { AngleVectors (NPC->r.currentAngles, forward, vright, up); } missile = CreateMissile( muzzle1, forward, 1600, 10000, NPC, qfalse ); missile->classname = "bryar_proj"; missile->s.weapon = WP_BRYAR_PISTOL; if ( g_spskill.integer <= 1 ) { missile->damage = 5; } else { missile->damage = 10; } missile->dflags = DAMAGE_DEATH_KNOCKBACK; missile->methodOfDeath = MOD_UNKNOWN; missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER; }
qboolean CG_SnapRefEntToBone(centity_t *cent, refEntity_t *refEnt, const char *bone_name) { centity_t *cl = cent; mdxaBone_t matrix; vec3_t boltOrg, holsterAngles, boltAng; //vec3_t out_axis[3]; int getBolt = -1; if (!cl->ghoul2) { assert(0); return qfalse; } if (cent->currentState.clientNum == cg.predictedPlayerState.clientNum && !cg.renderingThirdPerson) { //If in first person and you have it then render the thing spinning around on your hud. return qfalse; } getBolt = trap_G2API_AddBolt(cl->ghoul2, 0, bone_name); VectorCopy(cl->lerpAngles, holsterAngles); holsterAngles[PITCH] = 0; holsterAngles[ROLL] = 0; trap_G2API_GetBoltMatrix(cl->ghoul2, 0, getBolt, &matrix, holsterAngles /*cl->lerpAngles*/, cl->lerpOrigin, cg.time, cgs.gameModels, cl->modelScale); BG_GiveMeVectorFromMatrix(&matrix, ORIGIN, boltOrg); BG_GiveMeVectorFromMatrix(&matrix, NEGATIVE_Y, boltAng); vectoangles(boltAng, boltAng); //boltAng[PITCH] = boltAng[ROLL] = 0; //BG_GiveMeVectorFromMatrix(&matrix, ORIGIN, boltOrg); //BG_GiveMeVectorFromMatrix( &matrix, NEGATIVE_Y, refEnt->axis[0] );//out_axis[0] ); //BG_GiveMeVectorFromMatrix( &matrix, POSITIVE_X, refEnt->axis[1] );//out_axis[1] ); //BG_GiveMeVectorFromMatrix( &matrix, POSITIVE_Z, refEnt->axis[2] );//out_axis[2] ); VectorCopy(boltOrg, refEnt->origin); //VectorCopy(cl->lerpAngles, refEnt->angles); VectorCopy(boltAng, refEnt->angles); return qtrue; }
/* ------------------------- Mark1_FireRocket ------------------------- */ void Mark1_FireRocket(void) { mdxaBone_t boltMatrix; vec3_t muzzle1,enemy_org1,delta1,angleToEnemy1; static vec3_t forward, vright, up; int bolt = trap_G2API_AddBolt(NPC->ghoul2, 0, "*flash5"); gentity_t *missile; int damage = 50; trap_G2API_GetBoltMatrix( NPC->ghoul2, 0, bolt, &boltMatrix, NPC->r.currentAngles, NPC->r.currentOrigin, level.time, NULL, NPC->modelScale ); BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, muzzle1 ); // G_PlayEffect( "blaster/muzzle_flash", muzzle1 ); CalcEntitySpot( NPC->enemy, SPOT_HEAD, enemy_org1 ); VectorSubtract (enemy_org1, muzzle1, delta1); vectoangles ( delta1, angleToEnemy1 ); AngleVectors (angleToEnemy1, forward, vright, up); G_Sound( NPC, CHAN_AUTO, G_SoundIndex("sound/chars/mark1/misc/mark1_fire" )); missile = CreateMissile( muzzle1, forward, BOWCASTER_VELOCITY, 10000, NPC, qfalse ); missile->classname = "bowcaster_proj"; missile->s.weapon = WP_BOWCASTER; VectorSet( missile->r.maxs, BOWCASTER_SIZE, BOWCASTER_SIZE, BOWCASTER_SIZE ); VectorScale( missile->r.maxs, -1, missile->r.mins ); missile->damage = damage; missile->dflags = DAMAGE_DEATH_KNOCKBACK; missile->methodOfDeath = MOD_ROCKET; missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER; missile->splashDamage = BOWCASTER_SPLASH_DAMAGE; missile->splashRadius = BOWCASTER_SPLASH_RADIUS; // we don't want it to bounce missile->bounceCount = 0; }
/* ------------------------- Mark2_FireBlaster ------------------------- */ void Mark2_FireBlaster(qboolean advance) { vec3_t muzzle1,enemy_org1,delta1,angleToEnemy1; static vec3_t forward, vright, up; static vec3_t muzzle; gentity_t *missile; mdxaBone_t boltMatrix; int bolt = trap_G2API_AddBolt(NPC->ghoul2, 0, "*flash"); trap_G2API_GetBoltMatrix( NPC->ghoul2, 0, bolt, &boltMatrix, NPC->r.currentAngles, NPC->r.currentOrigin, level.time, NULL, NPC->modelScale ); BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, muzzle1 ); if (NPC->health) { CalcEntitySpot( NPC->enemy, SPOT_HEAD, enemy_org1 ); VectorSubtract (enemy_org1, muzzle1, delta1); vectoangles ( delta1, angleToEnemy1 ); AngleVectors (angleToEnemy1, forward, vright, up); } else { AngleVectors (NPC->r.currentAngles, forward, vright, up); } G_PlayEffectID( G_EffectIndex("bryar/muzzle_flash"), muzzle1, forward ); G_Sound( NPC, CHAN_AUTO, G_SoundIndex("sound/chars/mark2/misc/mark2_fire")); missile = CreateMissile( muzzle1, forward, 1600, 10000, NPC, qfalse ); missile->classname = "bryar_proj"; missile->s.weapon = WP_BRYAR_PISTOL; missile->damage = 1; missile->dflags = DAMAGE_DEATH_KNOCKBACK; missile->methodOfDeath = MOD_BRYAR_PISTOL; missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER; }
/* ================== CG_SetInitialSnapshot This will only happen on the very first snapshot, or on tourney restarts. All other times will use CG_TransitionSnapshot instead. FIXME: Also called by map_restart? ================== */ void CG_SetInitialSnapshot( snapshot_t *snap ) { int i; centity_t *cent; entityState_t *state; cg.snap = snap; if ((cg_entities[snap->ps.clientNum].ghoul2 == NULL) && trap_G2_HaveWeGhoul2Models(cgs.clientinfo[snap->ps.clientNum].ghoul2Model)) { trap_G2API_DuplicateGhoul2Instance(cgs.clientinfo[snap->ps.clientNum].ghoul2Model, &cg_entities[snap->ps.clientNum].ghoul2); CG_CopyG2WeaponInstance(&cg_entities[snap->ps.clientNum], FIRST_WEAPON, cg_entities[snap->ps.clientNum].ghoul2); if (trap_G2API_AddBolt(cg_entities[snap->ps.clientNum].ghoul2, 0, "face") == -1) { //check now to see if we have this bone for setting anims and such cg_entities[snap->ps.clientNum].noFace = qtrue; } } BG_PlayerStateToEntityState( &snap->ps, &cg_entities[ snap->ps.clientNum ].currentState, qfalse ); // sort out solid entities CG_BuildSolidList(); CG_ExecuteNewServerCommands( snap->serverCommandSequence ); // set our local weapon selection pointer to // what the server has indicated the current weapon is CG_Respawn(); for ( i = 0 ; i < cg.snap->numEntities ; i++ ) { state = &cg.snap->entities[ i ]; cent = &cg_entities[ state->number ]; memcpy(¢->currentState, state, sizeof(entityState_t)); //cent->currentState = *state; cent->interpolate = qfalse; cent->currentValid = qtrue; CG_ResetEntity( cent ); // check for events CG_CheckEvents( cent ); } }
/* ------------------------- Mark1Dead_FireRocket - Shoot the left weapon, the multi-blaster ------------------------- */ void Mark1Dead_FireRocket (void) { mdxaBone_t boltMatrix; vec3_t muzzle1,muzzle_dir; gentity_t *missile; int damage = 50; int bolt = trap_G2API_AddBolt(NPC->ghoul2, 0, "*flash5"); trap_G2API_GetBoltMatrix( NPC->ghoul2, 0, bolt, &boltMatrix, NPC->r.currentAngles, NPC->r.currentOrigin, level.time, NULL, NPC->modelScale ); BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, muzzle1 ); BG_GiveMeVectorFromMatrix( &boltMatrix, NEGATIVE_Y, muzzle_dir ); G_PlayEffectID( G_EffectIndex("bryar/muzzle_flash"), muzzle1, muzzle_dir ); G_Sound( NPC, CHAN_AUTO, G_SoundIndex("sound/chars/mark1/misc/mark1_fire")); missile = CreateMissile( muzzle1, muzzle_dir, BOWCASTER_VELOCITY, 10000, NPC, qfalse ); missile->classname = "bowcaster_proj"; missile->s.weapon = WP_BOWCASTER; VectorSet( missile->r.maxs, BOWCASTER_SIZE, BOWCASTER_SIZE, BOWCASTER_SIZE ); VectorScale( missile->r.maxs, -1, missile->r.mins ); missile->damage = damage; missile->dflags = DAMAGE_DEATH_KNOCKBACK; //missile->methodOfDeath = MOD_ENERGY; missile->methodOfDeath = MOD_ROCKET; missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER; missile->splashDamage = BOWCASTER_SPLASH_DAMAGE; missile->splashRadius = BOWCASTER_SPLASH_RADIUS; // we don't want it to bounce missile->bounceCount = 0; }
void UI_SaberDrawBlade( itemDef_t *item, char *saberName, int saberModel, saberType_t saberType, vec3_t origin, vec3_t angles, int bladeNum ) { char bladeColorString[MAX_QPATH]; saber_colors_t bladeColor; float bladeLength,bladeRadius; vec3_t bladeOrigin={0}; vec3_t axis[3]={0}; // vec3_t angles={0}; mdxaBone_t boltMatrix; qboolean tagHack = qfalse; char *tagName; int bolt; float scale; //[RGBSabers] int snum; //[/RGBSabers] if ( (item->flags&ITF_ISSABER) && saberModel < 2 ) { //[RGBSabers] snum = 0; trap_Cvar_VariableStringBuffer("ui_saber_color", bladeColorString, sizeof(bladeColorString) ); } else//if ( item->flags&ITF_ISSABER2 ) - presumed { snum = 1; //[/RGBSabers] trap_Cvar_VariableStringBuffer("ui_saber2_color", bladeColorString, sizeof(bladeColorString) ); } if ( !trap_G2API_HasGhoul2ModelOnIndex(&(item->ghoul2),saberModel) ) {//invalid index! return; } bladeColor = TranslateSaberColor( bladeColorString ); bladeLength = UI_SaberBladeLengthForSaber( saberName, bladeNum ); bladeRadius = UI_SaberBladeRadiusForSaber( saberName, bladeNum ); tagName = va( "*blade%d", bladeNum+1 ); bolt = trap_G2API_AddBolt( item->ghoul2,saberModel, tagName ); if ( bolt == -1 ) { tagHack = qtrue; //hmm, just fall back to the most basic tag (this will also make it work with pre-JKA saber models bolt = trap_G2API_AddBolt( item->ghoul2,saberModel, "*flash" ); if ( bolt == -1 ) {//no tag_flash either?!! bolt = 0; } } // angles[PITCH] = curYaw; // angles[ROLL] = 0; trap_G2API_GetBoltMatrix( item->ghoul2, saberModel, bolt, &boltMatrix, angles, origin, uiInfo.uiDC.realTime, NULL, vec3_origin );//NULL was cgs.model_draw // work the matrix axis stuff into the original axis and origins used. BG_GiveMeVectorFromMatrix(&boltMatrix, ORIGIN, bladeOrigin); BG_GiveMeVectorFromMatrix(&boltMatrix, NEGATIVE_Y, axis[0]);//front (was NEGATIVE_Y, but the md3->glm exporter screws up this tag somethin' awful) // ...changed this back to NEGATIVE_Y BG_GiveMeVectorFromMatrix(&boltMatrix, NEGATIVE_X, axis[1]);//right ... and changed this to NEGATIVE_X BG_GiveMeVectorFromMatrix(&boltMatrix, POSITIVE_Z, axis[2]);//up // Where do I get scale from? // scale = DC->xscale; scale = 1.0f; if ( tagHack ) { switch ( saberType ) { case SABER_SINGLE: VectorMA( bladeOrigin, scale, axis[0], bladeOrigin ); break; case SABER_DAGGER: case SABER_LANCE: break; case SABER_STAFF: if ( bladeNum == 0 ) { VectorMA( bladeOrigin, 12*scale, axis[0], bladeOrigin ); } if ( bladeNum == 1 ) { VectorScale( axis[0], -1, axis[0] ); VectorMA( bladeOrigin, 12*scale, axis[0], bladeOrigin ); } break; case SABER_BROAD: if ( bladeNum == 0 ) { VectorMA( bladeOrigin, -1*scale, axis[1], bladeOrigin ); } else if ( bladeNum == 1 ) { VectorMA( bladeOrigin, 1*scale, axis[1], bladeOrigin ); } break; case SABER_PRONG: if ( bladeNum == 0 ) { VectorMA( bladeOrigin, -3*scale, axis[1], bladeOrigin ); } else if ( bladeNum == 1 ) { VectorMA( bladeOrigin, 3*scale, axis[1], bladeOrigin ); } break; case SABER_ARC: VectorSubtract( axis[1], axis[2], axis[1] ); VectorNormalize( axis[1] ); switch ( bladeNum ) { case 0: VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); VectorScale( axis[0], 0.75f, axis[0] ); VectorScale( axis[1], 0.25f, axis[1] ); VectorAdd( axis[0], axis[1], axis[0] ); break; case 1: VectorScale( axis[0], 0.25f, axis[0] ); VectorScale( axis[1], 0.75f, axis[1] ); VectorAdd( axis[0], axis[1], axis[0] ); break; case 2: VectorMA( bladeOrigin, -8*scale, axis[0], bladeOrigin ); VectorScale( axis[0], -0.25f, axis[0] ); VectorScale( axis[1], 0.75f, axis[1] ); VectorAdd( axis[0], axis[1], axis[0] ); break; case 3: VectorMA( bladeOrigin, -16*scale, axis[0], bladeOrigin ); VectorScale( axis[0], -0.75f, axis[0] ); VectorScale( axis[1], 0.25f, axis[1] ); VectorAdd( axis[0], axis[1], axis[0] ); break; } break; case SABER_SAI: if ( bladeNum == 1 ) { VectorMA( bladeOrigin, -3*scale, axis[1], bladeOrigin ); } else if ( bladeNum == 2 ) { VectorMA( bladeOrigin, 3*scale, axis[1], bladeOrigin ); } break; case SABER_CLAW: switch ( bladeNum ) { case 0: VectorMA( bladeOrigin, 2*scale, axis[0], bladeOrigin ); VectorMA( bladeOrigin, 2*scale, axis[2], bladeOrigin ); break; case 1: VectorMA( bladeOrigin, 2*scale, axis[0], bladeOrigin ); VectorMA( bladeOrigin, 2*scale, axis[2], bladeOrigin ); VectorMA( bladeOrigin, 2*scale, axis[1], bladeOrigin ); break; case 2: VectorMA( bladeOrigin, 2*scale, axis[0], bladeOrigin ); VectorMA( bladeOrigin, 2*scale, axis[2], bladeOrigin ); VectorMA( bladeOrigin, -2*scale, axis[1], bladeOrigin ); break; } break; case SABER_STAR: switch ( bladeNum ) { case 0: VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; case 1: VectorScale( axis[0], 0.33f, axis[0] ); VectorScale( axis[2], 0.67f, axis[2] ); VectorAdd( axis[0], axis[2], axis[0] ); VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; case 2: VectorScale( axis[0], -0.33f, axis[0] ); VectorScale( axis[2], 0.67f, axis[2] ); VectorAdd( axis[0], axis[2], axis[0] ); VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; case 3: VectorScale( axis[0], -1, axis[0] ); VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; case 4: VectorScale( axis[0], -0.33f, axis[0] ); VectorScale( axis[2], -0.67f, axis[2] ); VectorAdd( axis[0], axis[2], axis[0] ); VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; case 5: VectorScale( axis[0], 0.33f, axis[0] ); VectorScale( axis[2], -0.67f, axis[2] ); VectorAdd( axis[0], axis[2], axis[0] ); VectorMA( bladeOrigin, 8*scale, axis[0], bladeOrigin ); break; } break; case SABER_TRIDENT: switch ( bladeNum ) { case 0: VectorMA( bladeOrigin, 24*scale, axis[0], bladeOrigin ); break; case 1: VectorMA( bladeOrigin, -6*scale, axis[1], bladeOrigin ); VectorMA( bladeOrigin, 24*scale, axis[0], bladeOrigin ); break; case 2: VectorMA( bladeOrigin, 6*scale, axis[1], bladeOrigin ); VectorMA( bladeOrigin, 24*scale, axis[0], bladeOrigin ); break; case 3: VectorMA( bladeOrigin, -32*scale, axis[0], bladeOrigin ); VectorScale( axis[0], -1, axis[0] ); break; } break; case SABER_SITH_SWORD: //no blade break; } } if ( saberType == SABER_SITH_SWORD ) {//draw no blade return; } //[RGBSabers] UI_DoSaber( bladeOrigin, axis[0], bladeLength, bladeLength, bladeRadius, bladeColor, snum ); //[/RGBSabers] }
void SetupGameGhoul2Model(gclient_t *client, char *modelname) { int handle; char afilename[MAX_QPATH]; char /**GLAName,*/ *slash; char GLAName[MAX_QPATH]; vec3_t tempVec = {0,0,0}; // First things first. If this is a ghoul2 model, then let's make sure we demolish this first. if (client->ghoul2 && trap_G2_HaveWeGhoul2Models(client->ghoul2)) { trap_G2API_CleanGhoul2Models(&(client->ghoul2)); } /* Com_sprintf( afilename, sizeof( afilename ), "models/players/%s/model.glm", modelname ); handle = trap_G2API_InitGhoul2Model(&client->ghoul2, afilename, 0, 0, -20, 0, 0); if (handle<0) { Com_sprintf( afilename, sizeof( afilename ), "models/players/kyle/model.glm" ); handle = trap_G2API_InitGhoul2Model(&client->ghoul2, afilename, 0, 0, -20, 0, 0); if (handle<0) { return; } } */ //rww - just load the "standard" model for the server" if (!precachedKyle) { Com_sprintf( afilename, sizeof( afilename ), "models/players/kyle/model.glm" ); handle = trap_G2API_InitGhoul2Model(&precachedKyle, afilename, 0, 0, -20, 0, 0); if (handle<0) { return; } } if (precachedKyle && trap_G2_HaveWeGhoul2Models(precachedKyle)) { trap_G2API_DuplicateGhoul2Instance(precachedKyle, &client->ghoul2); } else { return; } // The model is now loaded. GLAName[0] = 0; if (!BGPAFtextLoaded) { //get the location of the animation.cfg //GLAName = trap_G2API_GetGLAName( client->ghoul2, 0); trap_G2API_GetGLAName( client->ghoul2, 0, GLAName); if (!GLAName[0]) { if (!BG_ParseAnimationFile("models/players/_humanoid/animation.cfg")) { Com_Printf( "Failed to load animation file %s\n", afilename ); return; } return; } Q_strncpyz( afilename, GLAName, sizeof( afilename )); slash = Q_strrchr( afilename, '/' ); if ( slash ) { strcpy(slash, "/animation.cfg"); } // Now afilename holds just the path to the animation.cfg else { // Didn't find any slashes, this is a raw filename right in base (whish isn't a good thing) return; } // Try to load the animation.cfg for this model then. if ( !BG_ParseAnimationFile( afilename ) ) { // The GLA's animations failed if (!BG_ParseAnimationFile("models/players/_humanoid/animation.cfg")) { Com_Printf( "Failed to load animation file %s\n", afilename ); return; } } } trap_G2API_AddBolt(client->ghoul2, 0, "*r_hand"); trap_G2API_AddBolt(client->ghoul2, 0, "*l_hand"); // NOTE - ensure this sequence of bolt and bone accessing are always the same because the client expects them in a certain order trap_G2API_SetBoneAnim(client->ghoul2, 0, "model_root", 0, 12, BONE_ANIM_OVERRIDE_LOOP, 1.0f, level.time, -1, -1); trap_G2API_SetBoneAngles(client->ghoul2, 0, "upper_lumbar", tempVec, BONE_ANGLES_POSTMULT, POSITIVE_X, NEGATIVE_Y, NEGATIVE_Z, NULL, 0, level.time); trap_G2API_SetBoneAngles(client->ghoul2, 0, "cranium", tempVec, BONE_ANGLES_POSTMULT, POSITIVE_Z, NEGATIVE_Y, POSITIVE_X, NULL, 0, level.time); if (!g2SaberInstance) { trap_G2API_InitGhoul2Model(&g2SaberInstance, "models/weapons2/saber/saber_w.glm", 0, 0, -20, 0, 0); if (g2SaberInstance) { // indicate we will be bolted to model 0 (ie the player) on bolt 0 (always the right hand) when we get copied trap_G2API_SetBoltInfo(g2SaberInstance, 0, 0); // now set up the gun bolt on it trap_G2API_AddBolt(g2SaberInstance, 0, "*flash"); } } if (g2SaberInstance) { trap_G2API_CopySpecificGhoul2Model(g2SaberInstance, 0, client->ghoul2, 1); } }
/* ------------------------- NPC_Mark1_Pain - look at what was hit and see if it should be removed from the model. ------------------------- */ void NPC_Mark1_Pain(gentity_t *self, gentity_t *attacker, int damage) { int newBolt,i,chance; int hitLoc = gPainHitLoc; NPC_Pain( self, attacker, damage ); G_Sound( self, CHAN_AUTO, G_SoundIndex("sound/chars/mark1/misc/mark1_pain")); // Hit in the CHEST??? if (hitLoc==HL_CHEST) { chance = Q_irand( 1, 4); if ((chance == 1) && (damage > 5)) { NPC_SetAnim( self, SETANIM_BOTH, BOTH_PAIN1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD ); } } // Hit in the left arm? else if ((hitLoc==HL_ARM_LT) && (self->locationDamage[HL_ARM_LT] > LEFT_ARM_HEALTH)) { if (self->locationDamage[hitLoc] >= LEFT_ARM_HEALTH) // Blow it up? { newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*flash3" ); if ( newBolt != -1 ) { NPC_Mark1_Part_Explode(self,newBolt); } NPC_SetSurfaceOnOff( self, "l_arm", TURN_OFF ); } } // Hit in the right arm? else if ((hitLoc==HL_ARM_RT) && (self->locationDamage[HL_ARM_RT] > RIGHT_ARM_HEALTH)) // Blow it up? { if (self->locationDamage[hitLoc] >= RIGHT_ARM_HEALTH) { newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*flash4" ); if ( newBolt != -1 ) { NPC_Mark1_Part_Explode( self, newBolt ); } NPC_SetSurfaceOnOff( self, "r_arm", TURN_OFF ); } } // Check ammo pods else { for (i=0;i<6;i++) { if ((hitLoc==HL_GENERIC1+i) && (self->locationDamage[HL_GENERIC1+i] > AMMO_POD_HEALTH)) // Blow it up? { if (self->locationDamage[hitLoc] >= AMMO_POD_HEALTH) { newBolt = trap_G2API_AddBolt( self->ghoul2, 0, va("*torso_tube%d",(i+1)) ); if ( newBolt != -1 ) { NPC_Mark1_Part_Explode(self,newBolt); } NPC_SetSurfaceOnOff( self, va("torso_tube%d",(i+1)), TURN_OFF ); NPC_SetAnim( self, SETANIM_BOTH, BOTH_PAIN1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD ); break; } } } } // Are both guns shot off? if ((trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm" )>0) && (trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "r_arm" )>0)) { G_Damage(self,NULL,NULL,NULL,NULL,self->health,0,MOD_UNKNOWN); } }
void GM_Dying( gentity_t *self ) { if ( level.time - self->s.time < 4000 ) {//FIXME: need a real effect //self->s.powerups |= ( 1 << PW_SHOCKED ); //self->client->ps.powerups[PW_SHOCKED] = level.time + 1000; self->client->ps.electrifyTime = level.time + 1000; if ( TIMER_Done( self, "dyingExplosion" ) ) { int newBolt; switch ( Q_irand( 1, 14 ) ) { // Find place to generate explosion case 1: if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "r_hand" )) {//r_hand still there GM_CreateExplosion( self, trap_G2API_AddBolt(self->ghoul2, 0, "*flasha"), qtrue ); NPC_SetSurfaceOnOff( self, "r_hand", TURN_OFF ); } else if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "r_arm_middle" )) {//r_arm_middle still there newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*r_arm_elbow" ); NPC_SetSurfaceOnOff( self, "r_arm_middle", TURN_OFF ); } break; case 2: //FIXME: do only once? if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_hand" )) {//l_hand still there GM_CreateExplosion( self, trap_G2API_AddBolt(self->ghoul2, 0, "*flashc"), qfalse ); NPC_SetSurfaceOnOff( self, "l_hand", TURN_OFF ); } else if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm_wrist" )) {//l_arm_wrist still there newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*l_arm_cap_l_hand" ); NPC_SetSurfaceOnOff( self, "l_arm_wrist", TURN_OFF ); } else if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm_middle" )) {//l_arm_middle still there newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*l_arm_cap_l_hand" ); NPC_SetSurfaceOnOff( self, "l_arm_middle", TURN_OFF ); } else if (!trap_G2API_GetSurfaceRenderStatus( self->ghoul2, 0, "l_arm_augment" )) {//l_arm_augment still there newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*l_arm_elbow" ); NPC_SetSurfaceOnOff( self, "l_arm_augment", TURN_OFF ); } break; case 3: case 4: newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*hip_fr" ); GM_CreateExplosion( self, newBolt, qfalse ); break; case 5: case 6: newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*shldr_l" ); GM_CreateExplosion( self, newBolt, qfalse ); break; case 7: case 8: newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*uchest_r" ); GM_CreateExplosion( self, newBolt, qfalse ); break; case 9: case 10: GM_CreateExplosion( self, self->client->renderInfo.headBolt, qfalse ); break; case 11: newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*l_leg_knee" ); GM_CreateExplosion( self, newBolt, qtrue ); break; case 12: newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*r_leg_knee" ); GM_CreateExplosion( self, newBolt, qtrue ); break; case 13: newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*l_leg_foot" ); GM_CreateExplosion( self, newBolt, qtrue ); break; case 14: newBolt = trap_G2API_AddBolt( self->ghoul2, 0, "*r_leg_foot" ); GM_CreateExplosion( self, newBolt, qtrue ); break; } TIMER_Set( self, "dyingExplosion", Q_irand( 300, 1100 ) ); } } else {//one final, huge explosion G_PlayEffectID( G_EffectIndex("galak/explode"), self->r.currentOrigin, vec3_origin ); // G_PlayEffect( "small_chunks", self->r.currentOrigin ); // G_PlayEffect( "env/exp_trail_comp", self->r.currentOrigin, self->currentAngles ); self->nextthink = level.time + FRAMETIME; self->think = G_FreeEntity; } }
/*QUAKED worldspawn (0 0 0) ? Every map should have exactly one worldspawn. "music" music wav file "gravity" 800 is default gravity "message" Text to print during connection process */ void SP_worldspawn( void ) { char *text, temp[32]; int i; int lengthRed, lengthBlue, lengthGreen; G_SpawnString( "classname", "", &text ); if ( Q_stricmp( text, "worldspawn" ) ) { G_Error( "SP_worldspawn: The first entity isn't 'worldspawn'" ); } //The server will precache the standard model and animations, so that there is no hit //when the first client connnects. if (!BGPAFtextLoaded) { BG_ParseAnimationFile("models/players/_humanoid/animation.cfg"); } if (!precachedKyle) { trap_G2API_InitGhoul2Model(&precachedKyle, "models/players/kyle/model.glm", 0, 0, -20, 0, 0); } if (!g2SaberInstance) { trap_G2API_InitGhoul2Model(&g2SaberInstance, "models/weapons2/saber/saber_w.glm", 0, 0, -20, 0, 0); if (g2SaberInstance) { // indicate we will be bolted to model 0 (ie the player) on bolt 0 (always the right hand) when we get copied trap_G2API_SetBoltInfo(g2SaberInstance, 0, 0); // now set up the gun bolt on it trap_G2API_AddBolt(g2SaberInstance, 0, "*flash"); } } // make some data visible to connecting client trap_SetConfigstring( CS_GAME_VERSION, GAME_VERSION ); trap_SetConfigstring( CS_LEVEL_START_TIME, va("%i", level.startTime ) ); G_SpawnString( "music", "", &text ); trap_SetConfigstring( CS_MUSIC, text ); G_SpawnString( "message", "", &text ); trap_SetConfigstring( CS_MESSAGE, text ); // map specific message trap_SetConfigstring( CS_MOTD, g_motd.string ); // message of the day G_SpawnString( "gravity", "800", &text ); trap_Cvar_Set( "g_gravity", text ); G_SpawnString( "enableDust", "0", &text ); trap_Cvar_Set( "g_enableDust", text ); G_SpawnString( "enableBreath", "0", &text ); trap_Cvar_Set( "g_enableBreath", text ); g_entities[ENTITYNUM_WORLD].s.number = ENTITYNUM_WORLD; g_entities[ENTITYNUM_WORLD].classname = "worldspawn"; // see if we want a warmup time trap_SetConfigstring( CS_WARMUP, "" ); if ( g_restarted.integer ) { trap_Cvar_Set( "g_restarted", "0" ); level.warmupTime = 0; } else if ( g_doWarmup.integer && g_gametype.integer != GT_TOURNAMENT ) { // Turn it on level.warmupTime = -1; trap_SetConfigstring( CS_WARMUP, va("%i", level.warmupTime) ); G_LogPrintf( "Warmup:\n" ); } trap_SetConfigstring(CS_LIGHT_STYLES+(LS_STYLES_START*3)+0, defaultStyles[0][0]); trap_SetConfigstring(CS_LIGHT_STYLES+(LS_STYLES_START*3)+1, defaultStyles[0][1]); trap_SetConfigstring(CS_LIGHT_STYLES+(LS_STYLES_START*3)+2, defaultStyles[0][2]); for(i=1;i<LS_NUM_STYLES;i++) { Com_sprintf(temp, sizeof(temp), "ls_%dr", i); G_SpawnString(temp, defaultStyles[i][0], &text); lengthRed = strlen(text); trap_SetConfigstring(CS_LIGHT_STYLES+((i+LS_STYLES_START)*3)+0, text); Com_sprintf(temp, sizeof(temp), "ls_%dg", i); G_SpawnString(temp, defaultStyles[i][1], &text); lengthGreen = strlen(text); trap_SetConfigstring(CS_LIGHT_STYLES+((i+LS_STYLES_START)*3)+1, text); Com_sprintf(temp, sizeof(temp), "ls_%db", i); G_SpawnString(temp, defaultStyles[i][2], &text); lengthBlue = strlen(text); trap_SetConfigstring(CS_LIGHT_STYLES+((i+LS_STYLES_START)*3)+2, text); if (lengthRed != lengthGreen || lengthGreen != lengthBlue) { Com_Error(ERR_DROP, "Style %d has inconsistent lengths: R %d, G %d, B %d", i, lengthRed, lengthGreen, lengthBlue); } } }
void TurretClientRun(centity_t *ent) { if (!ent->ghoul2) { weaponInfo_t *weaponInfo; trap_G2API_InitGhoul2Model(&ent->ghoul2, CG_ConfigString( CS_MODELS+ent->currentState.modelindex ), 0, 0, 0, 0, 0); if (!ent->ghoul2) { //bad return; } ent->torsoBolt = trap_G2API_AddBolt( ent->ghoul2, 0, "*flash02" ); trap_G2API_SetBoneAngles( ent->ghoul2, 0, "bone_hinge", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_Y, POSITIVE_Z, POSITIVE_X, NULL, 100, cg.time ); trap_G2API_SetBoneAngles( ent->ghoul2, 0, "bone_gback", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_Y, POSITIVE_Z, POSITIVE_X, NULL, 100, cg.time ); trap_G2API_SetBoneAngles( ent->ghoul2, 0, "bone_barrel", vec3_origin, BONE_ANGLES_POSTMULT, POSITIVE_Y, POSITIVE_Z, POSITIVE_X, NULL, 100, cg.time ); trap_G2API_SetBoneAnim( ent->ghoul2, 0, "model_root", 0, 11, BONE_ANIM_OVERRIDE_FREEZE, 0.8f, cg.time, 0, 0 ); ent->turAngles[ROLL] = 0; ent->turAngles[PITCH] = 90; ent->turAngles[YAW] = 0; weaponInfo = &cg_weapons[WP_TURRET]; if ( !weaponInfo->registered ) { CG_RegisterWeapon(WP_TURRET); } } if (ent->currentState.fireflag == 2) { //I'm about to blow if (ent->turAngles) { trap_G2API_SetBoneAngles( ent->ghoul2, 0, "bone_hinge", ent->turAngles, BONE_ANGLES_REPLACE, NEGATIVE_Y, NEGATIVE_Z, NEGATIVE_X, NULL, 100, cg.time ); } return; } else if (ent->currentState.fireflag && ent->bolt4 != ent->currentState.fireflag) { vec3_t muzzleOrg, muzzleDir; mdxaBone_t boltMatrix; trap_G2API_GetBoltMatrix(ent->ghoul2, 0, ent->torsoBolt, &boltMatrix, /*ent->lerpAngles*/vec3_origin, ent->lerpOrigin, cg.time, cgs.gameModels, ent->modelScale); BG_GiveMeVectorFromMatrix(&boltMatrix, ORIGIN, muzzleOrg); BG_GiveMeVectorFromMatrix(&boltMatrix, NEGATIVE_X, muzzleDir); trap_FX_PlayEffectID(cgs.effects.mTurretMuzzleFlash, muzzleOrg, muzzleDir, -1, -1); ent->bolt4 = ent->currentState.fireflag; } else if (!ent->currentState.fireflag) { ent->bolt4 = 0; } if (ent->currentState.bolt2 != ENTITYNUM_NONE) { //turn toward the enemy centity_t *enemy = &cg_entities[ent->currentState.bolt2]; if (enemy) { vec3_t enAng; vec3_t enPos; VectorCopy(enemy->currentState.pos.trBase, enPos); VectorSubtract(enPos, ent->lerpOrigin, enAng); VectorNormalize(enAng); vectoangles(enAng, enAng); enAng[ROLL] = 0; enAng[PITCH] += 90; CreepToPosition(enAng, ent->turAngles); } } else { vec3_t idleAng; float turnAmount; if (ent->turAngles[YAW] > 360) { ent->turAngles[YAW] -= 361; } if (!ent->dustTrailTime) { ent->dustTrailTime = cg.time; } turnAmount = (cg.time-ent->dustTrailTime)*0.03; if (turnAmount > 360) { turnAmount = 360; } idleAng[PITCH] = 90; idleAng[ROLL] = 0; idleAng[YAW] = ent->turAngles[YAW] + turnAmount; ent->dustTrailTime = cg.time; CreepToPosition(idleAng, ent->turAngles); } if (cg.time < ent->frame_minus1_refreshed) { ent->frame_minus1_refreshed = cg.time; return; } ent->frame_minus1_refreshed = cg.time; trap_G2API_SetBoneAngles( ent->ghoul2, 0, "bone_hinge", ent->turAngles, BONE_ANGLES_REPLACE, NEGATIVE_Y, NEGATIVE_Z, NEGATIVE_X, NULL, 100, cg.time ); }
void SP_worldspawn( void ) { char *text, temp[32]; int i; int lengthRed, lengthBlue, lengthGreen; //I want to "cull" entities out of net sends to clients to reduce //net traffic on our larger open maps -rww G_SpawnFloat("distanceCull", "6000.0", &g_cullDistance); trap_SetServerCull(g_cullDistance); G_SpawnString( "classname", "", &text ); if ( Q_stricmp( text, "worldspawn" ) ) { G_Error( "SP_worldspawn: The first entity isn't 'worldspawn'" ); } for ( i = 0 ; i < level.numSpawnVars ; i++ ) { if ( Q_stricmp( "spawnscript", level.spawnVars[i][0] ) == 0 ) {//ONly let them set spawnscript, we don't want them setting an angle or something on the world. G_ParseField( level.spawnVars[i][0], level.spawnVars[i][1], &g_entities[ENTITYNUM_WORLD] ); } } //The server will precache the standard model and animations, so that there is no hit //when the first client connnects. if (!BGPAFtextLoaded) { BG_ParseAnimationFile("models/players/_humanoid/animation.cfg", bgHumanoidAnimations, qtrue); } if (!precachedKyle) { int defSkin; trap_G2API_InitGhoul2Model(&precachedKyle, "models/players/kyle/model.glm", 0, 0, -20, 0, 0); if (precachedKyle) { defSkin = trap_R_RegisterSkin("models/players/kyle/model_default.skin"); trap_G2API_SetSkin(precachedKyle, 0, defSkin, defSkin); } } if (!g2SaberInstance) { trap_G2API_InitGhoul2Model(&g2SaberInstance, "models/weapons2/saber/saber_w.glm", 0, 0, -20, 0, 0); if (g2SaberInstance) { // indicate we will be bolted to model 0 (ie the player) on bolt 0 (always the right hand) when we get copied trap_G2API_SetBoltInfo(g2SaberInstance, 0, 0); // now set up the gun bolt on it trap_G2API_AddBolt(g2SaberInstance, 0, "*blade1"); } } if (g_gametype.integer == GT_SIEGE) { //a tad bit of a hack, but.. EWebPrecache(); } // make some data visible to connecting client trap_SetConfigstring( CS_GAME_VERSION, GAME_VERSION ); trap_SetConfigstring( CS_LEVEL_START_TIME, va("%i", level.startTime ) ); G_SpawnString( "music", "", &text ); trap_SetConfigstring( CS_MUSIC, text ); G_SpawnString( "message", "", &text ); trap_SetConfigstring( CS_MESSAGE, text ); // map specific message trap_SetConfigstring( CS_MOTD, g_motd.string ); // message of the day G_SpawnString( "gravity", "800", &text ); trap_Cvar_Set( "g_gravity", text ); G_SpawnString( "enableBreath", "0", &text ); trap_Cvar_Set( "g_enableBreath", text ); G_SpawnString( "soundSet", "default", &text ); trap_SetConfigstring( CS_GLOBAL_AMBIENT_SET, text ); g_entities[ENTITYNUM_WORLD].s.number = ENTITYNUM_WORLD; g_entities[ENTITYNUM_WORLD].classname = "worldspawn"; // see if we want a warmup time trap_SetConfigstring( CS_WARMUP, "" ); if ( g_restarted.integer ) { trap_Cvar_Set( "g_restarted", "0" ); level.warmupTime = 0; } //Raz: Fix warmup #if 0 /* else if ( g_doWarmup.integer && g_gametype.integer != GT_DUEL && g_gametype.integer != GT_POWERDUEL ) { // Turn it on else if ( g_doWarmup.integer && level.gametype != GT_DUEL && level.gametype != GT_POWERDUEL ) { // Turn it on level.warmupTime = -1; trap_SetConfigstring( CS_WARMUP, va("%i", level.warmupTime) ); G_LogPrintf( "Warmup:\n" ); } */ #else else if ( g_doWarmup.integer && g_gametype.integer != GT_DUEL && g_gametype.integer != GT_POWERDUEL && g_gametype.integer != GT_SIEGE ) { // Turn it on level.warmupTime = -1; trap_SetConfigstring( CS_WARMUP, va("%i", level.warmupTime) ); G_LogPrintf( "Warmup:\n" ); } #endif trap_SetConfigstring(CS_LIGHT_STYLES+(LS_STYLES_START*3)+0, defaultStyles[0][0]); trap_SetConfigstring(CS_LIGHT_STYLES+(LS_STYLES_START*3)+1, defaultStyles[0][1]); trap_SetConfigstring(CS_LIGHT_STYLES+(LS_STYLES_START*3)+2, defaultStyles[0][2]); for(i=1;i<LS_NUM_STYLES;i++) { Com_sprintf(temp, sizeof(temp), "ls_%dr", i); G_SpawnString(temp, defaultStyles[i][0], &text); lengthRed = strlen(text); trap_SetConfigstring(CS_LIGHT_STYLES+((i+LS_STYLES_START)*3)+0, text); Com_sprintf(temp, sizeof(temp), "ls_%dg", i); G_SpawnString(temp, defaultStyles[i][1], &text); lengthGreen = strlen(text); trap_SetConfigstring(CS_LIGHT_STYLES+((i+LS_STYLES_START)*3)+1, text); Com_sprintf(temp, sizeof(temp), "ls_%db", i); G_SpawnString(temp, defaultStyles[i][2], &text); lengthBlue = strlen(text); trap_SetConfigstring(CS_LIGHT_STYLES+((i+LS_STYLES_START)*3)+2, text); if (lengthRed != lengthGreen || lengthGreen != lengthBlue) { Com_Error(ERR_DROP, "Style %d has inconsistent lengths: R %d, G %d, B %d", i, lengthRed, lengthGreen, lengthBlue); } } }
/* =========== 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); }
void GCam_FollowUpdate ( void ) { vec3_t center, dir, cameraAngles, vec, focus[MAX_CAMERA_GROUP_SUBJECTS];//No more than 16 subjects in a cameraGroup gentity_t *from = NULL; //centity_t *fromCent = NULL; int num_subjects = 0, i; qboolean focused = qfalse; if ( client_camera.cameraGroup[0] == -1 ) {//follow disabled return; } for( i = 0; i < MAX_CAMERA_GROUP_SUBJECTS; i++ ) { //fromCent = &cg_entities[client_camera.cameraGroup[i]]; from = &g_entities[client_camera.cameraGroup[i]]; if ( !from ) { continue; } focused = qfalse; if ( (from->s.eType == ET_PLAYER || from->s.eType == ET_NPC || from->s.number < MAX_CLIENTS) && client_camera.cameraGroupTag && client_camera.cameraGroupTag[0] ) { int newBolt = trap_G2API_AddBolt( &from->ghoul2, 0, client_camera.cameraGroupTag ); if ( newBolt != -1 ) { mdxaBone_t boltMatrix; vec3_t angle; VectorSet(angle, 0, from->client->ps.viewangles[YAW], 0); trap_G2API_GetBoltMatrix( &from->ghoul2, 0, newBolt, &boltMatrix, angle, from->client->ps.origin, level.time, NULL, from->modelScale ); BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, focus[num_subjects] ); focused = qtrue; } } if ( !focused ) { VectorCopy(from->r.currentOrigin, focus[num_subjects]); if ( from->s.eType == ET_PLAYER || from->s.eType == ET_NPC || from->s.number < MAX_CLIENTS ) {//Track to their eyes - FIXME: maybe go off a tag? focus[num_subjects][2] += from->client->ps.viewheight; } } if ( client_camera.cameraGroupZOfs ) { focus[num_subjects][2] += client_camera.cameraGroupZOfs; } num_subjects++; } if ( !num_subjects ) // Bad cameragroup { #ifndef FINAL_BUILD G_Printf(S_COLOR_RED"ERROR: Camera Focus unable to locate cameragroup: %s\n", client_camera.cameraGroup); #endif return; } //Now average all points VectorCopy( focus[0], center ); for( i = 1; i < num_subjects; i++ ) { VectorAdd( focus[i], center, center ); } VectorScale( center, 1.0f/((float)num_subjects), center ); //Need to set a speed to keep a distance from //the subject- fixme: only do this if have a distance //set VectorSubtract( client_camera.subjectPos, center, vec ); client_camera.subjectSpeed = VectorLengthSquared( vec ) * 100.0f / g_TimeSinceLastFrame; VectorCopy( center, client_camera.subjectPos ); VectorSubtract( center, camerapos, dir );//can't use client_camera.origin because it's not updated until the end of the move. //Get desired angle vectoangles(dir, cameraAngles); if ( client_camera.followInitLerp ) {//Lerping float frac = g_TimeSinceLastFrame/100.0f * client_camera.followSpeed/100.f; for( i = 0; i < 3; i++ ) { cameraAngles[i] = AngleNormalize180( cameraAngles[i] ); cameraAngles[i] = AngleNormalize180( client_camera.angles[i] + frac * AngleNormalize180(cameraAngles[i] - client_camera.angles[i]) ); cameraAngles[i] = AngleNormalize180( cameraAngles[i] ); } } else {//Snapping, should do this first time if follow_lerp_to_start_duration is zero //will lerp from this point on client_camera.followInitLerp = qtrue; for( i = 0; i < 3; i++ ) {//normalize so that when we start lerping, it doesn't freak out cameraAngles[i] = AngleNormalize180( cameraAngles[i] ); } //So tracker doesn't move right away thinking the first angle change //is the subject moving... FIXME: shouldn't set this until lerp done OR snapped? client_camera.subjectSpeed = 0; } VectorCopy( cameraAngles, client_camera.angles ); }
void BG_AttachToRancor( void *ghoul2, float rancYaw, vec3_t rancOrigin, int time, qhandle_t *modelList, vec3_t modelScale, qboolean inMouth, vec3_t out_origin, vec3_t out_angles, vec3_t out_axis[3] ) { mdxaBone_t boltMatrix; int boltIndex; vec3_t rancAngles; vec3_t temp_angles; // Getting the bolt here if ( inMouth ) {//in mouth boltIndex = trap_G2API_AddBolt(ghoul2, 0, "jaw_bone"); } else {//in right hand boltIndex = trap_G2API_AddBolt(ghoul2, 0, "*r_hand"); } VectorSet( rancAngles, 0, rancYaw, 0 ); trap_G2API_GetBoltMatrix( ghoul2, 0, boltIndex, &boltMatrix, rancAngles, rancOrigin, time, modelList, modelScale ); // Storing ent position, bolt position, and bolt axis if ( out_origin ) { BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, out_origin ); } if ( out_axis ) { if ( inMouth ) {//in mouth BG_GiveMeVectorFromMatrix( &boltMatrix, POSITIVE_Z, out_axis[0] ); BG_GiveMeVectorFromMatrix( &boltMatrix, NEGATIVE_Y, out_axis[1] ); BG_GiveMeVectorFromMatrix( &boltMatrix, NEGATIVE_X, out_axis[2] ); } else {//in hand BG_GiveMeVectorFromMatrix( &boltMatrix, NEGATIVE_Y, out_axis[0] ); BG_GiveMeVectorFromMatrix( &boltMatrix, POSITIVE_X, out_axis[1] ); BG_GiveMeVectorFromMatrix( &boltMatrix, POSITIVE_Z, out_axis[2] ); } //FIXME: this is messing up our axis and turning us inside-out? if ( out_angles ) { vectoangles( out_axis[0], out_angles ); vectoangles( out_axis[2], temp_angles ); out_angles[ROLL] = -temp_angles[PITCH]; } } else if ( out_angles ) { vec3_t temp_axis[3]; if ( inMouth ) {//in mouth BG_GiveMeVectorFromMatrix( &boltMatrix, POSITIVE_Z, temp_axis[0] ); BG_GiveMeVectorFromMatrix( &boltMatrix, NEGATIVE_X, temp_axis[2] ); } else {//in hand BG_GiveMeVectorFromMatrix( &boltMatrix, NEGATIVE_Y, temp_axis[0] ); BG_GiveMeVectorFromMatrix( &boltMatrix, POSITIVE_Z, temp_axis[2] ); } //FIXME: this is messing up our axis and turning us inside-out? vectoangles( temp_axis[0], out_angles ); vectoangles( temp_axis[2], temp_angles ); out_angles[ROLL] = -temp_angles[PITCH]; } }
/* ------------------------- Sentry_Fire ------------------------- */ void Sentry_Fire (void) { vec3_t muzzle; static vec3_t forward, vright, up; gentity_t *missile; mdxaBone_t boltMatrix; int bolt, which; NPCS.NPC->flags &= ~FL_SHIELDED; if ( NPCS.NPCInfo->localState == LSTATE_POWERING_UP ) { if ( TIMER_Done( NPCS.NPC, "powerup" )) { NPCS.NPCInfo->localState = LSTATE_ATTACKING; NPC_SetAnim( NPCS.NPC, SETANIM_BOTH, BOTH_ATTACK1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD ); } else { // can't do anything right now return; } } else if ( NPCS.NPCInfo->localState == LSTATE_ACTIVE ) { NPCS.NPCInfo->localState = LSTATE_POWERING_UP; G_Sound( NPCS.NPC, CHAN_AUTO, G_SoundIndex("sound/chars/sentry/misc/sentry_shield_open") ); NPC_SetAnim( NPCS.NPC, SETANIM_BOTH, BOTH_POWERUP1, SETANIM_FLAG_OVERRIDE|SETANIM_FLAG_HOLD ); TIMER_Set( NPCS.NPC, "powerup", 250 ); return; } else if ( NPCS.NPCInfo->localState != LSTATE_ATTACKING ) { // bad because we are uninitialized NPCS.NPCInfo->localState = LSTATE_ACTIVE; return; } // Which muzzle to fire from? which = NPCS.NPCInfo->burstCount % 3; switch( which ) { case 0: bolt = trap_G2API_AddBolt(NPCS.NPC->ghoul2, 0, "*flash1"); break; case 1: bolt = trap_G2API_AddBolt(NPCS.NPC->ghoul2, 0, "*flash2"); break; case 2: default: bolt = trap_G2API_AddBolt(NPCS.NPC->ghoul2, 0, "*flash03"); } trap_G2API_GetBoltMatrix( NPCS.NPC->ghoul2, 0, bolt, &boltMatrix, NPCS.NPC->r.currentAngles, NPCS.NPC->r.currentOrigin, level.time, NULL, NPCS.NPC->modelScale ); BG_GiveMeVectorFromMatrix( &boltMatrix, ORIGIN, muzzle ); AngleVectors( NPCS.NPC->r.currentAngles, forward, vright, up ); // G_Sound( NPC, G_SoundIndex("sound/chars/sentry/misc/shoot.wav")); G_PlayEffectID( G_EffectIndex("bryar/muzzle_flash"), muzzle, forward ); missile = CreateMissile( muzzle, forward, 1600, 10000, NPCS.NPC, qfalse ); missile->classname = "bryar_proj"; missile->s.weapon = WP_BRYAR_PISTOL; missile->dflags = DAMAGE_DEATH_KNOCKBACK; missile->methodOfDeath = MOD_BRYAR_PISTOL; missile->clipmask = MASK_SHOT | CONTENTS_LIGHTSABER; NPCS.NPCInfo->burstCount++; NPCS.NPC->attackDebounceTime = level.time + 50; missile->damage = 5; // now scale for difficulty if ( g_npcspskill.integer == 0 ) { NPCS.NPC->attackDebounceTime += 200; missile->damage = 1; } else if ( g_npcspskill.integer == 1 ) { NPCS.NPC->attackDebounceTime += 100; missile->damage = 3; } }
void turretG2_set_models( gentity_t *self, qboolean dying ) { if ( dying ) { if ( !(self->spawnflags&SPF_TURRETG2_TURBO) ) { self->s.modelindex = G_ModelIndex( name2 ); self->s.modelindex2 = G_ModelIndex( name ); } trap_G2API_RemoveGhoul2Model( &self->ghoul2, 0 ); G_KillG2Queue( self->s.number ); self->s.modelGhoul2 = 0; /* trap_G2API_InitGhoul2Model( &self->ghoul2, name2, 0, //base->s.modelindex, //note, this is not the same kind of index - this one's referring to the actual //index of the model in the g2 instance, whereas modelindex is the index of a //configstring -rww 0, 0, 0, 0); */ } else { if ( !(self->spawnflags&SPF_TURRETG2_TURBO) ) { self->s.modelindex = G_ModelIndex( name ); self->s.modelindex2 = G_ModelIndex( name2 ); //set the new onw trap_G2API_InitGhoul2Model( &self->ghoul2, name, 0, //base->s.modelindex, //note, this is not the same kind of index - this one's referring to the actual //index of the model in the g2 instance, whereas modelindex is the index of a //configstring -rww 0, 0, 0, 0); } else { self->s.modelindex = G_ModelIndex( name3 ); //set the new onw trap_G2API_InitGhoul2Model( &self->ghoul2, name3, 0, //base->s.modelindex, //note, this is not the same kind of index - this one's referring to the actual //index of the model in the g2 instance, whereas modelindex is the index of a //configstring -rww 0, 0, 0, 0); } self->s.modelGhoul2 = 1; if ( (self->spawnflags&SPF_TURRETG2_TURBO) ) { //larger self->s.g2radius = 128; } else { self->s.g2radius = 80; } if ( (self->spawnflags&SPF_TURRETG2_TURBO) ) { //different pitch bone and muzzle flash points G2Tur_SetBoneAngles(self, "pitch", vec3_origin); self->genericValue11 = trap_G2API_AddBolt( self->ghoul2, 0, "*muzzle1" ); self->genericValue12 = trap_G2API_AddBolt( self->ghoul2, 0, "*muzzle2" ); } else { G2Tur_SetBoneAngles(self, "Bone_body", vec3_origin); self->genericValue11 = trap_G2API_AddBolt( self->ghoul2, 0, "*flash03" ); } } }