void RT_FlyStop( gentity_t *self ) { self->client->ps.gravity = g_gravity->value; self->svFlags &= ~SVF_CUSTOM_GRAVITY; self->client->moveType = MT_RUNJUMP; //Stop the effect self->client->jetPackTime = 0; if ( self->genericBolt1 != -1 ) { G_StopEffect("rockettrooper/flameNEW", self->playerModel, self->genericBolt1, self->s.number ); } if ( self->genericBolt2 != -1 ) { G_StopEffect("rockettrooper/flameNEW", self->playerModel, self->genericBolt2, self->s.number ); } //stop jet loop sound self->s.loopSound = 0; G_SoundOnEnt( self, CHAN_ITEM, "sound/chars/boba/bf_land.wav" ); if ( self->NPC ) { self->count = 0; // SEEKER shot ammo count TIMER_Set( self, "jetRecharge", Q_irand( 1000, 5000 ) ); TIMER_Set( self, "jumpChaseDebounce", Q_irand( 500, 2000 ) ); } }
void TouchTieBomb( gentity_t *self, gentity_t *other, trace_t *trace ) { // Stop the effect. G_StopEffect( G_EffectIndex( "ships/tiebomber_bomb_falling" ), self->playerModel, gi.G2API_AddBolt( &self->ghoul2[0], "model_root" ), self->s.number ); self->e_ThinkFunc = thinkF_G_FreeEntity; self->nextthink = level.time + FRAMETIME; G_PlayEffect( G_EffectIndex( "ships/tiebomber_explosion2" ), self->currentOrigin, self->currentAngles ); G_RadiusDamage( self->currentOrigin, self, 900, 500, self, MOD_EXPLOSIVE_SPLASH ); }
/* ------------------------- NPC_Howler_Pain ------------------------- */ void NPC_Howler_Pain( gentity_t *self, gentity_t *inflictor, gentity_t *other, const vec3_t point, int damage, int mod,int hitLoc ) { if ( !self || !self->NPC ) { return; } if ( self->NPC->localState != LSTATE_BERZERK )//damage >= 10 ) { self->NPC->stats.aggression += damage; self->NPC->localState = LSTATE_WAITING; TIMER_Remove( self, "attacking" ); VectorCopy( self->NPC->lastPathAngles, self->s.angles ); //if ( self->client->ps.legsAnim == BOTH_GESTURE1 ) { G_StopEffect( G_EffectIndex( "howler/sonic" ), self->playerModel, self->genericBolt1, self->s.number ); } NPC_SetAnim( self, SETANIM_BOTH, BOTH_PAIN1, SETANIM_FLAG_OVERRIDE | SETANIM_FLAG_HOLD ); TIMER_Set( self, "takingPain", self->client->ps.legsAnimTimer );//2900 ); if ( self->health > HOWLER_PANIC_HEALTH ) {//still have some health left if ( Q_irand( 0, self->max_health ) > self->health )//FIXME: or check damage? {//back off! TIMER_Set( self, "standing", -level.time ); TIMER_Set( self, "running", -level.time ); TIMER_Set( self, "walking", -level.time ); TIMER_Set( self, "retreating", Q_irand( 1000, 5000 ) ); } else {//go after him! TIMER_Set( self, "standing", -level.time ); TIMER_Set( self, "running", self->client->ps.legsAnimTimer+Q_irand(3000,6000) ); TIMER_Set( self, "walking", -level.time ); TIMER_Set( self, "retreating", -level.time ); } } else if ( self->NPC ) {//panic! if ( Q_irand( 0, 1 ) ) {//berzerk self->NPC->localState = LSTATE_BERZERK; } else {//flee self->NPC->localState = LSTATE_FLEE; TIMER_Set( self, "flee", Q_irand( 10000, 30000 ) ); } } } }
void Boba_StopFlameThrower( gentity_t *self ) { if ( self->s.number < MAX_CLIENTS ) { self->client->ps.torsoAnimTimer = 0; G_StopEffect( G_EffectIndex("boba/fthrw"), self->playerModel, self->genericBolt3, self->s.number); return; } if ((NPCInfo->aiFlags&NPCAI_FLAMETHROW)) { self->NPC->aiFlags &= ~NPCAI_FLAMETHROW; self->client->ps.torsoAnimTimer = 0; TIMER_Set( self, "flameTime", 0); TIMER_Set( self, "nextAttackDelay", 0); TIMER_Set( self, "Boba_TacticsSelect", 0); // G_SoundOnEnt( self, CHAN_WEAPON, "sound/effects/flameoff.mp3" ); G_StopEffect( G_EffectIndex("boba/fthrw"), self->playerModel, self->genericBolt3, self->s.number); Boba_Printf("FlameThrower OFF"); } }
// Like a think or move command, this updates various vehicle properties. bool Update( Vehicle_t *pVeh, const usercmd_t *pUcmd ) { if ( !g_vehicleInfo[VEHICLE_BASE].Update( pVeh, pUcmd ) ) { return false; } // See whether this vehicle should be exploding. if ( pVeh->m_iDieTime != 0 ) { pVeh->m_pVehicleInfo->DeathUpdate( pVeh ); } // Update move direction. #ifndef _JK2MP //this makes prediction unhappy, and rightfully so. gentity_t *parent = (gentity_t *)pVeh->m_pParentEntity; if ( pVeh->m_ulFlags & VEH_FLYING ) { vec3_t vVehAngles; VectorSet(vVehAngles, 0, pVeh->m_vOrientation[YAW], 0 ); AngleVectors( vVehAngles, parent->client->ps.moveDir, NULL, NULL ); } else { vec3_t vVehAngles; VectorSet(vVehAngles, pVeh->m_vOrientation[PITCH], pVeh->m_vOrientation[YAW], 0 ); AngleVectors( vVehAngles, parent->client->ps.moveDir, NULL, NULL ); } // Check For A Strafe Ram //------------------------ if (!(pVeh->m_ulFlags&VEH_STRAFERAM) && !(pVeh->m_ulFlags&VEH_FLYING)) { // Started A Strafe //------------------ if (pVeh->m_ucmd.rightmove && !parentPS->hackingTime) { parentPS->hackingTime = (pVeh->m_ucmd.rightmove>0)?(level.time):(-1*level.time); } // Ended A Strafe //---------------- else if (!pVeh->m_ucmd.rightmove && parentPS->hackingTime) { // If It Was A Short Burst, Start The Strafe Ram //----------------------------------------------- if ((level.time - abs(parentPS->hackingTime))<300) { if (!VEH_StartStrafeRam(pVeh, (parentPS->hackingTime>0))) { parentPS->hackingTime = 0; } } // Otherwise, Clear The Timer //---------------------------- else { parentPS->hackingTime = 0; } } } // If Currently In A StrafeRam, Check To See If It Is Done (Timed Out) //--------------------------------------------------------------------- else if (!parentPS->hackingTime) { pVeh->m_ulFlags &=~VEH_STRAFERAM; } // Exhaust Effects Start And Stop When The Accelerator Is Pressed //---------------------------------------------------------------- if (pVeh->m_pVehicleInfo->iExhaustFX) { // Start It On Each Exhaust Bolt //------------------------------- if (pVeh->m_ucmd.forwardmove && !(pVeh->m_ulFlags&VEH_ACCELERATORON)) { pVeh->m_ulFlags |= VEH_ACCELERATORON; for (int i=0; (i<MAX_VEHICLE_EXHAUSTS && pVeh->m_iExhaustTag[i]!=-1); i++) { G_PlayEffect(pVeh->m_pVehicleInfo->iExhaustFX, parent->playerModel, pVeh->m_iExhaustTag[i], parent->s.number, parent->currentOrigin, 1, qtrue); } } // Stop It On Each Exhaust Bolt //------------------------------ else if (!pVeh->m_ucmd.forwardmove && (pVeh->m_ulFlags&VEH_ACCELERATORON)) { pVeh->m_ulFlags &=~VEH_ACCELERATORON; for (int i=0; (i<MAX_VEHICLE_EXHAUSTS && pVeh->m_iExhaustTag[i]!=-1); i++) { G_StopEffect(pVeh->m_pVehicleInfo->iExhaustFX, parent->playerModel, pVeh->m_iExhaustTag[i], parent->s.number); } } } if (!(pVeh->m_ulFlags&VEH_ARMORLOW) && (pVeh->m_iArmor <= pVeh->m_pVehicleInfo->armor/3)) { pVeh->m_ulFlags |= VEH_ARMORLOW; } // Armor Gone Effects (Fire) //--------------------------- if (pVeh->m_pVehicleInfo->iArmorGoneFX) { if (!(pVeh->m_ulFlags&VEH_ARMORGONE) && (pVeh->m_iArmor <= 0)) { pVeh->m_ulFlags |= VEH_ARMORGONE; G_PlayEffect(pVeh->m_pVehicleInfo->iArmorGoneFX, parent->playerModel, parent->crotchBolt, parent->s.number, parent->currentOrigin, 1, qtrue); parent->s.loopSound = G_SoundIndex( "sound/vehicles/common/fire_lp.wav" ); } } #endif return true; }
/* =============== NPC_Pain =============== */ void NPC_Pain( gentity_t *self, gentity_t *inflictor, gentity_t *other, const vec3_t point, int damage, int mod, int hitLoc ) { team_t otherTeam = TEAM_FREE; int voiceEvent = -1; if ( self->NPC == NULL ) return; if ( other == NULL ) return; //or just remove ->pain in player_die? if ( self->client->ps.pm_type == PM_DEAD ) return; if ( other == self ) return; other = G_CheckControlledTurretEnemy(self, other, qfalse); if (!other) { return; } //MCG: Ignore damage from your own team for now if ( other->client ) { otherTeam = other->client->playerTeam; // if ( otherTeam == TEAM_DISGUISE ) // { // otherTeam = TEAM_PLAYER; // } } if ( self->client->playerTeam && other->client && otherTeam == self->client->playerTeam && (!player->client->ps.viewEntity || other->s.number != player->client->ps.viewEntity)) {//hit by a teammate if ( other != self->enemy && self != other->enemy ) {//we weren't already enemies if ( self->enemy || other->enemy || (other->s.number&&other->s.number!=player->client->ps.viewEntity) /*|| (!other->s.number&&Q_irand( 0, 3 ))*/ ) {//if one of us actually has an enemy already, it's okay, just an accident OR wasn't hit by player or someone controlled by player OR player hit ally and didn't get 25% chance of getting mad (FIXME:accumulate anger+base on diff?) //FIXME: player should have to do a certain amount of damage to ally or hit them several times to make them mad //Still run pain and flee scripts if ( self->client && self->NPC ) {//Run any pain instructions if ( self->health <= (self->max_health/3) && G_ActivateBehavior(self, BSET_FLEE) ) { } else// if( VALIDSTRING( self->behaviorSet[BSET_PAIN] ) ) { G_ActivateBehavior(self, BSET_PAIN); } } if ( damage != -1 ) {//-1 == don't play pain anim //Set our proper pain animation if ( Q_irand( 0, 1 ) ) { NPC_ChoosePainAnimation( self, other, point, damage, mod, hitLoc, EV_FFWARN ); } else { NPC_ChoosePainAnimation( self, other, point, damage, mod, hitLoc ); } } return; } else if ( self->NPC && !other->s.number )//should be assumed, but... {//dammit, stop that! if ( self->NPC->charmedTime > level.time ) {//mindtricked return; } else if ( self->NPC->ffireCount < 3+((2-g_spskill->integer)*2) ) {//not mad enough yet //Com_Printf( "chck: %d < %d\n", self->NPC->ffireCount, 3+((2-g_spskill->integer)*2) ); if ( damage != -1 ) {//-1 == don't play pain anim //Set our proper pain animation if ( Q_irand( 0, 1 ) ) { NPC_ChoosePainAnimation( self, other, point, damage, mod, hitLoc, EV_FFWARN ); } else { NPC_ChoosePainAnimation( self, other, point, damage, mod, hitLoc ); } } return; } else if ( G_ActivateBehavior( self, BSET_FFIRE ) ) {//we have a specific script to run, so do that instead return; } else {//okay, we're going to turn on our ally, we need to set and lock our enemy and put ourselves in a bstate that lets us attack him (and clear any flags that would stop us) self->NPC->blockedSpeechDebounceTime = 0; voiceEvent = EV_FFTURN; self->NPC->behaviorState = self->NPC->tempBehavior = self->NPC->defaultBehavior = BS_DEFAULT; other->flags &= ~FL_NOTARGET; self->svFlags &= ~(SVF_IGNORE_ENEMIES|SVF_ICARUS_FREEZE|SVF_NO_COMBAT_SOUNDS); G_SetEnemy( self, other ); self->svFlags |= SVF_LOCKEDENEMY; self->NPC->scriptFlags &= ~(SCF_DONT_FIRE|SCF_CROUCHED|SCF_WALKING|SCF_NO_COMBAT_TALK|SCF_FORCED_MARCH); self->NPC->scriptFlags |= (SCF_CHASE_ENEMIES|SCF_NO_MIND_TRICK); //NOTE: we also stop ICARUS altogether stop_icarus = qtrue; if ( !killPlayerTimer ) { killPlayerTimer = level.time + 10000; } } } } } SaveNPCGlobals(); SetNPCGlobals( self ); //Do extra bits if ( NPCInfo->ignorePain == qfalse ) { NPCInfo->confusionTime = 0;//clear any charm or confusion, regardless if ( NPC->ghoul2.size() && NPC->headBolt != -1 ) { G_StopEffect("force/confusion", NPC->playerModel, NPC->headBolt, NPC->s.number ); } if ( damage != -1 ) {//-1 == don't play pain anim //Set our proper pain animation NPC_ChoosePainAnimation( self, other, point, damage, mod, hitLoc, voiceEvent ); } //Check to take a new enemy if ( NPC->enemy != other && NPC != other ) {//not already mad at them //if it's an eweb or emplaced gun, get mad at the owner, not the gun NPC_CheckAttacker( other, mod ); } } //Attempt to run any pain instructions if ( self->client && self->NPC ) { //FIXME: This needs better heuristics perhaps if(self->health <= (self->max_health/3) && G_ActivateBehavior(self, BSET_FLEE) ) { } else //if( VALIDSTRING( self->behaviorSet[BSET_PAIN] ) ) { G_ActivateBehavior(self, BSET_PAIN); } } //Attempt to fire any paintargets we might have if( self->paintarget && self->paintarget[0] ) { G_UseTargets2(self, other, self->paintarget); } if (self->client && self->client->NPC_class==CLASS_BOBAFETT) { Boba_Pain( self, inflictor, damage, mod); } RestoreNPCGlobals(); }
void G_StopEffect(const char *name, const int modelIndex, const int boltIndex, const int entNum ) { G_StopEffect( G_EffectIndex( name ), modelIndex, boltIndex, entNum ); }