void FishingAction(CCharEntity* PChar, FISHACTION action, uint16 stamina) { uint16 MessageOffset = GetMessageOffset(PChar->getZone()); switch (action) { case FISHACTION_CHECK: { if (CheckFisherLuck(PChar)) { // send messages if (catchtype[0] >= 0) { PChar->animation = ANIMATION_FISHING_FISH; if (catchtype[0] == 0) { if (catchsize[0] == 1) { // Large Fish: "Something caught the hook!!!" PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x32)); } else { // Small Fish: "Something caught the hook!" PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x08)); } } if (catchtype[0] >= 1 && catchtype[0] < 3) { // Non-fish targets: "You feel something pulling at your line." PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x33)); } if (catchtype[0] == 3) { // Monster: "Something clamps onto your line ferociously!" PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x34)); } PChar->pushPacket(new CFishingPacket(catchtype[0], catchsize[0])); } } else { // Message: "You didn't catch anything." PChar->animation = ANIMATION_FISHING_STOP; PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x04)); } } break; case FISHACTION_FINISH: { // you have a 15% change to break the rod, Line or loose a catch while reeling it in. if (rand() % 100 <= 15 && catchtype[0] <= 1 && stamina == 0) { DSP_DEBUG_BREAK_IF(PChar->UContainer->GetType() != UCONTAINER_FISHING); DSP_DEBUG_BREAK_IF(PChar->UContainer->GetItem(0) == NULL); CItem* PFish = PChar->UContainer->GetItem(0); int messageID = Breakage(PChar, PFish->getID()); if (messageID == 1) { // Message: "Your rod breaks. Whatever caught the hook was pretty big" PChar->animation = ANIMATION_FISHING_ROD_BREAK; PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x11)); } if (messageID == 2) { // Message: "Your line breaks!" PChar->animation = ANIMATION_FISHING_LINE_BREAK; PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x06)); } if (messageID == 3) { // Message: "You lost your catch Whatever caught thr hook was too small to catch with this rod" PChar->animation = ANIMATION_FISHING_LINE_BREAK; PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x13)); } PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x09)); PChar->animation = ANIMATION_FISHING_STOP; PChar->UContainer->Clean(); catchlevel[0] = 0; break; } if (stamina == 0) { DSP_DEBUG_BREAK_IF(PChar->UContainer->GetType() != UCONTAINER_FISHING); DSP_DEBUG_BREAK_IF(PChar->UContainer->GetItem(0) == NULL); CItem* PFish = PChar->UContainer->GetItem(0); if (catchtype[0] == 3) { PChar->animation = ANIMATION_FISHING_MONSTER; } else { PChar->animation = ANIMATION_FISHING_CAUGHT; } if (catchtype[0] == 3) { // Message: "You caught a monster" PChar->loc.zone->PushPacket(PChar, CHAR_INRANGE_SELF, new CCaughtFishPacket(PChar, 0x01, mobid[0], MessageOffset + 0x05)); SpawnCatch(PChar, mobid[0]); } if (catchtype[0] <= 2) { if (catchtype[0] == 2) { int GilChance = rand() % 100 ; if (GilChance <= 10) { // Give 100 Gil if gillchance <= 10% charutils::UpdateItem(PChar, LOC_INVENTORY, 0, 100); PChar->loc.zone->PushPacket(PChar, CHAR_INRANGE_SELF, new CCaughtFishPacket(PChar, 0x01, 0x0000FFFF, MessageOffset + 0x27)); PChar->loc.zone->PushPacket(PChar, CHAR_INRANGE_SELF, new CCaughtFishPacket(PChar, 0x64, 0x0000FFFF, MessageOffset + 0x26)); } else { // give 1 Gil charutils::UpdateItem(PChar, LOC_INVENTORY, 0, 1); PChar->loc.zone->PushPacket(PChar, CHAR_INRANGE_SELF, new CCaughtFishPacket(PChar, 0x01, 0x0000FFFF, MessageOffset + 0x27)); PChar->loc.zone->PushPacket(PChar, CHAR_INRANGE_SELF, new CCaughtFishPacket(PChar, 0x01, 0x0000FFFF, MessageOffset + 0x26)); } } else { if (CanSkillUp(PChar) == 0) { // Message: " You lost your catch due to lack of skill." PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x14)); } else { // if type is 0:fish or 1:item add item to invintory charutils::AddItem(PChar, LOC_INVENTORY, PFish->getID(), 1); PChar->loc.zone->PushPacket(PChar, CHAR_INRANGE_SELF, new CCaughtFishPacket(PChar, 0x01, PFish->getID(), MessageOffset + 0x27)); } } } if (PFish->isType(ITEM_USABLE)) { LureLoss(PChar, false); } delete PFish; } else if (stamina <= 0x64) { // Message: "Your line breaks!" PChar->animation = ANIMATION_FISHING_LINE_BREAK; LureLoss(PChar, true); PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x06)); } else if (stamina <= 0x100) { // Message: "You give up!" PChar->animation = ANIMATION_FISHING_STOP; if (PChar->UContainer->GetType() == UCONTAINER_FISHING && LureLoss(PChar, false)) { PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x24)); } else { PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x25)); } } else { // Message: "You lost your catch!" PChar->animation = ANIMATION_FISHING_STOP; LureLoss(PChar, false); PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x09)); } PChar->UContainer->Clean(); } break; case FISHACTION_WARNING: { // Message: "You don't know how much longer you can keep this one on the line..." PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x28)); return; } break; case FISHACTION_END: { // skillup PChar->animation = ANIMATION_NONE; if (catchtype[0] == 0 && catchlevel[0] >= 1 && CanSkillUp(PChar) == 1) { uint8 skillRank = PChar->RealSkills.rank[SKILL_FSH]; uint16 maxSkill = (skillRank + 1) * 100; int32 charSkill = PChar->RealSkills.skill[SKILL_FSH]; int skillAmount = rand() % 5; if (skillAmount > 0) { if ((skillAmount + charSkill) > maxSkill) { skillAmount = maxSkill - charSkill; } if (skillAmount > 0) { PChar->RealSkills.skill[SKILL_FSH] += skillAmount; PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, SKILL_FSH, skillAmount, 38)); charutils::SaveCharSkills(PChar, SKILL_FSH); } if ((charSkill / 10) < (charSkill + skillAmount) / 10) { PChar->WorkingSkills.skill[SKILL_FSH] += 0x20; PChar->pushPacket(new CCharSkillsPacket(PChar)); PChar->pushPacket(new CMessageBasicPacket(PChar, PChar, SKILL_FSH, (charSkill + skillAmount) / 10, 53)); } } catchlevel[0] = 0; } } break; } PChar->status = STATUS_UPDATE; PChar->pushPacket(new CCharUpdatePacket(PChar)); PChar->pushPacket(new CCharSyncPacket(PChar)); }
void FishingAction(CCharEntity* PChar, FISHACTION action, uint16 stamina) { uint16 MessageOffset = GetMessageOffset(PChar->getZone()); switch (action) { case FISHACTION_CHECK: { if (CheckFisherLuck(PChar)) { // сообщение: "Something caught the hook!" PChar->animation = ANIMATION_FISHING_FISH; PChar->updatemask |= UPDATE_HP; PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x08)); PChar->pushPacket(new CFishingPacket()); } else { // сообщение: "You didn't catch anything." PChar->animation = ANIMATION_FISHING_STOP; PChar->updatemask |= UPDATE_HP; PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x04)); } } break; case FISHACTION_FINISH: { if (stamina == 0) { // сообщение: "You caught fish!" DSP_DEBUG_BREAK_IF(PChar->UContainer->GetType() != UCONTAINER_FISHING); DSP_DEBUG_BREAK_IF(PChar->UContainer->GetItem(0) == nullptr); PChar->animation = ANIMATION_FISHING_CAUGHT; PChar->updatemask |= UPDATE_HP; CItem* PFish = PChar->UContainer->GetItem(0); // TODO: анализируем RodFlag charutils::AddItem(PChar, LOC_INVENTORY, PFish->getID(), 1); PChar->loc.zone->PushPacket(PChar, CHAR_INRANGE_SELF, new CCaughtFishPacket(PChar, PFish->getID(), MessageOffset + 0x27)); if (PFish->isType(ITEM_USABLE)) { LureLoss(PChar, false); } delete PFish; } else if (stamina <= 0x64) { // сообщение: "Your line breaks!" PChar->animation = ANIMATION_FISHING_LINE_BREAK; PChar->updatemask |= UPDATE_HP; LureLoss(PChar, true); PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x06)); } else if (stamina <= 0x100) { // сообщение: "You give up!" PChar->animation = ANIMATION_FISHING_STOP; PChar->updatemask |= UPDATE_HP; if (PChar->UContainer->GetType() == UCONTAINER_FISHING && LureLoss(PChar, false)) { PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x24)); } else { PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x25)); } } else { // сообщение: "You lost your catch!" PChar->animation = ANIMATION_FISHING_STOP; PChar->updatemask |= UPDATE_HP; LureLoss(PChar, false); PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x09)); } PChar->UContainer->Clean(); } break; case FISHACTION_WARNING: { // сообщение: "You don't know how much longer you can keep this one on the line..." PChar->pushPacket(new CMessageTextPacket(PChar, MessageOffset + 0x28)); return; } break; case FISHACTION_END: { // skillup PChar->animation = ANIMATION_NONE; PChar->updatemask |= UPDATE_HP; } break; } PChar->pushPacket(new CCharUpdatePacket(PChar)); PChar->pushPacket(new CCharSyncPacket(PChar)); }
// rod break and line break code int Breakage(CCharEntity* PChar, uint16 FishID) { uint8 SlotID = PChar->equip[SLOT_RANGED]; CItem* PRod = PChar->getStorage(LOC_INVENTORY)->GetItem(SlotID); DSP_DEBUG_BREAK_IF(PRod == NULL); int RodBeakType = 0; uint16 BrokenRodID = GetBrokenID(PRod->getID()); if (BrokenRodID == -1) { ShowDebug(CL_CYAN"RodID not found Please check the database: %u \n" CL_RESET); } const int8* Query = "SELECT rodid, fishid, break_type, loose_catch \ FROM fishing_rod_breakage \ WHERE fishid = %u \ ORDER BY rodid ASC"; int32 ret = Sql_Query(SqlHandle, Query, FishID); if (ret != SQL_ERROR && Sql_NumRows(SqlHandle) != 0) { while (Sql_NextRow(SqlHandle) == SQL_SUCCESS) { uint16 ent = Sql_GetIntData(SqlHandle, 0); int32 break_type = Sql_GetIntData(SqlHandle, 2); int32 loose_catch = Sql_GetIntData(SqlHandle, 3); if (PRod->getID() == ent) { if (break_type > 0 && loose_catch > 0) { // 40% chance to break the rod and 60% chance to break the line if (rand() % 100 <= 60) { // break line only RodBeakType = 2; } else { // break rod RodBeakType = 1; } } if (break_type == 1 && loose_catch == 0) { // break rod RodBeakType = 1; } if (break_type == 2 && loose_catch == 0) { // break line RodBeakType = 2; } if (break_type == 0 && loose_catch == 1) { // loose catch RodBeakType = 3; } } } } // RodBeakType 0 = none ( Ebishu & Judges rod is not breakable ) // RodBeakType 1 = rod // RodBeakType 2 = line // RodBeakType 3 = loose catch if (BrokenRodID > 0 && RodBeakType == 1) { // 30% chance to loose your bait / Lure on a rod break if (rand()% + 100 <= 30) { LureLoss(PChar, true); } else { LureLoss(PChar, false); } charutils::EquipItem(PChar, 0, SLOT_RANGED); charutils::UpdateItem(PChar, LOC_INVENTORY, SlotID, -1); charutils::AddItem(PChar, LOC_INVENTORY, BrokenRodID, 1); return 1; } if (RodBeakType == 2) { LureLoss(PChar, true); return 2; } // 20% chance to loose your catch if (RodBeakType == 3 && rand()% + 100 <= 20) { return 3; } return 0; }