Example #1
0
void Ship::SetFlightState(Ship::FlightState newState)
{
	if (m_flightState == newState) return;
	if (IsHyperspaceActive() && (newState != FLYING))
		ResetHyperspaceCountdown();

	if (newState == FLYING) {
		m_testLanded = false;
		if (m_flightState == DOCKING || m_flightState == DOCKED) onUndock.emit();
		m_dockedWith = 0;
		// lock thrusters for two seconds to push us out of station
		m_launchLockTimeout = 2.0;
	}

	m_flightState = newState;
	switch (m_flightState)
	{
		case FLYING: SetMoving(true); SetColliding(true); SetStatic(false); break;
		case DOCKING: SetMoving(false); SetColliding(false); SetStatic(false); break;
// TODO: set collision index? dynamic stations... use landed for open-air?
		case DOCKED: SetMoving(false); SetColliding(false); SetStatic(false); break;
		case LANDED: SetMoving(false); SetColliding(true); SetStatic(true); break;
		case HYPERSPACE: SetMoving(false); SetColliding(false); SetStatic(false); break;
	}
}
	void CharacterController::InjectKeyDown(const OIS::IKeyboard* keyboard)
	{
		if (HasObjectAttached() AND HasActivated())
		{
			if (keyboard->HasKeyDown(OIS::KeyCode_E) AND _currentUsableObject != nullptr)
			{
				if (_currentUsableObject->HasUsing())
					_currentUsableObject->Unuse();
				else
					_currentUsableObject->Use();
			}

			Math::Vec3F movement = VEC3F_ZERO;
			Math::Vec3F rotation = VEC3F_ZERO;

			if (keyboard->HasKeyDown(OIS::KeyCode_W) OR keyboard->HasKeyDownStr("up"))
			{
				_movementState = (HasRunning()) ? Character::CHARACTER_STATE::RunForward : Character::CHARACTER_STATE::WalkForward;

				movement = VEC3F_FORWARD;
				SetNormalSpeed(((HasRunning()) ? GetRunSpeed() : GetWalkSpeed()) * 0.02f);
				SetMoving(true);
			}

			if (keyboard->HasKeyDown(OIS::KeyCode_S) OR keyboard->HasKeyDownStr("down"))
			{
				_movementState = (HasRunning()) ? Character::CHARACTER_STATE::RunBack : Character::CHARACTER_STATE::WalkBack;

				movement = VEC3F_BACK;
				SetNormalSpeed(((HasRunning()) ? GetRunSpeed() : GetWalkSpeed()) * 0.02f);
				SetMoving(true);
			}

			if (keyboard->HasKeyDown(OIS::KeyCode_D) OR keyboard->HasKeyDownStr("right"))
			{
				_movementState = (HasRunning()) ? Character::CHARACTER_STATE::RunRight : Character::CHARACTER_STATE::WalkRight;

				movement = VEC3F_RIGHT;
				SetNormalSpeed(((HasRunning()) ? GetRunSpeed() : GetWalkSpeed()) * 0.015f);
				SetMoving(true);
			}

			if (keyboard->HasKeyDown(OIS::KeyCode_A) OR keyboard->HasKeyDownStr("left"))
			{
				_movementState = (HasRunning()) ? Character::CHARACTER_STATE::RunLeft : Character::CHARACTER_STATE::WalkLeft;

				movement = VEC3F_LEFT;
				SetNormalSpeed(((HasRunning()) ? GetRunSpeed() : GetWalkSpeed()) * 0.015f);
				SetMoving(true);
			}

			SetMovementDirection(movement);
		}
	}
Example #3
0
void AttractableSystem::Update(double DeltaTime)
{
    for (auto actor : mScene.GetActorsFromMap( GetType_static() ))
    {
        auto attractableC( actor->Get<IAttractableComponent>() );
        auto accelerationC( actor->Get<IAccelerationComponent>() );
        auto targetHolderC( actor->Get<ITargetHolderComponent>() );
        auto moveC( actor->Get<IMoveComponent>() );
        if (!attractableC.IsValid() || !accelerationC.IsValid() || !targetHolderC.IsValid() || !moveC.IsValid())
        {
            continue;
        }

        auto const accel = accelerationC->GetAcceleration();
        auto currentTarget( mScene.GetActor( targetHolderC->GetTargetGUID() ) );
        targetHolderC->SetTargetGUID( -1 );
        accelerationC->SetAcceleration( -1 * attractableC->GetDeceleration() );

        if (currentTarget.IsValid())
        {
            auto healthC( currentTarget->Get<IHealthComponent>() );
            if (healthC.IsValid() && healthC->IsAlive())
            {
                accelerationC->SetAcceleration( accel );
                targetHolderC->SetTargetGUID( currentTarget->GetGUID() );
                moveC->SetMoving( true );
                attractableC->GetTurnToTargetAct().Update( *actor, DeltaTime );
            }
        }
    }
}
	void CharacterController::InjectKeyUp(const OIS::IKeyboard* keyboard)
	{
		if (HasObjectAttached() AND HasActivated())
		{
			SetMovementDirection(VEC3F_ZERO);
			SetMoving(false);
		}
	}
Example #5
0
void Ship::SetFlightState(Ship::FlightState newState)
{
	if (m_flightState == newState) return;
	if (IsHyperspaceActive() && (newState != FLYING))
		AbortHyperjump();

	if (newState == FLYING) {
		m_testLanded = false;
		if (m_flightState == DOCKING || m_flightState == DOCKED)
			onUndock.emit();

		m_dockedWith = nullptr;

		// lock thrusters on for amount of time needed to push us out of station
		static const double MASS_LOCK_REFERENCE(40000.0); // based purely on experimentation
		// limit the time to between 2.0 and 20.0 seconds of thrust, the player can override
		m_launchLockTimeout = std::min(std::max(2.0, 2.0 * (GetMass() / MASS_LOCK_REFERENCE)), 20.0);
	}

	m_flightState = newState;
	Properties().Set("flightState", EnumStrings::GetString("ShipFlightState", m_flightState));

	switch (m_flightState)
	{
		case FLYING:		SetMoving(true);	SetColliding(true);		SetStatic(false);	break;
		case DOCKING:		SetMoving(false);	SetColliding(false);	SetStatic(false);	break;
		case UNDOCKING:	SetMoving(false);	SetColliding(false);	SetStatic(false);	break;
// TODO: set collision index? dynamic stations... use landed for open-air?
		case DOCKED:		SetMoving(false);	SetColliding(false);	SetStatic(false);	break;
		case LANDED:		SetMoving(false);	SetColliding(true);		SetStatic(true);	break;
		case JUMPING:		SetMoving(true);	SetColliding(false);	SetStatic(false);	break;
		case HYPERSPACE:	SetMoving(false);	SetColliding(false);	SetStatic(false);	break;
	}
}
Example #6
0
void NPC::NextGuardPosition() {
	if (!CalculateNewPosition2(guard_x, guard_y, guard_z, GetMovespeed())) {
		SetHeading(guard_heading);
		mlog(AI__WAYPOINTS, "Unable to move to next guard position. Probably rooted.");
	}
	else if((x_pos == guard_x) && (y_pos == guard_y) && (z_pos == guard_z))
	{
		if(moved)
		{
			moved=false;
			SetMoving(false);
			SendPosition();
		}
	}
}
void UnitGroup::SetNewGoal ()
{
	if (group->task == ft_Raid || group->task == ft_AttackDefend)
	{
		goal = globals->map->FindAttackDefendSector (globals->cb,globals->map->GetGameInfoCoords (float3(mid.x,0.0f,mid.y)));
	}

	if (goal.x < 0)
	{
		if (state != ugroup_WaitingForGoal)
			SetWaitingForGoal ();
	}
	else {
		//logPrintf ("New goal set: %d,%d\n", goal.x, goal.y);
		SetMoving ();
	}
}
Example #8
0
void Unit::Update(sf::Vector2f mouseWorldPos)
{
	if (mMoveAvailable)
		mSprite.setColor(sf::Color::White);
	else
		mSprite.setColor(sf::Color(127, 127, 127, 255));

	if (mUnitSubState != DEAD && mUnitSubState != DYING)
	{
		mUnitSubState = NORMAL;
		if (mUnitHP <= 0)
		{
			mUnitSubState = DYING;
			mHurtAnimationColor = 255;
		}
	}

	if (mUnitSubState == NORMAL)
	{
		SetMoving(!mMovementList.empty());
		if (!mMovementList.empty())
			mCurrentTargetTile = &mMovementList.front();

		if (mCurrentTargetTile != nullptr)
		{
			mTargetPosition = sf::Vector2f(mCurrentTargetTile->x * mTileSize, mCurrentTargetTile->y * mTileSize / 2);
			if (mCurrentPosition.x < mTargetPosition.x)
			{
				SetMovingRight(true);
				mCurrentPosition.x += 4;
				if (mCurrentPosition.x >= mTargetPosition.x)
					mCurrentPosition.x = mTargetPosition.x;
				if (mCurrentPosition.y < mTargetPosition.y)
				{
					mCurrentPosition.y += 2;
					if (mCurrentPosition.y >= mTargetPosition.y)
						mCurrentPosition.y = mTargetPosition.y;
				}
				if (mCurrentPosition.y > mTargetPosition.y)
				{
					mCurrentPosition.y -= 2;
					if (mCurrentPosition.y <= mTargetPosition.y)
						mCurrentPosition.y = mTargetPosition.y;
				}
			}
			else if (mCurrentPosition.x > mTargetPosition.x)
			{
				SetMovingLeft(true);
				mCurrentPosition.x -= 4;
				if (mCurrentPosition.x <= mTargetPosition.x)
					mCurrentPosition.x = mTargetPosition.x;
				if (mCurrentPosition.y < mTargetPosition.y)
				{
					mCurrentPosition.y += 2;
					if (mCurrentPosition.y >= mTargetPosition.y)
						mCurrentPosition.y = mTargetPosition.y;
				}
				if (mCurrentPosition.y > mTargetPosition.y)
				{
					mCurrentPosition.y -= 2;
					if (mCurrentPosition.y <= mTargetPosition.y)
						mCurrentPosition.y = mTargetPosition.y;
				}
			}
			else if (mCurrentPosition.y < mTargetPosition.y)
			{
				SetMovingDown(true);
				mCurrentPosition.y += 4;
				if (mCurrentPosition.y >= mTargetPosition.y)
					mCurrentPosition = mTargetPosition;
			}
			else if (mCurrentPosition.y > mTargetPosition.y)
			{
				SetMovingUp(true);
				mCurrentPosition.y -= 4;
				if (mCurrentPosition.y <= mTargetPosition.y)
					mCurrentPosition = mTargetPosition;
			}

			if (mCurrentPosition == mTargetPosition)
			{
				mMovementList.erase(mMovementList.begin() + 0);
				mCurrentTargetTile = nullptr;
				mGridVector = GridVector(mCurrentPosition.x / mTileSize, mCurrentPosition.y / mTileSize / 2);
			}
		}

		if (mMovingLeft)
		{
			mSpriteAnimationVector.x = 1;
			mSprite.setScale(2, 2);
			mAnimationSpeed = 0.5;
		}
		else if (mMovingRight)
		{
			mSpriteAnimationVector.x = 1;
			mSprite.setScale(-2, 2);
			mAnimationSpeed = 0.5;
		}
		else if (mMovingDown)
		{
			mSpriteAnimationVector.x = 2;
			mSprite.setScale(2, 2);
			mAnimationSpeed = 0.5;
		}
		else if (mMovingUp)
		{
			mSpriteAnimationVector.x = 3;
			mSprite.setScale(2, 2);
			mAnimationSpeed = 0.5;
		}
		else if (mMouseover)
		{
			if (mSpriteAnimationVector.y <= 0)
			{
				mSpriteAnimationVector.y = 1;
				mAnimationDirection = 1;
			}
			mSpriteAnimationVector.x = 4;
			mSprite.setScale(2, 2);
			mAnimationSpeed = 0.6;
		}
		else
		{
			if (mSpriteAnimationVector.y <= 0)
			{
				mSpriteAnimationVector.y = 1;
				mAnimationDirection = 1;
			}
			mSpriteAnimationVector.x = 0;
			mSprite.setScale(2, 2);
			mAnimationSpeed = 1.0;
		}

		int animationElapsed = mAnimationClock.getElapsedTime().asMilliseconds();
		int subAnimationElapsed = mSubAnimationClock.getElapsedTime().asMilliseconds();

		if (animationElapsed >= 500 * mAnimationSpeed && subAnimationElapsed >= 100 * mAnimationSpeed && !mMoving)
		{
			mSubAnimationClock.restart();
			if ((mSpriteAnimationVector.y <= 1 && mAnimationDirection == -1) || (mSpriteAnimationVector.y >= 3 && mAnimationDirection == 1))
				mAnimationDirection *= -1;
			mSpriteAnimationVector.y += mAnimationDirection;
			if (mSpriteAnimationVector.y >= 3 || mSpriteAnimationVector.y <= 1)
			{
				mAnimationDirection *= -1;
				mAnimationClock.restart();
			}
		}

		if (subAnimationElapsed >= 250 * mAnimationSpeed && mMoving)
		{
			mSubAnimationClock.restart();
			mAnimationClock.restart();
			mSpriteAnimationVector.y++;
			if (mSpriteAnimationVector.y > 3)
				mSpriteAnimationVector.y = 0;
		}

		mRenderPosition.x = mCurrentPosition.x + mTileSize / 2;
		mRenderPosition.y = mCurrentPosition.y + mTileSize;
		mSprite.setPosition(mRenderPosition);

		if (mSpriteAnimationVector.y == 0 && (mSpriteAnimationVector.x == 0 || mSpriteAnimationVector.x == 4))
			mSpriteAnimationVector.y = 1;
		mSprite.setTextureRect(sf::IntRect(mSpriteAnimationVector.x * mSpriteSize.x, mSpriteAnimationVector.y * mSpriteSize.y + mTeamNumber * mSpriteSize.y * 4, mSpriteSize.x, mSpriteSize.y));
	}
	else if (mUnitSubState == DYING)
		DyingUpdate();
	else if (mUnitSubState == DAMAGED)
		HurtUpdate();
}
void UnitGroup::Update ()
{
	if (state == ugroup_Building || units.empty ())
		return;

	int2 sector, dif;
	float2 pmin, pmax;
	if (!CalcPositioning (pmin,pmax,mid,sector))
		return;

	if (current.x < 0)
		current = globals->map->GetGameInfoCoords (float3 (mid.x,0.0f,mid.y));

	// change current?
	if (sector.x >= 0) {
		dif.x=sector.x-current.x; dif.y=sector.y-current.y;
		if (dif.x*dif.x+dif.y*dif.y > 2)
			current = sector;
	}

	GameInfo *b = globals->map->GetGameInfo (goal);

	// calc spreading
	float difx=pmax.x-pmin.x, dify=pmax.y-pmin.y;
	float spread = sqrtf (difx*difx+dify*dify);

	GameInfo *cur = 0;
	cur = globals->map->GetGameInfo (current);

	switch (state)
	{
	case ugroup_Grouping:
		if (spread < group->groupdist)
			SetMoving ();
		break;

	case ugroup_Pruning: {
		// is current target still in sector?
		if (find (cur->enemies.begin(),cur->enemies.end(), curTarget) == cur->enemies.end ())
		{
			// no, so find a new target
			if (cur->enemies.empty ()) // move on
			{
				SetNewGoal();
				SetMoving ();
			}
			else if (lastCmdFrame < globals->cb->GetCurrentFrame () - 30)
				SetPruning ();
		}
		break;}

	case ugroup_Moving:
		if (!cur->enemies.empty ())
			SetPruning ();
		else
		{
			if (goal.x < 0 || IsGoalReached (mid,spread))
				SetNewGoal ();

			if (spread > group->maxspread)
				SetGrouping ();
		}
		break;

	case ugroup_WaitingForGoal:
		SetNewGoal ();
		break;
	}
}
Example #10
0
void Transport::Update(uint32 diff)
{
    if (!AI())
    {
        if (!AIM_Initialize())
            sLog->outError("Could not initialize GameObjectAI for Transport");
    }
    else
        AI()->UpdateAI(diff);

    if (_isStopped)
        return;

    if (GetKeyFrames().size() <= 1)
        return;

    //_moveTimer = getMSTime() % _transportInfo->pathTime;
    _moveTimer += diff;
    _moveTimer %= _transportInfo->pathTime;
    // need restart path from beginning
    /* if (m_timer < m_curr->pathTime)
    {
        m_curr = keyFrames.begin();
        m_next = m_curr + 1;
    } */
    while (_moveTimer > _nextFrame->pathTime || _moveTimer < _currentFrame->departureTime)
    {
        // arrived at next stop point
        if (_transportInfo->pathTime > _nextFrame->pathTime && _moveTimer < _nextFrame->departureTime)
        {
            if (IsMoving())
            {
                SetMoving(false);
                DoEventIfAny(*_currentFrame, false);
            }
            break;
        }

        MoveToNextWayPoint();

        SetMoving(true);

        DoEventIfAny(*_currentFrame, true);

        // first check help in case client-server transport coordinates de-synchronization
        if (_currentFrame->IsTeleportFrame())
            TeleportTransport(_nextFrame->node->mapid, _nextFrame->node->x, _nextFrame->node->y, _nextFrame->node->z);

        ASSERT(_nextFrame != GetKeyFrames().begin());

        sScriptMgr->OnRelocate(this, _currentFrame->node->index, _currentFrame->node->mapid, _currentFrame->node->x, _currentFrame->node->y, _currentFrame->node->z);

        sLog->outDebug(LOG_FILTER_TRANSPORTS, "%s moved to %f %f %f %d", GetName(), GetPositionX(), GetPositionY(), GetPositionZ(), _currentFrame->node->mapid);
    }

    if (IsMoving())
    {
        if (_moveTimer < _currentFrame->departureTime || _moveTimer > _nextFrame->pathTime)
            sLog->outError("strange times, c.dep:%u, n.pt:%u (%s, %u)", _currentFrame->departureTime, _nextFrame->pathTime, GetName(), m_goInfo->moTransport.mapID);
        float t = CalculateSegmentPos((float)_moveTimer/(float)IN_MILLISECONDS);
        //if (t < -0.01f || t > 1.01f)
        //    sLog.outError("strange t=%f (%s, %u)", t, GetName(), m_goInfo->moTransport.mapID);
        //G3D::Vector3 pos;
        //m_spline->Evaluate(m_curr->node->index - 1, t, pos);
        //G3D::Vector3 dir;
        //m_spline->EvaluateDerivative(m_curr->node->index - 1, t, dir);
        //dir.z = 0.0f;
        //dir = -dir.direction();
        //Relocate(pos.x, pos.y, pos.z);
        float x = _currentFrame->node->x * (1.0f - t) + _nextFrame->node->x * t;
        float y = _currentFrame->node->y * (1.0f - t) + _nextFrame->node->y * t;
        float z = _currentFrame->node->z * (1.0f - t) + _nextFrame->node->z * t;
        float o = GetAngle(_nextFrame->node->x, _nextFrame->node->y) + float(M_PI);
        Relocate(x, y, z, o);
        UpdatePassengerPositions();
    }

    sScriptMgr->OnTransportUpdate(this, diff);
}
Example #11
0
void Transport::Update(uint32 diff)
{
    uint32 const positionUpdateDelay = 200;

    if (AI())
        AI()->UpdateAI(diff);
    else if (!AIM_Initialize())
        TC_LOG_ERROR("entities.transport", "Could not initialize GameObjectAI for Transport");

    if (GetKeyFrames().size() <= 1)
        return;

    if (IsMoving() || !_pendingStop)
        m_goValue.Transport.PathProgress += diff;

    uint32 timer = m_goValue.Transport.PathProgress % GetPeriod();

    // Set current waypoint
    // Desired outcome: _currentFrame->DepartureTime < timer < _nextFrame->ArriveTime
    // ... arrive | ... delay ... | departure
    //      event /         event /
    for (;;)
    {
        if (timer >= _currentFrame->ArriveTime)
        {
            if (!_triggeredArrivalEvent)
            {
                DoEventIfAny(*_currentFrame, false);
                _triggeredArrivalEvent = true;
            }

            if (timer < _currentFrame->DepartureTime)
            {
                SetMoving(false);
                if (_pendingStop && GetGoState() != GO_STATE_READY)
                {
                    SetGoState(GO_STATE_READY);
                    m_goValue.Transport.PathProgress = (m_goValue.Transport.PathProgress / GetPeriod());
                    m_goValue.Transport.PathProgress *= GetPeriod();
                    m_goValue.Transport.PathProgress += _currentFrame->ArriveTime;
                }
                break;  // its a stop frame and we are waiting
            }
        }

        if (timer >= _currentFrame->DepartureTime && !_triggeredDepartureEvent)
        {
            DoEventIfAny(*_currentFrame, true); // departure event
            _triggeredDepartureEvent = true;
        }

        // not waiting anymore
        SetMoving(true);

        // Enable movement
        if (GetGOInfo()->moTransport.canBeStopped)
            SetGoState(GO_STATE_ACTIVE);

        if (timer >= _currentFrame->DepartureTime && timer < _currentFrame->NextArriveTime)
            break;  // found current waypoint

        MoveToNextWaypoint();

        sScriptMgr->OnRelocate(this, _currentFrame->Node->index, _currentFrame->Node->mapid, _currentFrame->Node->x, _currentFrame->Node->y, _currentFrame->Node->z);

        TC_LOG_DEBUG("entities.transport", "Transport %u (%s) moved to node %u %u %f %f %f", GetEntry(), GetName().c_str(), _currentFrame->Node->index, _currentFrame->Node->mapid, _currentFrame->Node->x, _currentFrame->Node->y, _currentFrame->Node->z);

        // Departure event
        if (_currentFrame->IsTeleportFrame())
            if (TeleportTransport(_nextFrame->Node->mapid, _nextFrame->Node->x, _nextFrame->Node->y, _nextFrame->Node->z, _nextFrame->InitialOrientation))
                return; // Update more in new map thread
    }

    // Set position
    _positionChangeTimer.Update(diff);
    if (_positionChangeTimer.Passed())
    {
        _positionChangeTimer.Reset(positionUpdateDelay);
        if (IsMoving())
        {
            float t = CalculateSegmentPos(float(timer) * 0.001f);
            G3D::Vector3 pos, dir;
            _currentFrame->Spline->evaluate_percent(_currentFrame->Index, t, pos);
            _currentFrame->Spline->evaluate_derivative(_currentFrame->Index, t, dir);
            UpdatePosition(pos.x, pos.y, pos.z, atan2(dir.y, dir.x) + M_PI);
        }
        else
        {
            /* There are four possible scenarios that trigger loading/unloading passengers:
              1. transport moves from inactive to active grid
              2. the grid that transport is currently in becomes active
              3. transport moves from active to inactive grid
              4. the grid that transport is currently in unloads
            */
            if (_staticPassengers.empty() && GetMap()->IsGridLoaded(GetPositionX(), GetPositionY())) // 2.
                LoadStaticPassengers();
        }
    }

    sScriptMgr->OnTransportUpdate(this, diff);
}
Example #12
0
bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, int speed, bool checkZ) {
	if(GetID()==0)
		return true;

	if(speed <= 0)
	{
		SetCurrentSpeed(0);
		return true;
	}

	if ((m_Position.x-x == 0) && (m_Position.y-y == 0)) {//spawn is at target coords
		if(m_Position.z-z != 0) {
			m_Position.z = z;
			Log.Out(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f): Jumping pure Z.", x, y, z);
			return true;
		}
		Log.Out(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f) inWater=%d: We are there.", x, y, z, inWater);
		return false;
	} else if ((std::abs(m_Position.x - x) < 0.1) && (std::abs(m_Position.y - y) < 0.1)) {
		Log.Out(Logs::Detail, Logs::AI, "Calc Position2 (%.3f, %.3f, %.3f): X/Y difference <0.1, Jumping to target.", x, y, z);

		if(IsNPC()) {
			entity_list.ProcessMove(CastToNPC(), x, y, z);
		}

		m_Position.x = x;
		m_Position.y = y;
		m_Position.z = z;
		return true;
	}

	bool send_update = false;
	int compare_steps = 20;
	if(tar_ndx < compare_steps && m_TargetLocation.x==x && m_TargetLocation.y==y) {

		float new_x = m_Position.x + m_TargetV.x*tar_vector;
		float new_y = m_Position.y + m_TargetV.y*tar_vector;
		float new_z = m_Position.z + m_TargetV.z*tar_vector;
		if(IsNPC()) {
			entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
		}

		m_Position.x = new_x;
		m_Position.y = new_y;
		m_Position.z = new_z;

		Log.Out(Logs::Detail, Logs::AI, "Calculating new position2 to (%.3f, %.3f, %.3f), old vector (%.3f, %.3f, %.3f)", x, y, z, m_TargetV.x, m_TargetV.y, m_TargetV.z);

		uint8 NPCFlyMode = 0;

		if(IsNPC()) {
			if(CastToNPC()->GetFlyMode() == 1 || CastToNPC()->GetFlyMode() == 2)
				NPCFlyMode = 1;
		}

		//fix up pathing Z
		if(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving))
		{
			if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
			   (zone->HasWaterMap() && !zone->watermap->InWater(glm::vec3(m_Position))))
			{
				glm::vec3 dest(m_Position.x, m_Position.y, m_Position.z);

				float newz = zone->zonemap->FindBestZ(dest, nullptr) + 2.0f;

				Log.Out(Logs::Detail, Logs::AI, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,m_Position.x,m_Position.y,m_Position.z);

				if ((newz > -2000) &&
				    std::abs(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check.
				{
					if ((std::abs(x - m_Position.x) < 0.5) &&
					    (std::abs(y - m_Position.y) < 0.5)) {
						if (std::abs(z - m_Position.z) <=
						    RuleR(Map, FixPathingZMaxDeltaMoving))
							m_Position.z = z;
						else
							m_Position.z = newz + 1;
					}
					else
						m_Position.z = newz + 1;
				}
			}
		}

		tar_ndx++;
		return true;
	}


	if (tar_ndx>50) {
		tar_ndx--;
	} else {
		tar_ndx=0;
	}
	m_TargetLocation = glm::vec3(x, y, z);

	float nx = this->m_Position.x;
	float ny = this->m_Position.y;
	float nz = this->m_Position.z;
//	float nh = this->heading;

	m_TargetV.x = x - nx;
	m_TargetV.y = y - ny;
	m_TargetV.z = z - nz;
	SetCurrentSpeed((int8)speed);
	pRunAnimSpeed = speed;
	if(IsClient())
	{
		animation = speed / 2;
	}
	//pRunAnimSpeed = (int8)(speed*NPC_RUNANIM_RATIO);
	//speed *= NPC_SPEED_MULTIPLIER;

	Log.Out(Logs::Detail, Logs::AI, "Calculating new position2 to (%.3f, %.3f, %.3f), new vector (%.3f, %.3f, %.3f) rate %.3f, RAS %d", x, y, z, m_TargetV.x, m_TargetV.y, m_TargetV.z, speed, pRunAnimSpeed);

	// --------------------------------------------------------------------------
	// 2: get unit vector
	// --------------------------------------------------------------------------
	float mag = sqrtf (m_TargetV.x*m_TargetV.x + m_TargetV.y*m_TargetV.y + m_TargetV.z*m_TargetV.z);
	tar_vector = (float)speed / mag;

// mob move fix
	int numsteps = (int) ( mag * 16.0f / (float)speed + 0.5f);


// mob move fix

	if (numsteps<20)
	{
		if (numsteps>1)
		{
			tar_vector=1.0f	;
			m_TargetV.x = m_TargetV.x/(float)numsteps;
			m_TargetV.y = m_TargetV.y/(float)numsteps;
			m_TargetV.z = m_TargetV.z/(float)numsteps;

			float new_x = m_Position.x + m_TargetV.x;
			float new_y = m_Position.y + m_TargetV.y;
			float new_z = m_Position.z + m_TargetV.z;
			if(IsNPC()) {
				entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
			}

			m_Position.x = new_x;
			m_Position.y = new_y;
			m_Position.z = new_z;
			m_Position.w = CalculateHeadingToTarget(x, y);
			tar_ndx = 20 - numsteps;
			Log.Out(Logs::Detail, Logs::AI, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", m_Position.x, m_Position.y, m_Position.z, numsteps);
		}
		else
		{
			if(IsNPC()) {
				entity_list.ProcessMove(CastToNPC(), x, y, z);
			}

			m_Position.x = x;
			m_Position.y = y;
			m_Position.z = z;

			Log.Out(Logs::Detail, Logs::AI, "Only a single step to get there... jumping.");

		}
	}

	else {
		tar_vector/=16.0f;
		float dur = Timer::GetCurrentTime() - pLastChange;
		if(dur < 1.0f) {
			dur = 1.0f;
		}
		tar_vector = (tar_vector * AImovement_duration) / 100.0f;

		float new_x = m_Position.x + m_TargetV.x*tar_vector;
		float new_y = m_Position.y + m_TargetV.y*tar_vector;
		float new_z = m_Position.z + m_TargetV.z*tar_vector;
		if(IsNPC()) {
			entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
		}

		m_Position.x = new_x;
		m_Position.y = new_y;
		m_Position.z = new_z;
		m_Position.w = CalculateHeadingToTarget(x, y);
		Log.Out(Logs::Detail, Logs::AI, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", m_Position.x, m_Position.y, m_Position.z, numsteps);
	}

	uint8 NPCFlyMode = 0;

	if(IsNPC()) {
		if(CastToNPC()->GetFlyMode() == 1 || CastToNPC()->GetFlyMode() == 2)
			NPCFlyMode = 1;
	}

	//fix up pathing Z
	if(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving)) {

		if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
		   (zone->HasWaterMap() && !zone->watermap->InWater(glm::vec3(m_Position))))
		{
			glm::vec3 dest(m_Position.x, m_Position.y, m_Position.z);

			float newz = zone->zonemap->FindBestZ(dest, nullptr);

			Log.Out(Logs::Detail, Logs::AI, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,m_Position.x, m_Position.y, m_Position.z);

			if ((newz > -2000) &&
			    std::abs(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check.
			{
				if (std::abs(x - m_Position.x) < 0.5 && std::abs(y - m_Position.y) < 0.5) {
					if (std::abs(z - m_Position.z) <= RuleR(Map, FixPathingZMaxDeltaMoving))
						m_Position.z = z;
					else
						m_Position.z = newz + 1;
				}
				else
					m_Position.z = newz+1;
				}
		}
	}

	SetMoving(true);
	moved=true;

	m_Delta = glm::vec4(m_Position.x - nx, m_Position.y - ny, m_Position.z - nz, 0.0f);

	if (IsClient())
	{
		SendPosUpdate(1);
		CastToClient()->ResetPositionTimer();
	}
	else
	{
		SendPosUpdate();
		SetAppearance(eaStanding, false);
	}

	pLastChange = Timer::GetCurrentTime();
	return true;
}
Example #13
0
bool Mob::CalculateNewPosition(float x, float y, float z, float speed, bool checkZ) {
	if(GetID()==0)
		return true;

	float nx = x_pos;
	float ny = y_pos;
	float nz = z_pos;

	// if NPC is rooted
	if (speed == 0.0) {
		SetHeading(CalculateHeadingToTarget(x, y));
		if(moved){
			SendPosition();
			SetMoving(false);
			moved=false;
		}
		SetRunAnimSpeed(0);
		mlog(AI__WAYPOINTS, "Rooted while calculating new position to (%.3f, %.3f, %.3f)", x, y, z);
		return true;
	}

	float old_test_vector=test_vector;
	tar_vx = x - nx;
	tar_vy = y - ny;
	tar_vz = z - nz;

	if (tar_vx == 0 && tar_vy == 0)
		return false;
	pRunAnimSpeed = (uint8)(speed*NPC_RUNANIM_RATIO);
	speed *= NPC_SPEED_MULTIPLIER;

	mlog(AI__WAYPOINTS, "Calculating new position to (%.3f, %.3f, %.3f) vector (%.3f, %.3f, %.3f) rate %.3f RAS %d", x, y, z, tar_vx, tar_vy, tar_vz, speed, pRunAnimSpeed);

	// --------------------------------------------------------------------------
	// 2: get unit vector
	// --------------------------------------------------------------------------
	test_vector=sqrtf (x*x + y*y + z*z);
	tar_vector = speed / sqrtf (tar_vx*tar_vx + tar_vy*tar_vy + tar_vz*tar_vz);
	heading = CalculateHeadingToTarget(x, y);

	if (tar_vector >= 1.0) {
		if(IsNPC()) {
			entity_list.ProcessMove(CastToNPC(), x, y, z);
		}

		x_pos = x;
		y_pos = y;
		z_pos = z;
		mlog(AI__WAYPOINTS, "Close enough, jumping to waypoint");
	}
	else {
		float new_x = x_pos + tar_vx*tar_vector;
		float new_y = y_pos + tar_vy*tar_vector;
		float new_z = z_pos + tar_vz*tar_vector;
		if(IsNPC()) {
			entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
		}

		x_pos = new_x;
		y_pos = new_y;
		z_pos = new_z;
		mlog(AI__WAYPOINTS, "Next position (%.3f, %.3f, %.3f)", x_pos, y_pos, z_pos);
	}

	uint8 NPCFlyMode = 0;

	if(IsNPC()) {
		if(CastToNPC()->GetFlyMode() == 1 || CastToNPC()->GetFlyMode() == 2)
			NPCFlyMode = 1;
	}

	//fix up pathing Z
	if(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving))
	{
		if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
			(zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos)))
		{
			Map::Vertex dest(x_pos, y_pos, z_pos);

			float newz = zone->zonemap->FindBestZ(dest, nullptr) + 2.0f;

			mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos);

			if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check.
			{
				if(ABS(x - x_pos) < 0.5 && ABS(y - y_pos) < 0.5)
				{
					if(ABS(z - z_pos) <= RuleR(Map, FixPathingZMaxDeltaMoving))
						z_pos = z;
					else
						z_pos = newz + 1;
				}
				else
					z_pos = newz+1;
			}
		}
	}

	//OP_MobUpdate
	if((old_test_vector!=test_vector) || tar_ndx>20){ //send update
		tar_ndx=0;
		this->SetMoving(true);
		moved=true;
		delta_x=(x_pos-nx);
		delta_y=(y_pos-ny);
		delta_z=(z_pos-nz);
		delta_heading=0;//(heading-nh)*8;
		SendPosUpdate();
	}
	tar_ndx++;

	// now get new heading
	SetAppearance(eaStanding, false); // make sure they're standing
	pLastChange = Timer::GetCurrentTime();
	return true;
}
Example #14
0
bool Mob::MakeNewPositionAndSendUpdate(float x, float y, float z, float speed, bool checkZ) {
	if(GetID()==0)
		return true;

	if ((x_pos-x == 0) && (y_pos-y == 0)) {//spawn is at target coords
		if(z_pos-z != 0) {
			z_pos = z;
			mlog(AI__WAYPOINTS, "Calc Position2 (%.3f, %.3f, %.3f): Jumping pure Z.", x, y, z);
			return true;
		}
		mlog(AI__WAYPOINTS, "Calc Position2 (%.3f, %.3f, %.3f) inWater=%d: We are there.", x, y, z, inWater);
		return false;
	}
	else if ((ABS(x_pos - x) < 0.1) && (ABS(y_pos - y) < 0.1))
	{
		mlog(AI__WAYPOINTS, "Calc Position2 (%.3f, %.3f, %.3f): X/Y difference <0.1, Jumping to target.", x, y, z);

		if(IsNPC()) {
			entity_list.ProcessMove(CastToNPC(), x, y, z);
		}

		x_pos = x;
		y_pos = y;
		z_pos = z;
		return true;
	}

	int compare_steps = IsBoat() ? 1 : 20;
	if(tar_ndx < compare_steps && tarx==x && tary==y) {

		float new_x = x_pos + tar_vx*tar_vector;
		float new_y = y_pos + tar_vy*tar_vector;
		float new_z = z_pos + tar_vz*tar_vector;
		if(IsNPC()) {
			entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
		}

		x_pos = new_x;
		y_pos = new_y;
		z_pos = new_z;

		mlog(AI__WAYPOINTS, "Calculating new position2 to (%.3f, %.3f, %.3f), old vector (%.3f, %.3f, %.3f)", x, y, z, tar_vx, tar_vy, tar_vz);

		uint8 NPCFlyMode = 0;

		if(IsNPC()) {
			if(CastToNPC()->GetFlyMode() == 1 || CastToNPC()->GetFlyMode() == 2)
				NPCFlyMode = 1;
		}

		//fix up pathing Z
		if(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving))
		{
			if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
				(zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos)))
			{
				Map::Vertex dest(x_pos, y_pos, z_pos);

				float newz = zone->zonemap->FindBestZ(dest, nullptr) + 2.0f;

				mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos);

				if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check.
				{
					if((ABS(x - x_pos) < 0.5) && (ABS(y - y_pos) < 0.5))
					{
						if(ABS(z-z_pos) <= RuleR(Map, FixPathingZMaxDeltaMoving))
							z_pos = z;
						else
							z_pos = newz + 1;
					}
					else
						z_pos = newz + 1;
				}
			}
		}

		tar_ndx++;
		return true;
	}


	if (tar_ndx>50) {
		tar_ndx--;
	} else {
		tar_ndx=0;
	}
	tarx=x;
	tary=y;
	tarz=z;

	float nx = this->x_pos;
	float ny = this->y_pos;
	float nz = this->z_pos;
//	float nh = this->heading;

	tar_vx = x - nx;
	tar_vy = y - ny;
	tar_vz = z - nz;

	//pRunAnimSpeed = (int8)(speed*NPC_RUNANIM_RATIO);
	//speed *= NPC_SPEED_MULTIPLIER;

	mlog(AI__WAYPOINTS, "Calculating new position2 to (%.3f, %.3f, %.3f), new vector (%.3f, %.3f, %.3f) rate %.3f, RAS %d", x, y, z, tar_vx, tar_vy, tar_vz, speed, pRunAnimSpeed);

	// --------------------------------------------------------------------------
	// 2: get unit vector
	// --------------------------------------------------------------------------
	float mag = sqrtf (tar_vx*tar_vx + tar_vy*tar_vy + tar_vz*tar_vz);
	tar_vector = speed / mag;

// mob move fix
	int numsteps = (int) ( mag * 20 / speed) + 1;


// mob move fix

	if (numsteps<20)
	{
		if (numsteps>1)
		{
			tar_vector=1.0f				;
			tar_vx = tar_vx/numsteps;
			tar_vy = tar_vy/numsteps;
			tar_vz = tar_vz/numsteps;

			float new_x = x_pos + tar_vx;
			float new_y = y_pos + tar_vy;
			float new_z = z_pos + tar_vz;
			if(IsNPC()) {
				entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
			}

			x_pos = new_x;
			y_pos = new_y;
			z_pos = new_z;
			tar_ndx=22-numsteps;
			heading = CalculateHeadingToTarget(x, y);
			mlog(AI__WAYPOINTS, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", x_pos, y_pos, z_pos, numsteps);
		}
		else
		{
			if(IsNPC()) {
				entity_list.ProcessMove(CastToNPC(), x, y, z);
			}

			x_pos = x;
			y_pos = y;
			z_pos = z;

			mlog(AI__WAYPOINTS, "Only a single step to get there... jumping.");

		}
	}

	else {
		tar_vector/=20;

		float new_x = x_pos + tar_vx*tar_vector;
		float new_y = y_pos + tar_vy*tar_vector;
		float new_z = z_pos + tar_vz*tar_vector;
		if(IsNPC()) {
			entity_list.ProcessMove(CastToNPC(), new_x, new_y, new_z);
		}

		x_pos = new_x;
		y_pos = new_y;
		z_pos = new_z;
		heading = CalculateHeadingToTarget(x, y);
		mlog(AI__WAYPOINTS, "Next position2 (%.3f, %.3f, %.3f) (%d steps)", x_pos, y_pos, z_pos, numsteps);
	}

	uint8 NPCFlyMode = 0;

	if(IsNPC()) {
		if(CastToNPC()->GetFlyMode() == 1 || CastToNPC()->GetFlyMode() == 2)
			NPCFlyMode = 1;
	}

	//fix up pathing Z
	if(!NPCFlyMode && checkZ && zone->HasMap() && RuleB(Map, FixPathingZWhenMoving)) {

		if(!RuleB(Watermap, CheckForWaterWhenMoving) || !zone->HasWaterMap() ||
			(zone->HasWaterMap() && !zone->watermap->InWater(x_pos, y_pos, z_pos)))
		{
			Map::Vertex dest(x_pos, y_pos, z_pos);

			float newz = zone->zonemap->FindBestZ(dest, nullptr); + 2.0f;

			mlog(AI__WAYPOINTS, "BestZ returned %4.3f at %4.3f, %4.3f, %4.3f", newz,x_pos,y_pos,z_pos);

			if( (newz > -2000) && ABS(newz - dest.z) < RuleR(Map, FixPathingZMaxDeltaMoving)) // Sanity check.
			{
				if(ABS(x - x_pos) < 0.5 && ABS(y - y_pos) < 0.5)
				{
					if(ABS(z - z_pos) <= RuleR(Map, FixPathingZMaxDeltaMoving))
						z_pos = z;
					else
						z_pos = newz + 1;
				}
				else
					z_pos = newz+1;
				}
		}
	}

	SetMoving(true);
	moved=true;

	delta_x=x_pos-nx;
	delta_y=y_pos-ny;
	delta_z=z_pos-nz;
	delta_heading=0;

	if (IsClient())
		SendPosUpdate(1);
	else
		SendPosUpdate();

	SetAppearance(eaStanding, false);
	pLastChange = Timer::GetCurrentTime();
	return true;
}
Example #15
0
void Transport::Update(uint32 diff)
{
    uint32 const positionUpdateDelay = 200;

    if (AI())
        AI()->UpdateAI(diff);
    else if (!AIM_Initialize())
        TC_LOG_ERROR("entities.transport", "Could not initialize GameObjectAI for Transport");

    if (GetKeyFrames().size() <= 1)
        return;

    m_goValue.Transport.PathProgress += diff;

    uint32 timer = m_goValue.Transport.PathProgress % GetPeriod();

    // Set current waypoint
    // Desired outcome: _currentFrame->DepartureTime < timer < _nextFrame->ArriveTime
    // ... arrive | ... delay ... | departure
    //      event /         event /
    for (;;)
    {
        if (timer >= _currentFrame->ArriveTime)
        {
            if (!_triggeredArrivalEvent)
            {
                DoEventIfAny(*_currentFrame, false);
                _triggeredArrivalEvent = true;
            }

            if (timer < _currentFrame->DepartureTime)
            {
                SetMoving(false);
                if (_pendingStop)
                    SetGoState(GO_STATE_READY);
                break;  // its a stop frame and we are waiting
            }
        }

        if (_pendingStop && timer >= _currentFrame->DepartureTime && GetGoState() == GO_STATE_READY)
        {
            m_goValue.Transport.PathProgress = (m_goValue.Transport.PathProgress / GetPeriod());
            m_goValue.Transport.PathProgress *= GetPeriod();
            m_goValue.Transport.PathProgress += _currentFrame->ArriveTime;
            break;
        }

        if (timer >= _currentFrame->DepartureTime && !_triggeredDepartureEvent)
        {
            DoEventIfAny(*_currentFrame, true); // departure event
            _triggeredDepartureEvent = true;
        }

        if (timer >= _currentFrame->DepartureTime && timer < _currentFrame->NextArriveTime)
            break;  // found current waypoint

        MoveToNextWaypoint();

        // not waiting anymore
        SetMoving(true);

        // Enable movement
        if (GetGOInfo()->moTransport.canBeStopped)
            SetGoState(GO_STATE_ACTIVE);

        sScriptMgr->OnRelocate(this, _currentFrame->Node->index, _currentFrame->Node->mapid, _currentFrame->Node->x, _currentFrame->Node->y, _currentFrame->Node->z);

        TC_LOG_DEBUG("entities.transport", "Transport %u (%s) moved to node %u %u %f %f %f", GetEntry(), GetName().c_str(), _currentFrame->Node->index, _currentFrame->Node->mapid, _currentFrame->Node->x, _currentFrame->Node->y, _currentFrame->Node->z);

        // Departure event
        if (_currentFrame->IsTeleportFrame())
            if (TeleportTransport(_nextFrame->Node->mapid, _nextFrame->Node->x, _nextFrame->Node->y, _nextFrame->Node->z))
                return; // Update more in new map thread
    }

	// Add model to map after we are fully done with moving maps
    if (_delayedAddModel)
    {
        _delayedAddModel = false;
        if (m_model)
            GetMap()->InsertGameObjectModel(*m_model);
    }

    // Set position
    _positionChangeTimer.Update(diff);
    if (_positionChangeTimer.Passed())
    {
        _positionChangeTimer.Reset(positionUpdateDelay);
        if (IsMoving())
        {
            float t = CalculateSegmentPos(float(timer) * 0.001f);
            G3D::Vector3 pos, dir;
            _currentFrame->Spline->evaluate_percent(_currentFrame->Index, t, pos);
            _currentFrame->Spline->evaluate_derivative(_currentFrame->Index, t, dir);
            UpdatePosition(pos.x, pos.y, pos.z, atan2(dir.x, dir.y));
        }
    }

    sScriptMgr->OnTransportUpdate(this, diff);
}
Example #16
0
void Transport::Update(uint32 diff)
{
    uint32 const positionUpdateDelay = 200;

    if (AI())
        AI()->UpdateAI(diff);
    else if (!AIM_Initialize())
        TC_LOG_ERROR("entities.transport", "Could not initialize GameObjectAI for Transport");

    if (GetKeyFrames().size() <= 1)
        return;

    if (IsMoving() || !_pendingStop)
        m_goValue.Transport.PathProgress += diff;

    uint32 timer = m_goValue.Transport.PathProgress % GetTransportPeriod();
    bool justStopped = false;

    // Set current waypoint
    // Desired outcome: _currentFrame->DepartureTime < timer < _nextFrame->ArriveTime
    // ... arrive | ... delay ... | departure
    //      event /         event /
    for (;;)
    {
        if (timer >= _currentFrame->ArriveTime)
        {
            if (!_triggeredArrivalEvent)
            {
                DoEventIfAny(*_currentFrame, false);
                _triggeredArrivalEvent = true;
            }

            if (timer < _currentFrame->DepartureTime)
            {
                SetMoving(false);
                justStopped = true;
                if (_pendingStop && GetGoState() != GO_STATE_READY)
                {
                    SetGoState(GO_STATE_READY);
                    m_goValue.Transport.PathProgress = (m_goValue.Transport.PathProgress / GetTransportPeriod());
                    m_goValue.Transport.PathProgress *= GetTransportPeriod();
                    m_goValue.Transport.PathProgress += _currentFrame->ArriveTime;
                }
                break;  // its a stop frame and we are waiting
            }
        }

        if (timer >= _currentFrame->DepartureTime && !_triggeredDepartureEvent)
        {
            DoEventIfAny(*_currentFrame, true); // departure event
            _triggeredDepartureEvent = true;
        }

        // not waiting anymore
        SetMoving(true);

        // Enable movement
        if (GetGOInfo()->moTransport.allowstopping)
            SetGoState(GO_STATE_ACTIVE);

        if (timer >= _currentFrame->DepartureTime && timer < _currentFrame->NextArriveTime)
            break;  // found current waypoint

        MoveToNextWaypoint();

        sScriptMgr->OnRelocate(this, _currentFrame->Node->NodeIndex, _currentFrame->Node->ContinentID, _currentFrame->Node->Loc.X, _currentFrame->Node->Loc.Y, _currentFrame->Node->Loc.Z);

        TC_LOG_DEBUG("entities.transport", "Transport %u (%s) moved to node %u %u %f %f %f", GetEntry(), GetName().c_str(), _currentFrame->Node->NodeIndex, _currentFrame->Node->ContinentID, _currentFrame->Node->Loc.X, _currentFrame->Node->Loc.Y, _currentFrame->Node->Loc.Z);

        // Departure event
        if (_currentFrame->IsTeleportFrame())
            if (TeleportTransport(_nextFrame->Node->ContinentID, _nextFrame->Node->Loc.X, _nextFrame->Node->Loc.Y, _nextFrame->Node->Loc.Z, _nextFrame->InitialOrientation))
                return; // Update more in new map thread
    }

    // Add model to map after we are fully done with moving maps
    if (_delayedAddModel)
    {
        _delayedAddModel = false;
        if (m_model)
            GetMap()->InsertGameObjectModel(*m_model);
    }

    // Set position
    _positionChangeTimer.Update(diff);
    if (_positionChangeTimer.Passed())
    {
        _positionChangeTimer.Reset(positionUpdateDelay);
        if (IsMoving())
        {
            float t = !justStopped ? CalculateSegmentPos(float(timer) * 0.001f) : 1.0f;
            G3D::Vector3 pos, dir;
            _currentFrame->Spline->evaluate_percent(_currentFrame->Index, t, pos);
            _currentFrame->Spline->evaluate_derivative(_currentFrame->Index, t, dir);
            UpdatePosition(pos.x, pos.y, pos.z, std::atan2(dir.y, dir.x) + float(M_PI));
        }
        else if (justStopped)
            UpdatePosition(_currentFrame->Node->Loc.X, _currentFrame->Node->Loc.Y, _currentFrame->Node->Loc.Z, _currentFrame->InitialOrientation);
        else
        {
            /* There are four possible scenarios that trigger loading/unloading passengers:
              1. transport moves from inactive to active grid
              2. the grid that transport is currently in becomes active
              3. transport moves from active to inactive grid
              4. the grid that transport is currently in unloads
            */
            bool gridActive = GetMap()->IsGridLoaded(GetPositionX(), GetPositionY());

            if (_staticPassengers.empty() && gridActive) // 2.
                LoadStaticPassengers();
            else if (!_staticPassengers.empty() && !gridActive)
                // 4. - if transports stopped on grid edge, some passengers can remain in active grids
                //      unload all static passengers otherwise passengers won't load correctly when the grid that transport is currently in becomes active
                UnloadStaticPassengers();
        }
    }

    sScriptMgr->OnTransportUpdate(this, diff);
}
void GuardControllerSubSystem::Update(Actor& actor, double DeltaTime)
{
    Opt<GuardControllerComponent> guardCC=actor.Get<IControllerComponent>();
    if (!guardCC.IsValid()||!guardCC->IsEnabled())
    {
        return;
    }
    if (mProgramState.mMode == core::ProgramState::Client)
    {
        return;
    }
    auto targetHolderC = actor.Get<ITargetHolderComponent>();
    if (!targetHolderC.IsValid())
    {
        return;
    }
    auto healthC = actor.Get<IHealthComponent>();
    if (!healthC.IsValid() || !healthC->IsAlive())
    {
        return;
    }
    UpdateTarget( actor, targetHolderC );
    Opt<Actor> currentTarget( mScene.GetActor( targetHolderC->GetTargetGUID() ) );
    auto moveC( actor.Get<IMoveComponent>() );
    guardCC->SetNextMoveTimer( guardCC->GetNextMoveTimer() - DeltaTime );
    if (currentTarget.IsValid())
    {
        auto positionC( actor.Get<IPositionComponent>() );
        auto targetPositionC( currentTarget->Get<IPositionComponent>() );
        auto const distSqr = GetDistanceSqr( positionC, targetPositionC );
        glm::vec2 const distV( (targetPositionC->GetX() - positionC->GetX()), (targetPositionC->GetY() - positionC->GetY()) );
        double const Rot = atan2( distV.y, distV.x );
        positionC->SetOrientation( Rot );
        auto inventoryC = actor.Get<IInventoryComponent>();
        if (inventoryC.IsValid())
        {
            Opt<Weapon> weapon = inventoryC->GetSelectedWeapon();
            if (weapon.IsValid())
            {
                int32_t const aggroAltDistSqr = guardCC->GetAggroAltDist() * guardCC->GetAggroAltDist();
                if (distSqr < aggroAltDistSqr)
                {
                    weapon->SetShoot( false );
                    weapon->SetShootAlt( true );
                }
                else
                {
                    weapon->SetShoot( true );
                    weapon->SetShootAlt( false );
                }
            }
        }




        if (guardCC->GetNextMoveTimer() <= 0.0)
        {
            const int32_t ran = RandomGenerator::global()() % 3;
            if (ran == 0)
            {
                guardCC->SetMoveDirection( GuardControllerComponent::Left );
            }
            else if (ran == 1)
            {
                guardCC->SetMoveDirection( GuardControllerComponent::Right );
            }
            else
            {
                guardCC->SetMoveDirection( GuardControllerComponent::None );
            }
            guardCC->SetNextMoveTimer(guardCC->GetNextMoveTimerMax() 
                + (RandomGenerator::global()() % 100*0.02*- 1)*guardCC->GetNextMoveTimerVariance() );
        }
        int32_t const tooCloseDistSqr = guardCC->GetCloseDist() * guardCC->GetCloseDist();
        int32_t const walkAwayDistSqr = guardCC->GetWalkAwayDist() * guardCC->GetWalkAwayDist();
        double heading = 0.0;
        static const double pi = boost::math::constants::pi<double>();
        if (distSqr > tooCloseDistSqr)
        {
            heading = Rot;
            if (guardCC->GetMoveDirection() == GuardControllerComponent::Left)
            {
                heading -= pi / 4;
            }
            else if (guardCC->GetMoveDirection() == GuardControllerComponent::Right)
            {
                heading += pi / 4;
            }
            moveC->SetMoving( true );
        }
        else if (distSqr < walkAwayDistSqr)
        {
            heading = Rot-pi;
            if (guardCC->GetMoveDirection() == GuardControllerComponent::Left)
            {
                heading += pi / 4;
            }
            else if (guardCC->GetMoveDirection() == GuardControllerComponent::Right)
            {
                heading -= pi / 4;
            }
            moveC->SetMoving( true );
        }
        else
        {
            heading = Rot;
            if (guardCC->GetMoveDirection() == GuardControllerComponent::Left)
            {
                heading -= pi / 2;
                moveC->SetMoving( true );
            }
            else if (guardCC->GetMoveDirection() == GuardControllerComponent::Right)
            {
                heading += pi / 2;
                moveC->SetMoving( true );
            }
            else
            {
                moveC->SetMoving( false );
            }
        }
        moveC->SetHeading( heading );
    }
    else
    {
        moveC->SetMoving( false );
        Opt<IInventoryComponent> inventoryC = actor.Get<IInventoryComponent>();
        if (inventoryC.IsValid())
        {
            Opt<Weapon> weapon = inventoryC->GetSelectedWeapon();
            if (weapon.IsValid())
            {
                weapon->SetShoot( false );
                weapon->SetShootAlt( false );
            }
        }
    }
}
Example #18
0
void BrigadeClass::SetUnitOrders (int neworders, VU_ID oid)
	{
	Objective	o,so;
	GridIndex	x,y,dx,dy;
	Unit		e;

	SetOrdered(1);
	SetUnitTactic(0);

	o = FindObjective(oid);

#ifdef DEBUG
	if (gDumping)
		{
		FILE	*fp;
		int		id1;
		char	buffer[256];
		char	name1[80],name2[80],timestr[80];

		sprintf(buffer,"campaign\\save\\dump\\%d.BRI",GetCampID());

		fp = fopen(buffer,"a");
		if (fp)
			{
			if (o)
				{
				o->GetName(name1,79,FALSE);
				id1 = o->GetCampID();
				}
			else
				{
				sprintf(name1,"NONE");
				id1 = 0;
				}
			GetName(name2,79,FALSE);
			GetTimeString(TheCampaign.CurrentTime,timestr);
			sprintf(buffer,"%s (%d) ordered to %s %s (%d) @ %s.\n",name2,GetCampID(),OrderStr[neworders],name1,id1,timestr);
			fprintf(fp,buffer);
			fclose(fp);
			}
		else
			gDumping = 0;
		}
#endif
	
	if (!o)
		return;

	o->GetLocation(&dx,&dy);
	GetLocation(&x,&y);
	if ((x != dx || y != dy) && GetMovementType() != NoMove)
		{
		SetMoving(1);
		SetUnitDestination(dx,dy);
		}
	SetTempDest(0);

	if (neworders == GetOrders() && oid == GetUnitObjectiveID())
		return;
	
	DisposeWayPoints();
	SetUnitObjective(oid);
	GroundUnitClass::SetUnitOrders(neworders);

	// Reset component ordered state
	e = GetFirstUnitElement();
	while (e)
		{
		e->SetAssigned(0);
		e = GetNextUnitElement();
		}

	// If this is near the front, send a low priority request for an enemy recon patrol
	if (o->IsNearfront())
		{
		MissionRequestClass		mis;
		mis.tot = Camp_GetCurrentTime() + (rand()%MIN_TASK_GROUND + 30) * CampaignMinutes;
		mis.vs = GetTeam();
		mis.tot_type = TYPE_NE;
		o->GetLocation(&mis.tx,&mis.ty);
		mis.targetID = Id();
		mis.mission = AMIS_RECONPATROL;
		mis.roe_check = ROE_AIR_OVERFLY;
		mis.RequestEnemyMission();
		}

	// Let's make sure our objective tree jives with our assignment
	if (o->IsSecondary())
		{
		so = o->GetObjectiveParent();
		if (so)
			SetUnitPrimaryObj(so->Id());
		SetUnitSecondaryObj(o->Id());
		}
	else if (o->IsPrimary())
		{
		SetUnitPrimaryObj(o->Id());
		SetUnitSecondaryObj(o->Id());
		}
	else
		{
		so = o->GetObjectiveParent();
		if (so)
			{
			SetUnitSecondaryObj(so->Id());
			o = so->GetObjectiveParent();
			if (o)
				SetUnitPrimaryObj(o->Id());
			}
		}
	}