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; }
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; } } }
/** * \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; }
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; }
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; }