int CPC::GetMoveSlowValue() { if ((GetEffectState()&EFFECTSTATE_BURROW) && (auto stalkLV = m_pcSkill.GetSkillLevel(SKID_RG_TUNNELDRIVE, false)) >= 1) return g_skillTypeInfoMgr->SendMsg(nullptr, SKID_RG_TUNNELDRIVE, SM_GETINFO_SKILL, stalkLV, 0, 0, 0); // 6 * skLevel - 120 // if chasewalk is positive (from having soul link), overwrite everything else if ((auto chaseVal = GetEffective(EFST_CHASEWALK, 0)) && chaseVal > 0) return chaseVal; int value = 0; int const table[] = { GetEffective(EFST_DEC_AGI, 0) ? -25 : 0, GetEffective(EFST_BDPLAYING, 1), GetEffective(EFST_QUAGMIRE, 0), -1 * GetEffective(EFST_DONTFORGETME, 1), (GetHealthState&HEALTHSTATE_CURSE) ? -300 : 0, GetEffective(EFST_CHASEWALK, 0), (GetEffectState()&EFFECTSTATE_MARRIED) ? -100 : 0, -50 * (GetEffective(EFST_JOINTBEAT, 0)&1) - 30 * (GetEffective(EFST_JOINTBEAT, 0)&4), GetEffective(EFST_CLOAKING, 2) == 1 ? GetEffective(EFST_CLOAKING, 1) - 100 : 0, GetEffective(EFST_SLOWDOWN, 0) ? -75 : 0, -1 * GetEffective(EFST_MOVESLOW_POTION, 0), GetEffective(EFST_GS_GATLINGFEVER, 1), -1 * GetEffective(EFST_LONGING, 1), GetEffective(EFST_NJ_SUITON, 0), }; for (auto entry : table) if (value > entry) value = entry; return value; } int CPC::GetMoveHasteValue1() { int value = 0; int const table[] = { GetEffective(EFST_MOVHASTE_INFINITY, 0) <= 25 ? GetEffective(EFST_MOVHASTE_INFINITY, 0) : 25, GetEffective(EFST_MOVHASTE_POTION, 0), GetEffective(EFST_INC_AGI, 0) ? 25 : 0, GetEffective(EFST_WINDWALK, 0), GetEffective(EFST_CARTBOOST, 0), GetCategorySecondJob() == JT_ASSASSIN ? m_pcSkill.GetSkillLevel(SKID_TF_MISS, 1) : 0, GetEffective(EFST_CLOAKING, 2) ? GetEffective(EFST_CLOAKING, 0) - 100 : 0, GetEffective(EFST_BERSERK, 0) ? 25 : 0, GetEffective(EFST_RUN, 0), GetEffective(EFST_HLIF_AVOID, 0), GetEffective(EFST_MOVHASTE_HORSE, 0) ? 25 : 0, }; for (auto entry : table) if (value < entry) value = entry; return value; } int CPC::GetMoveHasteValue2() { auto value = GetEffective(EFST_STAR2, 0); if (!value) { value = GetEffective(EFST_DACCEL, 0); if (!value) value = GetEffective(EFST_RIDING, 0)); } return value; } unsigned int CPC::GetSpeed() { auto mult = m_characterTimeInfo.SpeedMount; auto value = GetCharacterInfo()->speed + GetCharacterInfo->plusCartspeed; // plusCartSpeed = (5 * (10 - lvPUSHCART))*speed/100 if (mult != 100) value = (speed * mult) / 100; if (GetEffective(EFST_STEELBODY, 0) || (GetEffective(EFST_DEFENDER, 0) && value < 200)) value = 200; if (m_characterTimeInfo.ChangeSpeedTime && m_characterTimeInfo.ChangeSpeed) value = (unsigned int)(value * 100.0 / (double)m_characterTimeInfo.ChangeSpeed); return value; } bool CPC::UpdateParameterValue(Param type, int delta) { switch(type) { case VAR_SPEEDAMOUNT: if (GetSpellCasting() && (value = m_pcSkill.GetSkillLevel(SKID_SA_FREECAST, false))) GetCharacterInfo()->SpeedMount = 5 * (35 - value); else { value = 100 - (GetMoveSlowValue() + GetMoveHasteValue1() + GetMoveHasteValue2()); if (value < 40) value = 40; GetCharacterInfo()->SpeedMount = value; Trace("Speed percent: %d, amount: %d\n", GetCharacterInfo()->SpeedMount, GetSpeed()); } m_pcClientUpdater.NotifyParameter(VAR_SPEED, GetSpeed()); return true; } }