void CShrapnel::Move (void) { fix xSpeed = FixDiv (m_info.xSpeed, I2X (25) / 1000); CFixVector vOffs; time_t nTicks; if ((nTicks = gameStates.app.nSDLTicks - m_info.tUpdate) < 25) return; xSpeed = (fix) (xSpeed / gameStates.gameplay.slowmo [0].fSpeed); for (; nTicks >= 25; nTicks -= 25) { if (--(m_info.nTurn)) vOffs = m_info.vOffs; else { m_info.nTurn = ((m_info.xTTL > I2X (1) / 2) ? 2 : 4) + d_rand () % 4; vOffs = m_info.vDir; vOffs [X] = FixMul (vOffs [X], 2 * d_rand ()); vOffs [Y] = FixMul (vOffs [Y], 2 * d_rand ()); vOffs [Z] = FixMul (vOffs [Z], 2 * d_rand ()); CFixVector::Normalize (vOffs); m_info.vOffs = vOffs; } vOffs *= xSpeed; m_info.vPos += vOffs; } if (m_info.nSmoke >= 0) particleManager.SetPos (m_info.nSmoke, &m_info.vPos, NULL, -1); m_info.tUpdate = gameStates.app.nSDLTicks - nTicks; }
// -------------------------------------------------------------------------------------------------------------------- // If a hiding robot gets bumped or hit, he decides to find another hiding place. void DoAIRobotHit (CObject *objP, int nType) { int r; if (objP->info.controlType != CT_AI) return; if ((nType != PA_WEAPON_ROBOT_COLLISION) && (nType != PA_PLAYER_COLLISION)) return; if (objP->cType.aiInfo.behavior != AIB_STILL) return; r = d_rand (); // Attack robots (eg, green guy) shouldn't have behavior = still. //Assert (ROBOTINFO (objP->info.nId).attackType == 0); // 1/8 time, charge CPlayerData, 1/4 time create path, rest of time, do nothing if (r < 4096) { CreatePathToPlayer (objP, 10, 1); objP->cType.aiInfo.behavior = AIB_STATION; objP->cType.aiInfo.nHideSegment = objP->info.nSegment; gameData.ai.localInfo [objP->Index ()].mode = AIM_CHASE_OBJECT; } else if (r < 4096 + 8192) { CreateNSegmentPath (objP, d_rand () / 8192 + 2, -1); gameData.ai.localInfo [objP->Index ()].mode = AIM_FOLLOW_PATH; } }
void SeismicDisturbanceFrame (void) { if (gameStates.gameplay.seismic.nShakeFrequency) { if (((gameStates.gameplay.seismic.nStartTime < gameData.time.xGame) && (gameStates.gameplay.seismic.nEndTime > gameData.time.xGame)) || StartSeismicDisturbance()) { fix deltaTime = gameData.time.xGame - gameStates.gameplay.seismic.nStartTime; int fc, rx, rz; fix h; fc = abs(deltaTime - (gameStates.gameplay.seismic.nEndTime - gameStates.gameplay.seismic.nStartTime) / 2); fc /= F1_0 / 16; if (fc > 16) fc = 16; else if (fc == 0) fc = 1; gameStates.gameplay.seismic.nVolume += fc; h = 3 * F1_0 / 16 + (F1_0 * (16 - fc)) / 32; rx = FixMul(d_rand() - 16384, h); rz = FixMul(d_rand() - 16384, h); gameData.objs.console->mType.physInfo.rotVel.p.x += rx; gameData.objs.console->mType.physInfo.rotVel.p.z += rz; // Shake the buddy! if (gameData.escort.nObjNum != -1) { gameData.objs.objects[gameData.escort.nObjNum].mType.physInfo.rotVel.p.x += rx*4; gameData.objs.objects[gameData.escort.nObjNum].mType.physInfo.rotVel.p.z += rz*4; } // Shake a guided missile! gameStates.gameplay.seismic.nMagnitude += rx; } } }
void DrawDebrisCorona (CObject *objP) { static tRgbaColorf debrisGlow = {0.66f, 0, 0, 1}; static tRgbaColorf markerGlow = {0, 0.66f, 0, 1}; static time_t t0 = 0; if (objP->info.nType == OBJ_MARKER) RenderWeaponCorona (objP, &markerGlow, 0.75f, 0, 4, 1, 1, 0); #if DBG else if (objP->info.nType == OBJ_DEBRIS) { #else else if ((objP->info.nType == OBJ_DEBRIS) && gameOpts->render.nDebrisLife) { #endif float h = (float) nDebrisLife [gameOpts->render.nDebrisLife] - X2F (objP->info.xLifeLeft); if (h < 0) h = 0; if (h < 10) { h = (10 - h) / 20.0f; if (gameStates.app.nSDLTicks - t0 > 50) { t0 = gameStates.app.nSDLTicks; debrisGlow.red = 0.5f + X2F (d_rand () % (I2X (1) / 4)); debrisGlow.green = X2F (d_rand () % (I2X (1) / 4)); } RenderWeaponCorona (objP, &debrisGlow, h, 5 * objP->info.xSize, 1.5f, 1, LIGHTTRAIL_BLENDMODE, 0); } } }
// Return true if time to start a seismic disturbance. static int start_seismic_disturbance(void) { int rval; if (Level_shake_duration < 1) return 0; rval = (2 * fixmul(d_rand(), Level_shake_frequency)) < FrameTime; if (rval) { Seismic_disturbance_start_time = GameTime64; Seismic_disturbance_end_time = GameTime64 + Level_shake_duration; if (!Seismic_sound_playing) { digi_play_sample_looping(Seismic_sound, F1_0, -1, -1); Seismic_sound_playing = 1; Next_seismic_sound_time = GameTime64 + d_rand()/2; } #ifdef NETWORK if (Game_mode & GM_MULTI) multi_send_seismic (Seismic_disturbance_start_time,Seismic_disturbance_end_time); #endif } return rval; }
void CreateSmallFireballOnObject (CObject *objP, fix size_scale, int bSound) { fix size; CFixVector vPos, vRand; short nSegment; vPos = objP->info.position.vPos; vRand = CFixVector::Random(); vRand *= (objP->info.xSize / 2); vPos += vRand; size = FixMul (size_scale, I2X (1) / 2 + d_rand () * 4 / 2); nSegment = FindSegByPos (vPos, objP->info.nSegment, 1, 0); if (nSegment != -1) { CObject *explObjP = /*Object*/CreateExplosion (nSegment, vPos, size, VCLIP_SMALL_EXPLOSION); if (!explObjP) return; AttachObject (objP, explObjP); if (bSound || (d_rand () < 8192)) { fix vol = I2X (1) / 2; if (objP->info.nType == OBJ_ROBOT) vol *= 2; audio.CreateObjectSound (SOUND_EXPLODING_WALL, SOUNDCLASS_EXPLOSION, objP->Index (), 0, vol); } } }
// -------------------------------------------------------------------------------- // Picks a Random point in a CSegment like so: // From center, go up to 50% of way towards any of the 8 vertices. CFixVector CSegment::RandomPoint (void) { int nVertex = (d_rand () * MAX_VERTICES_PER_SEGMENT) >> 15; CFixVector v = gameData.segs.vertices [m_verts [nVertex]] - m_vCenter; v *= (d_rand ()); return v; }
//this function is for when the CPlayerData intentionally drops a powerup //this function is based on DropPowerup() int SpitPowerup (CObject *spitterP, ubyte id, int seed) { short nObject; CObject *objP; CFixVector newVelocity, newPos; tObjTransformation *posP = OBJPOS (spitterP); #if 0 if ((gameData.app.nGameMode & GM_NETWORK) && (gameData.multiplayer.powerupsInMine [(int)id] + PowerupsOnShips (id) >= gameData.multiplayer.maxPowerupsAllowed [id])) return -1; #endif newVelocity = spitterP->mType.physInfo.velocity + spitterP->info.position.mOrient.FVec() * I2X (SPIT_SPEED); newVelocity[X] += (d_rand() - 16384) * SPIT_SPEED * 2; newVelocity[Y] += (d_rand() - 16384) * SPIT_SPEED * 2; newVelocity[Z] += (d_rand() - 16384) * SPIT_SPEED * 2; // Give keys zero velocity so they can be tracked better in multi if (IsMultiGame && (id >= POW_KEY_BLUE) && (id <= POW_KEY_GOLD)) newVelocity.SetZero (); //there's a piece of code which lets the CPlayerData pick up a powerup if //the distance between him and the powerup is less than 2 time their //combined radii. So we need to create powerups pretty far out from //the player. newPos = posP->vPos + posP->mOrient.FVec () * spitterP->info.xSize; if (IsMultiGame && (gameData.multigame.create.nLoc >= MAX_NET_CREATE_OBJECTS)) return (-1); nObject = CreatePowerup (id, (short) (GetTeam (gameData.multiplayer.nLocalPlayer) + 1), (short) OBJSEG (spitterP), newPos, 1); if (nObject < 0) { Int3(); return nObject; } objP = OBJECTS + nObject; objP->mType.physInfo.velocity = newVelocity; objP->mType.physInfo.drag = 512; //1024; objP->mType.physInfo.mass = I2X (1); objP->mType.physInfo.flags = PF_BOUNCE; objP->rType.vClipInfo.nClipIndex = gameData.objs.pwrUp.info [objP->info.nId].nClipIndex; objP->rType.vClipInfo.xFrameTime = gameData.eff.vClipP [objP->rType.vClipInfo.nClipIndex].xFrameTime; objP->rType.vClipInfo.nCurFrame = 0; if (spitterP == gameData.objs.consoleP) objP->cType.powerupInfo.nFlags |= PF_SPAT_BY_PLAYER; switch (objP->info.nId) { case POW_CONCUSSION_1: case POW_CONCUSSION_4: case POW_SHIELD_BOOST: case POW_ENERGY: objP->info.xLifeLeft = (d_rand() + I2X (3)) * 64; // Lives for 3 to 3.5 binary minutes (a binary minute is 64 seconds) if (gameData.app.nGameMode & GM_MULTI) objP->info.xLifeLeft /= 2; break; default: //if (gameData.app.nGameMode & GM_MULTI) // objP->info.xLifeLeft = (d_rand() + I2X (3)) * 64; // Lives for 5 to 5.5 binary minutes (a binary minute is 64 seconds) break; } MultiSendWeapons (1); return nObject; }
// If a smega missile been detonated, rock the mine! // This should be called every frame. // Maybe this should affect all robots, being called when they get their physics done. void rock_the_mine_frame(void) { int i; for (i=0; i<MAX_SMEGA_DETONATES; i++) { if (Smega_detonate_times[i] != 0) { fix delta_time = GameTime64 - Smega_detonate_times[i]; if (!Seismic_sound_playing) { digi_play_sample_looping(Seismic_sound, F1_0, -1, -1); Seismic_sound_playing = 1; Next_seismic_sound_time = GameTime64 + d_rand()/2; } if (delta_time < SMEGA_SHAKE_TIME) { // Control center destroyed, rock the player's ship. int fc, rx, rz; // -- fc = abs(delta_time - SMEGA_SHAKE_TIME/2); // Changed 10/23/95 to make decreasing for super mega missile. fc = (SMEGA_SHAKE_TIME - delta_time)/2; fc /= SMEGA_SHAKE_TIME/32; if (fc > 16) fc = 16; if (fc == 0) fc = 1; Seismic_tremor_volume += fc; rx = fixmul(d_rand() - 16384, 3*F1_0/16 + (F1_0*(16-fc))/32); rz = fixmul(d_rand() - 16384, 3*F1_0/16 + (F1_0*(16-fc))/32); if (FixedStep & EPS20) { ConsoleObject->mtype.phys_info.rotvel.x += rx; ConsoleObject->mtype.phys_info.rotvel.z += rz; // Shake the buddy! if (Buddy_objnum != object_none) { Objects[Buddy_objnum].mtype.phys_info.rotvel.x += rx*4; Objects[Buddy_objnum].mtype.phys_info.rotvel.z += rz*4; } } // Shake a guided missile! Seismic_tremor_magnitude += rx; } else Smega_detonate_times[i] = 0; } } // Hook in the rumble sound effect here. }
void generate_starfield() { int i; for (i=0;i<MAX_STARS;i++) { stars[i].x = (d_rand() - D_RAND_MAX/2) << 14; stars[i].z = (d_rand() - D_RAND_MAX/2) << 14; stars[i].y = (d_rand()/2) << 14; } }
/* Setup a random function in the given dimensions */ static void setup_func(funcp *p, int di) { double mn,mx; double ax[MXDI][2]; int i, j; p->di = di; /* Setup random input curve parameters */ /* (This is the one that effects smoothness of function the most) */ for (j = 0; j < di; j++) { for (mx = 4.0, i = 0; i < MXCHPARAMS; i++, mx *= 0.6) { p->ip[j][i] = d_rand(-mx, mx); } } /* Setup random shape parameters */ for (j = 0; j < di; j++) { for (i = 0; i < (1 << di); i++) { /* Initially random */ p->shape[j][i] = d_rand(-0.1, 0.1); } } /* Setup the random output value parameters */ /* First some axis dominant values */ for (i = 0; i < di; i++) { ax[i][0] = d_rand(0.0, 1.0); ax[i][1] = ax[i][0] + d_rand(-1.0, 1.0); } /* Sum them orthogonally and add indepent terms */ mn = 5.0; mx = -5.0; for (i = 0; i < (1 << di); i++) { /* Initially random */ p->op[i] = 0.0; for (j = 0; j < di; j++) { if ((1 << j) & i) p->op[i] += ax[j][1]; else p->op[i] += ax[j][0]; } p->op[i] += d_rand(-0.3, 0.3); if (p->op[i] < mn) mn = p->op[i]; if (p->op[i] > mx) mx = p->op[i]; } for (i = 0; i < (1 << di); i++) { /* Then scale to between 0.0 and 1.0 */ p->op[i] = (p->op[i] - mn)/(mx - mn); } }
void CObject::RandomBump (fix xScale, fix xForce, bool bSound) { fix angle; angle = (d_rand () - I2X (1) / 4); mType.physInfo.rotVel [X] += FixMul (angle, xScale); angle = (d_rand () - I2X (1) / 4); mType.physInfo.rotVel [Z] += FixMul (angle, xScale); CFixVector vRand = CFixVector::Random (); Bump (vRand, xForce); if (bSound) audio.CreateObjectSound (SOUND_PLAYER_HIT_WALL, SOUNDCLASS_GENERIC, Index ()); }
void DoSnipeFire (CObject *objP, tAILocalInfo *ailP) { if (ailP->nextActionTime < 0) { tAIStaticInfo *aiP = &objP->cType.aiInfo; CreateNSegmentPath (objP, 10 + d_rand () / 2048, OBJSEG (TARGETOBJ)); aiP->nPathLength = (aiP->nHideIndex < 0) ? 0 : SmoothPath (objP, &gameData.ai.routeSegs [aiP->nHideIndex], aiP->nPathLength); if (d_rand () < 8192) ailP->mode = AIM_SNIPE_RETREAT_BACKWARDS; else ailP->mode = AIM_SNIPE_RETREAT; ailP->nextActionTime = SNIPE_RETREAT_TIME; } }
// --------------------------------------------------------------------------------------- // Do seismic disturbance stuff including the looping sounds with changing volume. void do_seismic_stuff(void) { int stv_save; stv_save = Seismic_tremor_volume; Seismic_tremor_magnitude = 0; Seismic_tremor_volume = 0; rock_the_mine_frame(); seismic_disturbance_frame(); if (stv_save != 0) { if (Seismic_tremor_volume == 0) { digi_stop_looping_sound(); Seismic_sound_playing = 0; } if ((GameTime64 > Next_seismic_sound_time) && Seismic_tremor_volume) { int volume; volume = Seismic_tremor_volume * 2048; if (volume > F1_0) volume = F1_0; digi_change_looping_volume(volume); Next_seismic_sound_time = GameTime64 + d_rand()/4 + 8192; } } }
int CShrapnelCloud::Create (CObject* parentObjP, CObject* objP) { int i, h = (int) (X2F (parentObjP->info.xSize) * fShrapnelScale [gameOpts->render.effects.nShrapnels] + 0.5); objP->info.xLifeLeft = 0; objP->cType.explInfo.nSpawnTime = -1; objP->cType.explInfo.nDeleteObj = -1; objP->cType.explInfo.nDeleteTime = -1; h += d_rand () % h; if (!CStack<CShrapnel>::Create (h)) return 0; if (!Grow (h)) return 0; #pragma omp parallel { #pragma omp for for (i = 0; i < h; i++) { m_data.buffer [i].Create (parentObjP, objP); } } objP->info.xLifeLeft *= 2; objP->cType.explInfo.nSpawnTime = -1; objP->cType.explInfo.nDeleteObj = -1; objP->cType.explInfo.nDeleteTime = -1; return 1; }
void CShrapnel::Draw (void) { if ((m_info.xTTL > 0) && LoadExplBlast ()) { fix xSize = I2X (1) / 2 + d_rand () % (I2X (1) / 4); G3DrawSprite (m_info.vPos, xSize, xSize, bmpExplBlast, NULL, X2F (m_info.xTTL) / X2F (m_info.xLife) / 2, 0, 0); } }
void DoSeismicStuff (void) { int stv_save; if (gameStates.limitFPS.bSeismic && !gameStates.app.tick40fps.bTick) return; stv_save = gameStates.gameplay.seismic.nVolume; gameStates.gameplay.seismic.nMagnitude = 0; gameStates.gameplay.seismic.nVolume = 0; RockTheMineFrame(); SeismicDisturbanceFrame(); if (stv_save != 0) { if (gameStates.gameplay.seismic.nVolume == 0) { DigiStopLoopingSound(); gameStates.gameplay.seismic.bSound = 0; } if ((gameData.time.xGame > gameStates.gameplay.seismic.nNextSoundTime) && gameStates.gameplay.seismic.nVolume) { int volume = gameStates.gameplay.seismic.nVolume * 2048; if (volume > F1_0) volume = F1_0; DigiChangeLoopingVolume (volume); gameStates.gameplay.seismic.nNextSoundTime = gameData.time.xGame + d_rand () / 4 + 8192; } } }
// ----------------------------------------------------------------------------- // Fire Laser: Registers a laser fire, and performs special stuff for the fusion // cannon. void ChargeFusion (void) { if ((LOCALPLAYER.energy < I2X (2)) && (gameData.fusion.xAutoFireTime == 0)) { gameData.laser.nGlobalFiringCount = 0; } else { gameData.fusion.xFrameTime += gameData.time.xFrame; if (!gameData.FusionCharge ()) LOCALPLAYER.energy -= I2X (2); fix h = (gameData.fusion.xFrameTime <= LOCALPLAYER.energy) ? gameData.fusion.xFrameTime : LOCALPLAYER.energy; gameData.SetFusionCharge (gameData.FusionCharge () + h); LOCALPLAYER.energy -= h; if (LOCALPLAYER.energy > 0) gameData.fusion.xAutoFireTime = gameData.time.xGame + gameData.fusion.xFrameTime / 2 + 1; else { LOCALPLAYER.energy = 0; gameData.fusion.xAutoFireTime = gameData.time.xGame - 1; // Fire now! } if (gameStates.limitFPS.bFusion && !gameStates.app.tick40fps.bTick) return; float fScale = float (gameData.FusionCharge () >> 11) / 64.0f; tRgbaColorf* colorP = gameData.weapons.color + FUSION_ID; if (gameData.FusionCharge () < I2X (2)) paletteManager.BumpEffect (colorP->red * fScale, colorP->green * fScale, colorP->blue * fScale); else paletteManager.BumpEffect (colorP->blue * fScale, colorP->red * fScale, colorP->green * fScale); if (gameData.time.xGame < gameData.fusion.xLastSoundTime) //gametime has wrapped gameData.fusion.xNextSoundTime = gameData.fusion.xLastSoundTime = gameData.time.xGame; if (gameData.fusion.xNextSoundTime < gameData.time.xGame) { if (gameData.FusionCharge () > I2X (2)) { audio.PlaySound (11); gameData.objs.consoleP->ApplyDamageToPlayer (gameData.objs.consoleP, d_rand () * 4); } else { CreateAwarenessEvent (gameData.objs.consoleP, WEAPON_ROBOT_COLLISION); audio.PlaySound (SOUND_FUSION_WARMUP); if (IsMultiGame) MultiSendPlaySound (SOUND_FUSION_WARMUP, I2X (1)); } gameData.fusion.xLastSoundTime = gameData.time.xGame; gameData.fusion.xNextSoundTime = gameData.time.xGame + I2X (1) / 8 + d_rand () / 4; } gameData.fusion.xFrameTime = 0; } }
void CPaletteManager::FadeEffect (void) { float nDecAmount = 0; bool bForce = false; // Diminish at FADE_RATE units/second. // For frame rates > FADE_RATE Hz, use randomness to achieve this. if (gameData.time.xFrame < I2X (1) / FADE_RATE) { if (d_rand () < gameData.time.xFrame * FADE_RATE / 2) nDecAmount = 1; } else { if (!(nDecAmount = X2F (gameData.time.xFrame * FADE_RATE))) // one second = FADE_RATE counts nDecAmount = 1; // make sure we decrement by something } nDecAmount /= 64.0f; if (m_data.xFlashDuration) { // Part of hack system to force update of palette after exiting a menu. if (m_data.xLastEffectTime) bForce = true; if ((m_data.xLastEffectTime + I2X (1)/8 < gameData.time.xGame) || (m_data.xLastEffectTime > gameData.time.xGame)) { audio.PlaySound (SOUND_CLOAK_OFF, SOUNDCLASS_GENERIC, m_data.xFlashDuration / 4); m_data.xLastEffectTime = gameData.time.xGame; } m_data.xFlashDuration -= gameData.time.xFrame; if (m_data.xFlashDuration < 0) m_data.xFlashDuration = 0; if (bForce || (d_rand () > 4096)) { if ((gameData.demo.nState == ND_STATE_RECORDING) && (m_data.effect.red || m_data.effect.green || m_data.effect.blue)) NDRecordPaletteEffect (short (m_data.effect.red * 64), short (m_data.effect.green * 64), short (m_data.effect.blue * 64)); paletteManager.SetEffect (); return; } } m_data.effect.red = UpdateEffect (m_data.effect.red, nDecAmount); m_data.effect.green = UpdateEffect (m_data.effect.green, nDecAmount); m_data.effect.blue = UpdateEffect (m_data.effect.blue, nDecAmount); if ((gameData.demo.nState == ND_STATE_RECORDING) && (m_data.effect.red || m_data.effect.green || m_data.effect.blue)) NDRecordPaletteEffect (short (m_data.effect.red * 64), short (m_data.effect.green * 64), short (m_data.effect.blue * 64)); SetEffect (bForce); }
/* Create the netgame aux data. * Byte 0 is the protcol version number. * Bytes 1-4 hold the IPv4 multicast session for the game. */ static void ipx_mcast4_InitNetgameAuxData(ipx_socket_t *sk, u_char buf[NETGAME_AUX_SIZE]) { char addr[16]; Assert(game_addr.s_addr == 0); // The first byte is the version number buf[0] = IPX_MCAST4_VERSION; // Generate a random session // game_addr = inet_makeaddr(239*256 + 255, d_rand() % 0xFFFF); sprintf(addr, "%i.%i.%i.%i", 239, 255, d_rand() % 0xFF, d_rand() % 0xFF); game_addr.s_addr = inet_addr(addr); memcpy(buf + 1, &game_addr, sizeof(game_addr)); // Since we're obviously the hosting machine, subscribe to this address ipx_mcast4_HandleNetgameAuxData(sk, buf); }
// ----------------------------------------------------------------------------- //move all OBJECTS for the current frame int UpdateAllObjects (void) { int i; CObject *objP, *nextObjP; gameData.objs.nFrameCount++; #if DBG static int bOnce = 0; if (bOnce >= 0) { if (bOnce > 0) bOnce = -1; if (!OBJECTS [gameData.multiplayer.nLocalPlayer].CriticalDamage () && (gameStates.app.nSDLTicks - OBJECTS [gameData.multiplayer.nLocalPlayer].TimeLastRepaired () > 5000)) OBJECTS [gameData.multiplayer.nLocalPlayer].SetDamage (1 + d_rand () % 10, 1 + d_rand () % 10, 1 + d_rand () % 10); } #endif if (gameData.objs.nLastObject [0] > gameData.objs.nMaxUsedObjects) FreeObjectSlots (gameData.objs.nMaxUsedObjects); // Free all possible CObject slots. #if LIMIT_PHYSICS_FPS if (!gameStates.app.tick60fps.bTick) return 1; gameData.physics.xTime = SECS2X (gameStates.app.tick60fps.nTime); #else gameData.physics.xTime = gameData.time.xFrame; #endif CleanupObjects (); if (gameOpts->gameplay.nAutoLeveling) gameData.objs.consoleP->mType.physInfo.flags |= PF_LEVELLING; else gameData.objs.consoleP->mType.physInfo.flags &= ~PF_LEVELLING; // Move all OBJECTS gameStates.entropy.bConquering = 0; UpdatePlayerOrient (); //WaitForEffectsThread (); i = 0; for (objP = gameData.objs.lists.all.head; objP; objP = nextObjP) { nextObjP = objP->Links (0).next; if ((objP->info.nType != OBJ_NONE) && (objP->info.nType != OBJ_GHOST) && !(objP->info.nFlags & OF_SHOULD_BE_DEAD) && !objP->Update ()) return 0; i++; } return 1; }
// ----------------------------------------------------------------------------- // Called every frame. If control center been destroyed, then actually do something. void do_controlcen_dead_frame(void) { if ((Dead_controlcen_object_num != -1) && (Countdown_seconds_left > 0)) if (d_rand() < FrameTime*4) create_small_fireball_on_object(&Objects[Dead_controlcen_object_num], F1_0, 1); if (Control_center_destroyed && !Endlevel_sequence) do_countdown_frame(); }
CFixVector *RandomPointOnQuad (CFixVector *quad, CFixVector *vPos) { CFixVector vOffs; int i; i = rand () % 2; vOffs = quad [i + 1] - quad [i]; vOffs *= (2 * d_rand ()); vOffs += quad [i]; i += 2; *vPos = quad [(i + 1) % 4] - quad [i]; *vPos *= (2 * d_rand ()); *vPos += quad [i]; *vPos -= vOffs; *vPos *= (2 * d_rand ()); *vPos += vOffs; return vPos; }
void DoReactorSmoke (CObject *objP) { int h = -1, nObject, nSmoke, nShields = 0, nParts; CFixVector vDir, vPos; nObject = objP->Index (); if (!(SHOW_SMOKE && gameOpts->render.particles.bRobots)) { if (particleManager.GetObjectSystem (nObject) >= 0) KillObjectSmoke (nObject); return; } if ((objP->info.xShields < 0) || (objP->info.nFlags & (OF_SHOULD_BE_DEAD | OF_DESTROYED))) nParts = 0; else { nShields = X2IR (gameData.bots.info [gameStates.app.bD1Mission][objP->info.nId].strength); h = nShields ? X2IR (objP->info.xShields) * 100 / nShields : 0; } if (h < 0) h = 0; nParts = 10 - h / 10; if (nParts > 0) { nParts = REACTOR_MAX_PARTS; if (0 > (nSmoke = particleManager.GetObjectSystem (nObject))) { //PrintLog ("creating robot %d smoke\n", nObject); nSmoke = particleManager.Create (&objP->info.position.vPos, NULL, NULL, objP->info.nSegment, 1, nParts, F2X (-4.0), -1, 1, BOT_PART_LIFE * 2, BOT_PART_SPEED, SMOKE_PARTICLES, nObject, smokeColors, 1, -1); if (nSmoke < 0) return; particleManager.SetObjectSystem (nObject, nSmoke); } else { particleManager.SetScale (nSmoke, F2X (-4.0)); particleManager.SetDensity (nSmoke, nParts, -1); vDir[X] = d_rand () - I2X (1) / 4; vDir[Y] = d_rand () - I2X (1) / 4; vDir[Z] = d_rand () - I2X (1) / 4; CFixVector::Normalize (vDir); vPos = objP->info.position.vPos + vDir * (-objP->info.xSize / 2); particleManager.SetPos (nSmoke, &vPos, NULL, objP->info.nSegment); } } else KillObjectSmoke (nObject); }
// ---------------------------------------------------------------------- // General purpose robot-dies-with-death-roll-and-groan code. // Return true if tObject just died. // scale: F1_0*4 for boss, much smaller for much smaller guys int DoRobotDyingFrame (tObject *objP, fix StartTime, fix xRollDuration, sbyte *bDyingSoundPlaying, short deathSound, fix xExplScale, fix xSoundScale) { fix xRollVal, temp; fix xSoundDuration; tDigiSound *soundP; if (!xRollDuration) xRollDuration = F1_0/4; xRollVal = FixDiv (gameData.time.xGame - StartTime, xRollDuration); FixSinCos (FixMul (xRollVal, xRollVal), &temp, &objP->mType.physInfo.rotVel.p.x); FixSinCos (xRollVal, &temp, &objP->mType.physInfo.rotVel.p.y); FixSinCos (xRollVal-F1_0/8, &temp, &objP->mType.physInfo.rotVel.p.z); temp = gameData.time.xGame - StartTime; objP->mType.physInfo.rotVel.p.x = temp / 9; objP->mType.physInfo.rotVel.p.y = temp / 5; objP->mType.physInfo.rotVel.p.z = temp / 7; if (gameOpts->sound.digiSampleRate) { soundP = gameData.pig.sound.pSounds + DigiXlatSound (deathSound); xSoundDuration = FixDiv (soundP->nLength [soundP->bHires], gameOpts->sound.digiSampleRate); } else xSoundDuration = F1_0; if (StartTime + xRollDuration - xSoundDuration < gameData.time.xGame) { if (!*bDyingSoundPlaying) { #if TRACE con_printf (CONDBG, "Starting death sound!\n"); #endif *bDyingSoundPlaying = 1; DigiLinkSoundToObject2 (deathSound, OBJ_IDX (objP), 0, xSoundScale, xSoundScale * 256, SOUNDCLASS_ROBOT); // F1_0*512 means play twice as loud } else if (d_rand () < gameData.time.xFrame*16) CreateSmallFireballOnObject (objP, (F1_0 + d_rand ()) * (16 * xExplScale/F1_0) / 8, 0); } else if (d_rand () < gameData.time.xFrame * 8) CreateSmallFireballOnObject (objP, (F1_0/2 + d_rand ()) * (16 * xExplScale / F1_0) / 8, 1); return (StartTime + xRollDuration < gameData.time.xGame); }
// ---------------------------------------------------------------------- // General purpose robot-dies-with-death-roll-and-groan code. // Return true if CObject just died. // scale: I2X (4) for boss, much smaller for much smaller guys int DoRobotDyingFrame (CObject *objP, fix StartTime, fix xRollDuration, sbyte *bDyingSoundPlaying, short deathSound, fix xExplScale, fix xSoundScale) { fix xRollVal, temp; fix xSoundDuration; CSoundSample *soundP; if (!xRollDuration) xRollDuration = I2X (1)/4; xRollVal = FixDiv (gameData.time.xGame - StartTime, xRollDuration); FixSinCos (FixMul (xRollVal, xRollVal), &temp, &objP->mType.physInfo.rotVel[X]); FixSinCos (xRollVal, &temp, &objP->mType.physInfo.rotVel[Y]); FixSinCos (xRollVal-I2X (1)/8, &temp, &objP->mType.physInfo.rotVel[Z]); temp = gameData.time.xGame - StartTime; objP->mType.physInfo.rotVel[X] = temp / 9; objP->mType.physInfo.rotVel[Y] = temp / 5; objP->mType.physInfo.rotVel[Z] = temp / 7; if (gameOpts->sound.digiSampleRate) { soundP = gameData.pig.sound.soundP + audio.XlatSound (deathSound); xSoundDuration = FixDiv (soundP->nLength [soundP->bHires], gameOpts->sound.digiSampleRate); } else xSoundDuration = I2X (1); if (StartTime + xRollDuration - xSoundDuration < gameData.time.xGame) { if (!*bDyingSoundPlaying) { #if TRACE console.printf (CON_DBG, "Starting death sound!\n"); #endif *bDyingSoundPlaying = 1; audio.CreateObjectSound (deathSound, SOUNDCLASS_ROBOT, objP->Index (), 0, xSoundScale, xSoundScale * 256); // I2X (5)12 means play twice as loud } else if (d_rand () < gameData.time.xFrame*16) CreateSmallFireballOnObject (objP, (I2X (1) + d_rand ()) * (16 * xExplScale/I2X (1)) / 8, 0); } else if (d_rand () < gameData.time.xFrame * 8) CreateSmallFireballOnObject (objP, (I2X (1)/2 + d_rand ()) * (16 * xExplScale / I2X (1)) / 8, 1); return (StartTime + xRollDuration < gameData.time.xGame); }
// If a smega missile been detonated, rock the mine! // This should be called every frame. // Maybe this should affect all robots, being called when they get their physics done. void RockTheMineFrame (void) { int i; for (i = 0; i < MAX_ESHAKER_DETONATES; i++) { if (eshakerDetonateTimes [i] != 0) { fix deltaTime = gameData.time.xGame - eshakerDetonateTimes [i]; if (!gameStates.gameplay.seismic.bSound) { DigiPlaySampleLooping ((short) gameStates.gameplay.seismic.nSound, F1_0, -1, -1); gameStates.gameplay.seismic.bSound = 1; gameStates.gameplay.seismic.nNextSoundTime = gameData.time.xGame + d_rand()/2; } if (deltaTime < ESHAKER_SHAKE_TIME) { // Control center destroyed, rock the tPlayer's ship. int fc, rx, rz; fix h; // -- fc = abs(deltaTime - ESHAKER_SHAKE_TIME/2); // Changed 10/23/95 to make decreasing for super mega missile. fc = (ESHAKER_SHAKE_TIME - deltaTime) / (ESHAKER_SHAKE_TIME / 16); if (fc > 16) fc = 16; else if (fc == 0) fc = 1; gameStates.gameplay.seismic.nVolume += fc; h = 3 * F1_0 / 16 + (F1_0 * (16 - fc)) / 32; rx = FixMul(d_rand() - 16384, h); rz = FixMul(d_rand() - 16384, h); gameData.objs.console->mType.physInfo.rotVel.p.x += rx; gameData.objs.console->mType.physInfo.rotVel.p.z += rz; // Shake the buddy! if (gameData.escort.nObjNum != -1) { gameData.objs.objects[gameData.escort.nObjNum].mType.physInfo.rotVel.p.x += rx*4; gameData.objs.objects[gameData.escort.nObjNum].mType.physInfo.rotVel.p.z += rz*4; } // Shake a guided missile! gameStates.gameplay.seismic.nMagnitude += rx; } else eshakerDetonateTimes [i] = 0; } } // Hook in the rumble sound effect here. }
// ----------------------------------------------------------------------------- // Called every frame. If control center been destroyed, then actually do something. void DoReactorDeadFrame (void) { if ((gameData.reactor.nDeadObj != -1) && (gameData.objs.objects [gameData.reactor.nDeadObj].type == OBJ_CNTRLCEN) && (gameData.reactor.countdown.nSecsLeft > 0)) if (d_rand () < gameData.time.xFrame * 4) CreateSmallFireballOnObject (&gameData.objs.objects[gameData.reactor.nDeadObj], F1_0, 1); if (gameData.reactor.bDestroyed && !gameStates.app.bEndLevelSequence) DoCountdownFrame (); }
//initialize the player object position & orientation (at start of game, or new ship) void InitPlayerPosition(int random) { int NewPlayer=0; if (! ((Game_mode & GM_MULTI) && !(Game_mode&GM_MULTI_COOP)) ) // If not deathmatch NewPlayer = Player_num; #ifdef NETWORK else if ((Game_mode & GM_MULTI) && (Netgame.SpawnStyle == SPAWN_STYLE_PREVIEW) && Dead_player_camera != NULL) NewPlayer = previewed_spawn_point; #endif else if (random == 1) { int i, trys=0; fix closest_dist = 0x7ffffff, dist; timer_update(); d_srand((fix)timer_query()); do { trys++; NewPlayer = d_rand() % NumNetPlayerPositions; closest_dist = 0x7fffffff; for (i=0; i<N_players; i++ ) { if ( (i!=Player_num) && (Objects[Players[i].objnum].type == OBJ_PLAYER) ) { dist = find_connected_distance(&Objects[Players[i].objnum].pos, Objects[Players[i].objnum].segnum, &Player_init[NewPlayer].pos, Player_init[NewPlayer].segnum, 15, WID_FLY_FLAG ); // Used to be 5, search up to 15 segments if ( (dist < closest_dist) && (dist >= 0) ) { closest_dist = dist; } } } } while ( (closest_dist<i2f(15*20)) && (trys<MAX_PLAYERS*2) ); } else { // If deathmatch and not random, positions were already determined by sync packet reset_player_object(); reset_cruise(); return; } Assert(NewPlayer >= 0); Assert(NewPlayer < NumNetPlayerPositions); ConsoleObject->pos = Player_init[NewPlayer].pos; ConsoleObject->orient = Player_init[NewPlayer].orient; #ifdef NETWORK if ((Game_mode & GM_MULTI) && (Netgame.SpawnStyle == SPAWN_STYLE_PREVIEW) && Dead_player_camera != NULL) { ConsoleObject->orient = Dead_player_camera->orient; Dead_player_camera = NULL; } #endif obj_relink(ConsoleObject-Objects,Player_init[NewPlayer].segnum); reset_player_object(); reset_cruise(); }
void DropCurrentWeapon () { int ammo=0,seed; objnum_t objnum; if (num_objects >= MAX_USED_OBJECTS) return; if (Primary_weapon==0) { HUD_init_message(HM_DEFAULT, "You cannot drop your base weapon!"); return; } HUD_init_message(HM_DEFAULT, "%s dropped!",PRIMARY_WEAPON_NAMES(Primary_weapon)); digi_play_sample (SOUND_DROP_WEAPON,F1_0); seed = d_rand(); objnum = spit_powerup(ConsoleObject,Primary_weapon_to_powerup[Primary_weapon],seed); if (objnum==object_none) return; if (Primary_weapon == VULCAN_INDEX || Primary_weapon == GAUSS_INDEX) { //if it's one of these, drop some ammo with the weapon ammo = Players[Player_num].primary_ammo[VULCAN_INDEX]; if ((Players[Player_num].primary_weapon_flags & HAS_FLAG(VULCAN_INDEX)) && (Players[Player_num].primary_weapon_flags & HAS_FLAG(GAUSS_INDEX))) ammo /= 2; //if both vulcan & gauss, drop half Players[Player_num].primary_ammo[VULCAN_INDEX] -= ammo; if (objnum!=object_none) Objects[objnum].ctype.powerup_info.count = ammo; } if (Primary_weapon == OMEGA_INDEX) { //dropped weapon has current energy if (objnum!=object_none) Objects[objnum].ctype.powerup_info.count = Omega_charge; } #ifdef NETWORK if ((Game_mode & GM_MULTI) && objnum!=object_none) multi_send_drop_weapon(objnum,seed); #endif Players[Player_num].primary_weapon_flags &= (~(1<<Primary_weapon)); auto_select_weapon (0); }