Пример #1
0
void WiggleObject (CObject *objP)
{
	fix		xWiggle;
	int		nParent;
	CObject	*pParent;

if (gameStates.render.nShadowPass == 2)
	return;
if (gameOpts->app.bEpilepticFriendly)
	return;
if (!gameStates.app.bNostalgia && (!EGI_FLAG (nDrag, 0, 0, 0) || !EGI_FLAG (bWiggle, 1, 0, 1)))
	return;
nParent = gameData.objs.parentObjs [objP->Index ()];
pParent = (nParent < 0) ? NULL : OBJECTS + nParent;
FixFastSinCos (fix (gameData.time.xGame / gameStates.gameplay.slowmo [1].fSpeed), &xWiggle, NULL);
if (gameData.time.xFrame < I2X (1))// Only scale wiggle if getting at least 1 FPS, to avoid causing the opposite problem.
	xWiggle = FixMul (xWiggle * 20, gameData.time.xFrame); //make wiggle fps-independent (based on pre-scaled amount of wiggle at 20 FPS)
if (SPECTATOR (objP))
	OBJPOS (objP)->vPos += (OBJPOS (objP)->mOrient.UVec () * FixMul (xWiggle, gameData.pig.ship.player->wiggle)) * (I2X (1) / 20);
else if ((objP->info.nType == OBJ_PLAYER) || !pParent)
	objP->mType.physInfo.velocity += objP->info.position.mOrient.UVec () * FixMul (xWiggle, gameData.pig.ship.player->wiggle);
else {
	objP->mType.physInfo.velocity += pParent->info.position.mOrient.UVec () * FixMul (xWiggle, gameData.pig.ship.player->wiggle);
	objP->info.position.vPos += objP->mType.physInfo.velocity * gameData.time.xFrame;
	}
}
Пример #2
0
// ----------------------------------------------------------------------------------
//	When some robots collide with the CPlayerData, they attack.
//	If CPlayerData is cloaked, then robot probably didn't actually collide, deal with that here.
void DoAIRobotHitAttack (CObject *robotP, CObject *playerobjP, CFixVector *vCollision)
{
	tAILocalInfo	*ailP = gameData.ai.localInfo + OBJ_IDX (robotP);
	tRobotInfo		*botInfoP = &ROBOTINFO (robotP->info.nId);

if (!gameStates.app.cheats.bRobotsFiring)
	return;
//	If CPlayerData is dead, stop firing.
if (OBJECTS [LOCALPLAYER.nObject].info.nType == OBJ_GHOST)
	return;
if (botInfoP->attackType != 1)
	return;
if (ailP->nextPrimaryFire > 0)
	return;
if (!(LOCALPLAYER.flags & PLAYER_FLAGS_CLOAKED)) {
	if (CFixVector::Dist (OBJPOS (gameData.objs.consoleP)->vPos, robotP->info.position.vPos) <
		 robotP->info.xSize + gameData.objs.consoleP->info.xSize + I2X (2)) {
		playerobjP->CollidePlayerAndNastyRobot (robotP, *vCollision);
		if (botInfoP->energyDrain && LOCALPLAYER.energy) {
			LOCALPLAYER.energy -= I2X (botInfoP->energyDrain);
			if (LOCALPLAYER.energy < 0)
				LOCALPLAYER.energy = 0;
			}
		}
	}
robotP->cType.aiInfo.GOAL_STATE = AIS_RECOVER;
SetNextFireTime (robotP, ailP, botInfoP, 1);	//	1 = nGun: 0 is special (uses nextSecondaryFire)
}
Пример #3
0
fix CheckVectorToHitbox (CFixVector& intersection, CFixVector *p0, CFixVector *p1, CFixVector *vRef, CObject *objP, fix rad, short& nModel)
{
	int				iModel, nModels;
	fix				xDist = 0x7fffffff, dMin = 0x7fffffff;
	CModelHitboxes	*pmhb = gameData.models.hitboxes + objP->rType.polyObjInfo.nModel;
	tBox				hb [MAX_HITBOXES + 1];
	CFixVector		vHit;

if (extraGameInfo [IsMultiGame].nHitboxes == 1) {
	iModel =
	nModels = 0;
	}
else {
	iModel = 1;
	nModels = pmhb->nHitboxes;
	}
if (!vRef)
	vRef = &OBJPOS (objP)->vPos;
intersection.Create (0x7fffffff, 0x7fffffff, 0x7fffffff);
TransformHitboxes (objP, vRef, hb);
for (; iModel <= nModels; iModel++) {
	if (FindLineHitboxIntersection (vHit, hb + iModel, p0, p1, p0, rad)) {
		xDist = RegisterHit (&intersection, &vHit, vRef, dMin);
		if (dMin > xDist) {
			dMin = xDist;
			nModel = iModel;
			}
		}
	}
return xDist;
}
Пример #4
0
void UpdateOglHeadLight (void)
{
	tDynLight	*pl;
	tObject		*objP;
	short			nPlayer;

for (nPlayer = 0; nPlayer < MAX_PLAYERS; nPlayer++) {
	if (gameData.render.lights.dynamic.nHeadLights [nPlayer] < 0)
		continue;
	pl = gameData.render.lights.dynamic.lights + gameData.render.lights.dynamic.nHeadLights [nPlayer];
	objP = OBJECTS + gameData.multiplayer.players [nPlayer].nObject;
	pl->info.vPos = OBJPOS (objP)->vPos;
	pl->vDir = OBJPOS (objP)->mOrient.fVec;
	VmVecScaleInc (&pl->info.vPos, &pl->vDir, objP->size / 4);
	}
}
Пример #5
0
fix CheckHitboxToHitbox (CFixVector& intersection, CObject *objP1, CObject *objP2, CFixVector *p0, CFixVector *p1, short& nModel)
{
	CFixVector		vHit, vRef = OBJPOS (objP2)->vPos;
	int				iModel1, nModels1, iModel2, nModels2, nHits = 0;
	CModelHitboxes	*pmhb1 = gameData.models.hitboxes + objP1->rType.polyObjInfo.nModel;
	CModelHitboxes	*pmhb2 = gameData.models.hitboxes + objP2->rType.polyObjInfo.nModel;
	tBox				hb1 [MAX_HITBOXES + 1];
	tBox				hb2 [MAX_HITBOXES + 1];
	fix				xDist = 0x7fffffff, dMin = 0x7fffffff;

if (extraGameInfo [IsMultiGame].nHitboxes == 1) {
	iModel1 =
	nModels1 =
	iModel2 =
	nModels2 = 0;
	}
else {
	iModel1 =
	iModel2 = 1;
	nModels1 = pmhb1->nHitboxes;
	nModels2 = pmhb2->nHitboxes;
	}
#if DBG
memset (hb1, 0, sizeof (hb1));
memset (hb2, 0, sizeof (hb2));
#endif
TransformHitboxes (objP1, p1, hb1);
TransformHitboxes (objP2, &vRef, hb2);
for (; iModel1 <= nModels1; iModel1++) {
	for (; iModel2 <= nModels2; iModel2++) {
		if (FindHitboxIntersection (vHit, hb1 + iModel1, hb2 + iModel2, p0)) {
			xDist = RegisterHit (&intersection, &vHit, &vRef, dMin);
			if (dMin > xDist) {
				nHits++;
				dMin = xDist;
				nModel = iModel1;
				}
			}
		}
	}
if (!nHits) {
	for (; iModel2 <= nModels2; iModel2++) {
		if (FindLineHitboxIntersection (vHit, hb2 + iModel2, p0, p1, p0, 0)) {
			xDist = RegisterHit (&intersection, &vHit, &vRef, dMin);
			if (dMin > xDist) {
				nHits++;
				dMin = xDist;
				nModel = iModel1;
				}
			}
		}
	}
#if DBG
if (nHits) {
	pmhb1->vHit = pmhb2->vHit = intersection;
	pmhb1->tHit = pmhb2->tHit = gameStates.app.nSDLTicks;
	}
#endif
return nHits ? dMin ? dMin : 1 : 0;
}
Пример #6
0
void DrawShieldSphere (tObject *objP, float red, float green, float blue, float alpha)
{
if (!CreateShieldSphere ())
	return;
#if !SIMPLE_SPHERE
if (gameData.render.shield.nFaces > 0) 
#endif
	{
	if ((gameOpts->render.bDepthSort > 0) || (gameOpts->render.nPath && !gameOpts->render.bDepthSort))
		RIAddSphere (riSphereShield, red, green, blue, alpha, objP);
	else {
		tOOF_vector	p;
		fix nSize = gameData.models.polyModels [objP->rType.polyObjInfo.nModel].rad;
		float	fScale, r = f2fl (nSize) * 1.05f;
		tPosition *posP = OBJPOS (objP);
		vmsVector vPos;
		gameStates.ogl.bUseTransform = 1;
		G3StartInstanceMatrix (&posP->vPos, &posP->mOrient);
		RenderSphere (&gameData.render.shield, (tOOF_vector *) OOF_VecVms2Oof (&p, gameData.models.offsets + objP->rType.polyObjInfo.nModel),
						  r, r, r, red, green, blue, alpha, bmpShield, 1);
		G3DoneInstance ();
		gameStates.ogl.bUseTransform = 0;
		fScale = gameData.render.shield.pPulse->fScale;
		VmVecRotate (&vPos, gameData.models.offsets + objP->rType.polyObjInfo.nModel, ObjectView (objP));
		VmVecInc (&vPos, &posP->vPos);
		RenderObjectHalo (&vPos, 3 * nSize / 2, red * fScale, green * fScale, blue * fScale, alpha * fScale, 0);
		}
	}
}
Пример #7
0
void DrawShieldSphere (tObject *objP, float red, float green, float blue, float alpha)
{
if (!CreateShieldSphere ())
	return;
#if !SIMPLE_SPHERE
if (gameData.render.shield.nFaces > 0)
#endif
	{
	if ((gameOpts->render.bDepthSort > 0) || (RENDERPATH && !gameOpts->render.bDepthSort))
		TIAddSphere (riSphereShield, red, green, blue, alpha, objP);
	else {
		tOOF_vector	p = {0, 0, 0};
		fix nSize = gameData.models.polyModels [objP->rType.polyObjInfo.nModel].rad;
		float	fScale, r = X2F (nSize) /** 1.05f*/;
		tTransformation *posP = OBJPOS (objP);
		vmsVector vPos;
		//gameStates.ogl.bUseTransform = 1;
		glBlendFunc (GL_ONE, GL_ONE);
		G3StartInstanceMatrix (*PolyObjPos (objP, &vPos), posP->mOrient);
		RenderSphere (&gameData.render.shield, &p, r, r, r, red, green, blue, alpha, bmpShield, 1, 1);
		G3DoneInstance ();
		gameStates.ogl.bUseTransform = 0;
		fScale = gameData.render.shield.pPulse->fScale;
		G3StartInstanceMatrix (vPos, posP->mOrient);
		vPos.SetZero();
		RenderObjectHalo (&vPos, 3 * nSize / 2, red * fScale, green * fScale, blue * fScale, alpha * fScale, 0);
		G3DoneInstance ();
		}
	}
}
Пример #8
0
//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;
}
Пример #9
0
CFixMatrix *CObject::View (void)
{
	tObjectViewData	*viewP = gameData.objs.viewData +Index ();

if (viewP->nFrame != gameData.objs.nFrameCount) {
	viewP->mView = OBJPOS (this)->mOrient.Transpose ();
	viewP->nFrame = gameStates.render.nFrameCount;
	}
return &viewP->mView;
}
Пример #10
0
//------------------------------------------------------------------------------
//do special cloaked render
int DrawCloakedObject (CObject *objP, fix light, fix *glow, fix xCloakStartTime, fix xCloakEndTime)
{
	tObjTransformation	*posP = OBJPOS (objP);
	tCloakInfo	ci;
	int			bOk = 0;

if (gameStates.render.bQueryCoronas)
	return 1;
GetCloakInfo (objP, xCloakStartTime, xCloakEndTime, &ci);
if (ci.bFading < 0) {
	fix xNewLight, xSaveGlow;
	tBitmapIndex * altTextures = NULL;

	if (objP->rType.polyObjInfo.nAltTextures > 0)
		altTextures = mpTextureIndex [objP->rType.polyObjInfo.nAltTextures - 1];
	xNewLight = FixMul (light, ci.xLightScale);
	xSaveGlow = glow [0];
	glow [0] = FixMul (glow [0], ci.xLightScale);
	gameData.models.nLightScale = ci.xLightScale;
	bOk = DrawPolyModel (objP, &posP->vPos, &posP->mOrient,
								reinterpret_cast<CAngleVector*> (&objP->rType.polyObjInfo.animAngles),
								objP->rType.polyObjInfo.nModel, objP->rType.polyObjInfo.nSubObjFlags,
								xNewLight, glow, altTextures, NULL);
	gameData.models.nLightScale = 0;
	glow [0] = xSaveGlow;
	}
else {
	gameStates.render.bCloaked = 1;
	gameStates.render.grAlpha = GrAlpha (ci.nFadeValue);
	CCanvas::Current ()->SetColorRGB (0, 0, 0, 255);	//set to black (matters for s3)
	fpDrawTexPolyMulti = G3DrawTexPolyFlat;
	bOk = DrawPolyModel (objP, &posP->vPos, &posP->mOrient,
								reinterpret_cast<CAngleVector*> (&objP->rType.polyObjInfo.animAngles),
								objP->rType.polyObjInfo.nModel, objP->rType.polyObjInfo.nSubObjFlags,
								light, glow, NULL, NULL);
	fpDrawTexPolyMulti = G3DrawTexPolyMulti;
	gameStates.render.grAlpha = 1.0f;
	gameStates.render.bCloaked = 0;
	}
return bOk;
}
Пример #11
0
void DoPlayerSmoke (tObject *objP, int i)
{
	int				h, j, d, nParts, nType;
	float				nScale;
	tCloud			*pCloud;
	vmsVector		fn, mn, vDir, *vDirP;
	tThrusterInfo	ti;

	static int	bForward = 1;

if (i < 0)
	i = objP->info.nId;
if ((gameData.multiplayer.players [i].flags & PLAYER_FLAGS_CLOAKED) ||
	 (gameStates.render.automap.bDisplay && IsMultiGame && !AM_SHOW_PLAYERS)) {
	KillObjectSmoke (i);
	return;
	}
j = OBJ_IDX (objP);
if (gameOpts->render.smoke.bDecreaseLag && (i == gameData.multiplayer.nLocalPlayer)) {
	fn = objP->info.position.mOrient[FVEC];
	mn = objP->info.position.vPos - objP->info.vLastPos;
	vmsVector::Normalize(fn);
	vmsVector::Normalize(mn);
	d = vmsVector::Dot(fn, mn);
	if (d >= -F1_0 / 2)
		bForward = 1;
	else {
		if (bForward) {
			if ((h = gameData.smoke.objects [j]) >= 0) {
				KillObjectSmoke (j);
				DestroySmoke (h);
				}
			bForward = 0;
			nScale = 0;
			return;
			}
		}
	}
#if 0
if (EGI_FLAG (bThrusterFlames, 1, 1, 0)) {
	if ((a <= F1_0 / 4) && (a || !gameStates.input.bControlsSkipFrame))	//no thruster flames if moving backward
		DropAfterburnerBlobs (objP, 2, I2X (1), -1, gameData.objs.consoleP, 1); //F1_0 / 4);
	}
#endif
if ((gameData.app.nGameMode & GM_NETWORK) && !gameData.multiplayer.players [i].connected)
	nParts = 0;
else if (objP->info.nFlags & (OF_SHOULD_BE_DEAD | OF_DESTROYED))
	nParts = 0;
else if ((i == gameData.multiplayer.nLocalPlayer) && (gameStates.app.bPlayerIsDead || (gameData.multiplayer.players [i].shields < 0)))
	nParts = 0;
else {
	h = X2IR (gameData.multiplayer.players [i].shields);
	nParts = 10 - h / 5;
	nScale = X2F (objP->info.xSize);
	if (h <= 25)
		nScale /= 1.5;
	else if (h <= 50)
		nScale /= 2;
	else
		nScale /= 3;
	if (nParts <= 0) {
		nType = 2;
		//nParts = (gameStates.entropy.nTimeLastMoved < 0) ? 250 : 125;
		}
	else {
		CreateDamageExplosion (nParts, j);
		nType = (h > 25);
		nParts *= 25;
		nParts += 75;
		}
	nParts = objP->mType.physInfo.thrust.IsZero() ? SHIP_MAX_PARTS : SHIP_MAX_PARTS / 2;
	if (SHOW_SMOKE && nParts && gameOpts->render.smoke.bPlayers) {
		if (gameOpts->render.smoke.bSyncSizes) {
			nParts = -MAX_PARTICLES (nParts, gameOpts->render.smoke.nDens [0]);
			nScale = PARTICLE_SIZE (gameOpts->render.smoke.nSize [0], nScale);
			}
		else {
			nParts = -MAX_PARTICLES (nParts, gameOpts->render.smoke.nDens [1]);
			nScale = PARTICLE_SIZE (gameOpts->render.smoke.nSize [1], nScale);
			}
		if (!objP->mType.physInfo.thrust.IsZero ())
			vDirP = NULL;
		else {	// if the ship is standing still, let the thruster smoke move away from it
			nParts /= 2;
			nScale /= 2;
			vDir = OBJPOS (objP)->mOrient [FVEC] * (F1_0 / 8);
			vDir = -vDir;
			vDirP = &vDir;
			}
		if (0 > (h = gameData.smoke.objects [j])) {
			//PrintLog ("creating tPlayer smoke\n");
			h = SetSmokeObject (j,
					CreateSmoke (&objP->info.position.vPos, vDirP, NULL, objP->info.nSegment, 2, nParts, nScale,
									 gameOpts->render.smoke.nSize [1],
									 2, PLR_PART_LIFE / (nType + 1) * (vDirP ? 2 : 1), PLR_PART_SPEED, SMOKE_PARTICLES, j, smokeColors + nType, 1, -1));
			}
		else {
			if (vDirP)
				SetSmokeDir (h, vDirP);
			SetSmokeLife (h, PLR_PART_LIFE / (nType + 1) * (vDirP ? 2 : 1));
			SetSmokeType (h, SMOKE_PARTICLES);
			SetSmokePartScale (h, -nScale);
			SetSmokeDensity (h, nParts, gameOpts->render.smoke.bSyncSizes ? -1 : gameOpts->render.smoke.nSize [1]);
			SetSmokeSpeed (gameData.smoke.objects [i],
								objP->mType.physInfo.thrust.IsZero () ? PLR_PART_SPEED * 2 : PLR_PART_SPEED);
			}
		CalcThrusterPos (objP, &ti, 0);
		for (j = 0; j < 2; j++)
			if ((pCloud = GetCloud (h, j)))
				SetCloudPos (pCloud, ti.vPos + j, NULL, objP->info.nSegment);
		DoGatlingSmoke (objP);
		return;
		}
	}
KillObjectSmoke (i);
KillGatlingSmoke (objP);
}
Пример #12
0
void CObject::SaveState (CFile& cf)
{
cf.WriteInt (info.nSignature);      
cf.WriteByte ((sbyte) info.nType); 
cf.WriteByte ((sbyte) info.nId);
cf.WriteShort (info.nNextInSeg);
cf.WriteShort (info.nPrevInSeg);
cf.WriteByte ((sbyte) info.controlType);
cf.WriteByte ((sbyte) info.movementType);
cf.WriteByte ((sbyte) info.renderType);
cf.WriteByte ((sbyte) info.nFlags);
cf.WriteShort (info.nSegment);
cf.WriteShort (info.nAttachedObj);
cf.WriteVector (OBJPOS (this)->vPos);     
cf.WriteMatrix (OBJPOS (this)->mOrient);  
cf.WriteFix (info.xSize); 
cf.WriteFix (info.xShields);
cf.WriteVector (info.vLastPos);  
cf.WriteByte (info.contains.nType); 
cf.WriteByte (info.contains.nId);   
cf.WriteByte (info.contains.nCount);
cf.WriteByte (info.nCreator);
cf.WriteFix (info.xLifeLeft);   
if (info.movementType == MT_PHYSICS) {
	cf.WriteVector (mType.physInfo.velocity);   
	cf.WriteVector (mType.physInfo.thrust);     
	cf.WriteFix (mType.physInfo.mass);       
	cf.WriteFix (mType.physInfo.drag);       
	cf.WriteFix (mType.physInfo.brakes);     
	cf.WriteVector (mType.physInfo.rotVel);     
	cf.WriteVector (mType.physInfo.rotThrust);  
	cf.WriteFixAng (mType.physInfo.turnRoll);   
	cf.WriteShort ((short) mType.physInfo.flags);      
	}
else if (info.movementType == MT_SPINNING) {
	cf.WriteVector(mType.spinRate);  
	}
switch (info.controlType) {
	case CT_WEAPON:
		cf.WriteShort (cType.laserInfo.parent.nType);
		cf.WriteShort (cType.laserInfo.parent.nObject);
		cf.WriteInt (cType.laserInfo.parent.nSignature);
		cf.WriteFix (cType.laserInfo.xCreationTime);
		if (cType.laserInfo.nLastHitObj)
			cf.WriteShort (gameData.objs.nHitObjects [Index () * MAX_HIT_OBJECTS + cType.laserInfo.nLastHitObj - 1]);
		else
			cf.WriteShort (-1);
		cf.WriteShort (cType.laserInfo.nHomingTarget);
		cf.WriteFix (cType.laserInfo.xScale);
		break;

	case CT_EXPLOSION:
		cf.WriteFix (cType.explInfo.nSpawnTime);
		cf.WriteFix (cType.explInfo.nDeleteTime);
		cf.WriteShort (cType.explInfo.nDeleteObj);
		cf.WriteShort (cType.explInfo.attached.nParent);
		cf.WriteShort (cType.explInfo.attached.nPrev);
		cf.WriteShort (cType.explInfo.attached.nNext);
		break;

	case CT_AI:
		cf.WriteByte ((sbyte) cType.aiInfo.behavior);
		cf.Write (cType.aiInfo.flags, 1, MAX_AI_FLAGS);
		cf.WriteShort (cType.aiInfo.nHideSegment);
		cf.WriteShort (cType.aiInfo.nHideIndex);
		cf.WriteShort (cType.aiInfo.nPathLength);
		cf.WriteByte (cType.aiInfo.nCurPathIndex);
		cf.WriteByte (cType.aiInfo.bDyingSoundPlaying);
		cf.WriteShort (cType.aiInfo.nDangerLaser);
		cf.WriteInt (cType.aiInfo.nDangerLaserSig);
		cf.WriteFix (cType.aiInfo.xDyingStartTime);
		break;

	case CT_LIGHT:
		cf.WriteFix (cType.lightInfo.intensity);
		break;

	case CT_POWERUP:
		cf.WriteInt (cType.powerupInfo.nCount);
		cf.WriteFix (cType.powerupInfo.xCreationTime);
		cf.WriteInt (cType.powerupInfo.nFlags);
		break;
	}
switch (info.renderType) {
	case RT_MORPH:
	case RT_POLYOBJ: {
		int i;
		cf.WriteInt (rType.polyObjInfo.nModel);
		for (i = 0; i < MAX_SUBMODELS; i++)
			cf.WriteAngVec (rType.polyObjInfo.animAngles [i]);
		cf.WriteInt (rType.polyObjInfo.nSubObjFlags);
		cf.WriteInt (rType.polyObjInfo.nTexOverride);
		cf.WriteInt (rType.polyObjInfo.nAltTextures);
		break;
		}
	case RT_WEAPON_VCLIP:
	case RT_HOSTAGE:
	case RT_POWERUP:
	case RT_FIREBALL:
	case RT_THRUSTER:
		cf.WriteInt (rType.vClipInfo.nClipIndex);
		cf.WriteFix (rType.vClipInfo.xFrameTime);
		cf.WriteByte (rType.vClipInfo.nCurFrame);
		break;

	case RT_LASER:
		break;
	}
}
Пример #13
0
//	-----------------------------------------------------------------------------
//do whatever this thing does in a frame
void DoReactorFrame (CObject *objP)
{
	int				nBestGun, i;
	tReactorStates	*rStatP;

	//	If a boss level, then gameData.reactor.bPresent will be 0.
if (!gameData.reactor.bPresent)
	return;
i = FindReactor (objP);
if (i < 0)
	return;
rStatP = gameData.reactor.states + i;
#if DBG
if (!gameStates.app.cheats.bRobotsFiring || (gameStates.app.bGameSuspended & SUSP_ROBOTS))
	return;
#else
if (!gameStates.app.cheats.bRobotsFiring)
	return;
#endif

if (!(rStatP->bHit || rStatP->bSeenPlayer)) {
	if (gameStates.app.tick40fps.bTick) {		//	Do ever so often...
		CFixVector	vecToPlayer;
		fix			xDistToPlayer;
		int			i;
		CSegment		*segP = SEGMENTS + objP->info.nSegment;

		// This is a hack.  Since the control center is not processed by
		// ai_do_frame, it doesn't know how to deal with cloaked dudes.  It
		// seems to work in single-CPlayerData mode because it is actually using
		// the value of Believed_player_position that was set by the last
		// person to go through ai_do_frame.  But since a no-robots game
		// never goes through ai_do_frame, I'm making it so the control
		// center can spot cloaked dudes.

		if (IsMultiGame)
			gameData.ai.target.vBelievedPos = OBJPOS (OBJECTS + LOCALPLAYER.nObject)->vPos;

		//	Hack for special control centers which are isolated and not reachable because the
		//	real control center is inside the boss.
		for (i = 0; i < MAX_SIDES_PER_SEGMENT; i++)
			if (IS_CHILD (segP->m_children [i]))
				break;
		if (i == MAX_SIDES_PER_SEGMENT)
			return;

		vecToPlayer = OBJPOS (gameData.objs.consoleP)->vPos - objP->info.position.vPos;
		xDistToPlayer = CFixVector::Normalize (vecToPlayer);
		if (xDistToPlayer < I2X (200)) {
			rStatP->bSeenPlayer = AICanSeeTarget (objP, &objP->info.position.vPos, 0, &vecToPlayer);
			rStatP->nNextFireTime = 0;
			}
		}		
	return;
	}

//	Periodically, make the reactor fall asleep if CPlayerData not visible.
if (rStatP->bHit || rStatP->bSeenPlayer) {
	if ((rStatP->xLastVisCheckTime + I2X (5) < gameData.time.xGame) || 
		 (rStatP->xLastVisCheckTime > gameData.time.xGame)) {
		CFixVector	vecToPlayer;
		fix			xDistToPlayer;

		vecToPlayer = gameData.objs.consoleP->info.position.vPos - objP->info.position.vPos;
		xDistToPlayer = CFixVector::Normalize (vecToPlayer);
		rStatP->xLastVisCheckTime = gameData.time.xGame;
		if (xDistToPlayer < I2X (120)) {
			rStatP->bSeenPlayer = AICanSeeTarget (objP, &objP->info.position.vPos, 0, &vecToPlayer);
			if (!rStatP->bSeenPlayer)
				rStatP->bHit = 0;
			}
		}
	}

if ((rStatP->nNextFireTime < 0) && 
	 !(gameStates.app.bPlayerIsDead && (gameData.time.xGame > gameStates.app.nPlayerTimeOfDeath + I2X (2)))) {
	nBestGun = CalcBestReactorGun (gameData.reactor.props [objP->info.nId].nGuns, rStatP->vGunPos, rStatP->vGunDir, 
											 (LOCALPLAYER.flags & PLAYER_FLAGS_CLOAKED) ? &gameData.ai.target.vBelievedPos : &gameData.objs.consoleP->info.position.vPos);
	if (nBestGun != -1) {
		int			nRandProb, count;
		CFixVector	vecToGoal;
		fix			xDistToPlayer;
		fix			xDeltaFireTime;

		if (LOCALPLAYER.flags & PLAYER_FLAGS_CLOAKED) {
			vecToGoal = gameData.ai.target.vBelievedPos - rStatP->vGunPos[nBestGun];
			xDistToPlayer = CFixVector::Normalize (vecToGoal);
			} 
		else {
			vecToGoal = gameData.objs.consoleP->info.position.vPos - rStatP->vGunPos [nBestGun];
			xDistToPlayer = CFixVector::Normalize (vecToGoal);
			}
		if (xDistToPlayer > I2X (300)) {
			rStatP->bHit = 0;
			rStatP->bSeenPlayer = 0;
			return;
			}
		if (gameData.app.nGameMode & GM_MULTI)
			MultiSendCtrlcenFire (&vecToGoal, nBestGun, objP->Index ());
		CreateNewLaserEasy (&vecToGoal, &rStatP->vGunPos [nBestGun], objP->Index (), CONTROLCEN_WEAPON_NUM, 1);
		//	some of time, based on level, fire another thing, not directly at CPlayerData, so it might hit him if he's constantly moving.
		nRandProb = I2X (1) / (abs (gameData.missions.nCurrentLevel) / 4 + 2);
		count = 0;
		while ((d_rand () > nRandProb) && (count < 4)) {
			CFixVector	vRand;

			vRand = CFixVector::Random();
			vecToGoal += vRand * (I2X (1)/6);
			CFixVector::Normalize (vecToGoal);
			if (IsMultiGame)
				MultiSendCtrlcenFire (&vecToGoal, nBestGun, objP->Index ());
			CreateNewLaserEasy (&vecToGoal, &rStatP->vGunPos [nBestGun], objP->Index (), CONTROLCEN_WEAPON_NUM, 0);
			count++;
			}
		xDeltaFireTime = I2X (NDL - gameStates.app.nDifficultyLevel) / 4;
		if (gameStates.app.nDifficultyLevel == 0)
			xDeltaFireTime += (fix) (I2X (1) / 2 * gameStates.gameplay.slowmo [0].fSpeed);
		if (IsMultiGame) // slow down rate of fire in multi player
			xDeltaFireTime *= 2;
		rStatP->nNextFireTime = xDeltaFireTime;
		}
	} 
else
	rStatP->nNextFireTime -= gameData.physics.xTime;
}
Пример #14
0
void DoPlayerSmoke (CObject *objP, int nPlayer)
{
	int					nObject, nSmoke, d, nParts, nType;
	float					nScale;
	CParticleEmitter	*emitterP;
	CFixVector			fn, mn, vDir, *vDirP;
	tThrusterInfo		ti;

	static int	bForward = 1;

if (nPlayer < 0)
	nPlayer = objP->info.nId;
if ((gameData.multiplayer.players [nPlayer].flags & PLAYER_FLAGS_CLOAKED) ||
	 (automap.m_bDisplay && IsMultiGame && !AM_SHOW_PLAYERS)) {
	KillObjectSmoke (nPlayer);
	return;
	}
nObject = objP->Index ();
if (gameOpts->render.particles.bDecreaseLag && (nPlayer == gameData.multiplayer.nLocalPlayer)) {
	fn = objP->info.position.mOrient.FVec ();
	mn = objP->info.position.vPos - objP->info.vLastPos;
	CFixVector::Normalize (fn);
	CFixVector::Normalize (mn);
	d = CFixVector::Dot (fn, mn);
	if (d >= -I2X (1) / 2)
		bForward = 1;
	else {
		if (bForward) {
			if ((nSmoke = particleManager.GetObjectSystem (nObject)) >= 0) {
				KillObjectSmoke (nObject);
				particleManager.Destroy (nSmoke);
				}
			bForward = 0;
			nScale = 0;
			return;
			}
		}
	}
#if 0
if (EGI_FLAG (bThrusterFlames, 1, 1, 0)) {
	if ((a <= I2X (1) / 4) && (a || !gameStates.input.bControlsSkipFrame))	//no thruster flames if moving backward
		DropAfterburnerBlobs (objP, 2, I2X (1), -1, gameData.objs.consoleP, 1); //I2X (1) / 4);
	}
#endif
if ((gameData.app.nGameMode & GM_NETWORK) && !gameData.multiplayer.players [nPlayer].connected)
	nParts = 0;
else if (objP->info.nFlags & (OF_SHOULD_BE_DEAD | OF_DESTROYED))
	nParts = 0;
else if ((nPlayer == gameData.multiplayer.nLocalPlayer) && (gameStates.app.bPlayerIsDead || (gameData.multiplayer.players [nPlayer].shields < 0)))
	nParts = 0;
else {
	nSmoke = X2IR (gameData.multiplayer.players [nPlayer].shields);
	nParts = 10 - nSmoke / 5;
	nScale = X2F (objP->info.xSize);
	if (nSmoke <= 25)
		nScale /= 1.5;
	else if (nSmoke <= 50)
		nScale /= 2;
	else
		nScale /= 3;
	if (nParts <= 0) {
		nType = 2;
		//nParts = (gameStates.entropy.nTimeLastMoved < 0) ? 250 : 125;
		}
	else {
		CreateDamageExplosion (nParts, nObject);
		nType = (nSmoke > 25);
		nParts *= 25;
		nParts += 75;
		}
	nParts = objP->mType.physInfo.thrust.IsZero () ? SHIP_MAX_PARTS : SHIP_MAX_PARTS / 2;
	if (SHOW_SMOKE && nParts && gameOpts->render.particles.bPlayers) {
		if (gameOpts->render.particles.bSyncSizes) {
			nParts = -MAX_PARTICLES (nParts, gameOpts->render.particles.nDens [0]);
			nScale = PARTICLE_SIZE (gameOpts->render.particles.nSize [0], nScale);
			}
		else {
			nParts = -MAX_PARTICLES (nParts, gameOpts->render.particles.nDens [1]);
			nScale = PARTICLE_SIZE (gameOpts->render.particles.nSize [1], nScale);
			}
		if (!objP->mType.physInfo.thrust.IsZero ())
			vDirP = NULL;
		else {	// if the ship is standing still, let the thruster smoke move away from it
			nParts /= 2;
			nScale /= 2;
			vDir = OBJPOS (objP)->mOrient.FVec () * (I2X (1) / 8);
			vDir = -vDir;
			vDirP = &vDir;
			}
		if (0 > (nSmoke = particleManager.GetObjectSystem (nObject))) {
			//PrintLog ("creating CPlayerData smoke\n");
			nSmoke = particleManager.Create (&objP->info.position.vPos, vDirP, NULL, objP->info.nSegment, 2, nParts, nScale,
														gameOpts->render.particles.nSize [1],
														2, PLR_PART_LIFE / (nType + 1) * (vDirP ? 2 : 1), PLR_PART_SPEED, SMOKE_PARTICLES, nObject, smokeColors + nType, 1, -1);
			if (nSmoke < 0)
				return;
			particleManager.SetObjectSystem (nObject, nSmoke);
			}
		else {
			if (vDirP)
				particleManager.SetDir (nSmoke, vDirP);
			particleManager.SetLife (nSmoke, PLR_PART_LIFE / (nType + 1) * (vDirP ? 2 : 1));
			particleManager.SetType (nSmoke, SMOKE_PARTICLES);
			particleManager.SetScale (nSmoke, -nScale);
			particleManager.SetDensity (nSmoke, nParts, gameOpts->render.particles.bSyncSizes ? -1 : gameOpts->render.particles.nSize [1]);
			particleManager.SetSpeed (particleManager.GetObjectSystem (nObject),
											  objP->mType.physInfo.thrust.IsZero () ? PLR_PART_SPEED * 2 : PLR_PART_SPEED);
			}
		CalcThrusterPos (objP, &ti, 0);
		for (int i = 0; i < 2; i++)
			if ((emitterP = particleManager.GetEmitter (nSmoke, i)))
				emitterP->SetPos (ti.vPos + i, NULL, objP->info.nSegment);
		DoGatlingSmoke (objP);
		return;
		}
	}
KillObjectSmoke (nObject);
KillGatlingSmoke (objP);
}