Пример #1
0
int CEntityMng::ActivatePath( int characterID , char *start , char *dest , int playType )
{
	activator_t *activator;
	worldentity_t *startEnt , *destEnt , *nextEnt;
	vec3_t diff;
	float  dist;

	if( playType & GTH_ENTITY_PLAY_FORWARD )
	{
		startEnt = SearchTarget( start , GTH_WORLD_ENTITY_TYPE_PATH );
		if( !startEnt )  return false;
		destEnt = SearchTarget( dest , GTH_WORLD_ENTITY_TYPE_PATH );
		nextEnt = startEnt->targetEntity;
	}
	else
	{
		startEnt = SearchTarget( dest , GTH_WORLD_ENTITY_TYPE_PATH );
		if( !startEnt )  return false;		
		destEnt = SearchTarget( start , GTH_WORLD_ENTITY_TYPE_PATH );
		nextEnt = startEnt->prevEntity;
	}
	
	if( nextEnt )
	{
		VectorSubtract( diff , nextEnt->origin , startEnt->origin );
		dist = (float) sqrt( VectorDotProduct( diff , diff ) );
	}
	else
		dist = 0.0f;

	activator = startEnt->activator;

	activator->startEntity = startEnt;
	activator->destEntity = destEnt;
	activator->currEntity = startEnt;

	activator->playType = playType;
	activator->startTime = m_timer->GetAppTime();
	activator->currChainTime = activator->startTime;
	activator->moveSpeed = GTH_ENTITY_PLAYER_MOVE_SPEED * startEnt->speed;
	activator->currChainCompleteTime = dist / activator->moveSpeed;
	activator->characterID = characterID;

	if( m_currPathEntity )
		Deactivate( m_currPathEntity );

	activator->playing = true;
	startEnt->inuse = true;
	m_currPathEntity = startEnt;

	return true;
}
Пример #2
0
void CEntityMng::Initialize( float visibleDist )
{
	worldentity_t  *entity;
	int i;

	m_frameFlag = 0;
	m_visibleDist = visibleDist;
	m_MDLMng->ClearWorldUseFlag();
	m_linked = NULL;
	m_currCameraPathEntity = NULL;
	m_currPathEntity = NULL;
	m_numActivator = 0;

	entity = &m_entities[0];
	for( i = 0 ; i < m_numEntities ; i++ , entity++ )
	{
		entity->linkedCluster = m_world->FindCluster( entity->origin );
		if( entity->linkedCluster < 0 )
		{
			entity->inuse = false;
			continue;
		}

		entity->targetEntity = SearchTarget( entity->target );
		if( entity->targetEntity )
			entity->targetEntity->prevEntity = entity;

		entity->inuse = false;
		switch( entity->classType )
		{
		case GTH_WORLD_ENTITY_TYPE_PLAYER_POS :
			        break;
		
		case GTH_WORLD_ENTITY_TYPE_MODEL :
			        entity->idxMDLEntity = m_MDLMng->AddWorldEntity( entity->itemName , entity->origin 
						                                           , entity->angles );
					if( entity->idxMDLEntity < 0 )	break;
					if( !m_MDLMng->GetMDLWorldClassBoundBox( entity->idxMDLEntity , entity->mins , entity->maxs ) )
					{
						VectorClear( entity->mins );
						VectorClear( entity->maxs );
					}
					entity->radius = CalculateRadius( entity->mins , entity->maxs );
					AddLink( entity );
					entity->inuse = true;
					break;

		case GTH_WORLD_ENTITY_TYPE_TELEPORT :
			    if( !entity->target ) break;
				entity->idxMDLEntity = m_MDLMng->AddWorldEntity( entity->itemName , entity->origin 
						                                           , entity->angles );
				if( entity->idxMDLEntity < 0 )	break;
				if( !m_MDLMng->GetMDLWorldClassBoundBox( entity->idxMDLEntity , entity->mins , entity->maxs ) )
				{
					VectorClear( entity->mins );
					VectorClear( entity->maxs );
				}
			    AddLink( entity );
				entity->inuse = true;
			        break;

		case GTH_WORLD_ENTITY_TYPE_ACTIVATOR :
			    if( !entity->targetEntity ) break;
				AddLink( entity );
				entity->inuse = true;
			        break;

		case GTH_WORLD_ENTITY_TYPE_DEACTIVATOR :
			    if( !entity->targetEntity ) break;
				AddLink( entity );
				entity->inuse = true;
			        break;

		case GTH_WORLD_ENTITY_TYPE_DOOR :
				AddLink( entity );
				entity->activator = GetNewActivator();
				entity->inuse = true;
			        break;

		case GTH_WORLD_ENTITY_TYPE_PATH :
				AddLink( entity );
				entity->activator = GetNewActivator();
				entity->inuse = false;
			        break;

		case GTH_WORLD_ENTITY_TYPE_CAMERA_PATH :
				AddLink( entity );
				entity->activator = GetNewActivator();
				entity->inuse = false;
			        break;

		case GTH_WORLD_ENTITY_TYPE_SOUND :
				AddLink( entity );
				entity->activator = GetNewActivator();
				entity->inuse = true;
			        break;

		default:
			        break;
		}
	}
}
Пример #3
0
/**
 * \brief Alt quantum burst projectile think functiom.
 *
 * Alt quantum burst projectile think function.
 *
 * @param ent the projectile
 */
static void WP_QuantumAltThink(gentity_t *ent)
{
	vec3_t start, newdir, targetdir, lup={0,0,1}, lright, search; 
	float dot, dot2;

	ent->health--;
	if (ent->health<=0)
	{
		G_FreeEntity(ent);
		return;
	}

	if (ent->target_ent)
	{	/* Already have a target, start homing. */
		if (ent->health <= 0 || !ent->inuse)
		{	/* No longer target this */
			ent->target_ent = NULL;
			ent->nextthink = level.time + 1000;
			ent->health -= 5;
			return;
		}
		VectorSubtract(ent->target_ent->r.currentOrigin, ent->r.currentOrigin, targetdir);
		VectorNormalize(targetdir);

		/* Now the rocket can't do a 180 in space, so we'll limit the turn to about 45 degrees. */
		dot = DotProduct(targetdir, ent->movedir);
		/* a dot of 1.0 means right-on-target. */
		if (dot < 0.0)
		{	/* Go in the direction opposite, start a 180. */
			CrossProduct(ent->movedir, lup, lright);
			dot2 = DotProduct(targetdir, lright);
			if (dot2 > 0)
			{	/* Turn 45 degrees right. */
				VectorAdd(ent->movedir, lright, newdir);
			}
			else
			{	/* Turn 45 degrees left. */
				VectorSubtract(ent->movedir, lright, newdir);
			}
			/* Yeah we've adjusted horizontally, but let's split the difference vertically, so we kinda try to move towards it. */
			newdir[2] = (targetdir[2] + ent->movedir[2]) * 0.5;
			VectorNormalize(newdir);
		}
		else if (dot < 0.7)
		{	/* Need about one correcting turn.  Generate by meeting the target direction "halfway". */
			/* Note, this is less than a 45 degree turn, but it is sufficient.  We do this because the rocket may have to go UP. */
			VectorAdd(ent->movedir, targetdir, newdir);
			VectorNormalize(newdir);
		}
		else
		{	/* else adjust to right on target. */
			VectorCopy(targetdir, newdir);
		}

		VectorScale(newdir, rpg_altPhotonSpeed.integer, ent->s.pos.trDelta);
		VectorCopy(newdir, ent->movedir);
		SnapVector(ent->s.pos.trDelta);			/* save net bandwidth */
		VectorCopy(ent->r.currentOrigin, ent->s.pos.trBase);
		SnapVector(ent->s.pos.trBase);
		ent->s.pos.trTime = level.time;

		/* Home at a reduced frequency. */
		ent->nextthink = level.time + QUANTUM_ALT_THINK_TIME;	/* Nothing at all spectacular happened, continue. */
	}
	else
	{	/* Search in front of the missile for targets. */
		VectorCopy(ent->r.currentOrigin, start);
		CrossProduct(ent->movedir, lup, lright);

		/* Search straight ahead. */
		VectorMA(start, QUANTUM_ALT_SEARCH_DIST, ent->movedir, search);

		/* Add some small randomness to the search Z height, to give a bit of variation to where we are searching. */
		search[2] += flrandom(-QUANTUM_ALT_SEARCH_DIST*0.075, QUANTUM_ALT_SEARCH_DIST*0.075);

		if (SearchTarget(ent, start, search))
			return;

		/* Search to the right. */
		VectorMA(search, QUANTUM_ALT_SEARCH_DIST*0.1, lright, search);
		if (SearchTarget(ent, start, search))
			return;
		
		/* Search to the left. */
		VectorMA(search, -QUANTUM_ALT_SEARCH_DIST*0.2, lright, search);
		if (SearchTarget(ent, start, search))
			return;

		/* Search at a higher rate than correction. */
		ent->nextthink = level.time + QUANTUM_ALT_SEARCH_TIME;	/* Nothing at all spectacular happened, continue. */

	}
	return;
}
Пример #4
0
bool CAutoTower::EventProcess(const Event &event)
{
    CObject*    target;
    Math::Vector    pos;
    float       angle, quick;

    CAuto::EventProcess(event);

    if ( m_engine->GetPause() )  return true;
    if ( event.type != EVENT_FRAME )  return true;

    m_timeVirus -= event.rTime;

    if ( m_object->GetVirusMode() )  // contaminated by a virus?
    {
        if ( m_timeVirus <= 0.0f )
        {
            m_timeVirus = 0.1f+Math::Rand()*0.3f;

            angle = m_object->GetPartRotationY(1);
            angle += Math::Rand()*0.5f;
            m_object->SetPartRotationY(1, angle);

            m_object->SetPartRotationZ(2, Math::Rand()*0.5f);
        }
        return true;
    }

    CPowerContainerObject* power = nullptr;
    float energy = 0.0f;
    if ( m_object->GetPower() != nullptr && m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer) )
    {
        power = dynamic_cast<CPowerContainerObject*>(m_object->GetPower());
        energy = power->GetEnergy();
    }

    UpdateInterface(event.rTime);

    if ( m_phase == ATP_WAIT )  return true;

    m_progress += event.rTime*m_speed;

    if ( m_phase == ATP_ZERO )
    {
        FireStopUpdate(m_progress, true);  // blinks
        if ( m_progress < 1.0f )
        {
            if ( energy >= ENERGY_FIRE )
            {
                m_phase    = ATP_SEARCH;
                m_progress = 0.0f;
                m_speed    = 1.0f/3.0f;
            }
        }
        else
        {
            m_phase    = ATP_ZERO;
            m_progress = 0.0f;
            m_speed    = 1.0f/1.0f;
        }
    }

    if ( m_phase == ATP_SEARCH )
    {
        FireStopUpdate(m_progress, false);  // extinguished
        if ( m_progress < 1.0f )
        {
            quick = 1.0f;
//?         if ( g_researchDone & RESEARCH_QUICK )  quick = 3.0f;

            angle = m_object->GetPartRotationY(1);
            angle -= event.rTime*quick*2.0f;
            m_object->SetPartRotationY(1, angle);

            angle = m_object->GetPartRotationZ(2);
            angle += event.rTime*quick*0.5f;
            if ( angle > 0.0f )  angle = 0.0f;
            m_object->SetPartRotationZ(2, angle);
        }
        else
        {
            target = SearchTarget(m_targetPos);
            if ( energy < ENERGY_FIRE )
            {
                m_main->DisplayError(ERR_TOWER_ENERGY, m_object);
            }
            if ( target == nullptr || energy < ENERGY_FIRE )
            {
                m_phase    = ATP_ZERO;
                m_progress = 0.0f;
                m_speed    = 1.0f/1.0f;
            }
            else
            {
                pos = m_object->GetPosition();
                pos.y += 24.5f;
                m_angleYfinal = Math::RotateAngle(m_targetPos.x-pos.x, pos.z-m_targetPos.z);  // CW !
                m_angleYfinal += Math::PI*2.0f;
                m_angleYfinal -= m_object->GetRotationY();
                m_angleYactual = Math::NormAngle(m_object->GetPartRotationY(1));

                m_angleZfinal = -Math::PI/2.0f;
                m_angleZfinal -= Math::RotateAngle(Math::DistanceProjected(m_targetPos, pos), pos.y-m_targetPos.y);  // CW !
                m_angleZactual = m_object->GetPartRotationZ(2);

                m_phase    = ATP_TURN;
                m_progress = 0.0f;
                m_speed    = 1.0f/1.0f;
//?             if ( g_researchDone & RESEARCH_QUICK )  m_speed = 1.0f/0.2f;
            }
        }
    }

    if ( m_phase == ATP_TURN )
    {
        if ( m_progress < 1.0f )
        {
            angle = m_angleYactual+(m_angleYfinal-m_angleYactual)*m_progress;
            m_object->SetPartRotationY(1, angle);

            angle = m_angleZactual+(m_angleZfinal-m_angleZactual)*m_progress;
            m_object->SetPartRotationZ(2, angle);
        }
        else
        {
            m_object->SetPartRotationY(1, m_angleYfinal);
            m_object->SetPartRotationZ(2, m_angleZfinal);

            if ( power != nullptr )
            {
                energy = power->GetEnergy();
                energy -= ENERGY_FIRE;
                power->SetEnergy(energy);
            }

            m_sound->Play(SOUND_GGG, m_object->GetPosition());

            m_phase    = ATP_FIRE;
            m_progress = 0.0f;
            m_speed    = 1.0f/1.5f;
        }
    }

    if ( m_phase == ATP_FIRE )
    {
        if ( m_progress == 0.0f )
        {
            pos = m_object->GetPosition();
            pos.y += 24.5f;
            m_particle->CreateRay(pos, m_targetPos, Gfx::PARTIRAY1,
                                  Math::Point(5.0f, 5.0f), 1.5f);
        }
        if ( m_progress >= 1.0f )
        {
            m_phase    = ATP_ZERO;
            m_progress = 0.0f;
            m_speed    = 1.0f/1.0f;
        }
    }

    return true;
}
Пример #5
0
bool CAutoMush::EventProcess(const Event &event)
{
    Math::Vector    pos, speed, dir;
    Math::Point     dim;
    float       factor, zoom, size, angle;
    int         i, channel;

    CAuto::EventProcess(event);

    if ( m_engine->GetPause() )  return true;
    if ( event.type != EVENT_FRAME )  return true;

    m_progress += event.rTime*m_speed;

    factor = 0.0f;
    size = 1.0f;

    if ( m_phase == AMP_WAIT )
    {
        if ( m_progress >= 1.0f )
        {
            if ( !SearchTarget() )
            {
                m_phase    = AMP_WAIT;
                m_progress = 0.0f;
                m_speed    = 1.0f/(2.0f+Math::Rand()*2.0f);
            }
            else
            {
                m_phase    = AMP_SNIF;
                m_progress = 0.0f;
                m_speed    = 1.0f/1.5f;
            }
        }
    }

    if ( m_phase == AMP_SNIF )
    {
        if ( m_progress < 1.0f )
        {
            factor = m_progress;
        }
        else
        {
            m_phase    = AMP_ZOOM;
            m_progress = 0.0f;
            m_speed    = 1.0f/1.0f;
        }
    }

    if ( m_phase == AMP_ZOOM )
    {
        if ( m_progress < 1.0f )
        {
            factor = 1.0f;
            size = 1.0f+m_progress*0.3f;
        }
        else
        {
            m_sound->Play(SOUND_MUSHROOM, m_object->GetPosition());

            m_phase    = AMP_FIRE;
            m_progress = 0.0f;
            m_speed    = 1.0f/1.0f;
        }
    }

    if ( m_phase == AMP_FIRE )
    {
        if ( m_progress < 1.0f )
        {
            factor = 1.0f-m_progress;
            size = 1.0f+(1.0f-m_progress)*0.3f;

            if ( m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time )
            {
                m_lastParticle = m_time;

                for ( i=0 ; i<10 ; i++ )
                {
                    pos = m_object->GetPosition();
                    pos.y += 5.0f;
                    speed.x = (Math::Rand()-0.5f)*200.0f;
                    speed.z = (Math::Rand()-0.5f)*200.0f;
                    speed.y = -(20.0f+Math::Rand()*20.0f);
                    dim.x = 1.0f;
                    dim.y = dim.x;
                    channel = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGUN2, 2.0f, 100.0f, 0.0f);
                    m_particle->SetObjectFather(channel, m_object);
                }
            }
        }
        else
        {
            m_phase    = AMP_SMOKE;
            m_progress = 0.0f;
            m_speed    = 1.0f/2.0f;
        }
    }

    if ( m_phase == AMP_SMOKE )
    {
        if ( m_progress < 1.0f )
        {
            if ( m_lastParticle+m_engine->ParticleAdapt(0.10f) <= m_time )
            {
                m_lastParticle = m_time;

                pos = m_object->GetPosition();
                pos.y += 5.0f;
                speed.x = (Math::Rand()-0.5f)*4.0f;
                speed.z = (Math::Rand()-0.5f)*4.0f;
                speed.y = -(0.5f+Math::Rand()*0.5f);
                dim.x = Math::Rand()*2.5f+2.0f;
                dim.y = dim.x;
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE3, 4.0f, 0.0f, 0.0f);
            }
        }
        else
        {
            m_phase    = AMP_WAIT;
            m_progress = 0.0f;
            m_speed    = 1.0f/(2.0f+Math::Rand()*2.0f);
        }
    }

    if ( factor != 0.0f || size != 1.0f )
    {
        dir.x = sinf(m_time*Math::PI*4.0f);
        dir.z = cosf(m_time*Math::PI*4.0f);

        angle = sinf(m_time*10.0f)*factor*0.04f;
        m_object->SetRotationX(angle*dir.z);
        m_object->SetRotationZ(angle*dir.x);

        zoom = 1.0f+sinf(m_time*8.0f)*factor*0.06f;
        m_object->SetScaleX(zoom*size);
        zoom = 1.0f+sinf(m_time*5.0f)*factor*0.06f;
        m_object->SetScaleY(zoom*size);
        zoom = 1.0f+sinf(m_time*7.0f)*factor*0.06f;
        m_object->SetScaleZ(zoom*size);
    }
    else
    {
        m_object->SetRotationX(0.0f);
        m_object->SetRotationZ(0.0f);
        m_object->SetScale(Math::Vector(1.0f, 1.0f, 1.0f));
    }

    return true;
}