Esempio n. 1
0
int GatherShadowLightSources (void)
{
	tObject			*objP;
	int				h, i, j, k, n, m = gameOpts->render.shadows.nLights;
	short				*pnl;
//	tDynLight		*pl;
	tShaderLight	*psl;
	vmsVector		vLightDir;

psl = gameData.render.lights.dynamic.shader.lights;
for (h = 0, i = gameData.render.lights.dynamic.nLights; i; i--, psl++)
	psl->bShadow =
	psl->bExclusive = 0;
FORALL_OBJS (objP, h) {
	if (gameData.render.mine.bObjectRendered [h] != gameStates.render.nFrameFlipFlop)
		continue;
	pnl = gameData.render.lights.dynamic.nNearestSegLights + objP->info.nSegment * MAX_NEAREST_LIGHTS;
	k = h * MAX_SHADOW_LIGHTS;
	for (i = n = 0; (n < m) && (*pnl >= 0); i++, pnl++) {
		psl = gameData.render.lights.dynamic.shader.lights + *pnl;
		if (!psl->info.bState)
			continue;
		if (!CanSeePoint (objP, &objP->info.position.vPos, &psl->info.vPos, objP->info.nSegment))
			continue;
		vLightDir = objP->info.position.vPos - psl->info.vPos;
		vmsVector::Normalize(vLightDir);
		if (n) {
			for (j = 0; j < n; j++)
				if (abs (vmsVector::Dot(vLightDir, gameData.render.shadows.vLightDir[j])) > 2 * F1_0 / 3) // 60 deg
					break;
			if (j < n)
				continue;
			}
		gameData.render.shadows.vLightDir [n] = vLightDir;
		gameData.render.shadows.objLights [k + n++] = *pnl;
		psl->bShadow = 1;
		}
	gameData.render.shadows.objLights [k + n] = -1;
	}
psl = gameData.render.lights.dynamic.shader.lights;
for (h = 0, i = gameData.render.lights.dynamic.nLights; i; i--, psl++)
	if (psl->bShadow)
		h++;
return h;
}
Esempio n. 2
0
int GatherShadowLightSources (void)
{
	CObject			*objP;
	int				h, i, j, k, l, n, m = gameOpts->render.shadows.nLights;
	short				*pnl;
//	CDynLight		*pl;
	CDynLight*		prl;
	CFixVector		vLightDir;

n = lightManager.LightCount (1);
for (h = l = 0; l < n; l++) {
	prl = lightManager.RenderLights (h);
	prl->render.bShadow =
	prl->render.bExclusive = 0;
	}

FORALL_OBJS (objP, h) {
	h = objP->Index ();
	if (gameData.render.mine.bObjectRendered [h] != gameStates.render.nFrameFlipFlop)
		continue;
	pnl = lightManager.NearestSegLights () + objP->info.nSegment * MAX_NEAREST_LIGHTS;
	k = h * MAX_SHADOW_LIGHTS;
	for (i = n = 0; (n < m) && (*pnl >= 0); i++, pnl++) {
		prl = lightManager.RenderLights (*pnl);
		if (!prl->render.bState)
			continue;
		if (!CanSeePoint (objP, &objP->info.position.vPos, &prl->info.vPos, objP->info.nSegment))
			continue;
		vLightDir = objP->info.position.vPos - prl->info.vPos;
		CFixVector::Normalize (vLightDir);
		if (n) {
			for (j = 0; j < n; j++)
				if (abs (CFixVector::Dot (vLightDir, gameData.render.shadows.vLightDir[j])) > I2X (2) / 3) // 60 deg
					break;
			if (j < n)
				continue;
			}
		gameData.render.shadows.vLightDir [n] = vLightDir;
		gameData.render.shadows.objLights [k + n++] = *pnl;
		prl->render.bShadow = 1;
		}
	gameData.render.shadows.objLights [k + n] = -1;
	}
Esempio n. 3
0
/**
* Checks if the mob can detect the target using it's detection (sight, sound, etc)
* This is used to aggro and deaggro (Mobs start to deaggro after failing to detect target).
**/
bool CMobController::CanDetectTarget(CBattleEntity* PTarget, bool forceSight)
{
    if (PTarget->isDead() || PTarget->animation == ANIMATION_CHOCOBO) return false;

    float verticalDistance = abs(PMob->loc.p.y - PTarget->loc.p.y);

    if (verticalDistance > 8)
    {
        return false;
    }

    auto detects = PMob->m_Detects;
    auto currentDistance = distance(PTarget->loc.p, PMob->loc.p) + PTarget->getMod(MOD_STEALTH);

    bool detectSight = (detects & DETECT_SIGHT) || forceSight;
    bool hasInvisible = false;
    bool hasSneak = false;

    if (!PMob->m_TrueDetection)
    {
        hasInvisible = PTarget->StatusEffectContainer->HasStatusEffectByFlag(EFFECTFLAG_INVISIBLE);
        hasSneak = PTarget->StatusEffectContainer->HasStatusEffect(EFFECT_SNEAK);
    }

    if (detectSight && !hasInvisible && currentDistance < PMob->getMobMod(MOBMOD_SIGHT_RANGE) && isFaceing(PMob->loc.p, PTarget->loc.p, 40))
    {
        return CanSeePoint(PTarget->loc.p);
    }

    if ((PMob->m_Behaviour & BEHAVIOUR_AGGRO_AMBUSH) && currentDistance < 3 && !hasSneak)
    {
        return true;
    }

    if ((detects & DETECT_HEARING) && currentDistance < PMob->getMobMod(MOBMOD_SOUND_RANGE) && !hasSneak)
    {
        return CanSeePoint(PTarget->loc.p);
    }

    // everything below require distance to be below 20
    if (currentDistance > 20)
    {
        return false;
    }

    if ((detects & DETECT_LOWHP) && PTarget->GetHPP() < 75)
    {
        return CanSeePoint(PTarget->loc.p);
    }

    if ((detects & DETECT_MAGIC) && PTarget->PAI->IsCurrentState<CMagicState>() &&
        static_cast<CMagicState*>(PTarget->PAI->GetCurrentState())->GetSpell()->hasMPCost())
    {
        return CanSeePoint(PTarget->loc.p);
    }

    if ((detects & DETECT_WEAPONSKILL) && PTarget->PAI->IsCurrentState<CWeaponSkillState>())
    {
        return CanSeePoint(PTarget->loc.p);
    }

    if ((detects & DETECT_JOBABILITY) && PTarget->PAI->IsCurrentState<CAbilityState>())
    {
        return CanSeePoint(PTarget->loc.p);
    }

    return false;
}
Esempio n. 4
0
//-------------------------------------------------------------------------------------------
//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;
		}
	}
}