diff --git a/src/api/PlayerMinimal.cpp b/src/api/PlayerMinimal.cpp index c7f5fff1..2bda842b 100644 --- a/src/api/PlayerMinimal.cpp +++ b/src/api/PlayerMinimal.cpp @@ -14,17 +14,11 @@ namespace Sapphire::Api { using namespace Common; // player constructor -PlayerMinimal::PlayerMinimal( void ) : +PlayerMinimal::PlayerMinimal() : m_id( 0 ) { -} - -// deconstructor -PlayerMinimal::~PlayerMinimal( void ) -{ - } // load player from the db @@ -85,76 +79,101 @@ void PlayerMinimal::load( uint32_t charId ) } } - -std::string PlayerMinimal::getLookString() +std::string PlayerMinimal::getInfoJson() { + auto payload = nlohmann::json(); + auto& c = payload["content"]; - auto it = m_lookMap.begin(); + // DisplayName + c.push_back( getName() ); - std::string lookString; - - for( ; it != m_lookMap.end(); ++it ) - { - - std::string s = std::to_string( it->second ); - - lookString += "\"" + s + "\""; - if( it != m_lookMap.end() ) - { - lookString += ","; - } - } - - return lookString.substr( 0, lookString.size() - 1 ); -} - -std::string PlayerMinimal::getModelString() -{ - std::string modelString = "\"" - + std::to_string( m_modelEquip[ 0 ] ) + "\",\"" - + std::to_string( m_modelEquip[ 1 ] ) + "\",\"" - + std::to_string( m_modelEquip[ 2 ] ) + "\",\"" - + std::to_string( m_modelEquip[ 3 ] ) + "\",\"" - + std::to_string( m_modelEquip[ 4 ] ) + "\",\"" - + std::to_string( m_modelEquip[ 5 ] ) + "\",\"" - + std::to_string( m_modelEquip[ 6 ] ) + "\",\"" - + std::to_string( m_modelEquip[ 7 ] ) + "\",\"" - + std::to_string( m_modelEquip[ 8 ] ) + "\",\"" - + std::to_string( m_modelEquip[ 9 ] ) + "\""; - return modelString; -} - -std::string PlayerMinimal::getLevelsString() -{ + // class levels auto levelsArray = nlohmann::json(); - for( int i = 0; i < Common::CLASSJOB_SLOTS; ++i ) { // these must be strings levelsArray.push_back( std::to_string( m_classMap[ i ] ) ); } - return levelsArray.dump(); -} + // ClassLv + c.push_back( levelsArray ); -std::string PlayerMinimal::getInfoJson() -{ - std::string charDetails = "{\"content\":[\"" + std::string( getName() ) + "\"," + - getLevelsString() + "," - "\"0\",\"0\",\"0\",\"" + - std::to_string( getBirthMonth() ) + - "\",\"" + std::to_string( getBirthDay() ) + - "\",\"" + std::to_string( getGuardianDeity() ) + - "\",\"" + std::to_string( m_class ) + - "\",\"0\",\"" + std::to_string( getZoneId() ) + - "\",\"0\"," + - "[" + getLookString() + "]," + - "\"" + std::to_string( m_modelMainWeapon ) + "\",\"" + std::to_string( m_modelSubWeapon ) + "\"," + - "[" + getModelString() + "]," + - "\"1\",\"0\",\"0\",\"0\",\"" + std::to_string( m_equipDisplayFlags ) + - "\",\"0\",\"\",\"0\",\"0\"]," + - "\"classname\":\"ClientSelectData\",\"classid\":116}"; - return charDetails; + // Race + c.push_back( "0" ); + // Tribe + c.push_back( "0" ); + // Sex + c.push_back( "0" ); + + // BirthMonth + c.push_back( std::to_string( getBirthMonth() ) ); + // Birthday + c.push_back( std::to_string( getBirthDay() ) ); + // GuardianDeity + c.push_back( std::to_string( getGuardianDeity() ) ); + + // Class + c.push_back( std::to_string( m_class ) ); + + // ZoneId + c.push_back( "0" ); + + // TerritoryType + c.push_back( std::to_string( getZoneId() ) ); + + // ContentFinderCondition + c.push_back( "0" ); + + // look map + auto lookArray = nlohmann::json(); + for( auto& it : m_lookMap ) + { + lookArray.push_back( std::to_string( it.second ) ); + } + // Customize + c.push_back( lookArray ); + + // ModelMainWeapon + c.push_back( std::to_string( m_modelMainWeapon ) ); + // ModelSubWeapon + c.push_back( std::to_string( m_modelSubWeapon ) ); + + // model + auto modelArray = nlohmann::json(); + for( auto i : m_modelEquip ) + { + modelArray.push_back( std::to_string( i ) ); + } + // ModelEquip + c.push_back( modelArray ); + + // MainWeapon + c.push_back( "1" ); + // SubWeapon + c.push_back( "0" ); + // JobStone + c.push_back( "0" ); + + // RemakeFlag + c.push_back( "0" ); + + // ConfigFlags + c.push_back( std::to_string( m_equipDisplayFlags ) ); + + // Voice + c.push_back( "0" ); + // WorldName + c.push_back( "" ); + // LoginStatus + c.push_back( "0" ); + // IsOutTerritory + c.push_back( "0" ); + + + payload["classname"] = "ClientSelectData"; + payload["classid"] = 116; + + return payload.dump(); } uint8_t PlayerMinimal::getClassLevel() @@ -163,30 +182,6 @@ uint8_t PlayerMinimal::getClassLevel() return static_cast< uint8_t >( m_classMap[ classJobIndex ] ); } -std::string PlayerMinimal::getClassString() -{ - - std::map< uint8_t, uint16_t >::iterator it; - - it = m_classMap.begin(); - - std::string classString; - - for( ; it != m_classMap.end(); ++it ) - { - - std::string s = std::to_string( it->second ); - - classString += "\"" + s + "\""; - if( it != m_classMap.end() ) - { - classString += ","; - } - } - - return classString.substr( 0, classString.size() - 1 ); -} - void PlayerMinimal::saveAsNew() { diff --git a/src/api/PlayerMinimal.h b/src/api/PlayerMinimal.h index 17318358..d51251c2 100644 --- a/src/api/PlayerMinimal.h +++ b/src/api/PlayerMinimal.h @@ -11,9 +11,9 @@ namespace Sapphire::Api class PlayerMinimal { public: - PlayerMinimal( void ); + PlayerMinimal(); - ~PlayerMinimal( void ); + ~PlayerMinimal() = default; // write player to the database void write(); @@ -23,16 +23,8 @@ namespace Sapphire::Api void saveAsNew(); - std::string getLookString(); - std::string getInfoJson(); - std::string getModelString(); - - std::string getClassString(); - - std::string getLevelsString(); - uint8_t getClassLevel(); // return the id of the actor diff --git a/src/api/main.cpp b/src/api/main.cpp index 5d661387..004233ba 100644 --- a/src/api/main.cpp +++ b/src/api/main.cpp @@ -699,7 +699,7 @@ void defaultGet( shared_ptr< HttpServer::Response > response, shared_ptr< HttpSe catch( const exception& ) { string content = "Path not found: " + request->path; - *response << buildHttpResponse( 400, content ); + *response << buildHttpResponse( 404, content ); } } diff --git a/src/common/Common.h b/src/common/Common.h index a41095ca..14e279c8 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -990,6 +990,18 @@ namespace Sapphire::Common CircularAoEPlaced = 7 }; + enum class Role : uint8_t + { + None, + Tank, + Healer, + RangedPhysical, + RangedMagical, + Melee, + Crafter, + Gatherer + }; + using PlayerStateFlagList = std::vector< PlayerStateFlag >; } diff --git a/src/common/Network/CommonActorControl.h b/src/common/Network/CommonActorControl.h index e08bc79a..c29b2f2c 100644 --- a/src/common/Network/CommonActorControl.h +++ b/src/common/Network/CommonActorControl.h @@ -317,7 +317,7 @@ namespace Sapphire::Network::ActorControl UpdatedSeenHowTos = 0x133, AllotAttribute = 0x135, - ClearWaymarks = 0x13A, + ClearFieldMarkers = 0x13A, CameraMode = 0x13B, // param12, 1 = camera mode enable, 0 = disable CharaNameReq = 0x13D, // requests character name by content id HuntingLogDetails = 0x194, diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index ab499c36..39a408a5 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -136,7 +136,9 @@ namespace Sapphire::Network::Packets ActorSetPos = 0x0184, // updated 5.0 - ActorCast = 0x0187, // updated 5.0 + ActorCast = 0x0186, // updated 5.0 + + SomeCustomiseChangePacketProbably = 0x0187, // added 5.0 PartyList = 0x0188, // updated 5.0 HateRank = 0x0189, // updated 5.0 @@ -313,15 +315,14 @@ namespace Sapphire::Network::Packets ReqJoinNoviceNetwork = 0x0129, // updated 4.2 - ReqCountdownInitiate = 0x0133, // updated 4.5 - ReqCountdownCancel = 0x0134, // updated 4.5 - ClearWaymarks = 0x0135, // updated 4.5 + ReqCountdownInitiate = 0x0135, // updated 5.0 + ReqCountdownCancel = 0x0136, // updated 5.0 ZoneLineHandler = 0x0139, // updated 5.0 ClientTrigger = 0x013A, // updated 5.0 DiscoveryHandler = 0x013B, // updated 5.0 - AddWaymark = 0x013A, // updated 4.5 + PlaceFieldMarker = 0x013C, // updated 5.0 SkillHandler = 0x013D, // updated 5.0 GMCommand1 = 0x013E, // updated 5.0 @@ -331,6 +332,7 @@ namespace Sapphire::Network::Packets UpdatePositionHandler = 0x0141, // updated 5.0 InventoryModifyHandler = 0x0148, // updated 5.0 + InventoryEquipRecommendedItems = 0x0149, // updated 5.0 ReqPlaceHousingItem = 0x014B, // updated 5.0 BuildPresetHandler = 0x014F, // updated 5.0 diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 592856c8..b0773980 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -448,14 +448,19 @@ namespace Sapphire::Network::Packets::Server uint32_t max_hp; uint16_t max_mp; uint16_t max_something; - uint8_t effect_index; // which position do i display this - uint8_t unknown3; - uint16_t effect_id; - uint16_t param; - uint16_t unknown5; // Sort this out (old right half of power/param property) - float duration; - uint32_t actor_id1; - uint8_t unknown4[52]; + + struct StatusEntry + { + uint8_t index; // which position do i display this + uint8_t unknown3; + uint16_t id; + uint16_t param; + uint16_t unknown5; // Sort this out (old right half of power/param property) + float duration; + uint32_t sourceActorId; + } statusEntries[4]; + + uint32_t unknown4; }; /** @@ -551,12 +556,21 @@ namespace Sapphire::Network::Packets::Server uint64_t animationTargetId; // who the animation targets uint32_t actionId; // what the casting player casts, shown in battle log/ui - uint32_t sequence; // seems to only increment on retail? + /*! + * @brief Zone sequence for the effect. Used to link effects that are split across multiple packets as one + */ + uint32_t sequence; float animationLockTime; // maybe? doesn't seem to do anything - uint32_t someTargetId; // always 00 00 00 E0, 0x0E000000 is the internal def for INVALID TARGET ID + uint32_t someTargetId; // always 0x0E000000? - uint16_t hiddenAnimation; // if 0, always shows animation, otherwise hides it. counts up by 1 for each animation skipped on a caster + /*! + * @brief The cast sequence from the originating player. Should only be sent to the source, 0 for every other player. + * + * This needs to match the sequence sent from the player in the action start packet otherwise you'll cancel the + * initial animation and start a new one once the packet arrives. + */ + uint16_t sourceSequence; uint16_t rotation; uint16_t actionAnimationId; // the animation that is played by the casting character uint8_t variation; // variation in the animation @@ -1076,6 +1090,7 @@ namespace Sapphire::Network::Packets::Server */ struct FFXIVIpcPlayerStats : FFXIVIpcBasePacket< PlayerStats > { + // order comes from baseparam order column uint32_t strength; uint32_t dexterity; uint32_t vitality; @@ -1085,45 +1100,30 @@ namespace Sapphire::Network::Packets::Server uint32_t hp; uint32_t mp; uint32_t tp; - uint32_t gp; // Set to 10000 as non-gatherer for some reason + uint32_t gp; uint32_t cp; - uint32_t unknown_2; + uint32_t delay; uint32_t tenacity; - uint32_t attack; + uint32_t attackPower; uint32_t defense; - uint32_t accuracy; - uint32_t spellSpeed; + uint32_t directHitRate; + uint32_t evasion; uint32_t magicDefense; - uint32_t criticalHitRate; - uint32_t resistanceSlashing; - uint32_t resistancePiercing; - uint32_t resistanceBlunt; + uint32_t criticalHit; uint32_t attackMagicPotency; uint32_t healingMagicPotency; - uint32_t fire; - uint32_t ice; - uint32_t wind; - uint32_t earth; - uint32_t lightning; - uint32_t water; + uint32_t elementalBonus; uint32_t determination; uint32_t skillSpeed; - uint32_t spellSpeed1; - uint32_t spellSpeedMod; - uint32_t unknown_6; + uint32_t spellSpeed; + uint32_t haste; uint32_t craftsmanship; uint32_t control; uint32_t gathering; uint32_t perception; - uint32_t resistanceSlow; - uint32_t resistanceSilence; - uint32_t resistanceBlind; - uint32_t resistancePoison; - uint32_t resistanceStun; - uint32_t resistanceSleep; - uint32_t resistanceBind; - uint32_t resistanceHeavy; - uint32_t unknown_7[9]; // possibly level sync stats. + + // todo: what is here? + uint32_t unknown[26]; }; /** diff --git a/src/scripts/common/aethernet/HousingAethernet.cpp b/src/scripts/common/aethernet/HousingAethernet.cpp index 1e49410b..f89c6d4c 100644 --- a/src/scripts/common/aethernet/HousingAethernet.cpp +++ b/src/scripts/common/aethernet/HousingAethernet.cpp @@ -25,7 +25,7 @@ public: if( !pExdData ) return; - auto housingZone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ); + auto housingZone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentTerritory() ); if( !housingZone ) return; @@ -35,7 +35,7 @@ public: return; // check we're teleporting to the same territorytype - if( player.getCurrentZone()->getTerritoryTypeId() != pHousingAethernet->territoryType ) + if( player.getCurrentTerritory()->getTerritoryTypeId() != pHousingAethernet->territoryType ) return; // todo: this needs to be done properly and used queued zoning + aethernet animation diff --git a/src/scripts/common/eobj/HousingEstateEntrance.cpp b/src/scripts/common/eobj/HousingEstateEntrance.cpp index 0c7733de..e0447f31 100644 --- a/src/scripts/common/eobj/HousingEstateEntrance.cpp +++ b/src/scripts/common/eobj/HousingEstateEntrance.cpp @@ -30,7 +30,7 @@ public: if( !terriMgr ) return; - auto zone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ); + auto zone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentTerritory() ); if( !zone ) return; diff --git a/src/scripts/common/housing/CmnDefHousingSignboard.cpp b/src/scripts/common/housing/CmnDefHousingSignboard.cpp index 941ebec7..cf7ff4bf 100644 --- a/src/scripts/common/housing/CmnDefHousingSignboard.cpp +++ b/src/scripts/common/housing/CmnDefHousingSignboard.cpp @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -35,7 +34,7 @@ public: auto activeLand = player.getActiveLand(); auto territoryId = player.getTerritoryId(); - auto pTerritory = player.getCurrentZone(); + auto pTerritory = player.getCurrentTerritory(); auto pHousing = std::dynamic_pointer_cast< HousingZone >( pTerritory ); auto pHouMgr = pFw->get< HousingMgr >(); diff --git a/src/tools/action_parse/main.cpp b/src/tools/action_parse/main.cpp index 3adce507..aa40bdd1 100644 --- a/src/tools/action_parse/main.cpp +++ b/src/tools/action_parse/main.cpp @@ -74,7 +74,7 @@ int main() Logger::init( "action_parse" ); - if( !fs::exists( "ActionLut.cpp.tmpl" ) ) + if( !fs::exists( "ActionLutData.cpp.tmpl" ) ) throw std::runtime_error( "ActionLut.cpp.tmpl is missing in working directory" ); Logger::info( "Setting up EXD data" ); @@ -249,9 +249,11 @@ int main() // action.first, data.name, data.potency, data.flankPotency, data.frontPotency, data.rearPotency, // data.curePotency, data.restorePercentage ); - auto out = fmt::format( " // {}\n {{ {}, {{ {}, {}, {}, {}, {} }} }},\n", + auto out = fmt::format( " // {}\n {{ {}, {{ {}, {}, {}, {}, {}, {} }} }},\n", data.name, action.first, - data.potency, data.flankPotency, data.frontPotency, data.rearPotency, data.curePotency ); + data.potency, data.comboPotency, + data.flankPotency, data.frontPotency, data.rearPotency, + data.curePotency ); output += out; // Logger::info( out ); diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index ba1665d0..783a84ea 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -1,5 +1,8 @@ #include "Action.h" #include "ActionLut.h" +#include "EffectBuilder.h" + +#include #include #include @@ -11,15 +14,17 @@ #include "Actor/Player.h" #include "Actor/BNpc.h" -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include #include "Network/PacketWrappers/ActorControlPacket142.h" #include "Network/PacketWrappers/ActorControlPacket143.h" #include "Network/PacketWrappers/ActorControlPacket144.h" -#include + #include + #include +#include using namespace Sapphire; using namespace Sapphire::Common; @@ -33,19 +38,21 @@ using namespace Sapphire::World; Action::Action::Action() = default; Action::Action::~Action() = default; -Action::Action::Action( Entity::CharaPtr caster, uint32_t actionId, FrameworkPtr fw ) : - Action( std::move( caster ), actionId, nullptr, std::move( fw ) ) +Action::Action::Action( Entity::CharaPtr caster, uint32_t actionId, uint16_t sequence, FrameworkPtr fw ) : + Action( std::move( caster ), actionId, sequence, nullptr, std::move( fw ) ) { } -Action::Action::Action( Entity::CharaPtr caster, uint32_t actionId, Data::ActionPtr actionData, FrameworkPtr fw ) : +Action::Action::Action( Entity::CharaPtr caster, uint32_t actionId, uint16_t sequence, + Data::ActionPtr actionData, FrameworkPtr fw ) : m_pSource( std::move( caster ) ), m_pFw( std::move( fw ) ), m_actionData( std::move( actionData ) ), m_id( actionId ), m_targetId( 0 ), m_startTime( 0 ), - m_interruptType( Common::ActionInterruptType::None ) + m_interruptType( Common::ActionInterruptType::None ), + m_sequence( sequence ) { } @@ -68,6 +75,8 @@ bool Action::Action::init() m_actionData = actionData; } + m_effectBuilder = make_EffectBuilder( m_pSource, getId(), m_sequence ); + m_castTimeMs = static_cast< uint32_t >( m_actionData->cast100ms * 100 ); m_recastTimeMs = static_cast< uint32_t >( m_actionData->recast100ms * 100 ); m_cooldownGroup = m_actionData->cooldownGroup; @@ -217,13 +226,20 @@ void Action::Action::start() if( hasCastTime() ) { auto castPacket = makeZonePacket< Server::FFXIVIpcActorCast >( getId() ); + auto& data = castPacket->data(); - castPacket->data().action_id = static_cast< uint16_t >( m_id ); - castPacket->data().skillType = Common::SkillType::Normal; - castPacket->data().unknown_1 = m_id; + data.action_id = static_cast< uint16_t >( m_id ); + data.skillType = Common::SkillType::Normal; + data.unknown_1 = m_id; // This is used for the cast bar above the target bar of the caster. - castPacket->data().cast_time = m_castTimeMs / 1000.f; - castPacket->data().target_id = static_cast< uint32_t >( m_targetId ); + data.cast_time = m_castTimeMs / 1000.f; + data.target_id = static_cast< uint32_t >( m_targetId ); + + auto pos = m_pSource->getPos(); + data.posX = Common::Util::floatToUInt16( pos.x ); + data.posY = Common::Util::floatToUInt16( pos.y ); + data.posZ = Common::Util::floatToUInt16( pos.z ); + data.rotation = m_pSource->getRot(); m_pSource->sendToInRangeSet( castPacket, true ); @@ -326,30 +342,13 @@ void Action::Action::execute() player->sendDebug( "action combo success from action#{0}", player->getLastComboActionId() ); } - if( !hasClientsideTarget() ) + if( !hasClientsideTarget() ) { - snapshotAffectedActors( m_hitActors ); - - if( !m_hitActors.empty() ) - { - // only call script if actors are hit - if( !pScriptMgr->onExecute( *this ) && ActionLut::validEntryExists( getId() ) ) - { - auto lutEntry = ActionLut::getEntry( getId() ); - - // no script exists but we have a valid lut entry - if( auto player = getSourceChara()->getAsPlayer() ) - { - player->sendDebug( "Hit target: pot: {} (f: {}, r: {}), heal pot: {}", - lutEntry.potency, lutEntry.flankPotency, lutEntry.rearPotency, lutEntry.curePotency ); - } - } - } + buildEffects(); } else if( auto player = m_pSource->getAsPlayer() ) { pScriptMgr->onEObjHit( *player, m_targetId, getId() ); - return; } // set currently casted action as the combo action if it interrupts a combo @@ -360,6 +359,83 @@ void Action::Action::execute() } } +std::pair< uint32_t, Common::ActionHitSeverityType > Action::Action::calcDamage( uint32_t potency ) +{ + // todo: what do for npcs? + auto wepDmg = 1.f; + + if( auto player = m_pSource->getAsPlayer() ) + { + auto item = player->getEquippedWeapon(); + assert( item ); + + auto role = player->getRole(); + if( role == Common::Role::RangedMagical || role == Common::Role::Healer ) + { + wepDmg = item->getMagicalDmg(); + } + else + { + wepDmg = item->getPhysicalDmg(); + } + } + + auto dmg = Math::CalcStats::calcActionDamage( *m_pSource, potency, wepDmg ); + + return std::make_pair( dmg, Common::ActionHitSeverityType::NormalDamage ); +} + +void Action::Action::buildEffects() +{ + snapshotAffectedActors( m_hitActors ); + + auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >(); + + if( !pScriptMgr->onExecute( *this ) && !ActionLut::validEntryExists( getId() ) ) + { + if( auto player = m_pSource->getAsPlayer() ) + { + player->sendUrgent( "missing lut entry for action#{}", getId() ); + } + + return; + } + + if( m_hitActors.empty() ) + return; + + auto lutEntry = ActionLut::getEntry( getId() ); + + // no script exists but we have a valid lut entry + if( auto player = getSourceChara()->getAsPlayer() ) + { + player->sendDebug( "Hit target: pot: {} (c: {}, f: {}, r: {}), heal pot: {}", + lutEntry.potency, lutEntry.comboPotency, lutEntry.flankPotency, lutEntry.rearPotency, + lutEntry.curePotency ); + } + + for( auto& actor : m_hitActors ) + { + // todo: this is shit + if( lutEntry.curePotency > 0 ) + { + + m_effectBuilder->healTarget( actor, lutEntry.curePotency ); + } + + else if( lutEntry.potency > 0 ) + { + auto dmg = calcDamage( lutEntry.potency ); + m_effectBuilder->damageTarget( actor, dmg.first, dmg.second ); + } + } + + m_effectBuilder->buildAndSendPackets(); + + // at this point we're done with it and no longer need it + m_effectBuilder.reset(); +} + bool Action::Action::preCheck() { if( auto player = m_pSource->getAsPlayer() ) diff --git a/src/world/Action/Action.h b/src/world/Action/Action.h index 6f3fccca..8288b90e 100644 --- a/src/world/Action/Action.h +++ b/src/world/Action/Action.h @@ -20,8 +20,8 @@ namespace Sapphire::World::Action public: Action(); - Action( Entity::CharaPtr caster, uint32_t actionId, FrameworkPtr fw ); - Action( Entity::CharaPtr caster, uint32_t actionId, Data::ActionPtr actionData, FrameworkPtr fw ); + Action( Entity::CharaPtr caster, uint32_t actionId, uint16_t sequence, FrameworkPtr fw ); + Action( Entity::CharaPtr caster, uint32_t actionId, uint16_t sequence, Data::ActionPtr actionData, FrameworkPtr fw ); virtual ~Action(); @@ -85,6 +85,8 @@ namespace Sapphire::World::Action */ bool snapshotAffectedActors( std::vector< Entity::CharaPtr >& actors ); + void buildEffects(); + /*! * @brief Adds an actor filter to this action. * @param filter The ptr to the ActorFilter to add @@ -96,6 +98,10 @@ namespace Sapphire::World::Action */ void addDefaultActorFilters(); + std::pair< uint32_t, Common::ActionHitSeverityType > calcDamage( uint32_t potency ); + + std::pair< uint32_t, Common::ActionHitSeverityType > calcHealing( uint32_t potency ); + std::vector< Entity::CharaPtr >& getHitCharas(); @@ -139,6 +145,8 @@ namespace Sapphire::World::Action uint32_t m_id; + uint16_t m_sequence; + Common::ActionPrimaryCostType m_primaryCostType; uint16_t m_primaryCost; @@ -171,6 +179,8 @@ namespace Sapphire::World::Action Common::FFXIVARR_POSITION3 m_pos; + EffectBuilderPtr m_effectBuilder; + std::vector< World::Util::ActorFilterPtr > m_actorFilters; std::vector< Entity::CharaPtr > m_hitActors; }; diff --git a/src/world/Action/ActionLutData.cpp b/src/world/Action/ActionLutData.cpp index 1e9c1f97..76e352ae 100644 --- a/src/world/Action/ActionLutData.cpp +++ b/src/world/Action/ActionLutData.cpp @@ -5,1116 +5,1402 @@ using namespace Sapphire::World::Action; ActionLut::Lut ActionLut::m_actionLut = { // attack - { 7, { 0, 0, 0, 0, 0 } }, + { 7, { 0, 0, 0, 0, 0, 0 } }, // Shot - { 8, { 0, 0, 0, 0, 0 } }, + { 8, { 0, 0, 0, 0, 0, 0 } }, // Fast Blade - { 9, { 160, 0, 0, 0, 0 } }, - // Savage Blade - { 11, { 100, 0, 0, 0, 0 } }, - // Flash - { 14, { 0, 0, 0, 0, 0 } }, + { 9, { 200, 0, 0, 0, 0, 0 } }, // Riot Blade - { 15, { 100, 0, 0, 0, 0 } }, + { 15, { 100, 300, 0, 0, 0, 0 } }, // Shield Bash - { 16, { 110, 0, 0, 0, 0 } }, + { 16, { 110, 0, 0, 0, 0, 0 } }, // Sentinel - { 17, { 0, 0, 0, 0, 0 } }, - // Tempered Will - { 19, { 0, 0, 0, 0, 0 } }, + { 17, { 0, 0, 0, 0, 0, 0 } }, // Fight or Flight - { 20, { 0, 0, 0, 0, 0 } }, + { 20, { 0, 0, 0, 0, 0, 0 } }, // Rage of Halone - { 21, { 100, 0, 0, 0, 0 } }, - // Bulwark - { 22, { 0, 0, 0, 0, 0 } }, + { 21, { 100, 350, 0, 0, 0, 0 } }, // Circle of Scorn - { 23, { 100, 0, 0, 0, 0 } }, + { 23, { 120, 0, 0, 0, 0, 0 } }, // Shield Lob - { 24, { 120, 0, 0, 0, 0 } }, - // Shield Swipe - { 25, { 100, 0, 0, 0, 0 } }, - // Sword Oath - { 26, { 75, 0, 0, 0, 0 } }, + { 24, { 120, 0, 0, 0, 0, 0 } }, // Cover - { 27, { 0, 0, 0, 0, 0 } }, - // Shield Oath - { 28, { 0, 0, 0, 0, 0 } }, + { 27, { 0, 0, 0, 0, 0, 0 } }, + // Iron Will + { 28, { 0, 0, 0, 0, 0, 0 } }, // Spirits Within - { 29, { 300, 0, 0, 0, 0 } }, + { 29, { 370, 0, 0, 0, 0, 0 } }, // Hallowed Ground - { 30, { 0, 0, 0, 0, 0 } }, + { 30, { 0, 0, 0, 0, 0, 0 } }, // Heavy Swing - { 31, { 160, 0, 0, 0, 0 } }, - // Skull Sunder - { 35, { 100, 0, 0, 0, 0 } }, + { 31, { 200, 0, 0, 0, 0, 0 } }, // Maim - { 37, { 100, 0, 0, 0, 0 } }, + { 37, { 100, 300, 0, 0, 0, 0 } }, // Berserk - { 38, { 0, 0, 0, 0, 0 } }, + { 38, { 0, 0, 0, 0, 0, 0 } }, // Thrill of Battle - { 40, { 0, 0, 0, 0, 0 } }, + { 40, { 0, 0, 0, 0, 0, 0 } }, // Overpower - { 41, { 130, 0, 0, 0, 0 } }, + { 41, { 130, 0, 0, 0, 0, 0 } }, // Storm's Path - { 42, { 100, 0, 0, 0, 0 } }, + { 42, { 100, 380, 0, 0, 0, 250 } }, // Holmgang - { 43, { 0, 0, 0, 0, 0 } }, + { 43, { 0, 0, 0, 0, 0, 0 } }, // Vengeance - { 44, { 55, 0, 0, 0, 0 } }, + { 44, { 55, 0, 0, 0, 0, 0 } }, // Storm's Eye - { 45, { 100, 0, 0, 0, 0 } }, + { 45, { 100, 380, 0, 0, 0, 0 } }, // Tomahawk - { 46, { 140, 0, 0, 0, 0 } }, - // Butcher's Block - { 47, { 100, 0, 0, 0, 0 } }, + { 46, { 140, 0, 0, 0, 0, 0 } }, // Defiance - { 48, { 0, 0, 0, 0, 0 } }, + { 48, { 0, 0, 0, 0, 0, 0 } }, // Inner Beast - { 49, { 350, 0, 0, 0, 0 } }, - // Unchained - { 50, { 0, 0, 0, 0, 0 } }, + { 49, { 350, 0, 0, 0, 0, 0 } }, // Steel Cyclone - { 51, { 200, 0, 0, 0, 0 } }, + { 51, { 220, 0, 0, 0, 0, 0 } }, // Infuriate - { 52, { 0, 0, 0, 0, 0 } }, + { 52, { 0, 0, 0, 0, 0, 0 } }, // Bootshine - { 53, { 140, 0, 0, 0, 0 } }, + { 53, { 150, 0, 0, 0, 0, 0 } }, // True Strike - { 54, { 160, 0, 0, 180, 0 } }, + { 54, { 220, 0, 0, 0, 240, 0 } }, // Snap Punch - { 56, { 150, 170, 0, 0, 0 } }, - // Internal Release - { 59, { 0, 0, 0, 0, 0 } }, + { 56, { 210, 0, 230, 0, 0, 0 } }, // Fists of Earth - { 60, { 0, 0, 0, 0, 0 } }, + { 60, { 0, 0, 0, 0, 0, 0 } }, // Twin Snakes - { 61, { 110, 130, 0, 0, 0 } }, + { 61, { 150, 0, 170, 0, 0, 0 } }, // Arm of the Destroyer - { 62, { 50, 0, 0, 0, 0 } }, + { 62, { 80, 0, 0, 0, 0, 0 } }, // Fists of Fire - { 63, { 0, 0, 0, 0, 0 } }, - // Steel Peak - { 64, { 150, 0, 0, 0, 0 } }, + { 63, { 0, 0, 0, 0, 0, 0 } }, // Mantra - { 65, { 0, 0, 0, 0, 0 } }, + { 65, { 0, 0, 0, 0, 0, 0 } }, // Demolish - { 66, { 50, 0, 0, 70, 0 } }, - // Howling Fist - { 67, { 210, 0, 0, 0, 0 } }, + { 66, { 70, 0, 0, 0, 90, 0 } }, // Perfect Balance - { 69, { 0, 0, 0, 0, 0 } }, + { 69, { 0, 0, 0, 0, 0, 0 } }, // Rockbreaker - { 70, { 130, 0, 0, 0, 0 } }, + { 70, { 120, 0, 0, 0, 0, 0 } }, // Shoulder Tackle - { 71, { 100, 0, 0, 0, 0 } }, - // One Ilm Punch - { 72, { 120, 0, 0, 0, 0 } }, + { 71, { 100, 0, 0, 0, 0, 0 } }, // Fists of Wind - { 73, { 0, 0, 0, 0, 0 } }, + { 73, { 0, 0, 0, 0, 0, 0 } }, // Dragon Kick - { 74, { 120, 140, 0, 0, 0 } }, + { 74, { 180, 0, 200, 0, 0, 0 } }, // True Thrust - { 75, { 160, 0, 0, 0, 0 } }, + { 75, { 0, 0, 0, 0, 0, 0 } }, // Vorpal Thrust - { 78, { 100, 0, 0, 0, 0 } }, - // Heavy Thrust - { 79, { 150, 190, 0, 0, 0 } }, - // Impulse Drive - { 81, { 200, 0, 0, 0, 0 } }, + { 78, { 0, 0, 0, 0, 0, 0 } }, // Life Surge - { 83, { 0, 0, 0, 0, 0 } }, + { 83, { 0, 0, 0, 0, 0, 0 } }, // Full Thrust - { 84, { 100, 0, 0, 0, 0 } }, - // Blood for Blood - { 85, { 0, 0, 0, 0, 0 } }, + { 84, { 100, 530, 0, 0, 0, 0 } }, + // Lance Charge + { 85, { 0, 0, 0, 0, 0, 0 } }, // Doom Spike - { 86, { 140, 0, 0, 0, 0 } }, + { 86, { 170, 0, 0, 0, 0, 0 } }, // Disembowel - { 87, { 100, 0, 0, 0, 0 } }, + { 87, { 0, 0, 0, 0, 0, 0 } }, // Chaos Thrust - { 88, { 100, 0, 0, 140, 0 } }, + { 88, { 100, 290, 0, 0, 140, 0 } }, // Piercing Talon - { 90, { 120, 0, 0, 0, 0 } }, + { 90, { 150, 0, 0, 0, 0, 0 } }, // Jump - { 92, { 260, 0, 0, 0, 0 } }, + { 92, { 310, 0, 0, 0, 0, 0 } }, // Elusive Jump - { 94, { 0, 0, 0, 0, 0 } }, + { 94, { 0, 0, 0, 0, 0, 0 } }, // Spineshatter Dive - { 95, { 210, 0, 0, 0, 0 } }, + { 95, { 240, 0, 0, 0, 0, 0 } }, // Dragonfire Dive - { 96, { 320, 0, 0, 0, 0 } }, + { 96, { 380, 0, 0, 0, 0, 0 } }, // Heavy Shot - { 97, { 150, 0, 0, 0, 0 } }, + { 97, { 180, 0, 0, 0, 0, 0 } }, // Straight Shot - { 98, { 140, 0, 0, 0, 0 } }, + { 98, { 200, 0, 0, 0, 0, 0 } }, // Venomous Bite - { 100, { 100, 0, 0, 0, 0 } }, + { 100, { 100, 0, 0, 0, 0, 0 } }, // Raging Strikes - { 101, { 0, 0, 0, 0, 0 } }, - // Misery's End - { 103, { 190, 0, 0, 0, 0 } }, + { 101, { 0, 0, 0, 0, 0, 0 } }, // Quick Nock - { 106, { 110, 0, 0, 0, 0 } }, + { 106, { 150, 0, 0, 0, 0, 0 } }, // Barrage - { 107, { 0, 0, 0, 0, 0 } }, + { 107, { 0, 0, 0, 0, 0, 0 } }, // Bloodletter - { 110, { 130, 0, 0, 0, 0 } }, + { 110, { 150, 0, 0, 0, 0, 0 } }, // Repelling Shot - { 112, { 0, 0, 0, 0, 0 } }, + { 112, { 0, 0, 0, 0, 0, 0 } }, // Windbite - { 113, { 60, 0, 0, 0, 0 } }, + { 113, { 60, 0, 0, 0, 0, 0 } }, // Mage's Ballad - { 114, { 100, 0, 0, 0, 0 } }, - // Foe Requiem - { 115, { 0, 0, 0, 0, 0 } }, + { 114, { 100, 0, 0, 0, 0, 0 } }, // Army's Paeon - { 116, { 100, 0, 0, 0, 0 } }, + { 116, { 100, 0, 0, 0, 0, 0 } }, // Rain of Death - { 117, { 100, 0, 0, 0, 0 } }, + { 117, { 130, 0, 0, 0, 0, 0 } }, // Battle Voice - { 118, { 0, 0, 0, 0, 0 } }, + { 118, { 0, 0, 0, 0, 0, 0 } }, // Stone - { 119, { 140, 0, 0, 0, 0 } }, + { 119, { 140, 0, 0, 0, 0, 0 } }, // Cure - { 120, { 0, 0, 0, 0, 450 } }, + { 120, { 0, 0, 0, 0, 0, 450 } }, // Aero - { 121, { 50, 0, 0, 0, 0 } }, + { 121, { 50, 0, 0, 0, 0, 0 } }, // Medica - { 124, { 0, 0, 0, 0, 300 } }, + { 124, { 0, 0, 0, 0, 0, 300 } }, // Raise - { 125, { 0, 0, 0, 0, 0 } }, + { 125, { 0, 0, 0, 0, 0, 0 } }, // Stone II - { 127, { 200, 0, 0, 0, 0 } }, - // Repose - { 128, { 0, 0, 0, 0, 0 } }, + { 127, { 200, 0, 0, 0, 0, 0 } }, // Cure III - { 131, { 0, 0, 0, 0, 550 } }, + { 131, { 0, 0, 0, 0, 0, 550 } }, // Aero II - { 132, { 50, 0, 0, 0, 0 } }, + { 132, { 60, 0, 0, 0, 0, 0 } }, // Medica II - { 133, { 0, 0, 0, 0, 200 } }, + { 133, { 0, 0, 0, 0, 0, 200 } }, // Fluid Aura - { 134, { 0, 0, 0, 0, 0 } }, + { 134, { 0, 0, 0, 0, 0, 0 } }, // Cure II - { 135, { 0, 0, 0, 0, 700 } }, + { 135, { 0, 0, 0, 0, 0, 700 } }, // Presence of Mind - { 136, { 0, 0, 0, 0, 0 } }, + { 136, { 0, 0, 0, 0, 0, 0 } }, // Regen - { 137, { 0, 0, 0, 0, 150 } }, + { 137, { 0, 0, 0, 0, 0, 200 } }, // Holy - { 139, { 200, 0, 0, 0, 0 } }, + { 139, { 140, 0, 0, 0, 0, 0 } }, // Benediction - { 140, { 0, 0, 0, 0, 0 } }, + { 140, { 0, 0, 0, 0, 0, 0 } }, // Fire - { 141, { 180, 0, 0, 0, 0 } }, + { 141, { 180, 0, 0, 0, 0, 0 } }, // Blizzard - { 142, { 180, 0, 0, 0, 0 } }, + { 142, { 180, 0, 0, 0, 0, 0 } }, // Thunder - { 144, { 30, 0, 0, 0, 0 } }, + { 144, { 30, 0, 0, 0, 0, 0 } }, // Sleep - { 145, { 0, 0, 0, 0, 0 } }, + { 145, { 0, 0, 0, 0, 0, 0 } }, // Blizzard II - { 146, { 50, 0, 0, 0, 0 } }, + { 146, { 50, 0, 0, 0, 0, 0 } }, // Fire II - { 147, { 80, 0, 0, 0, 0 } }, + { 147, { 80, 0, 0, 0, 0, 0 } }, // Transpose - { 149, { 0, 0, 0, 0, 0 } }, + { 149, { 0, 0, 0, 0, 0, 0 } }, // Fire III - { 152, { 240, 0, 0, 0, 0 } }, + { 152, { 240, 0, 0, 0, 0, 0 } }, // Thunder III - { 153, { 70, 0, 0, 0, 0 } }, + { 153, { 70, 0, 0, 0, 0, 0 } }, // Blizzard III - { 154, { 240, 0, 0, 0, 0 } }, + { 154, { 240, 0, 0, 0, 0, 0 } }, // Aetherial Manipulation - { 155, { 0, 0, 0, 0, 0 } }, + { 155, { 0, 0, 0, 0, 0, 0 } }, // Scathe - { 156, { 100, 0, 0, 0, 0 } }, + { 156, { 100, 0, 0, 0, 0, 0 } }, // Manaward - { 157, { 0, 0, 0, 0, 0 } }, - // Convert - { 158, { 0, 0, 0, 0, 0 } }, + { 157, { 0, 0, 0, 0, 0, 0 } }, + // Manafont + { 158, { 0, 0, 0, 0, 0, 0 } }, // Freeze - { 159, { 100, 0, 0, 0, 0 } }, + { 159, { 100, 0, 0, 0, 0, 0 } }, // Flare - { 162, { 260, 0, 0, 0, 0 } }, + { 162, { 260, 0, 0, 0, 0, 0 } }, // Ruin - { 163, { 100, 0, 0, 0, 0 } }, + { 163, { 80, 0, 0, 0, 0, 0 } }, // Bio - { 164, { 0, 0, 0, 0, 0 } }, + { 164, { 0, 0, 0, 0, 0, 0 } }, // Summon - { 165, { 0, 0, 0, 0, 0 } }, + { 165, { 0, 0, 0, 0, 0, 0 } }, // Aetherflow - { 166, { 0, 0, 0, 0, 0 } }, - // Energy Drain - { 167, { 150, 0, 0, 0, 0 } }, + { 166, { 0, 0, 0, 0, 0, 0 } }, // Miasma - { 168, { 20, 0, 0, 0, 0 } }, + { 168, { 20, 0, 0, 0, 0, 0 } }, // Summon II - { 170, { 0, 0, 0, 0, 0 } }, - // Sustain - { 171, { 0, 0, 0, 0, 0 } }, + { 170, { 0, 0, 0, 0, 0, 0 } }, // Ruin II - { 172, { 100, 0, 0, 0, 0 } }, + { 172, { 80, 0, 0, 0, 0, 0 } }, // Resurrection - { 173, { 0, 0, 0, 0, 0 } }, + { 173, { 0, 0, 0, 0, 0, 0 } }, // Bane - { 174, { 0, 0, 0, 0, 0 } }, - // Rouse - { 176, { 0, 0, 0, 0, 0 } }, - // Miasma II - { 177, { 100, 0, 0, 0, 0 } }, + { 174, { 0, 0, 0, 0, 0, 0 } }, // Bio II - { 178, { 0, 0, 0, 0, 0 } }, - // Shadow Flare - { 179, { 50, 0, 0, 0, 0 } }, + { 178, { 0, 0, 0, 0, 0, 0 } }, // Summon III - { 180, { 0, 0, 0, 0, 0 } }, + { 180, { 0, 0, 0, 0, 0, 0 } }, // Fester - { 181, { 150, 0, 0, 0, 0 } }, - // Tri-bind - { 182, { 30, 0, 0, 0, 0 } }, + { 181, { 100, 0, 0, 0, 0, 0 } }, // Enkindle - { 184, { 0, 0, 0, 0, 0 } }, + { 184, { 0, 0, 0, 0, 0, 0 } }, // Adloquium - { 185, { 0, 0, 0, 0, 300 } }, + { 185, { 0, 0, 0, 0, 0, 300 } }, // Succor - { 186, { 0, 0, 0, 0, 150 } }, + { 186, { 0, 0, 0, 0, 0, 180 } }, // Sacred Soil - { 188, { 0, 0, 0, 0, 0 } }, + { 188, { 0, 0, 0, 0, 0, 100 } }, // Lustrate - { 189, { 0, 0, 0, 0, 600 } }, + { 189, { 0, 0, 0, 0, 0, 600 } }, // Physick - { 190, { 0, 0, 0, 0, 400 } }, + { 190, { 0, 0, 0, 0, 0, 400 } }, // Shield Wall - { 197, { 0, 0, 0, 0, 0 } }, + { 197, { 0, 0, 0, 0, 0, 0 } }, // Stronghold - { 198, { 0, 0, 0, 0, 0 } }, + { 198, { 0, 0, 0, 0, 0, 0 } }, // Last Bastion - { 199, { 0, 0, 0, 0, 0 } }, + { 199, { 0, 0, 0, 0, 0, 0 } }, // Braver - { 200, { 2400, 0, 0, 0, 0 } }, + { 200, { 2400, 0, 0, 0, 0, 0 } }, // Bladedance - { 201, { 5250, 0, 0, 0, 0 } }, + { 201, { 5250, 0, 0, 0, 0, 0 } }, // Final Heaven - { 202, { 9000, 0, 0, 0, 0 } }, + { 202, { 9000, 0, 0, 0, 0, 0 } }, // Skyshard - { 203, { 1650, 0, 0, 0, 0 } }, + { 203, { 1650, 0, 0, 0, 0, 0 } }, // Starstorm - { 204, { 3600, 0, 0, 0, 0 } }, + { 204, { 3600, 0, 0, 0, 0, 0 } }, // Meteor - { 205, { 6150, 0, 0, 0, 0 } }, + { 205, { 6150, 0, 0, 0, 0, 0 } }, // Healing Wind - { 206, { 0, 0, 0, 0, 0 } }, + { 206, { 0, 0, 0, 0, 0, 0 } }, // Breath of the Earth - { 207, { 0, 0, 0, 0, 0 } }, + { 207, { 0, 0, 0, 0, 0, 0 } }, // Pulse of Life - { 208, { 0, 0, 0, 0, 0 } }, + { 208, { 0, 0, 0, 0, 0, 0 } }, // Magitek Cannon - { 1128, { 0, 0, 0, 0, 0 } }, + { 1128, { 0, 0, 0, 0, 0, 0 } }, // Photon Stream - { 1129, { 0, 0, 0, 0, 0 } }, + { 1129, { 0, 0, 0, 0, 0, 0 } }, // attack - { 1533, { 0, 0, 0, 0, 0 } }, + { 1533, { 0, 0, 0, 0, 0, 0 } }, // Spinning Edge - { 2240, { 150, 0, 0, 0, 0 } }, + { 2240, { 200, 0, 0, 0, 0, 0 } }, // Shade Shift - { 2241, { 0, 0, 0, 0, 0 } }, + { 2241, { 0, 0, 0, 0, 0, 0 } }, // Gust Slash - { 2242, { 100, 0, 0, 0, 0 } }, + { 2242, { 100, 250, 0, 0, 0, 0 } }, // Hide - { 2245, { 0, 0, 0, 0, 0 } }, + { 2245, { 0, 0, 0, 0, 0, 0 } }, // Assassinate - { 2246, { 200, 0, 0, 0, 0 } }, + { 2246, { 200, 0, 0, 0, 0, 0 } }, // Throwing Dagger - { 2247, { 120, 0, 0, 0, 0 } }, + { 2247, { 120, 0, 0, 0, 0, 0 } }, // Mug - { 2248, { 140, 0, 0, 0, 0 } }, - // Hide - { 2253, { 0, 0, 0, 0, 0 } }, + { 2248, { 150, 0, 0, 0, 0, 0 } }, // Death Blossom - { 2254, { 110, 0, 0, 0, 0 } }, + { 2254, { 120, 0, 0, 0, 0, 0 } }, // Aeolian Edge - { 2255, { 100, 0, 0, 160, 0 } }, - // Jugulate - { 2256, { 80, 0, 0, 0, 0 } }, + { 2255, { 100, 360, 0, 0, 160, 0 } }, // Shadow Fang - { 2257, { 100, 0, 0, 0, 0 } }, + { 2257, { 100, 200, 0, 0, 0, 0 } }, // Trick Attack - { 2258, { 240, 0, 0, 400, 0 } }, + { 2258, { 340, 0, 0, 0, 500, 0 } }, // Ten - { 2259, { 0, 0, 0, 0, 0 } }, + { 2259, { 0, 0, 0, 0, 0, 0 } }, // Ninjutsu - { 2260, { 0, 0, 0, 0, 0 } }, + { 2260, { 0, 0, 0, 0, 0, 0 } }, // Chi - { 2261, { 0, 0, 0, 0, 0 } }, + { 2261, { 0, 0, 0, 0, 0, 0 } }, // Shukuchi - { 2262, { 0, 0, 0, 0, 0 } }, + { 2262, { 0, 0, 0, 0, 0, 0 } }, // Jin - { 2263, { 0, 0, 0, 0, 0 } }, + { 2263, { 0, 0, 0, 0, 0, 0 } }, // Kassatsu - { 2264, { 0, 0, 0, 0, 0 } }, + { 2264, { 0, 0, 0, 0, 0, 0 } }, // Fuma Shuriken - { 2265, { 240, 0, 0, 0, 0 } }, + { 2265, { 280, 0, 0, 0, 0, 0 } }, // Katon - { 2266, { 250, 0, 0, 0, 0 } }, + { 2266, { 250, 0, 0, 0, 0, 0 } }, // Raiton - { 2267, { 360, 0, 0, 0, 0 } }, + { 2267, { 400, 0, 0, 0, 0, 0 } }, // Hyoton - { 2268, { 140, 0, 0, 0, 0 } }, + { 2268, { 140, 0, 0, 0, 0, 0 } }, // Huton - { 2269, { 0, 0, 0, 0, 0 } }, + { 2269, { 0, 0, 0, 0, 0, 0 } }, // Doton - { 2270, { 45, 0, 0, 0, 0 } }, + { 2270, { 45, 0, 0, 0, 0, 0 } }, // Suiton - { 2271, { 180, 0, 0, 0, 0 } }, + { 2271, { 130, 0, 0, 0, 0, 0 } }, // Rabbit Medium - { 2272, { 0, 0, 0, 0, 0 } }, + { 2272, { 0, 0, 0, 0, 0, 0 } }, // Rook Autoturret - { 2864, { 80, 0, 0, 0, 0 } }, - // Bishop Autoturret - { 2865, { 60, 0, 0, 0, 0 } }, + { 2864, { 80, 0, 0, 0, 0, 0 } }, // Split Shot - { 2866, { 160, 0, 0, 0, 0 } }, - // Reload - { 2867, { 0, 0, 0, 0, 0 } }, + { 2866, { 160, 0, 0, 0, 0, 0 } }, // Slug Shot - { 2868, { 100, 0, 0, 0, 0 } }, + { 2868, { 100, 240, 0, 0, 0, 0 } }, // Spread Shot - { 2870, { 80, 0, 0, 0, 0 } }, + { 2870, { 180, 0, 0, 0, 0, 0 } }, // Hot Shot - { 2872, { 120, 0, 0, 0, 0 } }, + { 2872, { 300, 0, 0, 0, 0, 0 } }, // Clean Shot - { 2873, { 100, 0, 0, 0, 0 } }, + { 2873, { 100, 320, 0, 0, 0, 0 } }, // Gauss Round - { 2874, { 210, 0, 0, 0, 0 } }, - // Heartbreak - { 2875, { 240, 0, 0, 0, 0 } }, + { 2874, { 150, 0, 0, 0, 0, 0 } }, // Reassemble - { 2876, { 0, 0, 0, 0, 0 } }, + { 2876, { 0, 0, 0, 0, 0, 0 } }, // Wildfire - { 2878, { 0, 0, 0, 0, 0 } }, - // Quick Reload - { 2879, { 0, 0, 0, 0, 0 } }, - // Gauss Barrel - { 2880, { 0, 0, 0, 0, 0 } }, - // Rapid Fire - { 2881, { 0, 0, 0, 0, 0 } }, - // Hypercharge - { 2885, { 0, 0, 0, 0, 0 } }, - // Dismantle - { 2887, { 0, 0, 0, 0, 0 } }, - // Blank - { 2888, { 0, 0, 0, 0, 0 } }, + { 2878, { 0, 0, 0, 0, 0, 0 } }, // Ricochet - { 2890, { 320, 0, 0, 0, 0 } }, + { 2890, { 150, 0, 0, 0, 0, 0 } }, // Raiton - { 3203, { 0, 0, 0, 0, 0 } }, + { 3203, { 0, 0, 0, 0, 0, 0 } }, // Raiton - { 3204, { 0, 0, 0, 0, 0 } }, + { 3204, { 0, 0, 0, 0, 0, 0 } }, // Kanashibari - { 3207, { 0, 0, 0, 0, 0 } }, - // Turret Retrieval - { 3487, { 0, 0, 0, 0, 0 } }, + { 3207, { 0, 0, 0, 0, 0, 0 } }, // Goring Blade - { 3538, { 100, 0, 0, 0, 0 } }, + { 3538, { 100, 390, 0, 0, 0, 0 } }, // Royal Authority - { 3539, { 100, 0, 0, 0, 0 } }, + { 3539, { 100, 550, 0, 0, 0, 0 } }, // Divine Veil - { 3540, { 0, 0, 0, 0, 0 } }, + { 3540, { 0, 0, 0, 0, 0, 0 } }, // Clemency - { 3541, { 0, 0, 0, 0, 1200 } }, + { 3541, { 0, 0, 0, 0, 0, 1200 } }, // Sheltron - { 3542, { 0, 0, 0, 0, 0 } }, + { 3542, { 0, 0, 0, 0, 0, 0 } }, // Tornado Kick - { 3543, { 330, 0, 0, 0, 0 } }, - // Purification - { 3544, { 0, 0, 0, 0, 0 } }, + { 3543, { 330, 0, 0, 0, 0, 0 } }, // Elixir Field - { 3545, { 220, 0, 0, 0, 0 } }, + { 3545, { 200, 0, 0, 0, 0, 0 } }, // Meditation - { 3546, { 0, 0, 0, 0, 0 } }, + { 3546, { 0, 0, 0, 0, 0, 0 } }, // the Forbidden Chakra - { 3547, { 250, 0, 0, 0, 0 } }, - // Deliverance - { 3548, { 0, 0, 0, 0, 0 } }, + { 3547, { 370, 0, 0, 0, 0, 0 } }, // Fell Cleave - { 3549, { 520, 0, 0, 0, 0 } }, + { 3549, { 590, 0, 0, 0, 0, 0 } }, // Decimate - { 3550, { 280, 0, 0, 0, 0 } }, + { 3550, { 250, 0, 0, 0, 0, 0 } }, // Raw Intuition - { 3551, { 0, 0, 0, 0, 0 } }, + { 3551, { 0, 0, 0, 0, 0, 0 } }, // Equilibrium - { 3552, { 0, 0, 0, 0, 1200 } }, + { 3552, { 0, 0, 0, 0, 0, 1200 } }, // Blood of the Dragon - { 3553, { 0, 0, 0, 0, 0 } }, + { 3553, { 0, 0, 0, 0, 0, 0 } }, // Fang and Claw - { 3554, { 260, 300, 0, 0, 0 } }, + { 3554, { 320, 0, 360, 0, 0, 0 } }, // Geirskogul - { 3555, { 230, 0, 0, 0, 0 } }, + { 3555, { 270, 0, 0, 0, 0, 0 } }, // Wheeling Thrust - { 3556, { 260, 0, 0, 300, 0 } }, + { 3556, { 320, 0, 0, 0, 360, 0 } }, // Battle Litany - { 3557, { 0, 0, 0, 0, 0 } }, + { 3557, { 0, 0, 0, 0, 0, 0 } }, // Empyreal Arrow - { 3558, { 230, 0, 0, 0, 0 } }, + { 3558, { 230, 0, 0, 0, 0, 0 } }, // the Wanderer's Minuet - { 3559, { 100, 0, 0, 0, 0 } }, + { 3559, { 100, 0, 0, 0, 0, 0 } }, // Iron Jaws - { 3560, { 100, 0, 0, 0, 0 } }, + { 3560, { 100, 0, 0, 0, 0, 0 } }, // the Warden's Paean - { 3561, { 0, 0, 0, 0, 0 } }, + { 3561, { 0, 0, 0, 0, 0, 0 } }, // Sidewinder - { 3562, { 100, 0, 0, 0, 0 } }, + { 3562, { 100, 0, 0, 0, 0, 0 } }, // Armor Crush - { 3563, { 100, 160, 0, 0, 0 } }, - // Shadewalker - { 3564, { 0, 0, 0, 0, 0 } }, - // Smoke Screen - { 3565, { 0, 0, 0, 0, 0 } }, + { 3563, { 100, 330, 160, 0, 0, 0 } }, // Dream Within a Dream - { 3566, { 150, 0, 0, 0, 0 } }, - // Duality - { 3567, { 0, 0, 0, 0, 0 } }, + { 3566, { 200, 0, 0, 0, 0, 0 } }, // Stone III - { 3568, { 210, 0, 0, 0, 0 } }, + { 3568, { 240, 0, 0, 0, 0, 0 } }, // Asylum - { 3569, { 0, 0, 0, 0, 100 } }, + { 3569, { 0, 0, 0, 0, 0, 100 } }, // Tetragrammaton - { 3570, { 0, 0, 0, 0, 700 } }, + { 3570, { 0, 0, 0, 0, 0, 700 } }, // Assize - { 3571, { 400, 0, 0, 0, 400 } }, - // Aero III - { 3572, { 50, 0, 0, 0, 0 } }, + { 3571, { 400, 0, 0, 0, 0, 400 } }, // Ley Lines - { 3573, { 0, 0, 0, 0, 0 } }, + { 3573, { 0, 0, 0, 0, 0, 0 } }, // Sharpcast - { 3574, { 0, 0, 0, 0, 0 } }, + { 3574, { 0, 0, 0, 0, 0, 0 } }, // Enochian - { 3575, { 0, 0, 0, 0, 0 } }, + { 3575, { 0, 0, 0, 0, 0, 0 } }, // Blizzard IV - { 3576, { 260, 0, 0, 0, 0 } }, + { 3576, { 300, 0, 0, 0, 0, 0 } }, // Fire IV - { 3577, { 300, 0, 0, 0, 0 } }, + { 3577, { 300, 0, 0, 0, 0, 0 } }, // Painflare - { 3578, { 180, 0, 0, 0, 0 } }, + { 3578, { 150, 0, 0, 0, 0, 0 } }, // Ruin III - { 3579, { 120, 0, 0, 0, 0 } }, + { 3579, { 100, 0, 0, 0, 0, 0 } }, // Tri-disaster - { 3580, { 0, 0, 0, 0, 0 } }, + { 3580, { 0, 0, 0, 0, 0, 0 } }, // Dreadwyrm Trance - { 3581, { 0, 0, 0, 0, 0 } }, + { 3581, { 0, 0, 0, 0, 0, 0 } }, // Deathflare - { 3582, { 400, 0, 0, 0, 0 } }, + { 3582, { 400, 0, 0, 0, 0, 0 } }, // Indomitability - { 3583, { 0, 0, 0, 0, 500 } }, + { 3583, { 0, 0, 0, 0, 0, 400 } }, // Broil - { 3584, { 190, 0, 0, 0, 0 } }, + { 3584, { 240, 0, 0, 0, 0, 0 } }, // Deployment Tactics - { 3585, { 0, 0, 0, 0, 0 } }, + { 3585, { 0, 0, 0, 0, 0, 0 } }, // Emergency Tactics - { 3586, { 0, 0, 0, 0, 0 } }, + { 3586, { 0, 0, 0, 0, 0, 0 } }, // Dissipation - { 3587, { 0, 0, 0, 0, 0 } }, + { 3587, { 0, 0, 0, 0, 0, 0 } }, // Draw - { 3590, { 0, 0, 0, 0, 0 } }, - // Royal Road - { 3591, { 0, 0, 0, 0, 0 } }, - // Spread - { 3592, { 0, 0, 0, 0, 0 } }, + { 3590, { 0, 0, 0, 0, 0, 0 } }, // Redraw - { 3593, { 0, 0, 0, 0, 0 } }, + { 3593, { 0, 0, 0, 0, 0, 0 } }, // Benefic - { 3594, { 0, 0, 0, 0, 400 } }, + { 3594, { 0, 0, 0, 0, 0, 400 } }, // Aspected Benefic - { 3595, { 0, 0, 0, 0, 200 } }, + { 3595, { 0, 0, 0, 0, 0, 200 } }, // Malefic - { 3596, { 150, 0, 0, 0, 0 } }, + { 3596, { 150, 0, 0, 0, 0, 0 } }, // Malefic II - { 3598, { 180, 0, 0, 0, 0 } }, + { 3598, { 170, 0, 0, 0, 0, 0 } }, // Combust - { 3599, { 0, 0, 0, 0, 0 } }, + { 3599, { 0, 0, 0, 0, 0, 0 } }, // Helios - { 3600, { 0, 0, 0, 0, 300 } }, + { 3600, { 0, 0, 0, 0, 0, 330 } }, // Aspected Helios - { 3601, { 0, 0, 0, 0, 200 } }, + { 3601, { 0, 0, 0, 0, 0, 100 } }, // Ascend - { 3603, { 0, 0, 0, 0, 0 } }, + { 3603, { 0, 0, 0, 0, 0, 0 } }, // Diurnal Sect - { 3604, { 0, 0, 0, 0, 0 } }, + { 3604, { 0, 0, 0, 0, 0, 0 } }, // Nocturnal Sect - { 3605, { 0, 0, 0, 0, 0 } }, + { 3605, { 0, 0, 0, 0, 0, 0 } }, // Lightspeed - { 3606, { 0, 0, 0, 0, 0 } }, + { 3606, { 0, 0, 0, 0, 0, 0 } }, // Combust II - { 3608, { 0, 0, 0, 0, 0 } }, + { 3608, { 0, 0, 0, 0, 0, 0 } }, // Benefic II - { 3610, { 0, 0, 0, 0, 650 } }, - // Time Dilation - { 3611, { 0, 0, 0, 0, 0 } }, + { 3610, { 0, 0, 0, 0, 0, 700 } }, // Synastry - { 3612, { 0, 0, 0, 0, 0 } }, + { 3612, { 0, 0, 0, 0, 0, 0 } }, // Collective Unconscious - { 3613, { 0, 0, 0, 0, 150 } }, + { 3613, { 0, 0, 0, 0, 0, 50 } }, // Essential Dignity - { 3614, { 0, 0, 0, 0, 400 } }, + { 3614, { 0, 0, 0, 0, 0, 400 } }, // Gravity - { 3615, { 200, 0, 0, 0, 0 } }, - // Celestial Opposition - { 3616, { 0, 0, 0, 0, 0 } }, + { 3615, { 130, 0, 0, 0, 0, 0 } }, // Hard Slash - { 3617, { 150, 0, 0, 0, 0 } }, - // Spinning Slash - { 3619, { 100, 0, 0, 0, 0 } }, + { 3617, { 200, 0, 0, 0, 0, 0 } }, // Unleash - { 3621, { 50, 0, 0, 0, 0 } }, + { 3621, { 150, 0, 0, 0, 0, 0 } }, // Syphon Strike - { 3623, { 100, 0, 0, 0, 0 } }, + { 3623, { 100, 300, 0, 0, 0, 0 } }, // Unmend - { 3624, { 150, 0, 0, 0, 0 } }, + { 3624, { 150, 0, 0, 0, 0, 0 } }, // Blood Weapon - { 3625, { 0, 0, 0, 0, 0 } }, - // Power Slash - { 3627, { 100, 0, 0, 0, 0 } }, - // Darkside - { 3628, { 0, 0, 0, 0, 0 } }, + { 3625, { 0, 0, 0, 0, 0, 0 } }, // Grit - { 3629, { 0, 0, 0, 0, 0 } }, - // Blood Price - { 3631, { 0, 0, 0, 0, 0 } }, + { 3629, { 0, 0, 0, 0, 0, 0 } }, // Souleater - { 3632, { 100, 0, 0, 0, 0 } }, - // Dark Passenger - { 3633, { 140, 0, 0, 0, 0 } }, + { 3632, { 100, 400, 0, 0, 0, 300 } }, // Dark Mind - { 3634, { 0, 0, 0, 0, 0 } }, - // Dark Arts - { 3635, { 0, 0, 0, 0, 0 } }, + { 3634, { 0, 0, 0, 0, 0, 0 } }, // Shadow Wall - { 3636, { 0, 0, 0, 0, 0 } }, + { 3636, { 0, 0, 0, 0, 0, 0 } }, // Living Dead - { 3638, { 0, 0, 0, 0, 0 } }, + { 3638, { 0, 0, 0, 0, 0, 0 } }, // Salted Earth - { 3639, { 75, 0, 0, 0, 0 } }, + { 3639, { 60, 0, 0, 0, 0, 0 } }, // Plunge - { 3640, { 200, 0, 0, 0, 0 } }, + { 3640, { 200, 0, 0, 0, 0, 0 } }, // Abyssal Drain - { 3641, { 120, 0, 0, 0, 0 } }, - // Sole Survivor - { 3642, { 0, 0, 0, 0, 0 } }, + { 3641, { 200, 0, 0, 0, 0, 200 } }, // Carve and Spit - { 3643, { 100, 0, 0, 0, 0 } }, + { 3643, { 450, 0, 0, 0, 0, 0 } }, // Big Shot - { 4238, { 0, 0, 0, 0, 0 } }, + { 4238, { 0, 0, 0, 0, 0, 0 } }, // Desperado - { 4239, { 0, 0, 0, 0, 0 } }, + { 4239, { 0, 0, 0, 0, 0, 0 } }, // Land Waker - { 4240, { 0, 0, 0, 0, 0 } }, + { 4240, { 0, 0, 0, 0, 0, 0 } }, // Dark Force - { 4241, { 0, 0, 0, 0, 0 } }, + { 4241, { 0, 0, 0, 0, 0, 0 } }, // Dragonsong Dive - { 4242, { 0, 0, 0, 0, 0 } }, + { 4242, { 0, 0, 0, 0, 0, 0 } }, // Chimatsuri - { 4243, { 0, 0, 0, 0, 0 } }, + { 4243, { 0, 0, 0, 0, 0, 0 } }, // Sagittarius Arrow - { 4244, { 0, 0, 0, 0, 0 } }, + { 4244, { 0, 0, 0, 0, 0, 0 } }, // Satellite Beam - { 4245, { 0, 0, 0, 0, 0 } }, + { 4245, { 0, 0, 0, 0, 0, 0 } }, // Teraflare - { 4246, { 0, 0, 0, 0, 0 } }, + { 4246, { 0, 0, 0, 0, 0, 0 } }, // Angel Feathers - { 4247, { 0, 0, 0, 0, 0 } }, + { 4247, { 0, 0, 0, 0, 0, 0 } }, // Astral Stasis - { 4248, { 0, 0, 0, 0, 0 } }, + { 4248, { 0, 0, 0, 0, 0, 0 } }, // Form Shift - { 4262, { 0, 0, 0, 0, 0 } }, + { 4262, { 0, 0, 0, 0, 0, 0 } }, // Cannonfire - { 4271, { 0, 0, 0, 0, 0 } }, + { 4271, { 0, 0, 0, 0, 0, 0 } }, // the Balance - { 4401, { 0, 0, 0, 0, 0 } }, - // the Bole - { 4402, { 0, 0, 0, 0, 0 } }, + { 4401, { 0, 0, 0, 0, 0, 0 } }, // the Arrow - { 4403, { 0, 0, 0, 0, 0 } }, + { 4402, { 0, 0, 0, 0, 0, 0 } }, // the Spear - { 4404, { 0, 0, 0, 0, 0 } }, - // the Ewer - { 4405, { 0, 0, 0, 0, 0 } }, - // the Spire - { 4406, { 0, 0, 0, 0, 0 } }, - // the Balance - { 4407, { 0, 0, 0, 0, 0 } }, + { 4403, { 0, 0, 0, 0, 0, 0 } }, // the Bole - { 4408, { 0, 0, 0, 0, 0 } }, - // the Arrow - { 4409, { 0, 0, 0, 0, 0 } }, - // the Spear - { 4410, { 0, 0, 0, 0, 0 } }, + { 4404, { 0, 0, 0, 0, 0, 0 } }, // the Ewer - { 4411, { 0, 0, 0, 0, 0 } }, + { 4405, { 0, 0, 0, 0, 0, 0 } }, // the Spire - { 4412, { 0, 0, 0, 0, 0 } }, - // the Balance - { 4413, { 0, 0, 0, 0, 0 } }, - // the Bole - { 4414, { 0, 0, 0, 0, 0 } }, - // the Arrow - { 4415, { 0, 0, 0, 0, 0 } }, - // the Spear - { 4416, { 0, 0, 0, 0, 0 } }, - // the Ewer - { 4417, { 0, 0, 0, 0, 0 } }, - // the Spire - { 4418, { 0, 0, 0, 0, 0 } }, - // the Balance - { 4419, { 0, 0, 0, 0, 0 } }, - // the Bole - { 4420, { 0, 0, 0, 0, 0 } }, - // the Arrow - { 4421, { 0, 0, 0, 0, 0 } }, - // the Spear - { 4422, { 0, 0, 0, 0, 0 } }, - // the Ewer - { 4423, { 0, 0, 0, 0, 0 } }, - // the Spire - { 4424, { 0, 0, 0, 0, 0 } }, - // Empty Road - { 4645, { 0, 0, 0, 0, 0 } }, - // Undraw Spread - { 4646, { 0, 0, 0, 0, 0 } }, + { 4406, { 0, 0, 0, 0, 0, 0 } }, // Raiton - { 4977, { 0, 0, 0, 0, 0 } }, + { 4977, { 0, 0, 0, 0, 0, 0 } }, // Raiton - { 5069, { 0, 0, 0, 0, 0 } }, + { 5069, { 0, 0, 0, 0, 0, 0 } }, // attack - { 5199, { 0, 0, 0, 0, 0 } }, + { 5199, { 0, 0, 0, 0, 0, 0 } }, // attack - { 5846, { 0, 0, 0, 0, 0 } }, + { 5846, { 0, 0, 0, 0, 0, 0 } }, // Stickyloom - { 5874, { 0, 0, 0, 0, 0 } }, + { 5874, { 0, 0, 0, 0, 0, 0 } }, // Void Fire II - { 6274, { 0, 0, 0, 0, 0 } }, + { 6274, { 0, 0, 0, 0, 0, 0 } }, // Total Eclipse - { 7381, { 110, 0, 0, 0, 0 } }, + { 7381, { 120, 0, 0, 0, 0, 0 } }, // Intervention - { 7382, { 0, 0, 0, 0, 0 } }, + { 7382, { 0, 0, 0, 0, 0, 0 } }, // Requiescat - { 7383, { 350, 0, 0, 0, 0 } }, + { 7383, { 550, 0, 0, 0, 0, 0 } }, // Holy Spirit - { 7384, { 380, 0, 0, 0, 0 } }, + { 7384, { 350, 0, 0, 0, 0, 0 } }, // Passage of Arms - { 7385, { 0, 0, 0, 0, 0 } }, + { 7385, { 0, 0, 0, 0, 0, 0 } }, // Onslaught - { 7386, { 100, 0, 0, 0, 0 } }, + { 7386, { 100, 0, 0, 0, 0, 0 } }, // Upheaval - { 7387, { 300, 0, 0, 0, 0 } }, + { 7387, { 450, 0, 0, 0, 0, 0 } }, // Shake It Off - { 7388, { 0, 0, 0, 0, 0 } }, + { 7388, { 0, 0, 0, 0, 0, 0 } }, // Inner Release - { 7389, { 0, 0, 0, 0, 0 } }, + { 7389, { 0, 0, 0, 0, 0, 0 } }, // Delirium - { 7390, { 0, 0, 0, 0, 0 } }, + { 7390, { 0, 0, 0, 0, 0, 0 } }, // Quietus - { 7391, { 160, 0, 0, 0, 0 } }, + { 7391, { 210, 0, 0, 0, 0, 0 } }, // Bloodspiller - { 7392, { 400, 0, 0, 0, 0 } }, + { 7392, { 600, 0, 0, 0, 0, 0 } }, // The Blackest Night - { 7393, { 0, 0, 0, 0, 0 } }, + { 7393, { 0, 0, 0, 0, 0, 0 } }, // Riddle of Earth - { 7394, { 0, 0, 0, 0, 0 } }, + { 7394, { 0, 0, 0, 0, 0, 0 } }, // Riddle of Fire - { 7395, { 0, 0, 0, 0, 0 } }, + { 7395, { 0, 0, 0, 0, 0, 0 } }, // Brotherhood - { 7396, { 0, 0, 0, 0, 0 } }, + { 7396, { 0, 0, 0, 0, 0, 0 } }, // Sonic Thrust - { 7397, { 100, 0, 0, 0, 0 } }, + { 7397, { 100, 200, 0, 0, 0, 0 } }, // Dragon Sight - { 7398, { 0, 0, 0, 0, 0 } }, + { 7398, { 0, 0, 0, 0, 0, 0 } }, // Mirage Dive - { 7399, { 210, 0, 0, 0, 0 } }, + { 7399, { 250, 0, 0, 0, 0, 0 } }, // Nastrond - { 7400, { 330, 0, 0, 0, 0 } }, + { 7400, { 400, 0, 0, 0, 0, 0 } }, // Hellfrog Medium - { 7401, { 400, 0, 0, 0, 0 } }, + { 7401, { 400, 0, 0, 0, 0, 0 } }, // Bhavacakra - { 7402, { 600, 0, 0, 0, 0 } }, + { 7402, { 500, 0, 0, 0, 0, 0 } }, // Ten Chi Jin - { 7403, { 0, 0, 0, 0, 0 } }, + { 7403, { 0, 0, 0, 0, 0, 0 } }, // Pitch Perfect - { 7404, { 100, 0, 0, 0, 0 } }, + { 7404, { 100, 0, 0, 0, 0, 0 } }, // Troubadour - { 7405, { 0, 0, 0, 0, 0 } }, + { 7405, { 0, 0, 0, 0, 0, 0 } }, // Caustic Bite - { 7406, { 120, 0, 0, 0, 0 } }, + { 7406, { 150, 0, 0, 0, 0, 0 } }, // Stormbite - { 7407, { 120, 0, 0, 0, 0 } }, + { 7407, { 100, 0, 0, 0, 0, 0 } }, // Nature's Minne - { 7408, { 0, 0, 0, 0, 0 } }, + { 7408, { 0, 0, 0, 0, 0, 0 } }, // Refulgent Arrow - { 7409, { 300, 0, 0, 0, 0 } }, - // Cooldown - { 7410, { 150, 0, 0, 0, 0 } }, + { 7409, { 340, 0, 0, 0, 0, 0 } }, + // Heat Blast + { 7410, { 200, 0, 0, 0, 0, 0 } }, // Heated Split Shot - { 7411, { 190, 0, 0, 0, 0 } }, + { 7411, { 200, 0, 0, 0, 0, 0 } }, // Heated Slug Shot - { 7412, { 100, 0, 0, 0, 0 } }, + { 7412, { 100, 300, 0, 0, 0, 0 } }, // Heated Clean Shot - { 7413, { 100, 0, 0, 0, 0 } }, + { 7413, { 100, 400, 0, 0, 0, 0 } }, // Barrel Stabilizer - { 7414, { 0, 0, 0, 0, 0 } }, + { 7414, { 0, 0, 0, 0, 0, 0 } }, // Rook Overdrive - { 7415, { 0, 0, 0, 0, 0 } }, + { 7415, { 0, 0, 0, 0, 0, 0 } }, // Flamethrower - { 7418, { 0, 0, 0, 0, 0 } }, + { 7418, { 0, 0, 0, 0, 0, 0 } }, // Between the Lines - { 7419, { 0, 0, 0, 0, 0 } }, + { 7419, { 0, 0, 0, 0, 0, 0 } }, // Thunder IV - { 7420, { 50, 0, 0, 0, 0 } }, + { 7420, { 50, 0, 0, 0, 0, 0 } }, // Triplecast - { 7421, { 0, 0, 0, 0, 0 } }, + { 7421, { 0, 0, 0, 0, 0, 0 } }, // Foul - { 7422, { 650, 0, 0, 0, 0 } }, + { 7422, { 650, 0, 0, 0, 0, 0 } }, // Aetherpact - { 7423, { 0, 0, 0, 0, 0 } }, + { 7423, { 0, 0, 0, 0, 0, 0 } }, // Bio III - { 7424, { 0, 0, 0, 0, 0 } }, + { 7424, { 0, 0, 0, 0, 0, 0 } }, // Miasma III - { 7425, { 50, 0, 0, 0, 0 } }, + { 7425, { 40, 0, 0, 0, 0, 0 } }, // Ruin IV - { 7426, { 200, 0, 0, 0, 0 } }, + { 7426, { 120, 0, 0, 0, 0, 0 } }, // Summon Bahamut - { 7427, { 0, 0, 0, 0, 0 } }, + { 7427, { 0, 0, 0, 0, 0, 0 } }, // Enkindle Bahamut - { 7429, { 0, 0, 0, 0, 0 } }, + { 7429, { 0, 0, 0, 0, 0, 0 } }, // Thin Air - { 7430, { 0, 0, 0, 0, 0 } }, + { 7430, { 0, 0, 0, 0, 0, 0 } }, // Stone IV - { 7431, { 250, 0, 0, 0, 0 } }, + { 7431, { 280, 0, 0, 0, 0, 0 } }, // Divine Benison - { 7432, { 0, 0, 0, 0, 0 } }, + { 7432, { 0, 0, 0, 0, 0, 0 } }, // Plenary Indulgence - { 7433, { 0, 0, 0, 0, 0 } }, + { 7433, { 0, 0, 0, 0, 0, 200 } }, // Excogitation - { 7434, { 0, 0, 0, 0, 800 } }, + { 7434, { 0, 0, 0, 0, 0, 800 } }, // Broil II - { 7435, { 230, 0, 0, 0, 0 } }, + { 7435, { 260, 0, 0, 0, 0, 0 } }, // Chain Stratagem - { 7436, { 0, 0, 0, 0, 0 } }, + { 7436, { 0, 0, 0, 0, 0, 0 } }, // Aetherpact - { 7437, { 0, 0, 0, 0, 0 } }, + { 7437, { 0, 0, 0, 0, 0, 0 } }, // Earthly Star - { 7439, { 150, 0, 0, 0, 540 } }, + { 7439, { 100, 0, 0, 0, 0, 540 } }, // Malefic III - { 7442, { 220, 0, 0, 0, 0 } }, + { 7442, { 210, 0, 0, 0, 0, 0 } }, // Minor Arcana - { 7443, { 0, 0, 0, 0, 0 } }, + { 7443, { 0, 0, 0, 0, 0, 0 } }, // Lord of Crowns - { 7444, { 300, 0, 0, 0, 0 } }, + { 7444, { 0, 0, 0, 0, 0, 0 } }, // Lady of Crowns - { 7445, { 0, 0, 0, 0, 500 } }, + { 7445, { 0, 0, 0, 0, 0, 0 } }, // Thunder II - { 7447, { 30, 0, 0, 0, 0 } }, + { 7447, { 30, 0, 0, 0, 0, 0 } }, // Sleeve Draw - { 7448, { 0, 0, 0, 0, 0 } }, + { 7448, { 0, 0, 0, 0, 0, 0 } }, // Hakaze - { 7477, { 150, 0, 0, 0, 0 } }, + { 7477, { 170, 0, 0, 0, 0, 0 } }, // Jinpu - { 7478, { 100, 0, 0, 0, 0 } }, + { 7478, { 100, 320, 0, 0, 0, 0 } }, // Shifu - { 7479, { 100, 0, 0, 0, 0 } }, + { 7479, { 100, 320, 0, 0, 0, 0 } }, // Yukikaze - { 7480, { 100, 0, 0, 0, 0 } }, + { 7480, { 100, 400, 0, 0, 0, 0 } }, // Gekko - { 7481, { 100, 0, 0, 0, 0 } }, + { 7481, { 100, 470, 0, 0, 0, 0 } }, // Kasha - { 7482, { 100, 0, 0, 0, 0 } }, + { 7482, { 100, 470, 0, 0, 0, 0 } }, // Fuga - { 7483, { 100, 0, 0, 0, 0 } }, + { 7483, { 100, 0, 0, 0, 0, 0 } }, // Mangetsu - { 7484, { 100, 0, 0, 0, 0 } }, + { 7484, { 100, 160, 0, 0, 0, 0 } }, // Oka - { 7485, { 100, 0, 0, 0, 0 } }, + { 7485, { 100, 160, 0, 0, 0, 0 } }, // Enpi - { 7486, { 100, 0, 0, 0, 0 } }, + { 7486, { 100, 0, 0, 0, 0, 0 } }, // Midare Setsugekka - { 7487, { 720, 0, 0, 0, 0 } }, + { 7487, { 800, 0, 0, 0, 0, 0 } }, // Tenka Goken - { 7488, { 360, 0, 0, 0, 0 } }, + { 7488, { 360, 0, 0, 0, 0, 0 } }, // Higanbana - { 7489, { 240, 0, 0, 0, 0 } }, + { 7489, { 250, 0, 0, 0, 0, 0 } }, // Hissatsu: Shinten - { 7490, { 300, 0, 0, 0, 0 } }, + { 7490, { 320, 0, 0, 0, 0, 0 } }, // Hissatsu: Kyuten - { 7491, { 150, 0, 0, 0, 0 } }, + { 7491, { 150, 0, 0, 0, 0, 0 } }, // Hissatsu: Gyoten - { 7492, { 100, 0, 0, 0, 0 } }, + { 7492, { 100, 0, 0, 0, 0, 0 } }, // Hissatsu: Yaten - { 7493, { 100, 0, 0, 0, 0 } }, + { 7493, { 100, 0, 0, 0, 0, 0 } }, // Hissatsu: Kaiten - { 7494, { 0, 0, 0, 0, 0 } }, - // Hagakure - { 7495, { 0, 0, 0, 0, 0 } }, + { 7494, { 0, 0, 0, 0, 0, 0 } }, // Hissatsu: Guren - { 7496, { 800, 0, 0, 0, 0 } }, + { 7496, { 850, 0, 0, 0, 0, 0 } }, // Meditate - { 7497, { 0, 0, 0, 0, 0 } }, + { 7497, { 0, 0, 0, 0, 0, 0 } }, // Third Eye - { 7498, { 0, 0, 0, 0, 0 } }, + { 7498, { 0, 0, 0, 0, 0, 0 } }, // Meikyo Shisui - { 7499, { 0, 0, 0, 0, 0 } }, - // Ageha - { 7500, { 250, 0, 0, 0, 0 } }, + { 7499, { 0, 0, 0, 0, 0, 0 } }, // Hissatsu: Seigan - { 7501, { 200, 0, 0, 0, 0 } }, + { 7501, { 220, 0, 0, 0, 0, 0 } }, // Merciful Eyes - { 7502, { 0, 0, 0, 0, 200 } }, + { 7502, { 0, 0, 0, 0, 0, 200 } }, // Jolt - { 7503, { 180, 0, 0, 0, 0 } }, + { 7503, { 180, 0, 0, 0, 0, 0 } }, // Riposte - { 7504, { 130, 0, 0, 0, 0 } }, + { 7504, { 130, 0, 0, 0, 0, 0 } }, // Verthunder - { 7505, { 310, 0, 0, 0, 0 } }, + { 7505, { 310, 0, 0, 0, 0, 0 } }, // Corps-a-corps - { 7506, { 130, 0, 0, 0, 0 } }, + { 7506, { 130, 0, 0, 0, 0, 0 } }, // Veraero - { 7507, { 310, 0, 0, 0, 0 } }, - // Tether - { 7508, { 0, 0, 0, 0, 0 } }, + { 7507, { 310, 0, 0, 0, 0, 0 } }, // Scatter - { 7509, { 100, 0, 0, 0, 0 } }, + { 7509, { 120, 0, 0, 0, 0, 0 } }, // Verfire - { 7510, { 270, 0, 0, 0, 0 } }, + { 7510, { 270, 0, 0, 0, 0, 0 } }, // Verstone - { 7511, { 270, 0, 0, 0, 0 } }, + { 7511, { 270, 0, 0, 0, 0, 0 } }, // Zwerchhau - { 7512, { 100, 0, 0, 0, 0 } }, + { 7512, { 100, 150, 0, 0, 0, 0 } }, // Moulinet - { 7513, { 60, 0, 0, 0, 0 } }, + { 7513, { 60, 0, 0, 0, 0, 0 } }, // Vercure - { 7514, { 0, 0, 0, 0, 350 } }, + { 7514, { 0, 0, 0, 0, 0, 350 } }, // Displacement - { 7515, { 130, 0, 0, 0, 0 } }, + { 7515, { 0, 0, 0, 0, 0, 0 } }, // Redoublement - { 7516, { 100, 0, 0, 0, 0 } }, + { 7516, { 100, 230, 0, 0, 0, 0 } }, // Fleche - { 7517, { 420, 0, 0, 0, 0 } }, + { 7517, { 420, 0, 0, 0, 0, 0 } }, // Acceleration - { 7518, { 0, 0, 0, 0, 0 } }, + { 7518, { 0, 0, 0, 0, 0, 0 } }, // Contre Sixte - { 7519, { 350, 0, 0, 0, 0 } }, + { 7519, { 350, 0, 0, 0, 0, 0 } }, // Embolden - { 7520, { 0, 0, 0, 0, 0 } }, + { 7520, { 0, 0, 0, 0, 0, 0 } }, // Manafication - { 7521, { 0, 0, 0, 0, 0 } }, - // Impact - { 7522, { 270, 0, 0, 0, 0 } }, + { 7521, { 0, 0, 0, 0, 0, 0 } }, // Verraise - { 7523, { 0, 0, 0, 0, 0 } }, + { 7523, { 0, 0, 0, 0, 0, 0 } }, // Jolt II - { 7524, { 240, 0, 0, 0, 0 } }, + { 7524, { 250, 0, 0, 0, 0, 0 } }, // Verflare - { 7525, { 600, 0, 0, 0, 0 } }, + { 7525, { 600, 0, 0, 0, 0, 0 } }, // Verholy - { 7526, { 600, 0, 0, 0, 0 } }, + { 7526, { 600, 0, 0, 0, 0, 0 } }, // Enchanted Riposte - { 7527, { 210, 0, 0, 0, 0 } }, + { 7527, { 210, 0, 0, 0, 0, 0 } }, // Enchanted Zwerchhau - { 7528, { 100, 0, 0, 0, 0 } }, + { 7528, { 100, 290, 0, 0, 0, 0 } }, // Enchanted Redoublement - { 7529, { 100, 0, 0, 0, 0 } }, + { 7529, { 100, 470, 0, 0, 0, 0 } }, // Enchanted Moulinet - { 7530, { 200, 0, 0, 0, 0 } }, + { 7530, { 200, 0, 0, 0, 0, 0 } }, // Magitek Cannon - { 7619, { 0, 0, 0, 0, 0 } }, + { 7619, { 0, 0, 0, 0, 0, 0 } }, // Photon Stream - { 7620, { 0, 0, 0, 0, 0 } }, + { 7620, { 0, 0, 0, 0, 0, 0 } }, // Diffractive Magitek Cannon - { 7621, { 0, 0, 0, 0, 0 } }, + { 7621, { 0, 0, 0, 0, 0, 0 } }, // High-powered Magitek Cannon - { 7622, { 0, 0, 0, 0, 0 } }, + { 7622, { 0, 0, 0, 0, 0, 0 } }, // Doom of the Living - { 7861, { 0, 0, 0, 0, 0 } }, - // Vermillion Scourge - { 7862, { 0, 0, 0, 0, 0 } }, - // Earth Tackle - { 7864, { 100, 0, 0, 0, 0 } }, - // Wind Tackle - { 7865, { 65, 0, 0, 0, 0 } }, - // Fire Tackle - { 7866, { 130, 0, 0, 0, 0 } }, + { 7861, { 0, 0, 0, 0, 0, 0 } }, + // Vermilion Scourge + { 7862, { 0, 0, 0, 0, 0, 0 } }, // Iaijutsu - { 7867, { 0, 0, 0, 0, 0 } }, - // Riddle of Wind - { 7868, { 65, 0, 0, 0, 0 } }, + { 7867, { 0, 0, 0, 0, 0, 0 } }, // Dissolve Union - { 7869, { 0, 0, 0, 0, 0 } }, + { 7869, { 0, 0, 0, 0, 0, 0 } }, // Stellar Detonation - { 8324, { 150, 0, 0, 0, 540 } }, + { 8324, { 100, 0, 0, 0, 0, 540 } }, // Broken Ridge - { 8395, { 0, 0, 0, 0, 0 } }, + { 8395, { 0, 0, 0, 0, 0, 0 } }, // Magitek Pulse - { 8624, { 0, 0, 0, 0, 0 } }, + { 8624, { 0, 0, 0, 0, 0, 0 } }, // Magitek Thunder - { 8625, { 0, 0, 0, 0, 0 } }, + { 8625, { 0, 0, 0, 0, 0, 0 } }, // attack - { 8687, { 0, 0, 0, 0, 0 } }, + { 8687, { 0, 0, 0, 0, 0, 0 } }, // Katon - { 9012, { 0, 0, 0, 0, 0 } }, + { 9012, { 0, 0, 0, 0, 0, 0 } }, // Remove Barrel - { 9015, { 0, 0, 0, 0, 0 } }, + { 9015, { 0, 0, 0, 0, 0, 0 } }, // Tenka Goken - { 9143, { 0, 0, 0, 0, 0 } }, + { 9143, { 0, 0, 0, 0, 0, 0 } }, // Thunderous Force - { 9294, { 0, 0, 0, 0, 0 } }, + { 9294, { 0, 0, 0, 0, 0, 0 } }, // Raiton - { 9301, { 0, 0, 0, 0, 0 } }, + { 9301, { 0, 0, 0, 0, 0, 0 } }, // Raiton - { 9302, { 0, 0, 0, 0, 0 } }, + { 9302, { 0, 0, 0, 0, 0, 0 } }, // Bishop Overdrive - { 9372, { 0, 0, 0, 0, 0 } }, + { 9372, { 0, 0, 0, 0, 0, 0 } }, // Undraw - { 9629, { 0, 0, 0, 0, 0 } }, + { 9629, { 0, 0, 0, 0, 0, 0 } }, // Self-detonate - { 9775, { 0, 0, 0, 0, 0 } }, + { 9775, { 0, 0, 0, 0, 0, 0 } }, // Shatterstone - { 9823, { 0, 0, 0, 0, 0 } }, + { 9823, { 0, 0, 0, 0, 0, 0 } }, // attack - { 9996, { 0, 0, 0, 0, 0 } }, + { 9996, { 0, 0, 0, 0, 0, 0 } }, // Ungarmax - { 10001, { 0, 0, 0, 0, 0 } }, + { 10001, { 0, 0, 0, 0, 0, 0 } }, // Starstorm - { 10894, { 0, 0, 0, 0, 0 } }, + { 10894, { 0, 0, 0, 0, 0, 0 } }, // attack - { 10946, { 0, 0, 0, 0, 0 } }, + { 10946, { 0, 0, 0, 0, 0, 0 } }, // attack - { 10947, { 0, 0, 0, 0, 0 } }, + { 10947, { 0, 0, 0, 0, 0, 0 } }, // Ruin III - { 11191, { 200, 0, 0, 0, 0 } }, + { 11191, { 200, 0, 0, 0, 0, 0 } }, // Physick - { 11192, { 0, 0, 0, 0, 400 } }, + { 11192, { 0, 0, 0, 0, 0, 400 } }, // Starstorm - { 11193, { 3600, 0, 0, 0, 0 } }, + { 11193, { 3600, 0, 0, 0, 0, 0 } }, // Snort - { 11383, { 0, 0, 0, 0, 0 } }, + { 11383, { 0, 0, 0, 0, 0, 0 } }, // 4-tonze Weight - { 11384, { 110, 0, 0, 0, 0 } }, + { 11384, { 110, 0, 0, 0, 0, 0 } }, // Water Cannon - { 11385, { 120, 0, 0, 0, 0 } }, + { 11385, { 120, 0, 0, 0, 0, 0 } }, // Song of Torment - { 11386, { 50, 0, 0, 0, 0 } }, + { 11386, { 50, 0, 0, 0, 0, 0 } }, // High Voltage - { 11387, { 90, 0, 0, 0, 0 } }, + { 11387, { 90, 0, 0, 0, 0, 0 } }, // Bad Breath - { 11388, { 0, 0, 0, 0, 0 } }, + { 11388, { 0, 0, 0, 0, 0, 0 } }, // Flying Frenzy - { 11389, { 80, 0, 0, 0, 0 } }, + { 11389, { 80, 0, 0, 0, 0, 0 } }, // Aqua Breath - { 11390, { 90, 0, 0, 0, 0 } }, + { 11390, { 90, 0, 0, 0, 0, 0 } }, // Plaincracker - { 11391, { 130, 0, 0, 0, 0 } }, + { 11391, { 130, 0, 0, 0, 0, 0 } }, // Acorn Bomb - { 11392, { 0, 0, 0, 0, 0 } }, + { 11392, { 0, 0, 0, 0, 0, 0 } }, // Bristle - { 11393, { 0, 0, 0, 0, 0 } }, + { 11393, { 0, 0, 0, 0, 0, 0 } }, // Mind Blast - { 11394, { 100, 0, 0, 0, 0 } }, + { 11394, { 100, 0, 0, 0, 0, 0 } }, // Blood Drain - { 11395, { 20, 0, 0, 0, 0 } }, + { 11395, { 20, 0, 0, 0, 0, 0 } }, // Bomb Toss - { 11396, { 110, 0, 0, 0, 0 } }, + { 11396, { 110, 0, 0, 0, 0, 0 } }, // 1000 Needles - { 11397, { 0, 0, 0, 0, 0 } }, + { 11397, { 0, 0, 0, 0, 0, 0 } }, // Drill Cannons - { 11398, { 120, 0, 0, 0, 0 } }, + { 11398, { 120, 0, 0, 0, 0, 0 } }, // the Look - { 11399, { 130, 0, 0, 0, 0 } }, + { 11399, { 130, 0, 0, 0, 0, 0 } }, // Sharpened Knife - { 11400, { 120, 0, 0, 0, 0 } }, + { 11400, { 120, 0, 0, 0, 0, 0 } }, // Loom - { 11401, { 0, 0, 0, 0, 0 } }, + { 11401, { 0, 0, 0, 0, 0, 0 } }, // Flame Thrower - { 11402, { 130, 0, 0, 0, 0 } }, + { 11402, { 130, 0, 0, 0, 0, 0 } }, // Faze - { 11403, { 0, 0, 0, 0, 0 } }, + { 11403, { 0, 0, 0, 0, 0, 0 } }, // Glower - { 11404, { 130, 0, 0, 0, 0 } }, + { 11404, { 130, 0, 0, 0, 0, 0 } }, // Missile - { 11405, { 0, 0, 0, 0, 0 } }, + { 11405, { 0, 0, 0, 0, 0, 0 } }, // White Wind - { 11406, { 0, 0, 0, 0, 0 } }, + { 11406, { 0, 0, 0, 0, 0, 0 } }, // Final Sting - { 11407, { 1500, 0, 0, 0, 0 } }, + { 11407, { 1500, 0, 0, 0, 0, 0 } }, // Self-destruct - { 11408, { 900, 0, 0, 0, 0 } }, + { 11408, { 900, 0, 0, 0, 0, 0 } }, // Transfusion - { 11409, { 0, 0, 0, 0, 0 } }, + { 11409, { 0, 0, 0, 0, 0, 0 } }, // Toad Oil - { 11410, { 0, 0, 0, 0, 0 } }, + { 11410, { 0, 0, 0, 0, 0, 0 } }, // Off-guard - { 11411, { 0, 0, 0, 0, 0 } }, + { 11411, { 0, 0, 0, 0, 0, 0 } }, // Sticky Tongue - { 11412, { 0, 0, 0, 0, 0 } }, + { 11412, { 0, 0, 0, 0, 0, 0 } }, // Tail Screw - { 11413, { 0, 0, 0, 0, 0 } }, + { 11413, { 0, 0, 0, 0, 0, 0 } }, // Level 5 Petrify - { 11414, { 0, 0, 0, 0, 0 } }, + { 11414, { 0, 0, 0, 0, 0, 0 } }, // Moon Flute - { 11415, { 0, 0, 0, 0, 0 } }, + { 11415, { 0, 0, 0, 0, 0, 0 } }, // Doom - { 11416, { 0, 0, 0, 0, 0 } }, + { 11416, { 0, 0, 0, 0, 0, 0 } }, // Mighty Guard - { 11417, { 0, 0, 0, 0, 0 } }, + { 11417, { 0, 0, 0, 0, 0, 0 } }, // Ice Spikes - { 11418, { 0, 0, 0, 0, 0 } }, + { 11418, { 0, 0, 0, 0, 0, 0 } }, // the Ram's Voice - { 11419, { 130, 0, 0, 0, 0 } }, + { 11419, { 130, 0, 0, 0, 0, 0 } }, // the Dragon's Voice - { 11420, { 110, 0, 0, 0, 0 } }, + { 11420, { 110, 0, 0, 0, 0, 0 } }, // Peculiar Light - { 11421, { 0, 0, 0, 0, 0 } }, + { 11421, { 0, 0, 0, 0, 0, 0 } }, // Ink Jet - { 11422, { 120, 0, 0, 0, 0 } }, + { 11422, { 120, 0, 0, 0, 0, 0 } }, // Flying Sardine - { 11423, { 10, 0, 0, 0, 0 } }, + { 11423, { 10, 0, 0, 0, 0, 0 } }, // Diamondback - { 11424, { 0, 0, 0, 0, 0 } }, + { 11424, { 0, 0, 0, 0, 0, 0 } }, // Fire Angon - { 11425, { 100, 0, 0, 0, 0 } }, + { 11425, { 100, 0, 0, 0, 0, 0 } }, // Feather Rain - { 11426, { 180, 0, 0, 0, 0 } }, + { 11426, { 180, 0, 0, 0, 0, 0 } }, // Eruption - { 11427, { 220, 0, 0, 0, 0 } }, + { 11427, { 220, 0, 0, 0, 0, 0 } }, // Mountain Buster - { 11428, { 310, 0, 0, 0, 0 } }, + { 11428, { 310, 0, 0, 0, 0, 0 } }, // Shock Strike - { 11429, { 310, 0, 0, 0, 0 } }, + { 11429, { 310, 0, 0, 0, 0, 0 } }, // Glass Dance - { 11430, { 290, 0, 0, 0, 0 } }, + { 11430, { 290, 0, 0, 0, 0, 0 } }, // Veil of the Whorl - { 11431, { 0, 0, 0, 0, 0 } }, + { 11431, { 0, 0, 0, 0, 0, 0 } }, // Tri-shackle - { 11482, { 30, 0, 0, 0, 0 } }, + { 11482, { 30, 0, 0, 0, 0, 0 } }, // attack - { 11784, { 0, 0, 0, 0, 0 } }, - // Stone of the Seventh Dawn - { 13423, { 140, 0, 0, 0, 0 } }, - // Aero of the Seventh Dawn - { 13424, { 50, 0, 0, 0, 0 } }, - // Cure of the Seventh Dawn - { 13425, { 0, 0, 0, 0, 700 } }, + { 11784, { 0, 0, 0, 0, 0, 0 } }, + // Stone IV of the Seventh Dawn + { 13423, { 140, 0, 0, 0, 0, 0 } }, + // Aero II of the Seventh Dawn + { 13424, { 50, 0, 0, 0, 0, 0 } }, + // Cure II of the Seventh Dawn + { 13425, { 0, 0, 0, 0, 0, 700 } }, // Aetherwell - { 13426, { 0, 0, 0, 0, 0 } }, + { 13426, { 0, 0, 0, 0, 0, 0 } }, // Thunderous Force - { 14587, { 0, 0, 0, 0, 0 } }, + { 14587, { 0, 0, 0, 0, 0, 0 } }, // Kyokufu - { 14840, { 180, 0, 0, 0, 0 } }, + { 14840, { 180, 0, 0, 0, 0, 0 } }, // Ajisai - { 14841, { 100, 0, 0, 0, 0 } }, + { 14841, { 100, 0, 0, 0, 0, 0 } }, // Hissatsu: Gyoten - { 14842, { 100, 0, 0, 0, 0 } }, + { 14842, { 100, 0, 0, 0, 0, 0 } }, // 冥界恐叫打 - { 14843, { 0, 0, 0, 0, 0 } }, + { 14843, { 0, 0, 0, 0, 0, 0 } }, // Second Wind - { 15375, { 0, 0, 0, 0, 500 } }, + { 15375, { 0, 0, 0, 0, 0, 500 } }, + // Interject + { 15537, { 0, 0, 0, 0, 0, 0 } }, + // Fight or Flight + { 15870, { 0, 0, 0, 0, 0, 0 } }, + // Cascade + { 15989, { 200, 0, 0, 0, 0, 0 } }, + // Fountain + { 15990, { 100, 250, 0, 0, 0, 0 } }, + // Reverse Cascade + { 15991, { 300, 0, 0, 0, 0, 0 } }, + // Fountainfall + { 15992, { 350, 0, 0, 0, 0, 0 } }, + // Windmill + { 15993, { 150, 0, 0, 0, 0, 0 } }, + // Bladeshower + { 15994, { 100, 200, 0, 0, 0, 0 } }, + // Rising Windmill + { 15995, { 250, 0, 0, 0, 0, 0 } }, + // Bloodshower + { 15996, { 300, 0, 0, 0, 0, 0 } }, + // Standard Step + { 15997, { 0, 0, 0, 0, 0, 0 } }, + // Technical Step + { 15998, { 0, 0, 0, 0, 0, 0 } }, + // Emboite + { 15999, { 0, 0, 0, 0, 0, 0 } }, + // Entrechat + { 16000, { 0, 0, 0, 0, 0, 0 } }, + // Jete + { 16001, { 0, 0, 0, 0, 0, 0 } }, + // Pirouette + { 16002, { 0, 0, 0, 0, 0, 0 } }, + // Standard Finish + { 16003, { 0, 0, 0, 0, 0, 0 } }, + // Technical Finish + { 16004, { 0, 0, 0, 0, 0, 0 } }, + // Saber Dance + { 16005, { 600, 0, 0, 0, 0, 0 } }, + // Closed Position + { 16006, { 0, 0, 0, 0, 0, 0 } }, + // Fan Dance + { 16007, { 150, 0, 0, 0, 0, 0 } }, + // Fan Dance II + { 16008, { 100, 0, 0, 0, 0, 0 } }, + // Fan Dance III + { 16009, { 200, 0, 0, 0, 0, 0 } }, + // En Avant + { 16010, { 0, 0, 0, 0, 0, 0 } }, + // Devilment + { 16011, { 0, 0, 0, 0, 0, 0 } }, + // Shield Samba + { 16012, { 0, 0, 0, 0, 0, 0 } }, + // Flourish + { 16013, { 0, 0, 0, 0, 0, 0 } }, + // Improvisation + { 16014, { 0, 0, 0, 0, 0, 0 } }, + // Curing Waltz + { 16015, { 0, 0, 0, 0, 0, 200 } }, + // Keen Edge + { 16137, { 200, 0, 0, 0, 0, 0 } }, + // No Mercy + { 16138, { 0, 0, 0, 0, 0, 0 } }, + // Brutal Shell + { 16139, { 100, 300, 0, 0, 0, 150 } }, + // Camouflage + { 16140, { 0, 0, 0, 0, 0, 0 } }, + // Demon Slice + { 16141, { 150, 0, 0, 0, 0, 0 } }, + // Royal Guard + { 16142, { 0, 0, 0, 0, 0, 0 } }, + // Lightning Shot + { 16143, { 150, 0, 0, 0, 0, 0 } }, + // Danger Zone + { 16144, { 350, 0, 0, 0, 0, 0 } }, + // Solid Barrel + { 16145, { 100, 400, 0, 0, 0, 0 } }, + // Gnashing Fang + { 16146, { 450, 0, 0, 0, 0, 0 } }, + // Savage Claw + { 16147, { 550, 0, 0, 0, 0, 0 } }, + // Nebula + { 16148, { 0, 0, 0, 0, 0, 0 } }, + // Demon Slaughter + { 16149, { 100, 250, 0, 0, 0, 0 } }, + // Wicked Talon + { 16150, { 650, 0, 0, 0, 0, 0 } }, + // Aurora + { 16151, { 0, 0, 0, 0, 0, 200 } }, + // Superbolide + { 16152, { 0, 0, 0, 0, 0, 0 } }, + // Sonic Break + { 16153, { 300, 0, 0, 0, 0, 0 } }, + // Rough Divide + { 16154, { 200, 0, 0, 0, 0, 0 } }, + // Continuation + { 16155, { 0, 0, 0, 0, 0, 0 } }, + // Jugular Rip + { 16156, { 260, 0, 0, 0, 0, 0 } }, + // Abdomen Tear + { 16157, { 280, 0, 0, 0, 0, 0 } }, + // Eye Gouge + { 16158, { 300, 0, 0, 0, 0, 0 } }, + // Bow Shock + { 16159, { 200, 0, 0, 0, 0, 0 } }, + // Heart of Light + { 16160, { 0, 0, 0, 0, 0, 0 } }, + // Heart of Stone + { 16161, { 0, 0, 0, 0, 0, 0 } }, + // Burst Strike + { 16162, { 500, 0, 0, 0, 0, 0 } }, + // Fated Circle + { 16163, { 320, 0, 0, 0, 0, 0 } }, + // Bloodfest + { 16164, { 0, 0, 0, 0, 0, 0 } }, + // Blasting Zone + { 16165, { 800, 0, 0, 0, 0, 0 } }, + // Single Standard Finish + { 16191, { 0, 0, 0, 0, 0, 0 } }, + // Double Standard Finish + { 16192, { 0, 0, 0, 0, 0, 0 } }, + // Single Technical Finish + { 16193, { 0, 0, 0, 0, 0, 0 } }, + // Double Technical Finish + { 16194, { 0, 0, 0, 0, 0, 0 } }, + // Triple Technical Finish + { 16195, { 0, 0, 0, 0, 0, 0 } }, + // Quadruple Technical Finish + { 16196, { 0, 0, 0, 0, 0, 0 } }, + // Physick + { 16230, { 0, 0, 0, 0, 0, 400 } }, + // Rightful Sword + { 16269, { 0, 0, 0, 0, 0, 0 } }, + // Brutal Shell + { 16418, { 0, 0, 0, 0, 0, 0 } }, + // Keen Edge + { 16434, { 0, 0, 0, 0, 0, 0 } }, + // Solid Barrel + { 16435, { 0, 0, 0, 0, 0, 0 } }, + // Soothing Potion + { 16436, { 0, 0, 0, 0, 0, 0 } }, + // Shining Blade + { 16437, { 0, 0, 0, 0, 0, 0 } }, + // Perfect Deception + { 16438, { 0, 0, 0, 0, 0, 0 } }, + // Leap of Faith + { 16439, { 0, 0, 0, 0, 0, 0 } }, + // Prominence + { 16457, { 100, 220, 0, 0, 0, 0 } }, + // Holy Circle + { 16458, { 250, 0, 0, 0, 0, 0 } }, + // Confiteor + { 16459, { 800, 0, 0, 0, 0, 0 } }, + // Atonement + { 16460, { 550, 0, 0, 0, 0, 0 } }, + // Intervene + { 16461, { 200, 0, 0, 0, 0, 0 } }, + // Mythril Tempest + { 16462, { 100, 200, 0, 0, 0, 0 } }, + // Chaotic Cyclone + { 16463, { 400, 0, 0, 0, 0, 0 } }, + // Nascent Flash + { 16464, { 0, 0, 0, 0, 0, 0 } }, + // Inner Chaos + { 16465, { 920, 0, 0, 0, 0, 0 } }, + // Flood of Darkness + { 16466, { 250, 0, 0, 0, 0, 0 } }, + // Edge of Darkness + { 16467, { 350, 0, 0, 0, 0, 0 } }, + // Stalwart Soul + { 16468, { 100, 160, 0, 0, 0, 0 } }, + // Flood of Shadow + { 16469, { 300, 0, 0, 0, 0, 0 } }, + // Edge of Shadow + { 16470, { 500, 0, 0, 0, 0, 0 } }, + // Dark Missionary + { 16471, { 0, 0, 0, 0, 0, 0 } }, + // Living Shadow + { 16472, { 0, 0, 0, 0, 0, 0 } }, + // Four-point Fury + { 16473, { 120, 0, 0, 0, 0, 0 } }, + // Enlightenment + { 16474, { 220, 0, 0, 0, 0, 0 } }, + // Anatman + { 16475, { 0, 0, 0, 0, 0, 0 } }, + // Six-sided Star + { 16476, { 400, 0, 0, 0, 0, 0 } }, + // Coerthan Torment + { 16477, { 100, 230, 0, 0, 0, 0 } }, + // High Jump + { 16478, { 400, 0, 0, 0, 0, 0 } }, + // Raiden Thrust + { 16479, { 330, 0, 0, 0, 0, 0 } }, + // Stardiver + { 16480, { 550, 0, 0, 0, 0, 0 } }, + // Hissatsu: Senei + { 16481, { 1100, 0, 0, 0, 0, 0 } }, + // Ikishoten + { 16482, { 0, 0, 0, 0, 0, 0 } }, + // Tsubame-gaeshi + { 16483, { 0, 0, 0, 0, 0, 0 } }, + // Kaeshi: Higanbana + { 16484, { 375, 0, 0, 0, 0, 0 } }, + // Kaeshi: Goken + { 16485, { 540, 0, 0, 0, 0, 0 } }, + // Kaeshi: Setsugekka + { 16486, { 1200, 0, 0, 0, 0, 0 } }, + // Shoha + { 16487, { 0, 0, 0, 0, 0, 0 } }, + // Hakke Mujinsatsu + { 16488, { 100, 140, 0, 0, 0, 0 } }, + // Meisui + { 16489, { 0, 0, 0, 0, 0, 0 } }, + // Goka Mekkyaku + { 16491, { 400, 0, 0, 0, 0, 0 } }, + // Hyosho Ranryu + { 16492, { 600, 0, 0, 0, 0, 0 } }, + // Bunshin + { 16493, { 0, 0, 0, 0, 0, 0 } }, + // Shadowbite + { 16494, { 100, 0, 0, 0, 0, 0 } }, + // Burst Shot + { 16495, { 230, 0, 0, 0, 0, 0 } }, + // Apex Arrow + { 16496, { 500, 0, 0, 0, 0, 0 } }, + // Auto Crossbow + { 16497, { 180, 0, 0, 0, 0, 0 } }, + // Drill + { 16498, { 700, 0, 0, 0, 0, 0 } }, + // Bioblaster + { 16499, { 60, 0, 0, 0, 0, 0 } }, + // Air Anchor + { 16500, { 700, 0, 0, 0, 0, 0 } }, + // Automaton Queen + { 16501, { 0, 0, 0, 0, 0, 0 } }, + // Queen Overdrive + { 16502, { 0, 0, 0, 0, 0, 0 } }, + // Despair + { 16505, { 380, 0, 0, 0, 0, 0 } }, + // Umbral Soul + { 16506, { 0, 0, 0, 0, 0, 0 } }, + // Xenoglossy + { 16507, { 750, 0, 0, 0, 0, 0 } }, + // Energy Drain + { 16508, { 100, 0, 0, 0, 0, 0 } }, + // Egi Assault + { 16509, { 0, 0, 0, 0, 0, 0 } }, + // Energy Siphon + { 16510, { 40, 0, 0, 0, 0, 0 } }, + // Outburst + { 16511, { 70, 0, 0, 0, 0, 0 } }, + // Egi Assault II + { 16512, { 0, 0, 0, 0, 0, 0 } }, + // Firebird Trance + { 16513, { 0, 0, 0, 0, 0, 0 } }, + // Fountain of Fire + { 16514, { 250, 0, 0, 0, 0, 0 } }, + // Brand of Purgatory + { 16515, { 350, 0, 0, 0, 0, 0 } }, + // Enkindle Phoenix + { 16516, { 0, 0, 0, 0, 0, 0 } }, + // Verthunder II + { 16524, { 0, 0, 0, 0, 0, 0 } }, + // Veraero II + { 16525, { 0, 0, 0, 0, 0, 0 } }, + // Impact + { 16526, { 220, 0, 0, 0, 0, 0 } }, + // Engagement + { 16527, { 150, 0, 0, 0, 0, 0 } }, + // Enchanted Reprise + { 16528, { 220, 0, 0, 0, 0, 0 } }, + // Reprise + { 16529, { 100, 0, 0, 0, 0, 0 } }, + // Scorch + { 16530, { 700, 0, 0, 0, 0, 0 } }, + // Afflatus Solace + { 16531, { 0, 0, 0, 0, 0, 700 } }, + // Dia + { 16532, { 120, 0, 0, 0, 0, 0 } }, + // Glare + { 16533, { 300, 0, 0, 0, 0, 0 } }, + // Afflatus Rapture + { 16534, { 0, 0, 0, 0, 0, 300 } }, + // Afflatus Misery + { 16535, { 900, 0, 0, 0, 0, 0 } }, + // Temperance + { 16536, { 0, 0, 0, 0, 0, 0 } }, + // Whispering Dawn + { 16537, { 0, 0, 0, 0, 0, 0 } }, + // Fey Illumination + { 16538, { 0, 0, 0, 0, 0, 0 } }, + // Art of War + { 16539, { 150, 0, 0, 0, 0, 0 } }, + // Biolysis + { 16540, { 0, 0, 0, 0, 0, 0 } }, + // Broil III + { 16541, { 280, 0, 0, 0, 0, 0 } }, + // Recitation + { 16542, { 0, 0, 0, 0, 0, 0 } }, + // Fey Blessing + { 16543, { 0, 0, 0, 0, 0, 0 } }, + // Summon Seraph + { 16545, { 0, 0, 0, 0, 0, 0 } }, + // Consolation + { 16546, { 0, 0, 0, 0, 0, 0 } }, + // Firebird Trance + { 16549, { 0, 0, 0, 0, 0, 0 } }, + // Divination + { 16552, { 0, 0, 0, 0, 0, 0 } }, + // Celestial Opposition + { 16553, { 0, 0, 0, 0, 0, 100 } }, + // Combust III + { 16554, { 0, 0, 0, 0, 0, 0 } }, + // Malefic IV + { 16555, { 240, 0, 0, 0, 0, 0 } }, + // Celestial Intersection + { 16556, { 0, 0, 0, 0, 0, 150 } }, + // Horoscope + { 16557, { 0, 0, 0, 0, 0, 100 } }, + // Horoscope + { 16558, { 0, 0, 0, 0, 0, 0 } }, + // Neutral Sect + { 16559, { 0, 0, 0, 0, 0, 0 } }, + // Ronkan Fire III + { 16574, { 430, 0, 0, 0, 0, 0 } }, + // Ronkan Blizzard III + { 16575, { 240, 0, 0, 0, 0, 0 } }, + // Ronkan Thunder III + { 16576, { 200, 0, 0, 0, 0, 0 } }, + // Ronkan Flare + { 16577, { 460, 0, 0, 0, 0, 0 } }, + // Falling Star + { 16578, { 1500, 0, 0, 0, 0, 0 } }, + // Detonator + { 16766, { 0, 0, 0, 0, 0, 0 } }, + // Fast Blade + { 16788, { 0, 0, 0, 0, 0, 0 } }, + // Sunshadow + { 16789, { 0, 0, 0, 0, 0, 0 } }, + // Assault I: Glittering Topaz + { 16791, { 0, 0, 0, 0, 0, 0 } }, + // Assault II: Shining Topaz + { 16792, { 0, 0, 0, 0, 0, 0 } }, + // Assault I: Downburst + { 16793, { 0, 0, 0, 0, 0, 0 } }, + // Assault II: Glittering Emerald + { 16794, { 0, 0, 0, 0, 0, 0 } }, + // Assault I: Earthen Armor + { 16795, { 0, 0, 0, 0, 0, 0 } }, + // Assault II: Mountain Buster + { 16796, { 0, 0, 0, 0, 0, 0 } }, + // Assault I: Aerial Slash + { 16797, { 0, 0, 0, 0, 0, 0 } }, + // Assault II: Slipstream + { 16798, { 0, 0, 0, 0, 0, 0 } }, + // Assault I: Crimson Cyclone + { 16799, { 0, 0, 0, 0, 0, 0 } }, + // Assault II: Flaming Crush + { 16800, { 0, 0, 0, 0, 0, 0 } }, + // Enkindle: Earthen Fury + { 16801, { 0, 0, 0, 0, 0, 0 } }, + // Enkindle: Aerial Blast + { 16802, { 0, 0, 0, 0, 0, 0 } }, + // Enkindle: Inferno + { 16803, { 0, 0, 0, 0, 0, 0 } }, + // Rough Divide + { 16804, { 200, 0, 0, 0, 0, 0 } }, + // Tactician + { 16889, { 0, 0, 0, 0, 0, 0 } }, + // Swashbuckler + { 16984, { 0, 0, 0, 0, 0, 0 } }, + // Greatest Eclipse + { 16985, { 0, 0, 0, 0, 0, 0 } }, + // Ronkan Cure II + { 17000, { 0, 0, 0, 0, 0, 1300 } }, + // Ronkan Medica + { 17001, { 0, 0, 0, 0, 0, 500 } }, + // Ronkan Esuna + { 17002, { 0, 0, 0, 0, 0, 0 } }, + // Ronkan Stone II + { 17003, { 200, 0, 0, 0, 0, 0 } }, + // Ronkan Renew + { 17004, { 0, 0, 0, 0, 0, 0 } }, + // Play + { 17055, { 0, 0, 0, 0, 0, 0 } }, + // Gunmetal Soul + { 17105, { 0, 0, 0, 0, 0, 0 } }, + // Crimson Lotus + { 17106, { 0, 0, 0, 0, 0, 0 } }, + // Acidic Bite + { 17122, { 300, 0, 0, 0, 0, 0 } }, + // Heavy Shot + { 17123, { 550, 0, 0, 0, 0, 0 } }, + // Radiant Arrow + { 17124, { 1100, 0, 0, 0, 0, 0 } }, + // Dulling Arrow + { 17125, { 0, 0, 0, 0, 0, 0 } }, + // Aspected Benefic + { 17151, { 0, 0, 0, 0, 0, 200 } }, + // Aspected Helios + { 17152, { 0, 0, 0, 0, 0, 100 } }, + // Hypercharge + { 17209, { 0, 0, 0, 0, 0, 0 } }, + // Summon Eos + { 17215, { 0, 0, 0, 0, 0, 0 } }, + // Summon Selene + { 17216, { 0, 0, 0, 0, 0, 0 } }, + // attack + { 17222, { 0, 0, 0, 0, 0, 0 } }, + // Chivalrous Spirit + { 17236, { 0, 0, 0, 0, 0, 1200 } }, + // Souldeep Invisibility + { 17291, { 0, 0, 0, 0, 0, 0 } }, + // Spinning Edge + { 17413, { 0, 0, 0, 0, 0, 0 } }, + // Gust Slash + { 17414, { 0, 0, 0, 0, 0, 0 } }, + // Aeolian Edge + { 17415, { 0, 0, 0, 0, 0, 0 } }, + // Shadow Fang + { 17416, { 0, 0, 0, 0, 0, 0 } }, + // Armor Crush + { 17417, { 0, 0, 0, 0, 0, 0 } }, + // Throwing Dagger + { 17418, { 0, 0, 0, 0, 0, 0 } }, + // Death Blossom + { 17419, { 0, 0, 0, 0, 0, 0 } }, + // Hakke Mujinsatsu + { 17420, { 0, 0, 0, 0, 0, 0 } }, + // Hunter's Prudence + { 17596, { 0, 0, 0, 0, 0, 1000 } }, + // Nebula + { 17839, { 0, 0, 0, 0, 0, 0 } }, + // Bio + { 17864, { 0, 0, 0, 0, 0, 0 } }, + // Bio II + { 17865, { 0, 0, 0, 0, 0, 0 } }, + // Ruin + { 17869, { 160, 0, 0, 0, 0, 0 } }, + // Ruin II + { 17870, { 0, 0, 0, 0, 0, 0 } }, + // Smackdown + { 17901, { 0, 0, 0, 0, 0, 0 } }, + // 攻撃 + { 18034, { 0, 0, 0, 0, 0, 0 } }, + // Ending + { 18073, { 0, 0, 0, 0, 0, 0 } }, + // Straight Shot + { 18190, { 0, 0, 0, 0, 0, 0 } }, }; \ No newline at end of file diff --git a/src/world/Action/EffectBuilder.cpp b/src/world/Action/EffectBuilder.cpp new file mode 100644 index 00000000..7068c01e --- /dev/null +++ b/src/world/Action/EffectBuilder.cpp @@ -0,0 +1,92 @@ +#include "EffectBuilder.h" +#include "EffectResult.h" + +#include + +#include + +#include + +#include +#include + +#include + +using namespace Sapphire; +using namespace Sapphire::World::Action; +using namespace Sapphire::Network::Packets; + +EffectBuilder::EffectBuilder( Entity::CharaPtr source, uint32_t actionId, uint16_t sequence ) : + m_sourceChara( std::move( source ) ), + m_actionId( actionId ), + m_sequence( sequence ) +{ + +} + +uint64_t EffectBuilder::getResultDelayMs() +{ + // todo: actually figure this retarded shit out + + return Common::Util::getTimeMs() + 850; +} + +EffectResultPtr EffectBuilder::getResult( Entity::CharaPtr& chara ) +{ + auto it = m_resolvedEffects.find( chara->getId() ); + if( it == m_resolvedEffects.end() ) + { + // create a new one and return it + // todo: this feels kinda dirty but makes for easy work + auto result = make_EffectResult( chara, getResultDelayMs() ); + + m_resolvedEffects[ chara->getId() ] = result; + + return result; + } + + return it->second; +} + +void EffectBuilder::healTarget( Entity::CharaPtr& target, uint32_t amount, Common::ActionHitSeverityType severity ) +{ + auto result = getResult( target ); + assert( result ); + + result->heal( amount, severity ); +} + +void EffectBuilder::damageTarget( Entity::CharaPtr& target, uint32_t amount, Common::ActionHitSeverityType severity ) +{ + auto result = getResult( target ); + assert( result ); + + result->damage( amount, severity ); +} + +void EffectBuilder::buildAndSendPackets() +{ + Logger::debug( "EffectBuilder result: " ); + Logger::debug( "Targets afflicted: {}", m_resolvedEffects.size() ); + + for( auto it = m_resolvedEffects.begin(); it != m_resolvedEffects.end(); ) + { + auto result = it->second; + Logger::debug( " - id: {}", result->getTarget()->getId() ); + + auto seq = m_sourceChara->getCurrentTerritory()->getNextEffectSequence(); + + auto effectPacket = std::make_shared< Server::EffectPacket >( m_sourceChara->getId(), result->getTarget()->getId(), m_actionId ); + effectPacket->setRotation( Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ) ); + effectPacket->setSequence( seq, m_sequence ); + + effectPacket->addEffect( result->buildEffectEntry() ); + + m_sourceChara->sendToInRangeSet( effectPacket, true ); + + // add effect to territory + m_sourceChara->getCurrentTerritory()->addEffectResult( std::move( result ) ); + + it = m_resolvedEffects.erase( it ); + } +} \ No newline at end of file diff --git a/src/world/Action/EffectBuilder.h b/src/world/Action/EffectBuilder.h new file mode 100644 index 00000000..d58bebfe --- /dev/null +++ b/src/world/Action/EffectBuilder.h @@ -0,0 +1,39 @@ +#ifndef SAPPHIRE_EFFECTBUILDER_H +#define SAPPHIRE_EFFECTBUILDER_H + +#include +#include + +namespace Sapphire::World::Action +{ + class EffectBuilder + { + public: + EffectBuilder( Entity::CharaPtr source, uint32_t actionId, uint16_t sequence ); + + + void healTarget( Entity::CharaPtr& target, uint32_t amount, + Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalHeal ); + + void damageTarget( Entity::CharaPtr& target, uint32_t amount, + Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalDamage ); + + void buildAndSendPackets(); + + + private: + EffectResultPtr getResult( Entity::CharaPtr& chara ); + + uint64_t getResultDelayMs(); + + private: + uint32_t m_actionId; + uint16_t m_sequence; + + Entity::CharaPtr m_sourceChara; + std::unordered_map< uint32_t, EffectResultPtr > m_resolvedEffects; + }; + +} + +#endif //SAPPHIRE_EFFECTBUILDER_H diff --git a/src/world/Action/EffectResult.cpp b/src/world/Action/EffectResult.cpp new file mode 100644 index 00000000..daf32155 --- /dev/null +++ b/src/world/Action/EffectResult.cpp @@ -0,0 +1,90 @@ +#include "EffectResult.h" + +#include + +#include "Actor/Chara.h" + +using namespace Sapphire; +using namespace Sapphire::World::Action; + + +EffectResult::EffectResult( Entity::CharaPtr target, uint64_t runAfter ) : + m_target( std::move( target ) ), + m_delayMs( runAfter ), + m_value( 0 ), + m_severity( Common::ActionHitSeverityType::NormalDamage ), + m_type( Common::ActionEffectType::Nothing ), + m_param( 0 ) +{ + +} + +Entity::CharaPtr EffectResult::getTarget() const +{ + return m_target; +} + +uint32_t EffectResult::getValue() const +{ + return m_value; +} + +uint64_t EffectResult::getDelay() +{ + return m_delayMs; +} + +void EffectResult::setParam( uint8_t param ) +{ + m_param = param; +} + +void EffectResult::damage( uint32_t amount, Common::ActionHitSeverityType severity ) +{ + m_severity = severity; + m_value = amount; + + m_type = Common::ActionEffectType::Damage; +} + +void EffectResult::heal( uint32_t amount, Sapphire::Common::ActionHitSeverityType severity ) +{ + m_severity = severity; + m_value = amount; + + m_type = Common::ActionEffectType::Heal; +} + +Common::EffectEntry EffectResult::buildEffectEntry() const +{ + Common::EffectEntry entry{}; + + // todo: that retarded shit so > u16 max numbers work + entry.value = getValue(); + entry.hitSeverity = m_severity; + entry.effectType = m_type; + entry.param = m_param; + + return entry; +} + +void EffectResult::execute() +{ + switch( m_type ) + { + case Common::ActionEffectType::Damage: + { + m_target->takeDamage( m_value ); + break; + } + + case Common::ActionEffectType::Heal: + { + m_target->heal( m_value ); + break; + } + + default: + break; + } +} \ No newline at end of file diff --git a/src/world/Action/EffectResult.h b/src/world/Action/EffectResult.h new file mode 100644 index 00000000..f1dd8b9c --- /dev/null +++ b/src/world/Action/EffectResult.h @@ -0,0 +1,46 @@ +#ifndef SAPPHIRE_EFFECTRESULT_H +#define SAPPHIRE_EFFECTRESULT_H + +#include +#include + +namespace Sapphire::World::Action +{ + /*! + * @brief A container for the computed result of an effect on a single actor. Used to apply damage/healing dealt + * at a later point in time. + */ + class EffectResult + { + public: + explicit EffectResult( Entity::CharaPtr target, uint64_t delayMs ); + + void damage( uint32_t amount, Common::ActionHitSeverityType severity ); + void heal( uint32_t amount, Common::ActionHitSeverityType severity ); + + Entity::CharaPtr getTarget() const; + + uint32_t getValue() const; + + uint64_t getDelay(); + + void setParam( uint8_t param ); + + Common::EffectEntry buildEffectEntry() const; + + void execute(); + + private: + uint64_t m_delayMs; + + Entity::CharaPtr m_target; + + Common::ActionHitSeverityType m_severity; + Common::ActionEffectType m_type; + + uint32_t m_value; + uint8_t m_param; + }; +} + +#endif //SAPPHIRE_EFFECTRESULT_H diff --git a/src/world/Actor/Actor.cpp b/src/world/Actor/Actor.cpp index 5d6dbd7c..efaf0e51 100644 --- a/src/world/Actor/Actor.cpp +++ b/src/world/Actor/Actor.cpp @@ -6,7 +6,7 @@ #include #include -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "Network/GameConnection.h" @@ -66,7 +66,7 @@ void Sapphire::Entity::Actor::setPos( float x, float y, float z, bool broadcastU m_pos.z = z; if( broadcastUpdate ) - m_pCurrentZone->updateActorPosition( *this ); + m_pCurrentTerritory->updateActorPosition( *this ); } void Sapphire::Entity::Actor::setPos( const Sapphire::Common::FFXIVARR_POSITION3& pos, bool broadcastUpdate ) @@ -74,7 +74,7 @@ void Sapphire::Entity::Actor::setPos( const Sapphire::Common::FFXIVARR_POSITION3 m_pos = pos; if( broadcastUpdate ) - m_pCurrentZone->updateActorPosition( *this ); + m_pCurrentTerritory->updateActorPosition( *this ); } float Sapphire::Entity::Actor::getRot() const @@ -330,23 +330,23 @@ std::set< Sapphire::Entity::ActorPtr > Sapphire::Entity::Actor::getInRangeActors return tempInRange; } -/*! \return ZonePtr to the current zone, nullptr if not set */ -Sapphire::ZonePtr Sapphire::Entity::Actor::getCurrentZone() const +/*! \return TerritoryPtr to the current zone, nullptr if not set */ +Sapphire::TerritoryPtr Sapphire::Entity::Actor::getCurrentTerritory() const { - return m_pCurrentZone; + return m_pCurrentTerritory; } -/*! \param ZonePtr to the zone to be set as current */ -void Sapphire::Entity::Actor::setCurrentZone( ZonePtr currZone ) +/*! \param TerritoryPtr to the zone to be set as current */ +void Sapphire::Entity::Actor::setCurrentZone( TerritoryPtr currZone ) { - m_pCurrentZone = currZone; + m_pCurrentTerritory = currZone; } /*! \return InstanceContentPtr to the current instance, nullptr if not an instance or not set */ Sapphire::InstanceContentPtr Sapphire::Entity::Actor::getCurrentInstance() const { - if( m_pCurrentZone ) - return m_pCurrentZone->getAsInstanceContent(); + if( m_pCurrentTerritory ) + return m_pCurrentTerritory->getAsInstanceContent(); return nullptr; } @@ -354,8 +354,8 @@ Sapphire::InstanceContentPtr Sapphire::Entity::Actor::getCurrentInstance() const /*! \return QuestBattlePtr to the current instance, nullptr if not an instance or not set */ Sapphire::QuestBattlePtr Sapphire::Entity::Actor::getCurrentQuestBattle() const { - if( m_pCurrentZone ) - return m_pCurrentZone->getAsQuestBattle(); + if( m_pCurrentTerritory ) + return m_pCurrentTerritory->getAsQuestBattle(); return nullptr; } diff --git a/src/world/Actor/Actor.h b/src/world/Actor/Actor.h index f251cbae..80bd066e 100644 --- a/src/world/Actor/Actor.h +++ b/src/world/Actor/Actor.h @@ -32,7 +32,7 @@ namespace Sapphire::Entity /*! Id of the zone the actor currently is in */ uint32_t m_territoryTypeId; /*! Ptr to the ZoneObj the actor belongs to */ - ZonePtr m_pCurrentZone; + TerritoryPtr m_pCurrentTerritory; /*! list of various actors in range */ std::set< ActorPtr > m_inRangeActor; @@ -122,9 +122,9 @@ namespace Sapphire::Entity BNpcPtr getAsBNpc(); - ZonePtr getCurrentZone() const; + TerritoryPtr getCurrentTerritory() const; - void setCurrentZone( ZonePtr currZone ); + void setCurrentZone( TerritoryPtr currZone ); InstanceContentPtr getCurrentInstance() const; diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index 548db5d8..8276842d 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -11,7 +11,7 @@ #include "Forwards.h" #include "Action/Action.h" -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "Network/GameConnection.h" #include "Network/PacketWrappers/ActorControlPacket142.h" @@ -53,7 +53,7 @@ Sapphire::Entity::BNpc::BNpc( FrameworkPtr pFw ) : } Sapphire::Entity::BNpc::BNpc( uint32_t id, BNpcTemplatePtr pTemplate, float posX, float posY, float posZ, float rot, - uint8_t level, uint32_t maxHp, ZonePtr pZone, FrameworkPtr pFw ) : + uint8_t level, uint32_t maxHp, TerritoryPtr pZone, FrameworkPtr pFw ) : Npc( ObjKind::BattleNpc, pFw ) { m_id = id; @@ -78,7 +78,7 @@ Sapphire::Entity::BNpc::BNpc( uint32_t id, BNpcTemplatePtr pTemplate, float posX m_class = ClassJob::Adventurer; - m_pCurrentZone = std::move( pZone ); + m_pCurrentTerritory = std::move( pZone ); m_spawnPos = m_pos; @@ -194,13 +194,13 @@ void Sapphire::Entity::BNpc::setState( BNpcState state ) bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos ) { - auto pNaviProvider = m_pCurrentZone->getNaviProvider(); + auto pNaviProvider = m_pCurrentTerritory->getNaviProvider(); if( !pNaviProvider ) { Logger::error( "No NaviProvider for zone#{0} - {1}", - m_pCurrentZone->getGuId(), - m_pCurrentZone->getInternalName() ); + m_pCurrentTerritory->getGuId(), + m_pCurrentTerritory->getInternalName() ); return false; } @@ -216,7 +216,7 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos ) return true; } - m_pCurrentZone->updateActorPosition( *this ); + m_pCurrentTerritory->updateActorPosition( *this ); face( pos ); setPos( pos1 ); sendPositionUpdate(); @@ -226,13 +226,13 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos ) bool Sapphire::Entity::BNpc::moveTo( const Entity::Chara& targetChara ) { - auto pNaviProvider = m_pCurrentZone->getNaviProvider(); + auto pNaviProvider = m_pCurrentTerritory->getNaviProvider(); if( !pNaviProvider ) { Logger::error( "No NaviProvider for zone#{0} - {1}", - m_pCurrentZone->getGuId(), - m_pCurrentZone->getInternalName() ); + m_pCurrentTerritory->getGuId(), + m_pCurrentTerritory->getInternalName() ); return false; } @@ -248,7 +248,7 @@ bool Sapphire::Entity::BNpc::moveTo( const Entity::Chara& targetChara ) return true; } - m_pCurrentZone->updateActorPosition( *this ); + m_pCurrentTerritory->updateActorPosition( *this ); face( targetChara.getPos() ); setPos( pos1 ); sendPositionUpdate(); @@ -407,7 +407,7 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount ) const uint8_t maxDistanceToOrigin = 40; const uint32_t roamTick = 20; - auto pNaviProvider = m_pCurrentZone->getNaviProvider(); + auto pNaviProvider = m_pCurrentTerritory->getNaviProvider(); if( !pNaviProvider ) return; @@ -692,7 +692,7 @@ void Sapphire::Entity::BNpc::autoAttack( CharaPtr pTarget ) srand( static_cast< uint32_t >( tick ) ); auto pRNGMgr = m_pFw->get< World::Manager::RNGMgr >(); - auto damage = Math::CalcStats::calculateAutoAttackDamage( *this ); + auto damage = Math::CalcStats::calcAutoAttackDamage( *this ); auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), pTarget->getId(), 7 ); effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) ); diff --git a/src/world/Actor/BNpc.h b/src/world/Actor/BNpc.h index 8f14e024..c76f8e99 100644 --- a/src/world/Actor/BNpc.h +++ b/src/world/Actor/BNpc.h @@ -51,7 +51,7 @@ namespace Sapphire::Entity public: BNpc( FrameworkPtr pFw ); BNpc( uint32_t id, BNpcTemplatePtr pTemplate, float posX, float posY, float posZ, float rot, - uint8_t level, uint32_t maxHp, ZonePtr pZone,FrameworkPtr pFw ); + uint8_t level, uint32_t maxHp, TerritoryPtr pZone,FrameworkPtr pFw ); virtual ~BNpc() override; diff --git a/src/world/Actor/Chara.cpp b/src/world/Actor/Chara.cpp index c3a09a0c..77f9004f 100644 --- a/src/world/Actor/Chara.cpp +++ b/src/world/Actor/Chara.cpp @@ -8,7 +8,7 @@ #include "Forwards.h" -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "Network/GameConnection.h" #include "Network/PacketWrappers/ActorControlPacket142.h" @@ -123,6 +123,67 @@ void Sapphire::Entity::Chara::setClass( Common::ClassJob classJob ) m_class = classJob; } +Sapphire::Common::Role Sapphire::Entity::Chara::getRole() const +{ + switch( getClass() ) + { + case ClassJob::Gladiator: + case ClassJob::Marauder: + case ClassJob::Paladin: + case ClassJob::Warrior: + case ClassJob::Darkknight: + case ClassJob::Gunbreaker: + return Role::Tank; + + case ClassJob::Pugilist: + case ClassJob::Lancer: + case ClassJob::Monk: + case ClassJob::Dragoon: + case ClassJob::Rogue: + case ClassJob::Ninja: + case ClassJob::Samurai: + return Role::Melee; + + case ClassJob::Archer: + case ClassJob::Bard: + case ClassJob::Machinist: + case ClassJob::Dancer: + return Role::RangedPhysical; + + case ClassJob::Conjurer: + case ClassJob::Whitemage: + case ClassJob::Scholar: + case ClassJob::Astrologian: + return Role::Healer; + + case ClassJob::Thaumaturge: + case ClassJob::Blackmage: + case ClassJob::Arcanist: + case ClassJob::Summoner: + case ClassJob::Redmage: + case ClassJob::Bluemage: + return Role::RangedMagical; + + case ClassJob::Carpenter: + case ClassJob::Blacksmith: + case ClassJob::Armorer: + case ClassJob::Goldsmith: + case ClassJob::Leatherworker: + case ClassJob::Weaver: + case ClassJob::Alchemist: + case ClassJob::Culinarian: + return Role::Crafter; + + case ClassJob::Miner: + case ClassJob::Botanist: + case ClassJob::Fisher: + return Role::Gatherer; + + default: + return Role::None; + } +} + /*! \param Id of the target to set */ void Sapphire::Entity::Chara::setTargetId( uint64_t targetId ) { @@ -460,18 +521,21 @@ void Sapphire::Entity::Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEf auto statusEffectAdd = makeZonePacket< FFXIVIpcEffectResult >( getId() ); statusEffectAdd->data().actor_id = pEffect->getTargetActorId(); - statusEffectAdd->data().actor_id1 = pEffect->getSrcActorId(); statusEffectAdd->data().current_hp = getHp(); statusEffectAdd->data().current_mp = getMp(); statusEffectAdd->data().current_tp = getTp(); - statusEffectAdd->data().duration = static_cast< float >( pEffect->getDuration() ) / 1000; - statusEffectAdd->data().effect_id = pEffect->getId(); - statusEffectAdd->data().effect_index = nextSlot; statusEffectAdd->data().max_hp = getMaxHp(); statusEffectAdd->data().max_mp = getMaxMp(); statusEffectAdd->data().max_something = 1; //statusEffectAdd->data().unknown2 = 28; - statusEffectAdd->data().param = pEffect->getParam(); + + auto& status = statusEffectAdd->data().statusEntries[0]; + + status.sourceActorId = pEffect->getSrcActorId(); + status.duration = static_cast< float >( pEffect->getDuration() ) / 1000; + status.id = pEffect->getId(); + status.index = nextSlot; + status.param = pEffect->getParam(); sendToInRangeSet( statusEffectAdd, isPlayer() ); } diff --git a/src/world/Actor/Chara.h b/src/world/Actor/Chara.h index 83d14fb6..d9fea85b 100644 --- a/src/world/Actor/Chara.h +++ b/src/world/Actor/Chara.h @@ -209,6 +209,8 @@ namespace Sapphire::Entity void setClass( Common::ClassJob classJob ); + Common::Role getRole() const; + void setTargetId( uint64_t targetId ); uint64_t getTargetId() const; diff --git a/src/world/Actor/EventObject.cpp b/src/world/Actor/EventObject.cpp index b8829d30..cc34720e 100644 --- a/src/world/Actor/EventObject.cpp +++ b/src/world/Actor/EventObject.cpp @@ -102,12 +102,12 @@ uint32_t Sapphire::Entity::EventObject::getHousingLink() const return m_housingLink; } -void Sapphire::Entity::EventObject::setParentInstance( Sapphire::ZonePtr instance ) +void Sapphire::Entity::EventObject::setParentInstance( Sapphire::TerritoryPtr instance ) { m_parentInstance = instance; } -Sapphire::ZonePtr Sapphire::Entity::EventObject::getParentInstance() const +Sapphire::TerritoryPtr Sapphire::Entity::EventObject::getParentInstance() const { return m_parentInstance; } diff --git a/src/world/Actor/EventObject.h b/src/world/Actor/EventObject.h index 5e99256d..7b38f64d 100644 --- a/src/world/Actor/EventObject.h +++ b/src/world/Actor/EventObject.h @@ -13,7 +13,7 @@ namespace Sapphire::Entity Common::FFXIVARR_POSITION3 pos, float rotation, const std::string& givenName = "none" ); using OnTalkEventHandler = std::function< void( Entity::Player&, Entity::EventObjectPtr, - ZonePtr, uint64_t ) >; + TerritoryPtr, uint64_t ) >; uint32_t getGimmickId() const; @@ -35,9 +35,9 @@ namespace Sapphire::Entity const std::string& getName() const; - ZonePtr getParentInstance() const; + TerritoryPtr getParentInstance() const; - void setParentInstance( ZonePtr instance ); + void setParentInstance( TerritoryPtr instance ); void spawn( PlayerPtr pTarget ) override; @@ -56,7 +56,7 @@ namespace Sapphire::Entity uint8_t m_state; float m_scale; std::string m_name; - ZonePtr m_parentInstance; + TerritoryPtr m_parentInstance; OnTalkEventHandler m_onTalkEventHandler; diff --git a/src/world/Actor/Npc.cpp b/src/world/Actor/Npc.cpp index b0c86a90..6dcf112f 100644 --- a/src/world/Actor/Npc.cpp +++ b/src/world/Actor/Npc.cpp @@ -9,7 +9,7 @@ #include "Forwards.h" #include "Action/Action.h" -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "Network/GameConnection.h" #include "Network/PacketWrappers/ActorControlPacket142.h" diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index b008b987..c7ddadee 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -16,7 +16,7 @@ #include "Manager/TerritoryMgr.h" #include "Manager/RNGMgr.h" -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "Territory/ZonePosition.h" #include "Territory/InstanceContent.h" #include "Territory/Land.h" @@ -311,8 +311,8 @@ bool Sapphire::Entity::Player::isAutoattackOn() const void Sapphire::Entity::Player::sendStats() { - auto statPacket = makeZonePacket< FFXIVIpcPlayerStats >( getId() ); + statPacket->data().strength = getStatValue( Common::BaseParam::Strength ); statPacket->data().dexterity = getStatValue( Common::BaseParam::Dexterity ); statPacket->data().vitality = getStatValue( Common::BaseParam::Vitality ); @@ -322,16 +322,14 @@ void Sapphire::Entity::Player::sendStats() statPacket->data().determination = getStatValue( Common::BaseParam::Determination ); statPacket->data().hp = getStatValue( Common::BaseParam::HP ); statPacket->data().mp = getStatValue( Common::BaseParam::MP ); - statPacket->data().accuracy = m_baseStats.accuracy; - statPacket->data().attack = getStatValue( Common::BaseParam::AttackPower ); + statPacket->data().directHitRate = getStatValue( Common::BaseParam::DirectHitRate ); + statPacket->data().attackPower = getStatValue( Common::BaseParam::AttackPower ); statPacket->data().attackMagicPotency = getStatValue( Common::BaseParam::AttackMagicPotency ); statPacket->data().healingMagicPotency = getStatValue( Common::BaseParam::HealingMagicPotency ); statPacket->data().skillSpeed = getStatValue( Common::BaseParam::SkillSpeed ); statPacket->data().spellSpeed = getStatValue( Common::BaseParam::SpellSpeed ); - statPacket->data().spellSpeed1 = getStatValue( Common::BaseParam::SpellSpeed ); - statPacket->data().spellSpeedMod = 100; - - statPacket->data().criticalHitRate = getStatValue( Common::BaseParam::CriticalHit ); + statPacket->data().haste = 100; + statPacket->data().criticalHit = getStatValue( Common::BaseParam::CriticalHit ); statPacket->data().defense = getStatValue( Common::BaseParam::Defense ); statPacket->data().magicDefense = getStatValue( Common::BaseParam::MagicDefense ); statPacket->data().tenacity = getStatValue( Common::BaseParam::Tenacity ); @@ -437,14 +435,14 @@ bool Sapphire::Entity::Player::setInstance( uint32_t instanceContentId ) return setInstance( instance ); } -bool Sapphire::Entity::Player::setInstance( ZonePtr instance ) +bool Sapphire::Entity::Player::setInstance( TerritoryPtr instance ) { m_onEnterEventDone = false; if( !instance ) return false; auto pTeriMgr = m_pFw->get< TerritoryMgr >(); - auto currentZone = getCurrentZone(); + auto currentZone = getCurrentTerritory(); // zoning within the same zone won't cause the prev data to be overwritten if( instance->getTerritoryTypeId() != m_territoryTypeId ) @@ -458,14 +456,14 @@ bool Sapphire::Entity::Player::setInstance( ZonePtr instance ) return pTeriMgr->movePlayer( instance, getAsPlayer() ); } -bool Sapphire::Entity::Player::setInstance( ZonePtr instance, Common::FFXIVARR_POSITION3 pos ) +bool Sapphire::Entity::Player::setInstance( TerritoryPtr instance, Common::FFXIVARR_POSITION3 pos ) { m_onEnterEventDone = false; if( !instance ) return false; auto pTeriMgr = m_pFw->get< TerritoryMgr >(); - auto currentZone = getCurrentZone(); + auto currentZone = getCurrentTerritory(); // zoning within the same zone won't cause the prev data to be overwritten if( instance->getTerritoryTypeId() != m_territoryTypeId ) @@ -489,7 +487,7 @@ bool Sapphire::Entity::Player::exitInstance() { auto pTeriMgr = m_pFw->get< TerritoryMgr >(); - auto pZone = getCurrentZone(); + auto pZone = getCurrentTerritory(); auto pInstance = pZone->getAsInstanceContent(); resetHp(); @@ -596,7 +594,7 @@ void Sapphire::Entity::Player::discover( int16_t map_id, int16_t sub_id ) int32_t offset = 4; auto info = pExdData->get< Sapphire::Data::Map >( - pExdData->get< Sapphire::Data::TerritoryType >( getCurrentZone()->getTerritoryTypeId() )->map ); + pExdData->get< Sapphire::Data::TerritoryType >( getCurrentTerritory()->getTerritoryTypeId() )->map ); if( info->discoveryArrayByte ) offset = 5 + 2 * info->discoveryIndex; else @@ -1065,7 +1063,7 @@ void Sapphire::Entity::Player::update( uint64_t tickCount ) if( m_queuedZoneing && ( tickCount - m_queuedZoneing->m_queueTime ) > 800 ) { Common::FFXIVARR_POSITION3 targetPos = m_queuedZoneing->m_targetPosition; - if( getCurrentZone()->getTerritoryTypeId() != m_queuedZoneing->m_targetZone ) + if( getCurrentTerritory()->getTerritoryTypeId() != m_queuedZoneing->m_targetZone ) { performZoning( m_queuedZoneing->m_targetZone, targetPos, m_queuedZoneing->m_targetRotation ); } @@ -1567,7 +1565,7 @@ void Sapphire::Entity::Player::autoAttack( CharaPtr pTarget ) auto pRNGMgr = m_pFw->get< World::Manager::RNGMgr >(); auto variation = static_cast< uint32_t >( pRNGMgr->getRandGenerator< float >( 0, 3 ).next() ); - auto damage = Math::CalcStats::calculateAutoAttackDamage( *this ); + auto damage = Math::CalcStats::calcAutoAttackDamage( *this ); if( getClass() == ClassJob::Machinist || getClass() == ClassJob::Bard || getClass() == ClassJob::Archer ) { @@ -1683,7 +1681,7 @@ void Sapphire::Entity::Player::sendZonePackets() pServerMgr->updatePlayerName( getId(), getName() ); } - getCurrentZone()->onBeforePlayerZoneIn( *this ); + getCurrentTerritory()->onBeforePlayerZoneIn( *this ); auto initPacket = makeZonePacket< FFXIVIpcInit >( getId() ); initPacket->data().charId = getId(); @@ -1749,17 +1747,17 @@ void Sapphire::Entity::Player::sendZonePackets() sendLandFlags(); auto initZonePacket = makeZonePacket< FFXIVIpcInitZone >( getId() ); - initZonePacket->data().zoneId = getCurrentZone()->getTerritoryTypeId(); - initZonePacket->data().weatherId = static_cast< uint8_t >( getCurrentZone()->getCurrentWeather() ); + initZonePacket->data().zoneId = getCurrentTerritory()->getTerritoryTypeId(); + initZonePacket->data().weatherId = static_cast< uint8_t >( getCurrentTerritory()->getCurrentWeather() ); initZonePacket->data().bitmask = 0x1; - initZonePacket->data().festivalId = getCurrentZone()->getCurrentFestival().first; - initZonePacket->data().additionalFestivalId = getCurrentZone()->getCurrentFestival().second; + initZonePacket->data().festivalId = getCurrentTerritory()->getCurrentFestival().first; + initZonePacket->data().additionalFestivalId = getCurrentTerritory()->getCurrentFestival().second; initZonePacket->data().pos.x = getPos().x; initZonePacket->data().pos.y = getPos().y; initZonePacket->data().pos.z = getPos().z; queuePacket( initZonePacket ); - getCurrentZone()->onPlayerZoneIn( *this ); + getCurrentTerritory()->onPlayerZoneIn( *this ); if( isLogin() ) { diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index 08caf559..efaf1f7d 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -480,10 +480,10 @@ namespace Sapphire::Entity bool setInstance( uint32_t instanceContentId ); /*! sets the players instance & initiates zoning process */ - bool setInstance( ZonePtr instance ); + bool setInstance( TerritoryPtr instance ); /*! sets the players instance & initiates zoning process */ - bool setInstance( Sapphire::ZonePtr instance, Sapphire::Common::FFXIVARR_POSITION3 pos ); + bool setInstance( Sapphire::TerritoryPtr instance, Sapphire::Common::FFXIVARR_POSITION3 pos ); /*! returns the player to their position before zoning into an instance */ bool exitInstance(); diff --git a/src/world/Actor/PlayerEvent.cpp b/src/world/Actor/PlayerEvent.cpp index 507973c8..7db09d0b 100644 --- a/src/world/Actor/PlayerEvent.cpp +++ b/src/world/Actor/PlayerEvent.cpp @@ -11,7 +11,7 @@ #include "Network/PacketWrappers/EventFinishPacket.h" #include "Network/PacketWrappers/DirectorPlayScenePacket.h" -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "ServerMgr.h" #include "Framework.h" diff --git a/src/world/Actor/PlayerInventory.cpp b/src/world/Actor/PlayerInventory.cpp index 77677c64..720f2f2e 100644 --- a/src/world/Actor/PlayerInventory.cpp +++ b/src/world/Actor/PlayerInventory.cpp @@ -3,7 +3,7 @@ #include #include -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "Network/PacketWrappers/ActorControlPacket142.h" #include "Network/PacketWrappers/ActorControlPacket143.h" diff --git a/src/world/Actor/PlayerSql.cpp b/src/world/Actor/PlayerSql.cpp index 91d032a3..61bac0a7 100644 --- a/src/world/Actor/PlayerSql.cpp +++ b/src/world/Actor/PlayerSql.cpp @@ -13,7 +13,7 @@ #include "Network/PacketWrappers/PlayerSetupPacket.h" #include "Manager/TerritoryMgr.h" -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "Inventory/Item.h" #include "Inventory/ItemContainer.h" #include "Manager/ItemMgr.h" @@ -64,7 +64,7 @@ bool Sapphire::Entity::Player::load( uint32_t charId, World::SessionPtr pSession m_prevPos.z = res->getFloat( "OPosZ" ); m_prevRot = res->getFloat( "OPosR" ); - ZonePtr pCurrZone = nullptr; + TerritoryPtr pCurrZone = nullptr; // if the zone is an instanceContent zone, we need to actually find the instance if( pTeriMgr->isInstanceContentTerritory( zoneId ) ) @@ -108,7 +108,7 @@ bool Sapphire::Entity::Player::load( uint32_t charId, World::SessionPtr pSession // see if a valid zone could be found for the character if( !pCurrZone ) { - Logger::error( "[{0}] Zone #{1} not found!", char_id_str, zoneId ); + Logger::error( "[{0}] Territory #{1} not found!", char_id_str, zoneId ); Logger::error( "[{0}] Setting default zone instead", char_id_str ); // default to new gridania diff --git a/src/world/ForwardsZone.h b/src/world/ForwardsZone.h index fb584c7b..4ff4af79 100644 --- a/src/world/ForwardsZone.h +++ b/src/world/ForwardsZone.h @@ -19,7 +19,7 @@ typedef std::vector< x > x ## PtrList; namespace Sapphire { TYPE_FORWARD( Cell ); -TYPE_FORWARD( Zone ); +TYPE_FORWARD( Territory ); TYPE_FORWARD( HousingZone ); TYPE_FORWARD( House ); TYPE_FORWARD( InstanceContent ); @@ -87,6 +87,8 @@ namespace World::Action TYPE_FORWARD( Action ); TYPE_FORWARD( EventAction ); TYPE_FORWARD( ItemAction ); +TYPE_FORWARD( EffectBuilder ); +TYPE_FORWARD( EffectResult ); using ActionCallback = std::function< void( Entity::Player&, uint32_t, uint64_t ) >; } diff --git a/src/world/Manager/ActionMgr.cpp b/src/world/Manager/ActionMgr.cpp index feced875..43d14170 100644 --- a/src/world/Manager/ActionMgr.cpp +++ b/src/world/Manager/ActionMgr.cpp @@ -19,12 +19,13 @@ World::Manager::ActionMgr::ActionMgr( Sapphire::FrameworkPtr pFw ) : } void World::Manager::ActionMgr::handlePlacedPlayerAction( Entity::Player& player, uint32_t actionId, - Data::ActionPtr actionData, Common::FFXIVARR_POSITION3 pos ) + Data::ActionPtr actionData, Common::FFXIVARR_POSITION3 pos, + uint16_t sequence ) { player.sendDebug( "got aoe act: {0}", actionData->name ); - auto action = Action::make_Action( player.getAsPlayer(), actionId, actionData, framework() ); + auto action = Action::make_Action( player.getAsPlayer(), actionId, sequence, actionData, framework() ); if( !action->init() ) return; @@ -42,9 +43,10 @@ void World::Manager::ActionMgr::handlePlacedPlayerAction( Entity::Player& player } void World::Manager::ActionMgr::handleTargetedPlayerAction( Entity::Player& player, uint32_t actionId, - Data::ActionPtr actionData, uint64_t targetId ) + Data::ActionPtr actionData, uint64_t targetId, + uint16_t sequence ) { - auto action = Action::make_Action( player.getAsPlayer(), actionId, actionData, framework() ); + auto action = Action::make_Action( player.getAsPlayer(), actionId, sequence, actionData, framework() ); action->setTargetId( targetId ); diff --git a/src/world/Manager/ActionMgr.h b/src/world/Manager/ActionMgr.h index e3ab37d3..75e238e9 100644 --- a/src/world/Manager/ActionMgr.h +++ b/src/world/Manager/ActionMgr.h @@ -22,9 +22,9 @@ namespace Sapphire::World::Manager ~ActionMgr() = default; void handleTargetedPlayerAction( Entity::Player& player, uint32_t actionId, - Data::ActionPtr actionData, uint64_t targetId ); + Data::ActionPtr actionData, uint64_t targetId, uint16_t sequence ); void handlePlacedPlayerAction( Entity::Player& player, uint32_t actionId, - Data::ActionPtr actionData, Common::FFXIVARR_POSITION3 pos ); + Data::ActionPtr actionData, Common::FFXIVARR_POSITION3 pos, uint16_t sequence ); void handleItemAction( Entity::Player& player, uint32_t itemId, Data::ItemActionPtr itemActionData, uint16_t itemSourceSlot, uint16_t itemSourceContainer ); diff --git a/src/world/Manager/DebugCommandMgr.cpp b/src/world/Manager/DebugCommandMgr.cpp index 76c89a7f..2cad42bb 100644 --- a/src/world/Manager/DebugCommandMgr.cpp +++ b/src/world/Manager/DebugCommandMgr.cpp @@ -27,7 +27,7 @@ #include "Actor/EventObject.h" #include "Actor/BNpc.h" -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "Territory/HousingZone.h" #include "Territory/InstanceContent.h" #include "Territory/QuestBattle.h" @@ -304,7 +304,7 @@ void Sapphire::World::Manager::DebugCommandMgr::set( char* data, Entity::Player& sscanf( params.c_str(), "%d", &weatherId ); - player.getCurrentZone()->setWeatherOverride( static_cast< Common::Weather >( weatherId ) ); + player.getCurrentTerritory()->setWeatherOverride( static_cast< Common::Weather >( weatherId ) ); } else if( subCommand == "festival" ) { @@ -448,7 +448,7 @@ void Sapphire::World::Manager::DebugCommandMgr::add( char* data, Entity::Player& player.sendNotice( "Template {0} not found in cache!", params ); return; } - auto playerZone = player.getCurrentZone(); + auto playerZone = player.getCurrentTerritory(); auto pBNpc = std::make_shared< Entity::BNpc >( playerZone->getNextActorId(), bNpcTemplate, player.getPos().x, @@ -538,7 +538,7 @@ void Sapphire::World::Manager::DebugCommandMgr::add( char* data, Entity::Player& effectPacket->addEffect( entry ); - auto sequence = player.getCurrentZone()->getNextEffectSequence(); + auto sequence = player.getCurrentTerritory()->getNextEffectSequence(); effectPacket->setSequence( sequence ); // effectPacket->setAnimationId( param1 ); @@ -581,11 +581,11 @@ void Sapphire::World::Manager::DebugCommandMgr::get( char* data, Entity::Player& if( ( subCommand == "pos" ) ) { - int16_t map_id = pExdData->get< Sapphire::Data::TerritoryType >( player.getCurrentZone()->getTerritoryTypeId() )->map; + int16_t map_id = pExdData->get< Sapphire::Data::TerritoryType >( player.getCurrentTerritory()->getTerritoryTypeId() )->map; player.sendNotice( "Pos:\n {0}\n {1}\n {2}\n {3}\n MapId: {4}\n ZoneId:{5}", player.getPos().x, player.getPos().y, player.getPos().z, - player.getRot(), map_id, player.getCurrentZone()->getTerritoryTypeId() ); + player.getRot(), map_id, player.getCurrentTerritory()->getTerritoryTypeId() ); } else { @@ -919,7 +919,7 @@ void Sapphire::World::Manager::DebugCommandMgr::instance( char* data, Entity::Pl sscanf( params.c_str(), "%d %d", &index, &value ); - auto instance = std::dynamic_pointer_cast< InstanceContent >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< InstanceContent >( player.getCurrentTerritory() ); if( !instance ) return; @@ -932,7 +932,7 @@ void Sapphire::World::Manager::DebugCommandMgr::instance( char* data, Entity::Pl sscanf( params.c_str(), "%s %hhu", objName, &state ); - auto instance = std::dynamic_pointer_cast< InstanceContent >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< InstanceContent >( player.getCurrentTerritory() ); if( !instance ) return; @@ -950,7 +950,7 @@ void Sapphire::World::Manager::DebugCommandMgr::instance( char* data, Entity::Pl sscanf( params.c_str(), "%s %i %i", objName, &state1, &state2 ); - auto instance = std::dynamic_pointer_cast< InstanceContent >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< InstanceContent >( player.getCurrentTerritory() ); if( !instance ) return; @@ -969,7 +969,7 @@ void Sapphire::World::Manager::DebugCommandMgr::instance( char* data, Entity::Pl sscanf( params.c_str(), "%hhu", &seq ); - auto instance = std::dynamic_pointer_cast< InstanceContent >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< InstanceContent >( player.getCurrentTerritory() ); if( !instance ) return; @@ -981,7 +981,7 @@ void Sapphire::World::Manager::DebugCommandMgr::instance( char* data, Entity::Pl sscanf( params.c_str(), "%hhu", &branch ); - auto instance = std::dynamic_pointer_cast< InstanceContent >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< InstanceContent >( player.getCurrentTerritory() ); if( !instance ) return; @@ -989,7 +989,7 @@ void Sapphire::World::Manager::DebugCommandMgr::instance( char* data, Entity::Pl } else if( subCommand == "qte_start" ) { - auto instance = std::dynamic_pointer_cast< InstanceContent >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< InstanceContent >( player.getCurrentTerritory() ); if( !instance ) return; @@ -998,7 +998,7 @@ void Sapphire::World::Manager::DebugCommandMgr::instance( char* data, Entity::Pl } else if( subCommand == "event_start" ) { - auto instance = std::dynamic_pointer_cast< InstanceContent >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< InstanceContent >( player.getCurrentTerritory() ); if( !instance ) return; @@ -1007,7 +1007,7 @@ void Sapphire::World::Manager::DebugCommandMgr::instance( char* data, Entity::Pl } else if( subCommand == "event_end" ) { - auto instance = std::dynamic_pointer_cast< InstanceContent >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< InstanceContent >( player.getCurrentTerritory() ); if( !instance ) return; @@ -1064,7 +1064,7 @@ void Sapphire::World::Manager::DebugCommandMgr::questBattle( char* data, Entity: else if( subCommand == "complete" ) { - auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentTerritory() ); if( !instance ) return; @@ -1074,7 +1074,7 @@ void Sapphire::World::Manager::DebugCommandMgr::questBattle( char* data, Entity: else if( subCommand == "fail" ) { - auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentTerritory() ); if( !instance ) return; @@ -1114,7 +1114,7 @@ void Sapphire::World::Manager::DebugCommandMgr::questBattle( char* data, Entity: sscanf( params.c_str(), "%d %d", &index, &value ); - auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentTerritory() ); if( !instance ) return; @@ -1127,7 +1127,7 @@ void Sapphire::World::Manager::DebugCommandMgr::questBattle( char* data, Entity: sscanf( params.c_str(), "%s %hhu", objName, &state ); - auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentTerritory() ); if( !instance ) return; @@ -1145,7 +1145,7 @@ void Sapphire::World::Manager::DebugCommandMgr::questBattle( char* data, Entity: sscanf( params.c_str(), "%s %i %i", objName, &state1, &state2 ); - auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentTerritory() ); if( !instance ) return; @@ -1164,7 +1164,7 @@ void Sapphire::World::Manager::DebugCommandMgr::questBattle( char* data, Entity: sscanf( params.c_str(), "%hhu", &seq ); - auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentTerritory() ); if( !instance ) return; @@ -1176,7 +1176,7 @@ void Sapphire::World::Manager::DebugCommandMgr::questBattle( char* data, Entity: sscanf( params.c_str(), "%hhu", &branch ); - auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentTerritory() ); if( !instance ) return; @@ -1184,7 +1184,7 @@ void Sapphire::World::Manager::DebugCommandMgr::questBattle( char* data, Entity: } else if( subCommand == "qte_start" ) { - auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentTerritory() ); if( !instance ) return; @@ -1193,7 +1193,7 @@ void Sapphire::World::Manager::DebugCommandMgr::questBattle( char* data, Entity: } else if( subCommand == "event_start" ) { - auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentTerritory() ); if( !instance ) return; @@ -1202,7 +1202,7 @@ void Sapphire::World::Manager::DebugCommandMgr::questBattle( char* data, Entity: } else if( subCommand == "event_end" ) { - auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentZone() ); + auto instance = std::dynamic_pointer_cast< QuestBattle >( player.getCurrentTerritory() ); if( !instance ) return; @@ -1252,7 +1252,7 @@ void Sapphire::World::Manager::DebugCommandMgr::housing( char* data, Entity::Pla // // if ( permissionSet < 5 ) // { -// auto pZone = player.getCurrentZone(); +// auto pZone = player.getCurrentTerritory(); // if( pTeriMgr->isHousingTerritory( pZone->getTerritoryTypeId() ) ) // { // auto pHousing = std::dynamic_pointer_cast< HousingZone >( pZone ); @@ -1267,7 +1267,7 @@ void Sapphire::World::Manager::DebugCommandMgr::housing( char* data, Entity::Pla // player.sendLandFlags(); // } // else -// player.sendDebug( "You aren't in a housing Zone." ); +// player.sendDebug( "You aren't in a housing Territory." ); // } // } // else diff --git a/src/world/Manager/HousingMgr.cpp b/src/world/Manager/HousingMgr.cpp index 623c6073..5c773e9f 100644 --- a/src/world/Manager/HousingMgr.cpp +++ b/src/world/Manager/HousingMgr.cpp @@ -16,7 +16,7 @@ #include "Event/EventDefs.h" #include "TerritoryMgr.h" -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "Territory/HousingZone.h" #include "Territory/Housing/HousingInteriorTerritory.h" #include "HousingMgr.h" @@ -362,7 +362,7 @@ void Sapphire::World::Manager::HousingMgr::sendLandSignFree( Entity::Player& pla Sapphire::LandPurchaseResult Sapphire::World::Manager::HousingMgr::purchaseLand( Entity::Player& player, uint8_t plot, uint8_t state ) { - auto pHousing = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ); + auto pHousing = std::dynamic_pointer_cast< HousingZone >( player.getCurrentTerritory() ); auto plotPrice = pHousing->getLand( plot )->getCurrentPrice(); auto gilAvailable = player.getCurrency( CurrencyType::Gil ); @@ -418,7 +418,7 @@ bool Sapphire::World::Manager::HousingMgr::relinquishLand( Entity::Player& playe { // TODO: Fix "permissions" being sent incorrectly // TODO: Add checks for land state before relinquishing - auto pHousing = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ); + auto pHousing = std::dynamic_pointer_cast< HousingZone >( player.getCurrentTerritory() ); auto pLand = pHousing->getLand( plot ); auto plotMaxPrice = pLand->getCurrentPrice(); @@ -660,7 +660,7 @@ void Sapphire::World::Manager::HousingMgr::createHouse( Sapphire::HousePtr house void Sapphire::World::Manager::HousingMgr::buildPresetEstate( Entity::Player& player, uint8_t plotNum, uint32_t presetCatalogId ) { - auto hZone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ); + auto hZone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentTerritory() ); if( !hZone ) return; @@ -830,7 +830,8 @@ void Sapphire::World::Manager::HousingMgr::sendEstateInventory( Entity::Player& // and we have to switch up our way of getting the LandPtr if( plotNum == 255 ) { - auto internalZone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentZone() ); + auto internalZone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( + player.getCurrentTerritory() ); if( !internalZone ) return; @@ -846,7 +847,7 @@ void Sapphire::World::Manager::HousingMgr::sendEstateInventory( Entity::Player& } else { - auto zone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ); + auto zone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentTerritory() ); if( !zone ) return; @@ -971,14 +972,15 @@ void Sapphire::World::Manager::HousingMgr::reqPlaceHousingItem( Sapphire::Entity bool isOutside = false; // inside housing territory - if( auto zone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ) ) + if( auto zone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentTerritory() ) ) { land = zone->getLand( landId ); isOutside = true; } // otherwise, inside a house. landId is 0 when inside a plot - else if( auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentZone() ) ) + else if( auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( + player.getCurrentTerritory() ) ) { // todo: this whole process is retarded and needs to be fixed // perhaps maintain a list of estates by ident inside housingmgr? @@ -1043,12 +1045,13 @@ void Sapphire::World::Manager::HousingMgr::reqPlaceItemInStore( Sapphire::Entity LandPtr land; bool isOutside = false; - if( auto zone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ) ) + if( auto zone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentTerritory() ) ) { land = zone->getLand( landId ); isOutside = true; } - else if( auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentZone() ) ) + else if( auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( + player.getCurrentTerritory() ) ) { // todo: this whole process is retarded and needs to be fixed // perhaps maintain a list of estates by ident inside housingmgr? @@ -1133,7 +1136,7 @@ bool Sapphire::World::Manager::HousingMgr::placeExternalItem( Entity::Player& pl invMgr->updateHousingItemPosition( item ); // add to zone and spawn - auto zone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ); + auto zone = std::dynamic_pointer_cast< HousingZone >( player.getCurrentTerritory() ); assert( zone ); zone->spawnYardObject( ident.landId, freeSlot, *item ); @@ -1146,7 +1149,7 @@ bool Sapphire::World::Manager::HousingMgr::placeInteriorItem( Entity::Player& pl { auto invMgr = framework()->get< InventoryMgr >(); - auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentZone() ); + auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentTerritory() ); assert( zone ); auto ident = zone->getLandIdent(); @@ -1177,7 +1180,7 @@ bool Sapphire::World::Manager::HousingMgr::placeInteriorItem( Entity::Player& pl invMgr->saveHousingContainer( ident, container ); invMgr->updateHousingItemPosition( item ); - auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentZone() ); + auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentTerritory() ); assert( zone ); zone->spawnHousingObject( containerIdx, freeSlot, containerId, item ); @@ -1202,7 +1205,7 @@ Sapphire::Common::HousingObject Sapphire::World::Manager::HousingMgr::getYardObj void Sapphire::World::Manager::HousingMgr::sendInternalEstateInventoryBatch( Sapphire::Entity::Player& player, bool storeroom ) { - auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentZone() ); + auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentTerritory() ); if( !zone ) return; @@ -1243,11 +1246,12 @@ void Sapphire::World::Manager::HousingMgr::reqMoveHousingItem( Entity::Player& p // todo: what happens when either of these fail? how does the server let the client know that the moment failed // as is, if it does fail, the client will be locked and unable to move any item until reentering the territory - if( auto terri = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentZone() ) ) + if( auto terri = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( + player.getCurrentTerritory() ) ) { moveInternalItem( player, ident, *terri, slot, pos, rot ); } - else if( auto terri = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ) ) + else if( auto terri = std::dynamic_pointer_cast< HousingZone >( player.getCurrentTerritory() ) ) { moveExternalItem( player, ident, slot, *terri, pos, rot ); } @@ -1339,7 +1343,8 @@ void Sapphire::World::Manager::HousingMgr::reqRemoveHousingItem( Sapphire::Entit uint16_t containerId, uint8_t slot, bool sendToStoreroom ) { - if( auto terri = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentZone() ) ) + if( auto terri = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( + player.getCurrentTerritory() ) ) { auto ident = terri->getLandIdent(); auto landSet = toLandSetId( ident.territoryTypeId, ident.wardNum ); @@ -1353,7 +1358,7 @@ void Sapphire::World::Manager::HousingMgr::reqRemoveHousingItem( Sapphire::Entit removeInternalItem( player, *terri, containerId, slot, sendToStoreroom ); } - else if( auto terri = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ) ) + else if( auto terri = std::dynamic_pointer_cast< HousingZone >( player.getCurrentTerritory() ) ) { auto land = terri->getLand( plot ); if( !land ) @@ -1542,7 +1547,7 @@ Sapphire::ItemContainerPtr Sapphire::World::Manager::HousingMgr::getFreeEstateIn void Sapphire::World::Manager::HousingMgr::reqEstateExteriorRemodel( Sapphire::Entity::Player& player, uint16_t plot ) { - auto terri = std::dynamic_pointer_cast< HousingZone >( player.getCurrentZone() ); + auto terri = std::dynamic_pointer_cast< HousingZone >( player.getCurrentTerritory() ); if( !terri ) return; @@ -1569,7 +1574,7 @@ void Sapphire::World::Manager::HousingMgr::reqEstateExteriorRemodel( Sapphire::E void Sapphire::World::Manager::HousingMgr::reqEstateInteriorRemodel( Sapphire::Entity::Player& player ) { - auto terri = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentZone() ); + auto terri = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( player.getCurrentTerritory() ); if( !terri ) return; diff --git a/src/world/Manager/PlayerMgr.cpp b/src/world/Manager/PlayerMgr.cpp index 557f9c7f..1f0f60a1 100644 --- a/src/world/Manager/PlayerMgr.cpp +++ b/src/world/Manager/PlayerMgr.cpp @@ -5,7 +5,7 @@ #include #include -#include +#include #include @@ -26,7 +26,7 @@ void Sapphire::World::Manager::PlayerMgr::movePlayerToLandDestination( Sapphire: if( !terriMgr ) return; - Sapphire::ZonePtr destinationZone; + Sapphire::TerritoryPtr destinationZone; auto terriPos = terriMgr->getTerritoryPosition( landId ); if( terriPos ) diff --git a/src/world/Manager/TerritoryMgr.cpp b/src/world/Manager/TerritoryMgr.cpp index fb5fd0ca..83b833e8 100644 --- a/src/world/Manager/TerritoryMgr.cpp +++ b/src/world/Manager/TerritoryMgr.cpp @@ -8,7 +8,7 @@ #include "Actor/Player.h" -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "Territory/ZonePosition.h" #include "Territory/InstanceContent.h" #include "Territory/QuestBattle.h" @@ -181,7 +181,7 @@ bool Sapphire::World::Manager::TerritoryMgr::createDefaultTerritories() uint32_t guid = getNextInstanceId(); - auto pZone = make_Zone( territoryTypeId, guid, territoryInfo->name, pPlaceName->name, framework() ); + auto pZone = make_Territory( territoryTypeId, guid, territoryInfo->name, pPlaceName->name, framework() ); pZone->init(); std::string bgPath = territoryInfo->bg; @@ -197,11 +197,11 @@ bool Sapphire::World::Manager::TerritoryMgr::createDefaultTerritories() hasNaviMesh ? "NAVI" : "", pPlaceName->name ); - InstanceIdToZonePtrMap instanceMap; + InstanceIdToTerritoryPtrMap instanceMap; instanceMap[ guid ] = pZone; - m_guIdToZonePtrMap[ guid ] = pZone; + m_guIdToTerritoryPtrMap[ guid ] = pZone; m_territoryTypeIdToInstanceGuidMap[ territoryTypeId ] = instanceMap; - m_zoneSet.insert( { pZone } ); + m_territorySet.insert( { pZone } ); } @@ -243,12 +243,12 @@ bool Sapphire::World::Manager::TerritoryMgr::createHousingTerritories() pPlaceName->name, framework() ); pHousingZone->init(); - InstanceIdToZonePtrMap instanceMap; + InstanceIdToTerritoryPtrMap instanceMap; instanceMap[ guid ] = pHousingZone; - m_guIdToZonePtrMap[ guid ] = pHousingZone; + m_guIdToTerritoryPtrMap[ guid ] = pHousingZone; m_territoryTypeIdToInstanceGuidMap[ territoryTypeId ][ guid ] = pHousingZone; - m_landSetIdToZonePtrMap[ pHousingZone->getLandSetId() ] = pHousingZone; - m_zoneSet.insert( { pHousingZone } ); + m_landSetIdToTerritoryPtrMap[ pHousingZone->getLandSetId() ] = pHousingZone; + m_territorySet.insert( { pHousingZone } ); } } @@ -256,7 +256,7 @@ bool Sapphire::World::Manager::TerritoryMgr::createHousingTerritories() return true; } -Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::createTerritoryInstance( uint32_t territoryTypeId ) +Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::createTerritoryInstance( uint32_t territoryTypeId ) { if( !isValidTerritory( territoryTypeId ) ) return nullptr; @@ -274,17 +274,17 @@ Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::createTerritoryInstanc Logger::debug( "Starting instance for territory: {0} ({1})", territoryTypeId, pPlaceName->name ); - auto pZone = make_Zone( territoryTypeId, getNextInstanceId(), pTeri->name, pPlaceName->name, framework() ); + auto pZone = make_Territory( territoryTypeId, getNextInstanceId(), pTeri->name, pPlaceName->name, framework() ); pZone->init(); - m_guIdToZonePtrMap[ pZone->getGuId() ] = pZone; + m_guIdToTerritoryPtrMap[ pZone->getGuId() ] = pZone; m_territoryTypeIdToInstanceGuidMap[ pZone->getTerritoryTypeId() ][ pZone->getGuId() ] = pZone; - m_zoneSet.insert( { pZone } ); + m_territorySet.insert( { pZone } ); return pZone; } -Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::createQuestBattle( uint32_t questBattleId ) +Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::createQuestBattle( uint32_t questBattleId ) { auto it = m_questBattleToContentFinderMap.find( questBattleId ); @@ -321,13 +321,13 @@ Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::createQuestBattle( uin pZone->init(); m_questBattleIdToInstanceMap[ questBattleId ][ pZone->getGuId() ] = pZone; - m_guIdToZonePtrMap[ pZone->getGuId() ] = pZone; + m_guIdToTerritoryPtrMap[ pZone->getGuId() ] = pZone; m_instanceZoneSet.insert( pZone ); return pZone; } -Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::createInstanceContent( uint32_t contentFinderConditionId ) +Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::createInstanceContent( uint32_t contentFinderConditionId ) { auto pExdData = framework()->get< Data::ExdDataGenerated >(); @@ -355,19 +355,19 @@ Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::createInstanceContent( pZone->init(); m_instanceContentIdToInstanceMap[ instanceContentId ][ pZone->getGuId() ] = pZone; - m_guIdToZonePtrMap[ pZone->getGuId() ] = pZone; + m_guIdToTerritoryPtrMap[ pZone->getGuId() ] = pZone; m_instanceZoneSet.insert( pZone ); return pZone; } -Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::findOrCreateHousingInterior( const Common::LandIdent landIdent ) +Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::findOrCreateHousingInterior( const Common::LandIdent landIdent ) { // check if zone already spawned first auto ident = *reinterpret_cast< const uint64_t* >( &landIdent ); - auto it = m_landIdentToZonePtrMap.find( ident ); - if( it != m_landIdentToZonePtrMap.end() ) + auto it = m_landIdentToTerritoryPtrMap.find( ident ); + if( it != m_landIdentToTerritoryPtrMap.end() ) { return it->second; } @@ -427,23 +427,23 @@ Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::findOrCreateHousingInt zone->init(); - m_landIdentToZonePtrMap[ ident ] = zone; - m_guIdToZonePtrMap[ zone->getGuId() ] = zone; - m_zoneSet.insert( { zone } ); + m_landIdentToTerritoryPtrMap[ ident ] = zone; + m_guIdToTerritoryPtrMap[ zone->getGuId() ] = zone; + m_territorySet.insert( { zone } ); return zone; } bool Sapphire::World::Manager::TerritoryMgr::removeTerritoryInstance( uint32_t guId ) { - ZonePtr pZone; + TerritoryPtr pZone; if( ( pZone = getTerritoryByGuId( guId ) ) == nullptr ) return false; - m_guIdToZonePtrMap.erase( pZone->getGuId() ); + m_guIdToTerritoryPtrMap.erase( pZone->getGuId() ); m_instanceZoneSet.erase( pZone ); - m_zoneSet.erase( pZone ); + m_territorySet.erase( pZone ); if( isInstanceContentTerritory( pZone->getTerritoryTypeId() ) ) { @@ -456,10 +456,10 @@ bool Sapphire::World::Manager::TerritoryMgr::removeTerritoryInstance( uint32_t g return true; } -Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::getTerritoryByGuId( uint32_t guId ) const +Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::getTerritoryByGuId( uint32_t guId ) const { - auto it = m_guIdToZonePtrMap.find( guId ); - if( it == m_guIdToZonePtrMap.end() ) + auto it = m_guIdToTerritoryPtrMap.find( guId ); + if( it == m_guIdToTerritoryPtrMap.end() ) return nullptr; return it->second; @@ -495,7 +495,7 @@ Sapphire::ZonePositionPtr Sapphire::World::Manager::TerritoryMgr::getTerritoryPo return nullptr; } -Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::getZoneByTerritoryTypeId( uint32_t territoryTypeId ) const +Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::getZoneByTerritoryTypeId( uint32_t territoryTypeId ) const { auto zoneMap = m_territoryTypeIdToInstanceGuidMap.find( territoryTypeId ); if( zoneMap == m_territoryTypeIdToInstanceGuidMap.end() ) @@ -505,10 +505,10 @@ Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::getZoneByTerritoryType return zoneMap->second.begin()->second; } -Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::getZoneByLandSetId( uint32_t landSetId ) const +Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::getZoneByLandSetId( uint32_t landSetId ) const { - auto zoneMap = m_landSetIdToZonePtrMap.find( landSetId ); - if( zoneMap == m_landSetIdToZonePtrMap.end() ) + auto zoneMap = m_landSetIdToTerritoryPtrMap.find( landSetId ); + if( zoneMap == m_landSetIdToTerritoryPtrMap.end() ) return nullptr; return zoneMap->second; @@ -516,7 +516,7 @@ Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::getZoneByLandSetId( ui void Sapphire::World::Manager::TerritoryMgr::updateTerritoryInstances( uint64_t tickCount ) { - for( auto& zone : m_zoneSet ) + for( auto& zone : m_territorySet ) { zone->update( tickCount ); } @@ -527,7 +527,7 @@ void Sapphire::World::Manager::TerritoryMgr::updateTerritoryInstances( uint64_t } // remove internal house zones with nobody in them - for( auto it = m_landIdentToZonePtrMap.begin(); it != m_landIdentToZonePtrMap.end(); ) + for( auto it = m_landIdentToTerritoryPtrMap.begin(); it != m_landIdentToTerritoryPtrMap.end(); ) { auto zone = std::dynamic_pointer_cast< Territory::Housing::HousingInteriorTerritory >( it->second ); assert( zone ); // wtf?? @@ -540,8 +540,8 @@ void Sapphire::World::Manager::TerritoryMgr::updateTerritoryInstances( uint64_t Logger::info( "Removing HousingInteriorTerritory#{0} - has been inactive for 60 seconds", zone->getGuId() ); // remove zone from maps - m_zoneSet.erase( zone ); - it = m_landIdentToZonePtrMap.erase( it ); + m_territorySet.erase( zone ); + it = m_landIdentToTerritoryPtrMap.erase( it ); } else it++; @@ -565,7 +565,7 @@ void Sapphire::World::Manager::TerritoryMgr::updateTerritoryInstances( uint64_t // remove zone from maps m_instanceZoneSet.erase( zone ); - m_guIdToZonePtrMap.erase( zone->getGuId() ); + m_guIdToTerritoryPtrMap.erase( zone->getGuId() ); inIt = m_questBattleIdToInstanceMap[ zone->getQuestBattleId() ].erase( inIt ); } else @@ -598,11 +598,11 @@ bool Sapphire::World::Manager::TerritoryMgr::movePlayer( uint32_t territoryTypeI return movePlayer( pZone, pPlayer ); } -bool Sapphire::World::Manager::TerritoryMgr::movePlayer( ZonePtr pZone, Sapphire::Entity::PlayerPtr pPlayer ) +bool Sapphire::World::Manager::TerritoryMgr::movePlayer( TerritoryPtr pZone, Sapphire::Entity::PlayerPtr pPlayer ) { if( !pZone ) { - Logger::error( "Zone not found on this server." ); + Logger::error( "Territory not found on this server." ); return false; } @@ -628,8 +628,8 @@ bool Sapphire::World::Manager::TerritoryMgr::movePlayer( ZonePtr pZone, Sapphire // mark character as zoning in progress pPlayer->setLoadingComplete( false ); - if( pPlayer->getLastPing() != 0 && pPlayer->getCurrentZone() ) - pPlayer->getCurrentZone()->removeActor( pPlayer ); + if( pPlayer->getLastPing() != 0 && pPlayer->getCurrentTerritory() ) + pPlayer->getCurrentTerritory()->removeActor( pPlayer ); pPlayer->setCurrentZone( pZone ); pZone->pushActor( pPlayer ); @@ -642,7 +642,7 @@ bool Sapphire::World::Manager::TerritoryMgr::movePlayer( ZonePtr pZone, Sapphire return true; } -Sapphire::ZonePtr Sapphire::World::Manager::TerritoryMgr::getLinkedInstance( uint32_t playerId ) const +Sapphire::TerritoryPtr Sapphire::World::Manager::TerritoryMgr::getLinkedInstance( uint32_t playerId ) const { auto it = m_playerIdToInstanceMap.find( playerId ); if( it != m_playerIdToInstanceMap.end() ) @@ -661,7 +661,7 @@ void Sapphire::World::Manager::TerritoryMgr::setCurrentFestival( uint16_t festiv { m_currentFestival = { festivalId, additionalFestival }; - for( const auto& zone : m_zoneSet ) + for( const auto& zone : m_territorySet ) { zone->setCurrentFestival( festivalId, additionalFestival ); } diff --git a/src/world/Manager/TerritoryMgr.h b/src/world/Manager/TerritoryMgr.h index 67b0229b..62967378 100644 --- a/src/world/Manager/TerritoryMgr.h +++ b/src/world/Manager/TerritoryMgr.h @@ -102,21 +102,21 @@ namespace Sapphire::World::Manager bool isHousingTerritory( uint32_t territoryTypeId ) const; /*! creates a new instance for a given territoryTypeId */ - ZonePtr createTerritoryInstance( uint32_t territoryTypeId ); + TerritoryPtr createTerritoryInstance( uint32_t territoryTypeId ); - ZonePtr createInstanceContent( uint32_t contentFinderConditionId ); + TerritoryPtr createInstanceContent( uint32_t contentFinderConditionId ); - ZonePtr createQuestBattle( uint32_t contentFinderConditionId ); + TerritoryPtr createQuestBattle( uint32_t contentFinderConditionId ); void createAndJoinQuestBattle( Entity::Player& player, uint16_t contentFinderConditionId ); - ZonePtr findOrCreateHousingInterior( const Common::LandIdent landIdent ); + TerritoryPtr findOrCreateHousingInterior( const Common::LandIdent landIdent ); /*! removes instance by instanceId, return true if successful */ bool removeTerritoryInstance( uint32_t guId ); - /*! returns a ZonePtr to the instance or nullptr if not found */ - ZonePtr getTerritoryByGuId( uint32_t guId ) const; + /*! returns a TerritoryPtr to the instance or nullptr if not found */ + TerritoryPtr getTerritoryByGuId( uint32_t guId ) const; /*! returns the cached detail of a territory, nullptr if not found */ Data::TerritoryTypePtr getTerritoryDetail( uint32_t territoryTypeId ) const; @@ -129,17 +129,17 @@ namespace Sapphire::World::Manager /*! returns a default Zone by territoryTypeId TODO: Mind multiple instances?! */ - ZonePtr getZoneByTerritoryTypeId( uint32_t territoryTypeId ) const; + TerritoryPtr getZoneByTerritoryTypeId( uint32_t territoryTypeId ) const; /*! returns a Zone by landSetId */ - ZonePtr getZoneByLandSetId( uint32_t landSetId ) const; + TerritoryPtr getZoneByLandSetId( uint32_t landSetId ) const; bool movePlayer( uint32_t territoryTypeId, Entity::PlayerPtr pPlayer ); - bool movePlayer( ZonePtr, Entity::PlayerPtr pPlayer ); + bool movePlayer( TerritoryPtr, Entity::PlayerPtr pPlayer ); /*! returns an instancePtr if the player is still bound to an isntance */ - ZonePtr getLinkedInstance( uint32_t playerId ) const; + TerritoryPtr getLinkedInstance( uint32_t playerId ) const; /*! * @brief Sets the current festival for every zone @@ -163,16 +163,16 @@ namespace Sapphire::World::Manager private: using TerritoryTypeDetailCache = std::unordered_map< uint16_t, Data::TerritoryTypePtr >; - using InstanceIdToZonePtrMap = std::unordered_map< uint32_t, ZonePtr >; - using LandSetIdToZonePtrMap = std::unordered_map< uint32_t, ZonePtr >; - using TerritoryTypeIdToInstanceMap = std::unordered_map< uint16_t, InstanceIdToZonePtrMap >; - using InstanceContentIdToInstanceMap = std::unordered_map< uint16_t, InstanceIdToZonePtrMap >; - using QuestBattleIdToInstanceMap = std::unordered_map< uint16_t, InstanceIdToZonePtrMap >; + using InstanceIdToTerritoryPtrMap = std::unordered_map< uint32_t, TerritoryPtr >; + using LandSetIdToTerritoryPtrMap = std::unordered_map< uint32_t, TerritoryPtr >; + using TerritoryTypeIdToInstanceMap = std::unordered_map< uint16_t, InstanceIdToTerritoryPtrMap >; + using InstanceContentIdToInstanceMap = std::unordered_map< uint16_t, InstanceIdToTerritoryPtrMap >; + using QuestBattleIdToInstanceMap = std::unordered_map< uint16_t, InstanceIdToTerritoryPtrMap >; using QuestBattleIdToContentFinderCondMap = std::unordered_map< uint16_t, uint16_t >; using PlayerIdToInstanceIdMap = std::unordered_map< uint32_t, uint32_t >; using PositionMap = std::unordered_map< int32_t, ZonePositionPtr >; using InstanceIdList = std::vector< uint32_t >; - using LandIdentToZonePtrMap = std::unordered_map< uint64_t, ZonePtr >; + using LandIdentToTerritoryPtrMap = std::unordered_map< uint64_t, TerritoryPtr >; /*! map holding details for territory templates */ TerritoryTypeDetailCache m_territoryTypeDetailCacheMap; @@ -181,7 +181,7 @@ namespace Sapphire::World::Manager TerritoryTypeIdToInstanceMap m_territoryTypeIdToInstanceGuidMap; /*! map holding actual instances of default territories */ - LandSetIdToZonePtrMap m_landSetIdToZonePtrMap; + LandSetIdToTerritoryPtrMap m_landSetIdToTerritoryPtrMap; /*! map holding actual instances of InstanceContent */ InstanceContentIdToInstanceMap m_instanceContentIdToInstanceMap; @@ -190,7 +190,7 @@ namespace Sapphire::World::Manager QuestBattleIdToInstanceMap m_questBattleIdToInstanceMap; /*! flat map for easier lookup of instances by guid */ - InstanceIdToZonePtrMap m_guIdToZonePtrMap; + InstanceIdToTerritoryPtrMap m_guIdToTerritoryPtrMap; /*! map holding positions for zonelines */ PositionMap m_territoryPositionMap; @@ -199,16 +199,16 @@ namespace Sapphire::World::Manager PlayerIdToInstanceIdMap m_playerIdToInstanceMap; /*! map for storing landident to zones, used for internal housing zones */ - LandIdentToZonePtrMap m_landIdentToZonePtrMap; + LandIdentToTerritoryPtrMap m_landIdentToTerritoryPtrMap; /*! internal counter for instanceIds */ uint32_t m_lastInstanceId; - /*! set of ZonePtrs for quick iteration*/ - std::set< ZonePtr > m_zoneSet; + /*! set of TerritoryPtrs for quick iteration*/ + std::set< TerritoryPtr > m_territorySet; - /*! set of ZonePtrs for quick iteration*/ - std::set< ZonePtr > m_instanceZoneSet; + /*! set of TerritoryPtrs for quick iteration*/ + std::set< TerritoryPtr > m_instanceZoneSet; /*! current festival(s) to set for public zones from festival.exd */ std::pair< uint16_t, uint16_t > m_currentFestival; diff --git a/src/world/Math/CalcStats.cpp b/src/world/Math/CalcStats.cpp index f697c73d..d9c6d143 100644 --- a/src/world/Math/CalcStats.cpp +++ b/src/world/Math/CalcStats.cpp @@ -15,93 +15,93 @@ using namespace Sapphire::Math; using namespace Sapphire::Entity; -const int levelTable[81][5] = +const int levelTable[81][6] = { // MAIN,SUB,DIV,HP,ELMT,THREAT - { 1, 1, 1, 1, 1 }, - { 20, 56, 56, 0, 52 }, - { 21, 57, 57, 0, 54 }, - { 22, 60, 60, 0, 56 }, - { 24, 62, 62, 0, 58 }, - { 26, 65, 65, 0, 60 }, - { 27, 68, 68, 0, 62 }, - { 29, 70, 70, 0, 64 }, - { 31, 73, 73, 0, 66 }, - { 33, 76, 76, 0, 68 }, - { 35, 78, 78, 0, 70 }, - { 36, 82, 82, 0, 73 }, - { 38, 85, 85, 0, 75 }, - { 41, 89, 89, 0, 78 }, - { 44, 93, 93, 0, 81 }, - { 46, 96, 96, 0, 84 }, - { 49, 100, 100, 0, 86 }, - { 52, 104, 104, 0, 89 }, - { 54, 109, 109, 0, 93 }, - { 57, 113, 113, 0, 95 }, - { 60, 116, 116, 0, 98 }, - { 63, 122, 122, 0, 102 }, - { 67, 127, 127, 0, 105 }, - { 71, 133, 133, 0, 109 }, - { 74, 138, 138, 0, 113 }, - { 78, 144, 144, 0, 117 }, - { 81, 150, 150, 0, 121 }, - { 85, 155, 155, 0, 125 }, - { 89, 162, 162, 0, 129 }, - { 92, 168, 168, 0, 133 }, - { 97, 173, 173, 0, 137 }, - { 101, 181, 181, 0, 143 }, - { 106, 188, 188, 0, 148 }, - { 110, 194, 194, 0, 153 }, - { 115, 202, 202, 0, 159 }, - { 119, 209, 209, 0, 165 }, - { 124, 215, 215, 0, 170 }, - { 128, 223, 223, 0, 176 }, - { 134, 229, 229, 0, 181 }, - { 139, 236, 236, 0, 186 }, - { 144, 244, 244, 0, 192 }, - { 150, 253, 253, 0, 200 }, - { 155, 263, 263, 0, 207 }, - { 161, 272, 272, 0, 215 }, - { 166, 283, 283, 0, 223 }, - { 171, 292, 292, 0, 231 }, - { 177, 302, 302, 0, 238 }, - { 183, 311, 311, 0, 246 }, - { 189, 322, 322, 0, 254 }, - { 196, 331, 331, 0, 261 }, - { 202, 341, 341, 1700, 269 }, - { 204, 342, 393, 1774, 270 }, - { 205, 344, 444, 1851, 271 }, - { 207, 345, 496, 1931, 273 }, - { 209, 346, 548, 2015, 274 }, - { 210, 347, 600, 2102, 275 }, - { 212, 349, 651, 2194, 276 }, - { 214, 350, 703, 2289, 278 }, - { 215, 351, 755, 2388, 279 }, - { 217, 352, 806, 2492, 280 }, - { 218, 354, 858, 2600, 282 }, - { 224, 355, 941, 2700, 283 }, - { 228, 356, 1032, 2800, 284 }, - { 236, 357, 1133, 2900, 286 }, - { 244, 358, 1243, 3000, 287 }, - { 252, 359, 1364, 3100, 288 }, - { 260, 360, 1497, 3200, 290 }, - { 268, 361, 1643, 3300, 292 }, - { 276, 362, 1802, 3400, 293 }, - { 284, 363, 1978, 3500, 294 }, - { 292, 364, 2170, 3600, 295 }, + { 1, 1, 1, 1, 1, 1 }, + { 20, 56, 56, 0, 52, 2 }, + { 21, 57, 57, 0, 54, 2 }, + { 22, 60, 60, 0, 56, 3 }, + { 24, 62, 62, 0, 58, 3 }, + { 26, 65, 65, 0, 60, 3 }, + { 27, 68, 68, 0, 62, 3 }, + { 29, 70, 70, 0, 64, 4 }, + { 31, 73, 73, 0, 66, 4 }, + { 33, 76, 76, 0, 68, 4 }, + { 35, 78, 78, 0, 70, 5 }, + { 36, 82, 82, 0, 73, 5 }, + { 38, 85, 85, 0, 75, 5 }, + { 41, 89, 89, 0, 78, 6 }, + { 44, 93, 93, 0, 81, 6 }, + { 46, 96, 96, 0, 84, 7 }, + { 49, 100, 100, 0, 86, 7 }, + { 52, 104, 104, 0, 89, 8 }, + { 54, 109, 109, 0, 93, 9 }, + { 57, 113, 113, 0, 95, 9 }, + { 60, 116, 116, 0, 98, 10 }, + { 63, 122, 122, 0, 102, 10 }, + { 67, 127, 127, 0, 105, 11 }, + { 71, 133, 133, 0, 109, 12 }, + { 74, 138, 138, 0, 113, 13 }, + { 78, 144, 144, 0, 117, 14 }, + { 81, 150, 150, 0, 121, 15 }, + { 85, 155, 155, 0, 125, 16 }, + { 89, 162, 162, 0, 129, 17 }, + { 92, 168, 168, 0, 133, 18 }, + { 97, 173, 173, 0, 137, 19 }, + { 101, 181, 181, 0, 143, 20 }, + { 106, 188, 188, 0, 148, 22 }, + { 110, 194, 194, 0, 153, 23 }, + { 115, 202, 202, 0, 159, 25 }, + { 119, 209, 209, 0, 165, 27 }, + { 124, 215, 215, 0, 170, 29 }, + { 128, 223, 223, 0, 176, 31 }, + { 134, 229, 229, 0, 181, 33 }, + { 139, 236, 236, 0, 186, 35 }, + { 144, 244, 244, 0, 192, 38 }, + { 150, 253, 253, 0, 200, 40 }, + { 155, 263, 263, 0, 207, 43 }, + { 161, 272, 272, 0, 215, 46 }, + { 166, 283, 283, 0, 223, 49 }, + { 171, 292, 292, 0, 231, 52 }, + { 177, 302, 302, 0, 238, 55 }, + { 183, 311, 311, 0, 246, 58 }, + { 189, 322, 322, 0, 254, 62 }, + { 196, 331, 331, 0, 261, 66 }, + { 202, 341, 341, 1700, 269, 70 }, + { 204, 342, 393, 1774, 270, 84 }, + { 205, 344, 444, 1851, 271, 99 }, + { 207, 345, 496, 1931, 273, 113 }, + { 209, 346, 548, 2015, 274, 128 }, + { 210, 347, 600, 2102, 275, 142 }, + { 212, 349, 651, 2194, 276, 157 }, + { 214, 350, 703, 2289, 278, 171 }, + { 215, 351, 755, 2388, 279, 186 }, + { 217, 352, 806, 2492, 280, 200 }, + { 218, 354, 858, 2600, 282, 215 }, + { 224, 355, 941, 2700, 283, 232 }, + { 228, 356, 1032, 2800, 284, 250 }, + { 236, 357, 1133, 2900, 286, 269 }, + { 244, 358, 1243, 3000, 287, 290 }, + { 252, 359, 1364, 3100, 288, 313 }, + { 260, 360, 1497, 3200, 290, 337 }, + { 268, 361, 1643, 3300, 292, 363 }, + { 276, 362, 1802, 3400, 293, 392 }, + { 284, 363, 1978, 3500, 294, 422 }, + { 292, 364, 2170, 3600, 295, 455 }, - // todo: add proper shbr values + // todo: add proper shbr values - hp/elmt/threat // sub/div added from http://theoryjerks.akhmorning.com/resources/levelmods/ - { 292, 365, 2263, 3600, 295 }, - { 292, 366, 2360, 3600, 295 }, - { 292, 367, 2461, 3600, 295 }, - { 292, 368, 2566, 3600, 295 }, - { 292, 370, 2676, 3600, 295 }, - { 292, 372, 2790, 3600, 295 }, - { 292, 374, 2910, 3600, 295 }, - { 292, 376, 3034, 3600, 295 }, - { 292, 378, 3164, 3600, 295 }, - { 292, 380, 3300, 3600, 295 }, + { 296, 365, 2263, 3600, 466, 466 }, + { 300, 366, 2360, 3600, 295, 466 }, + { 305, 367, 2461, 3600, 295, 466 }, + { 310, 368, 2566, 3600, 295, 466 }, + { 315, 370, 2676, 3600, 295, 466 }, + { 320, 372, 2790, 3600, 295, 466 }, + { 325, 374, 2910, 3600, 295, 466 }, + { 330, 376, 3034, 3600, 295, 466 }, + { 335, 378, 3164, 3600, 295, 466 }, + { 340, 380, 3300, 3600, 569, 569 }, }; /* @@ -219,16 +219,9 @@ float CalcStats::autoAttackPotency( const Sapphire::Entity::Chara& chara ) { uint32_t aaPotency = AUTO_ATTACK_POTENCY; - // check if ranged class - switch( chara.getClass() ) + if( chara.getRole() == Common::Role::RangedPhysical ) { - case Common::ClassJob::Machinist: - case Common::ClassJob::Bard: - case Common::ClassJob::Archer: - aaPotency = RANGED_AUTO_ATTACK_POTENCY; - - default: - break; + aaPotency = RANGED_AUTO_ATTACK_POTENCY; } float autoAttackDelay = 2.5f; @@ -442,7 +435,7 @@ float CalcStats::healingMagicPotency( const Sapphire::Entity::Chara& chara ) return std::floor( 100.f * ( chara.getStatValue( Common::BaseParam::HealingMagicPotency ) - 292.f ) / 264.f + 100.f ) / 100.f; } -float CalcStats::calculateAutoAttackDamage( const Sapphire::Entity::Chara& chara ) +float CalcStats::calcAutoAttackDamage( const Sapphire::Entity::Chara& chara ) { // D = ⌊ f(ptc) × f(aa) × f(ap) × f(det) × f(tnc) × traits ⌋ × f(ss) ⌋ × // f(chr) ⌋ × f(dhr) ⌋ × rand[ 0.95, 1.05 ] ⌋ × buff_1 ⌋ × buff... ⌋ @@ -451,12 +444,25 @@ float CalcStats::calculateAutoAttackDamage( const Sapphire::Entity::Chara& chara auto aa = autoAttack( chara ); auto ap = getPrimaryAttackPower( chara ); auto det = determination( chara ); - auto ten = tenacity( chara ); - Logger::debug( "auto attack: pot: {} aa: {} ap: {} det: {} ten: {}", pot, aa, ap, det, ten ); + auto ten = 1.f; + if( chara.getRole() == Common::Role::Tank ) + ten = tenacity( chara ); + // todo: everything after tenacity auto factor = std::floor( pot * aa * ap * det * ten ); + constexpr auto format = "auto attack: pot: {} aa: {} ap: {} det: {} ten: {} = {}"; + + if( auto player = const_cast< Entity::Chara& >( chara ).getAsPlayer() ) + { + player->sendDebug( format, pot, aa, ap, det, ten, factor ); + } + else + { + Logger::debug( format, pot, aa, ap, det, ten, factor ); + } + // todo: traits factor = std::floor( factor * speed( chara ) ); @@ -472,6 +478,38 @@ float CalcStats::calculateAutoAttackDamage( const Sapphire::Entity::Chara& chara return factor; } +float CalcStats::calcActionDamage( const Sapphire::Entity::Chara& chara, uint32_t ptc, float wepDmg ) +{ + // D = ⌊ f(pot) × f(wd) × f(ap) × f(det) × f(tnc) × traits ⌋ + // × f(chr) ⌋ × f(dhr) ⌋ × rand[ 0.95, 1.05 ] ⌋ buff_1 ⌋ × buff_1 ⌋ × buff... ⌋ + + auto pot = potency( ptc ); + auto wd = weaponDamage( chara, wepDmg ); + auto ap = getPrimaryAttackPower( chara ); + auto det = determination( chara ); + + auto ten = 1.f; + if( chara.getRole() == Common::Role::Tank ) + ten = tenacity( chara ); + + auto factor = std::floor( pot * wd * ap * det * ten ); + + constexpr auto format = "dmg: pot: {} ({}) wd: {} ({}) ap: {} det: {} ten: {} = {}"; + + if( auto player = const_cast< Entity::Chara& >( chara ).getAsPlayer() ) + { + player->sendDebug( format, pot, ptc, wd, wepDmg, ap, det, ten, factor ); + } + else + { + Logger::debug( format, pot, ptc, wd, wepDmg, ap, det, ten, factor ); + } + + // todo: the rest + + return factor; +} + uint32_t CalcStats::primaryStatValue( const Sapphire::Entity::Chara& chara ) { return chara.getStatValue( chara.getPrimaryStat() ); diff --git a/src/world/Math/CalcStats.h b/src/world/Math/CalcStats.h index 8b8f7d36..1b22238a 100644 --- a/src/world/Math/CalcStats.h +++ b/src/world/Math/CalcStats.h @@ -128,7 +128,9 @@ namespace Sapphire::Math //////////////////////////////////////////// - static float calculateAutoAttackDamage( const Sapphire::Entity::Chara& chara ); + static float calcAutoAttackDamage( const Sapphire::Entity::Chara& chara ); + + static float calcActionDamage( const Sapphire::Entity::Chara& chara, uint32_t ptc, float wepDmg ); static uint32_t primaryStatValue( const Sapphire::Entity::Chara& chara ); private: diff --git a/src/world/Navi/NaviProvider.cpp b/src/world/Navi/NaviProvider.cpp index 89534d0c..433a2408 100644 --- a/src/world/Navi/NaviProvider.cpp +++ b/src/world/Navi/NaviProvider.cpp @@ -1,6 +1,6 @@ #include #include -#include +#include #include #include diff --git a/src/world/Network/GameConnection.cpp b/src/world/Network/GameConnection.cpp index e9c9f5f2..12489297 100644 --- a/src/world/Network/GameConnection.cpp +++ b/src/world/Network/GameConnection.cpp @@ -8,7 +8,7 @@ #include #include -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "Network/PacketWrappers/PlayerSetupPacket.h" @@ -215,13 +215,13 @@ void Sapphire::Network::GameConnection::handleZonePacket( Sapphire::Network::Pac std::string name = itStr != m_zoneHandlerStrMap.end() ? itStr->second : "unknown"; // dont display packet notification if it is a ping or pos update, don't want the spam if( opcode != PingHandler && opcode != UpdatePositionHandler ) - Logger::debug( "[{0}] Handling Zone IPC : {1} ( {2:04X} )", m_pSession->getId(), name, opcode ); + Logger::debug( "[{0}] Handling World IPC : {1} ( {2:04X} )", m_pSession->getId(), name, opcode ); ( this->*( it->second ) )( m_pFw, pPacket, *m_pSession->getPlayer() ); } else { - Logger::debug( "[{0}] Undefined Zone IPC : Unknown ( {1:04X} )", m_pSession->getId(), opcode ); + Logger::debug( "[{0}] Undefined World IPC : Unknown ( {1:04X} )", m_pSession->getId(), opcode ); Logger::debug( "Dump:\n{0}", Util::binaryToHexDump( const_cast< uint8_t* >( &pPacket.data[ 0 ] ), pPacket.segHdr.size ) ); @@ -433,7 +433,7 @@ void Sapphire::Network::GameConnection::handlePackets( const Sapphire::Network:: auto pe1 = std::make_shared< FFXIVRawPacket >( 0x02, 0x38, 0, 0 ); *( unsigned int* ) ( &pe1->data()[ 0 ] ) = playerId; sendSinglePacket( pe1 ); - Logger::info( "[{0}] Setting session for zone connection", id ); + Logger::info( "[{0}] Setting session for world connection", id ); session->setZoneConnection( pCon ); } // chat connection, assinging it to the session diff --git a/src/world/Network/Handlers/ActionHandler.cpp b/src/world/Network/Handlers/ActionHandler.cpp index 460c294a..dd365b9b 100644 --- a/src/world/Network/Handlers/ActionHandler.cpp +++ b/src/world/Network/Handlers/ActionHandler.cpp @@ -48,7 +48,7 @@ void Sapphire::Network::GameConnection::actionHandler( FrameworkPtr pFw, if( !action ) return; - actionMgr->handleTargetedPlayerAction( player, actionId, action, targetId ); + actionMgr->handleTargetedPlayerAction( player, actionId, action, targetId, sequence ); break; } @@ -112,5 +112,5 @@ void Sapphire::Network::GameConnection::placedActionHandler( FrameworkPtr pFw, return; auto actionMgr = pFw->get< World::Manager::ActionMgr >(); - actionMgr->handlePlacedPlayerAction( player, actionId, action, pos ); + actionMgr->handlePlacedPlayerAction( player, actionId, action, pos, sequence ); } diff --git a/src/world/Network/Handlers/ClientTriggerHandler.cpp b/src/world/Network/Handlers/ClientTriggerHandler.cpp index c309cc41..b47ed892 100644 --- a/src/world/Network/Handlers/ClientTriggerHandler.cpp +++ b/src/world/Network/Handlers/ClientTriggerHandler.cpp @@ -8,7 +8,7 @@ #include #include -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "Territory/ZonePosition.h" #include "Manager/HousingMgr.h" @@ -287,12 +287,12 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( FrameworkPtr pFw, } case ClientTriggerType::DirectorInitFinish: // Director init finish { - player.getCurrentZone()->onInitDirector( player ); + player.getCurrentTerritory()->onInitDirector( player ); break; } case ClientTriggerType::DirectorSync: // Director init finish { - player.getCurrentZone()->onDirectorSync( player ); + player.getCurrentTerritory()->onDirectorSync( player ); break; } case ClientTriggerType::EnterTerritoryEventFinished:// this may still be something else. I think i have seen it elsewhere @@ -313,7 +313,7 @@ void Sapphire::Network::GameConnection::clientTriggerHandler( FrameworkPtr pFw, } case ClientTriggerType::RequestHousingBuildPreset: { - auto zone = player.getCurrentZone(); + auto zone = player.getCurrentTerritory(); auto hZone = std::dynamic_pointer_cast< HousingZone >( zone ); if (!hZone) return; diff --git a/src/world/Network/Handlers/GMCommandHandlers.cpp b/src/world/Network/Handlers/GMCommandHandlers.cpp index 658b3b73..7dd91a2e 100644 --- a/src/world/Network/Handlers/GMCommandHandlers.cpp +++ b/src/world/Network/Handlers/GMCommandHandlers.cpp @@ -14,7 +14,7 @@ #include "Session.h" #include "Manager/TerritoryMgr.h" -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "Territory/InstanceContent.h" #include "Network/PacketWrappers/PlayerSetupPacket.h" @@ -190,9 +190,9 @@ void Sapphire::Network::GameConnection::gm1Handler( FrameworkPtr pFw, } case GmCommand::Weather: { - targetPlayer->getCurrentZone()->setWeatherOverride( static_cast< Common::Weather >( param1 ) ); - player.sendNotice( "Weather in Zone \"{0}\" of {1} set in range.", - targetPlayer->getCurrentZone()->getName(), targetPlayer->getName() ); + targetPlayer->getCurrentTerritory()->setWeatherOverride( static_cast< Common::Weather >( param1 ) ); + player.sendNotice( "Weather in Territory \"{0}\" of {1} set in range.", + targetPlayer->getCurrentTerritory()->getName(), targetPlayer->getName() ); break; } case GmCommand::Call: @@ -208,7 +208,7 @@ void Sapphire::Network::GameConnection::gm1Handler( FrameworkPtr pFw, { player.sendNotice( "Name: {0}" "\nGil: {1}" - "\nZone: {2}" + "\nTerritory: {2}" "({3})" "\nClass: {4}" "\nLevel: {5}" @@ -217,7 +217,7 @@ void Sapphire::Network::GameConnection::gm1Handler( FrameworkPtr pFw, "\nPlayTime: {8}", targetPlayer->getName(), targetPlayer->getCurrency( CurrencyType::Gil ), - targetPlayer->getCurrentZone()->getName(), + targetPlayer->getCurrentTerritory()->getName(), targetPlayer->getZoneId(), static_cast< uint8_t >( targetPlayer->getClass() ), targetPlayer->getLevel(), @@ -551,7 +551,7 @@ void Sapphire::Network::GameConnection::gm1Handler( FrameworkPtr pFw, } case GmCommand::TeriInfo: { - auto pCurrentZone = player.getCurrentZone(); + auto pCurrentZone = player.getCurrentTerritory(); player.sendNotice( "ZoneId: {0}" "\nName: {1}" "\nInternalName: {2}" @@ -657,16 +657,16 @@ void Sapphire::Network::GameConnection::gm2Handler( FrameworkPtr pFw, { player.exitInstance(); } - if( targetPlayer->getCurrentZone()->getGuId() != player.getCurrentZone()->getGuId() ) + if( targetPlayer->getCurrentTerritory()->getGuId() != player.getCurrentTerritory()->getGuId() ) { - // Checks if the target player is in an InstanceContent to avoid binding to a Zone or PublicContent + // Checks if the target player is in an InstanceContent to avoid binding to a Territory or PublicContent if( targetPlayer->getCurrentInstance() ) { auto pInstanceContent = targetPlayer->getCurrentInstance()->getAsInstanceContent(); // Not sure if GMs actually get bound to an instance they jump to on retail. It's mostly here to avoid a crash for now pInstanceContent->bindPlayer( player.getId() ); } - player.setInstance( targetPlayer->getCurrentZone()->getGuId() ); + player.setInstance( targetPlayer->getCurrentTerritory()->getGuId() ); } player.changePosition( targetActor->getPos().x, targetActor->getPos().y, targetActor->getPos().z, targetActor->getRot() ); @@ -687,9 +687,9 @@ void Sapphire::Network::GameConnection::gm2Handler( FrameworkPtr pFw, { targetPlayer->exitInstance(); } - if( targetPlayer->getCurrentZone()->getGuId() != player.getCurrentZone()->getGuId() ) + if( targetPlayer->getCurrentTerritory()->getGuId() != player.getCurrentTerritory()->getGuId() ) { - targetPlayer->setInstance( player.getCurrentZone()->getGuId() ); + targetPlayer->setInstance( player.getCurrentTerritory()->getGuId() ); } targetPlayer->changePosition( player.getPos().x, player.getPos().y, player.getPos().z, player.getRot() ); targetPlayer->sendZoneInPackets( 0x00, 0x00, 0, 0, false ); diff --git a/src/world/Network/Handlers/InventoryHandler.cpp b/src/world/Network/Handlers/InventoryHandler.cpp index cf429b02..8fc94bdd 100644 --- a/src/world/Network/Handlers/InventoryHandler.cpp +++ b/src/world/Network/Handlers/InventoryHandler.cpp @@ -8,7 +8,7 @@ #include "Network/GameConnection.h" #include "Network/PacketWrappers/ServerNoticePacket.h" -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "Territory/ZonePosition.h" #include "Manager/DebugCommandMgr.h" diff --git a/src/world/Network/Handlers/PacketHandlers.cpp b/src/world/Network/Handlers/PacketHandlers.cpp index 709b65d1..c4166431 100644 --- a/src/world/Network/Handlers/PacketHandlers.cpp +++ b/src/world/Network/Handlers/PacketHandlers.cpp @@ -15,7 +15,7 @@ #include "Network/GameConnection.h" -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "Territory/HousingZone.h" #include "Territory/Land.h" #include "Territory/ZonePosition.h" @@ -281,7 +281,7 @@ void Sapphire::Network::GameConnection::zoneLineHandler( FrameworkPtr pFw, player.sendDebug( "Walking ZoneLine#{0}", zoneLineId ); - auto pZone = player.getCurrentZone(); + auto pZone = player.getCurrentTerritory(); auto pLine = pTeriMgr->getTerritoryPosition( zoneLineId ); @@ -411,7 +411,7 @@ void Sapphire::Network::GameConnection::finishLoadingHandler( FrameworkPtr pFw, gcPacket->data().gcRank[ 2 ] = player.getGcRankArray()[ 2 ]; player.queuePacket( gcPacket ); - player.getCurrentZone()->onFinishLoading( player ); + player.getCurrentTerritory()->onFinishLoading( player ); // player is done zoning player.setLoadingComplete( true ); @@ -428,7 +428,7 @@ void Sapphire::Network::GameConnection::finishLoadingHandler( FrameworkPtr pFw, player.spawn( player.getAsPlayer() ); // notify the zone of a change in position to force an "inRangeActor" update - player.getCurrentZone()->updateActorPosition( player ); + player.getCurrentTerritory()->updateActorPosition( player ); } void Sapphire::Network::GameConnection::socialListHandler( FrameworkPtr pFw, @@ -450,7 +450,7 @@ void Sapphire::Network::GameConnection::socialListHandler( FrameworkPtr pFw, int32_t entrysizes = sizeof( listPacket->data().entries ); memset( listPacket->data().entries, 0, sizeof( listPacket->data().entries ) ); - listPacket->data().entries[ 0 ].bytes[ 2 ] = player.getCurrentZone()->getTerritoryTypeId(); + listPacket->data().entries[ 0 ].bytes[ 2 ] = player.getCurrentTerritory()->getTerritoryTypeId(); listPacket->data().entries[ 0 ].bytes[ 3 ] = 0x80; listPacket->data().entries[ 0 ].bytes[ 4 ] = 0x02; listPacket->data().entries[ 0 ].bytes[ 6 ] = 0x3B; @@ -458,7 +458,7 @@ void Sapphire::Network::GameConnection::socialListHandler( FrameworkPtr pFw, listPacket->data().entries[ 0 ].classJob = static_cast< uint8_t >( player.getClass() ); listPacket->data().entries[ 0 ].contentId = player.getContentId(); listPacket->data().entries[ 0 ].level = player.getLevel(); - listPacket->data().entries[ 0 ].zoneId = player.getCurrentZone()->getTerritoryTypeId(); + listPacket->data().entries[ 0 ].zoneId = player.getCurrentTerritory()->getTerritoryTypeId(); listPacket->data().entries[ 0 ].zoneId1 = 0x0100; // TODO: no idea what this does //listPacket.data().entries[0].one = 1; @@ -516,7 +516,7 @@ void Sapphire::Network::GameConnection::chatHandler( FrameworkPtr pFw, if( player.isActingAsGm() ) chatPacket->data().chatType = ChatType::GMSay; - player.getCurrentZone()->queuePacketForRange( player, 50, chatPacket ); + player.getCurrentTerritory()->queuePacketForRange( player, 50, chatPacket ); break; } case ChatType::Yell: @@ -524,7 +524,7 @@ void Sapphire::Network::GameConnection::chatHandler( FrameworkPtr pFw, if( player.isActingAsGm() ) chatPacket->data().chatType = ChatType::GMYell; - player.getCurrentZone()->queuePacketForRange( player, 6000, chatPacket ); + player.getCurrentTerritory()->queuePacketForRange( player, 6000, chatPacket ); break; } case ChatType::Shout: @@ -532,12 +532,12 @@ void Sapphire::Network::GameConnection::chatHandler( FrameworkPtr pFw, if( player.isActingAsGm() ) chatPacket->data().chatType = ChatType::GMShout; - player.getCurrentZone()->queuePacketForRange( player, 6000, chatPacket ); + player.getCurrentTerritory()->queuePacketForRange( player, 6000, chatPacket ); break; } default: { - player.getCurrentZone()->queuePacketForRange( player, 50, chatPacket ); + player.getCurrentTerritory()->queuePacketForRange( player, 50, chatPacket ); break; } } diff --git a/src/world/Network/PacketWrappers/EffectPacket.h b/src/world/Network/PacketWrappers/EffectPacket.h index 7afa3950..46c8338b 100644 --- a/src/world/Network/PacketWrappers/EffectPacket.h +++ b/src/world/Network/PacketWrappers/EffectPacket.h @@ -64,9 +64,10 @@ namespace Sapphire::Network::Packets::Server FFXIVPacketBase::setTargetActor( targetId ); } - void setSequence( uint32_t sequence ) + void setSequence( uint32_t sequence, uint16_t sourceSequence = 0 ) { m_data.sequence = sequence; + m_data.sourceSequence = sourceSequence; } }; diff --git a/src/world/Script/ScriptMgr.cpp b/src/world/Script/ScriptMgr.cpp index 4b7bd27c..6557b326 100644 --- a/src/world/Script/ScriptMgr.cpp +++ b/src/world/Script/ScriptMgr.cpp @@ -3,7 +3,7 @@ #include -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "Territory/InstanceContent.h" #include "Territory/QuestBattle.h" #include "Actor/Player.h" @@ -163,7 +163,7 @@ void Sapphire::Scripting::ScriptMgr::onPlayerFirstEnterWorld( Entity::Player& pl bool Sapphire::Scripting::ScriptMgr::onTalk( Entity::Player& player, uint64_t actorId, uint32_t eventId ) { // check if the actor is an eobj and call its script if we have one - auto zone = player.getCurrentZone(); + auto zone = player.getCurrentTerritory(); if( auto eobj = zone->getEObj( actorId ) ) { auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::EventObjectScript >( eobj->getObjectId() ); @@ -412,7 +412,7 @@ bool Sapphire::Scripting::ScriptMgr::onStatusTimeOut( Entity::CharaPtr pChara, u return false; } -bool Sapphire::Scripting::ScriptMgr::onZoneInit( ZonePtr pZone ) +bool Sapphire::Scripting::ScriptMgr::onZoneInit( TerritoryPtr pZone ) { auto script = m_nativeScriptMgr->getScript< Sapphire::ScriptAPI::ZoneScript >( pZone->getTerritoryTypeId() ); if( script ) diff --git a/src/world/Script/ScriptMgr.h b/src/world/Script/ScriptMgr.h index 94bc8067..c68a0482 100644 --- a/src/world/Script/ScriptMgr.h +++ b/src/world/Script/ScriptMgr.h @@ -84,7 +84,7 @@ namespace Sapphire::Scripting bool onStatusTimeOut( Entity::CharaPtr pActor, uint32_t effectId ); - bool onZoneInit( ZonePtr pZone ); + bool onZoneInit( TerritoryPtr pZone ); bool onEventHandlerReturn( Entity::Player& player, uint32_t eventId, uint16_t subEvent, uint16_t param1, uint16_t param2, uint16_t param3 ); diff --git a/src/world/ServerMgr.cpp b/src/world/ServerMgr.cpp index feffd356..5fbd66e6 100644 --- a/src/world/ServerMgr.cpp +++ b/src/world/ServerMgr.cpp @@ -286,7 +286,7 @@ void Sapphire::World::ServerMgr::mainLoop() // if the player is in a zone, let the zone handler take care of his updates // else do it here. - if( !session->getPlayer()->getCurrentZone() ) + if( !session->getPlayer()->getCurrentTerritory() ) session->update(); } diff --git a/src/world/Territory/Cell.cpp b/src/world/Territory/Cell.cpp index d4ea8bf0..ff495c90 100644 --- a/src/world/Territory/Cell.cpp +++ b/src/world/Territory/Cell.cpp @@ -2,7 +2,7 @@ #include "Actor/Chara.h" #include "Forwards.h" -#include "Zone.h" +#include "Territory.h" #include // TODO: the entire zone / areahandling is a bit outdated ( in parts i used this for the 1.0 iteration ) @@ -22,7 +22,7 @@ Sapphire::Cell::~Cell() removeActors(); } -void Sapphire::Cell::init( uint32_t x, uint32_t y, ZonePtr pZone ) +void Sapphire::Cell::init( uint32_t x, uint32_t y, TerritoryPtr pZone ) { m_pZone = pZone; m_posX = x; diff --git a/src/world/Territory/Cell.h b/src/world/Territory/Cell.h index c1cf413d..23351b34 100644 --- a/src/world/Territory/Cell.h +++ b/src/world/Territory/Cell.h @@ -13,7 +13,7 @@ typedef std::set< Entity::ActorPtr > ActorSet; class Cell { - friend class Zone; + friend class Territory; private: bool m_bForcedActive; @@ -25,14 +25,14 @@ private: bool m_bUnloadPending; uint16_t m_playerCount; - ZonePtr m_pZone; + TerritoryPtr m_pZone; public: Cell(); ~Cell(); - void init( uint32_t x, uint32_t y, ZonePtr pZone ); + void init( uint32_t x, uint32_t y, TerritoryPtr pZone ); void addActor( Entity::ActorPtr pAct ); diff --git a/src/world/Territory/Housing/HousingInteriorTerritory.cpp b/src/world/Territory/Housing/HousingInteriorTerritory.cpp index 7ffa045c..0b8985d4 100644 --- a/src/world/Territory/Housing/HousingInteriorTerritory.cpp +++ b/src/world/Territory/Housing/HousingInteriorTerritory.cpp @@ -36,7 +36,7 @@ Sapphire::World::Territory::Housing::HousingInteriorTerritory::HousingInteriorTe const std::string& internalName, const std::string& contentName, FrameworkPtr pFw ) : - Zone( territoryTypeId, guId, internalName, contentName, pFw ), + Territory( territoryTypeId, guId, internalName, contentName, pFw ), m_landIdent( ident ) { } @@ -54,7 +54,7 @@ void Sapphire::World::Territory::Housing::HousingInteriorTerritory::onPlayerZone { auto pHousingMgr = m_pFw->get< HousingMgr >(); - Logger::debug( "HousingInteriorTerritory::onPlayerZoneIn: Zone#{0}|{1}, Entity#{2}", + Logger::debug( "HousingInteriorTerritory::onPlayerZoneIn: Territory#{0}|{1}, Entity#{2}", getGuId(), getTerritoryTypeId(), player.getId() ); auto indoorInitPacket = makeZonePacket< Server::FFXIVIpcHousingIndoorInitialize >( player.getId() ); diff --git a/src/world/Territory/Housing/HousingInteriorTerritory.h b/src/world/Territory/Housing/HousingInteriorTerritory.h index 3993ba39..efc4860b 100644 --- a/src/world/Territory/Housing/HousingInteriorTerritory.h +++ b/src/world/Territory/Housing/HousingInteriorTerritory.h @@ -1,11 +1,11 @@ #include "ForwardsZone.h" -#include "Territory/Zone.h" +#include "Territory/Territory.h" #include "Common.h" #include namespace Sapphire::World::Territory::Housing { - class HousingInteriorTerritory : public Zone + class HousingInteriorTerritory : public Territory { public: HousingInteriorTerritory( Common::LandIdent ident, uint16_t territoryTypeId, diff --git a/src/world/Territory/HousingZone.cpp b/src/world/Territory/HousingZone.cpp index e138b38e..c252b909 100644 --- a/src/world/Territory/HousingZone.cpp +++ b/src/world/Territory/HousingZone.cpp @@ -33,7 +33,7 @@ Sapphire::HousingZone::HousingZone( uint8_t wardNum, const std::string& internalName, const std::string& contentName, FrameworkPtr pFw ) : - Zone( territoryTypeId, guId, internalName, contentName, pFw ), + Territory( territoryTypeId, guId, internalName, contentName, pFw ), m_wardNum( wardNum ), m_territoryTypeId( territoryTypeId ), m_landSetId( ( static_cast< uint32_t >( territoryTypeId ) << 16 ) | wardNum ), @@ -155,7 +155,7 @@ bool Sapphire::HousingZone::init() void Sapphire::HousingZone::onPlayerZoneIn( Entity::Player& player ) { - Logger::debug( "HousingZone::onPlayerZoneIn: Zone#{0}|{1}, Entity#{2}", + Logger::debug( "HousingZone::onPlayerZoneIn: Territory#{0}|{1}, Entity#{2}", getGuId(), getTerritoryTypeId(), player.getId() ); auto isInSubdivision = isPlayerSubInstance( player ) ? true : false; diff --git a/src/world/Territory/HousingZone.h b/src/world/Territory/HousingZone.h index 001f5a58..804624ed 100644 --- a/src/world/Territory/HousingZone.h +++ b/src/world/Territory/HousingZone.h @@ -1,7 +1,7 @@ #ifndef SAPPHIRE_HOUSINGZONE_H #define SAPPHIRE_HOUSINGZONE_H -#include "Zone.h" +#include "Territory.h" #include "Forwards.h" #include @@ -24,7 +24,7 @@ namespace Sapphire RELOCATE = 4, }; - class HousingZone : public Zone + class HousingZone : public Territory { public: HousingZone( uint8_t landSetId, diff --git a/src/world/Territory/InstanceContent.cpp b/src/world/Territory/InstanceContent.cpp index 79d6be6c..267da084 100644 --- a/src/world/Territory/InstanceContent.cpp +++ b/src/world/Territory/InstanceContent.cpp @@ -34,7 +34,7 @@ Sapphire::InstanceContent::InstanceContent( std::shared_ptr< Sapphire::Data::Ins const std::string& contentName, uint32_t instanceContentId, FrameworkPtr pFw ) : - Zone( static_cast< uint16_t >( territoryType ), guId, internalName, contentName, pFw ), + Territory( static_cast< uint16_t >( territoryType ), guId, internalName, contentName, pFw ), Director( Event::Director::InstanceContent, instanceContentId ), m_instanceConfiguration( pInstanceConfiguration ), m_instanceContentId( instanceContentId ), @@ -48,7 +48,7 @@ Sapphire::InstanceContent::InstanceContent( std::shared_ptr< Sapphire::Data::Ins bool Sapphire::InstanceContent::init() { - if( !Zone::init() ) + if( !Territory::init() ) return false; auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >(); @@ -75,7 +75,7 @@ Sapphire::Data::ExdDataGenerated::InstanceContentPtr Sapphire::InstanceContent:: void Sapphire::InstanceContent::onPlayerZoneIn( Entity::Player& player ) { - Logger::debug( "InstanceContent::onPlayerZoneIn: Zone#{0}|{1}, Entity#{2}", + Logger::debug( "InstanceContent::onPlayerZoneIn: Territory#{0}|{1}, Entity#{2}", getGuId(), getTerritoryTypeId(), player.getId() ); // mark player as "bound by duty" @@ -90,7 +90,7 @@ void Sapphire::InstanceContent::onPlayerZoneIn( Entity::Player& player ) void Sapphire::InstanceContent::onLeaveTerritory( Entity::Player& player ) { - Logger::debug( "InstanceContent::onLeaveTerritory: Zone#{0}|{1}, Entity#{2}", + Logger::debug( "InstanceContent::onLeaveTerritory: Territory#{0}|{1}, Entity#{2}", getGuId(), getTerritoryTypeId(), player.getId() ); clearDirector( player ); @@ -318,7 +318,7 @@ void Sapphire::InstanceContent::onRegisterEObj( Entity::EventObjectPtr object ) // todo: data should be renamed to eventId m_eventIdToObjectMap[ objData->data ] = object; else - Logger::error( "InstanceContent::onRegisterEObj Zone " + + Logger::error( "InstanceContent::onRegisterEObj Territory " + m_internalName + ": No EObj data found for EObj with ID: " + std::to_string( object->getObjectId() ) ); } diff --git a/src/world/Territory/InstanceContent.h b/src/world/Territory/InstanceContent.h index 2acae2b2..a34ac2fb 100644 --- a/src/world/Territory/InstanceContent.h +++ b/src/world/Territory/InstanceContent.h @@ -1,7 +1,7 @@ #ifndef SAPPHIRE_INSTANCECONTENT_H #define SAPPHIRE_INSTANCECONTENT_H -#include "Zone.h" +#include "Territory.h" #include "Event/Director.h" #include "Forwards.h" @@ -12,7 +12,7 @@ namespace Sapphire::Data namespace Sapphire { - class InstanceContent : public Event::Director, public Zone + class InstanceContent : public Event::Director, public Territory { public: enum InstanceContentState diff --git a/src/world/Territory/QuestBattle.cpp b/src/world/Territory/QuestBattle.cpp index 0227bbcd..63e60b9b 100644 --- a/src/world/Territory/QuestBattle.cpp +++ b/src/world/Territory/QuestBattle.cpp @@ -36,7 +36,7 @@ Sapphire::QuestBattle::QuestBattle( std::shared_ptr< Sapphire::Data::QuestBattle const std::string& contentName, uint32_t questBattleId, FrameworkPtr pFw ) : - Zone( static_cast< uint16_t >( territoryType ), guId, internalName, contentName, pFw ), + Territory( static_cast< uint16_t >( territoryType ), guId, internalName, contentName, pFw ), Director( Event::Director::QuestBattle, questBattleId ), m_pBattleDetails( pBattleDetails ), m_questBattleId( questBattleId ), @@ -48,7 +48,7 @@ Sapphire::QuestBattle::QuestBattle( std::shared_ptr< Sapphire::Data::QuestBattle bool Sapphire::QuestBattle::init() { - if( !Zone::init() ) + if( !Territory::init() ) return false; auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >(); @@ -69,7 +69,7 @@ Sapphire::Data::ExdDataGenerated::QuestBattlePtr Sapphire::QuestBattle::getQuest void Sapphire::QuestBattle::onPlayerZoneIn( Entity::Player& player ) { - Logger::debug( "QuestBattle::onPlayerZoneIn: Zone#{0}|{1}, Entity#{2}", + Logger::debug( "QuestBattle::onPlayerZoneIn: Territory#{0}|{1}, Entity#{2}", getGuId(), getTerritoryTypeId(), player.getId() ); m_pPlayer = player.getAsPlayer(); @@ -83,7 +83,7 @@ void Sapphire::QuestBattle::onPlayerZoneIn( Entity::Player& player ) void Sapphire::QuestBattle::onLeaveTerritory( Entity::Player& player ) { - Logger::debug( "QuestBattle::onLeaveTerritory: Zone#{0}|{1}, Entity#{2}", + Logger::debug( "QuestBattle::onLeaveTerritory: Territory#{0}|{1}, Entity#{2}", getGuId(), getTerritoryTypeId(), player.getId() ); clearDirector( player ); @@ -291,7 +291,7 @@ void Sapphire::QuestBattle::onRegisterEObj( Entity::EventObjectPtr object ) // todo: data should be renamed to eventId m_eventIdToObjectMap[ objData->data ] = object; else - Logger::error( "InstanceContent::onRegisterEObj Zone " + + Logger::error( "InstanceContent::onRegisterEObj Territory " + m_internalName + ": No EObj data found for EObj with ID: " + std::to_string( object->getObjectId() ) ); } diff --git a/src/world/Territory/QuestBattle.h b/src/world/Territory/QuestBattle.h index f4a40b61..4553fe06 100644 --- a/src/world/Territory/QuestBattle.h +++ b/src/world/Territory/QuestBattle.h @@ -1,7 +1,7 @@ #ifndef SAPPHIRE_QUESTBATTLE_H #define SAPPHIRE_QUESTBATTLE_H -#include "Zone.h" +#include "Territory.h" #include "Event/Director.h" #include "Forwards.h" @@ -12,7 +12,7 @@ namespace Sapphire::Data namespace Sapphire { - class QuestBattle : public Event::Director, public Zone + class QuestBattle : public Event::Director, public Territory { public: QuestBattle( std::shared_ptr< Sapphire::Data::QuestBattle > pBattleDetails, diff --git a/src/world/Territory/Zone.cpp b/src/world/Territory/Territory.cpp similarity index 83% rename from src/world/Territory/Zone.cpp rename to src/world/Territory/Territory.cpp index e0a159c4..dcfce47b 100644 --- a/src/world/Territory/Zone.cpp +++ b/src/world/Territory/Territory.cpp @@ -15,7 +15,7 @@ #include #include -#include "Zone.h" +#include "Territory.h" #include "InstanceContent.h" #include "QuestBattle.h" #include "Manager/TerritoryMgr.h" @@ -31,15 +31,15 @@ #include "Actor/SpawnPoint.h" #include "Actor/BNpcTemplate.h" +#include "Action/EffectResult.h" + #include "Network/GameConnection.h" #include "Script/ScriptMgr.h" -#include "Session.h" #include "ForwardsZone.h" #include "ServerMgr.h" #include "CellHandler.h" -#include "Zone.h" #include "Framework.h" #include "Manager/RNGMgr.h" @@ -54,7 +54,7 @@ using namespace Sapphire::World::Manager; /** * \brief */ -Sapphire::Zone::Zone() : +Sapphire::Territory::Territory() : m_territoryTypeId( 0 ), m_guId( 0 ), m_currentWeather( Weather::FairSkies ), @@ -65,9 +65,9 @@ Sapphire::Zone::Zone() : { } -Sapphire::Zone::Zone( uint16_t territoryTypeId, uint32_t guId, - const std::string& internalName, const std::string& placeName, - FrameworkPtr pFw ) : +Sapphire::Territory::Territory( uint16_t territoryTypeId, uint32_t guId, + const std::string& internalName, const std::string& placeName, + FrameworkPtr pFw ) : m_currentWeather( Weather::FairSkies ), m_nextEObjId( 0x400D0000 ), m_nextActorId( 0x500D0000 ), @@ -93,7 +93,7 @@ Sapphire::Zone::Zone( uint16_t territoryTypeId, uint32_t guId, m_currentWeather = getNextWeather(); } -void Sapphire::Zone::loadWeatherRates() +void Sapphire::Territory::loadWeatherRates() { if( !m_territoryTypeInfo ) return; @@ -118,11 +118,9 @@ void Sapphire::Zone::loadWeatherRates() } } -Sapphire::Zone::~Zone() -{ -} +Sapphire::Territory::~Territory() = default; -bool Sapphire::Zone::init() +bool Sapphire::Territory::init() { auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >(); @@ -144,22 +142,22 @@ bool Sapphire::Zone::init() return true; } -void Sapphire::Zone::setWeatherOverride( Weather weather ) +void Sapphire::Territory::setWeatherOverride( Weather weather ) { m_weatherOverride = weather; } -Weather Sapphire::Zone::getCurrentWeather() const +Weather Sapphire::Territory::getCurrentWeather() const { return m_currentWeather; } -const Sapphire::FestivalPair& Sapphire::Zone::getCurrentFestival() const +const Sapphire::FestivalPair& Sapphire::Territory::getCurrentFestival() const { return m_currentFestival; } -void Sapphire::Zone::setCurrentFestival( uint16_t festivalId, uint16_t additionalFestivalId ) +void Sapphire::Territory::setCurrentFestival( uint16_t festivalId, uint16_t additionalFestivalId ) { m_currentFestival = { festivalId, additionalFestivalId }; @@ -172,11 +170,11 @@ void Sapphire::Zone::setCurrentFestival( uint16_t festivalId, uint16_t additiona } } -void Sapphire::Zone::loadCellCache() +void Sapphire::Territory::loadCellCache() { } -Weather Sapphire::Zone::getNextWeather() +Weather Sapphire::Territory::getNextWeather() { uint32_t unixTime = Util::getTimeSeconds(); // Get Eorzea hour for weather start @@ -206,7 +204,7 @@ Weather Sapphire::Zone::getNextWeather() return Weather::FairSkies; } -void Sapphire::Zone::pushActor( Entity::ActorPtr pActor ) +void Sapphire::Territory::pushActor( Entity::ActorPtr pActor ) { float mx = pActor->getPos().x; float my = pActor->getPos().z; @@ -271,7 +269,7 @@ void Sapphire::Zone::pushActor( Entity::ActorPtr pActor ) } } -void Sapphire::Zone::removeActor( Entity::ActorPtr pActor ) +void Sapphire::Territory::removeActor( Entity::ActorPtr pActor ) { float mx = pActor->getPos().x; float my = pActor->getPos().z; @@ -314,7 +312,7 @@ void Sapphire::Zone::removeActor( Entity::ActorPtr pActor ) } -void Sapphire::Zone::queuePacketForRange( Entity::Player& sourcePlayer, uint32_t range, +void Sapphire::Territory::queuePacketForRange( Entity::Player& sourcePlayer, uint32_t range, Network::Packets::FFXIVPacketBasePtr pPacketEntry ) { auto pTeriMgr = m_pFw->get< TerritoryMgr >(); @@ -339,7 +337,7 @@ void Sapphire::Zone::queuePacketForRange( Entity::Player& sourcePlayer, uint32_t } } -void Sapphire::Zone::queuePacketForZone( Entity::Player& sourcePlayer, +void Sapphire::Territory::queuePacketForZone( Entity::Player& sourcePlayer, Network::Packets::FFXIVPacketBasePtr pPacketEntry, bool forSelf ) { @@ -361,37 +359,37 @@ void Sapphire::Zone::queuePacketForZone( Entity::Player& sourcePlayer, } } -uint32_t Sapphire::Zone::getTerritoryTypeId() const +uint32_t Sapphire::Territory::getTerritoryTypeId() const { return m_territoryTypeId; } -uint32_t Sapphire::Zone::getGuId() const +uint32_t Sapphire::Territory::getGuId() const { return m_guId; } -const std::string& Sapphire::Zone::getName() const +const std::string& Sapphire::Territory::getName() const { return m_placeName; } -const std::string& Sapphire::Zone::getInternalName() const +const std::string& Sapphire::Territory::getInternalName() const { return m_internalName; } -const std::string& Sapphire::Zone::getBgPath() const +const std::string& Sapphire::Territory::getBgPath() const { return m_bgPath; } -std::size_t Sapphire::Zone::getPopCount() const +std::size_t Sapphire::Territory::getPopCount() const { return m_playerMap.size(); } -bool Sapphire::Zone::checkWeather() +bool Sapphire::Territory::checkWeather() { if( m_weatherOverride != Weather::None ) { @@ -413,7 +411,7 @@ bool Sapphire::Zone::checkWeather() return false; } -void Sapphire::Zone::updateBNpcs( uint64_t tickCount ) +void Sapphire::Territory::updateBNpcs( uint64_t tickCount ) { if( ( tickCount - m_lastMobUpdate ) <= 250 ) return; @@ -468,12 +466,12 @@ void Sapphire::Zone::updateBNpcs( uint64_t tickCount ) } -uint64_t Sapphire::Zone::getLastActivityTime() const +uint64_t Sapphire::Territory::getLastActivityTime() const { return m_lastActivityTime; } -bool Sapphire::Zone::update( uint64_t tickCount ) +bool Sapphire::Territory::update( uint64_t tickCount ) { //TODO: this should be moved to a updateWeather call and pulled out of updateSessions bool changedWeather = checkWeather(); @@ -488,6 +486,8 @@ bool Sapphire::Zone::update( uint64_t tickCount ) updateSpawnPoints(); + processEffectResults( tickCount ); + if( !m_playerMap.empty() ) m_lastActivityTime = tickCount; @@ -496,7 +496,7 @@ bool Sapphire::Zone::update( uint64_t tickCount ) return true; } -void Sapphire::Zone::updateSessions( uint64_t tickCount, bool changedWeather ) +void Sapphire::Territory::updateSessions( uint64_t tickCount, bool changedWeather ) { // update sessions in this zone for( auto it = m_playerMap.begin(); it != m_playerMap.end(); ++it ) @@ -511,7 +511,7 @@ void Sapphire::Zone::updateSessions( uint64_t tickCount, bool changedWeather ) } // this session is not linked to this area anymore, remove it from zone session list - if( ( !pPlayer->getCurrentZone() ) || ( pPlayer->getCurrentZone() != shared_from_this() ) ) + if( ( !pPlayer->getCurrentTerritory() ) || ( pPlayer->getCurrentTerritory() != shared_from_this() ) ) { removeActor( pPlayer ); return; @@ -529,12 +529,12 @@ void Sapphire::Zone::updateSessions( uint64_t tickCount, bool changedWeather ) pPlayer->getSession()->update(); // this session is not linked to this area anymore, remove it from zone session list - if( ( !pPlayer->getCurrentZone() ) || ( pPlayer->getCurrentZone() != shared_from_this() ) ) + if( ( !pPlayer->getCurrentTerritory() ) || ( pPlayer->getCurrentTerritory() != shared_from_this() ) ) return; } } -bool Sapphire::Zone::isCellActive( uint32_t x, uint32_t y ) +bool Sapphire::Territory::isCellActive( uint32_t x, uint32_t y ) { uint32_t endX = ( ( x + 1 ) <= _sizeX ) ? x + 1 : ( _sizeX - 1 ); uint32_t endY = ( ( y + 1 ) <= _sizeY ) ? y + 1 : ( _sizeY - 1 ); @@ -559,7 +559,7 @@ bool Sapphire::Zone::isCellActive( uint32_t x, uint32_t y ) return false; } -void Sapphire::Zone::updateCellActivity( uint32_t x, uint32_t y, int32_t radius ) +void Sapphire::Territory::updateCellActivity( uint32_t x, uint32_t y, int32_t radius ) { uint32_t endX = ( x + radius ) <= _sizeX ? x + radius : ( _sizeX - 1 ); @@ -608,10 +608,10 @@ void Sapphire::Zone::updateCellActivity( uint32_t x, uint32_t y, int32_t radius } } -void Sapphire::Zone::updateActorPosition( Entity::Actor& actor ) +void Sapphire::Territory::updateActorPosition( Entity::Actor& actor ) { - if( actor.getCurrentZone() != shared_from_this() ) + if( actor.getCurrentTerritory() != shared_from_this() ) return; //actor.checkInRangeActors(); @@ -679,7 +679,7 @@ void Sapphire::Zone::updateActorPosition( Entity::Actor& actor ) } -void Sapphire::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell ) +void Sapphire::Territory::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell ) { if( pCell == nullptr ) return; @@ -728,37 +728,37 @@ void Sapphire::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell ) } } -void Sapphire::Zone::onPlayerZoneIn( Entity::Player& player ) +void Sapphire::Territory::onPlayerZoneIn( Entity::Player& player ) { - Logger::debug( "Zone::onEnterTerritory: Zone#{0}|{1}, Entity#{2}", getGuId(), getTerritoryTypeId(), player.getId() ); + Logger::debug( "Territory::onEnterTerritory: Territory#{0}|{1}, Entity#{2}", getGuId(), getTerritoryTypeId(), player.getId() ); } -void Sapphire::Zone::onLeaveTerritory( Entity::Player& player ) +void Sapphire::Territory::onLeaveTerritory( Entity::Player& player ) { - Logger::debug( "Zone::onLeaveTerritory: Zone#{0}|{1}, Entity#{2}", getGuId(), getTerritoryTypeId(), player.getId() ); + Logger::debug( "Territory::onLeaveTerritory: Territory#{0}|{1}, Entity#{2}", getGuId(), getTerritoryTypeId(), player.getId() ); } -void Sapphire::Zone::onUpdate( uint64_t tickCount ) +void Sapphire::Territory::onUpdate( uint64_t tickCount ) { updateBNpcs( tickCount ); } -void Sapphire::Zone::onFinishLoading( Entity::Player& player ) +void Sapphire::Territory::onFinishLoading( Entity::Player& player ) { } -void Sapphire::Zone::onInitDirector( Entity::Player& player ) +void Sapphire::Territory::onInitDirector( Entity::Player& player ) { } -void Sapphire::Zone::onEnterTerritory( Sapphire::Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ) +void Sapphire::Territory::onEnterTerritory( Sapphire::Entity::Player& player, uint32_t eventId, uint16_t param1, uint16_t param2 ) { } -void Sapphire::Zone::registerEObj( Entity::EventObjectPtr object ) +void Sapphire::Territory::registerEObj( Entity::EventObjectPtr object ) { if( !object ) return; @@ -772,7 +772,7 @@ void Sapphire::Zone::registerEObj( Entity::EventObjectPtr object ) //Logger::debug( "Registered instance eobj: " + std::to_string( object->getId() ) ); } -Sapphire::Entity::EventObjectPtr Sapphire::Zone::getEObj( uint32_t objId ) +Sapphire::Entity::EventObjectPtr Sapphire::Territory::getEObj( uint32_t objId ) { auto obj = m_eventObjects.find( objId ); if( obj == m_eventObjects.end() ) @@ -781,28 +781,28 @@ Sapphire::Entity::EventObjectPtr Sapphire::Zone::getEObj( uint32_t objId ) return obj->second; } -Sapphire::InstanceContentPtr Sapphire::Zone::getAsInstanceContent() +Sapphire::InstanceContentPtr Sapphire::Territory::getAsInstanceContent() { - return std::dynamic_pointer_cast< InstanceContent, Zone >( shared_from_this() ); + return std::dynamic_pointer_cast< InstanceContent, Territory >( shared_from_this() ); } -Sapphire::QuestBattlePtr Sapphire::Zone::getAsQuestBattle() +Sapphire::QuestBattlePtr Sapphire::Territory::getAsQuestBattle() { - return std::dynamic_pointer_cast< QuestBattle, Zone >( shared_from_this() ); + return std::dynamic_pointer_cast< QuestBattle, Territory >( shared_from_this() ); } -uint32_t Sapphire::Zone::getNextEObjId() +uint32_t Sapphire::Territory::getNextEObjId() { return ++m_nextEObjId; } -uint32_t Sapphire::Zone::getNextActorId() +uint32_t Sapphire::Territory::getNextActorId() { return ++m_nextActorId; } -Sapphire::Entity::EventObjectPtr Sapphire::Zone::registerEObj( const std::string& name, uint32_t objectId, uint32_t mapLink, +Sapphire::Entity::EventObjectPtr Sapphire::Territory::registerEObj( const std::string& name, uint32_t objectId, uint32_t mapLink, uint8_t state, FFXIVARR_POSITION3 pos, float scale, float rotation ) { @@ -813,12 +813,12 @@ Sapphire::Entity::EventObjectPtr Sapphire::Zone::registerEObj( const std::string return eObj; } -Sapphire::Data::TerritoryTypePtr Sapphire::Zone::getTerritoryTypeInfo() const +Sapphire::Data::TerritoryTypePtr Sapphire::Territory::getTerritoryTypeInfo() const { return m_territoryTypeInfo; } -bool Sapphire::Zone::loadSpawnGroups() +bool Sapphire::Territory::loadSpawnGroups() { auto pDb = m_pFw->get< Db::DbWorkerPool< Db::ZoneDbConnection > >(); auto stmt = pDb->getPreparedStatement( Db::ZoneDbStatements::ZONE_SEL_SPAWNGROUPS ); @@ -863,7 +863,7 @@ bool Sapphire::Zone::loadSpawnGroups() return false; } -void Sapphire::Zone::updateSpawnPoints() +void Sapphire::Territory::updateSpawnPoints() { auto pRNGMgr = m_pFw->get< World::Manager::RNGMgr >(); auto rng = pRNGMgr->getRandGenerator< float >( 0.f, PI * 2 ); @@ -906,13 +906,13 @@ void Sapphire::Zone::updateSpawnPoints() } -uint32_t Sapphire::Zone::getNextEffectSequence() +uint32_t Sapphire::Territory::getNextEffectSequence() { return m_effectCounter++; } Sapphire::Entity::BNpcPtr - Sapphire::Zone::createBNpcFromLevelEntry( uint32_t levelId, uint8_t level, uint8_t type, + Sapphire::Territory::createBNpcFromLevelEntry( uint32_t levelId, uint8_t level, uint8_t type, uint32_t hp, uint16_t nameId, uint32_t directorId, uint8_t bnpcType ) { @@ -1006,9 +1006,9 @@ Sapphire::Entity::BNpcPtr return bnpc; } -Sapphire::Entity::BNpcPtr Sapphire::Zone::getActiveBNpcByLevelId( uint32_t levelId ) +Sapphire::Entity::BNpcPtr Sapphire::Territory::getActiveBNpcByLevelId( uint32_t levelId ) { - for( auto bnpcIt : m_bNpcMap ) + for( const auto& bnpcIt : m_bNpcMap ) { if( bnpcIt.second->getLevelId() == levelId ) return bnpcIt.second; @@ -1016,7 +1016,32 @@ Sapphire::Entity::BNpcPtr Sapphire::Zone::getActiveBNpcByLevelId( uint32_t level return nullptr; } -std::shared_ptr< Sapphire::World::Navi::NaviProvider > Sapphire::Zone::getNaviProvider() +std::shared_ptr< Sapphire::World::Navi::NaviProvider > Sapphire::Territory::getNaviProvider() { return m_pNaviProvider; } + +void Sapphire::Territory::addEffectResult( Sapphire::World::Action::EffectResultPtr result ) +{ + m_effectResults.emplace_back( std::move( result ) ); +} + +void Sapphire::Territory::processEffectResults( uint64_t tickCount ) + +{ + // todo: move this to generic territory/instance delay wrapper cause it might be useful scheduling other things + for( auto it = m_effectResults.begin(); it != m_effectResults.end(); ) + { + auto effect = *it; + + if( tickCount < effect->getDelay() ) + { + ++it; + continue; + } + + effect->execute(); + + it = m_effectResults.erase( it ); + } +} \ No newline at end of file diff --git a/src/world/Territory/Zone.h b/src/world/Territory/Territory.h similarity index 90% rename from src/world/Territory/Zone.h rename to src/world/Territory/Territory.h index 217f0230..34258d29 100644 --- a/src/world/Territory/Zone.h +++ b/src/world/Territory/Territory.h @@ -29,7 +29,7 @@ namespace Sapphire struct TerritoryType; } - class Zone : public CellHandler< Cell >, public std::enable_shared_from_this< Zone > + class Territory : public CellHandler< Cell >, public std::enable_shared_from_this< Territory > { protected: uint32_t m_territoryTypeId; @@ -65,13 +65,15 @@ namespace Sapphire uint32_t m_effectCounter; std::shared_ptr< World::Navi::NaviProvider > m_pNaviProvider; + std::vector< World::Action::EffectResultPtr > m_effectResults; + public: - Zone(); + Territory(); - Zone( uint16_t territoryTypeId, uint32_t guId, const std::string& internalName, - const std::string& placeName, FrameworkPtr pFw ); + Territory( uint16_t territoryTypeId, uint32_t guId, const std::string& internalName, + const std::string& placeName, FrameworkPtr pFw ); - virtual ~Zone(); + virtual ~Territory(); /*! overrides the zone's weather, set to 0 to unlock */ void setWeatherOverride( Common::Weather weather ); @@ -174,6 +176,10 @@ namespace Sapphire uint32_t getNextEffectSequence(); std::shared_ptr< World::Navi::NaviProvider > getNaviProvider(); + + void addEffectResult( World::Action::EffectResultPtr result ); + + void processEffectResults( uint64_t tickCount ); }; }