/* ======================== BG_TouchJumpPad ======================== */ void BG_TouchJumpPad( playerState_t *ps, entityState_t *jumppad ) { vec3_t angles; float p; int effectNum; // spectators don't use jump pads if ( ps->pm_type != PM_NORMAL ) { return; } // flying characters don't hit bounce pads if ( ps->powerups[PW_FLIGHT] ) { return; } // if we didn't hit this same jumppad the previous frame // then don't play the event sound again if we are in a fat trigger if ( ps->jumppad_ent != jumppad->number ) { vectoangles( jumppad->origin2, angles); p = fabs( AngleNormalize180( angles[PITCH] ) ); if( p < 45 ) { effectNum = 0; } else { effectNum = 1; } BG_AddPredictableEventToPlayerstate( EV_JUMP_PAD, effectNum, ps ); } // remember hitting this jumppad this frame ps->jumppad_ent = jumppad->number; ps->jumppad_frame = ps->pmove_framecount; // give the player the velocity from the jumppad VectorCopy( jumppad->origin2, ps->velocity ); }
/* =============== G_AddPredictableEvent Use for non-pmove events that would also be predicted on the client side: jumppads and item pickups Adds an event+parm and twiddles the event counter =============== */ void G_AddPredictableEvent( gentity_t *ent, int event, int eventParm ) { if( !ent->client ) return; BG_AddPredictableEventToPlayerstate( event, eventParm, &ent->client->ps ); }
/* =================== CG_TouchItem =================== */ static void CG_TouchItem( centity_t *cent ) { gitem_t *item; if ( !cg_predictItems.integer ) { return; } if ( !BG_PlayerTouchesItem( &cg.cur_lc->predictedPlayerState, ¢->currentState, cg.time ) ) { return; } // never pick an item up twice in a prediction if ( cent->miscTime == cg.time ) { return; } if ( !BG_CanItemBeGrabbed( cgs.gametype, ¢->currentState, &cg.cur_lc->predictedPlayerState ) ) { return; // can't hold it } item = BG_ItemForItemNum( cent->currentState.modelindex ); // Special case for flags. // We don't predict touching our own flag #ifdef MISSIONPACK if( cgs.gametype == GT_1FCTF ) { if( item->giType == IT_TEAM && item->giTag != PW_NEUTRALFLAG ) { return; } } #endif if( cgs.gametype == GT_CTF ) { if (cg.cur_lc->predictedPlayerState.persistant[PERS_TEAM] == TEAM_RED && item->giType == IT_TEAM && item->giTag == PW_REDFLAG) return; if (cg.cur_lc->predictedPlayerState.persistant[PERS_TEAM] == TEAM_BLUE && item->giType == IT_TEAM && item->giTag == PW_BLUEFLAG) return; } // grab it BG_AddPredictableEventToPlayerstate( EV_ITEM_PICKUP, cent->currentState.modelindex , &cg.cur_lc->predictedPlayerState); // remove it from the frame so it won't be drawn cent->currentState.eFlags |= EF_NODRAW; // don't touch it again this prediction cent->miscTime = cg.time; // if it's a weapon, give them some predicted ammo so the autoswitch will work if ( item->giType == IT_WEAPON ) { cg.cur_lc->predictedPlayerState.stats[ STAT_WEAPONS ] |= 1 << item->giTag; if ( !cg.cur_lc->predictedPlayerState.ammo[ item->giTag ] ) { cg.cur_lc->predictedPlayerState.ammo[ item->giTag ] = 1; } } }
static void CelebrateStart( gentity_t *player ) { /*player->s.torsoAnim = ( ( player->s.torsoAnim & ANIM_TOGGLEBIT ) ^ ANIM_TOGGLEBIT ) | TORSO_GESTURE; player->nextthink = level.time + TIMER_GESTURE; player->think = CelebrateStop;*/ // We don't want the taunt sound effect because it interfears with the computer voice giving awards // FIXME: just get timing right? //FIXME: why does this get lost now? BG_AddPredictableEventToPlayerstate( EV_TAUNT, 0, &player->client->ps ); }
/* =============== PM_AddEvent =============== */ void PM_AddEvent( int newEvent ) { BG_AddPredictableEventToPlayerstate( newEvent, 0, pm->ps ); }