Exemplo n.º 1
0
void CBirdsFlock::OnAIEvent(EAIStimulusType type, const Vec3& pos, float radius, float threat, EntityId sender)
{
	CFlock::OnAIEvent(type,pos,radius,threat,sender);
	if(type==AISTIM_SOUND)
	{
		if(threat > 0 && Distance::Point_PointSq(pos, m_bc.flockPos) < radius*radius * threat * threat)
			TakeOff();
	}
}
Exemplo n.º 2
0
void PlayScene::onPanelSecond(CCObject *target, TouchEventType e) {
  if (e == TOUCH_EVENT_BEGAN)
    return;
  SetResultPanelState(RESULT_PANEL_NORMAL);
  if(sub_win_) {
    TakeOff();
  } else {
    //失败
    CCScene *sc = GameScene::create();
    CCDirector::sharedDirector()->replaceScene(CCTransitionSlideInB::create(0.5, sc));
  }
}
Exemplo n.º 3
0
void CBirdsFlock::Update(CCamera *pCamera)
{

	UpdateLandingPoints();

	m_isPlayerNearOrigin = GetEntity()!=NULL && IsPlayerInProximity(GetEntity()->GetPos());

	CFlock::Update(pCamera);

	float dt = gEnv->pTimer->GetFrameTime();

	// set the ai object in the middle of the boids
	UpdateAvgBoidPos(dt);

	if(m_status == Bird::FLYING && !m_bc.noLanding &&
			(gEnv->pTimer->GetFrameStartTime()- m_flightStartTime).GetSeconds() > m_flightDuration)
	{
		if(GetEntity() && !m_isPlayerNearOrigin)
			Land();
	}

	if(m_status == Bird::LANDING)
	{
		float timePassed = (gEnv->pTimer->GetFrameStartTime()- m_flightStartTime).GetSeconds();

		if(timePassed < START_LANDING_TIME+0.5f)
		{
			int n = m_boids.size();
			int numBoidsLandingNow = int(float(n*timePassed)/START_LANDING_TIME);

			if(numBoidsLandingNow >n)
				numBoidsLandingNow = n;

			for(int i = 0; i<numBoidsLandingNow ; ++i)
			{
				CBoidBird *bird = static_cast<CBoidBird *>(m_boids[i]);

				if(bird && !bird->IsDead() && !bird->IsLanding())
					bird->Land();
			}
		}

	}


	if(m_status == Bird::LANDING || m_status == Bird::ON_GROUND)
	{
		if(IsPlayerInProximity(GetAvgBoidPos()))
			TakeOff();
	}

}
void CEyeBotCircle::ControlStep() {
   /* Get RAB message, if any */
   RLOG << "Message received: ";
   if(! m_pcRABSens->GetReadings().empty()) {
      m_psFBMsg = &(m_pcRABSens->GetReadings()[0]);
      LOG << *reinterpret_cast<const UInt64*>(m_psFBMsg->Data.ToCArray());
   }
   else {
      m_psFBMsg = NULL;
      LOG << "none";
   }
   LOG << std::endl;
   /* Execute state logic */
   switch(m_eState) {
      case STATE_START:
         TakeOff();
         break;
      case STATE_TAKE_OFF:
         TakeOff();
         break;
      case STATE_LEAVE_CIRCLE_CENTER:
         LeaveCircleCenter();
         break;
      case STATE_MOVE_ALONG_CIRCLE:
         MoveAlongCircle();
         break;
      case STATE_GO_TO_CENTER:
         GoToCenter();
         break;
      case STATE_LAND:
         Land();
         break;
      default:
         LOGERR << "[BUG] Unknown robot state: " << m_eState << std::endl;
   }
   /* Write debug information */
   RLOG << "Current state: " << m_eState << std::endl;
   RLOG << "Target pos: " << m_cTargetPos << std::endl;
}
Exemplo n.º 5
0
void CBirdsFlock::CreateBoids(SBoidsCreateContext &ctx)
{
	CFlock::CreateBoids(ctx);
	m_boidDefaultAnimName =  m_bc.GetAnimationName(Bird::ANIM_FLY);

	m_bc.bAutoTakeOff = false;

	for(uint32 i = 0; i < m_RequestedBoidsCount; i++)
	{
		CBoidObject *boid = new CBoidBird(m_bc);

		if(m_bc.bSpawnFromPoint)
		{
			CBoidBird *pBoid = (CBoidBird *)boid;
			float radius	= 0.5; // Spawn not far from origin
			float z				= /*gEnv->p3DEngine->GetTerrainElevation(m_origin.x,m_origin.y)*/ + 7.f + Boid::Frand()*2.f;	// z = terrain height + [5-9]
			pBoid->m_pos	= m_origin + Vec3(radius*Boid::Frand(),radius*Boid::Frand(), radius*Boid::Frand());
			z = .25f*Boid::Frand() + .25f;	// z-heading = 0.0 - 0.5
			pBoid->m_heading		= (Vec3(Boid::Frand(),Boid::Frand(),z)).GetNormalized();
			pBoid->m_scale			= m_bc.boidScale + Boid::Frand()*m_bc.boidRandomScale;
			boid->m_speed				= m_bc.MinSpeed + (Boid::Frand()+1)/2.0f*(m_bc.MaxSpeed - m_bc.MinSpeed);
			pBoid->m_dead				= 0;
			pBoid->m_currentAccel(0,0,0);
			pBoid->SetSpawnFromPt(true);
			pBoid->m_fNoCenterAttract = m_bc.factorAttractToOrigin;
			pBoid->m_fNoKeepHeight		= m_bc.factorKeepHeight;
			pBoid->SetAttracted(false);
		}
		else
		{
			float radius = m_bc.fSpawnRadius;
			boid->m_pos = m_origin + Vec3(radius*Boid::Frand(),radius*Boid::Frand(),Boid::Frand()*radius);
			boid->m_heading = (Vec3(Boid::Frand(),Boid::Frand(),0)).GetNormalized();
			boid->m_scale = m_bc.boidScale + Boid::Frand()*m_bc.boidRandomScale;
			boid->m_speed = m_bc.MinSpeed + (Boid::Frand()+1)/2.0f*(m_bc.MaxSpeed - m_bc.MinSpeed);
		}

		AddBoid(boid);
	}

	m_lastUpdatePosTimePassed = 1;
	m_avgBoidPos = GetPos();
	//
	m_hasLanded = false;
	TakeOff();

	m_terrainPoints = 0;
}
Exemplo n.º 6
0
void *StartDrone(void *vd) {
  Drone *d = vd;
  while (1) {
    switch(d->current_state) {
      case READY: TakeOff(d);
      case IN_FLIGHT: Fly(d);
      case ARRIVED: LandDrone(d);
      case DELIVERING: DeliverPackage(d);
      case DONE: return 0;
      case FAILED: return 0;
      case TAKING_OFF: ;
      case TAKEOFF_QUEUE: ;
      case FLIGHT_EVADING: ;
      case LANDING: ;
    }
  }
  return 0;
}
Exemplo n.º 7
0
    void UpdateAI(const uint32 diff)
    {
        if(WaitTimer)
        if(WaitTimer < diff)
        {
            if(Intro)
            {
                if(MovePhase >= 7)
                {
                    m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
                    m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
                    m_creature->GetMotionMaster()->MovePoint(8,IntroWay[7][0],IntroWay[7][1],IntroWay[7][2]);
                }
                else
                {
                    m_creature->GetMotionMaster()->MovePoint(MovePhase,IntroWay[MovePhase][0],IntroWay[MovePhase][1],IntroWay[MovePhase][2]);
                    ++MovePhase;
                }
            }

            if(Flying)
            {
                if(MovePhase >= 7)
                {
                    m_creature->RemoveUnitMovementFlag(MOVEMENTFLAG_LEVITATING);
                    m_creature->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
                    m_creature->GetMotionMaster()->MovePoint(8,IntroWay[7][0],IntroWay[7][1],IntroWay[7][2]);
                }
                else
                {
                    m_creature->GetMotionMaster()->MovePoint(MovePhase,IntroWay[MovePhase][0],IntroWay[MovePhase][1],IntroWay[MovePhase][2]);
                    ++MovePhase;
                }
            }

            WaitTimer = 0;
        }else WaitTimer -= diff;

        if(!UpdateVictim())
            return;

        if(Flying)
            return;

        //  Phase 1 "GROUND FIGHT"
        if(Phase == 1)
        {
            if(Movement)
            {
                DoStartMovement(m_creature->getVictim());
                Movement = false;
            }

            if (BellowingRoarTimer < diff)
            {
                DoCast(m_creature->getVictim(),SPELL_BELLOWING_ROAR);
                BellowingRoarTimer = 30000+rand()%10000 ; //Timer
            }else BellowingRoarTimer -= diff;

            if (SmolderingBreathTimer < diff)
            {
                DoCast(m_creature->getVictim(),SPELL_SMOLDERING_BREATH);
                SmolderingBreathTimer = 20000;//timer
            }else SmolderingBreathTimer -= diff;

            if (CharredEarthTimer < diff)
            {
                if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
                    DoCast(target,SPELL_CHARRED_EARTH);
                CharredEarthTimer = 20000; //timer
            }else CharredEarthTimer -= diff;

            if (TailSweepTimer < diff)
            {
                if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
                    if (!m_creature->HasInArc( M_PI, target))
                        DoCast(target,SPELL_TAIL_SWEEP);
                TailSweepTimer = 15000;//timer
            }else TailSweepTimer -= diff;

            if (SearingCindersTimer < diff)
            {
                if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
                    DoCast(target,SPELL_SEARING_CINDERS);
                SearingCindersTimer = 10000; //timer
            }else SearingCindersTimer -= diff;

            uint32 Prozent;
            Prozent = (m_creature->GetHealth()*100) / m_creature->GetMaxHealth();

            if (Prozent < 75 && FlyCount == 0) // first take off 75%
                TakeOff();

            if (Prozent < 50 && FlyCount == 1) // secound take off 50%
                TakeOff();

            if (Prozent < 25 && FlyCount == 2) // third take off 25%
                TakeOff();

            DoMeleeAttackIfReady();
        }

        //Phase 2 "FLYING FIGHT"
        if (Phase == 2)
        {
            if (!RainBones)
            {
                if (!Skeletons)
                {
                    for (uint8 i = 0; i <= 3; ++i)
                    {
                        DoCast(m_creature->getVictim(), SPELL_SUMMON_SKELETON);
                        Skeletons = true;
                    }
                }

                if (RainofBonesTimer < diff && !RainBones) // only once at the beginning of phase 2
                {
                    DoCast(m_creature->getVictim(),SPELL_RAIN_OF_BONES);
                    RainBones = true;
                    SmokingBlastTimer = 20000;
                }else RainofBonesTimer -= diff;

                if (DistractingAshTimer < diff)
                {
                    if (Unit* target = SelectUnit(SELECT_TARGET_RANDOM, 0))
                        DoCast(target,SPELL_DISTRACTING_ASH);
                    DistractingAshTimer = 2000;//timer wrong
                }else DistractingAshTimer -= diff;
            }

            if (RainBones)
            {
                if (SmokingBlastTimer < diff)
                 {
                    DoCast(m_creature->getVictim(),SPELL_SMOKING_BLAST);
                    SmokingBlastTimer = 1500 ; //timer wrong
                 }else SmokingBlastTimer -= diff;
            }

            if (FireballBarrageTimer < diff)
            {
                if (Unit* target = SelectUnit(SELECT_TARGET_FARTHEST, 0))
                    DoCast(target,SPELL_FIREBALL_BARRAGE);
                FireballBarrageTimer = 20000; //Timer
            }else FireballBarrageTimer -= diff;

            if (FlyTimer < diff) //landing
            {
                if(rand()%2 == 0)
                    DoYell(YELL_LAND_PHASE_1, LANG_UNIVERSAL, NULL);
                else
                    DoYell(YELL_LAND_PHASE_2, LANG_UNIVERSAL, NULL);

                (*m_creature).GetMotionMaster()->Clear(false);
                m_creature->GetMotionMaster()->MovePoint(3,IntroWay[3][0],IntroWay[3][1],IntroWay[3][2]);

                Flying = true;
            }else FlyTimer -= diff;
        }
    }
Exemplo n.º 8
0
		void UpdateAI(const uint32 uiDiff)
		{
			if (!UpdateVictim())
				return;

			if (m_uiBerserkTimer < uiDiff)
			{
				DoCast(me, SPELL_BERSERK);
				DoScriptText(SAY_BERSERK, me);
				m_uiBerserkTimer = 9999999;
			} else m_uiBerserkTimer -= uiDiff;

			if(Phase == PHASE_LAND || Phase == PHASE_ENRAGE)
			{
				if (m_uiBreathTimer <= uiDiff)
				{
					//DoScriptText(SAY_BREATH, me);
					DoCast(me, RAID_MODE(SPELL_FROST_BREATH_10_NORMAL,SPELL_FROST_BREATH_25_NORMAL));
					m_uiBreathTimer = 15000;
				} else m_uiBreathTimer -= uiDiff;

				if (m_uiCleaveTimer <= uiDiff)
				{
					DoCast(me, SPELL_CLEAVE);
					m_uiCleaveTimer = 10000;
				} else m_uiCleaveTimer -= uiDiff;

				if (m_uiTailSmashTimer <= uiDiff)
				{
					DoCast(me, SPELL_TAIL_SMASH);
					m_uiTailSmashTimer = 8000;
				} else m_uiTailSmashTimer -= uiDiff;

				if (m_uiBlisteringColdTimer <= uiDiff)
				{
					BlisteringCold();
					m_uiBlisteringColdTimer = 35000;
				} else m_uiBlisteringColdTimer -= uiDiff;

				if (m_uiUnchainedMagicTimer <= uiDiff)
				{
					UnchainedMagic();
					m_uiUnchainedMagicTimer = 10000;
				} else m_uiUnchainedMagicTimer -= uiDiff;
			}

			if(Phase == PHASE_LAND)
			{
				if ((m_uiPhaseTimer <= uiDiff) || ((me->GetHealth()*100) / me->GetMaxHealth() == 85))
				{
					Phase = PHASE_FLY;
					m_uiPhaseTimer = 60000;
					TakeOff();
					m_uiMarkTimer = 15000;
				} else m_uiPhaseTimer -= uiDiff;
			}

			if(Phase == PHASE_FLY)
			{
				if (m_uiPhaseTimer <= uiDiff)
				{
					Phase = PHASE_LAND;
					m_uiPhaseTimer = 60000;
					LandDown();
				} else m_uiPhaseTimer -= uiDiff;

				if (m_uiMarkTimer < uiDiff)
				{
					MarkPlayer();
					m_uiMarkTimer = 9999999;
					m_uiIceBoltTriggerTimer = 5000;
				} else m_uiMarkTimer -= uiDiff;

				if (m_uiIceBoltTriggerTimer < uiDiff)
				{
					CastIceBlockTrigger();
					m_uiIceBoltTriggerTimer = 9999999;
					m_uiIceBombTimer = 10000;
				} else m_uiIceBoltTriggerTimer -= uiDiff;

				if (m_uiIceBombTimer <= uiDiff)
				{
					FrostBombTrigger();
					m_uiIceBombTimer = 10000;
				} else m_uiIceBombTimer -= uiDiff;
			}

			if(Phase == PHASE_ENRAGE)
			{
				if (m_uiMysticBuffetTimer <= uiDiff)
				{
					WorkAroundForLoSmkII();
					m_uiMysticBuffetTimer = 10000;
				} else m_uiMysticBuffetTimer -= uiDiff;

				if (m_uiMarkTimer < uiDiff)
				{
					MarkPlayer();
					m_uiMarkTimer = 9999999;
					m_uiIceBoltTriggerTimer = 5000;
				} else m_uiMarkTimer -= uiDiff;

				if (m_uiIceBoltTriggerTimer < uiDiff)
				{
					CastIceBlockTrigger();
					m_uiIceBoltTriggerTimer = 35000;
					m_uiMarkTimer = 30000;
				} else m_uiIceBoltTriggerTimer -= uiDiff;
			}

			if(Phase == PHASE_LAND || Phase == PHASE_FLY)
			{
				if((me->GetHealth()*100) / me->GetMaxHealth() < 35)
				{
					if (Phase == PHASE_FLY) LandDown();
					Phase = PHASE_ENRAGE;
					m_uiMarkTimer = 15000;
					//DoCast(me, SPELL_MYSTIC_BUFFET);
					WorkAroundForLoSmkII();
					DoScriptText(SAY_PHASE_3, me);
				}
			}

			DoMeleeAttackIfReady();
		}
Exemplo n.º 9
0
        void UpdateAI(uint32 diff)
        {
            if (Intro)
			{
				if (MovePhase)
				{
					if (MovePhase >= 7)
					{
						me->SetDisableGravity(false);
						me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
						me->GetMotionMaster()->MovePoint(8, IntroWay[7][0], IntroWay[7][1], IntroWay[7][2]);
					}
					else
					{
						me->GetMotionMaster()->MovePoint(MovePhase, IntroWay[MovePhase][0], IntroWay[MovePhase][1], IntroWay[MovePhase][2]);
					}
					MovePhase = 0;
				}
				return;
			}

			if (Flying && MovePhase)
            {
                if (MovePhase >= 7)
                {
                    me->SetDisableGravity(false);
                    me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
                    me->GetMotionMaster()->MovePoint(8, IntroWay[7][0], IntroWay[7][1], IntroWay[7][2]);
                }
                else
                    me->GetMotionMaster()->MovePoint(MovePhase, IntroWay[MovePhase][0], IntroWay[MovePhase][1], IntroWay[MovePhase][2]);
                    
				MovePhase = 0;
            }

            if (!UpdateVictim())
                return;

            if (Flying)
                return;

            //  Phase 1 "GROUND FIGHT"
            if (Phase == 1)
            {
                if (Movement)
                {
                    DoStartMovement(me->GetVictim());
                    Movement = false;
                }

                if (BellowingRoarTimer <= diff)
                {
                    DoCastVictim(SPELL_BELLOWING_ROAR);
                    BellowingRoarTimer = urand(30000, 40000);
                } else BellowingRoarTimer -= diff;

                if (SmolderingBreathTimer <= diff)
                {
                    DoCastVictim(SPELL_SMOLDERING_BREATH);
                    SmolderingBreathTimer = 20000;
                } else SmolderingBreathTimer -= diff;

                if (CharredEarthTimer <= diff)
                {
                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                        DoCast(target, SPELL_CHARRED_EARTH);
                    CharredEarthTimer = 20000;
                } else CharredEarthTimer -= diff;

                if (TailSweepTimer <= diff)
                {
                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                        if (!me->HasInArc(M_PI, target))
                            DoCast(target, SPELL_TAIL_SWEEP);
                    TailSweepTimer = 15000;
                } else TailSweepTimer -= diff;

                if (SearingCindersTimer <= diff)
                {
                    if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                        DoCast(target, SPELL_SEARING_CINDERS);
                    SearingCindersTimer = 10000;
                } else SearingCindersTimer -= diff;

                uint32 Prozent = uint32(me->GetHealthPct());

                if (Prozent < 75 && FlyCount == 0) // first take off 75%
                    TakeOff();

                if (Prozent < 50 && FlyCount == 1) // secound take off 50%
                    TakeOff();

                if (Prozent < 25 && FlyCount == 2) // third take off 25%
                    TakeOff();

                DoMeleeAttackIfReady();
            }

            //Phase 2 "FLYING FIGHT"
            if (Phase == 2)
            {
                if (!RainBones)
                {
                    if (!Skeletons)
                    {
                        for (uint8 i = 0; i <= 3; ++i)
                        {
                            DoCastVictim(SPELL_SUMMON_SKELETON);
                            Skeletons = true;
                        }
                    }

                    if (RainofBonesTimer < diff && !RainBones) // only once at the beginning of phase 2
                    {
                        DoCastVictim(SPELL_RAIN_OF_BONES);
                        RainBones = true;
                        SmokingBlastTimer = 20000;
                    } else RainofBonesTimer -= diff;

                    if (DistractingAshTimer <= diff)
                    {
                        if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                            DoCast(target, SPELL_DISTRACTING_ASH);
                        DistractingAshTimer = 2000; //timer wrong
                    } else DistractingAshTimer -= diff;
                }

                if (RainBones)
                {
                    if (SmokingBlastTimer <= diff)
                     {
                        DoCastVictim(SPELL_SMOKING_BLAST);
                        SmokingBlastTimer = 1500; //timer wrong
                     } else SmokingBlastTimer -= diff;
                }

                if (FireballBarrageTimer <= diff)
                {
                    if (Unit* target = SelectTarget(SELECT_TARGET_FARTHEST, 0))
                        DoCast(target, SPELL_FIREBALL_BARRAGE);
                    FireballBarrageTimer = 20000;
                } else FireballBarrageTimer -= diff;

                if (FlyTimer <= diff) //landing
                {
                    Talk(YELL_LAND_PHASE);

                    me->GetMotionMaster()->Clear(false);
                    me->GetMotionMaster()->MovePoint(3, IntroWay[3][0], IntroWay[3][1], IntroWay[3][2]);

                    Flying = true;
                } else FlyTimer -= diff;
            }
        }
Exemplo n.º 10
0
    void UpdateAI(const uint32 diff)
    {
        if (!WaitTimer)
        return;

        if (WaitTimer <= diff)
        {
            if (Intro)
            {
                if (MovePhase >= 7)
                {
                    me->RemoveUnitMovementFlag(MOVEFLAG_ONTRANSPORT | MOVEFLAG_LEVITATING);
                    me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
                    me->GetMotionMaster()->MovePoint(8,IntroWay[7][0],IntroWay[7][1],IntroWay[7][2]);
                }
                else
                {
                    me->GetMotionMaster()->MovePoint(MovePhase,IntroWay[MovePhase][0],IntroWay[MovePhase][1],IntroWay[MovePhase][2]);
                    ++MovePhase;
                }
            }

            if (Flying)
            {
                if (MovePhase >= 7)
                {
                    me->RemoveUnitMovementFlag(MOVEFLAG_ONTRANSPORT | MOVEFLAG_LEVITATING);
                    me->HandleEmoteCommand(EMOTE_ONESHOT_LAND);
                    me->GetMotionMaster()->MovePoint(8,IntroWay[7][0],IntroWay[7][1],IntroWay[7][2]);
                }
                else
                {
                    me->GetMotionMaster()->MovePoint(MovePhase,IntroWay[MovePhase][0],IntroWay[MovePhase][1],IntroWay[MovePhase][2]);
                    ++MovePhase;
                }
            }

            WaitTimer = 0;
        } else WaitTimer -= diff;

        if (!UpdateVictim())
            return;

        if (Flying)
            return;

        //  Phase 1 "GROUND FIGHT"
        if (Phase == 1)
        {
            if (Movement)
            {
                DoStartMovement(me->getVictim());
                Movement = false;
            }

            if (BellowingRoarTimer <= diff)
            {
                DoCast(me->getVictim(), SPELL_BELLOWING_ROAR);
                BellowingRoarTimer = urand(30000,40000);
            } else BellowingRoarTimer -= diff;

            if (SmolderingBreathTimer <= diff)
            {
                DoCast(me->getVictim(), SPELL_SMOLDERING_BREATH);
                SmolderingBreathTimer = 20000;
            } else SmolderingBreathTimer -= diff;

            if (CharredEarthTimer <= diff)
            {
                if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                    DoCast(pTarget, SPELL_CHARRED_EARTH);
                CharredEarthTimer = 20000;
            } else CharredEarthTimer -= diff;

            if (TailSweepTimer <= diff)
            {
                if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                    if (!me->HasInArc(M_PI, pTarget))
                        DoCast(pTarget, SPELL_TAIL_SWEEP);
                TailSweepTimer = 15000;
            } else TailSweepTimer -= diff;

            if (SearingCindersTimer <= diff)
            {
                if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                    DoCast(pTarget, SPELL_SEARING_CINDERS);
                SearingCindersTimer = 10000;
            } else SearingCindersTimer -= diff;

            uint32 Prozent;
            Prozent = (me->GetHealth()*100) / me->GetMaxHealth();

            if (Prozent < 75 && FlyCount == 0) // first take off 75%
                TakeOff();

            if (Prozent < 50 && FlyCount == 1) // secound take off 50%
                TakeOff();

            if (Prozent < 25 && FlyCount == 2) // third take off 25%
                TakeOff();

            DoMeleeAttackIfReady();
        }

        //Phase 2 "FLYING FIGHT"
        if (Phase == 2)
        {
            if (!RainBones)
            {
                if (RainofBonesTimer <= diff && !RainBones) // only once at the beginning of phase 2
                {

                    if (!Skeletons)
                    {
                        for (int i = 0; i < 5; i++)
                            DoCast(me->getVictim(), SPELL_SUMMON_SKELETON, true);
                        Skeletons = true;
                    }

                    DoCast(me->getVictim(), SPELL_RAIN_OF_BONES);
                    RainBones = true;
                    SmokingBlastTimer = 20000;
                } else RainofBonesTimer -= diff;

                if (DistractingAshTimer <= diff)
                {
                    if (Unit* pTarget = SelectTarget(SELECT_TARGET_RANDOM, 0, 100, true))
                        DoCast(pTarget, SPELL_DISTRACTING_ASH);
                    DistractingAshTimer = 2000; //timer wrong
                } else DistractingAshTimer -= diff;
            }

            if (RainBones)
            {
                if (SmokingBlastTimer <= diff)
                 {
                    DoCast(me->getVictim(), SPELL_SMOKING_BLAST);
                    SmokingBlastTimer = 1500; //timer wrong
                 } else SmokingBlastTimer -= diff;
            }

            if (FireballBarrageTimer <= diff)
            {
                Map *map = me->GetMap();
                if (!map->IsDungeon()) return;
                Map::PlayerList const &PlayerList = map->GetPlayers();
                for (Map::PlayerList::const_iterator i = PlayerList.begin(); i != PlayerList.end(); ++i)
                {
                    if (Player* i_pl = i->getSource())
                        if (i_pl->isAlive() && !me->IsWithinDistInMap(i_pl,80))
                        {
                            DoCast(i_pl, SPELL_FIREBALL_BARRAGE);
                        }
                }
                FireballBarrageTimer = 20000;
            } else FireballBarrageTimer -= diff;

            if (FlyTimer <= diff) //landing
            {
                me->MonsterYell(RAND(*YELL_LAND_PHASE_1,*YELL_LAND_PHASE_2), LANG_UNIVERSAL, 0);

                me->GetMotionMaster()->Clear(false);
                me->GetMotionMaster()->MovePoint(3,IntroWay[3][0],IntroWay[3][1],IntroWay[3][2]);

                Flying = true;
            } else FlyTimer -= diff;
        }
    }
Exemplo n.º 11
0
bool CAutoBase::EventProcess(const Event &event)
{
    Math::Matrix*   mat;
    Event       newEvent;
    CObject*    pObj;
    Math::Vector    pos, speed, vibCir, iPos;
    Math::Point     dim, p;
    float       angle, dist, time, h, len, vSpeed;
    int         i, max;

    CAuto::EventProcess(event);

    if ( m_engine->GetPause() )  return true;

begin:
    iPos = m_object->GetPosition(0);

    if ( m_phase == ABP_START )
    {
        if ( m_param != PARAM_STOP     &&  // not placed on the ground?
             m_param != PARAM_FIXSCENE )
        {
            FreezeCargo(true);  // freeze whole cargo
        }

        if ( m_param == PARAM_STOP )  // raises the ground?
        {
            m_phase    = ABP_WAIT;
            m_progress = 0.0f;
            m_speed    = 1.0f/2.0f;

            for ( i=0 ; i<8 ; i++ )
            {
                m_object->SetAngleZ(1+i, Math::PI/2.0f-124.0f*Math::PI/180.0f);
                m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f);
                m_object->SetAngleX(18+i,  10.0f*Math::PI/180.0f);
                m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, -11.5f));
                m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f,  11.5f));
            }

            pObj = m_main->GetSelectObject();
            m_main->SelectObject(pObj);
            m_camera->SetControllingObject(pObj);
            if ( pObj == 0 )
            {
                m_camera->SetType(Gfx::CAM_TYPE_BACK);
            }
            else
            {
                m_camera->SetType(pObj->GetCameraType());
                m_camera->SetDist(pObj->GetCameraDist());
            }

            m_main->StartMusic();
        }

        if ( m_param == PARAM_FIXSCENE )  // raises the ground?
        {
            m_phase    = ABP_WAIT;
            m_progress = 0.0f;
            m_speed    = 1.0f/2.0f;

            for ( i=0 ; i<8 ; i++ )
            {
                m_object->SetAngleZ(1+i, Math::PI/2.0f-124.0f*Math::PI/180.0f);
                m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f);
                m_object->SetAngleX(18+i,  10.0f*Math::PI/180.0f);
                m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, -11.5f));
                m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f,  11.5f));
            }
        }

        if ( m_param == PARAM_LANDING )  // Landing?
        {
            m_phase    = ABP_LAND;
            m_progress = 0.0f;
            m_speed    = 1.0f/BASE_LAND_TIME;

            m_main->SetMovieLock(true);  // blocks everything until the end of the landing
            m_bMotor = true;  // lights the jet engine

            m_camera->SetType(Gfx::CAM_TYPE_SCRIPT);

            pos = m_pos;
            pos.x -= 150.0f;
            m_terrain->AdjustToFloor(pos);
            pos.y += 10.0f;
            m_camera->SetScriptEye(pos);
            m_posSound = pos;

            pos = m_object->GetPosition(0);
            pos.y += 300.0f+50.0f;
            m_camera->SetScriptLookat(pos);

            m_camera->FixCamera();
            m_engine->SetFocus(2.0f);

            m_engine->SetFogStart(0.9f);

            if ( m_soundChannel == -1 )
            {
                m_soundChannel = m_sound->Play(SOUND_FLY, m_posSound, 0.3f, 2.0f, true);
                m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, BASE_LAND_TIME, SOPER_CONTINUE);
                m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.5f, 2.0f, SOPER_STOP);
            }

            m_main->StartMusic();
        }

        if ( m_param == PARAM_PORTICO )  // gate on the porch?
        {
            pos = m_object->GetPosition(0);
            m_finalPos = pos;
            pos.z += BASE_PORTICO_TIME_MOVE*5.0f;  // back
            pos.y += 10.0f;  // rises (the gate)
            m_object->SetPosition(0, pos);
            MoveCargo();  // all cargo moves

            m_phase    = ABP_PORTICO_MOVE;
            m_progress = 0.0f;
            m_speed    = 1.0f/BASE_PORTICO_TIME_MOVE;

            m_main->StartMusic();
        }

        if ( m_param == PARAM_TRANSIT1 ||
             m_param == PARAM_TRANSIT2 ||
             m_param == PARAM_TRANSIT3 )  // transit in space?
        {
            m_phase    = ABP_TRANSIT_MOVE;
            m_progress = 0.0f;
            m_speed    = 1.0f/BASE_TRANSIT_TIME;

            m_object->SetAngleZ(0, -Math::PI/2.0f);
            pos = m_object->GetPosition(0);
            pos.y += 10000.0f;  // in space
            m_finalPos = pos;
            m_object->SetPosition(0, pos);

            m_main->SetMovieLock(true);  // blocks everything until the end of the landing
            m_bMotor = true;  // lights the jet engine

            m_camera->SetType(Gfx::CAM_TYPE_SCRIPT);
            pos.x += 1000.0f;
            pos.z -= 60.0f;
            pos.y += 80.0f;
            m_camera->SetScriptEye(pos);
            m_posSound = pos;
            m_camera->FixCamera();
            m_engine->SetFocus(1.0f);

            BeginTransit();

            mat = m_object->GetWorldMatrix(0);
            speed = Math::Vector(0.0f, 0.0f, 0.0f);
            dim.x = 10.0f;
            dim.y = dim.x;
            pos = Math::Vector(42.0f, -2.0f, 17.0f);
            pos = Transform(*mat, pos);
            m_partiChannel[0] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f);
            pos = Math::Vector(17.0f, -2.0f, 42.0f);
            pos = Transform(*mat, pos);
            m_partiChannel[1] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f);
            pos = Math::Vector(42.0f, -2.0f, -17.0f);
            pos = Transform(*mat, pos);
            m_partiChannel[2] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f);
            pos = Math::Vector(17.0f, -2.0f, -42.0f);
            pos = Transform(*mat, pos);
            m_partiChannel[3] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f);
            pos = Math::Vector(-42.0f, -2.0f, 17.0f);
            pos = Transform(*mat, pos);
            m_partiChannel[4] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f);
            pos = Math::Vector(-17.0f, -2.0f, 42.0f);
            pos = Transform(*mat, pos);
            m_partiChannel[5] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f);
            pos = Math::Vector(-42.0f, -2.0f, -17.0f);
            pos = Transform(*mat, pos);
            m_partiChannel[6] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f);
            pos = Math::Vector(-17.0f, -2.0f, -42.0f);
            pos = Transform(*mat, pos);
            m_partiChannel[7] = m_particle->CreateParticle(pos, speed, dim, Gfx::PARTILENS1, BASE_TRANSIT_TIME+1.0f, 0.0f, 0.0f);

            if ( m_soundChannel == -1 )
            {
                m_soundChannel = m_sound->Play(SOUND_FLY, m_posSound, 0.0f, 1.2f, true);
                m_sound->AddEnvelope(m_soundChannel, 1.0f, 1.0f, BASE_TRANSIT_TIME*0.55f, SOPER_CONTINUE);
                m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.8f, BASE_TRANSIT_TIME*0.45f, SOPER_STOP);
            }
        }
    }

    if ( event.type == EVENT_UPDINTERFACE )
    {
        if ( m_object->GetSelect() )  CreateInterface(true);
    }

    if ( event.type == EVENT_OBJECT_BTAKEOFF )
    {
        return TakeOff(true);
    }

    if ( event.type != EVENT_FRAME )  return true;
    if ( m_phase == ABP_WAIT )  return true;

    m_progress += event.rTime*m_speed;

    if ( m_phase == ABP_LAND )
    {
        if ( m_progress < 1.0f )
        {
            pos = m_pos;
            pos.y += powf(1.0f-m_progress, 2.0f)*300.0f;
            m_object->SetPosition(0, pos);
            MoveCargo();  // all cargo moves

            vibCir.z = sinf(m_time*Math::PI* 2.01f)*(Math::PI/150.0f)+
                       sinf(m_time*Math::PI* 2.51f)*(Math::PI/200.0f)+
                       sinf(m_time*Math::PI*19.01f)*(Math::PI/400.0f);
            vibCir.x = sinf(m_time*Math::PI* 2.03f)*(Math::PI/150.0f)+
                       sinf(m_time*Math::PI* 2.52f)*(Math::PI/200.0f)+
                       sinf(m_time*Math::PI*19.53f)*(Math::PI/400.0f);
            vibCir.y = 0.0f;
            vibCir *= Math::Min(1.0f, (1.0f-m_progress)*3.0f);
            m_object->SetCirVibration(vibCir);

            pos = m_pos;
            pos.x -= 150.0f;
            m_terrain->AdjustToFloor(pos);
            pos.y += 10.0f;
            m_camera->SetScriptEye(pos);

            pos = m_object->GetPosition(0);
            pos.y += 50.0f;
            m_camera->SetScriptLookat(pos);

            m_engine->SetFocus(1.0f+(1.0f-m_progress));

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

                // Dust thrown to the ground.
                pos = m_pos;
                pos.x += (Math::Rand()-0.5f)*10.0f;
                pos.z += (Math::Rand()-0.5f)*10.0f;
                angle = Math::Rand()*(Math::PI*2.0f);
                dist = m_progress*50.0f;
                p = Math::RotatePoint(angle, dist);
                speed.x = p.x;
                speed.z = p.y;
                speed.y = 0.0f;
                dim.x = (Math::Rand()*15.0f+15.0f)*m_progress;
                dim.y = dim.x;
                if ( dim.x >= 1.0f )
                {
                    m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, 2.0f, 0.0f, 2.0f);
                }

                // Particles are ejected from the jet engine.
                pos = m_object->GetPosition(0);
                pos.y += 6.0f;
                h = m_terrain->GetHeightToFloor(pos)/300.0f;
                speed.x = (Math::Rand()-0.5f)*(80.0f-50.0f*h);
                speed.z = (Math::Rand()-0.5f)*(80.0f-50.0f*h);
                speed.y = -(Math::Rand()*(h+1.0f)*40.0f+(h+1.0f)*40.0f);
                dim.x = Math::Rand()*2.0f+2.0f;
                dim.y = dim.x;
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 2.0f, 10.0f, 2.0f);

                // Black smoke from the jet engine.
                if ( m_progress > 0.8f )
                {
                    pos = m_pos;
                    pos.x += (Math::Rand()-0.5f)*8.0f;
                    pos.z += (Math::Rand()-0.5f)*8.0f;
                    pos.y += 3.0f;
                    speed.x = (Math::Rand()-0.5f)*8.0f;
                    speed.z = (Math::Rand()-0.5f)*8.0f;
                    speed.y = 0.0f;
                    dim.x = Math::Rand()*4.0f+4.0f;
                    dim.y = dim.x;
                    m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE3, 4.0f, 0.0f, 2.0f);
                }
            }
        }
        else
        {
            m_bMotor = false;  // put out the reactor

            m_object->SetPosition(0, m_pos);  // setting down
            m_object->SetCirVibration(Math::Vector(0.0f, 0.0f, 0.0f));
            MoveCargo();  // all cargo moves

            // Impact with the ground.
            max = static_cast<int>(50.0f*m_engine->GetParticleDensity());
            for ( i=0 ; i<max ; i++ )
            {
                angle = Math::Rand()*(Math::PI*2.0f);
                p = Math::RotatePoint(angle, 46.0f);
                pos = m_pos;
                pos.x += p.x;
                pos.z += p.y;
                speed = Math::Vector(0.0f, 0.0f, 0.0f);
                dim.x = Math::Rand()*10.0f+10.0f;
                dim.y = dim.x;
                time = Math::Rand()*2.0f+1.5f;
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, time, 0.0f, 2.0f);
            }

//?         m_camera->StartEffect(CE_CRASH, m_pos, 1.0f);
            m_camera->StartEffect(Gfx::CAM_EFFECT_EXPLO, m_pos, 2.0f);
            m_engine->SetFocus(1.0f);
            m_sound->Play(SOUND_BOUM, m_posSound, 0.6f, 0.5f);

            m_phase    = ABP_OPENWAIT;
            m_progress = 0.0f;
            m_speed    = 1.0f/2.0f;
        }
    }

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

                // Black smoke from the reactor.
                pos = m_pos;
                pos.x += (Math::Rand()-0.5f)*8.0f;
                pos.z += (Math::Rand()-0.5f)*8.0f;
                pos.y += 3.0f;
                speed.x = (Math::Rand()-0.5f)*8.0f;
                speed.z = (Math::Rand()-0.5f)*8.0f;
                speed.y = 0.0f;
                dim.x = Math::Rand()*4.0f+4.0f;
                dim.y = dim.x;
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE3, 4.0f, 0.0f, 2.0f);
            }
        }
        else
        {
            m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.0f, 0.3f, true);
            m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.3f, 1.0f, SOPER_CONTINUE);
            m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.0f, BASE_DOOR_TIME-1.5f, SOPER_CONTINUE);
            m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 1.0f, SOPER_STOP);

            m_phase    = ABP_OPEN;
            m_progress = 0.0f;
            m_speed    = 1.0f/BASE_DOOR_TIME;
        }
    }

    if ( m_phase == ABP_OPEN )
    {
        if ( m_progress < 1.0f )
        {
            angle = -m_progress*124.0f*Math::PI/180.0f;
            for ( i=0 ; i<8 ; i++ )
            {
                m_object->SetAngleZ(1+i, Math::PI/2.0f+angle);
            }

            if ( m_param != PARAM_PORTICO )
            {
                angle = m_progress*Math::PI*2.0f;
                p = Math::RotatePoint(angle, -150.0f);
                pos = m_pos;
                pos.x += p.x;
                pos.z += p.y;
                m_terrain->AdjustToFloor(pos);
                pos.y += 10.0f;
                pos.y += m_progress*40.0f;
                m_camera->SetScriptEye(pos);

                m_engine->SetFogStart(0.9f-(0.9f-m_fogStart)*m_progress);
            }
        }
        else
        {
            for ( i=0 ; i<8 ; i++ )
            {
                m_object->SetAngleZ(1+i, Math::PI/2.0f-124.0f*Math::PI/180.0f);
            }

            // Clash the doors with the ground.
            max = static_cast<int>(20.0f*m_engine->GetParticleDensity());
            for ( i=0 ; i<max ; i++ )
            {
                angle = Math::Rand()*(20.0f*Math::PI/180.0f)-(10.0f*Math::PI/180.0f);
                angle += (Math::PI/4.0f)*(rand()%8);
                p = Math::RotatePoint(angle, 74.0f);
                pos = m_pos;
                pos.x += p.x;
                pos.z += p.y;
                speed = Math::Vector(0.0f, 0.0f, 0.0f);
                dim.x = Math::Rand()*8.0f+8.0f;
                dim.y = dim.x;
                time = Math::Rand()*2.0f+1.5f;
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, time, 0.0f, 2.0f);
            }

            m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.3f, 1.5f, true);
            m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.5f, BASE_DOOR_TIME2, SOPER_CONTINUE);
            m_sound->AddEnvelope(m_soundChannel, 0.0f, 1.5f, 0.5f, SOPER_STOP);

            m_phase    = ABP_OPEN2;
            m_progress = 0.0f;
            m_speed    = 1.0f/BASE_DOOR_TIME2;
        }
    }

    if ( m_phase == ABP_OPEN2 )
    {
        if ( m_progress < 1.0f )
        {
            len = 7.0f-m_progress*(7.0f+11.5f);
            for ( i=0 ; i<8 ; i++ )
            {
                m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f,  len));
                m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, -len));
                m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f*m_progress);
                m_object->SetAngleX(18+i,  10.0f*Math::PI/180.0f*m_progress);
            }

            if ( m_param != PARAM_PORTICO )
            {
                angle = m_progress*Math::PI/2.0f;
                p = Math::RotatePoint(angle, -150.0f);
                pos = m_pos;
                pos.x += p.x;
                pos.z += p.y;
                m_terrain->AdjustToFloor(pos);
                pos.y += 10.0f;
                pos.y += m_progress*40.0f;
                m_camera->SetScriptEye(pos);

                m_engine->SetFogStart(0.9f-(0.9f-m_fogStart)*m_progress);
            }
        }
        else
        {
            for ( i=0 ; i<8 ; i++ )
            {
                m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f, -11.5f));
                m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f,  11.5f));
                m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f);
                m_object->SetAngleX(18+i,  10.0f*Math::PI/180.0f);
            }

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

    if ( m_phase == ABP_LDWAIT )
    {
        if ( m_progress >= 1.0f )
        {
            FreezeCargo(false);  // frees all cargo

            if ( m_param != PARAM_PORTICO )
            {
                m_main->SetMovieLock(false);  // you can play!

                pObj = m_main->GetSelectObject();
                m_main->SelectObject(pObj);
                m_camera->SetControllingObject(pObj);
                if ( pObj == 0 )
                {
                    m_camera->SetType(Gfx::CAM_TYPE_BACK);
                }
                else
                {
                    m_camera->SetType(pObj->GetCameraType());
                    m_camera->SetDist(pObj->GetCameraDist());
                }
                m_sound->Play(SOUND_BOUM, m_object->GetPosition(0));
                m_soundChannel = -1;

                m_engine->SetFogStart(m_fogStart);
            }

            m_bOpen    = true;
            m_phase    = ABP_WAIT;
            m_progress = 0.0f;
            m_speed    = 1.0f/1.0f;
        }
    }

    if ( m_phase == ABP_CLOSE2 )
    {
        if ( m_progress < 1.0f )
        {
            len = 7.0f-(1.0f-m_progress)*(7.0f+11.5f);
            for ( i=0 ; i<8 ; i++ )
            {
                m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f,  len));
                m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, -len));
                m_object->SetAngleX(10+i, -10.0f*Math::PI/180.0f*(1.0f-m_progress));
                m_object->SetAngleX(18+i,  10.0f*Math::PI/180.0f*(1.0f-m_progress));
            }
        }
        else
        {
            for ( i=0 ; i<8 ; i++ )
            {
                m_object->SetPosition(10+i, Math::Vector(23.5f, 0.0f,  7.0f));
                m_object->SetPosition(18+i, Math::Vector(23.5f, 0.0f, -7.0f));
                m_object->SetAngleX(10+i, 0.0f);
                m_object->SetAngleX(18+i, 0.0f);
            }

            m_soundChannel = m_sound->Play(SOUND_MANIP, m_posSound, 0.0f, 0.3f, true);
            m_sound->AddEnvelope(m_soundChannel, 0.3f, 0.3f, 1.0f, SOPER_CONTINUE);
            m_sound->AddEnvelope(m_soundChannel, 0.3f, 1.0f, BASE_DOOR_TIME-1.5f, SOPER_CONTINUE);
            m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.3f, 1.0f, SOPER_STOP);

            m_phase    = ABP_CLOSE;
            m_progress = 0.0f;
            m_speed    = 1.0f/BASE_DOOR_TIME;
        }
    }

    if ( m_phase == ABP_CLOSE )
    {
        if ( m_progress < 1.0f )
        {
            angle = -(1.0f-m_progress)*124.0f*Math::PI/180.0f;
            for ( i=0 ; i<8 ; i++ )
            {
                m_object->SetAngleZ(1+i, Math::PI/2.0f+angle);
            }
        }
        else
        {
            for ( i=0 ; i<8 ; i++ )
            {
                m_object->SetAngleZ(1+i, Math::PI/2.0f);
            }
            m_bMotor = true;  // lights the jet engine

            // Shock of the closing doors.
            max = static_cast<int>(20.0f*m_engine->GetParticleDensity());
            for ( i=0 ; i<max ; i++ )
            {
                angle = Math::Rand()*Math::PI*2.0f;
                p = Math::RotatePoint(angle, 32.0f);
                pos = m_pos;
                pos.x += p.x;
                pos.z += p.y;
                pos.y += 85.0f;
                speed = Math::Vector(0.0f, 0.0f, 0.0f);
                dim.x = Math::Rand()*3.0f+3.0f;
                dim.y = dim.x;
                time = Math::Rand()*1.0f+1.0f;
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, time);
            }
            m_sound->Play(SOUND_BOUM, m_object->GetPosition(0));

            m_soundChannel = -1;
            m_bOpen    = false;
            m_phase    = ABP_TOWAIT;
            m_progress = 0.0f;
            m_speed    = 1.0f/2.0f;
        }
    }

    if ( m_phase == ABP_TOWAIT )
    {
        if ( m_progress < 1.0f )
        {
            if ( m_soundChannel == -1 )
            {
                m_soundChannel = m_sound->Play(SOUND_FLY, m_posSound, 0.0f, 0.5f, true);
                m_sound->AddEnvelope(m_soundChannel, 1.0f, 0.5f, 2.0f, SOPER_CONTINUE);
                m_sound->AddEnvelope(m_soundChannel, 0.3f, 2.0f, BASE_TAKO_TIME, SOPER_STOP);
            }

            vibCir.z = sinf(m_time*Math::PI*19.01f)*(Math::PI/400.0f);
            vibCir.x = sinf(m_time*Math::PI*19.53f)*(Math::PI/400.0f);
            vibCir.y = 0.0f;
            vibCir *= m_progress*1.0f;
            m_object->SetCirVibration(vibCir);

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

                // Particles are ejected from the reactor.
                pos = m_object->GetPosition(0);
                pos.y += 6.0f;
                speed.x = (Math::Rand()-0.5f)*160.0f;
                speed.z = (Math::Rand()-0.5f)*160.0f;
                speed.y = -(Math::Rand()*10.0f+10.0f);
                dim.x = Math::Rand()*2.0f+2.0f;
                dim.y = dim.x;
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 2.0f, 10.0f, 2.0f);
            }

            m_engine->SetFogStart(m_fogStart+(0.9f-m_fogStart)*m_progress);
        }
        else
        {
            m_engine->SetFogStart(0.9f);

            m_phase    = ABP_TAKEOFF;
            m_progress = 0.0f;
            m_speed    = 1.0f/BASE_TAKO_TIME;
        }
    }

    if ( m_phase == ABP_TAKEOFF )
    {
        if ( m_progress < 1.0f )
        {
            pos = m_pos;
            pos.y += powf(m_progress, 2.0f)*600.0f;
            m_object->SetPosition(0, pos);
            MoveCargo();  // all cargo moves

            vibCir.z = sinf(m_time*Math::PI*19.01f)*(Math::PI/400.0f);
            vibCir.x = sinf(m_time*Math::PI*19.53f)*(Math::PI/400.0f);
            vibCir.y = 0.0f;
            m_object->SetCirVibration(vibCir);

            pos = m_pos;
            pos.x -= 110.0f+m_progress*250.0f;
            m_terrain->AdjustToFloor(pos);
            pos.y += 10.0f;
            m_camera->SetScriptEye(pos);

            pos = m_object->GetPosition(0);
            pos.y += 50.0f;
            m_camera->SetScriptLookat(pos);

            m_engine->SetFocus(1.0f+m_progress);

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

                // Dust thrown to the ground.
                pos = m_pos;
                pos.x += (Math::Rand()-0.5f)*10.0f;
                pos.z += (Math::Rand()-0.5f)*10.0f;
                angle = Math::Rand()*(Math::PI*2.0f);
                dist = (1.0f-m_progress)*50.0f;
                p = Math::RotatePoint(angle, dist);
                speed.x = p.x;
                speed.z = p.y;
                speed.y = 0.0f;
                dim.x = (Math::Rand()*10.0f+10.0f)*(1.0f-m_progress);
                dim.y = dim.x;
                if ( dim.x >= 1.0f )
                {
                    m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, 2.0f, 0.0f, 2.0f);
                }

                // Particles are ejected from the reactor.
                pos = m_object->GetPosition(0);
                pos.y += 6.0f;
                speed.x = (Math::Rand()-0.5f)*40.0f;
                speed.z = (Math::Rand()-0.5f)*40.0f;
                time = 5.0f+150.0f*m_progress;
                speed.y = -(Math::Rand()*time+time);
                time = 2.0f+m_progress*12.0f;
                dim.x = Math::Rand()*time+time;
                dim.y = dim.x;
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 2.0f, 10.0f, 2.0f);

                // Black smoke from the reactor.
                pos = m_object->GetPosition(0);
                pos.y += 3.0f;
                speed.x = (Math::Rand()-0.5f)*10.0f*(4.0f-m_progress*3.0f);
                speed.z = (Math::Rand()-0.5f)*10.0f*(4.0f-m_progress*3.0f);
                speed.y = 0.0f;
                dim.x = Math::Rand()*20.0f+20.0f;
                dim.y = dim.x;
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTISMOKE3, 10.0f, 0.0f, 2.0f);
            }
        }
        else
        {
            m_soundChannel = -1;
            newEvent.type = EVENT_WIN;
            m_eventQueue->AddEvent(newEvent);

            m_phase    = ABP_WAIT;
            m_progress = 0.0f;
            m_speed    = 1.0f/2.0f;
        }
    }

    if ( m_phase == ABP_PORTICO_MOVE )  // advance of the gate?
    {
        if ( m_progress < 1.0f )
        {
            pos = m_object->GetPosition(0);
            pos.z -= event.rTime*5.0f;
            m_object->SetPosition(0, pos);
            MoveCargo();  // all cargo moves
        }
        else
        {
            m_phase    = ABP_PORTICO_WAIT1;
            m_progress = 0.0f;
            m_speed    = 1.0f/1.0f;
        }
    }

    if ( m_phase == ABP_PORTICO_WAIT1 )  // expectation the gate?
    {
        if ( m_progress >= 1.0f )
        {
            m_phase    = ABP_PORTICO_DOWN;
            m_progress = 0.0f;
            m_speed    = 1.0f/BASE_PORTICO_TIME_DOWN;
        }
    }

    if ( m_phase == ABP_PORTICO_DOWN )  // down the gate?
    {
        if ( m_progress < 1.0f )
        {
            pos = m_object->GetPosition(0);
            pos.y -= event.rTime*(10.0f/BASE_PORTICO_TIME_DOWN);
            m_object->SetPosition(0, pos);
            MoveCargo();  // all cargo moves
        }
        else
        {
            // Impact with the ground.
            max = static_cast<int>(50.0f*m_engine->GetParticleDensity());
            for ( i=0 ; i<max ; i++ )
            {
                angle = Math::Rand()*(Math::PI*2.0f);
                p = Math::RotatePoint(angle, 46.0f);
                pos = m_pos;
                pos.x += p.x;
                pos.z += p.y;
                speed = Math::Vector(0.0f, 0.0f, 0.0f);
                dim.x = Math::Rand()*10.0f+10.0f;
                dim.y = dim.x;
                time = Math::Rand()*2.0f+1.5f;
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTICRASH, time, 0.0f, 2.0f);
            }

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

    if ( m_phase == ABP_PORTICO_WAIT2 )  // expectation the gate?
    {
        if ( m_progress >= 1.0f )
        {
            m_phase    = ABP_PORTICO_OPEN;
            m_progress = 0.0f;
            m_speed    = 1.0f/BASE_PORTICO_TIME_OPEN;
        }
    }

    if ( m_phase == ABP_PORTICO_OPEN )  // opening the gate?
    {
        if ( m_progress < 1.0f )
        {
        }
        else
        {
            m_phase    = ABP_OPEN;
            m_progress = 0.0f;
            m_speed    = 1.0f/2.0f;
        }
    }

    if ( m_phase == ABP_TRANSIT_MOVE )  // transit in space?
    {
        if ( m_progress < 1.0f )
        {
            pos = m_object->GetPosition(0);
            pos.x += event.rTime*(2000.0f/BASE_TRANSIT_TIME);
            m_object->SetPosition(0, pos);
            pos.x += 60.0f;
            m_camera->SetScriptLookat(pos);
        }
        else
        {
            m_object->SetAngleZ(0, 0.0f);

            m_param = PARAM_LANDING;
            m_phase    = ABP_START;
            m_progress = 0.0f;
            m_speed    = 1.0f/1.0f;

            EndTransit();

            if ( m_soundChannel != -1 )
            {
                m_sound->FlushEnvelope(m_soundChannel);
                m_sound->AddEnvelope(m_soundChannel, 0.0f, 0.8f, 0.01f, SOPER_STOP);
                m_soundChannel = -1;
            }
            goto begin;
        }
    }

    if ( m_bMotor )
    {
        if ( m_lastMotorParticle+m_engine->ParticleAdapt(0.02f) <= m_time )
        {
            m_lastMotorParticle = m_time;

            mat = m_object->GetWorldMatrix(0);

            if ( event.rTime == 0.0f )
            {
                vSpeed = 0.0f;
            }
            else
            {
                pos = m_object->GetPosition(0);
                if ( m_phase == ABP_TRANSIT_MOVE )
                {
                    vSpeed = (pos.x-iPos.x)/event.rTime;
                }
                else
                {
                    vSpeed = (pos.y-iPos.y)/event.rTime;
                }
                if ( vSpeed < 0.0f )  vSpeed *= 1.5f;
            }

            pos = Math::Vector(0.0f, 6.0f, 0.0f);
            speed.x = (Math::Rand()-0.5f)*4.0f;
            speed.z = (Math::Rand()-0.5f)*4.0f;
            speed.y = vSpeed*0.8f-(8.0f+Math::Rand()*6.0f);
            speed += pos;
            pos = Transform(*mat, pos);
            speed = Transform(*mat, speed);
            speed -= pos;

            dim.x = 4.0f+Math::Rand()*4.0f;
            dim.y = dim.x;

            m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIBASE, 3.0f, 0.0f, 0.0f);

            if ( m_phase == ABP_TRANSIT_MOVE )
            {
                speed = Math::Vector(0.0f, 0.0f, 0.0f);
                dim.x = 12.0f;
                dim.y = dim.x;
                pos = Math::Vector(0.0f, 7.0f, 0.0f);
                pos.x += (Math::Rand()-0.5f)*2.0f;  pos.z += (Math::Rand()-0.5f)*2.0f;
                pos = Transform(*mat, pos);
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 1.0f, 0.0f, 0.0f);

                speed = Math::Vector(0.0f, 0.0f, 0.0f);
                dim.x = 4.0f;
                dim.y = dim.x;
                pos = Math::Vector(42.0f, 0.0f, 17.0f);
                pos.x += (Math::Rand()-0.5f)*2.0f;  pos.z += (Math::Rand()-0.5f)*2.0f;
                pos = Transform(*mat, pos);
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 0.5f, 0.0f, 0.0f);
                pos = Math::Vector(17.0f, 0.0f, 42.0f);
                pos.x += (Math::Rand()-0.5f)*2.0f;  pos.z += (Math::Rand()-0.5f)*2.0f;
                pos = Transform(*mat, pos);
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 0.5f, 0.0f, 0.0f);
                pos = Math::Vector(42.0f, 0.0f, -17.0f);
                pos.x += (Math::Rand()-0.5f)*2.0f;  pos.z += (Math::Rand()-0.5f)*2.0f;
                pos = Transform(*mat, pos);
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 0.5f, 0.0f, 0.0f);
                pos = Math::Vector(17.0f, 0.0f, -42.0f);
                pos.x += (Math::Rand()-0.5f)*2.0f;  pos.z += (Math::Rand()-0.5f)*2.0f;
                pos = Transform(*mat, pos);
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 0.5f, 0.0f, 0.0f);
                pos = Math::Vector(-42.0f, 0.0f, 17.0f);
                pos.x += (Math::Rand()-0.5f)*2.0f;  pos.z += (Math::Rand()-0.5f)*2.0f;
                pos = Transform(*mat, pos);
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 0.5f, 0.0f, 0.0f);
                pos = Math::Vector(-17.0f, 0.0f, 42.0f);
                pos.x += (Math::Rand()-0.5f)*2.0f;  pos.z += (Math::Rand()-0.5f)*2.0f;
                pos = Transform(*mat, pos);
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 0.5f, 0.0f, 0.0f);
                pos = Math::Vector(-42.0f, 0.0f, -17.0f);
                pos.x += (Math::Rand()-0.5f)*2.0f;  pos.z += (Math::Rand()-0.5f)*2.0f;
                pos = Transform(*mat, pos);
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 0.5f, 0.0f, 0.0f);
                pos = Math::Vector(-17.0f, 0.0f, -42.0f);
                pos.x += (Math::Rand()-0.5f)*2.0f;  pos.z += (Math::Rand()-0.5f)*2.0f;
                pos = Transform(*mat, pos);
                m_particle->CreateParticle(pos, speed, dim, Gfx::PARTIGAS, 0.5f, 0.0f, 0.0f);

                pos = Math::Vector(42.0f, -2.0f, 17.0f);
                pos = Transform(*mat, pos);
                m_particle->SetPosition(m_partiChannel[0], pos);
                pos = Math::Vector(17.0f, -2.0f, 42.0f);
                pos = Transform(*mat, pos);
                m_particle->SetPosition(m_partiChannel[1], pos);
                pos = Math::Vector(42.0f, -2.0f, -17.0f);
                pos = Transform(*mat, pos);
                m_particle->SetPosition(m_partiChannel[2], pos);
                pos = Math::Vector(17.0f, -2.0f, -42.0f);
                pos = Transform(*mat, pos);
                m_particle->SetPosition(m_partiChannel[3], pos);
                pos = Math::Vector(-42.0f, -2.0f, 17.0f);
                pos = Transform(*mat, pos);
                m_particle->SetPosition(m_partiChannel[4], pos);
                pos = Math::Vector(-17.0f, -2.0f, 42.0f);
                pos = Transform(*mat, pos);
                m_particle->SetPosition(m_partiChannel[5], pos);
                pos = Math::Vector(-42.0f, -2.0f, -17.0f);
                pos = Transform(*mat, pos);
                m_particle->SetPosition(m_partiChannel[6], pos);
                pos = Math::Vector(-17.0f, -2.0f, -42.0f);
                pos = Transform(*mat, pos);
                m_particle->SetPosition(m_partiChannel[7], pos);
            }
        }
    }

    if ( m_soundChannel != -1 )
    {
        pos = m_engine->GetEyePt();
        m_sound->Position(m_soundChannel, pos);
    }

    return true;
}
Exemplo n.º 12
0
void CBoidBird::Think( float dt,SBoidContext &bc )
{
	m_accel.zero();
	

	float factorAlignment = bc.factorAlignment;
	float factorCohesion = bc.factorCohesion;
	float factorSeparation = bc.factorSeparation;
	float factorAvoidLand = bc.factorAvoidLand;
	float factorAttractToOrigin = bc.factorAttractToOrigin;
	float factorKeepHeight = bc.factorKeepHeight;

	if(m_status == Bird::LANDING)
	{
		//factorAlignment /= 3.f;
		factorCohesion *=10.f;
		factorSeparation = 0;
		factorAvoidLand = 0;
		factorAttractToOrigin *=10;
		factorKeepHeight = 0;
	}
	
	if (m_spawnFromPt)
	{
		// Set the acceleration of the boid
		float fHalfDesired = m_desiredHeigh * .5f;
		if (m_pos.z < fHalfDesired)
		{
			m_accel.z = 3.f;
		}
		else
		{
			m_accel.z = .5f;
			// Set z-acceleration
			float fRange = 1.f - (m_pos.z-fHalfDesired)/fHalfDesired;	// 1..0 range

			if (m_heading.z > 0.2f)
				m_accel.z = .5f + fRange;	// 2..1

			m_accel.x += m_heading.x * .1f;
			m_accel.y += m_heading.y * .1f;
		}

		if (m_pos.z > m_desiredHeigh)
			SetSpawnFromPt(false);

		// Limits birds to above water and land.
		if (m_pos.z < bc.terrainZ-0.2f)
		{
			m_pos.z = bc.terrainZ-0.2f;
		}
		if (m_pos.z < bc.waterLevel-0.2f)
		{
			m_pos.z = bc.waterLevel-0.2f;
		}
		return;
	}
	
	float height = m_pos.z - bc.flockPos.z;

	// Free will.
	// Continue accelerating in same dir until target speed reached.
	// Try to maintain average speed of (maxspeed+minspeed)/2
	float targetSpeed = (bc.MaxSpeed + bc.MinSpeed)/2;
	m_accel -= m_heading*(m_speed-targetSpeed)*0.5f;

	// Desired height.
	float dh = m_desiredHeigh - m_pos.z;
	float dhexp = -(dh*dh)/(3*3);

	dhexp = clamp_tpl(dhexp,-70.0f,70.0f); // Max values for expf
	// Gaussian weight.
	float fKeepHeight = factorKeepHeight - m_fNoKeepHeight;
	m_fNoKeepHeight = max(0.f, m_fNoKeepHeight - .01f*dt);
	m_accel.z = exp_tpl(dhexp) * fKeepHeight;

	if (factorAlignment != 0)
	{
		//CalcCohesion();
		Vec3 alignmentAccel;
		Vec3 cohesionAccel;
		Vec3 separationAccel;
		CalcFlockBehavior(bc,alignmentAccel,cohesionAccel,separationAccel);

		//! Adjust for allignment,
		//m_accel += alignmentAccel.Normalized()*ALIGNMENT_FACTOR;

		m_accel += alignmentAccel*factorAlignment;
		m_accel += cohesionAccel*factorCohesion;
		m_accel += separationAccel*factorSeparation;
	}

	// Avoid land.
	if (height < bc.MinHeight && m_status != Bird::LANDING)
	{
		float v = (1.0f - height/bc.MinHeight);
		m_accel += Vec3(0,0,v*v)*bc.factorAvoidLand;
	}
	else if (height > bc.MaxHeight)
	{		// Avoid max height.
		float v = (height - bc.MaxHeight)*0.1f;
		m_accel += Vec3(0,0,-v);
	}
	else if(m_status != Bird::TAKEOFF)
	{
		// Always try to accelerate in direction opposite to current in Z axis.
		m_accel.z = -(m_heading.z*m_heading.z*m_heading.z * 100.0f);
	}

		// Attract to origin point.
	float fAttractToOrigin = factorAttractToOrigin - m_fNoCenterAttract;
	m_fNoCenterAttract = max(0.f, m_fNoCenterAttract - .01f*dt);
	if (bc.followPlayer)
	{
		m_accel += (bc.playerPos - m_pos) * fAttractToOrigin;
	}
	else
	{
		if ((rand()&31) == 1)
		{
			m_birdOriginPos = Vec3(	bc.flockPos.x+Boid::Frand()*bc.fSpawnRadius,bc.flockPos.y+Boid::Frand()*bc.fSpawnRadius,bc.flockPos.z+Boid::Frand()*bc.fSpawnRadius );
			if (m_birdOriginPos.z - bc.terrainZ < bc.MinHeight)
			{
				m_birdOriginPos.z = bc.terrainZ + bc.MinHeight;
			}
		}

		m_accel += (m_birdOriginPos - m_pos) * fAttractToOrigin;
	}

	// Attract to bc.attractionPoint
	if (m_pos.GetSquaredDistance2D(bc.attractionPoint) < 5.f)
	{
		SetAttracted(false);

		CBirdsFlock *pFlock = (CBirdsFlock *)m_flock;
		if (!pFlock->GetAttractOutput())
		{	// Activate the AttractTo flownode output
			pFlock->SetAttractOutput(true);

			// Activate the flow node output
			IEntity *pFlockEntity = pFlock->GetEntity();
			if (pFlockEntity)
			{
				IScriptTable *scriptObject = pFlockEntity->GetScriptTable();
				if (scriptObject)
					Script::CallMethod(scriptObject, "OnAttractPointReached");
			}
		}
	}
	if (m_attractedToPt)
	{
		if(m_status == Bird::ON_GROUND)
			TakeOff(bc);
		else
			SetStatus(Bird::FLYING);

		m_accel += (bc.attractionPoint - m_pos) * m_fAttractionFactor;
		if (m_fAttractionFactor < 300.f * factorAttractToOrigin) m_fAttractionFactor += 3.f*dt;
	}

	// Avoid collision with Terrain and Static objects.
	float fCollisionAvoidanceWeight = 1.0f;

	m_alignHorizontally = 0;

	if(m_status == Bird::TAKEOFF)
	{ 
		if(m_accel.z < 0)
			m_accel.z = -m_accel.z;

		m_accel.z *= bc.factorTakeOff;
	}

	if (bc.avoidObstacles)
	{
		// Avoid obstacles & terrain.
		float fCollDistance = m_collisionInfo.CheckDistance() ;

		if(m_collisionInfo.IsColliding())
		{
				float w = (1.0f - m_collisionInfo.Distance()/fCollDistance);
				m_accel += m_collisionInfo.Normal() * w*w * bc.factorAvoidLand * fCollisionAvoidanceWeight;
		}
	}

	// Limits birds to above water and land.
	if (m_pos.z < bc.terrainZ-0.2f)
	{
		m_pos.z = bc.terrainZ-0.2f;
	}
	if (m_pos.z < bc.waterLevel-0.2f)
	{
		m_pos.z = bc.waterLevel-0.2f;
	}
}
Exemplo n.º 13
0
void CBoidBird::Update( float dt,SBoidContext &bc )
{
	if (m_physicsControlled)
	{
		UpdatePhysics(dt,bc);
		return;
	}
	if (m_dead)
		return;
	
	if (m_heading.IsZero())
		m_heading = Vec3(1,0,0);

	m_lastThinkTime += dt;

	{
		if (bc.followPlayer && !m_spawnFromPt)
		{
			if (m_pos.GetSquaredDistance(bc.playerPos) > MAX_BIRDS_DISTANCE*MAX_BIRDS_DISTANCE)
			{
				float z = bc.MinHeight + (Boid::Frand()+1)/2.0f*(bc.MaxHeight - bc.MinHeight);
				m_pos = bc.playerPos + Vec3(Boid::Frand()*MAX_BIRDS_DISTANCE,Boid::Frand()*MAX_BIRDS_DISTANCE,z );
				m_speed = bc.MinSpeed + ((Boid::Frand()+1)/2.0f) / (bc.MaxSpeed - bc.MinSpeed);
				m_heading = Vec3(Boid::Frand(),Boid::Frand(),0).GetNormalized();
			}
		}

		if(m_status == Bird::TAKEOFF)
		{
			float timePassed = (gEnv->pTimer->GetFrameStartTime() - m_takeOffStartTime).GetSeconds();
			if(m_playingTakeOffAnim &&  timePassed >= m_TakeOffAnimLength)
			{
				m_playingTakeOffAnim = false;
				PlayAnimationId(Bird::ANIM_FLY,true);
			}
			else if( timePassed > TAKEOFF_TIME)
			{
				SetStatus(Bird::FLYING);
			}

		}

		if(m_status == Bird::LANDING)
		{
			Vec3 vDist(m_landingPoint - m_pos);
			float dist2 = vDist.GetLengthSquared2D();
			float dist = sqrt_tpl(dist2 + vDist.z*vDist.z);

			if(dist > 0.02f && m_pos.z > m_landingPoint.z)
			{
				//if(vDist.z < 3 && m_heading)
				vDist /= dist;
				float fInterpSpeed = 2+fabs(m_heading.Dot(vDist))*3.f;
				Interpolate(m_heading,vDist, fInterpSpeed, dt);
				m_heading.NormalizeSafe(); 
			
				if(m_heading.z < vDist.z)
				{
					Interpolate(m_heading.z,vDist.z,3.0f,dt);
					m_heading.NormalizeSafe();
				}

				bool wasLandDeceleratingAlready = m_landDecelerating;
				m_accel.zero();
				m_landDecelerating = dist < bc.landDecelerationHeight;
				if(m_landDecelerating)
				{
					float newspeed= m_startLandSpeed* dist/3.f;
					if(m_speed > newspeed)
						m_speed = newspeed;
 					if(m_speed < 0.2f)
 						m_speed = 0.2f;
					if(!wasLandDeceleratingAlready)
						PlayAnimationId(Bird::ANIM_LANDING_DECELERATING, true);
				}
				else
					m_startLandSpeed = m_speed;
			}
			else
				Landed(bc);

			CalcMovementBird( dt,bc,true );
			UpdatePitch(dt,bc);
			return;

		}

		if (m_status != Bird::ON_GROUND)
		{
			Think(dt,bc);

			// Calc movement with current velocity.
			CalcMovementBird( dt,bc,true );
		}
		else 
		{
			if(bc.walkSpeed > 0 && m_onGroundStatus == Bird::OGS_WALKING)
				ThinkWalk(dt,bc);
			CalcMovementBird( dt,bc,true );
		}

		m_accel.Set(0,0,0);
		UpdatePitch(dt,bc);

		// Check if landing/on ground after think().
		if ( m_status == Bird::LANDING ||(m_dying && m_status != Bird::ON_GROUND))
		{
			float LandEpsilon = 0.5f;

			// Check if landed on water.
			if (m_pos.z-bc.waterLevel < LandEpsilon+0.1f && !m_dying)
			{
				//! From water immidiatly take off.
				//! Gives fishing effect. 
				TakeOff(bc);
			}

		}

		m_actionTime += dt;

		if (m_status == Bird::ON_GROUND )
			UpdateOnGroundAction(dt, bc);
		else
		{
			if(!bc.noLanding && m_actionTime > m_maxActionTime 
				&& !static_cast<CBirdsFlock*>(m_flock)->IsPlayerNearOrigin())
				Land();
		}
	}








}
Exemplo n.º 14
0
    void UpdateAI(const uint32 uiDiff)
    {
		if (!UpdateVictim())
            return;

	if(Phase == PHASE_LAND || Phase == PHASE_ENRAGE)
	{
		if (m_uiBreathTimer <= uiDiff)
        {
			DoCast(me->getVictim(), RAID_MODE(SPELL_FROST_BREATH_10_NORMAL,SPELL_FROST_BREATH_25_NORMAL));
            m_uiBreathTimer = urand(14000,20000);
        } 
		else m_uiBreathTimer -= uiDiff;

		if (m_uiCleaveTimer <= uiDiff)
        {
			DoCast(me->getVictim() , SPELL_CLEAVE);
            m_uiCleaveTimer = urand(10000,11000);
        } 
		else m_uiCleaveTimer -= uiDiff;

		if (m_uiTailSmashTimer <= uiDiff)
        {
			TakeOff();//DoCast(me, SPELL_TAIL_SMASH);
            m_uiTailSmashTimer = 50000;//urand(5000,10000);
        } 
		else m_uiTailSmashTimer -= uiDiff;

		if (m_uiBlisteringColdTimer <= uiDiff)
        {
			BlisteringCold();
            m_uiBlisteringColdTimer = urand(30000,31000);
        } 
		else m_uiBlisteringColdTimer -= uiDiff;
	}

	if(Phase == PHASE_LAND)
	{
	// Todo: Flyphase
	}

	if(Phase == PHASE_FLY)
	{	
		if (m_uiMarkTimer < uiDiff)
		{
			MarkPlayer();
			m_uiMarkTimer = 20000;
			m_uiIceBoltTriggerTimer = 5000;
		}
		else m_uiMarkTimer -= uiDiff;

		if (m_uiIceBoltTriggerTimer < uiDiff)
		{
			CastIceBlockTrigger();
			m_uiIceBoltTriggerTimer = 31000;
		}
		else m_uiIceBoltTriggerTimer -= uiDiff;
	}

	if(Phase == PHASE_ENRAGE)
	{
	// Alle 5 sek Iceblock Count auf ein Random Spieler
	}

	if(Phase == PHASE_LAND || Phase == PHASE_FLY)
    {
        if((me->GetHealth()*100) / me->GetMaxHealth() < 35)
        {
			Phase = PHASE_ENRAGE;
			DoCast(me, SPELL_MYSTIC_BUFFED);
		}
	}

	 DoMeleeAttackIfReady();
    }