void SP_rail_lane(gentity_t *ent) { gi.SetBrushModel(ent, ent->model); G_SpawnInt("delay", "0", &ent->delay); mRailLanes.push_back().Setup(ent); G_FreeEntity(ent); }
void SP_rail_track(gentity_t *ent) { gi.SetBrushModel(ent, ent->model); G_SpawnInt("delay", "0", &ent->delay); mRailTracks.push_back().Setup(ent); G_FreeEntity(ent); mRailSystemActive = true; }
void Pilot_Update(void) { mActivePilotCount = 0; mRegistered.clear(); for (int i=0; i<ENTITYNUM_WORLD; i++) { if (g_entities[i].inuse && g_entities[i].client && g_entities[i].NPC && g_entities[i].NPC->greetEnt && g_entities[i].NPC->greetEnt->owner==(&g_entities[i]) ) { mActivePilotCount++; } if ( g_entities[i].inuse && g_entities[i].client && g_entities[i].m_pVehicle && !g_entities[i].owner && g_entities[i].health>0 && g_entities[i].m_pVehicle->m_pVehicleInfo->type==VH_SPEEDER && !mRegistered.full()) { mRegistered.push_back(&g_entities[i]); } } if (player && player->inuse && TIMER_Done(player, "FlybySoundArchitectureDebounce")) { TIMER_Set(player, "FlybySoundArchitectureDebounce", 300); Vehicle_t* pVeh = G_IsRidingVehicle(player); if (pVeh && (pVeh->m_pVehicleInfo->soundFlyBy || pVeh->m_pVehicleInfo->soundFlyBy2) && //fabsf(pVeh->m_pParentEntity->currentAngles[2])<15.0f && VectorLength(pVeh->m_pParentEntity->client->ps.velocity)>500.0f) { vec3_t projectedPosition; vec3_t projectedDirection; vec3_t projectedRight; vec3_t anglesNoRoll; VectorCopy(pVeh->m_pParentEntity->currentAngles, anglesNoRoll); anglesNoRoll[2] = 0; AngleVectors(anglesNoRoll, projectedDirection, projectedRight, 0); VectorMA(player->currentOrigin, 1.2f, pVeh->m_pParentEntity->client->ps.velocity, projectedPosition); VectorMA(projectedPosition, Q_flrand(-200.0f, 200.0f), projectedRight, projectedPosition); gi.trace(&mPilotViewTrace, player->currentOrigin, 0, 0, projectedPosition, player->s.number, MASK_SHOT, G2_NOCOLLIDE, 0); if ((mPilotViewTrace.allsolid==qfalse) && (mPilotViewTrace.startsolid==qfalse) && (mPilotViewTrace.fraction<0.99f) && (mPilotViewTrace.plane.normal[2]<0.5f) && (DotProduct(projectedDirection, mPilotViewTrace.plane.normal)<-0.5f) ) { // CG_DrawEdge(player->currentOrigin, mPilotViewTrace.endpos, EDGE_IMPACT_POSSIBLE); TIMER_Set(player, "FlybySoundArchitectureDebounce", Q_irand(1000, 2000)); int soundFlyBy = pVeh->m_pVehicleInfo->soundFlyBy; if (pVeh->m_pVehicleInfo->soundFlyBy2 && (!soundFlyBy || !Q_irand(0,1))) { soundFlyBy = pVeh->m_pVehicleInfo->soundFlyBy2; } G_SoundAtSpot(mPilotViewTrace.endpos, soundFlyBy, qtrue); } else { // CG_DrawEdge(player->currentOrigin, mPilotViewTrace.endpos, EDGE_IMPACT_SAFE); } } } }
void CRailTrack::Update() { mNextUpdateTime = level.time + mNextUpdateDelay; // Now, Attempt To Add A Number Of Movers To The Track //----------------------------------------------------- int attempt; int startCol; int stopCol; int atCol; int testColIndex; for (attempt=0; attempt<mNumMoversPerRow; attempt++) { // Randomly Select A Mover And Test To See If It Is Active //--------------------------------------------------------- CRailMover* mover = mMovers[Q_irand(0, mMovers.size()-1)]; if (mover->Active()) { continue; } // Don't Spawn Until Start Time Has Expired //------------------------------------------ if (level.time < ((mover->mLane)?(mover->mLane->mStartTime):(mStartTime))) { continue; } // If Center Locked, Stop Spawning Center Track Movers //----------------------------------------------------- if (mover->mCenter && mCenterLocked) { continue; } // Restrict It To A Lane //----------------------- if (mover->mLane) { startCol = mover->mLane->mMinCol; stopCol = mover->mLane->mMaxCol+1; } // Or Let It Go Anywhere On The Track //------------------------------------ else { startCol = 0; stopCol = mCols; } stopCol -= (mover->mCols-1); // If The Mover Is Too Big To Fit In The Lane, Go On To Next Attempt //------------------------------------------------------------------- if (stopCol<=startCol) { assert(0); // Should Not Happen continue; } // Force It To Center //-------------------- if (mover->mCenter && stopCol!=(startCol+1)) { startCol = ((mCols/2) - (mover->mCols/2)); stopCol = startCol+1; } // Construct A List Of Columns To Test For Insertion //--------------------------------------------------- mTestCols.clear(); for (int i=startCol; i<stopCol; i++) { mTestCols.push_back(i); } // Now Try All The Cols To See If The Building Can Fit //----------------------------------------------------- while (!mTestCols.empty()) { // Randomly Pick A Column, Then Remove It From The Vector //-------------------------------------------------------- testColIndex = Q_irand(0, mTestCols.size()-1); atCol = mTestCols[testColIndex]; mTestCols.erase_swap(testColIndex); if (TestMoverInCells(mover, atCol)) { // Ok, We've Found A Safe Column To Insert This Mover //---------------------------------------------------- InsertMoverInCells(mover, atCol); // Now Transport The Actual Mover Entity Into Position, Link It & Send It Off //---------------------------------------------------------------------------- CVec3 StartPos(mGridBottomLeftCorner); StartPos[mWAxis] += ((atCol * mGridCellSize) + ((mover->mCols/2.0f) * mGridCellSize)); StartPos[mHAxis] += (((mover->mRows/2.0f) * mGridCellSize) * ((mNegative)?(1):(-1))); StartPos[2] = 0; // If Centered, Actually Put It At EXACTLY The Right Position On The Width Axis //------------------------------------------------------------------------------ if (mover->mCenter) { StartPos[mWAxis] = mGridCenter[mWAxis]; float deltaOffset = mGridCenter[mWAxis] - mover->mOriginOffset[mWAxis]; if (deltaOffset<(mGridCellSize*0.5f) ) { StartPos[mWAxis] -= deltaOffset; } } StartPos -= mover->mOriginOffset; G_SetOrigin(mover->mEnt, StartPos.v); // Start It Moving //----------------- VectorCopy(StartPos.v, mover->mEnt->s.pos.trBase); VectorCopy(mVelocity.v, mover->mEnt->s.pos.trDelta); mover->mEnt->s.pos.trTime = level.time; mover->mEnt->s.pos.trDuration = mTravelTimeMilliseconds + (mNextUpdateDelay*mover->mRows); mover->mEnt->s.pos.trType = TR_LINEAR_STOP; mover->mEnt->s.eFlags &= ~EF_NODRAW; mover->mSoundPlayed = false; // Successfully Inserted This Mover. Now Move On To The Next Mover //------------------------------------------------------------------ break; } } } // Incriment The Current Row //--------------------------- mRow++; if (mRow>=mRows) { mRow = 0; } // Erase The Erase Row //--------------------- int EraseRow = mRow - MAX_ROW_HISTORY; if (EraseRow<0) { EraseRow += mRows; } for (int col=0; col<mCols; col++) { mCells.get(col, EraseRow) = 0; } }
void Rail_Initialize() { for (int lane=0; lane<mRailLanes.size(); lane++) { mRailLanes[lane].Initialize(); } for (int mover=0; mover<mRailMovers.size(); mover++) { mRailMovers[mover].Initialize(); } // Precache All The Woosh Sounds //------------------------------- if (!mRailMovers.empty()) { mWooshMed.push_back(G_SoundIndex("sound/effects/woosh1")); mWooshSml.push_back(G_SoundIndex("sound/effects/woosh2")); mWooshMed.push_back(G_SoundIndex("sound/effects/woosh3")); mWooshSml.push_back(G_SoundIndex("sound/effects/woosh4")); mWooshLar.push_back(G_SoundIndex("sound/effects/woosh5")); mWooshSml.push_back(G_SoundIndex("sound/effects/woosh6")); mWooshSup.push_back(G_SoundIndex("sound/effects/woosh7")); mWooshSup.push_back(G_SoundIndex("sound/effects/woosh8")); mWooshSup.push_back(G_SoundIndex("sound/effects/woosh9")); mWooshLar.push_back(G_SoundIndex("sound/effects/woosh10")); mWooshLar.push_back(G_SoundIndex("sound/effects/woosh11")); mWooshLar.push_back(G_SoundIndex("sound/effects/woosh12")); mWooshSml.push_back(G_SoundIndex("sound/effects/woosh13")); mWooshMed.push_back(G_SoundIndex("sound/effects/woosh14")); mWooshMed.push_back(G_SoundIndex("sound/effects/woosh15")); mWooshMed.push_back(G_SoundIndex("sound/effects/woosh16")); mWooshSml.push_back(G_SoundIndex("sound/effects/woosh17")); mWooshMed.push_back(G_SoundIndex("sound/effects/woosh18")); mWooshMed.push_back(G_SoundIndex("sound/effects/woosh19")); mWooshMed.push_back(G_SoundIndex("sound/effects/woosh20")); mWooshMed.push_back(G_SoundIndex("sound/effects/woosh21")); mWooshLar.push_back(G_SoundIndex("sound/effects/woosh22")); mWooshLar.push_back(G_SoundIndex("sound/effects/woosh23")); mWooshSup.push_back(G_SoundIndex("sound/effects/woosh24")); mWooshSup.push_back(G_SoundIndex("sound/effects/woosh25")); mWooshMed.push_back(G_SoundIndex("sound/effects/woosh26")); mWooshMed.push_back(G_SoundIndex("sound/effects/woosh27")); mWooshMed.push_back(G_SoundIndex("sound/effects/woosh28")); mWooshLar.push_back(G_SoundIndex("sound/effects/woosh29")); mWooshTun.push_back(G_SoundIndex("sound/effects/whoosh_tunnel")); } }
void SP_rail_mover(gentity_t *ent) { gi.SetBrushModel(ent, ent->model); mRailMovers.push_back().Setup(ent); }
//////////////////////////////////////////////////////////////////////////////////////// // Update The Packs, Delete Dead Leaders, Join / Split Packs, Find MY Leader //////////////////////////////////////////////////////////////////////////////////////// gentity_t* NPC_AnimalUpdateLeader(void) { // Find The Closest Pack Leader, Not Counting Myself //--------------------------------------------------- gentity_t* closestLeader = 0; float closestDist = 0; int myLeaderNum = 0; for (int i=0; i<mPacks.size(); i++) { // Dump Dead Leaders //------------------- if (mPacks[i]==0 || mPacks[i]->health<=0) { if (mPacks[i]==NPC->client->leader) { NPC->client->leader = 0; } mPacks.erase_swap(i); if (i>=mPacks.size()) { closestLeader = 0; break; } } // Don't Count Self //------------------ if (mPacks[i]==NPC) { myLeaderNum = i; continue; } float Dist = Distance(mPacks[i]->currentOrigin, NPC->currentOrigin); if (!closestLeader || Dist<closestDist) { closestDist = Dist; closestLeader = mPacks[i]; } } // In Joining Distance? //---------------------- if (closestLeader && closestDist<JOIN_PACK_DISTANCE) { // Am I Already A Leader? //------------------------ if (NPC->client->leader==NPC) { mPacks.erase_swap(myLeaderNum); // Erase Myself From The Leader List } // Join The Pack! //---------------- NPC->client->leader = closestLeader; } // Do I Have A Leader? //--------------------- if (NPC->client->leader) { // AM I A Leader? //---------------- if (NPC->client->leader!=NPC) { // If Our Leader Is Dead, Clear Him Out if ( NPC->client->leader->health<=0 || NPC->client->leader->inuse == 0) { NPC->client->leader = 0; } // If My Leader Isn't His Own Leader, Then, Use His Leader //--------------------------------------------------------- else if (NPC->client->leader->client->leader!=NPC->client->leader) { // Eh. Can this get more confusing? NPC->client->leader = NPC->client->leader->client->leader; } // If Our Leader Is Too Far Away, Clear Him Out //------------------------------------------------------ else if ( Distance(NPC->client->leader->currentOrigin, NPC->currentOrigin)>LEAVE_PACK_DISTANCE) { NPC->client->leader = 0; } } } // If We Couldn't Find A Leader, Then Become One //----------------------------------------------- else if (!mPacks.full()) { NPC->client->leader = NPC; mPacks.push_back(NPC); } return NPC->client->leader; }