int16 CBattleEntity::GetRangedWeaponDelay(bool tp) { CItemWeapon* PRange = (CItemWeapon*)m_Weapons[SLOT_RANGED]; CItemWeapon* PAmmo = (CItemWeapon*)m_Weapons[SLOT_AMMO]; // base delay int delay = 240; if (PRange != nullptr && PRange->getDamage() != 0) { delay += ((PRange->getDelay() * 60) / 1000); } if (PAmmo != nullptr && PAmmo->isThrowing()) { // this is a throwing weapon delay += ((PAmmo->getDelay() * 60) / 1000); } delay = (((delay - getMod(MOD_RANGED_DELAY)) * 1000) / 110); //apply haste and delay reductions that don't affect tp if (!tp) { delay = delay * ((float)(100 + getMod(MOD_RANGED_DELAYP)) / 100); } else { if (PAmmo != nullptr && PAmmo->getDamage() != 0 && !PAmmo->isThrowing()) { delay += ((PAmmo->getDelay() * 60) / 1000); } } return delay; }
void StartFishing(CCharEntity* PChar) { if (PChar->animation != ANIMATION_NONE) { PChar->pushPacket(new CMessageSystemPacket(0,0,142)); PChar->pushPacket(new CReleasePacket(PChar,RELEASE_FISHING)); return; } uint16 MessageOffset = GetMessageOffset(PChar->getZone()); if (MessageOffset == 0) { ShowWarning(CL_YELLOW"Player wants to fish in %s\n" CL_RESET, PChar->loc.zone->GetName()); PChar->pushPacket(new CReleasePacket(PChar,RELEASE_FISHING)); return; } CItemWeapon* WeaponItem = nullptr; WeaponItem = (CItemWeapon*)PChar->getEquip(SLOT_RANGED); if ((WeaponItem == nullptr) || !(WeaponItem->isType(ITEM_WEAPON)) || (WeaponItem->getSkillType() != SKILL_FSH)) { // сообщение: "You can't fish without a rod in your hands" PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x01)); PChar->pushPacket(new CReleasePacket(PChar,RELEASE_FISHING)); return; } WeaponItem = (CItemWeapon*)PChar->getEquip(SLOT_AMMO); if ((WeaponItem == nullptr) || !(WeaponItem->isType(ITEM_WEAPON)) || (WeaponItem->getSkillType() != SKILL_FSH)) { // сообщение: "You can't fish without bait on the hook" PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x02)); PChar->pushPacket(new CReleasePacket(PChar,RELEASE_FISHING)); return; } PChar->animation = ANIMATION_FISHING_START; PChar->updatemask |= UPDATE_HP; PChar->pushPacket(new CCharUpdatePacket(PChar)); PChar->pushPacket(new CCharSyncPacket(PChar)); }
void CLatentEffectContainer::CheckLatentsWeaponBreak(uint8 slot) { for (uint16 i = 0; i < m_LatentEffectList.size(); ++i) { if( m_LatentEffectList.at(i)->GetConditionsID() == LATENT_WEAPON_BROKEN && m_LatentEffectList.at(i)->GetConditionsValue() == slot) { CItemWeapon* PWeaponMain = (m_POwner->equip[slot] != 0) ? (CItemWeapon*)(m_POwner->getStorage(LOC_INVENTORY)->GetItem(m_POwner->equip[slot])) : NULL; if( PWeaponMain && m_POwner->unlockedWeapons[PWeaponMain->getUnlockId()-1].unlocked && m_LatentEffectList.at(i)->GetSlot() == slot ) { m_LatentEffectList.at(i)->Activate(); } } } }
void CLatentEffectContainer::CheckLatentsWeaponBreak(uint8 slot) { for (uint16 i = 0; i < m_LatentEffectList.size(); ++i) { if( m_LatentEffectList.at(i)->GetConditionsID() == LATENT_WEAPON_BROKEN && m_LatentEffectList.at(i)->GetConditionsValue() == slot) { CItemWeapon* PWeaponMain = (CItemWeapon*)m_POwner->getEquip((SLOTTYPE)slot); if( PWeaponMain && m_POwner->unlockedWeapons[PWeaponMain->getUnlockId()-1].unlocked && m_LatentEffectList.at(i)->GetSlot() == slot ) { m_LatentEffectList.at(i)->Activate(); } } } }
/************************************************************************ * * * Creates a Daken throw. * * * ************************************************************************/ void CAttackRound::CreateDakenAttack() { if (m_attacker->objtype == TYPE_PC) { CItemWeapon* PAmmo = m_attacker->m_Weapons[SLOT_AMMO]; if (PAmmo && PAmmo->isShuriken()) { uint16 daken = m_attacker->getMod(Mod::DAKEN); if (dsprand::GetRandomNumber(100) < daken) { AddAttackSwing(PHYSICAL_ATTACK_TYPE::DAKEN, RIGHTATTACK, 1); } } } }
int16 CBattleEntity::GetAmmoDelay(bool tp) { CItemWeapon* PAmmo = (CItemWeapon*)m_Weapons[SLOT_AMMO]; int delay = 240; if (PAmmo != nullptr && PAmmo->getDamage() != 0) { delay += ((PAmmo->getDelay() * 60) / 1000); } delay = (((delay - getMod(MOD_RANGED_DELAY)) * 1000) / 110); //don't think delay reduction affects cooldown time //if (!tp) //{ // delay = delay * ((float)(100 + getMod(MOD_RANGED_DELAYP))/100); //} return delay; }
bool CLatentEffect::Deactivate() { if (IsActivated()) { //remove the modifier from weapon, not player if (GetModValue() == Mod::ADDITIONAL_EFFECT || GetModValue() == Mod::DMG) { CCharEntity* PChar = (CCharEntity*)m_POwner; CItemWeapon* weapon = (CItemWeapon*)PChar->getEquip((SLOTTYPE)GetSlot()); int16 modPower = GetModPower(); if (weapon != nullptr && (weapon->isType(ITEM_ARMOR) || weapon->isType(ITEM_WEAPON))) { if (GetModValue() == Mod::ADDITIONAL_EFFECT) { for (uint8 i = 0; i < weapon->modList.size(); ++i) { //ensure the additional effect is fully removed from the weapon if (weapon->modList.at(i).getModID() == Mod::ADDITIONAL_EFFECT) { weapon->modList.at(i).setModAmount(0); } } } else { weapon->addModifier(CModifier(GetModValue(), -modPower)); } } } else { m_POwner->delModifier(m_ModValue, m_ModPower); } m_Activated = false; //printf("LATENT DEACTIVATED: %d\n", m_ModValue); return true; } return false; }
void CMagicState::CharAfterFinish() { if(m_PEntity->objtype != TYPE_PC) { return; } CCharEntity* PChar = (CCharEntity*)m_PEntity; charutils::RemoveStratagems(PChar, m_PSpell); charutils::UpdateHealth(PChar); // only skill up if the effect landed if(m_PSpell->tookEffect()){ charutils::TrySkillUP(PChar, (SKILLTYPE)m_PSpell->getSkillType(), m_PTarget->GetMLevel()); if (m_PSpell->getSkillType() == SKILL_SNG) { CItemWeapon* PItem = (CItemWeapon*)PChar->getEquip(SLOT_RANGED); if (PItem && PItem->isType(ITEM_ARMOR)) { SKILLTYPE Skilltype = (SKILLTYPE)PItem->getSkillType(); if (Skilltype == SKILL_STR || Skilltype == SKILL_WND || Skilltype == SKILL_SNG) { charutils::TrySkillUP(PChar, Skilltype, m_PTarget->GetMLevel()); } } } } PChar->pushPacket(new CCharUpdatePacket(PChar)); // make wyvern use breath if(PChar->PPet!=NULL && ((CPetEntity*)PChar->PPet)->getPetType() == PETTYPE_WYVERN) { ((CAIPetDummy*)PChar->PPet->PBattleAI)->m_MasterCommand = MASTERCOMMAND_HEALING_BREATH; PChar->PPet->PBattleAI->SetCurrentAction(ACTION_MOBABILITY_START); } SetHiPCLvl(m_PTarget, PChar->GetMLevel()); }
void CLatentEffect::Activate() { if( !IsActivated() ) { //additional effect/dmg latents add mod to weapon, not player if (GetModValue() == MOD_ADDITIONAL_EFFECT || GetModValue() == MOD_DMG) { CCharEntity* PChar = (CCharEntity*)m_POwner; CItemWeapon* weapon = (CItemWeapon*)PChar->getEquip((SLOTTYPE)GetSlot()); weapon->addModifier(new CModifier(GetModValue(), GetModPower())); } else { m_POwner->addModifier(m_ModValue, m_ModPower); } m_Activated = true; //printf("LATENT ACTIVATED: %d, Current value: %d\n", m_ModValue, m_POwner->getMod(m_ModValue)); } }
bool LureLoss(CCharEntity* PChar, bool RemoveFly) { CItemWeapon* PLure = (CItemWeapon*)PChar->getEquip(SLOT_AMMO); DSP_DEBUG_BREAK_IF(PLure == nullptr); DSP_DEBUG_BREAK_IF(PLure->isType(ITEM_WEAPON) == false); DSP_DEBUG_BREAK_IF(PLure->getSkillType() != SKILL_FSH); if (!RemoveFly && ( PLure->getStackSize() == 1)) { return false; } if (PLure->getQuantity() == 1) { charutils::EquipItem(PChar, 0, PChar->equip[SLOT_AMMO], LOC_INVENTORY); } charutils::UpdateItem(PChar, PLure->getLocationID(), PLure->getSlotID(), -1); PChar->pushPacket(new CInventoryFinishPacket()); return true; }
bool CheckFisherLuck(CCharEntity* PChar) { if (PChar->UContainer->GetType() != UCONTAINER_EMPTY) { ShowDebug(CL_CYAN"Player cannot fish! UContainer is not empty\n" CL_RESET); return false; } CItemFish* PFish = nullptr; CItemWeapon* WeaponItem = nullptr; WeaponItem = (CItemWeapon*)PChar->getEquip(SLOT_RANGED); DSP_DEBUG_BREAK_IF(WeaponItem == nullptr); DSP_DEBUG_BREAK_IF(WeaponItem->isType(ITEM_WEAPON) == false); DSP_DEBUG_BREAK_IF(WeaponItem->getSkillType() != SKILL_FSH); uint16 RodID = WeaponItem->getID(); WeaponItem = (CItemWeapon*)PChar->getEquip(SLOT_AMMO); DSP_DEBUG_BREAK_IF(WeaponItem == nullptr); DSP_DEBUG_BREAK_IF(WeaponItem->isType(ITEM_WEAPON) == false); DSP_DEBUG_BREAK_IF(WeaponItem->getSkillType() != SKILL_FSH); uint16 LureID = WeaponItem->getID(); int32 FishingChance = WELL512::irand()%100; if (FishingChance <= 20) { const int8* Query = "SELECT " "fish.fishid," // 0 "fish.max," // 1 "fish.watertype," // 2 "fish.size," // 3 "fish.stamina," // 4 "fish.log," // 5 "fish.quest," // 6 "rod.flag " // 7 "FROM fishing_zone AS zone " "INNER JOIN fishing_rod AS rod USING (fishid) " "INNER JOIN fishing_lure AS lure USING (fishid) " "INNER JOIN fishing_fish AS fish USING (fishid) " "WHERE zone.zoneid = %u AND rod.rodid = %u AND lure.lureid = %u AND lure.luck = 0"; int32 ret = Sql_Query(SqlHandle, Query, PChar->getZone(), RodID, LureID); if( ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0) { while(Sql_NextRow(SqlHandle) == SQL_SUCCESS) { // ловля предметов, необходимых для поисков uint8 logid = (uint8)Sql_GetIntData(SqlHandle,5); uint8 quest = (uint8)Sql_GetIntData(SqlHandle,6); if(logid < MAX_QUESTAREA && quest < MAX_QUESTID) { uint8 current = PChar->m_questLog[logid].current [quest/8] & (1 << (quest % 8)); uint8 complete = PChar->m_questLog[logid].complete[quest/8] & (1 << (quest % 8)); if (complete == 0 && current != 0) { PFish = new CItemFish(*itemutils::GetItemPointer(Sql_GetIntData(SqlHandle,0))); PChar->UContainer->SetType(UCONTAINER_FISHING); PChar->UContainer->SetItem(0, PFish); break; } } // TODO: ловля простых предметов } } } else { const int8* Query = "SELECT " "fish.fishid," // 0 "fish.min," // 1 "fish.max," // 2 "fish.size," // 3 "fish.stamina," // 4 "fish.watertype," // 5 "rod.flag, " // 6 "lure.luck " // 7 "FROM fishing_zone AS zone " "INNER JOIN fishing_rod AS rod USING (fishid) " "INNER JOIN fishing_lure AS lure USING (fishid) " "INNER JOIN fishing_fish AS fish USING (fishid) " "WHERE zone.zoneid = %u AND rod.rodid = %u AND lure.lureid = %u AND lure.luck != 0 " "ORDER BY luck"; int32 ret = Sql_Query(SqlHandle, Query, PChar->getZone(), RodID, LureID); if( ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0) { int32 FisherLuck = 0; int32 FishingChance = WELL512::irand()%1000; while(Sql_NextRow(SqlHandle) == SQL_SUCCESS) { FisherLuck += Sql_GetIntData(SqlHandle,7); if (FishingChance <= FisherLuck) { PFish = new CItemFish(*itemutils::GetItemPointer(Sql_GetIntData(SqlHandle,0))); PChar->UContainer->SetType(UCONTAINER_FISHING); PChar->UContainer->SetItem(0, PFish); break; } } } } return (PFish != nullptr); }
void CLatentEffectContainer::CheckLatentsEquip(uint8 slot) { for (uint16 i = 0; i < m_LatentEffectList.size(); ++i) { if (m_LatentEffectList.at(i)->GetSlot() == slot) { switch(m_LatentEffectList.at(i)->GetConditionsID()) { case LATENT_HP_UNDER_PERCENT: if ((m_POwner->health.hp != NULL && m_POwner->health.maxhp != NULL) && ((float)m_POwner->health.hp / m_POwner->health.maxhp )*100 <= m_LatentEffectList.at(i)->GetConditionsValue()) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_HP_OVER_PERCENT: if ((m_POwner->health.hp != NULL && m_POwner->health.maxhp != NULL) && ((float)m_POwner->health.hp / m_POwner->health.maxhp )*100 >= m_LatentEffectList.at(i)->GetConditionsValue()) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_HP_UNDER_TP_UNDER_100: if ((m_POwner->health.hp != NULL && m_POwner->health.maxhp != NULL) && ((float)m_POwner->health.hp / m_POwner->health.maxhp )*100 <= m_LatentEffectList.at(i)->GetConditionsValue() && m_POwner->health.tp < 100) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_HP_OVER_TP_UNDER_100: if ((m_POwner->health.hp != NULL && m_POwner->health.maxhp != NULL) && ((float)m_POwner->health.hp / m_POwner->health.maxhp )*100 >= m_LatentEffectList.at(i)->GetConditionsValue() && m_POwner->health.tp < 100) { m_POwner->addHP(4); m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_MP_UNDER_PERCENT: if ((m_POwner->health.mp != NULL && m_POwner->health.maxmp != NULL) && (float)(m_POwner->health.mp / m_POwner->health.maxmp)*100 <= m_LatentEffectList.at(i)->GetConditionsValue()) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_MP_UNDER: if (m_POwner->health.mp <= m_LatentEffectList.at(i)->GetConditionsValue()) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_TP_UNDER: if (m_POwner->health.tp < m_LatentEffectList.at(i)->GetConditionsValue()) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_TP_OVER: if (m_POwner->health.tp > m_LatentEffectList.at(i)->GetConditionsValue()) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_PET_ID: CheckLatentsPetType((PETTYPE)m_LatentEffectList.at(i)->GetConditionsValue()); break; case LATENT_SUBJOB: if( m_POwner->GetSJob() == m_LatentEffectList.at(i)->GetConditionsValue()) { m_LatentEffectList.at(i)->Activate(); } break; case LATENT_WEAPON_BROKEN: { CItemWeapon* PWeaponMain = (m_POwner->equip[SLOT_MAIN] != 0) ? (CItemWeapon*)(m_POwner->getStorage(LOC_INVENTORY)->GetItem(m_POwner->equip[SLOT_MAIN])) : NULL; CItemWeapon* PWeaponSub = (m_POwner->equip[SLOT_SUB] != 0) ? (CItemWeapon*)(m_POwner->getStorage(LOC_INVENTORY)->GetItem(m_POwner->equip[SLOT_SUB])) : NULL; CItemWeapon* PWeaponRanged = (m_POwner->equip[SLOT_RANGED] != 0) ? (CItemWeapon*)(m_POwner->getStorage(LOC_INVENTORY)->GetItem(m_POwner->equip[SLOT_RANGED])) : NULL; if( PWeaponMain && m_POwner->unlockedWeapons[PWeaponMain->getUnlockId()-1].unlocked && m_LatentEffectList.at(i)->GetSlot() == SLOT_MAIN ) { m_LatentEffectList.at(i)->Activate(); } if( PWeaponSub && m_POwner->unlockedWeapons[PWeaponSub->getUnlockId()-1].unlocked && m_LatentEffectList.at(i)->GetSlot() == SLOT_SUB) { m_LatentEffectList.at(i)->Activate(); } if( PWeaponRanged && m_POwner->unlockedWeapons[PWeaponRanged->getUnlockId()-1].unlocked && m_LatentEffectList.at(i)->GetSlot() == SLOT_RANGED) { m_LatentEffectList.at(i)->Activate(); } break; } case LATENT_ZONE: if( m_LatentEffectList.at(i)->GetConditionsValue() == m_POwner->getZone()) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_IN_DYNAMIS: if (m_POwner->isInDynamis()) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_FOOD_ACTIVE: case LATENT_NO_FOOD_ACTIVE: CheckLatentsFoodEffect(); break; case LATENT_STATUS_EFFECT_ACTIVE: CheckLatentsStatusEffect(); break; case LATENT_JOB_IN_PARTY: CheckLatentsPartyJobs(); break; case LATENT_PARTY_MEMBERS: case LATENT_PARTY_MEMBERS_IN_ZONE: { if(m_POwner->PParty != NULL) CheckLatentsPartyMembers(m_POwner->PParty->members.size()); } break; case LATENT_AVATAR_IN_PARTY: CheckLatentsPartyAvatar(); break; case LATENT_MOON_FIRST_QUARTER: CheckLatentsMoonPhase(); break; case LATENT_TIME_OF_DAY: CheckLatentsDay(); break; case LATENT_HOUR_OF_DAY: CheckLatentsHours(); break; case LATENT_FIRESDAY: case LATENT_EARTHSDAY: case LATENT_WATERSDAY: case LATENT_WINDSDAY: case LATENT_DARKSDAY: case LATENT_ICEDAY: case LATENT_LIGHTNINGSDAY: case LATENT_LIGHTSDAY: CheckLatentsWeekDay(); break; case LATENT_JOB_LEVEL_EVEN: if (m_POwner->GetMLevel() % 2 == 0) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_JOB_LEVEL_ODD: if (m_POwner->GetMLevel() % 2 == 1) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_JOB_MULTIPLE_5: if (m_POwner->GetMLevel() % 5 == 0) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_JOB_MULTIPLE_10: if (m_POwner->GetMLevel() % 10 == 0) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_JOB_MULTIPLE_13_NIGHT: { TIMETYPE VanadielTOTD = CVanaTime::getInstance()->SyncTime(); if (m_POwner->GetMLevel() % 13 == 0 && (VanadielTOTD == TIME_NIGHT)) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } } break; case LATENT_JOB_LEVEL_BELOW: if (m_POwner->GetMLevel() < m_LatentEffectList.at(i)->GetConditionsValue()) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_JOB_LEVEL_ABOVE: if (m_POwner->GetMLevel() >= m_LatentEffectList.at(i)->GetConditionsValue()) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_WEATHER_ELEMENT: if (zoneutils::GetZone(m_POwner->getZone())->GetWeatherElement() == m_LatentEffectList.at(i)->GetConditionsValue()) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_NATION_CONTROL: CheckLatentsZone(); break; default: ShowWarning("Latent ID %d unhandled in CheckLatentsEquip\n", m_LatentEffectList.at(i)->GetConditionsID()); break; } } } m_POwner->UpdateHealth(); }
bool CRangeState::CanUseRangedAttack(CBattleEntity* PTarget) { if (!PTarget) { m_errorMsg = std::make_unique<CMessageBasicPacket>(m_PEntity, m_PEntity, 0, 0, MSGBASIC_CANNOT_ATTACK_TARGET); return false; } CItemWeapon* PRanged = (CItemWeapon*)m_PEntity->getEquip(SLOT_RANGED); CItemWeapon* PAmmo = (CItemWeapon*)m_PEntity->getEquip(SLOT_AMMO); if (!(PRanged && PRanged->isType(ITEM_WEAPON) || PAmmo && PAmmo->isThrowing())) { m_errorMsg = std::make_unique<CMessageBasicPacket>(m_PEntity, m_PEntity, 0, 0, MSGBASIC_NO_RANGED_WEAPON); return false; } auto SkillType = PRanged ? PRanged->getSkillType() : PAmmo->getSkillType(); switch (SkillType) { case SKILL_THR: { // remove barrage, doesn't work here m_PEntity->StatusEffectContainer->DelStatusEffect(EFFECT_BARRAGE); break; } case SKILL_ARC: case SKILL_MRK: { PRanged = (CItemWeapon*)m_PEntity->getEquip(SLOT_AMMO); if (PRanged != nullptr && PRanged->isType(ITEM_WEAPON)) { break; } } default: { m_errorMsg = std::make_unique<CMessageBasicPacket>(m_PEntity, m_PEntity, 0, 0, MSGBASIC_NO_RANGED_WEAPON); return false; } } if (!isFaceing(m_PEntity->loc.p, PTarget->loc.p, 40)) { m_errorMsg = std::make_unique<CMessageBasicPacket>(m_PEntity, PTarget, 0, 0, MSGBASIC_CANNOT_SEE); return false; } if (distance(m_PEntity->loc.p, PTarget->loc.p) > 25) { m_errorMsg = std::make_unique<CMessageBasicPacket>(m_PEntity, 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, 0, 0, MSGBASIC_CANNOT_PERFORM_ACTION); return false; } return true; }
void CLatentEffectContainer::CheckLatentsEquip(uint8 slot) { for (uint16 i = 0; i < m_LatentEffectList.size(); ++i) { if (m_LatentEffectList.at(i)->GetSlot() == slot) { switch(m_LatentEffectList.at(i)->GetConditionsID()) { case LATENT_HP_UNDER_PERCENT: if (((float)m_POwner->health.hp / m_POwner->health.maxhp )*100 <= m_LatentEffectList.at(i)->GetConditionsValue()) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_HP_OVER_PERCENT: if (((float)m_POwner->health.hp / m_POwner->health.maxhp )*100 >= m_LatentEffectList.at(i)->GetConditionsValue()) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_HP_UNDER_TP_UNDER_100: if (((float)m_POwner->health.hp / m_POwner->health.maxhp )*100 <= m_LatentEffectList.at(i)->GetConditionsValue() && m_POwner->health.tp < 100) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_HP_OVER_TP_UNDER_100: if (((float)m_POwner->health.hp / m_POwner->health.maxhp )*100 >= m_LatentEffectList.at(i)->GetConditionsValue() && m_POwner->health.tp < 100) { m_POwner->addHP(4); m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_TP_UNDER_100: if (m_POwner->health.tp < 100) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_TP_OVER_100: if (m_POwner->health.tp >= 100) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_SUBJOB: if( m_POwner->GetSJob() == m_LatentEffectList.at(i)->GetConditionsValue()) { m_LatentEffectList.at(i)->Activate(); } break; case LATENT_WEAPON_BROKEN: { CItemWeapon* PWeaponMain = (m_POwner->equip[SLOT_MAIN] != 0) ? (CItemWeapon*)(m_POwner->getStorage(LOC_INVENTORY)->GetItem(m_POwner->equip[SLOT_MAIN])) : NULL; CItemWeapon* PWeaponSub = (m_POwner->equip[SLOT_SUB] != 0) ? (CItemWeapon*)(m_POwner->getStorage(LOC_INVENTORY)->GetItem(m_POwner->equip[SLOT_SUB])) : NULL; CItemWeapon* PWeaponRanged = (m_POwner->equip[SLOT_RANGED] != 0) ? (CItemWeapon*)(m_POwner->getStorage(LOC_INVENTORY)->GetItem(m_POwner->equip[SLOT_RANGED])) : NULL; if( PWeaponMain && m_POwner->unlockedWeapons[PWeaponMain->getUnlockId()-1].unlocked && m_LatentEffectList.at(i)->GetSlot() == SLOT_MAIN ) { m_LatentEffectList.at(i)->Activate(); } if( PWeaponSub && m_POwner->unlockedWeapons[PWeaponSub->getUnlockId()-1].unlocked && m_LatentEffectList.at(i)->GetSlot() == SLOT_SUB) { m_LatentEffectList.at(i)->Activate(); } if( PWeaponRanged && m_POwner->unlockedWeapons[PWeaponRanged->getUnlockId()-1].unlocked && m_LatentEffectList.at(i)->GetSlot() == SLOT_RANGED) { m_LatentEffectList.at(i)->Activate(); } break; } case LATENT_ZONE: if( m_LatentEffectList.at(i)->GetConditionsValue() == m_POwner->getZone()) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; case LATENT_IN_DYNAMIS: if (m_POwner->isInDynamis()) { m_LatentEffectList.at(i)->Activate(); } else { m_LatentEffectList.at(i)->Deactivate(); } break; } } } }
bool CheckFisherLuck(CCharEntity* PChar) { if (PChar->UContainer->GetType() != UCONTAINER_EMPTY) { ShowDebug(CL_CYAN"Player cannot fish! UContainer is not empty\n" CL_RESET); return false; } CItemFish* PFish = NULL; CItemWeapon* WeaponItem = NULL; WeaponItem = (CItemWeapon*)PChar->getStorage(LOC_INVENTORY)->GetItem(PChar->equip[SLOT_RANGED]); DSP_DEBUG_BREAK_IF(WeaponItem == NULL); DSP_DEBUG_BREAK_IF(WeaponItem->isType(ITEM_WEAPON) == false); DSP_DEBUG_BREAK_IF(WeaponItem->getSkillType() != SKILL_FSH); uint16 RodID = WeaponItem->getID(); WeaponItem = (CItemWeapon*)PChar->getStorage(LOC_INVENTORY)->GetItem(PChar->equip[SLOT_AMMO]); DSP_DEBUG_BREAK_IF(WeaponItem == NULL); DSP_DEBUG_BREAK_IF(WeaponItem->isType(ITEM_WEAPON) == false); DSP_DEBUG_BREAK_IF(WeaponItem->getSkillType() != SKILL_FSH); uint16 LureID = WeaponItem->getID(); int FishingChance = rand() % 100; int ListID = GridList(PChar); if (ListID == 0) { ShowDebug(CL_CYAN"Fish list not found for Zone: %u \n" CL_RESET, PChar->getZone()); } if (ListID > 0 && FishingChance <= 50) { const int8* Query = "SELECT ListID, EntityID \ FROM fishing_list \ WHERE ListID = %u \ ORDER BY ListID ASC"; int32 ret = Sql_Query(SqlHandle, Query, ListID); int RC = 0; // this will pick a random number from range 1 to max record count int RID = rand() % Sql_NumRows(SqlHandle) + 1; if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0) { while (Sql_NextRow(SqlHandle) == SQL_SUCCESS) { RC = RC + 1; uint32 EntityID = Sql_GetIntData(SqlHandle, 1); if (RC == RID) { // Gil if (EntityID == 0x0000FFFF) { // do not change this item number this is a place holder ID for gil PFish = new CItemFish(*itemutils::GetItemPointer(14117)); PChar->UContainer->SetType(UCONTAINER_FISHING); PChar->UContainer->SetItem(0, PFish); catchtype[0] = 2; break; } // Monster if (EntityID == 0x0001046A) { GetMobInfo(PChar); if (IsSpawned(mobid[0]) == false && mobid[0] > 0) { // do not change this item number this is a place holder ID for mobs PFish = new CItemFish(*itemutils::GetItemPointer(14117)); PChar->UContainer->SetType(UCONTAINER_FISHING); PChar->UContainer->SetItem(0, PFish); break; } } if (EntityID != 0x0000FFFF || EntityID != 0x0001046A) { // get fish or item for returned record if its not a monster or gil GetOtherInfo(EntityID); // Fish if (catchtype[0] == 0) { // will create a fish entity if the bait can be used to catch the fish if (BaitCheck(LureID, EntityID) == true) { PFish = new CItemFish(*itemutils::GetItemPointer(EntityID)); PChar->UContainer->SetType(UCONTAINER_FISHING); PChar->UContainer->SetItem(0, PFish); break; } } // Item if (catchtype[0] == 1) { PFish = new CItemFish(*itemutils::GetItemPointer(EntityID)); PChar->UContainer->SetType(UCONTAINER_FISHING); PChar->UContainer->SetItem(0, PFish); break; } } } if(RC == Sql_NumRows(SqlHandle)) { break; } } } } return (PFish != NULL); }
void CPlayerController::WeaponSkill(uint16 targid, uint16 wsid) { auto PChar = static_cast<CCharEntity*>(POwner); if (PChar->PAI->CanChangeState()) { //#TODO: put all this in weaponskill_state CWeaponSkill* PWeaponSkill = battleutils::GetWeaponSkill(wsid); if (PWeaponSkill && !charutils::hasWeaponSkill(PChar, PWeaponSkill->getID())) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_CANNOT_USE_WS)); return; } if (PChar->StatusEffectContainer->HasStatusEffect(EFFECT_AMNESIA)) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_CANNOT_USE_ANY_WS)); return; } if (PChar->health.tp < 1000) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_NOT_ENOUGH_TP)); return; } if (PWeaponSkill->getType() == SKILL_ARC || PWeaponSkill->getType() == SKILL_MRK) { CItemWeapon* PItem = (CItemWeapon*)PChar->getEquip(SLOT_AMMO); // before allowing ranged weapon skill... if (PItem == nullptr || !(PItem->isType(ITEM_WEAPON)) || !PChar->m_Weapons[SLOT_AMMO]->isRanged() || !PChar->m_Weapons[SLOT_RANGED]->isRanged() || PChar->equip[SLOT_AMMO] == 0) { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_NO_RANGED_WEAPON)); return; } } std::unique_ptr<CMessageBasicPacket> errMsg; auto PTarget = PChar->IsValidTarget(targid, battleutils::isValidSelfTargetWeaponskill(wsid) ? TARGET_SELF : TARGET_ENEMY, errMsg); if (PTarget) { if (!isFaceing(PChar->loc.p, PTarget->loc.p, 40)) { PChar->pushPacket(new CMessageBasicPacket(PChar, PTarget, 0, 0, MSGBASIC_CANNOT_SEE)); return; } CController::WeaponSkill(targid, wsid); } else if (errMsg) { PChar->pushPacket(std::move(errMsg)); } } else { PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, 0, 0, MSGBASIC_UNABLE_TO_USE_WS)); } }