From 8e41ae8e04eb05346b0b189cb3eb03d6cf8e5d58 Mon Sep 17 00:00:00 2001 From: WinterSolstice8 <60417494+wintersolstice8@users.noreply.github.com> Date: Thu, 29 Aug 2024 18:35:43 -0600 Subject: [PATCH] [core] Force crit fail on synth if player zones for any reason --- src/map/packet_system.cpp | 12 ------------ src/map/utils/charutils.cpp | 23 +++++++++++++++++++++++ src/map/utils/charutils.h | 2 ++ src/map/zone_entities.cpp | 6 ++++++ 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/src/map/packet_system.cpp b/src/map/packet_system.cpp index db68e6ba88d..c2125fc62d9 100644 --- a/src/map/packet_system.cpp +++ b/src/map/packet_system.cpp @@ -553,18 +553,6 @@ void SmallPacket0x00D(map_session_data_t* const PSession, CCharEntity* const PCh PSession->shuttingDown = 2; _sql->Query("UPDATE char_stats SET zoning = 1 WHERE charid = %u", PChar->id); charutils::CheckEquipLogic(PChar, SCRIPT_CHANGEZONE, PChar->getZone()); - - if (PChar->CraftContainer->getItemsCount() > 0 && PChar->animation == ANIMATION_SYNTH) - { - // NOTE: - // Supposed non-losable items are reportely lost if this condition is met: - // https://ffxiclopedia.fandom.com/wiki/Lu_Shang%27s_Fishing_Rod - // The broken rod can never be lost in a normal failed synth. It will only be lost if the synth is - // interrupted in some way, such as by being attacked or moving to another area (e.g. ship docking). - - ShowWarning("SmallPacket0x00D: %s attempting to zone in the middle of a synth, failing their synth!", PChar->getName()); - synthutils::doSynthFail(PChar); - } } if (PChar->loc.zone != nullptr) diff --git a/src/map/utils/charutils.cpp b/src/map/utils/charutils.cpp index aadd53bd876..267ca99bc51 100644 --- a/src/map/utils/charutils.cpp +++ b/src/map/utils/charutils.cpp @@ -86,6 +86,7 @@ #include "roe.h" #include "spell.h" #include "status_effect_container.h" +#include "trade_container.h" #include "trait.h" #include "treasure_pool.h" #include "unitychat.h" @@ -103,6 +104,7 @@ #include "itemutils.h" #include "petutils.h" #include "puppetutils.h" +#include "synthutils.h" #include "zoneutils.h" /************************************************************************ @@ -6521,6 +6523,12 @@ namespace charutils PChar->resetPetZoningInfo(); } + // If player somehow gets zoned, force crit fail their synth + if (PChar->CraftContainer && PChar->CraftContainer->getItemsCount() > 0) + { + charutils::forceSynthCritFail("SendToZone", PChar); + } + PChar->pushPacket(new CServerIPPacket(PChar, type, ipp)); } @@ -7122,4 +7130,19 @@ namespace charutils return 0; } + void forceSynthCritFail(std::string sourceFunction, CCharEntity* PChar) + { + // NOTE: + // Supposed non-losable items are reportedly lost if this condition is met: + // https://ffxiclopedia.fandom.com/wiki/Lu_Shang%27s_Fishing_Rod + // The broken rod can never be lost in a normal failed synth. It will only be lost if the synth is + // interrupted in some way, such as by being attacked or moving to another area (e.g. ship docking). + + ShowWarning("%s: %s attempting to zone in the middle of a synth, failing their synth!", sourceFunction, PChar->getName()); + PChar->setModifier(Mod::SYNTH_FAIL_RATE, 10000); // Force crit fail + synthutils::doSynthFail(PChar); + + PChar->CraftContainer->Clean(); // Clean to reset m_ItemCount to 0 + } + }; // namespace charutils diff --git a/src/map/utils/charutils.h b/src/map/utils/charutils.h index f02b41c90cc..68644f969ff 100644 --- a/src/map/utils/charutils.h +++ b/src/map/utils/charutils.h @@ -279,6 +279,8 @@ namespace charutils bool hasEntitySpawned(CCharEntity* PChar, CBaseEntity* entity); uint32 getCharIdFromName(std::string const& name); + + void forceSynthCritFail(std::string sourceFunction, CCharEntity* PChar); }; // namespace charutils #endif // _CHARUTILS_H diff --git a/src/map/zone_entities.cpp b/src/map/zone_entities.cpp index cf197aa5f42..062172fc59e 100644 --- a/src/map/zone_entities.cpp +++ b/src/map/zone_entities.cpp @@ -485,6 +485,12 @@ void CZoneEntities::DecreaseZoneCounter(CCharEntity* PChar) } } + // Duplicated from charUtils, it is theoretically possible through d/c magic to hit this block and not sendToZone + if (PChar->CraftContainer && PChar->CraftContainer->getItemsCount() > 0) + { + charutils::forceSynthCritFail("DecreaseZoneCounter", PChar); + } + if (PChar->animation == ANIMATION_SYNTH) { PChar->CraftContainer->setQuantity(0, synthutils::SYNTHESIS_FAIL);