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); } }
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); } }
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; } }
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 (); } }
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; } }
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); }
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); }
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; }
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; }
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; }
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); }
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 ); } } } }
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()); } } }