// ----------------------------------------------------------------------------------------------------------- //given an CObject and a gun number, return position in 3-space of gun //fills in gun_point int CalcGunPoint (CFixVector *vGunPoint, CObject *objP, int nGun) { CPolyModel* pm = gameData.models.polyModels [0] + objP->rType.polyObjInfo.nModel; tRobotInfo* botInfoP; CFixVector* vGunPoints, vGunPos, vRot; CFixMatrix m; int nSubModel; //submodel number Assert(objP->info.renderType == RT_POLYOBJ || objP->info.renderType == RT_MORPH); //Assert(objP->info.nId < gameData.bots.nTypes [gameStates.app.bD1Data]); botInfoP = &ROBOTINFO (objP->info.nId); if (!(vGunPoints = GetGunPoints (objP, nGun))) return 0; vGunPos = vGunPoints [nGun]; nSubModel = botInfoP->gunSubModels [nGun]; //instance up the tree for this gun while (nSubModel != 0) { m = CFixMatrix::Create (objP->rType.polyObjInfo.animAngles [nSubModel]); CFixMatrix::Transpose (m); vRot = m * vGunPos; vGunPos = vRot + pm->SubModels ().offsets [nSubModel]; nSubModel = pm->SubModels ().parents [nSubModel]; } //now instance for the entire CObject //VmVecInc (&vGunPos, gameData.models.offsets + botInfoP->nModel); *vGunPoint = *objP->View () * vGunPos; *vGunPoint += objP->info.position.vPos; return 1; }
// ----------------------------------------------------------------------------------------------------------- //given an tObject and a gun number, return position in 3-space of gun //fills in gun_point int CalcGunPoint (vmsVector *vGunPoint, tObject *objP, int nGun) { tPolyModel *pm = gameData.models.polyModels + objP->rType.polyObjInfo.nModel; tRobotInfo *botInfoP; vmsVector *vGunPoints, vGunPos, vRot; vmsMatrix m; int nSubModel, bCustom = 0; //submodel number Assert(objP->renderType == RT_POLYOBJ || objP->renderType==RT_MORPH); //Assert(objP->id < gameData.bots.nTypes [gameStates.app.bD1Data]); botInfoP = &ROBOTINFO (objP->id); if (!(vGunPoints = GetGunPoints (objP, nGun))) return 0; vGunPos = vGunPoints [nGun]; nSubModel = botInfoP->gunSubModels [nGun]; //instance up the tree for this gun while (nSubModel != 0) { VmAngles2Matrix (&m, &objP->rType.polyObjInfo.animAngles [nSubModel]); VmTransposeMatrix (&m); VmVecRotate (&vRot, &vGunPos, &m); VmVecAdd (&vGunPos, &vRot, &pm->subModels.offsets [nSubModel]); nSubModel = pm->subModels.parents [nSubModel]; } //now instance for the entire tObject VmVecRotate (vGunPoint, &vGunPos, ObjectView (objP)); VmVecInc (vGunPoint, &objP->position.vPos); return 1; }
void DoGatlingSmoke (tObject *objP) { int nModel = objP->rType.polyObjInfo.nModel; int bHires = G3HaveModel (nModel) - 1; if (bHires >= 0) { tG3Model *pm = gameData.models.g3Models [bHires] + nModel; if (pm->bBullets) { int nPlayer = objP->info.nId; int nGun = EquippedPlayerGun (objP); int bDoEffect = (bHires >= 0) && ((nGun == VULCAN_INDEX) || (nGun == GAUSS_INDEX)) && (gameData.multiplayer.weaponStates [nPlayer].firing [0].nDuration >= GATLING_DELAY); int i = gameData.multiplayer.gatlingSmoke [nPlayer]; if (bDoEffect) { int bSpectate = SPECTATOR (objP); tTransformation *posP = bSpectate ? &gameStates.app.playerPos : &objP->info.position; vmsVector *vGunPoints, vEmitter, vDir; vmsMatrix m, *viewP; if (!(vGunPoints = GetGunPoints (objP, nGun))) return; if (bSpectate) { viewP = &m; *viewP = posP->mOrient.Transpose(); } else viewP = ObjectView (objP); vEmitter = *viewP * vGunPoints[nGun]; vEmitter += posP->vPos; //vDir = posP->mOrient[FVEC]; vDir = posP->mOrient[FVEC] * (F1_0 / 8); if (i < 0) { gameData.multiplayer.gatlingSmoke [nPlayer] = CreateSmoke (&vEmitter, &vDir, &posP->mOrient, objP->info.nSegment, 1, GATLING_MAX_PARTS, F1_0 / 2, 1, 1, GATLING_PART_LIFE, GATLING_PART_SPEED, SMOKE_PARTICLES, 0x7ffffffe, smokeColors + 1, 0, -1); } else { SetSmokePos (i, &vEmitter, &posP->mOrient, objP->info.nSegment); } } else { if (i >= 0) { SetSmokeLife (i, 0); gameData.multiplayer.gatlingSmoke [nPlayer] = -1; } } } } }
int FireWeaponDelayedWithSpread ( CObject *objP, ubyte nLaserType, int nGun, fix xSpreadR, fix xSpreadU, fix xDelay, int bMakeSound, int bHarmless, short nLightObj) { short nLaserSeg; int nFate; CFixVector vLaserPos, vLaserDir, *vGunPoints; CHitQuery fq; CHitData hitData; int nObject; CObject* laserP; #if FULL_COCKPIT_OFFS int bLaserOffs = ((gameStates.render.cockpit.nType == CM_FULL_COCKPIT) && (objP->Index () == LOCALPLAYER.nObject)); #else int bLaserOffs = 0; #endif CFixMatrix m; int bSpectate = SPECTATOR (objP); tObjTransformation* posP = bSpectate ? &gameStates.app.playerPos : &objP->info.position; #if DBG if (nLaserType == SMARTMINE_BLOB_ID) nLaserType = nLaserType; #endif CreateAwarenessEvent (objP, PA_WEAPON_WALL_COLLISION); // Find the initial vPosition of the laser if (!(vGunPoints = GetGunPoints (objP, nGun))) return 0; TransformGunPoint (objP, vGunPoints, nGun, xDelay, nLaserType, &vLaserPos, &m); //--------------- Find vLaserPos and nLaserSeg ------------------ fq.p0 = &posP->vPos; fq.startSeg = bSpectate ? gameStates.app.nPlayerSegment : objP->info.nSegment; fq.p1 = &vLaserPos; fq.radP0 = fq.radP1 = 0x10; fq.thisObjNum = objP->Index (); fq.ignoreObjList = NULL; fq.flags = FQ_CHECK_OBJS | FQ_IGNORE_POWERUPS; fq.bCheckVisibility = false; nFate = FindHitpoint (&fq, &hitData); nLaserSeg = hitData.hit.nSegment; if (nLaserSeg == -1) { //some sort of annoying error return -1; } //SORT OF HACK... IF ABOVE WAS CORRECT THIS WOULDNT BE NECESSARY. if (CFixVector::Dist (vLaserPos, posP->vPos) > 3 * objP->info.xSize / 2) { return -1; } if (nFate == HIT_WALL) { return -1; } #if 0 //as of 12/6/94, we don't care if the laser is stuck in an object. We //just fire away normally if (nFate == HIT_OBJECT) { if (OBJECTS [hitData.hitObject].nType == OBJ_ROBOT) OBJECTS [hitData.hitObject].Die (); if (OBJECTS [hitData.hitObject].nType != OBJ_POWERUP) return; } #endif // Now, make laser spread out. vLaserDir = m.FVec (); if (xSpreadR || xSpreadU) { vLaserDir += m.RVec () * xSpreadR; vLaserDir += m.UVec () * xSpreadU; } if (bLaserOffs) vLaserDir += m.UVec () * LASER_OFFS; nObject = CreateNewWeapon (&vLaserDir, &vLaserPos, nLaserSeg, objP->Index (), nLaserType, bMakeSound); // Omega cannon is a hack, not surprisingly. Don't want to do the rest of this stuff. if (nLaserType == OMEGA_ID) return -1; if (nObject == -1) return -1; //TrackWeaponObject (nObject, int (objP->info.nId)); laserP = OBJECTS + nObject; if ((nLaserType == GUIDEDMSL_ID) && gameData.multigame.bIsGuided) gameData.objs.guidedMissile [objP->info.nId].objP = laserP; gameData.multigame.bIsGuided = 0; if (gameData.objs.bIsMissile [nLaserType] && (nLaserType != GUIDEDMSL_ID)) { if (!gameData.objs.missileViewerP && (objP->info.nId == gameData.multiplayer.nLocalPlayer)) gameData.objs.missileViewerP = laserP; } // If this weapon is supposed to be silent, set that bit! if (!bMakeSound) laserP->info.nFlags |= OF_SILENT; // If this weapon is supposed to be silent, set that bit! if (bHarmless) laserP->info.nFlags |= OF_HARMLESS; // If the object firing the laser is the CPlayerData, then indicate the laser object so robots can dodge. // New by MK on 6/8/95, don't let robots evade proximity bombs, thereby decreasing uselessness of bombs. if ((objP == gameData.objs.consoleP) && !WeaponIsPlayerMine (laserP->info.nId)) gameStates.app.bPlayerFiredLaserThisFrame = nObject; if (gameStates.app.cheats.bHomingWeapons || gameData.weapons.info [nLaserType].homingFlag) { if (objP == gameData.objs.consoleP) { laserP->cType.laserInfo.nHomingTarget = FindHomingObject (&vLaserPos, laserP); gameData.multigame.laser.nTrack = laserP->cType.laserInfo.nHomingTarget; } else {// Some other CPlayerData shot the homing thing Assert (IsMultiGame); laserP->cType.laserInfo.nHomingTarget = gameData.multigame.laser.nTrack; } } lightClusterManager.Add (nObject, nLightObj); return nObject; }