void HomingCheat (void) { if (!gameStates.app.cheats.bHomingWeapons) { int i; gameStates.app.cheats.bHomingWeapons = 1; for (i = 0;i < 20;i++) { OldHomingState [i] = WI_homingFlag (i); WI_set_homingFlag (i, 1); } HUDInitMessage (TXT_WPN_HOMING); } }
void HomingCheat (int bVerbose) { int i; if (gameStates.app.cheats.bHomingWeapons = !gameStates.app.cheats.bHomingWeapons) { for (i = 0; i < 20; i++) { bOldHomingStates [i] = WI_homingFlag (i); WI_set_homingFlag (i, 1); } if (bVerbose) HUDInitMessage (TXT_WPN_HOMING); } else { for (i = 0; i < 20; i++) WI_set_homingFlag (i, bOldHomingStates [i]); } }
//------------------------------------------------------------------------------------------- //sequence this weapon object for this _frame_ (underscores added here to aid MK in his searching!) void DoWeaponSequence (CObject *objP) { CObject *gmObjP; fix xWeaponSpeed, xScaleFactor, xDistToTarget; Assert (objP->info.controlType == CT_WEAPON); // Ok, this is a big hack by MK. // If you want an CObject to last for exactly one frame, then give it a lifeleft of ONE_FRAME_TIME if (objP->info.xLifeLeft == ONE_FRAME_TIME) { if (IsMultiGame) objP->info.xLifeLeft = OMEGA_MULTI_LIFELEFT; else objP->info.xLifeLeft = 0; objP->info.renderType = RT_NONE; } if (objP->info.xLifeLeft < 0) { // We died of old age objP->Die (); if (WI_damage_radius (objP->info.nId)) objP->ExplodeBadassWeapon (objP->info.position.vPos); return; } //delete weapons that are not moving xWeaponSpeed = objP->mType.physInfo.velocity.Mag(); if (!((gameData.app.nFrameCount ^ objP->info.nSignature) & 3) && (objP->info.nType == OBJ_WEAPON) && (objP->info.nId != FLARE_ID) && (gameData.weapons.info [objP->info.nId].speed [gameStates.app.nDifficultyLevel] > 0) && (xWeaponSpeed < I2X (2))) { ReleaseObject (objP->Index ()); return; } if ((objP->info.nType == OBJ_WEAPON) && (objP->info.nId == FUSION_ID)) { //always set fusion weapon to max vel CFixVector::Normalize (objP->mType.physInfo.velocity); objP->mType.physInfo.velocity *= (WI_speed (objP->info.nId,gameStates.app.nDifficultyLevel)); } // For homing missiles, turn towards target. (unless it's the guided missile) if ((gameData.laser.xUpdateTime >= I2X (1) / 40) && (objP->info.nType == OBJ_WEAPON) && (gameStates.app.cheats.bHomingWeapons || WI_homingFlag (objP->info.nId)) && !(objP->info.nFlags & PF_HAS_BOUNCED) && !((objP->info.nId == GUIDEDMSL_ID) && (objP == (gmObjP = gameData.objs.guidedMissile [OBJECTS [objP->cType.laserInfo.parent.nObject].info.nId].objP)) && (objP->info.nSignature == gmObjP->info.nSignature))) { fix xFrameTime; for (xFrameTime = gameData.laser.xUpdateTime; xFrameTime >= I2X (1) / 40; xFrameTime -= I2X (1) / 40) { CFixVector vVecToObject, vNewVel; fix dot = I2X (1); fix speed, xMaxSpeed, xDist; int nObjId = objP->info.nId; // For first 1/2 second of life, missile flies straight. //if (objP->cType.laserInfo.xCreationTime + HomingMslStraightTime (nObjId) < gameData.time.xGame) { int nHomingTarget = objP->cType.laserInfo.nHomingTarget; // If it's time to do tracking, then it's time to grow up, stop bouncing and start exploding!. if ((nObjId == ROBOT_SMARTMINE_BLOB_ID) || (nObjId == ROBOT_SMARTMSL_BLOB_ID) || (nObjId == SMARTMINE_BLOB_ID) || (nObjId == SMARTMSL_BLOB_ID) || (nObjId == EARTHSHAKER_MEGA_ID)) objP->mType.physInfo.flags &= ~PF_BOUNCE; // Make sure the CObject we are tracking is still trackable. nHomingTarget = TrackHomingTarget (nHomingTarget, objP, &dot); if (nHomingTarget != -1) { if (nHomingTarget == LOCALPLAYER.nObject) { xDistToTarget = CFixVector::Dist (objP->info.position.vPos, OBJECTS [nHomingTarget].info.position.vPos); if ((xDistToTarget < LOCALPLAYER.homingObjectDist) || (LOCALPLAYER.homingObjectDist < 0)) LOCALPLAYER.homingObjectDist = xDistToTarget; } vVecToObject = OBJECTS [nHomingTarget].info.position.vPos - objP->info.position.vPos; xDist = CFixVector::Normalize (vVecToObject); vNewVel = objP->mType.physInfo.velocity; speed = CFixVector::Normalize (vNewVel); xMaxSpeed = WI_speed (objP->info.nId,gameStates.app.nDifficultyLevel); if (speed + I2X (1) < xMaxSpeed) { speed += FixMul (xMaxSpeed, I2X (1) / 80); if (speed > xMaxSpeed) speed = xMaxSpeed; } if (EGI_FLAG (bEnhancedShakers, 0, 0, 0) && (objP->info.nId == EARTHSHAKER_MEGA_ID)) { fix h = (objP->info.xLifeLeft + I2X (1) - 1) / I2X (1); if (h > 7) vVecToObject *= (I2X (1) / (h - 6)); } #if 0 vVecToObject *= HomingMslScale (); #endif vNewVel += vVecToObject; // The boss' smart children track better... if (gameData.weapons.info [objP->info.nId].renderType != WEAPON_RENDER_POLYMODEL) vNewVel += vVecToObject; CFixVector::Normalize (vNewVel); CFixVector vOldVel = objP->mType.physInfo.velocity; objP->mType.physInfo.velocity = vNewVel; objP->mType.physInfo.velocity *= speed; CFixVector vTest = objP->info.position.vPos + vNewVel * xDist; if (!CanSeePoint (NULL, &objP->info.position.vPos, &vTest, objP->info.nSegment, 3 * objP->info.xSize / 2)) objP->mType.physInfo.velocity = vOldVel; else { // Subtract off life proportional to amount turned. For hardest turn, it will lose 2 seconds per second. dot = abs (I2X (1) - dot); objP->info.xLifeLeft -= FixMul (dot * 32, I2X (1) / 40); } // Only polygon OBJECTS have visible orientation, so only they should turn. if (gameData.weapons.info [objP->info.nId].renderType == WEAPON_RENDER_POLYMODEL) HomingMissileTurnTowardsVelocity (objP, &vNewVel); // vNewVel is normalized velocity. } } } } // Make sure weapon is not moving faster than allowed speed. if ((objP->info.nType == OBJ_WEAPON) && (xWeaponSpeed > WI_speed (objP->info.nId, gameStates.app.nDifficultyLevel))) { // Only slow down if not allowed to move. Makes sense, huh? Allows proxbombs to get moved by physics force. --MK, 2/13/96 if (WI_speed (objP->info.nId, gameStates.app.nDifficultyLevel)) { xScaleFactor = FixDiv (WI_speed (objP->info.nId,gameStates.app.nDifficultyLevel), xWeaponSpeed); objP->mType.physInfo.velocity *= xScaleFactor; } } }