void CParasite::Retreat(CStateManager& mgr, EStateMsg msg, float) { switch (msg) { case EStateMsg::Activate: { zeus::CVector3f dir = mgr.GetPlayer().GetTranslation() - GetTranslation(); dir.z() = 0.f; if (dir.canBeNormalized()) dir.normalize(); else dir = mgr.GetPlayer().GetTransform().basis[1]; x5f8_targetPos = GetTranslation() - dir * 3.f; FaceTarget(x5f8_targetPos); x5e8_stateProgress = 0; x742_27_landed = false; x742_28_onGround = false; x742_25_jumpVelDirty = true; x450_bodyController->GetCommandMgr().DeliverCmd(CBCJumpCmd(x5f8_targetPos, pas::EJumpType::One)); break; } case EStateMsg::Update: x3b4_speed = 1.f; break; case EStateMsg::Deactivate: x742_28_onGround = true; break; } }
void CParasite::Attack(CStateManager& mgr, EStateMsg msg, float) { switch (msg) { case EStateMsg::Activate: x608_telegraphRemTime = 0.f; if (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed) { float rz = mgr.GetActiveRandom()->Float(); float ry = mgr.GetActiveRandom()->Float(); float rx = mgr.GetActiveRandom()->Float(); x5f8_targetPos = (zeus::CVector3f(rx, ry, rz) - 0.5f) * 0.5f + mgr.GetPlayer().GetTranslation(); } else { float rz = mgr.GetActiveRandom()->Float(); float ry = mgr.GetActiveRandom()->Float(); float rx = mgr.GetActiveRandom()->Float(); x5f8_targetPos = (zeus::CVector3f(rx, ry, rz) + mgr.GetPlayer().GetTranslation() - GetTranslation()).normalized() * 15.f + GetTranslation(); } FaceTarget(x5f8_targetPos); x5e8_stateProgress = 0; x742_30_attackOver = false; x742_24_receivedTelegraph = false; x742_28_onGround = false; break; case EStateMsg::Update: switch (x5e8_stateProgress) { case 0: if (x450_bodyController->GetCurrentStateId() == pas::EAnimationState::Jump) { x5e8_stateProgress = 1; } else { x742_25_jumpVelDirty = true; FaceTarget(x5f8_targetPos); x450_bodyController->GetCommandMgr().DeliverCmd(CBCJumpCmd(x5f8_targetPos, pas::EJumpType::Normal)); } break; default: break; } break; case EStateMsg::Deactivate: x742_28_onGround = true; x742_30_attackOver = true; break; default: break; } }
bool CMobController::MobSkill(uint16 targid, uint16 wsid) { if (POwner) { FaceTarget(targid); return POwner->PAI->Internal_MobSkill(targid, wsid); } return false; }
void CMobController::Cast(uint16 targid, uint16 spellid) { FaceTarget(targid); CController::Cast(targid, spellid); }
void CMobController::Move() { if (!PMob->PAI->CanFollowPath()) { return; } float currentDistance = distance(PMob->loc.p, PTarget->loc.p); if (PMob->PAI->PathFind->IsFollowingScriptedPath() && PMob->PAI->CanFollowPath()) { PMob->PAI->PathFind->FollowPath(); return; } // attempt to teleport if (PMob->getMobMod(MOBMOD_TELEPORT_TYPE) == 1) { if (m_Tick >= m_LastSpecialTime + std::chrono::milliseconds(PMob->getBigMobMod(MOBMOD_TELEPORT_CD))) { CMobSkill* teleportBegin = battleutils::GetMobSkill(PMob->getMobMod(MOBMOD_TELEPORT_START)); if (teleportBegin) { m_LastSpecialTime = m_Tick; MobSkill(PMob->targid, teleportBegin->getID()); } } } bool move = PMob->PAI->PathFind->IsFollowingPath(); float attack_range = PMob->m_ModelSize; if (PMob->getMobMod(MOBMOD_ATTACK_SKILL_LIST) > 0) { auto skillList {battleutils::GetMobSkillList(PMob->getMobMod(MOBMOD_ATTACK_SKILL_LIST))}; if (!skillList.empty()) { auto skill {battleutils::GetMobSkill(skillList.front())}; if (skill) { attack_range = skill->getDistance(); } } } if (PMob->getMobMod(MOBMOD_SHARE_POS) > 0) { CMobEntity* posShare = (CMobEntity*)PMob->GetEntity(PMob->getMobMod(MOBMOD_SHARE_POS) + PMob->targid, TYPE_MOB); PMob->loc = posShare->loc; } else if (((distance(PMob->loc.p, PTarget->loc.p) > attack_range - 0.2f) || move) && PMob->PAI->CanFollowPath()) { //#TODO: can this be moved to scripts entirely? if (PMob->getMobMod(MOBMOD_DRAW_IN) > 0) { if (currentDistance >= PMob->m_ModelSize * 2) battleutils::DrawIn(PTarget, PMob, PMob->m_ModelSize - 0.2f); } if (PMob->speed != 0 && PMob->getMobMod(MOBMOD_NO_MOVE) == 0 && m_Tick >= m_LastSpecialTime) { // attempt to teleport to target (if in range) if (PMob->getMobMod(MOBMOD_TELEPORT_TYPE) == 2) { CMobSkill* teleportBegin = battleutils::GetMobSkill(PMob->getMobMod(MOBMOD_TELEPORT_START)); if (teleportBegin && currentDistance <= teleportBegin->getDistance()) { MobSkill(PMob->targid, teleportBegin->getID()); m_LastSpecialTime = m_Tick; return; } } else if (CanMoveForward(currentDistance)) { if (!PMob->PAI->PathFind->IsFollowingPath() || distanceSquared(PMob->PAI->PathFind->GetDestination(), PTarget->loc.p) > 10) { //path to the target if we don't have a path already PMob->PAI->PathFind->PathInRange(PTarget->loc.p, attack_range - 0.2f, PATHFLAG_WALLHACK | PATHFLAG_RUN); } PMob->PAI->PathFind->FollowPath(); if (!PMob->PAI->PathFind->IsFollowingPath()) { //arrived at target - move if there is another mob under me if (PTarget->objtype == TYPE_PC) { for (auto PSpawnedMob : static_cast<CCharEntity*>(PTarget)->SpawnMOBList) { if (PSpawnedMob.second != PMob && !PSpawnedMob.second->PAI->PathFind->IsFollowingPath() && distance(PSpawnedMob.second->loc.p, PMob->loc.p) < 1.f) { auto angle = getangle(PMob->loc.p, PTarget->loc.p) + 64; position_t new_pos {0, PMob->loc.p.x - (cosf(rotationToRadian(angle)) * 1.5f), PTarget->loc.p.y, PMob->loc.p.z + (sinf(rotationToRadian(angle)) * 1.5f), 0}; if (PMob->PAI->PathFind->ValidPosition(new_pos)) { PMob->PAI->PathFind->PathTo(new_pos, PATHFLAG_WALLHACK | PATHFLAG_RUN); } break; } } } } } else { FaceTarget(); } } } else { FaceTarget(); } }
bool CMobController::Cast(uint16 targid, SpellID spellid) { FaceTarget(targid); return CController::Cast(targid, spellid); }
void Spider::Update(s32 time) { if (active) { if (this->IsStillAlive() && this->pair->PhysxObject && this->pair->SceneNode) { try { this->pair->updateTransformation(); sound->setPosition(this->pair->SceneNode->getAbsolutePosition()); // pair->SoundNode->setLoopingStreamMode(); //if target exists if (target) { FaceTarget(); //TODO: UNIFY VARIABLES FOR READABILITY vector3df direction, position, playerPos, resultant; f32 distanceToTarget; //get position of player and target this->pair->PhysxObject->getPosition(position); this->target->pair->PhysxObject->getPosition(playerPos); //get vector this->player direction = playerPos - position; //get magnitude distanceToTarget = direction.getLength(); //std::cout << distanceToTarget << std::endl; if (distanceToTarget < 600) { attackPhase = true; } else { attackPhase = false; } if (soundReset) { soundResetTimer += time; } if (distanceToTarget < 350) { line3df ray; ray.start = position + (direction.normalize() * 10.0f); ray.end = playerPos; IPhysxObject* closestObject = physxMan->raycastClosestObject(ray); if (closestObject->getType() == EOT_SPHERE) { attackTimer += time; } else { //sidestrafe vector3df lookAt = direction; if (circleDirection == 0) { lookAt.rotateXZBy(90); } else { lookAt.rotateXZBy(-90); } lookAt.Y = 0; vector3df resul = position + lookAt.normalize() * speed; if (!(_isnan(resul.X))) if (!(_isnan(resul.Y))) if (!(_isnan(resul.Z))) pair->PhysxObject->setPosition(resul); //std::cout << resul.X << " " << resul.Y << " " << resul.Z << std::endl; pair->updateTransformation(); } } if (attackTimer >= 2000) { // pair->SoundNode->stop(); soundWalkCurrentPosition = sound->getPlayPosition(); sound->stop(); sound->drop(); //sound->roll(); u32 soundSelect = (rand() % 4); if (soundSelect ==0) { sound = soundEngine->play3D("media/sounds/Chitter.wav",this->pair->SceneNode->getAbsolutePosition(), false, true, true); } else if (soundSelect == 1) { sound = soundEngine->play3D("media/sounds/Chitter2.wav",this->pair->SceneNode->getAbsolutePosition(), false, true, true); } else if (soundSelect == 2) { sound = soundEngine->play3D("media/sounds/Chitter3.wav",this->pair->SceneNode->getAbsolutePosition(), false, true, true); } else { sound = soundEngine->play3D("media/sounds/Chitter4.wav",this->pair->SceneNode->getAbsolutePosition(), false, true, true); } sound->setMinDistance(100.0f); sound->setMaxDistance(1000.0f); sound->setIsPaused(false); soundReset = true; //pair->SoundNode->setPlayOnceMode(); target->health -= strength; target->damagedTimer = 355; target->webTimer = 510; //attack logic target->pair->PhysxObject->setLinearVelocity((-direction.normalize()) * 100.0f); attackTimer = 0; } if (soundResetTimer >= 300) { sound->stop(); sound->drop(); sound = soundEngine->play3D("media/sounds/InsectWalk1.wav", this->pair->SceneNode->getAbsolutePosition(), true, false, true); sound->setPlayPosition(soundWalkCurrentPosition); sound->setMinDistance(100.0f); sound->setMaxDistance(1000.0f); soundResetTimer = 0; soundReset = false; } CheckPhase(); //normalise vector direction.normalize(); //normalise with respect to time elapsed since last update direction = direction * (time/10.0f) * speed; direction.Y = 0; //no flying mr bug //find and apply the change resultant = position + direction * speed; //check for floating point errors that were appearing if (distanceToTarget > 300) { if (!(_isnan(resultant.X))) { this->pair->PhysxObject->setPosition(resultant); //std::cout << resultant.X << " " << resultant.Y << " " << resultant.Z << std::endl; this->pair->updateTransformation(); } } } } catch (...) { std::cerr << "exception lol" << std::endl; std::cerr << "Enemy: " << &pair << std::endl; active = false; try { this->pair->SceneNode->setVisible(false); this->pair->SceneNode->remove(); } catch (...) { std::cerr << "Recovery failed: Mesh still in Scene Graph" << std::endl; } try { physxMan->removePhysxObject(this->pair->PhysxObject); } catch (...) { std::cerr << "Recovery failed: Mesh still in Physics Graph" << std::endl; } } } else { try { for (u32 i = 0; i < enemyArray->size(); ++i) { Enemy* enemy = (*enemyArray)[i]; if (enemy->pair == this->pair) { enemyArray->erase(i); break; } } physxMan->removePhysxObject(this->pair->PhysxObject); this->pair->SceneNode->setVisible(false); this->pair->SceneNode->remove(); } catch (...) { std::cerr << "another exception" << std::endl; std::cerr << "Enemy: " << &pair << std::endl; } active = false; } } }