Exemple #1
0
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));
}
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;
}
Exemple #3
0
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());
}
Exemple #4
0
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;
}
Exemple #5
0
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);
}
Exemple #6
0
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;
}
	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);
	}
Exemple #8
0
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));
    }
}