bool CAbilityState::CanUseAbility() { if (m_PEntity->objtype == TYPE_MOB || m_PEntity->objtype == TYPE_PET) return true; if (m_PEntity->objtype == TYPE_PC) { auto PAbility = GetAbility(); auto PChar = static_cast<CCharEntity*>(m_PEntity); if (PChar->PRecastContainer->HasRecast(RECAST_ABILITY, PAbility->getRecastId(), PAbility->getRecastTime())) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_WAIT_LONGER)); return false; } if (PChar->StatusEffectContainer->HasStatusEffect({EFFECT_AMNESIA, EFFECT_IMPAIRMENT})) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_UNABLE_TO_USE_JA2)); return false; } std::unique_ptr<CMessageBasicPacket> errMsg; auto PTarget = GetTarget(); if (PChar->IsValidTarget(PTarget->targid, PAbility->getValidTarget(), errMsg)) { if (PChar != PTarget && distance(PChar->loc.p, PTarget->loc.p) > PAbility->getRange()) { PChar->pushPacket(new CMessageBasicPacket(PChar, PTarget, 0, 0, MSGBASIC_TOO_FAR_AWAY)); return false; } if (!m_PEntity->PAI->TargetFind->canSee(&PTarget->loc.p)) { m_errorMsg = std::make_unique<CMessageBasicPacket>(m_PEntity, PTarget, PAbility->getID(), 0, MSGBASIC_CANNOT_PERFORM_ACTION); return false; } if (PAbility->getID() >= ABILITY_HEALING_RUBY) { // Blood pact MP costs are stored under animation ID if (PChar->health.mp < PAbility->getAnimationID()) { PChar->pushPacket(new CMessageBasicPacket(PChar, PTarget, 0, 0, MSGBASIC_UNABLE_TO_USE_JA)); return false; } } CBaseEntity* PMsgTarget = PChar; int32 errNo = luautils::OnAbilityCheck(PChar, PTarget, PAbility, &PMsgTarget); if (errNo != 0) { PChar->pushPacket(new CMessageBasicPacket(PChar, PMsgTarget, PAbility->getID() + 16, PAbility->getID(), errNo)); return false; } return true; } return false; } return true; }
void Aiming::aim() { Vector target(0, 0, 0); // Nothing to aim at here if (!getValidTarget(target)) return; double curAimTime = g_Filming.GetDebugClientTime(); Vector idealaim; AnglesFromTo(ppmove->origin, target, idealaim); // Are we using snapto or nice aiming if (aim_snapto->value != 0) { // Simple aim float cangles[3]; pEngfuncs->GetViewAngles(cangles); cangles[0] = idealaim.y; cangles[1] = idealaim.x; pEngfuncs->SetViewAngles(cangles); } else { float angles[3]; float reaim[2]; float deltaT = (float)(curAimTime - m_LastAimTime); if(deltaT < 0) deltaT = 0; pEngfuncs->GetViewAngles(angles); reaim[0] = idealaim.x - angles[1]; reaim[1] = idealaim.y - angles[0]; // For when angles are on the 359..0 crossover if (reaim[0] > 180.0f) reaim[0] -= 360.0f; else if (reaim[0] < -180.0f) reaim[0] += 360.0f; if (reaim[1] > 180.0f) reaim[1] -= 360.0f; else if (reaim[1] < -180.0f) reaim[1] += 360.0f; // avoid over-controlling: m_Awake[0] = m_Awake[0] && 0.5f * aim_rest_x->value < abs(reaim[0]) || 0.5f * aim_wake_x->value < abs(reaim[0]); m_Awake[1] = m_Awake[1] && 0.5f * aim_rest_y->value < abs(reaim[1]) || 0.5f * aim_wake_y->value < abs(reaim[1]); if(m_Awake[0]) m_D1[0] += deltaT * aim_accel->value; else m_D1[0] -= deltaT * aim_deaccel->value; if(m_Awake[1]) m_D1[1] += deltaT * aim_accel->value; else m_D1[1] -= deltaT * aim_deaccel->value; m_D1[0] = clamp(m_D1[0], 0, 1); m_D1[1] = clamp(m_D1[1], 0, 1); m_D0[0] = m_D1[0] * (reaim[0] -m_D0[0]); m_D0[1] = m_D1[1] * (reaim[1] -m_D0[1]); // apply re-aiming: angles[1] += m_D0[0]; angles[0] += m_D0[1]; pEngfuncs->SetViewAngles(angles); } m_LastAimTime = curAimTime; }
bool CSpell::isHeal() { return (getValidTarget() & TARGET_SELF) && getSkillType() == SKILL_HEA || m_ID == 549 || m_ID == 578 || m_ID == 581 || m_ID == 593; }
bool CSpell::canTargetEnemy() { return (getValidTarget() & TARGET_ENEMY) && !(getValidTarget() & TARGET_SELF); }
bool CSpell::isBuff() { return (getValidTarget() & TARGET_SELF) && !(getValidTarget() & TARGET_ENEMY); }