void CAutoPowerCaptor::ChargeObject(float rTime) { Math::Vector sPos = m_object->GetPosition(); for (CObject* obj : CObjectManager::GetInstancePointer()->GetAllObjects()) { Math::Vector oPos = obj->GetPosition(); float dist = Math::Distance(oPos, sPos); if ( dist > 20.0f ) continue; if (! IsObjectBeingTransported(obj) && obj->Implements(ObjectInterfaceType::PowerContainer) ) { CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(obj); if (powerContainer->IsRechargeable()) { float energy = powerContainer->GetEnergy(); energy += rTime/2.0f; if ( energy > 1.0f ) energy = 1.0f; powerContainer->SetEnergy(energy); } } if (obj->Implements(ObjectInterfaceType::Powered)) { CObject* power = dynamic_cast<CPoweredObject*>(obj)->GetPower(); if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) ) { CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(power); if (powerContainer->IsRechargeable()) { float energy = powerContainer->GetEnergy(); energy += rTime/2.0f; if ( energy > 1.0f ) energy = 1.0f; powerContainer->SetEnergy(energy); } } } if (obj->Implements(ObjectInterfaceType::Carrier)) { CObject* power = dynamic_cast<CCarrierObject*>(obj)->GetCargo(); if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) ) { CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(power); if (powerContainer->IsRechargeable()) { float energy = powerContainer->GetEnergy(); energy += rTime/2.0f; if ( energy > 1.0f ) energy = 1.0f; powerContainer->SetEnergy(energy); } } } } }
bool CTaskFire::EventProcess(const Event &event) { CPhysics* physics; Math::Matrix* mat; Math::Vector pos, speed, dir, vib; ObjectType type; Math::Point dim; float energy, fire; int i, channel; if ( m_engine->GetPause() ) return true; if ( event.type != EVENT_FRAME ) return true; if ( m_bError ) return false; m_time += event.rTime; m_lastSound -= event.rTime; m_progress += event.rTime*m_speed; CPowerContainerObject* power = nullptr; if (m_object->GetPower() != nullptr && m_object->GetPower()->Implements(ObjectInterfaceType::PowerContainer)) { power = dynamic_cast<CPowerContainerObject*>(m_object->GetPower()); energy = power->GetEnergy(); if ( m_bOrganic ) fire = ENERGY_FIREi; else if ( m_bRay ) fire = ENERGY_FIREr; else fire = ENERGY_FIRE; energy -= event.rTime*fire; power->SetEnergy(energy); } if ( m_lastParticle+0.05f <= m_time ) { m_lastParticle = m_time; if ( m_bOrganic ) { mat = m_object->GetWorldMatrix(1); // insect-cannon for ( i=0 ; i<6 ; i++ ) { pos = Math::Vector(0.0f, 2.5f, 0.0f); pos = Math::Transform(*mat, pos); speed = Math::Vector(200.0f, 0.0f, 0.0f); physics = m_object->GetPhysics(); if ( physics != nullptr ) { speed += physics->GetLinMotion(MO_REASPEED); } speed.x += (Math::Rand()-0.5f)*10.0f; speed.y += (Math::Rand()-0.5f)*20.0f; speed.z += (Math::Rand()-0.5f)*30.0f; speed = Math::Transform(*mat, speed); speed -= pos; dim.x = Math::Rand()*0.5f+0.5f; dim.y = dim.x; channel = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGUN4, 0.8f, 0.0f, 0.0f); m_particle->SetObjectFather(channel, m_object); } } else if ( m_bRay ) { mat = m_object->GetWorldMatrix(2); // cannon for ( i=0 ; i<4 ; i++ ) { pos = Math::Vector(4.0f, 0.0f, 0.0f); pos.y += (rand()%3-1)*1.5f; pos.z += (rand()%3-1)*1.5f; pos = Math::Transform(*mat, pos); speed = Math::Vector(200.0f, 0.0f, 0.0f); speed.x += (Math::Rand()-0.5f)*6.0f; speed.y += (Math::Rand()-0.5f)*12.0f; speed.z += (Math::Rand()-0.5f)*12.0f; speed = Math::Transform(*mat, speed); speed -= pos; dim.x = 1.0f; dim.y = dim.x; channel = m_particle->CreateTrack(pos, speed, dim, Gfx::PARTITRACK11, 2.0f, 200.0f, 0.5f, 1.0f); m_particle->SetObjectFather(channel, m_object); speed = Math::Vector(5.0f, 0.0f, 0.0f); speed.x += (Math::Rand()-0.5f)*1.0f; speed.y += (Math::Rand()-0.5f)*2.0f; speed.z += (Math::Rand()-0.5f)*2.0f; speed = Math::Transform(*mat, speed); speed -= pos; speed.y += 5.0f; dim.x = 2.0f; dim.y = dim.x; m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE2, 2.0f, 0.0f, 0.5f); } } else { type = m_object->GetType(); if ( type == OBJECT_MOBILErc ) { mat = m_object->GetWorldMatrix(2); // cannon } else { mat = m_object->GetWorldMatrix(1); // cannon } for ( i=0 ; i<3 ; i++ ) { if ( type == OBJECT_MOBILErc ) { pos = Math::Vector(0.0f, 0.0f, 0.0f); } else { pos = Math::Vector(3.0f, 1.0f, 0.0f); } pos.y += (Math::Rand()-0.5f)*1.0f; pos.z += (Math::Rand()-0.5f)*1.0f; pos = Math::Transform(*mat, pos); speed = Math::Vector(200.0f, 0.0f, 0.0f); physics = m_object->GetPhysics(); if ( physics != nullptr ) { speed += physics->GetLinMotion(MO_REASPEED); } speed.x += (Math::Rand()-0.5f)*3.0f; speed.y += (Math::Rand()-0.5f)*6.0f; speed.z += (Math::Rand()-0.5f)*6.0f; speed = Math::Transform(*mat, speed); speed -= pos; dim.x = Math::Rand()*0.7f+0.7f; dim.y = dim.x; channel = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGUN1, 0.8f, 0.0f, 0.0f); m_particle->SetObjectFather(channel, m_object); } if ( type != OBJECT_MOBILErc && m_progress > 0.3f ) { pos = Math::Vector(-1.0f, 1.0f, 0.0f); pos.y += (Math::Rand()-0.5f)*0.4f; pos.z += (Math::Rand()-0.5f)*0.4f; pos = Math::Transform(*mat, pos); speed = Math::Vector(-4.0f, 0.0f, 0.0f); speed.x += (Math::Rand()-0.5f)*2.0f; speed.y += (Math::Rand()-0.2f)*4.0f; speed.z += (Math::Rand()-0.5f)*4.0f; speed = Math::Transform(*mat, speed); speed -= pos; dim.x = Math::Rand()*1.2f+1.2f; dim.y = dim.x; m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, 2.0f, 0.0f, 0.0f); //? m_particle->CreateParticle(pos, speed, dim, PARTISMOKE2, 4.0f, 0.0f, 0.0f); } } dir = Math::Vector(0.0f, 0.0f, 0.0f); if ( m_progress < 0.1f ) { dir.z = (Math::PI*0.04f)*(m_progress*10.0f); } else if ( m_progress < 0.9f ) { dir.z = (Math::PI*0.04f); } else { dir.z = (Math::PI*0.04f)*(1.0f-(m_progress-0.9f)*10.0f); } m_object->SetTilt(dir); vib.x = (Math::Rand()-0.5f)*0.01f; vib.y = (Math::Rand()-0.5f)*0.02f; vib.z = (Math::Rand()-0.5f)*0.02f; m_object->SetCirVibration(vib); vib.x = (Math::Rand()-0.5f)*0.20f; vib.y = (Math::Rand()-0.5f)*0.05f; vib.z = (Math::Rand()-0.5f)*0.20f; m_object->SetLinVibration(vib); } if ( m_bRay && m_lastSound <= 0.0f ) { m_lastSound = Math::Rand()*0.4f+0.4f; m_sound->Play(SOUND_FIREp, m_object->GetPosition()); } return true; }
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 CTaskRecover::EventProcess(const Event &event) { Math::Vector pos, speed; Math::Point dim; float a, g, cirSpeed, angle, energy, dist, linSpeed; if ( m_engine->GetPause() ) return true; if ( event.type != EVENT_FRAME ) return true; if ( m_bError ) return false; if ( m_phase == TRP_TURN ) // preliminary rotation? { a = m_object->GetRotationY(); g = m_angle; cirSpeed = Math::Direction(a, g)*1.0f; if ( cirSpeed > 1.0f ) cirSpeed = 1.0f; if ( cirSpeed < -1.0f ) cirSpeed = -1.0f; m_physics->SetMotorSpeedZ(cirSpeed); // turns left / right return true; } m_progress += event.rTime*m_speed; // others advance m_time += event.rTime; if ( m_phase == TRP_DOWN ) { angle = Math::PropAngle(126, -10, m_progress); m_object->SetPartRotationZ(2, angle); m_object->SetPartRotationZ(4, angle); angle = Math::PropAngle(-144, 0, m_progress); m_object->SetPartRotationZ(3, angle); m_object->SetPartRotationZ(5, angle); } if ( m_phase == TRP_MOVE ) // preliminary forward/backward? { dist = Math::Distance(m_object->GetPosition(), m_ruin->GetPosition()); linSpeed = 0.0f; if ( dist > RECOVER_DIST ) linSpeed = 1.0f; if ( dist < RECOVER_DIST ) linSpeed = -1.0f; m_physics->SetMotorSpeedX(linSpeed); // forward/backward return true; } if ( m_phase == TRP_OPER ) { assert(m_object->Implements(ObjectInterfaceType::Powered)); CObject* powerObj = dynamic_cast<CPoweredObject*>(m_object)->GetPower(); if (powerObj != nullptr && powerObj->Implements(ObjectInterfaceType::PowerContainer)) { CPowerContainerObject* power = dynamic_cast<CPowerContainerObject*>(powerObj); energy = power->GetEnergy(); energy -= event.rTime * ENERGY_RECOVER * m_speed; power->SetEnergy(energy); } speed.x = (Math::Rand()-0.5f)*0.1f*m_progress; speed.y = (Math::Rand()-0.5f)*0.1f*m_progress; speed.z = (Math::Rand()-0.5f)*0.1f*m_progress; m_ruin->SetCirVibration(speed); if ( m_progress >= 0.75f ) { m_ruin->SetScale(1.0f-(m_progress-0.75f)/0.25f); } if ( m_progress > 0.5f && m_progress < 0.8f ) { m_metal->SetScale((m_progress-0.5f)/0.3f); } if ( m_lastParticle+m_engine->ParticleAdapt(0.02f) <= m_time ) { m_lastParticle = m_time; pos = m_recoverPos; pos.x += (Math::Rand()-0.5f)*8.0f*(1.0f-m_progress); pos.z += (Math::Rand()-0.5f)*8.0f*(1.0f-m_progress); pos.y -= 4.0f; speed.x = (Math::Rand()-0.5f)*0.0f; speed.z = (Math::Rand()-0.5f)*0.0f; speed.y = Math::Rand()*15.0f; dim.x = Math::Rand()*2.0f+1.5f; dim.y = dim.x; m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIRECOVER, 1.0f, 0.0f, 0.0f); } } if ( m_phase == TRP_UP ) { angle = Math::PropAngle(-10, 126, m_progress); m_object->SetPartRotationZ(2, angle); m_object->SetPartRotationZ(4, angle); angle = Math::PropAngle(0, -144, m_progress); m_object->SetPartRotationZ(3, angle); m_object->SetPartRotationZ(5, angle); if ( m_lastParticle+m_engine->ParticleAdapt(0.02f) <= m_time ) { m_lastParticle = m_time; pos = m_recoverPos; pos.y -= 4.0f; speed.x = (Math::Rand()-0.5f)*0.0f; speed.z = (Math::Rand()-0.5f)*0.0f; speed.y = Math::Rand()*15.0f; dim.x = Math::Rand()*2.0f+1.5f; dim.y = dim.x; m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIRECOVER, 1.0f, 0.0f, 0.0f); } } return true; }
bool CAutoPowerStation::EventProcess(const Event &event) { 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_bLastVirus ) { m_bLastVirus = true; m_energyVirus = dynamic_cast<CPowerContainerObject*>(m_object)->GetEnergyLevel(); } if ( m_timeVirus <= 0.0f ) { m_timeVirus = 0.1f+Math::Rand()*0.3f; dynamic_cast<CPowerContainerObject*>(m_object)->SetEnergyLevel(Math::Rand()); } return true; } else { if ( m_bLastVirus ) { m_bLastVirus = false; dynamic_cast<CPowerContainerObject*>(m_object)->SetEnergyLevel(m_energyVirus); } } UpdateInterface(event.rTime); float big = dynamic_cast<CPowerContainerObject*>(m_object)->GetEnergy(); Gfx::TerrainRes res = m_terrain->GetResource(m_object->GetPosition()); if ( res == Gfx::TR_POWER ) { big += event.rTime*0.01f; // recharges the large battery } float used = big; float freq = 1.0f; if (big > 0.0f) { CObject* vehicle = SearchVehicle(); if (vehicle != nullptr) { if (vehicle->Implements(ObjectInterfaceType::Powered)) { CObject* power = dynamic_cast<CPoweredObject*>(vehicle)->GetPower(); if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) ) { CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(power); if (powerContainer->IsRechargeable()) { float energy = powerContainer->GetEnergy(); float add = event.rTime*0.2f; if ( add > big*4.0f ) add = big*4.0f; if ( add > 1.0f-energy ) add = 1.0f-energy; energy += add; // Charging the battery powerContainer->SetEnergy(energy); if ( energy < freq ) freq = energy; big -= add/4.0f; // discharge the large battery } } } if (vehicle->Implements(ObjectInterfaceType::Carrier)) { CObject* power = dynamic_cast<CCarrierObject*>(vehicle)->GetCargo(); if ( power != nullptr && power->Implements(ObjectInterfaceType::PowerContainer) ) { CPowerContainerObject* powerContainer = dynamic_cast<CPowerContainerObject*>(power); if (powerContainer->IsRechargeable()) { float energy = powerContainer->GetEnergy(); float add = event.rTime*0.2f; if ( add > big*4.0f ) add = big*4.0f; if ( add > 1.0f-energy ) add = 1.0f-energy; energy += add; // Charging the battery powerContainer->SetEnergy(energy); if ( energy < freq ) freq = energy; big -= add/4.0f; // discharge the large battery } } } } } used -= big; // energy used if ( freq < 1.0f ) // charging in progress? { freq = 1.0f+3.0f*freq; if ( m_soundChannel == -1 ) { m_soundChannel = m_sound->Play(SOUND_STATION, m_object->GetPosition(), 0.3f, freq, true); } m_sound->Frequency(m_soundChannel, freq); } else { if ( m_soundChannel != -1 ) { m_sound->Stop(m_soundChannel); m_soundChannel = -1; } } if ( used != 0.0f && m_lastParticle+m_engine->ParticleAdapt(0.05f) <= m_time ) { m_lastParticle = m_time; Math::Vector pos, ppos, speed; Math::Point dim; Math::Matrix* mat = m_object->GetWorldMatrix(0); pos = Math::Vector(-15.0f, 7.0f, 0.0f); // battery position pos = Math::Transform(*mat, pos); speed.x = (Math::Rand()-0.5f)*20.0f; speed.y = (Math::Rand()-0.5f)*20.0f; speed.z = (Math::Rand()-0.5f)*20.0f; ppos.x = pos.x; ppos.y = pos.y+(Math::Rand()-0.5f)*4.0f; ppos.z = pos.z; dim.x = 1.5f; dim.y = 1.5f; m_particle->CreateParticle(ppos, speed, dim, Gfx::PARTIBLITZ, 1.0f, 0.0f, 0.0f); ppos = pos; ppos.y += 1.0f; ppos.x += (Math::Rand()-0.5f)*3.0f; ppos.z += (Math::Rand()-0.5f)*3.0f; speed.x = 0.0f; speed.z = 0.0f; speed.y = 2.5f+Math::Rand()*5.0f; dim.x = Math::Rand()*1.0f+0.6f; dim.y = dim.x; m_particle->CreateParticle(ppos, speed, dim, Gfx::PARTIVAPOR, 3.0f); } if ( big < 0.0f ) big = 0.0f; if ( big > 1.0f ) big = 1.0f; dynamic_cast<CPowerContainerObject*>(m_object)->SetEnergy(big); // Shift the large battery return true; }