int LasersAreRelated (int o1, int o2)
{
	CObject	*objP1, *objP2;
	short		id1, id2;
	fix		ct1, ct2;

if ((o1 < 0) || (o2 < 0))
	return 0;
objP1 = OBJECTS + o1;
objP2 = OBJECTS + o2;
id1 = objP1->info.nId;
ct1 = objP1->cType.laserInfo.xCreationTime;
// See if o2 is the parent of o1
if (objP1->info.nType == OBJ_WEAPON)
	if ((objP1->cType.laserInfo.parent.nObject == o2) &&
		 (objP1->cType.laserInfo.parent.nSignature == objP2->info.nSignature)) {
		//	o1 is a weapon, o2 is the parent of 1, so if o1 is PROXIMITY_BOMB and o2 is player, they are related only if o1 < 2.0 seconds old
		if (LaserCreationTimeout (id1, ct1))
			return 0;
		return 1;
		}

id2 = objP2->info.nId;
ct2 = objP2->cType.laserInfo.xCreationTime;
// See if o1 is the parent of o2
if (objP2->info.nType == OBJ_WEAPON)
	if ((objP2->cType.laserInfo.parent.nObject == o1) &&
		 (objP2->cType.laserInfo.parent.nSignature == objP1->info.nSignature)) {
		//	o2 is a weapon, o1 is the parent of 2, so if o2 is PROXIMITY_BOMB and o1 is player, they are related only if o1 < 2.0 seconds old
		if (LaserCreationTimeout (id2, ct2))
			return 0;
		return 1;
		}

// They must both be weapons
if ((objP1->info.nType != OBJ_WEAPON) || (objP2->info.nType != OBJ_WEAPON))
	return 0;

//	Here is the 09/07/94 change -- Siblings must be identical, others can hurt each other
// See if they're siblings...
//	MK: 06/08/95, Don't allow prox bombs to detonate for 3/4 second.  Else too likely to get toasted by your own bomb if hit by opponent.
if (objP1->cType.laserInfo.parent.nSignature == objP2->cType.laserInfo.parent.nSignature) {
	if ((id1 != PROXMINE_ID)  && (id2 != PROXMINE_ID) && (id1 != SMARTMINE_ID) && (id2 != SMARTMINE_ID))
		return 1;
	//	If neither is older than 1/2 second, then can't blow up!
	if ((gameData.time.xGame > (ct1 + I2X (1)/2) * gameStates.gameplay.slowmo [0].fSpeed) ||
		 (gameData.time.xGame > (ct2 + I2X (1)/2) * gameStates.gameplay.slowmo [0].fSpeed))
		return 0;
	return 1;
	}

//	Anything can cause a collision with a robot super prox mine.
if (WeaponIsMine (id1) || WeaponIsMine (id2))
	return 0;
if (!COMPETITION && EGI_FLAG (bKillMissiles, 0, 0, 0) && (gameData.objs.bIsMissile [id1] || gameData.objs.bIsMissile [id2]))
	return 0;
return 1;
}
Beispiel #2
0
static int RenderWeapon (CObject* objP, int bForce)
{
if (gameStates.render.nType != 1)
	return 0;
if (gameStates.render.nShadowPass != 2) {
	if (automap.m_bDisplay && !AM_SHOW_POWERUPS (1))
		return 0;
	if (objP->info.nType != OBJ_WEAPON)
		DrawWeaponVClip (objP);
	else {
		if (WeaponIsMine (objP->info.nId)) {
			if (!DoObjectSmoke (objP))
				DrawWeaponVClip (objP);
			}
		else if ((objP->info.nId != OMEGA_ID) || !(SHOW_LIGHTNING && gameOpts->render.lightning.bOmega && !gameStates.render.bOmegaModded)) {
			DrawWeaponVClip (objP);
			if (objP->info.nId != OMEGA_ID) {
				RenderLightTrail (objP);
				RenderMslLockIndicator (objP);
				}
			}
		}
	}
return 1;
}
Beispiel #3
0
static int RenderWeaponModel (CObject* objP, int bDepthSort, int bSpectate)
{
if (automap.m_bDisplay && !AM_SHOW_POWERUPS (1))
	return 0;
if (!(gameStates.app.bNostalgia || gameOpts->render.powerups.b3D) && WeaponIsMine (objP->info.nId) && (objP->info.nId != SMALLMINE_ID))
	ConvertWeaponToVClip (objP);
else {
	if (gameStates.render.nType != 1)
		return 0;
	if (gameData.objs.bIsMissile [objP->info.nId]) {	//make missiles smaller during launch
		if ((objP->cType.laserInfo.parent.nType == OBJ_PLAYER) &&
			 (gameData.models.renderModels [1][108].m_bValid > 0)) {	//hires player ship
			float dt = X2F (gameData.time.xGame - objP->CreationTime ());

			if (dt < 1) {
				fix xScale = (fix) (I2X (1) + I2X (1) * dt * dt) / 2;
				gameData.models.vScale.Set (xScale, xScale, xScale);
				}
			}
		//DoObjectSmoke (objP);
		DrawPolygonObject (objP, bDepthSort, 0);
#if RENDER_HITBOX
#	if 0
		DrawShieldSphere (objP, 0.66f, 0.2f, 0.0f, 0.4f);
#	else
		RenderHitbox (objP, 0.5f, 0.0f, 0.6f, 0.4f);
#	endif
#endif
		RenderThrusterFlames (objP);
		gameData.models.vScale.SetZero ();
		}
	else {
#if RENDER_HITBOX
#	if 0
		DrawShieldSphere (objP, 0.66f, 0.2f, 0.0f, 0.4f);
#	else
		RenderHitbox (objP, 0.5f, 0.0f, 0.6f, 0.4f);
#	endif
#endif
		if (objP->info.nType != OBJ_WEAPON) {
			DrawPolygonObject (objP, bDepthSort, 0);
			if ((objP->info.nId != SMALLMINE_ID) && !gameStates.render.bQueryCoronas)
				RenderLightTrail (objP);
			}
		else {
			if ((objP->info.nId == VULCAN_ID) || (objP->info.nId == GAUSS_ID)) {
				if (SHOW_OBJ_FX && extraGameInfo [0].bTracers) {
					if (!gameStates.render.bQueryCoronas)
						RenderLightTrail (objP);
					gameData.models.vScale.Set (I2X (1) / 4, I2X (1) / 4, I2X (2));
					CFixVector vSavedPos = objP->info.position.vPos;
					objP->info.position.vPos += objP->info.position.mOrient.FVec ();
					DrawPolygonObject (objP, bDepthSort, 0);
					objP->info.position.vPos = vSavedPos;
					}
				}
			else {
				if ((objP->info.nId != SMALLMINE_ID) && !gameStates.render.bQueryCoronas)
					RenderLightTrail (objP);
				DrawPolygonObject (objP, bDepthSort, 0);
				}
			gameData.models.vScale.SetZero ();
			}
		}
	}
return 1;
}
Beispiel #4
0
CObject* CreateExplosion (CObject* parentP, short nSegment, CFixVector& vPos, fix xSize,
								  ubyte nVClip, fix xMaxDamage, fix xMaxDistance, fix xMaxForce, short nParent)
{
	short			nObject;
	CObject		*explObjP, *objP;
	fix			dist, force, damage;
	CFixVector	vHit, vForce;
	int			nType, id;
	int			flash = parentP ? static_cast<int> (gameData.weapons.info [parentP->info.nId].flash) : 0;

nObject = CreateFireball (nVClip, nSegment, vPos, xSize, RT_FIREBALL);

if (nObject < 0) {
#if TRACE
	console.printf (1, "Can'nType create CObject in /*Object*/CreateExplosionSub.\n");
#endif
	return NULL;
	}

explObjP = OBJECTS + nObject;
//now set explosion-specific data
explObjP->info.xLifeLeft = gameData.eff.vClips [0][nVClip].xTotalTime;
explObjP->cType.explInfo.nSpawnTime = -1;
explObjP->cType.explInfo.nDeleteObj = -1;
explObjP->cType.explInfo.nDeleteTime = -1;

if (xMaxDamage <= 0)
	return explObjP;
// -- now legal for xBadAss explosions on a CWall. Assert (this != NULL);
FORALL_OBJS (objP, i) {
	nType = objP->info.nType;
	id = objP->info.nId;
	//	Weapons used to be affected by xBadAss explosions, but this introduces serious problems.
	//	When a smart bomb blows up, if one of its children goes right towards a nearby CWall, it will
	//	blow up, blowing up all the children.  So I remove it.  MK, 09/11/94
	if (objP == parentP)
		continue;
	if (objP->info.nFlags & OF_SHOULD_BE_DEAD)
		continue;
	if (nType == OBJ_WEAPON) {
		if (!WeaponIsMine (objP->info.nId))
		continue;
		}
	else if (nType == OBJ_ROBOT) {
		if (nParent < 0)
			continue;
		if ((OBJECTS [nParent].info.nType == OBJ_ROBOT) && (OBJECTS [nParent].info.nId == id))
			continue;
		}
	else if ((nType != OBJ_REACTOR) && (nType != OBJ_PLAYER))
		continue;
	dist = CFixVector::Dist (objP->info.position.vPos, explObjP->info.position.vPos);
	// Make damage be from 'xMaxDamage' to 0.0, where 0.0 is 'xMaxDistance' away;
	if (dist >= xMaxDistance)
		continue;
	if (!ObjectToObjectVisibility (explObjP, objP, FQ_TRANSWALL))
		continue;
	damage = xMaxDamage - FixMulDiv (dist, xMaxDamage, xMaxDistance);
	force = xMaxForce - FixMulDiv (dist, xMaxForce, xMaxDistance);
	// Find the force vector on the CObject
	CFixVector::NormalizedDir(vForce, objP->info.position.vPos, explObjP->info.position.vPos);
	vForce *= force;
	// Find where the point of impact is... (vHit)
	vHit = explObjP->info.position.vPos - objP->info.position.vPos;
	vHit *= (FixDiv (objP->info.xSize, objP->info.xSize + dist));
	if (nType == OBJ_WEAPON) {
		objP->ApplyForce (vForce);
		if (WeaponIsMine (objP->info.nId) && (FixMul (dist, force) > I2X (8000))) {	//prox bombs have chance of blowing up
			objP->Die ();
			objP->ExplodeBadassWeapon (objP->info.position.vPos);
			}
		}
	else if (nType == OBJ_ROBOT) {
		CFixVector	vNegForce;
		fix			xScale = -2 * (7 - gameStates.app.nDifficultyLevel) / 8;

		objP->ApplyForce (vForce);
		//	If not a boss, stun for 2 seconds at 32 force, 1 second at 16 force
		if (flash && !ROBOTINFO (objP->info.nId).bossFlag) {
			tAIStaticInfo	*aip = &objP->cType.aiInfo;
			int				nForce = X2I (FixDiv (vForce.Mag () * flash, gameData.time.xFrame) / 128) + 2;

			if (explObjP->cType.aiInfo.SKIP_AI_COUNT * gameData.time.xFrame >= I2X (1))
				aip->SKIP_AI_COUNT--;
			else {
				aip->SKIP_AI_COUNT += nForce;
				objP->mType.physInfo.rotThrust [X] = ((d_rand () - 16384) * nForce) / 16;
				objP->mType.physInfo.rotThrust [Y] = ((d_rand () - 16384) * nForce) / 16;
				objP->mType.physInfo.rotThrust [Z] = ((d_rand () - 16384) * nForce) / 16;
				objP->mType.physInfo.flags |= PF_USES_THRUST;
				}
			}
		vNegForce [X] = vForce [X] * xScale;
		vNegForce [Y] = vForce [Y] * xScale;
		vNegForce [Z] = vForce [Z] * xScale;
		objP->ApplyRotForce (vNegForce);
		if (objP->info.xShields >= 0) {
			if (ROBOTINFO (objP->info.nId).bossFlag &&
				 bossProps [gameStates.app.bD1Mission][ROBOTINFO (objP->info.nId).bossFlag - BOSS_D2].bInvulKinetic)
				damage /= 4;
			if (objP->ApplyDamageToRobot (damage, nParent)) {
				if (!gameStates.gameplay.bNoBotAI && parentP && (nParent == LOCALPLAYER.nObject))
					cockpit->AddPointsToScore (ROBOTINFO (objP->info.nId).scoreValue);
				}
			}
		if (!flash && ROBOTINFO (objP->info.nId).companion)
			BuddyOuchMessage (damage);
		}
	else if (nType == OBJ_REACTOR) {
		if (objP->info.xShields >= 0)
			objP->ApplyDamageToReactor (damage, nParent);
		}
	else if (nType == OBJ_PLAYER) {
		CObject*		killerP = NULL;
		CFixVector	vRotForce;

		//	Hack!Warning!Test code!
		if (flash && (objP->info.nId == gameData.multiplayer.nLocalPlayer)) {
			int fe = min (I2X (4), force * flash / 32);	//	For four seconds or less
			if (parentP->cType.laserInfo.parent.nSignature == gameData.objs.consoleP->info.nSignature) {
				fe /= 2;
				force /= 2;
				}
			if (force > I2X (1)) {
				paletteManager.SetFlashDuration (fe);
				force = PK1 + X2I (PK2 * force);
				paletteManager.BumpEffect (force, force, force);
#if TRACE
				console.printf (CON_DBG, "force = %7.3f, adding %i\n", X2F (force), PK1 + X2I (PK2*force));
#endif
				}
			}
		if (parentP && IsMultiGame && (parentP->info.nType == OBJ_PLAYER))
			killerP = parentP;
		vRotForce = vForce;
		if (nParent > -1) {
			killerP = OBJECTS + nParent;
			if (killerP != gameData.objs.consoleP)		// if someone else whacks you, cut force by 2x
				vRotForce [X] /= 2;
				vRotForce [Y] /= 2;
				vRotForce [Z] /= 2;
			}
		vRotForce [X] /= 2;
		vRotForce [Y] /= 2;
		vRotForce [Z] /= 2;
		objP->ApplyForce (vForce);
		objP->ApplyRotForce (vRotForce);
		if (gameStates.app.nDifficultyLevel == 0)
			damage /= 4;
		if (objP->info.xShields >= 0)
			objP->ApplyDamageToPlayer (killerP, damage);
		}
	}
Beispiel #5
0
tObject *ObjectCreateExplosionSub (tObject *objP, short nSegment, vmsVector *vPos, fix xSize, 
											  ubyte nVClip, fix xMaxDamage, fix xMaxDistance, fix xMaxForce, short nParent)
{
	short			nObject;
	tObject		*explObjP, *obj0P;
	fix			dist, force, damage;
	vmsVector	pos_hit, vForce;
	int			i, t, id;

nObject = CreateObject (OBJ_FIREBALL, nVClip, -1, nSegment, vPos, &vmdIdentityMatrix, xSize, 
							   CT_EXPLOSION, MT_NONE, RT_FIREBALL, 1);

if (nObject < 0) {
#if TRACE
	con_printf (1, "Can't create tObject in ObjectCreateExplosionSub.\n");
#endif
	return NULL;
	}

explObjP = gameData.objs.objects + nObject;
//now set explosion-specific data
explObjP->lifeleft = gameData.eff.vClips [0][nVClip].xTotalTime;
explObjP->cType.explInfo.nSpawnTime = -1;
explObjP->cType.explInfo.nDeleteObj = -1;
explObjP->cType.explInfo.nDeleteTime = -1;

if (xMaxDamage <= 0)
	return explObjP;
// -- now legal for xBadAss explosions on a tWall. Assert (objP != NULL);
for (i = 0, obj0P = gameData.objs.objects; i <= gameData.objs.nLastObject; i++, obj0P++) {
	t = obj0P->nType;
	id = obj0P->id;
	//	Weapons used to be affected by xBadAss explosions, but this introduces serious problems.
	//	When a smart bomb blows up, if one of its children goes right towards a nearby tWall, it will
	//	blow up, blowing up all the children.  So I remove it.  MK, 09/11/94
	if (obj0P == objP)
		continue;
	if (obj0P->flags & OF_SHOULD_BE_DEAD)
		continue;
	if (t == OBJ_WEAPON) {
		if (!WeaponIsMine (obj0P->id)) 
		continue;
		}
	else if (t == OBJ_ROBOT) {
		if (nParent < 0)
			continue;
		if ((gameData.objs.objects [nParent].nType == OBJ_ROBOT) && (gameData.objs.objects [nParent].id == id))
			continue;
		}
	else if ((t != OBJ_REACTOR) && (t != OBJ_PLAYER))
		continue;
	dist = VmVecDistQuick (&obj0P->position.vPos, &explObjP->position.vPos);
	// Make damage be from 'xMaxDamage' to 0.0, where 0.0 is 'xMaxDistance' away;
	if (dist >= xMaxDistance)
		continue;
	if (!ObjectToObjectVisibility (explObjP, obj0P, FQ_TRANSWALL))
		continue;
	damage = xMaxDamage - FixMulDiv (dist, xMaxDamage, xMaxDistance);
	force = xMaxForce - FixMulDiv (dist, xMaxForce, xMaxDistance);
	// Find the force vector on the tObject
	VmVecNormalizedDirQuick (&vForce, &obj0P->position.vPos, &explObjP->position.vPos);
	VmVecScale (&vForce, force);
	// Find where the point of impact is... (pos_hit)
	VmVecSub (&pos_hit, &explObjP->position.vPos, &obj0P->position.vPos);
	VmVecScale (&pos_hit, FixDiv (obj0P->size, obj0P->size + dist));
	if (t == OBJ_WEAPON) {
		PhysApplyForce (obj0P, &vForce);
		if (WeaponIsMine (obj0P->id) && (FixMul (dist, force) > i2f (8000))) {	//prox bombs have chance of blowing up
			KillObject (obj0P);
			ExplodeBadassWeapon (obj0P, &obj0P->position.vPos);
			}
		}
	else if (t == OBJ_ROBOT) {
		vmsVector	vNegForce;
		fix			xScale = -2 * (7 - gameStates.app.nDifficultyLevel) / 8;

		PhysApplyForce (obj0P, &vForce);
		//	If not a boss, stun for 2 seconds at 32 force, 1 second at 16 force
		if (objP && (!ROBOTINFO (obj0P->id).bossFlag) && (gameData.weapons.info [objP->id].flash)) {
			tAIStatic	*aip = &obj0P->cType.aiInfo;
			int			force_val = f2i (FixDiv (VmVecMagQuick (&vForce) * gameData.weapons.info [objP->id].flash, gameData.time.xFrame)/128) + 2;

			if (explObjP->cType.aiInfo.SKIP_AI_COUNT * gameData.time.xFrame >= F1_0) 
				aip->SKIP_AI_COUNT--;
			else {
				aip->SKIP_AI_COUNT += force_val;
				obj0P->mType.physInfo.rotThrust.p.x = ((d_rand () - 16384) * force_val)/16;
				obj0P->mType.physInfo.rotThrust.p.y = ((d_rand () - 16384) * force_val)/16;
				obj0P->mType.physInfo.rotThrust.p.z = ((d_rand () - 16384) * force_val)/16;
				obj0P->mType.physInfo.flags |= PF_USES_THRUST;
				}
			}
		vNegForce.p.x = vForce.p.x * xScale;
		vNegForce.p.y = vForce.p.y * xScale;
		vNegForce.p.z = vForce.p.z * xScale;
		PhysApplyRot (obj0P, &vNegForce);
		if (obj0P->shields >= 0) {
			if (ROBOTINFO (obj0P->id).bossFlag &&
				 bossProps [gameStates.app.bD1Mission][ROBOTINFO (obj0P->id).bossFlag-BOSS_D2].bInvulKinetic)
				damage /= 4;
			if (ApplyDamageToRobot (obj0P, damage, nParent) && objP && (nParent == LOCALPLAYER.nObject))
				AddPointsToScore (ROBOTINFO (obj0P->id).scoreValue);
			}
		if (objP && (ROBOTINFO (obj0P->id).companion) && !gameData.weapons.info [objP->id].flash) {
			int	i, count;
			char	szOuch [6*4 + 2];

			count = f2i (damage / 8);
			if (count > 4)
				count = 4;
			else if (count <= 0)
				count = 1;
			szOuch [0] = 0;
			for (i = 0; i < count; i++) {
				strcat (szOuch, TXT_BUDDY_OUCH);
				strcat (szOuch, " ");
				}
			BuddyMessage (szOuch);
			}
		}
	else if (t == OBJ_REACTOR) {
		if (obj0P->shields >= 0)
			ApplyDamageToReactor (obj0P, damage, nParent);
		}
	else if (t == OBJ_PLAYER) {
		tObject		*killerP = NULL;
		vmsVector	vForce2;

		//	Hack!Warning!Test code!
		if (objP && gameData.weapons.info [objP->id].flash && obj0P->id==gameData.multiplayer.nLocalPlayer) {
			int fe = min (F1_0*4, force*gameData.weapons.info [objP->id].flash/32);	//	For four seconds or less
			if (objP->cType.laserInfo.nParentSig == gameData.objs.console->nSignature) {
				fe /= 2;
				force /= 2;
				}
			if (force > F1_0) {
				gameData.render.xFlashEffect = fe;
				PALETTE_FLASH_ADD (PK1 + f2i (PK2*force), PK1 + f2i (PK2*force), PK1 + f2i (PK2*force));
#if TRACE
				con_printf (CONDBG, "force = %7.3f, adding %i\n", f2fl (force), PK1 + f2i (PK2*force));
#endif
				}
			}
		if (objP && IsMultiGame && (objP->nType == OBJ_PLAYER))
			killerP = objP;
		vForce2 = vForce;
		if (nParent > -1) {
			killerP = gameData.objs.objects + nParent;
			if (killerP != gameData.objs.console)		// if someone else whacks you, cut force by 2x
				vForce2.p.x /= 2;
				vForce2.p.y /= 2;
				vForce2.p.z /= 2;
			}
		vForce2.p.x /= 2;
		vForce2.p.y /= 2;
		vForce2.p.z /= 2;
		PhysApplyForce (obj0P, &vForce);
		PhysApplyRot (obj0P, &vForce2);
		if (gameStates.app.nDifficultyLevel == 0)
			damage /= 4;
		if (obj0P->shields >= 0)
			ApplyDamageToPlayer (obj0P, killerP, damage);
		}
	}
return explObjP;
}