From e8dcef63ba3e17f9dfa583812ada703ce2ce908e Mon Sep 17 00:00:00 2001 From: collett Date: Sun, 5 Jan 2020 17:09:27 +0900 Subject: [PATCH 1/8] Action system updates. --- src/common/Common.h | 1 + src/common/Network/PacketDef/Ipcs.h | 6 +- .../Network/PacketDef/Zone/ServerZoneDef.h | 59 +- src/tools/action_parse/main.cpp | 4 +- src/world/Action/Action.cpp | 147 +- src/world/Action/Action.h | 8 + src/world/Action/ActionLut.h | 2 +- src/world/Action/ActionLutData.cpp | 2703 +++++++++-------- src/world/Action/EffectBuilder.cpp | 205 +- src/world/Action/EffectBuilder.h | 15 +- src/world/Action/EffectResult.cpp | 34 +- src/world/Action/EffectResult.h | 6 +- src/world/Actor/Chara.cpp | 12 + src/world/Actor/Chara.h | 2 + src/world/Actor/Player.cpp | 43 +- src/world/Actor/Player.h | 7 + src/world/Manager/ActionMgr.cpp | 24 +- .../Network/PacketWrappers/EffectPacket.h | 3 +- 18 files changed, 1896 insertions(+), 1385 deletions(-) diff --git a/src/common/Common.h b/src/common/Common.h index a78728e4..46ce75e4 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -629,6 +629,7 @@ namespace Sapphire::Common * @param value The actionid that starts/continues the combo. eg, 3617 will start a spinning slash and/or syphon strike combo */ StartActionCombo = 28, + ComboVisualEffect = 29, Knockback = 33, Mount = 38, VFX = 59, // links to VFX sheet diff --git a/src/common/Network/PacketDef/Ipcs.h b/src/common/Network/PacketDef/Ipcs.h index 689e9bd7..7a8b0947 100644 --- a/src/common/Network/PacketDef/Ipcs.h +++ b/src/common/Network/PacketDef/Ipcs.h @@ -156,7 +156,7 @@ namespace Sapphire::Network::Packets SilentSetClassJob = 0x018E, // updated 5.0 - seems to be the case, not sure if it's actually used for anything PlayerSetup = 0x0295, // updated 5.18 PlayerStats = 0x017A, // updated 5.18 - ActorOwner = 0x0322, // updated 5.11 + ActorOwner = 0x03BB, // updated 5.18 PlayerStateFlags = 0x02C6, // updated 5.18 PlayerClassInfo = 0x01B0, // updated 5.18 @@ -341,8 +341,8 @@ namespace Sapphire::Network::Packets PlaceFieldMarker = 0x013C, // updated 5.0 SkillHandler = 0x01BE, // updated 5.18 - GMCommand1 = 0x00A4, // updated 5.1 - GMCommand2 = 0x013F, // updated 5.0 + GMCommand1 = 0x014D, // updated 5.18 + GMCommand2 = 0x032C, // updated 5.18 AoESkillHandler = 0x140, // updated 5.0 UpdatePositionHandler = 0x0318, // updated 5.18 diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 310251b3..2cb79a26 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -537,33 +537,6 @@ namespace Sapphire::Network::Packets::Server /* 0012 */ uint32_t unknown_12; }; - - /** - * Structural representation of the packet sent by the server - * for battle actions - */ - struct EffectHeader - { - uint64_t animationTargetId; // who the animation targets - - uint32_t actionId; // what the casting player casts, shown in battle log/ui - uint32_t globalEffectCounter; // seems to only increment on retail? - - 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 - - uint16_t hiddenAnimation; // if 0, always shows animation, otherwise hides it. counts up by 1 for each animation skipped on a caster - uint16_t rotation; - uint16_t actionAnimationId; // the animation that is played by the casting character - uint8_t variation; // variation in the animation - Common::ActionEffectDisplayType effectDisplayType; - - uint8_t unknown20; // is read by handler, runs code which gets the LODWORD of animationLockTime (wtf?) - uint8_t effectCount; // ignores effects if 0, otherwise parses all of them - uint16_t padding_21; - - }; - struct FFXIVIpcEffect : FFXIVIpcBasePacket< Effect > { uint64_t animationTargetId; // who the animation targets @@ -608,17 +581,35 @@ namespace Sapphire::Network::Packets::Server template< int size > struct FFXIVIpcAoeEffect { - EffectHeader header; + uint64_t animationTargetId; // who the animation targets - Common::EffectEntry effects[size]; + uint32_t actionId; // what the casting player casts, shown in battle log/ui + uint32_t globalSequence; // seems to only increment on retail? + + 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 + + uint16_t sourceSequence; // if 0, always shows animation, otherwise hides it. counts up by 1 for each animation skipped on a caster + uint16_t rotation; + uint16_t actionAnimationId; // the animation that is played by the casting character + uint8_t variation; // variation in the animation + Common::ActionEffectDisplayType effectDisplayType; + + uint8_t unknown20; // is read by handler, runs code which gets the LODWORD of animationLockTime (wtf?) + uint8_t effectCount; // ignores effects if 0, otherwise parses all of them + uint16_t padding_21[3]; + uint16_t padding; + + struct + { + Common::EffectEntry entries[8]; + } effects[size]; uint16_t padding_6A[3]; - uint32_t effectTargetId[size]; - Common::FFXIVARR_POSITION3 position; - uint32_t effectFlags; - - uint32_t padding_78; + uint64_t effectTargetId[size]; + uint16_t unkFlag[3]; // all 0x7FFF + uint16_t unk[3]; }; struct FFXIVIpcAoeEffect8 : diff --git a/src/tools/action_parse/main.cpp b/src/tools/action_parse/main.cpp index aa40bdd1..ff750cf6 100644 --- a/src/tools/action_parse/main.cpp +++ b/src/tools/action_parse/main.cpp @@ -249,11 +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.comboPotency, data.flankPotency, data.frontPotency, data.rearPotency, - data.curePotency ); + data.curePotency, 0 ); output += out; // Logger::info( out ); diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index 871473e6..1c2f10aa 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -1,5 +1,4 @@ #include "Action.h" -#include "ActionLut.h" #include "EffectBuilder.h" #include @@ -127,6 +126,15 @@ bool Action::Action::init() // todo: add missing rows for secondaryCostType/secondaryCostType and rename the current rows to primaryCostX + if( ActionLut::validEntryExists( static_cast< uint16_t >( getId() ) ) ) + { + m_lutEntry = ActionLut::getEntry( static_cast< uint16_t >( getId() ) ); + } + else + { + std::memset( &m_lutEntry, 0, sizeof( ActionEntry ) ); + } + addDefaultActorFilters(); return true; @@ -162,6 +170,11 @@ bool Action::Action::isInterrupted() const return m_interruptType != Common::ActionInterruptType::None; } +Common::ActionInterruptType Action::Action::getInterruptType() const +{ + return m_interruptType; +} + void Action::Action::setInterrupted( Common::ActionInterruptType type ) { m_interruptType = type; @@ -212,6 +225,30 @@ bool Action::Action::update() return true; } + if( m_pTarget == nullptr && m_targetId != 0 ) + { + // try to search for the target actor + for( auto actor : m_pSource->getInRangeActors( true ) ) + { + if( actor->getId() == m_targetId ) + { + m_pTarget = actor->getAsChara(); + break; + } + } + } + + if( m_pTarget != nullptr ) + { + if( !m_pTarget->isAlive() ) + { + // interrupt the cast if target died + setInterrupted( Common::ActionInterruptType::RegularInterrupt ); + interrupt(); + return true; + } + } + return false; } @@ -336,7 +373,7 @@ void Action::Action::execute() } } - if( isComboAction() ) + if( isCorrectCombo() ) { auto player = m_pSource->getAsPlayer(); @@ -356,7 +393,15 @@ void Action::Action::execute() // ignore it otherwise (ogcds, etc.) if( !m_actionData->preservesCombo ) { - m_pSource->setLastComboActionId( getId() ); + // potential combo starter or correct combo from last action + if( ( !isComboAction() || isCorrectCombo() ) ) + { + m_pSource->setLastComboActionId( getId() ); + } + else // clear last combo action if the combo breaks + { + m_pSource->setLastComboActionId( 0 ); + } } } @@ -391,7 +436,7 @@ void Action::Action::buildEffects() snapshotAffectedActors( m_hitActors ); auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >(); - auto hasLutEntry = ActionLut::validEntryExists( static_cast< uint16_t >( getId() ) ); + auto hasLutEntry = hasValidLutEntry(); if( !pScriptMgr->onExecute( *this ) && !hasLutEntry ) { @@ -406,29 +451,69 @@ void Action::Action::buildEffects() if( !hasLutEntry || m_hitActors.empty() ) return; - auto lutEntry = ActionLut::getEntry( static_cast< uint16_t >( 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 ); + player->sendDebug( "Hit target: pot: {} (c: {}, f: {}, r: {}), heal pot: {}, mpp: {}", + m_lutEntry.potency, m_lutEntry.comboPotency, m_lutEntry.flankPotency, m_lutEntry.rearPotency, + m_lutEntry.curePotency, m_lutEntry.restoreMPPercentage ); } + // when aoe, these effects are in the target whatever is hit first + bool shouldRestoreMP = true; + bool shouldShowComboEffect = true; + for( auto& actor : m_hitActors ) { - // todo: this is shit - if( lutEntry.curePotency > 0 ) + if( m_lutEntry.potency > 0 ) { - - m_effectBuilder->healTarget( actor, lutEntry.curePotency ); - } - - else if( lutEntry.potency > 0 ) - { - auto dmg = calcDamage( lutEntry.potency ); + auto dmg = calcDamage( isCorrectCombo() ? m_lutEntry.comboPotency : m_lutEntry.potency ); m_effectBuilder->damageTarget( actor, dmg.first, dmg.second ); + + if( dmg.first > 0 ) + actor->onActionHostile( m_pSource ); + + if( isCorrectCombo() && shouldShowComboEffect ) + { + m_effectBuilder->comboVisualEffect( actor ); + shouldShowComboEffect = false; + } + + if( !isComboAction() || isCorrectCombo() ) + { + if( m_lutEntry.curePotency > 0 ) // actions with self heal + { + m_effectBuilder->selfHeal( actor, m_pSource, m_lutEntry.curePotency ); + } + + if( m_lutEntry.restoreMPPercentage > 0 && shouldRestoreMP ) + { + m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100 ); + shouldRestoreMP = false; + } + + if ( !m_actionData->preservesCombo ) // we need something like m_actionData->hasNextComboAction + { + m_effectBuilder->startCombo( actor, getId() ); // this is on all targets hit + } + } + } + else if( m_lutEntry.curePotency > 0 ) + { + // todo: calcHealing() + m_effectBuilder->healTarget( actor, m_lutEntry.curePotency ); + + if( m_lutEntry.restoreMPPercentage > 0 && shouldRestoreMP ) + { + // always restore caster mp I don't think there are any actions that can restore target MP post 5.0 + m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100 ); + shouldRestoreMP = false; + } + } + else if( m_lutEntry.restoreMPPercentage > 0 && shouldRestoreMP ) + { + m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100 ); + shouldRestoreMP = false; } } @@ -511,7 +596,7 @@ void Action::Action::setAdditionalData( uint32_t data ) m_additionalData = data; } -bool Action::Action::isComboAction() const +bool Action::Action::isCorrectCombo() const { auto lastActionId = m_pSource->getLastComboActionId(); @@ -523,6 +608,11 @@ bool Action::Action::isComboAction() const return m_actionData->actionCombo == lastActionId; } +bool Action::Action::isComboAction() const +{ + return m_actionData->actionCombo != 0; +} + bool Action::Action::primaryCostCheck( bool subtractCosts ) { switch( m_primaryCostType ) @@ -657,11 +747,24 @@ void Action::Action::addDefaultActorFilters() bool Action::Action::preFilterActor( Sapphire::Entity::Actor& actor ) const { auto kind = actor.getObjKind(); + auto chara = actor.getAsChara(); // todo: are there any server side eobjs that players can hit? if( kind != ObjKind::BattleNpc && kind != ObjKind::Player ) return false; + if( m_lutEntry.potency > 0 && chara == m_pSource ) + { + // damage action shouldn't hit self + return false; + } + + if( ( m_lutEntry.potency > 0 || m_lutEntry.curePotency > 0 ) && !chara->isAlive() ) + { + // can't deal damage or heal a dead entity + return false; + } + // todo: handle things such based on canTargetX return true; @@ -680,4 +783,10 @@ Sapphire::Entity::CharaPtr Action::Action::getHitChara() } return nullptr; +} + +bool Action::Action::hasValidLutEntry() const +{ + return m_lutEntry.potency != 0 || m_lutEntry.comboPotency != 0 || m_lutEntry.flankPotency != 0 || m_lutEntry.frontPotency != 0 || + m_lutEntry.rearPotency != 0 || m_lutEntry.curePotency != 0 || m_lutEntry.restoreMPPercentage != 0; } \ No newline at end of file diff --git a/src/world/Action/Action.h b/src/world/Action/Action.h index 8288b90e..b85f5f03 100644 --- a/src/world/Action/Action.h +++ b/src/world/Action/Action.h @@ -2,6 +2,7 @@ #define _ACTION_H_ #include +#include "ActionLut.h" #include "Util/ActorFilter.h" #include "ForwardsZone.h" @@ -37,6 +38,7 @@ namespace Sapphire::World::Action Entity::CharaPtr getSourceChara() const; bool isInterrupted() const; + Common::ActionInterruptType getInterruptType() const; void setInterrupted( Common::ActionInterruptType type ); uint32_t getCastTime() const; @@ -45,6 +47,8 @@ namespace Sapphire::World::Action uint32_t getAdditionalData() const; void setAdditionalData( uint32_t data ); + bool isCorrectCombo() const; + bool isComboAction() const; /*! @@ -143,6 +147,8 @@ namespace Sapphire::World::Action bool preFilterActor( Entity::Actor& actor ) const; + bool hasValidLutEntry() const; + uint32_t m_id; uint16_t m_sequence; @@ -183,6 +189,8 @@ namespace Sapphire::World::Action std::vector< World::Util::ActorFilterPtr > m_actorFilters; std::vector< Entity::CharaPtr > m_hitActors; + + ActionEntry m_lutEntry; }; } diff --git a/src/world/Action/ActionLut.h b/src/world/Action/ActionLut.h index f8eeafa8..f19b8c84 100644 --- a/src/world/Action/ActionLut.h +++ b/src/world/Action/ActionLut.h @@ -13,7 +13,7 @@ namespace Sapphire::World::Action uint16_t frontPotency; uint16_t rearPotency; uint16_t curePotency; -// uint16_t restorePercentage; + uint16_t restoreMPPercentage; }; class ActionLut diff --git a/src/world/Action/ActionLutData.cpp b/src/world/Action/ActionLutData.cpp index 76e352ae..88b8a71a 100644 --- a/src/world/Action/ActionLutData.cpp +++ b/src/world/Action/ActionLutData.cpp @@ -5,1402 +5,1523 @@ using namespace Sapphire::World::Action; ActionLut::Lut ActionLut::m_actionLut = { // attack - { 7, { 0, 0, 0, 0, 0, 0 } }, + { 7, { 0, 0, 0, 0, 0, 0, 0 } }, // Shot - { 8, { 0, 0, 0, 0, 0, 0 } }, + { 8, { 0, 0, 0, 0, 0, 0, 0 } }, // Fast Blade - { 9, { 200, 0, 0, 0, 0, 0 } }, + { 9, { 200, 0, 0, 0, 0, 0, 0 } }, // Riot Blade - { 15, { 100, 300, 0, 0, 0, 0 } }, + { 15, { 100, 300, 0, 0, 0, 0, 10 } }, // Shield Bash - { 16, { 110, 0, 0, 0, 0, 0 } }, + { 16, { 110, 0, 0, 0, 0, 0, 0 } }, // Sentinel - { 17, { 0, 0, 0, 0, 0, 0 } }, + { 17, { 0, 0, 0, 0, 0, 0, 0 } }, // Fight or Flight - { 20, { 0, 0, 0, 0, 0, 0 } }, + { 20, { 0, 0, 0, 0, 0, 0, 0 } }, // Rage of Halone - { 21, { 100, 350, 0, 0, 0, 0 } }, + { 21, { 100, 350, 0, 0, 0, 0, 0 } }, // Circle of Scorn - { 23, { 120, 0, 0, 0, 0, 0 } }, + { 23, { 120, 0, 0, 0, 0, 0, 0 } }, // Shield Lob - { 24, { 120, 0, 0, 0, 0, 0 } }, + { 24, { 120, 0, 0, 0, 0, 0, 0 } }, // Cover - { 27, { 0, 0, 0, 0, 0, 0 } }, + { 27, { 0, 0, 0, 0, 0, 0, 0 } }, // Iron Will - { 28, { 0, 0, 0, 0, 0, 0 } }, + { 28, { 0, 0, 0, 0, 0, 0, 0 } }, // Spirits Within - { 29, { 370, 0, 0, 0, 0, 0 } }, + { 29, { 100, 0, 0, 0, 0, 0, 5 } }, // Hallowed Ground - { 30, { 0, 0, 0, 0, 0, 0 } }, + { 30, { 0, 0, 0, 0, 0, 0, 0 } }, // Heavy Swing - { 31, { 200, 0, 0, 0, 0, 0 } }, + { 31, { 200, 0, 0, 0, 0, 0, 0 } }, // Maim - { 37, { 100, 300, 0, 0, 0, 0 } }, + { 37, { 100, 300, 0, 0, 0, 0, 0 } }, // Berserk - { 38, { 0, 0, 0, 0, 0, 0 } }, + { 38, { 0, 0, 0, 0, 0, 0, 0 } }, // Thrill of Battle - { 40, { 0, 0, 0, 0, 0, 0 } }, + { 40, { 0, 0, 0, 0, 0, 0, 0 } }, // Overpower - { 41, { 130, 0, 0, 0, 0, 0 } }, + { 41, { 130, 0, 0, 0, 0, 0, 0 } }, // Storm's Path - { 42, { 100, 380, 0, 0, 0, 250 } }, + { 42, { 100, 380, 0, 0, 0, 250, 0 } }, // Holmgang - { 43, { 0, 0, 0, 0, 0, 0 } }, + { 43, { 0, 0, 0, 0, 0, 0, 0 } }, // Vengeance - { 44, { 55, 0, 0, 0, 0, 0 } }, + { 44, { 55, 0, 0, 0, 0, 0, 0 } }, // Storm's Eye - { 45, { 100, 380, 0, 0, 0, 0 } }, + { 45, { 100, 380, 0, 0, 0, 0, 0 } }, // Tomahawk - { 46, { 140, 0, 0, 0, 0, 0 } }, + { 46, { 140, 0, 0, 0, 0, 0, 0 } }, // Defiance - { 48, { 0, 0, 0, 0, 0, 0 } }, + { 48, { 0, 0, 0, 0, 0, 0, 0 } }, // Inner Beast - { 49, { 350, 0, 0, 0, 0, 0 } }, + { 49, { 350, 0, 0, 0, 0, 0, 0 } }, // Steel Cyclone - { 51, { 220, 0, 0, 0, 0, 0 } }, + { 51, { 220, 0, 0, 0, 0, 0, 0 } }, // Infuriate - { 52, { 0, 0, 0, 0, 0, 0 } }, + { 52, { 0, 0, 0, 0, 0, 0, 0 } }, // Bootshine - { 53, { 150, 0, 0, 0, 0, 0 } }, + { 53, { 150, 0, 0, 0, 0, 0, 0 } }, // True Strike - { 54, { 220, 0, 0, 0, 240, 0 } }, + { 54, { 220, 0, 0, 0, 240, 0, 0 } }, // Snap Punch - { 56, { 210, 0, 230, 0, 0, 0 } }, + { 56, { 210, 0, 230, 0, 0, 0, 0 } }, // Fists of Earth - { 60, { 0, 0, 0, 0, 0, 0 } }, + { 60, { 0, 0, 0, 0, 0, 0, 0 } }, // Twin Snakes - { 61, { 150, 0, 170, 0, 0, 0 } }, + { 61, { 150, 0, 170, 0, 0, 0, 0 } }, // Arm of the Destroyer - { 62, { 80, 0, 0, 0, 0, 0 } }, + { 62, { 80, 0, 0, 0, 0, 0, 0 } }, // Fists of Fire - { 63, { 0, 0, 0, 0, 0, 0 } }, + { 63, { 0, 0, 0, 0, 0, 0, 0 } }, // Mantra - { 65, { 0, 0, 0, 0, 0, 0 } }, + { 65, { 0, 0, 0, 0, 0, 0, 0 } }, // Demolish - { 66, { 70, 0, 0, 0, 90, 0 } }, + { 66, { 70, 0, 0, 0, 90, 0, 0 } }, // Perfect Balance - { 69, { 0, 0, 0, 0, 0, 0 } }, + { 69, { 0, 0, 0, 0, 0, 0, 0 } }, // Rockbreaker - { 70, { 120, 0, 0, 0, 0, 0 } }, + { 70, { 120, 0, 0, 0, 0, 0, 0 } }, // Shoulder Tackle - { 71, { 100, 0, 0, 0, 0, 0 } }, + { 71, { 100, 0, 0, 0, 0, 0, 0 } }, // Fists of Wind - { 73, { 0, 0, 0, 0, 0, 0 } }, + { 73, { 0, 0, 0, 0, 0, 0, 0 } }, // Dragon Kick - { 74, { 180, 0, 200, 0, 0, 0 } }, + { 74, { 180, 0, 200, 0, 0, 0, 0 } }, // True Thrust - { 75, { 0, 0, 0, 0, 0, 0 } }, + { 75, { 0, 0, 0, 0, 0, 0, 0 } }, // Vorpal Thrust - { 78, { 0, 0, 0, 0, 0, 0 } }, + { 78, { 0, 0, 0, 0, 0, 0, 0 } }, // Life Surge - { 83, { 0, 0, 0, 0, 0, 0 } }, + { 83, { 0, 0, 0, 0, 0, 0, 0 } }, // Full Thrust - { 84, { 100, 530, 0, 0, 0, 0 } }, + { 84, { 100, 530, 0, 0, 0, 0, 0 } }, // Lance Charge - { 85, { 0, 0, 0, 0, 0, 0 } }, + { 85, { 0, 0, 0, 0, 0, 0, 0 } }, // Doom Spike - { 86, { 170, 0, 0, 0, 0, 0 } }, + { 86, { 170, 0, 0, 0, 0, 0, 0 } }, // Disembowel - { 87, { 0, 0, 0, 0, 0, 0 } }, + { 87, { 0, 0, 0, 0, 0, 0, 0 } }, // Chaos Thrust - { 88, { 100, 290, 0, 0, 140, 0 } }, + { 88, { 100, 290, 0, 0, 140, 0, 0 } }, // Piercing Talon - { 90, { 150, 0, 0, 0, 0, 0 } }, + { 90, { 150, 0, 0, 0, 0, 0, 0 } }, // Jump - { 92, { 310, 0, 0, 0, 0, 0 } }, + { 92, { 310, 0, 0, 0, 0, 0, 0 } }, // Elusive Jump - { 94, { 0, 0, 0, 0, 0, 0 } }, + { 94, { 0, 0, 0, 0, 0, 0, 0 } }, // Spineshatter Dive - { 95, { 240, 0, 0, 0, 0, 0 } }, + { 95, { 240, 0, 0, 0, 0, 0, 0 } }, // Dragonfire Dive - { 96, { 380, 0, 0, 0, 0, 0 } }, + { 96, { 380, 0, 0, 0, 0, 0, 0 } }, // Heavy Shot - { 97, { 180, 0, 0, 0, 0, 0 } }, + { 97, { 180, 0, 0, 0, 0, 0, 0 } }, // Straight Shot - { 98, { 200, 0, 0, 0, 0, 0 } }, + { 98, { 200, 0, 0, 0, 0, 0, 0 } }, // Venomous Bite - { 100, { 100, 0, 0, 0, 0, 0 } }, + { 100, { 100, 0, 0, 0, 0, 0, 0 } }, // Raging Strikes - { 101, { 0, 0, 0, 0, 0, 0 } }, + { 101, { 0, 0, 0, 0, 0, 0, 0 } }, // Quick Nock - { 106, { 150, 0, 0, 0, 0, 0 } }, + { 106, { 150, 0, 0, 0, 0, 0, 0 } }, // Barrage - { 107, { 0, 0, 0, 0, 0, 0 } }, + { 107, { 0, 0, 0, 0, 0, 0, 0 } }, // Bloodletter - { 110, { 150, 0, 0, 0, 0, 0 } }, + { 110, { 150, 0, 0, 0, 0, 0, 0 } }, // Repelling Shot - { 112, { 0, 0, 0, 0, 0, 0 } }, + { 112, { 0, 0, 0, 0, 0, 0, 0 } }, // Windbite - { 113, { 60, 0, 0, 0, 0, 0 } }, + { 113, { 60, 0, 0, 0, 0, 0, 0 } }, // Mage's Ballad - { 114, { 100, 0, 0, 0, 0, 0 } }, + { 114, { 100, 0, 0, 0, 0, 0, 0 } }, // Army's Paeon - { 116, { 100, 0, 0, 0, 0, 0 } }, + { 116, { 100, 0, 0, 0, 0, 0, 0 } }, // Rain of Death - { 117, { 130, 0, 0, 0, 0, 0 } }, + { 117, { 130, 0, 0, 0, 0, 0, 0 } }, // Battle Voice - { 118, { 0, 0, 0, 0, 0, 0 } }, + { 118, { 0, 0, 0, 0, 0, 0, 0 } }, // Stone - { 119, { 140, 0, 0, 0, 0, 0 } }, + { 119, { 140, 0, 0, 0, 0, 0, 0 } }, // Cure - { 120, { 0, 0, 0, 0, 0, 450 } }, + { 120, { 0, 0, 0, 0, 0, 450, 0 } }, // Aero - { 121, { 50, 0, 0, 0, 0, 0 } }, + { 121, { 50, 0, 0, 0, 0, 0, 0 } }, // Medica - { 124, { 0, 0, 0, 0, 0, 300 } }, + { 124, { 0, 0, 0, 0, 0, 300, 0 } }, // Raise - { 125, { 0, 0, 0, 0, 0, 0 } }, + { 125, { 0, 0, 0, 0, 0, 0, 0 } }, // Stone II - { 127, { 200, 0, 0, 0, 0, 0 } }, + { 127, { 200, 0, 0, 0, 0, 0, 0 } }, // Cure III - { 131, { 0, 0, 0, 0, 0, 550 } }, + { 131, { 0, 0, 0, 0, 0, 550, 0 } }, // Aero II - { 132, { 60, 0, 0, 0, 0, 0 } }, + { 132, { 60, 0, 0, 0, 0, 0, 0 } }, // Medica II - { 133, { 0, 0, 0, 0, 0, 200 } }, + { 133, { 0, 0, 0, 0, 0, 200, 0 } }, // Fluid Aura - { 134, { 0, 0, 0, 0, 0, 0 } }, + { 134, { 0, 0, 0, 0, 0, 0, 0 } }, // Cure II - { 135, { 0, 0, 0, 0, 0, 700 } }, + { 135, { 0, 0, 0, 0, 0, 700, 0 } }, // Presence of Mind - { 136, { 0, 0, 0, 0, 0, 0 } }, + { 136, { 0, 0, 0, 0, 0, 0, 0 } }, // Regen - { 137, { 0, 0, 0, 0, 0, 200 } }, + { 137, { 0, 0, 0, 0, 0, 200, 0 } }, // Holy - { 139, { 140, 0, 0, 0, 0, 0 } }, + { 139, { 140, 0, 0, 0, 0, 0, 0 } }, // Benediction - { 140, { 0, 0, 0, 0, 0, 0 } }, + { 140, { 0, 0, 0, 0, 0, 0, 0 } }, // Fire - { 141, { 180, 0, 0, 0, 0, 0 } }, + { 141, { 180, 0, 0, 0, 0, 0, 0 } }, // Blizzard - { 142, { 180, 0, 0, 0, 0, 0 } }, + { 142, { 180, 0, 0, 0, 0, 0, 0 } }, // Thunder - { 144, { 30, 0, 0, 0, 0, 0 } }, + { 144, { 30, 0, 0, 0, 0, 0, 0 } }, // Sleep - { 145, { 0, 0, 0, 0, 0, 0 } }, + { 145, { 0, 0, 0, 0, 0, 0, 0 } }, // Blizzard II - { 146, { 50, 0, 0, 0, 0, 0 } }, + { 146, { 50, 0, 0, 0, 0, 0, 0 } }, // Fire II - { 147, { 80, 0, 0, 0, 0, 0 } }, + { 147, { 80, 0, 0, 0, 0, 0, 0 } }, // Transpose - { 149, { 0, 0, 0, 0, 0, 0 } }, + { 149, { 0, 0, 0, 0, 0, 0, 0 } }, // Fire III - { 152, { 240, 0, 0, 0, 0, 0 } }, + { 152, { 240, 0, 0, 0, 0, 0, 0 } }, // Thunder III - { 153, { 70, 0, 0, 0, 0, 0 } }, + { 153, { 70, 0, 0, 0, 0, 0, 0 } }, // Blizzard III - { 154, { 240, 0, 0, 0, 0, 0 } }, + { 154, { 240, 0, 0, 0, 0, 0, 0 } }, // Aetherial Manipulation - { 155, { 0, 0, 0, 0, 0, 0 } }, + { 155, { 0, 0, 0, 0, 0, 0, 0 } }, // Scathe - { 156, { 100, 0, 0, 0, 0, 0 } }, + { 156, { 100, 0, 0, 0, 0, 0, 0 } }, // Manaward - { 157, { 0, 0, 0, 0, 0, 0 } }, + { 157, { 0, 0, 0, 0, 0, 0, 0 } }, // Manafont - { 158, { 0, 0, 0, 0, 0, 0 } }, + { 158, { 0, 0, 0, 0, 0, 0, 30 } }, // Freeze - { 159, { 100, 0, 0, 0, 0, 0 } }, + { 159, { 100, 0, 0, 0, 0, 0, 0 } }, // Flare - { 162, { 260, 0, 0, 0, 0, 0 } }, + { 162, { 260, 0, 0, 0, 0, 0, 0 } }, // Ruin - { 163, { 80, 0, 0, 0, 0, 0 } }, + { 163, { 180, 0, 0, 0, 0, 0, 0 } }, // Bio - { 164, { 0, 0, 0, 0, 0, 0 } }, + { 164, { 0, 0, 0, 0, 0, 0, 0 } }, // Summon - { 165, { 0, 0, 0, 0, 0, 0 } }, + { 165, { 0, 0, 0, 0, 0, 0, 0 } }, // Aetherflow - { 166, { 0, 0, 0, 0, 0, 0 } }, - // Miasma - { 168, { 20, 0, 0, 0, 0, 0 } }, - // Summon II - { 170, { 0, 0, 0, 0, 0, 0 } }, - // Ruin II - { 172, { 80, 0, 0, 0, 0, 0 } }, - // Resurrection - { 173, { 0, 0, 0, 0, 0, 0 } }, - // Bane - { 174, { 0, 0, 0, 0, 0, 0 } }, - // Bio II - { 178, { 0, 0, 0, 0, 0, 0 } }, - // Summon III - { 180, { 0, 0, 0, 0, 0, 0 } }, - // Fester - { 181, { 100, 0, 0, 0, 0, 0 } }, - // Enkindle - { 184, { 0, 0, 0, 0, 0, 0 } }, - // Adloquium - { 185, { 0, 0, 0, 0, 0, 300 } }, - // Succor - { 186, { 0, 0, 0, 0, 0, 180 } }, - // Sacred Soil - { 188, { 0, 0, 0, 0, 0, 100 } }, - // Lustrate - { 189, { 0, 0, 0, 0, 0, 600 } }, - // Physick - { 190, { 0, 0, 0, 0, 0, 400 } }, - // Shield Wall - { 197, { 0, 0, 0, 0, 0, 0 } }, - // Stronghold - { 198, { 0, 0, 0, 0, 0, 0 } }, - // Last Bastion - { 199, { 0, 0, 0, 0, 0, 0 } }, - // Braver - { 200, { 2400, 0, 0, 0, 0, 0 } }, - // Bladedance - { 201, { 5250, 0, 0, 0, 0, 0 } }, - // Final Heaven - { 202, { 9000, 0, 0, 0, 0, 0 } }, - // Skyshard - { 203, { 1650, 0, 0, 0, 0, 0 } }, - // Starstorm - { 204, { 3600, 0, 0, 0, 0, 0 } }, - // Meteor - { 205, { 6150, 0, 0, 0, 0, 0 } }, - // Healing Wind - { 206, { 0, 0, 0, 0, 0, 0 } }, - // Breath of the Earth - { 207, { 0, 0, 0, 0, 0, 0 } }, - // Pulse of Life - { 208, { 0, 0, 0, 0, 0, 0 } }, - // Magitek Cannon - { 1128, { 0, 0, 0, 0, 0, 0 } }, - // Photon Stream - { 1129, { 0, 0, 0, 0, 0, 0 } }, - // attack - { 1533, { 0, 0, 0, 0, 0, 0 } }, - // Spinning Edge - { 2240, { 200, 0, 0, 0, 0, 0 } }, - // Shade Shift - { 2241, { 0, 0, 0, 0, 0, 0 } }, - // Gust Slash - { 2242, { 100, 250, 0, 0, 0, 0 } }, - // Hide - { 2245, { 0, 0, 0, 0, 0, 0 } }, - // Assassinate - { 2246, { 200, 0, 0, 0, 0, 0 } }, - // Throwing Dagger - { 2247, { 120, 0, 0, 0, 0, 0 } }, - // Mug - { 2248, { 150, 0, 0, 0, 0, 0 } }, - // Death Blossom - { 2254, { 120, 0, 0, 0, 0, 0 } }, - // Aeolian Edge - { 2255, { 100, 360, 0, 0, 160, 0 } }, - // Shadow Fang - { 2257, { 100, 200, 0, 0, 0, 0 } }, - // Trick Attack - { 2258, { 340, 0, 0, 0, 500, 0 } }, - // Ten - { 2259, { 0, 0, 0, 0, 0, 0 } }, - // Ninjutsu - { 2260, { 0, 0, 0, 0, 0, 0 } }, - // Chi - { 2261, { 0, 0, 0, 0, 0, 0 } }, - // Shukuchi - { 2262, { 0, 0, 0, 0, 0, 0 } }, - // Jin - { 2263, { 0, 0, 0, 0, 0, 0 } }, - // Kassatsu - { 2264, { 0, 0, 0, 0, 0, 0 } }, - // Fuma Shuriken - { 2265, { 280, 0, 0, 0, 0, 0 } }, - // Katon - { 2266, { 250, 0, 0, 0, 0, 0 } }, - // Raiton - { 2267, { 400, 0, 0, 0, 0, 0 } }, - // Hyoton - { 2268, { 140, 0, 0, 0, 0, 0 } }, - // Huton - { 2269, { 0, 0, 0, 0, 0, 0 } }, - // Doton - { 2270, { 45, 0, 0, 0, 0, 0 } }, - // Suiton - { 2271, { 130, 0, 0, 0, 0, 0 } }, - // Rabbit Medium - { 2272, { 0, 0, 0, 0, 0, 0 } }, - // Rook Autoturret - { 2864, { 80, 0, 0, 0, 0, 0 } }, - // Split Shot - { 2866, { 160, 0, 0, 0, 0, 0 } }, - // Slug Shot - { 2868, { 100, 240, 0, 0, 0, 0 } }, - // Spread Shot - { 2870, { 180, 0, 0, 0, 0, 0 } }, - // Hot Shot - { 2872, { 300, 0, 0, 0, 0, 0 } }, - // Clean Shot - { 2873, { 100, 320, 0, 0, 0, 0 } }, - // Gauss Round - { 2874, { 150, 0, 0, 0, 0, 0 } }, - // Reassemble - { 2876, { 0, 0, 0, 0, 0, 0 } }, - // Wildfire - { 2878, { 0, 0, 0, 0, 0, 0 } }, - // Ricochet - { 2890, { 150, 0, 0, 0, 0, 0 } }, - // Raiton - { 3203, { 0, 0, 0, 0, 0, 0 } }, - // Raiton - { 3204, { 0, 0, 0, 0, 0, 0 } }, - // Kanashibari - { 3207, { 0, 0, 0, 0, 0, 0 } }, - // Goring Blade - { 3538, { 100, 390, 0, 0, 0, 0 } }, - // Royal Authority - { 3539, { 100, 550, 0, 0, 0, 0 } }, - // Divine Veil - { 3540, { 0, 0, 0, 0, 0, 0 } }, - // Clemency - { 3541, { 0, 0, 0, 0, 0, 1200 } }, - // Sheltron - { 3542, { 0, 0, 0, 0, 0, 0 } }, - // Tornado Kick - { 3543, { 330, 0, 0, 0, 0, 0 } }, - // Elixir Field - { 3545, { 200, 0, 0, 0, 0, 0 } }, - // Meditation - { 3546, { 0, 0, 0, 0, 0, 0 } }, - // the Forbidden Chakra - { 3547, { 370, 0, 0, 0, 0, 0 } }, - // Fell Cleave - { 3549, { 590, 0, 0, 0, 0, 0 } }, - // Decimate - { 3550, { 250, 0, 0, 0, 0, 0 } }, - // Raw Intuition - { 3551, { 0, 0, 0, 0, 0, 0 } }, - // Equilibrium - { 3552, { 0, 0, 0, 0, 0, 1200 } }, - // Blood of the Dragon - { 3553, { 0, 0, 0, 0, 0, 0 } }, - // Fang and Claw - { 3554, { 320, 0, 360, 0, 0, 0 } }, - // Geirskogul - { 3555, { 270, 0, 0, 0, 0, 0 } }, - // Wheeling Thrust - { 3556, { 320, 0, 0, 0, 360, 0 } }, - // Battle Litany - { 3557, { 0, 0, 0, 0, 0, 0 } }, - // Empyreal Arrow - { 3558, { 230, 0, 0, 0, 0, 0 } }, - // the Wanderer's Minuet - { 3559, { 100, 0, 0, 0, 0, 0 } }, - // Iron Jaws - { 3560, { 100, 0, 0, 0, 0, 0 } }, - // the Warden's Paean - { 3561, { 0, 0, 0, 0, 0, 0 } }, - // Sidewinder - { 3562, { 100, 0, 0, 0, 0, 0 } }, - // Armor Crush - { 3563, { 100, 330, 160, 0, 0, 0 } }, - // Dream Within a Dream - { 3566, { 200, 0, 0, 0, 0, 0 } }, - // Stone III - { 3568, { 240, 0, 0, 0, 0, 0 } }, - // Asylum - { 3569, { 0, 0, 0, 0, 0, 100 } }, - // Tetragrammaton - { 3570, { 0, 0, 0, 0, 0, 700 } }, - // Assize - { 3571, { 400, 0, 0, 0, 0, 400 } }, - // Ley Lines - { 3573, { 0, 0, 0, 0, 0, 0 } }, - // Sharpcast - { 3574, { 0, 0, 0, 0, 0, 0 } }, - // Enochian - { 3575, { 0, 0, 0, 0, 0, 0 } }, - // Blizzard IV - { 3576, { 300, 0, 0, 0, 0, 0 } }, - // Fire IV - { 3577, { 300, 0, 0, 0, 0, 0 } }, - // Painflare - { 3578, { 150, 0, 0, 0, 0, 0 } }, - // Ruin III - { 3579, { 100, 0, 0, 0, 0, 0 } }, - // Tri-disaster - { 3580, { 0, 0, 0, 0, 0, 0 } }, - // Dreadwyrm Trance - { 3581, { 0, 0, 0, 0, 0, 0 } }, - // Deathflare - { 3582, { 400, 0, 0, 0, 0, 0 } }, - // Indomitability - { 3583, { 0, 0, 0, 0, 0, 400 } }, - // Broil - { 3584, { 240, 0, 0, 0, 0, 0 } }, - // Deployment Tactics - { 3585, { 0, 0, 0, 0, 0, 0 } }, - // Emergency Tactics - { 3586, { 0, 0, 0, 0, 0, 0 } }, - // Dissipation - { 3587, { 0, 0, 0, 0, 0, 0 } }, - // Draw - { 3590, { 0, 0, 0, 0, 0, 0 } }, - // Redraw - { 3593, { 0, 0, 0, 0, 0, 0 } }, - // Benefic - { 3594, { 0, 0, 0, 0, 0, 400 } }, - // Aspected Benefic - { 3595, { 0, 0, 0, 0, 0, 200 } }, - // Malefic - { 3596, { 150, 0, 0, 0, 0, 0 } }, - // Malefic II - { 3598, { 170, 0, 0, 0, 0, 0 } }, - // Combust - { 3599, { 0, 0, 0, 0, 0, 0 } }, - // Helios - { 3600, { 0, 0, 0, 0, 0, 330 } }, - // Aspected Helios - { 3601, { 0, 0, 0, 0, 0, 100 } }, - // Ascend - { 3603, { 0, 0, 0, 0, 0, 0 } }, - // Diurnal Sect - { 3604, { 0, 0, 0, 0, 0, 0 } }, - // Nocturnal Sect - { 3605, { 0, 0, 0, 0, 0, 0 } }, - // Lightspeed - { 3606, { 0, 0, 0, 0, 0, 0 } }, - // Combust II - { 3608, { 0, 0, 0, 0, 0, 0 } }, - // Benefic II - { 3610, { 0, 0, 0, 0, 0, 700 } }, - // Synastry - { 3612, { 0, 0, 0, 0, 0, 0 } }, - // Collective Unconscious - { 3613, { 0, 0, 0, 0, 0, 50 } }, - // Essential Dignity - { 3614, { 0, 0, 0, 0, 0, 400 } }, - // Gravity - { 3615, { 130, 0, 0, 0, 0, 0 } }, - // Hard Slash - { 3617, { 200, 0, 0, 0, 0, 0 } }, - // Unleash - { 3621, { 150, 0, 0, 0, 0, 0 } }, - // Syphon Strike - { 3623, { 100, 300, 0, 0, 0, 0 } }, - // Unmend - { 3624, { 150, 0, 0, 0, 0, 0 } }, - // Blood Weapon - { 3625, { 0, 0, 0, 0, 0, 0 } }, - // Grit - { 3629, { 0, 0, 0, 0, 0, 0 } }, - // Souleater - { 3632, { 100, 400, 0, 0, 0, 300 } }, - // Dark Mind - { 3634, { 0, 0, 0, 0, 0, 0 } }, - // Shadow Wall - { 3636, { 0, 0, 0, 0, 0, 0 } }, - // Living Dead - { 3638, { 0, 0, 0, 0, 0, 0 } }, - // Salted Earth - { 3639, { 60, 0, 0, 0, 0, 0 } }, - // Plunge - { 3640, { 200, 0, 0, 0, 0, 0 } }, - // Abyssal Drain - { 3641, { 200, 0, 0, 0, 0, 200 } }, - // Carve and Spit - { 3643, { 450, 0, 0, 0, 0, 0 } }, - // Big Shot - { 4238, { 0, 0, 0, 0, 0, 0 } }, - // Desperado - { 4239, { 0, 0, 0, 0, 0, 0 } }, - // Land Waker - { 4240, { 0, 0, 0, 0, 0, 0 } }, - // Dark Force - { 4241, { 0, 0, 0, 0, 0, 0 } }, - // Dragonsong Dive - { 4242, { 0, 0, 0, 0, 0, 0 } }, - // Chimatsuri - { 4243, { 0, 0, 0, 0, 0, 0 } }, - // Sagittarius Arrow - { 4244, { 0, 0, 0, 0, 0, 0 } }, - // Satellite Beam - { 4245, { 0, 0, 0, 0, 0, 0 } }, - // Teraflare - { 4246, { 0, 0, 0, 0, 0, 0 } }, - // Angel Feathers - { 4247, { 0, 0, 0, 0, 0, 0 } }, - // Astral Stasis - { 4248, { 0, 0, 0, 0, 0, 0 } }, - // Form Shift - { 4262, { 0, 0, 0, 0, 0, 0 } }, - // Cannonfire - { 4271, { 0, 0, 0, 0, 0, 0 } }, - // the Balance - { 4401, { 0, 0, 0, 0, 0, 0 } }, - // the Arrow - { 4402, { 0, 0, 0, 0, 0, 0 } }, - // the Spear - { 4403, { 0, 0, 0, 0, 0, 0 } }, - // the Bole - { 4404, { 0, 0, 0, 0, 0, 0 } }, - // the Ewer - { 4405, { 0, 0, 0, 0, 0, 0 } }, - // the Spire - { 4406, { 0, 0, 0, 0, 0, 0 } }, - // Raiton - { 4977, { 0, 0, 0, 0, 0, 0 } }, - // Raiton - { 5069, { 0, 0, 0, 0, 0, 0 } }, - // attack - { 5199, { 0, 0, 0, 0, 0, 0 } }, - // attack - { 5846, { 0, 0, 0, 0, 0, 0 } }, - // Stickyloom - { 5874, { 0, 0, 0, 0, 0, 0 } }, - // Void Fire II - { 6274, { 0, 0, 0, 0, 0, 0 } }, - // Total Eclipse - { 7381, { 120, 0, 0, 0, 0, 0 } }, - // Intervention - { 7382, { 0, 0, 0, 0, 0, 0 } }, - // Requiescat - { 7383, { 550, 0, 0, 0, 0, 0 } }, - // Holy Spirit - { 7384, { 350, 0, 0, 0, 0, 0 } }, - // Passage of Arms - { 7385, { 0, 0, 0, 0, 0, 0 } }, - // Onslaught - { 7386, { 100, 0, 0, 0, 0, 0 } }, - // Upheaval - { 7387, { 450, 0, 0, 0, 0, 0 } }, - // Shake It Off - { 7388, { 0, 0, 0, 0, 0, 0 } }, - // Inner Release - { 7389, { 0, 0, 0, 0, 0, 0 } }, - // Delirium - { 7390, { 0, 0, 0, 0, 0, 0 } }, - // Quietus - { 7391, { 210, 0, 0, 0, 0, 0 } }, - // Bloodspiller - { 7392, { 600, 0, 0, 0, 0, 0 } }, - // The Blackest Night - { 7393, { 0, 0, 0, 0, 0, 0 } }, - // Riddle of Earth - { 7394, { 0, 0, 0, 0, 0, 0 } }, - // Riddle of Fire - { 7395, { 0, 0, 0, 0, 0, 0 } }, - // Brotherhood - { 7396, { 0, 0, 0, 0, 0, 0 } }, - // Sonic Thrust - { 7397, { 100, 200, 0, 0, 0, 0 } }, - // Dragon Sight - { 7398, { 0, 0, 0, 0, 0, 0 } }, - // Mirage Dive - { 7399, { 250, 0, 0, 0, 0, 0 } }, - // Nastrond - { 7400, { 400, 0, 0, 0, 0, 0 } }, - // Hellfrog Medium - { 7401, { 400, 0, 0, 0, 0, 0 } }, - // Bhavacakra - { 7402, { 500, 0, 0, 0, 0, 0 } }, - // Ten Chi Jin - { 7403, { 0, 0, 0, 0, 0, 0 } }, - // Pitch Perfect - { 7404, { 100, 0, 0, 0, 0, 0 } }, - // Troubadour - { 7405, { 0, 0, 0, 0, 0, 0 } }, - // Caustic Bite - { 7406, { 150, 0, 0, 0, 0, 0 } }, - // Stormbite - { 7407, { 100, 0, 0, 0, 0, 0 } }, - // Nature's Minne - { 7408, { 0, 0, 0, 0, 0, 0 } }, - // Refulgent Arrow - { 7409, { 340, 0, 0, 0, 0, 0 } }, - // Heat Blast - { 7410, { 200, 0, 0, 0, 0, 0 } }, - // Heated Split Shot - { 7411, { 200, 0, 0, 0, 0, 0 } }, - // Heated Slug Shot - { 7412, { 100, 300, 0, 0, 0, 0 } }, - // Heated Clean Shot - { 7413, { 100, 400, 0, 0, 0, 0 } }, - // Barrel Stabilizer - { 7414, { 0, 0, 0, 0, 0, 0 } }, - // Rook Overdrive - { 7415, { 0, 0, 0, 0, 0, 0 } }, - // Flamethrower - { 7418, { 0, 0, 0, 0, 0, 0 } }, - // Between the Lines - { 7419, { 0, 0, 0, 0, 0, 0 } }, - // Thunder IV - { 7420, { 50, 0, 0, 0, 0, 0 } }, - // Triplecast - { 7421, { 0, 0, 0, 0, 0, 0 } }, - // Foul - { 7422, { 650, 0, 0, 0, 0, 0 } }, - // Aetherpact - { 7423, { 0, 0, 0, 0, 0, 0 } }, - // Bio III - { 7424, { 0, 0, 0, 0, 0, 0 } }, - // Miasma III - { 7425, { 40, 0, 0, 0, 0, 0 } }, - // Ruin IV - { 7426, { 120, 0, 0, 0, 0, 0 } }, - // Summon Bahamut - { 7427, { 0, 0, 0, 0, 0, 0 } }, - // Enkindle Bahamut - { 7429, { 0, 0, 0, 0, 0, 0 } }, - // Thin Air - { 7430, { 0, 0, 0, 0, 0, 0 } }, - // Stone IV - { 7431, { 280, 0, 0, 0, 0, 0 } }, - // Divine Benison - { 7432, { 0, 0, 0, 0, 0, 0 } }, - // Plenary Indulgence - { 7433, { 0, 0, 0, 0, 0, 200 } }, - // Excogitation - { 7434, { 0, 0, 0, 0, 0, 800 } }, - // Broil II - { 7435, { 260, 0, 0, 0, 0, 0 } }, - // Chain Stratagem - { 7436, { 0, 0, 0, 0, 0, 0 } }, - // Aetherpact - { 7437, { 0, 0, 0, 0, 0, 0 } }, - // Earthly Star - { 7439, { 100, 0, 0, 0, 0, 540 } }, - // Malefic III - { 7442, { 210, 0, 0, 0, 0, 0 } }, - // Minor Arcana - { 7443, { 0, 0, 0, 0, 0, 0 } }, - // Lord of Crowns - { 7444, { 0, 0, 0, 0, 0, 0 } }, - // Lady of Crowns - { 7445, { 0, 0, 0, 0, 0, 0 } }, - // Thunder II - { 7447, { 30, 0, 0, 0, 0, 0 } }, - // Sleeve Draw - { 7448, { 0, 0, 0, 0, 0, 0 } }, - // Hakaze - { 7477, { 170, 0, 0, 0, 0, 0 } }, - // Jinpu - { 7478, { 100, 320, 0, 0, 0, 0 } }, - // Shifu - { 7479, { 100, 320, 0, 0, 0, 0 } }, - // Yukikaze - { 7480, { 100, 400, 0, 0, 0, 0 } }, - // Gekko - { 7481, { 100, 470, 0, 0, 0, 0 } }, - // Kasha - { 7482, { 100, 470, 0, 0, 0, 0 } }, - // Fuga - { 7483, { 100, 0, 0, 0, 0, 0 } }, - // Mangetsu - { 7484, { 100, 160, 0, 0, 0, 0 } }, - // Oka - { 7485, { 100, 160, 0, 0, 0, 0 } }, - // Enpi - { 7486, { 100, 0, 0, 0, 0, 0 } }, - // Midare Setsugekka - { 7487, { 800, 0, 0, 0, 0, 0 } }, - // Tenka Goken - { 7488, { 360, 0, 0, 0, 0, 0 } }, - // Higanbana - { 7489, { 250, 0, 0, 0, 0, 0 } }, - // Hissatsu: Shinten - { 7490, { 320, 0, 0, 0, 0, 0 } }, - // Hissatsu: Kyuten - { 7491, { 150, 0, 0, 0, 0, 0 } }, - // Hissatsu: Gyoten - { 7492, { 100, 0, 0, 0, 0, 0 } }, - // Hissatsu: Yaten - { 7493, { 100, 0, 0, 0, 0, 0 } }, - // Hissatsu: Kaiten - { 7494, { 0, 0, 0, 0, 0, 0 } }, - // Hissatsu: Guren - { 7496, { 850, 0, 0, 0, 0, 0 } }, - // Meditate - { 7497, { 0, 0, 0, 0, 0, 0 } }, - // Third Eye - { 7498, { 0, 0, 0, 0, 0, 0 } }, - // Meikyo Shisui - { 7499, { 0, 0, 0, 0, 0, 0 } }, - // Hissatsu: Seigan - { 7501, { 220, 0, 0, 0, 0, 0 } }, - // Merciful Eyes - { 7502, { 0, 0, 0, 0, 0, 200 } }, - // Jolt - { 7503, { 180, 0, 0, 0, 0, 0 } }, - // Riposte - { 7504, { 130, 0, 0, 0, 0, 0 } }, - // Verthunder - { 7505, { 310, 0, 0, 0, 0, 0 } }, - // Corps-a-corps - { 7506, { 130, 0, 0, 0, 0, 0 } }, - // Veraero - { 7507, { 310, 0, 0, 0, 0, 0 } }, - // Scatter - { 7509, { 120, 0, 0, 0, 0, 0 } }, - // Verfire - { 7510, { 270, 0, 0, 0, 0, 0 } }, - // Verstone - { 7511, { 270, 0, 0, 0, 0, 0 } }, - // Zwerchhau - { 7512, { 100, 150, 0, 0, 0, 0 } }, - // Moulinet - { 7513, { 60, 0, 0, 0, 0, 0 } }, - // Vercure - { 7514, { 0, 0, 0, 0, 0, 350 } }, - // Displacement - { 7515, { 0, 0, 0, 0, 0, 0 } }, - // Redoublement - { 7516, { 100, 230, 0, 0, 0, 0 } }, - // Fleche - { 7517, { 420, 0, 0, 0, 0, 0 } }, - // Acceleration - { 7518, { 0, 0, 0, 0, 0, 0 } }, - // Contre Sixte - { 7519, { 350, 0, 0, 0, 0, 0 } }, - // Embolden - { 7520, { 0, 0, 0, 0, 0, 0 } }, - // Manafication - { 7521, { 0, 0, 0, 0, 0, 0 } }, - // Verraise - { 7523, { 0, 0, 0, 0, 0, 0 } }, - // Jolt II - { 7524, { 250, 0, 0, 0, 0, 0 } }, - // Verflare - { 7525, { 600, 0, 0, 0, 0, 0 } }, - // Verholy - { 7526, { 600, 0, 0, 0, 0, 0 } }, - // Enchanted Riposte - { 7527, { 210, 0, 0, 0, 0, 0 } }, - // Enchanted Zwerchhau - { 7528, { 100, 290, 0, 0, 0, 0 } }, - // Enchanted Redoublement - { 7529, { 100, 470, 0, 0, 0, 0 } }, - // Enchanted Moulinet - { 7530, { 200, 0, 0, 0, 0, 0 } }, - // Magitek Cannon - { 7619, { 0, 0, 0, 0, 0, 0 } }, - // Photon Stream - { 7620, { 0, 0, 0, 0, 0, 0 } }, - // Diffractive Magitek Cannon - { 7621, { 0, 0, 0, 0, 0, 0 } }, - // High-powered Magitek Cannon - { 7622, { 0, 0, 0, 0, 0, 0 } }, - // Doom of the Living - { 7861, { 0, 0, 0, 0, 0, 0 } }, - // Vermilion Scourge - { 7862, { 0, 0, 0, 0, 0, 0 } }, - // Iaijutsu - { 7867, { 0, 0, 0, 0, 0, 0 } }, - // Dissolve Union - { 7869, { 0, 0, 0, 0, 0, 0 } }, - // Stellar Detonation - { 8324, { 100, 0, 0, 0, 0, 540 } }, - // Broken Ridge - { 8395, { 0, 0, 0, 0, 0, 0 } }, - // Magitek Pulse - { 8624, { 0, 0, 0, 0, 0, 0 } }, - // Magitek Thunder - { 8625, { 0, 0, 0, 0, 0, 0 } }, - // attack - { 8687, { 0, 0, 0, 0, 0, 0 } }, - // Katon - { 9012, { 0, 0, 0, 0, 0, 0 } }, - // Remove Barrel - { 9015, { 0, 0, 0, 0, 0, 0 } }, - // Tenka Goken - { 9143, { 0, 0, 0, 0, 0, 0 } }, - // Thunderous Force - { 9294, { 0, 0, 0, 0, 0, 0 } }, - // Raiton - { 9301, { 0, 0, 0, 0, 0, 0 } }, - // Raiton - { 9302, { 0, 0, 0, 0, 0, 0 } }, - // Bishop Overdrive - { 9372, { 0, 0, 0, 0, 0, 0 } }, - // Undraw - { 9629, { 0, 0, 0, 0, 0, 0 } }, - // Self-detonate - { 9775, { 0, 0, 0, 0, 0, 0 } }, - // Shatterstone - { 9823, { 0, 0, 0, 0, 0, 0 } }, - // attack - { 9996, { 0, 0, 0, 0, 0, 0 } }, - // Ungarmax - { 10001, { 0, 0, 0, 0, 0, 0 } }, - // Starstorm - { 10894, { 0, 0, 0, 0, 0, 0 } }, - // attack - { 10946, { 0, 0, 0, 0, 0, 0 } }, - // attack - { 10947, { 0, 0, 0, 0, 0, 0 } }, - // Ruin III - { 11191, { 200, 0, 0, 0, 0, 0 } }, - // Physick - { 11192, { 0, 0, 0, 0, 0, 400 } }, - // Starstorm - { 11193, { 3600, 0, 0, 0, 0, 0 } }, - // Snort - { 11383, { 0, 0, 0, 0, 0, 0 } }, - // 4-tonze Weight - { 11384, { 110, 0, 0, 0, 0, 0 } }, - // Water Cannon - { 11385, { 120, 0, 0, 0, 0, 0 } }, - // Song of Torment - { 11386, { 50, 0, 0, 0, 0, 0 } }, - // High Voltage - { 11387, { 90, 0, 0, 0, 0, 0 } }, - // Bad Breath - { 11388, { 0, 0, 0, 0, 0, 0 } }, - // Flying Frenzy - { 11389, { 80, 0, 0, 0, 0, 0 } }, - // Aqua Breath - { 11390, { 90, 0, 0, 0, 0, 0 } }, - // Plaincracker - { 11391, { 130, 0, 0, 0, 0, 0 } }, - // Acorn Bomb - { 11392, { 0, 0, 0, 0, 0, 0 } }, - // Bristle - { 11393, { 0, 0, 0, 0, 0, 0 } }, - // Mind Blast - { 11394, { 100, 0, 0, 0, 0, 0 } }, - // Blood Drain - { 11395, { 20, 0, 0, 0, 0, 0 } }, - // Bomb Toss - { 11396, { 110, 0, 0, 0, 0, 0 } }, - // 1000 Needles - { 11397, { 0, 0, 0, 0, 0, 0 } }, - // Drill Cannons - { 11398, { 120, 0, 0, 0, 0, 0 } }, - // the Look - { 11399, { 130, 0, 0, 0, 0, 0 } }, - // Sharpened Knife - { 11400, { 120, 0, 0, 0, 0, 0 } }, - // Loom - { 11401, { 0, 0, 0, 0, 0, 0 } }, - // Flame Thrower - { 11402, { 130, 0, 0, 0, 0, 0 } }, - // Faze - { 11403, { 0, 0, 0, 0, 0, 0 } }, - // Glower - { 11404, { 130, 0, 0, 0, 0, 0 } }, - // Missile - { 11405, { 0, 0, 0, 0, 0, 0 } }, - // White Wind - { 11406, { 0, 0, 0, 0, 0, 0 } }, - // Final Sting - { 11407, { 1500, 0, 0, 0, 0, 0 } }, - // Self-destruct - { 11408, { 900, 0, 0, 0, 0, 0 } }, - // Transfusion - { 11409, { 0, 0, 0, 0, 0, 0 } }, - // Toad Oil - { 11410, { 0, 0, 0, 0, 0, 0 } }, - // Off-guard - { 11411, { 0, 0, 0, 0, 0, 0 } }, - // Sticky Tongue - { 11412, { 0, 0, 0, 0, 0, 0 } }, - // Tail Screw - { 11413, { 0, 0, 0, 0, 0, 0 } }, - // Level 5 Petrify - { 11414, { 0, 0, 0, 0, 0, 0 } }, - // Moon Flute - { 11415, { 0, 0, 0, 0, 0, 0 } }, - // Doom - { 11416, { 0, 0, 0, 0, 0, 0 } }, - // Mighty Guard - { 11417, { 0, 0, 0, 0, 0, 0 } }, - // Ice Spikes - { 11418, { 0, 0, 0, 0, 0, 0 } }, - // the Ram's Voice - { 11419, { 130, 0, 0, 0, 0, 0 } }, - // the Dragon's Voice - { 11420, { 110, 0, 0, 0, 0, 0 } }, - // Peculiar Light - { 11421, { 0, 0, 0, 0, 0, 0 } }, - // Ink Jet - { 11422, { 120, 0, 0, 0, 0, 0 } }, - // Flying Sardine - { 11423, { 10, 0, 0, 0, 0, 0 } }, - // Diamondback - { 11424, { 0, 0, 0, 0, 0, 0 } }, - // Fire Angon - { 11425, { 100, 0, 0, 0, 0, 0 } }, - // Feather Rain - { 11426, { 180, 0, 0, 0, 0, 0 } }, - // Eruption - { 11427, { 220, 0, 0, 0, 0, 0 } }, - // Mountain Buster - { 11428, { 310, 0, 0, 0, 0, 0 } }, - // Shock Strike - { 11429, { 310, 0, 0, 0, 0, 0 } }, - // Glass Dance - { 11430, { 290, 0, 0, 0, 0, 0 } }, - // Veil of the Whorl - { 11431, { 0, 0, 0, 0, 0, 0 } }, - // Tri-shackle - { 11482, { 30, 0, 0, 0, 0, 0 } }, - // attack - { 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, 0 } }, - // Thunderous Force - { 14587, { 0, 0, 0, 0, 0, 0 } }, - // Kyokufu - { 14840, { 180, 0, 0, 0, 0, 0 } }, - // Ajisai - { 14841, { 100, 0, 0, 0, 0, 0 } }, - // Hissatsu: Gyoten - { 14842, { 100, 0, 0, 0, 0, 0 } }, - // 冥界恐叫打 - { 14843, { 0, 0, 0, 0, 0, 0 } }, - // Second Wind - { 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 } }, + { 166, { 0, 0, 0, 0, 0, 0, 10 } }, // 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 } }, + { 167, { 150, 0, 0, 0, 0, 0, 5 } }, + // Miasma + { 168, { 20, 0, 0, 0, 0, 0, 0 } }, + // Summon II + { 170, { 0, 0, 0, 0, 0, 0, 0 } }, // Ruin II - { 17870, { 0, 0, 0, 0, 0, 0 } }, + { 172, { 160, 0, 0, 0, 0, 0, 0 } }, + // Resurrection + { 173, { 0, 0, 0, 0, 0, 0, 0 } }, + // Bane + { 174, { 0, 0, 0, 0, 0, 0, 0 } }, + // Bio II + { 178, { 0, 0, 0, 0, 0, 0, 0 } }, + // Summon III + { 180, { 0, 0, 0, 0, 0, 0, 0 } }, + // Fester + { 181, { 100, 0, 0, 0, 0, 0, 0 } }, + // Enkindle + { 184, { 0, 0, 0, 0, 0, 0, 0 } }, + // Adloquium + { 185, { 0, 0, 0, 0, 0, 300, 0 } }, + // Succor + { 186, { 0, 0, 0, 0, 0, 180, 0 } }, + // Sacred Soil + { 188, { 0, 0, 0, 0, 0, 100, 0 } }, + // Lustrate + { 189, { 0, 0, 0, 0, 0, 600, 0 } }, + // Physick + { 190, { 0, 0, 0, 0, 0, 400, 0 } }, + // Shield Wall + { 197, { 0, 0, 0, 0, 0, 0, 0 } }, + // Stronghold + { 198, { 0, 0, 0, 0, 0, 0, 0 } }, + // Last Bastion + { 199, { 0, 0, 0, 0, 0, 0, 0 } }, + // Braver + { 200, { 2400, 0, 0, 0, 0, 0, 0 } }, + // Bladedance + { 201, { 5250, 0, 0, 0, 0, 0, 0 } }, + // Final Heaven + { 202, { 9000, 0, 0, 0, 0, 0, 0 } }, + // Skyshard + { 203, { 1650, 0, 0, 0, 0, 0, 0 } }, + // Starstorm + { 204, { 3600, 0, 0, 0, 0, 0, 0 } }, + // Meteor + { 205, { 6150, 0, 0, 0, 0, 0, 0 } }, + // Healing Wind + { 206, { 0, 0, 0, 0, 0, 0, 0 } }, + // Breath of the Earth + { 207, { 0, 0, 0, 0, 0, 0, 0 } }, + // Pulse of Life + { 208, { 0, 0, 0, 0, 0, 0, 0 } }, + // Magitek Cannon + { 1128, { 0, 0, 0, 0, 0, 0, 0 } }, + // Photon Stream + { 1129, { 0, 0, 0, 0, 0, 0, 0 } }, + // attack + { 1533, { 0, 0, 0, 0, 0, 0, 0 } }, + // Spinning Edge + { 2240, { 220, 0, 0, 0, 0, 0, 0 } }, + // Shade Shift + { 2241, { 0, 0, 0, 0, 0, 0, 0 } }, + // Gust Slash + { 2242, { 100, 330, 0, 0, 0, 0, 0 } }, + // Hide + { 2245, { 0, 0, 0, 0, 0, 0, 0 } }, + // Assassinate + { 2246, { 200, 0, 0, 0, 0, 0, 0 } }, + // Throwing Dagger + { 2247, { 120, 0, 0, 0, 0, 0, 0 } }, + // Mug + { 2248, { 150, 0, 0, 0, 0, 0, 0 } }, + // Death Blossom + { 2254, { 120, 0, 0, 0, 0, 0, 0 } }, + // Aeolian Edge + { 2255, { 100, 420, 0, 0, 160, 0, 0 } }, + // Shadow Fang + { 2257, { 200, 0, 0, 0, 0, 0, 0 } }, + // Trick Attack + { 2258, { 350, 0, 0, 0, 500, 0, 0 } }, + // Ten + { 2259, { 0, 0, 0, 0, 0, 0, 0 } }, + // Ninjutsu + { 2260, { 0, 0, 0, 0, 0, 0, 0 } }, + // Chi + { 2261, { 0, 0, 0, 0, 0, 0, 0 } }, + // Shukuchi + { 2262, { 0, 0, 0, 0, 0, 0, 0 } }, + // Jin + { 2263, { 0, 0, 0, 0, 0, 0, 0 } }, + // Kassatsu + { 2264, { 0, 0, 0, 0, 0, 0, 0 } }, + // Fuma Shuriken + { 2265, { 500, 0, 0, 0, 0, 0, 0 } }, + // Katon + { 2266, { 500, 0, 0, 0, 0, 0, 0 } }, + // Raiton + { 2267, { 800, 0, 0, 0, 0, 0, 0 } }, + // Hyoton + { 2268, { 400, 0, 0, 0, 0, 0, 0 } }, + // Huton + { 2269, { 0, 0, 0, 0, 0, 0, 0 } }, + // Doton + { 2270, { 100, 0, 0, 0, 0, 0, 0 } }, + // Suiton + { 2271, { 600, 0, 0, 0, 0, 0, 0 } }, + // Rabbit Medium + { 2272, { 0, 0, 0, 0, 0, 0, 0 } }, + // Rook Autoturret + { 2864, { 80, 0, 0, 0, 0, 0, 0 } }, + // Split Shot + { 2866, { 180, 0, 0, 0, 0, 0, 0 } }, + // Slug Shot + { 2868, { 100, 260, 0, 0, 0, 0, 0 } }, + // Spread Shot + { 2870, { 180, 0, 0, 0, 0, 0, 0 } }, + // Hot Shot + { 2872, { 300, 0, 0, 0, 0, 0, 0 } }, + // Clean Shot + { 2873, { 100, 340, 0, 0, 0, 0, 0 } }, + // Gauss Round + { 2874, { 150, 0, 0, 0, 0, 0, 0 } }, + // Reassemble + { 2876, { 0, 0, 0, 0, 0, 0, 0 } }, + // Wildfire + { 2878, { 0, 0, 0, 0, 0, 0, 0 } }, + // Ricochet + { 2890, { 150, 0, 0, 0, 0, 0, 0 } }, + // Raiton + { 3203, { 0, 0, 0, 0, 0, 0, 0 } }, + // Raiton + { 3204, { 0, 0, 0, 0, 0, 0, 0 } }, + // Kanashibari + { 3207, { 0, 0, 0, 0, 0, 0, 0 } }, + // Goring Blade + { 3538, { 100, 390, 0, 0, 0, 0, 0 } }, + // Royal Authority + { 3539, { 100, 550, 0, 0, 0, 0, 0 } }, + // Divine Veil + { 3540, { 0, 0, 0, 0, 0, 0, 0 } }, + // Clemency + { 3541, { 0, 0, 0, 0, 0, 1200, 0 } }, + // Sheltron + { 3542, { 0, 0, 0, 0, 0, 0, 0 } }, + // Tornado Kick + { 3543, { 430, 0, 0, 0, 0, 0, 0 } }, + // Elixir Field + { 3545, { 200, 0, 0, 0, 0, 0, 0 } }, + // Meditation + { 3546, { 0, 0, 0, 0, 0, 0, 0 } }, + // the Forbidden Chakra + { 3547, { 370, 0, 0, 0, 0, 0, 0 } }, + // Fell Cleave + { 3549, { 590, 0, 0, 0, 0, 0, 0 } }, + // Decimate + { 3550, { 250, 0, 0, 0, 0, 0, 0 } }, + // Raw Intuition + { 3551, { 0, 0, 0, 0, 0, 0, 0 } }, + // Equilibrium + { 3552, { 0, 0, 0, 0, 0, 1200, 0 } }, + // Blood of the Dragon + { 3553, { 0, 0, 0, 0, 0, 0, 0 } }, + // Fang and Claw + { 3554, { 320, 0, 360, 0, 0, 0, 0 } }, + // Geirskogul + { 3555, { 300, 0, 0, 0, 0, 0, 0 } }, + // Wheeling Thrust + { 3556, { 320, 0, 0, 0, 360, 0, 0 } }, + // Battle Litany + { 3557, { 0, 0, 0, 0, 0, 0, 0 } }, + // Empyreal Arrow + { 3558, { 230, 0, 0, 0, 0, 0, 0 } }, + // the Wanderer's Minuet + { 3559, { 100, 0, 0, 0, 0, 0, 0 } }, + // Iron Jaws + { 3560, { 100, 0, 0, 0, 0, 0, 0 } }, + // the Warden's Paean + { 3561, { 0, 0, 0, 0, 0, 0, 0 } }, + // Sidewinder + { 3562, { 100, 0, 0, 0, 0, 0, 0 } }, + // Armor Crush + { 3563, { 100, 400, 160, 0, 0, 0, 0 } }, + // Dream Within a Dream + { 3566, { 200, 0, 0, 0, 0, 0, 0 } }, + // Stone III + { 3568, { 240, 0, 0, 0, 0, 0, 0 } }, + // Asylum + { 3569, { 0, 0, 0, 0, 0, 100, 0 } }, + // Tetragrammaton + { 3570, { 0, 0, 0, 0, 0, 700, 0 } }, + // Assize + { 3571, { 400, 0, 0, 0, 0, 400, 5 } }, + // Ley Lines + { 3573, { 0, 0, 0, 0, 0, 0, 0 } }, + // Sharpcast + { 3574, { 0, 0, 0, 0, 0, 0, 0 } }, + // Enochian + { 3575, { 0, 0, 0, 0, 0, 0, 0 } }, + // Blizzard IV + { 3576, { 300, 0, 0, 0, 0, 0, 0 } }, + // Fire IV + { 3577, { 300, 0, 0, 0, 0, 0, 0 } }, + // Painflare + { 3578, { 130, 0, 0, 0, 0, 0, 0 } }, + // Ruin III + { 3579, { 200, 0, 0, 0, 0, 0, 0 } }, + // Tri-disaster + { 3580, { 300, 0, 0, 0, 0, 0, 0 } }, + // Dreadwyrm Trance + { 3581, { 0, 0, 0, 0, 0, 0, 0 } }, + // Deathflare + { 3582, { 400, 0, 0, 0, 0, 0, 0 } }, + // Indomitability + { 3583, { 0, 0, 0, 0, 0, 400, 0 } }, + // Broil + { 3584, { 240, 0, 0, 0, 0, 0, 0 } }, + // Deployment Tactics + { 3585, { 0, 0, 0, 0, 0, 0, 0 } }, + // Emergency Tactics + { 3586, { 0, 0, 0, 0, 0, 0, 0 } }, + // Dissipation + { 3587, { 0, 0, 0, 0, 0, 0, 0 } }, + // Draw + { 3590, { 0, 0, 0, 0, 0, 0, 0 } }, + // Redraw + { 3593, { 0, 0, 0, 0, 0, 0, 0 } }, + // Benefic + { 3594, { 0, 0, 0, 0, 0, 400, 0 } }, + // Aspected Benefic + { 3595, { 0, 0, 0, 0, 0, 200, 0 } }, + // Malefic + { 3596, { 150, 0, 0, 0, 0, 0, 0 } }, + // Malefic II + { 3598, { 170, 0, 0, 0, 0, 0, 0 } }, + // Combust + { 3599, { 0, 0, 0, 0, 0, 0, 0 } }, + // Helios + { 3600, { 0, 0, 0, 0, 0, 330, 0 } }, + // Aspected Helios + { 3601, { 0, 0, 0, 0, 0, 200, 0 } }, + // Ascend + { 3603, { 0, 0, 0, 0, 0, 0, 0 } }, + // Diurnal Sect + { 3604, { 0, 0, 0, 0, 0, 0, 0 } }, + // Nocturnal Sect + { 3605, { 0, 0, 0, 0, 0, 0, 0 } }, + // Lightspeed + { 3606, { 0, 0, 0, 0, 0, 0, 0 } }, + // Combust II + { 3608, { 0, 0, 0, 0, 0, 0, 0 } }, + // Benefic II + { 3610, { 0, 0, 0, 0, 0, 700, 0 } }, + // Synastry + { 3612, { 0, 0, 0, 0, 0, 0, 0 } }, + // Collective Unconscious + { 3613, { 0, 0, 0, 0, 0, 100, 0 } }, + // Essential Dignity + { 3614, { 0, 0, 0, 0, 0, 400, 0 } }, + // Gravity + { 3615, { 140, 0, 0, 0, 0, 0, 0 } }, + // Hard Slash + { 3617, { 200, 0, 0, 0, 0, 0, 0 } }, + // Unleash + { 3621, { 150, 0, 0, 0, 0, 0, 0 } }, + // Syphon Strike + { 3623, { 100, 300, 0, 0, 0, 0, 6 } }, + // Unmend + { 3624, { 150, 0, 0, 0, 0, 0, 0 } }, + // Blood Weapon + { 3625, { 0, 0, 0, 0, 0, 0, 0 } }, + // Grit + { 3629, { 0, 0, 0, 0, 0, 0, 0 } }, + // Souleater + { 3632, { 100, 400, 0, 0, 0, 300, 0 } }, + // Dark Mind + { 3634, { 0, 0, 0, 0, 0, 0, 0 } }, + // Shadow Wall + { 3636, { 0, 0, 0, 0, 0, 0, 0 } }, + // Living Dead + { 3638, { 0, 0, 0, 0, 0, 0, 0 } }, + // Salted Earth + { 3639, { 60, 0, 0, 0, 0, 0, 0 } }, + // Plunge + { 3640, { 200, 0, 0, 0, 0, 0, 0 } }, + // Abyssal Drain + { 3641, { 200, 0, 0, 0, 0, 200, 0 } }, + // Carve and Spit + { 3643, { 450, 0, 0, 0, 0, 0, 6 } }, + // Big Shot + { 4238, { 0, 0, 0, 0, 0, 0, 0 } }, + // Desperado + { 4239, { 0, 0, 0, 0, 0, 0, 0 } }, + // Land Waker + { 4240, { 0, 0, 0, 0, 0, 0, 0 } }, + // Dark Force + { 4241, { 0, 0, 0, 0, 0, 0, 0 } }, + // Dragonsong Dive + { 4242, { 0, 0, 0, 0, 0, 0, 0 } }, + // Chimatsuri + { 4243, { 0, 0, 0, 0, 0, 0, 0 } }, + // Sagittarius Arrow + { 4244, { 0, 0, 0, 0, 0, 0, 0 } }, + // Satellite Beam + { 4245, { 0, 0, 0, 0, 0, 0, 0 } }, + // Teraflare + { 4246, { 0, 0, 0, 0, 0, 0, 0 } }, + // Angel Feathers + { 4247, { 0, 0, 0, 0, 0, 0, 0 } }, + // Astral Stasis + { 4248, { 0, 0, 0, 0, 0, 0, 0 } }, + // Form Shift + { 4262, { 0, 0, 0, 0, 0, 0, 0 } }, + // Cannonfire + { 4271, { 0, 0, 0, 0, 0, 0, 0 } }, + // the Balance + { 4401, { 0, 0, 0, 0, 0, 0, 0 } }, + // the Arrow + { 4402, { 0, 0, 0, 0, 0, 0, 0 } }, + // the Spear + { 4403, { 0, 0, 0, 0, 0, 0, 0 } }, + // the Bole + { 4404, { 0, 0, 0, 0, 0, 0, 0 } }, + // the Ewer + { 4405, { 0, 0, 0, 0, 0, 0, 0 } }, + // the Spire + { 4406, { 0, 0, 0, 0, 0, 0, 0 } }, + // Raiton + { 4977, { 0, 0, 0, 0, 0, 0, 0 } }, + // Raiton + { 5069, { 0, 0, 0, 0, 0, 0, 0 } }, + // attack + { 5199, { 0, 0, 0, 0, 0, 0, 0 } }, + // attack + { 5846, { 0, 0, 0, 0, 0, 0, 0 } }, + // Stickyloom + { 5874, { 0, 0, 0, 0, 0, 0, 0 } }, + // Void Fire II + { 6274, { 0, 0, 0, 0, 0, 0, 0 } }, + // Total Eclipse + { 7381, { 120, 0, 0, 0, 0, 0, 0 } }, + // Intervention + { 7382, { 0, 0, 0, 0, 0, 0, 0 } }, + // Requiescat + { 7383, { 150, 0, 0, 0, 0, 0, 0 } }, + // Holy Spirit + { 7384, { 350, 0, 0, 0, 0, 0, 0 } }, + // Passage of Arms + { 7385, { 0, 0, 0, 0, 0, 0, 0 } }, + // Onslaught + { 7386, { 100, 0, 0, 0, 0, 0, 0 } }, + // Upheaval + { 7387, { 450, 0, 0, 0, 0, 0, 0 } }, + // Shake It Off + { 7388, { 0, 0, 0, 0, 0, 0, 0 } }, + // Inner Release + { 7389, { 0, 0, 0, 0, 0, 0, 0 } }, + // Delirium + { 7390, { 0, 0, 0, 0, 0, 0, 0 } }, + // Quietus + { 7391, { 210, 0, 0, 0, 0, 0, 6 } }, + // Bloodspiller + { 7392, { 600, 0, 0, 0, 0, 0, 0 } }, + // The Blackest Night + { 7393, { 0, 0, 0, 0, 0, 0, 0 } }, + // Riddle of Earth + { 7394, { 0, 0, 0, 0, 0, 0, 0 } }, + // Riddle of Fire + { 7395, { 0, 0, 0, 0, 0, 0, 0 } }, + // Brotherhood + { 7396, { 0, 0, 0, 0, 0, 0, 0 } }, + // Sonic Thrust + { 7397, { 100, 200, 0, 0, 0, 0, 0 } }, + // Dragon Sight + { 7398, { 0, 0, 0, 0, 0, 0, 0 } }, + // Mirage Dive + { 7399, { 300, 0, 0, 0, 0, 0, 0 } }, + // Nastrond + { 7400, { 400, 0, 0, 0, 0, 0, 0 } }, + // Hellfrog Medium + { 7401, { 200, 0, 0, 0, 0, 0, 0 } }, + // Bhavacakra + { 7402, { 300, 0, 0, 0, 0, 0, 0 } }, + // Ten Chi Jin + { 7403, { 0, 0, 0, 0, 0, 0, 0 } }, + // Pitch Perfect + { 7404, { 100, 0, 0, 0, 0, 0, 0 } }, + // Troubadour + { 7405, { 0, 0, 0, 0, 0, 0, 0 } }, + // Caustic Bite + { 7406, { 150, 0, 0, 0, 0, 0, 0 } }, + // Stormbite + { 7407, { 100, 0, 0, 0, 0, 0, 0 } }, + // Nature's Minne + { 7408, { 0, 0, 0, 0, 0, 0, 0 } }, + // Refulgent Arrow + { 7409, { 330, 0, 0, 0, 0, 0, 0 } }, + // Heat Blast + { 7410, { 220, 0, 0, 0, 0, 0, 0 } }, + // Heated Split Shot + { 7411, { 220, 0, 0, 0, 0, 0, 0 } }, + // Heated Slug Shot + { 7412, { 100, 330, 0, 0, 0, 0, 0 } }, + // Heated Clean Shot + { 7413, { 100, 440, 0, 0, 0, 0, 0 } }, + // Barrel Stabilizer + { 7414, { 0, 0, 0, 0, 0, 0, 0 } }, + // Rook Overdrive + { 7415, { 0, 0, 0, 0, 0, 0, 0 } }, + // Flamethrower + { 7418, { 0, 0, 0, 0, 0, 0, 0 } }, + // Between the Lines + { 7419, { 0, 0, 0, 0, 0, 0, 0 } }, + // Thunder IV + { 7420, { 50, 0, 0, 0, 0, 0, 0 } }, + // Triplecast + { 7421, { 0, 0, 0, 0, 0, 0, 0 } }, + // Foul + { 7422, { 650, 0, 0, 0, 0, 0, 0 } }, + // Aetherpact + { 7423, { 0, 0, 0, 0, 0, 0, 0 } }, + // Bio III + { 7424, { 0, 0, 0, 0, 0, 0, 0 } }, + // Miasma III + { 7425, { 50, 0, 0, 0, 0, 0, 0 } }, + // Ruin IV + { 7426, { 300, 0, 0, 0, 0, 0, 0 } }, + // Summon Bahamut + { 7427, { 0, 0, 0, 0, 0, 0, 0 } }, + // Enkindle Bahamut + { 7429, { 650, 0, 0, 0, 0, 0, 0 } }, + // Thin Air + { 7430, { 0, 0, 0, 0, 0, 0, 0 } }, + // Stone IV + { 7431, { 280, 0, 0, 0, 0, 0, 0 } }, + // Divine Benison + { 7432, { 0, 0, 0, 0, 0, 0, 0 } }, + // Plenary Indulgence + { 7433, { 0, 0, 0, 0, 0, 200, 0 } }, + // Excogitation + { 7434, { 0, 0, 0, 0, 0, 800, 0 } }, + // Broil II + { 7435, { 260, 0, 0, 0, 0, 0, 0 } }, + // Chain Stratagem + { 7436, { 0, 0, 0, 0, 0, 0, 0 } }, + // Aetherpact + { 7437, { 0, 0, 0, 0, 0, 0, 0 } }, + // Earthly Star + { 7439, { 100, 0, 0, 0, 0, 540, 0 } }, + // Malefic III + { 7442, { 210, 0, 0, 0, 0, 0, 0 } }, + // Minor Arcana + { 7443, { 0, 0, 0, 0, 0, 0, 0 } }, + // Lord of Crowns + { 7444, { 0, 0, 0, 0, 0, 0, 0 } }, + // Lady of Crowns + { 7445, { 0, 0, 0, 0, 0, 0, 0 } }, + // Thunder II + { 7447, { 30, 0, 0, 0, 0, 0, 0 } }, + // Sleeve Draw + { 7448, { 0, 0, 0, 0, 0, 0, 0 } }, + // Hakaze + { 7477, { 200, 0, 0, 0, 0, 0, 0 } }, + // Jinpu + { 7478, { 100, 320, 0, 0, 0, 0, 0 } }, + // Shifu + { 7479, { 100, 320, 0, 0, 0, 0, 0 } }, + // Yukikaze + { 7480, { 100, 360, 0, 0, 0, 0, 0 } }, + // Gekko + { 7481, { 100, 480, 0, 0, 0, 0, 0 } }, + // Kasha + { 7482, { 100, 480, 0, 0, 0, 0, 0 } }, + // Fuga + { 7483, { 100, 0, 0, 0, 0, 0, 0 } }, + // Mangetsu + { 7484, { 100, 160, 0, 0, 0, 0, 0 } }, + // Oka + { 7485, { 100, 160, 0, 0, 0, 0, 0 } }, + // Enpi + { 7486, { 100, 0, 0, 0, 0, 0, 0 } }, + // Midare Setsugekka + { 7487, { 800, 0, 0, 0, 0, 0, 0 } }, + // Tenka Goken + { 7488, { 360, 0, 0, 0, 0, 0, 0 } }, + // Higanbana + { 7489, { 250, 0, 0, 0, 0, 0, 0 } }, + // Hissatsu: Shinten + { 7490, { 320, 0, 0, 0, 0, 0, 0 } }, + // Hissatsu: Kyuten + { 7491, { 150, 0, 0, 0, 0, 0, 0 } }, + // Hissatsu: Gyoten + { 7492, { 100, 0, 0, 0, 0, 0, 0 } }, + // Hissatsu: Yaten + { 7493, { 100, 0, 0, 0, 0, 0, 0 } }, + // Hissatsu: Kaiten + { 7494, { 0, 0, 0, 0, 0, 0, 0 } }, + // Hagakure + { 7495, { 0, 0, 0, 0, 0, 0, 0 } }, + // Hissatsu: Guren + { 7496, { 850, 0, 0, 0, 0, 0, 0 } }, + // Meditate + { 7497, { 0, 0, 0, 0, 0, 0, 0 } }, + // Third Eye + { 7498, { 0, 0, 0, 0, 0, 0, 0 } }, + // Meikyo Shisui + { 7499, { 0, 0, 0, 0, 0, 0, 0 } }, + // Hissatsu: Seigan + { 7501, { 220, 0, 0, 0, 0, 0, 0 } }, + // Merciful Eyes + { 7502, { 0, 0, 0, 0, 0, 200, 0 } }, + // Jolt + { 7503, { 180, 0, 0, 0, 0, 0, 0 } }, + // Riposte + { 7504, { 130, 0, 0, 0, 0, 0, 0 } }, + // Verthunder + { 7505, { 0, 0, 0, 0, 0, 0, 0 } }, + // Corps-a-corps + { 7506, { 130, 0, 0, 0, 0, 0, 0 } }, + // Veraero + { 7507, { 0, 0, 0, 0, 0, 0, 0 } }, + // Scatter + { 7509, { 120, 0, 0, 0, 0, 0, 0 } }, + // Verfire + { 7510, { 0, 0, 0, 0, 0, 0, 0 } }, + // Verstone + { 7511, { 0, 0, 0, 0, 0, 0, 0 } }, + // Zwerchhau + { 7512, { 100, 150, 0, 0, 0, 0, 0 } }, + // Moulinet + { 7513, { 60, 0, 0, 0, 0, 0, 0 } }, + // Vercure + { 7514, { 0, 0, 0, 0, 0, 350, 0 } }, + // Displacement + { 7515, { 0, 0, 0, 0, 0, 0, 0 } }, + // Redoublement + { 7516, { 100, 230, 0, 0, 0, 0, 0 } }, + // Fleche + { 7517, { 420, 0, 0, 0, 0, 0, 0 } }, + // Acceleration + { 7518, { 0, 0, 0, 0, 0, 0, 0 } }, + // Contre Sixte + { 7519, { 380, 0, 0, 0, 0, 0, 0 } }, + // Embolden + { 7520, { 0, 0, 0, 0, 0, 0, 0 } }, + // Manafication + { 7521, { 0, 0, 0, 0, 0, 0, 0 } }, + // Verraise + { 7523, { 0, 0, 0, 0, 0, 0, 0 } }, + // Jolt II + { 7524, { 280, 0, 0, 0, 0, 0, 0 } }, + // Verflare + { 7525, { 600, 0, 0, 0, 0, 0, 0 } }, + // Verholy + { 7526, { 600, 0, 0, 0, 0, 0, 0 } }, + // Enchanted Riposte + { 7527, { 210, 0, 0, 0, 0, 0, 0 } }, + // Enchanted Zwerchhau + { 7528, { 100, 290, 0, 0, 0, 0, 0 } }, + // Enchanted Redoublement + { 7529, { 100, 470, 0, 0, 0, 0, 0 } }, + // Enchanted Moulinet + { 7530, { 200, 0, 0, 0, 0, 0, 0 } }, + // Magitek Cannon + { 7619, { 0, 0, 0, 0, 0, 0, 0 } }, + // Photon Stream + { 7620, { 0, 0, 0, 0, 0, 0, 0 } }, + // Diffractive Magitek Cannon + { 7621, { 0, 0, 0, 0, 0, 0, 0 } }, + // High-powered Magitek Cannon + { 7622, { 0, 0, 0, 0, 0, 0, 0 } }, + // Doom of the Living + { 7861, { 0, 0, 0, 0, 0, 0, 0 } }, + // Vermilion Scourge + { 7862, { 0, 0, 0, 0, 0, 0, 0 } }, + // Iaijutsu + { 7867, { 0, 0, 0, 0, 0, 0, 0 } }, + // Dissolve Union + { 7869, { 0, 0, 0, 0, 0, 0, 0 } }, + // Stellar Detonation + { 8324, { 100, 0, 0, 0, 0, 540, 0 } }, + // Broken Ridge + { 8395, { 0, 0, 0, 0, 0, 0, 0 } }, + // Magitek Pulse + { 8624, { 0, 0, 0, 0, 0, 0, 0 } }, + // Magitek Thunder + { 8625, { 0, 0, 0, 0, 0, 0, 0 } }, + // attack + { 8687, { 0, 0, 0, 0, 0, 0, 0 } }, + // Katon + { 9012, { 0, 0, 0, 0, 0, 0, 0 } }, + // Remove Barrel + { 9015, { 0, 0, 0, 0, 0, 0, 0 } }, + // Tenka Goken + { 9143, { 0, 0, 0, 0, 0, 0, 0 } }, + // Thunderous Force + { 9294, { 0, 0, 0, 0, 0, 0, 0 } }, + // Raiton + { 9301, { 0, 0, 0, 0, 0, 0, 0 } }, + // Raiton + { 9302, { 0, 0, 0, 0, 0, 0, 0 } }, + // Bishop Overdrive + { 9372, { 0, 0, 0, 0, 0, 0, 0 } }, + // Undraw + { 9629, { 0, 0, 0, 0, 0, 0, 0 } }, + // Self-detonate + { 9775, { 0, 0, 0, 0, 0, 0, 0 } }, + // Shatterstone + { 9823, { 0, 0, 0, 0, 0, 0, 0 } }, + // attack + { 9996, { 0, 0, 0, 0, 0, 0, 0 } }, + // Ungarmax + { 10001, { 0, 0, 0, 0, 0, 0, 0 } }, + // Starstorm + { 10894, { 0, 0, 0, 0, 0, 0, 0 } }, + // attack + { 10946, { 0, 0, 0, 0, 0, 0, 0 } }, + // attack + { 10947, { 0, 0, 0, 0, 0, 0, 0 } }, + // Ruin III + { 11191, { 200, 0, 0, 0, 0, 0, 0 } }, + // Physick + { 11192, { 0, 0, 0, 0, 0, 400, 0 } }, + // Starstorm + { 11193, { 3600, 0, 0, 0, 0, 0, 0 } }, + // Snort + { 11383, { 0, 0, 0, 0, 0, 0, 0 } }, + // 4-tonze Weight + { 11384, { 200, 0, 0, 0, 0, 0, 0 } }, + // Water Cannon + { 11385, { 200, 0, 0, 0, 0, 0, 0 } }, + // Song of Torment + { 11386, { 50, 0, 0, 0, 0, 0, 0 } }, + // High Voltage + { 11387, { 180, 0, 0, 0, 0, 0, 0 } }, + // Bad Breath + { 11388, { 0, 0, 0, 0, 0, 0, 0 } }, + // Flying Frenzy + { 11389, { 150, 0, 0, 0, 0, 0, 0 } }, + // Aqua Breath + { 11390, { 140, 0, 0, 0, 0, 0, 0 } }, + // Plaincracker + { 11391, { 220, 0, 0, 0, 0, 0, 0 } }, + // Acorn Bomb + { 11392, { 0, 0, 0, 0, 0, 0, 0 } }, + // Bristle + { 11393, { 0, 0, 0, 0, 0, 0, 0 } }, + // Mind Blast + { 11394, { 200, 0, 0, 0, 0, 0, 0 } }, + // Blood Drain + { 11395, { 50, 0, 0, 0, 0, 0, 0 } }, + // Bomb Toss + { 11396, { 200, 0, 0, 0, 0, 0, 0 } }, + // 1000 Needles + { 11397, { 0, 0, 0, 0, 0, 0, 0 } }, + // Drill Cannons + { 11398, { 200, 0, 0, 0, 0, 0, 0 } }, + // the Look + { 11399, { 220, 0, 0, 0, 0, 0, 0 } }, + // Sharpened Knife + { 11400, { 220, 0, 0, 0, 0, 0, 0 } }, + // Loom + { 11401, { 0, 0, 0, 0, 0, 0, 0 } }, + // Flame Thrower + { 11402, { 220, 0, 0, 0, 0, 0, 0 } }, + // Faze + { 11403, { 0, 0, 0, 0, 0, 0, 0 } }, + // Glower + { 11404, { 220, 0, 0, 0, 0, 0, 0 } }, + // Missile + { 11405, { 0, 0, 0, 0, 0, 0, 0 } }, + // White Wind + { 11406, { 0, 0, 0, 0, 0, 0, 0 } }, + // Final Sting + { 11407, { 2000, 0, 0, 0, 0, 0, 0 } }, + // Self-destruct + { 11408, { 1500, 0, 0, 0, 0, 0, 0 } }, + // Transfusion + { 11409, { 0, 0, 0, 0, 0, 0, 0 } }, + // Toad Oil + { 11410, { 0, 0, 0, 0, 0, 0, 0 } }, + // Off-guard + { 11411, { 0, 0, 0, 0, 0, 0, 0 } }, + // Sticky Tongue + { 11412, { 0, 0, 0, 0, 0, 0, 0 } }, + // Tail Screw + { 11413, { 0, 0, 0, 0, 0, 0, 0 } }, + // Level 5 Petrify + { 11414, { 0, 0, 0, 0, 0, 0, 0 } }, + // Moon Flute + { 11415, { 0, 0, 0, 0, 0, 0, 0 } }, + // Doom + { 11416, { 0, 0, 0, 0, 0, 0, 0 } }, + // Mighty Guard + { 11417, { 0, 0, 0, 0, 0, 0, 0 } }, + // Ice Spikes + { 11418, { 0, 0, 0, 0, 0, 0, 0 } }, + // the Ram's Voice + { 11419, { 220, 0, 0, 0, 0, 0, 0 } }, + // the Dragon's Voice + { 11420, { 200, 0, 0, 0, 0, 0, 0 } }, + // Peculiar Light + { 11421, { 0, 0, 0, 0, 0, 0, 0 } }, + // Ink Jet + { 11422, { 200, 0, 0, 0, 0, 0, 0 } }, + // Flying Sardine + { 11423, { 10, 0, 0, 0, 0, 0, 0 } }, + // Diamondback + { 11424, { 0, 0, 0, 0, 0, 0, 0 } }, + // Fire Angon + { 11425, { 200, 0, 0, 0, 0, 0, 0 } }, + // Feather Rain + { 11426, { 220, 0, 0, 0, 0, 0, 0 } }, + // Eruption + { 11427, { 300, 0, 0, 0, 0, 0, 0 } }, + // Mountain Buster + { 11428, { 400, 0, 0, 0, 0, 0, 0 } }, + // Shock Strike + { 11429, { 400, 0, 0, 0, 0, 0, 0 } }, + // Glass Dance + { 11430, { 350, 0, 0, 0, 0, 0, 0 } }, + // Veil of the Whorl + { 11431, { 0, 0, 0, 0, 0, 0, 0 } }, + // Tri-shackle + { 11482, { 30, 0, 0, 0, 0, 0, 0 } }, + // attack + { 11784, { 0, 0, 0, 0, 0, 0, 0 } }, + // Stone IV of the Seventh Dawn + { 13423, { 140, 0, 0, 0, 0, 0, 0 } }, + // Aero II of the Seventh Dawn + { 13424, { 50, 0, 0, 0, 0, 0, 0 } }, + // Cure II of the Seventh Dawn + { 13425, { 0, 0, 0, 0, 0, 700, 0 } }, + // Aetherwell + { 13426, { 0, 0, 0, 0, 0, 0, 0 } }, + // Thunderous Force + { 14587, { 0, 0, 0, 0, 0, 0, 0 } }, + // Kyokufu + { 14840, { 180, 0, 0, 0, 0, 0, 0 } }, + // Ajisai + { 14841, { 100, 0, 0, 0, 0, 0, 0 } }, + // Hissatsu: Gyoten + { 14842, { 100, 0, 0, 0, 0, 0, 0 } }, + // 冥界恐叫打 + { 14843, { 0, 0, 0, 0, 0, 0, 0 } }, + // Second Wind + { 15375, { 0, 0, 0, 0, 0, 500, 0 } }, + // Interject + { 15537, { 0, 0, 0, 0, 0, 0, 0 } }, + // Fight or Flight + { 15870, { 0, 0, 0, 0, 0, 0, 0 } }, + // Cascade + { 15989, { 250, 0, 0, 0, 0, 0, 0 } }, + // Fountain + { 15990, { 100, 300, 0, 0, 0, 0, 0 } }, + // Reverse Cascade + { 15991, { 300, 0, 0, 0, 0, 0, 0 } }, + // Fountainfall + { 15992, { 350, 0, 0, 0, 0, 0, 0 } }, + // Windmill + { 15993, { 150, 0, 0, 0, 0, 0, 0 } }, + // Bladeshower + { 15994, { 100, 200, 0, 0, 0, 0, 0 } }, + // Rising Windmill + { 15995, { 300, 0, 0, 0, 0, 0, 0 } }, + // Bloodshower + { 15996, { 350, 0, 0, 0, 0, 0, 0 } }, + // Standard Step + { 15997, { 0, 0, 0, 0, 0, 0, 0 } }, + // Technical Step + { 15998, { 0, 0, 0, 0, 0, 0, 0 } }, + // Emboite + { 15999, { 0, 0, 0, 0, 0, 0, 0 } }, + // Entrechat + { 16000, { 0, 0, 0, 0, 0, 0, 0 } }, + // Jete + { 16001, { 0, 0, 0, 0, 0, 0, 0 } }, + // Pirouette + { 16002, { 0, 0, 0, 0, 0, 0, 0 } }, + // Standard Finish + { 16003, { 0, 0, 0, 0, 0, 0, 0 } }, + // Technical Finish + { 16004, { 0, 0, 0, 0, 0, 0, 0 } }, + // Saber Dance + { 16005, { 600, 0, 0, 0, 0, 0, 0 } }, + // Closed Position + { 16006, { 0, 0, 0, 0, 0, 0, 0 } }, + // Fan Dance + { 16007, { 150, 0, 0, 0, 0, 0, 0 } }, + // Fan Dance II + { 16008, { 100, 0, 0, 0, 0, 0, 0 } }, + // Fan Dance III + { 16009, { 200, 0, 0, 0, 0, 0, 0 } }, + // En Avant + { 16010, { 0, 0, 0, 0, 0, 0, 0 } }, + // Devilment + { 16011, { 0, 0, 0, 0, 0, 0, 0 } }, + // Shield Samba + { 16012, { 0, 0, 0, 0, 0, 0, 0 } }, + // Flourish + { 16013, { 0, 0, 0, 0, 0, 0, 0 } }, + // Improvisation + { 16014, { 0, 0, 0, 0, 0, 0, 0 } }, + // Curing Waltz + { 16015, { 0, 0, 0, 0, 0, 300, 0 } }, + // Keen Edge + { 16137, { 200, 0, 0, 0, 0, 0, 0 } }, + // No Mercy + { 16138, { 0, 0, 0, 0, 0, 0, 0 } }, + // Brutal Shell + { 16139, { 100, 300, 0, 0, 0, 150, 0 } }, + // Camouflage + { 16140, { 0, 0, 0, 0, 0, 0, 0 } }, + // Demon Slice + { 16141, { 150, 0, 0, 0, 0, 0, 0 } }, + // Royal Guard + { 16142, { 0, 0, 0, 0, 0, 0, 0 } }, + // Lightning Shot + { 16143, { 150, 0, 0, 0, 0, 0, 0 } }, + // Danger Zone + { 16144, { 350, 0, 0, 0, 0, 0, 0 } }, + // Solid Barrel + { 16145, { 100, 400, 0, 0, 0, 0, 0 } }, + // Gnashing Fang + { 16146, { 450, 0, 0, 0, 0, 0, 0 } }, + // Savage Claw + { 16147, { 550, 0, 0, 0, 0, 0, 0 } }, + // Nebula + { 16148, { 0, 0, 0, 0, 0, 0, 0 } }, + // Demon Slaughter + { 16149, { 100, 250, 0, 0, 0, 0, 0 } }, + // Wicked Talon + { 16150, { 650, 0, 0, 0, 0, 0, 0 } }, + // Aurora + { 16151, { 0, 0, 0, 0, 0, 200, 0 } }, + // Superbolide + { 16152, { 0, 0, 0, 0, 0, 0, 0 } }, + // Sonic Break + { 16153, { 300, 0, 0, 0, 0, 0, 0 } }, + // Rough Divide + { 16154, { 200, 0, 0, 0, 0, 0, 0 } }, + // Continuation + { 16155, { 0, 0, 0, 0, 0, 0, 0 } }, + // Jugular Rip + { 16156, { 260, 0, 0, 0, 0, 0, 0 } }, + // Abdomen Tear + { 16157, { 280, 0, 0, 0, 0, 0, 0 } }, + // Eye Gouge + { 16158, { 300, 0, 0, 0, 0, 0, 0 } }, + // Bow Shock + { 16159, { 200, 0, 0, 0, 0, 0, 0 } }, + // Heart of Light + { 16160, { 0, 0, 0, 0, 0, 0, 0 } }, + // Heart of Stone + { 16161, { 0, 0, 0, 0, 0, 0, 0 } }, + // Burst Strike + { 16162, { 500, 0, 0, 0, 0, 0, 0 } }, + // Fated Circle + { 16163, { 320, 0, 0, 0, 0, 0, 0 } }, + // Bloodfest + { 16164, { 0, 0, 0, 0, 0, 0, 0 } }, + // Blasting Zone + { 16165, { 800, 0, 0, 0, 0, 0, 0 } }, + // Single Standard Finish + { 16191, { 0, 0, 0, 0, 0, 0, 0 } }, + // Double Standard Finish + { 16192, { 0, 0, 0, 0, 0, 0, 0 } }, + // Single Technical Finish + { 16193, { 0, 0, 0, 0, 0, 0, 0 } }, + // Double Technical Finish + { 16194, { 0, 0, 0, 0, 0, 0, 0 } }, + // Triple Technical Finish + { 16195, { 0, 0, 0, 0, 0, 0, 0 } }, + // Quadruple Technical Finish + { 16196, { 0, 0, 0, 0, 0, 0, 0 } }, + // Physick + { 16230, { 0, 0, 0, 0, 0, 400, 0 } }, + // Rightful Sword + { 16269, { 0, 0, 0, 0, 0, 0, 0 } }, + // Brutal Shell + { 16418, { 0, 0, 0, 0, 0, 0, 0 } }, + // Keen Edge + { 16434, { 0, 0, 0, 0, 0, 0, 0 } }, + // Solid Barrel + { 16435, { 0, 0, 0, 0, 0, 0, 0 } }, + // Soothing Potion + { 16436, { 0, 0, 0, 0, 0, 0, 0 } }, + // Shining Blade + { 16437, { 0, 0, 0, 0, 0, 0, 0 } }, + // Perfect Deception + { 16438, { 0, 0, 0, 0, 0, 0, 0 } }, + // Leap of Faith + { 16439, { 0, 0, 0, 0, 0, 0, 0 } }, + // Prominence + { 16457, { 100, 220, 0, 0, 0, 0, 5 } }, + // Holy Circle + { 16458, { 250, 0, 0, 0, 0, 0, 0 } }, + // Confiteor + { 16459, { 800, 0, 0, 0, 0, 0, 0 } }, + // Atonement + { 16460, { 550, 0, 0, 0, 0, 0, 0 } }, + // Intervene + { 16461, { 200, 0, 0, 0, 0, 0, 0 } }, + // Mythril Tempest + { 16462, { 100, 200, 0, 0, 0, 0, 0 } }, + // Chaotic Cyclone + { 16463, { 400, 0, 0, 0, 0, 0, 0 } }, + // Nascent Flash + { 16464, { 0, 0, 0, 0, 0, 0, 0 } }, + // Inner Chaos + { 16465, { 920, 0, 0, 0, 0, 0, 0 } }, + // Flood of Darkness + { 16466, { 250, 0, 0, 0, 0, 0, 0 } }, + // Edge of Darkness + { 16467, { 350, 0, 0, 0, 0, 0, 0 } }, + // Stalwart Soul + { 16468, { 100, 160, 0, 0, 0, 0, 6 } }, + // Flood of Shadow + { 16469, { 300, 0, 0, 0, 0, 0, 0 } }, + // Edge of Shadow + { 16470, { 500, 0, 0, 0, 0, 0, 0 } }, + // Dark Missionary + { 16471, { 0, 0, 0, 0, 0, 0, 0 } }, + // Living Shadow + { 16472, { 0, 0, 0, 0, 0, 0, 0 } }, + // Four-point Fury + { 16473, { 120, 0, 0, 0, 0, 0, 0 } }, + // Enlightenment + { 16474, { 220, 0, 0, 0, 0, 0, 0 } }, + // Anatman + { 16475, { 0, 0, 0, 0, 0, 0, 0 } }, + // Six-sided Star + { 16476, { 400, 0, 0, 0, 0, 0, 0 } }, + // Coerthan Torment + { 16477, { 100, 230, 0, 0, 0, 0, 0 } }, + // High Jump + { 16478, { 400, 0, 0, 0, 0, 0, 0 } }, + // Raiden Thrust + { 16479, { 330, 0, 0, 0, 0, 0, 0 } }, + // Stardiver + { 16480, { 600, 0, 0, 0, 0, 0, 0 } }, + // Hissatsu: Senei + { 16481, { 1100, 0, 0, 0, 0, 0, 0 } }, + // Ikishoten + { 16482, { 0, 0, 0, 0, 0, 0, 0 } }, + // Tsubame-gaeshi + { 16483, { 0, 0, 0, 0, 0, 0, 0 } }, + // Kaeshi: Higanbana + { 16484, { 375, 0, 0, 0, 0, 0, 0 } }, + // Kaeshi: Goken + { 16485, { 540, 0, 0, 0, 0, 0, 0 } }, + // Kaeshi: Setsugekka + { 16486, { 1200, 0, 0, 0, 0, 0, 0 } }, + // Shoha + { 16487, { 400, 0, 0, 0, 0, 0, 0 } }, + // Hakke Mujinsatsu + { 16488, { 100, 140, 0, 0, 0, 0, 0 } }, + // Meisui + { 16489, { 0, 0, 0, 0, 0, 0, 0 } }, + // Goka Mekkyaku + { 16491, { 750, 0, 0, 0, 0, 0, 0 } }, + // Hyosho Ranryu + { 16492, { 1200, 0, 0, 0, 0, 0, 0 } }, + // Bunshin + { 16493, { 0, 0, 0, 0, 0, 0, 0 } }, + // Shadowbite + { 16494, { 100, 0, 0, 0, 0, 0, 0 } }, + // Burst Shot + { 16495, { 230, 0, 0, 0, 0, 0, 0 } }, + // Apex Arrow + { 16496, { 120, 0, 0, 0, 0, 0, 0 } }, + // Auto Crossbow + { 16497, { 180, 0, 0, 0, 0, 0, 0 } }, + // Drill + { 16498, { 700, 0, 0, 0, 0, 0, 0 } }, + // Bioblaster + { 16499, { 60, 0, 0, 0, 0, 0, 0 } }, + // Air Anchor + { 16500, { 700, 0, 0, 0, 0, 0, 0 } }, + // Automaton Queen + { 16501, { 0, 0, 0, 0, 0, 0, 0 } }, + // Queen Overdrive + { 16502, { 0, 0, 0, 0, 0, 0, 0 } }, + // Despair + { 16505, { 380, 0, 0, 0, 0, 0, 0 } }, + // Umbral Soul + { 16506, { 0, 0, 0, 0, 0, 0, 0 } }, + // Xenoglossy + { 16507, { 750, 0, 0, 0, 0, 0, 0 } }, + // Energy Drain + { 16508, { 100, 0, 0, 0, 0, 0, 0 } }, + // Egi Assault + { 16509, { 0, 0, 0, 0, 0, 0, 0 } }, + // Energy Siphon + { 16510, { 40, 0, 0, 0, 0, 0, 0 } }, + // Outburst + { 16511, { 0, 0, 0, 0, 0, 0, 0 } }, + // Egi Assault II + { 16512, { 0, 0, 0, 0, 0, 0, 0 } }, + // Firebird Trance + { 16513, { 0, 0, 0, 0, 0, 0, 0 } }, + // Fountain of Fire + { 16514, { 250, 0, 0, 0, 0, 0, 0 } }, + // Brand of Purgatory + { 16515, { 350, 0, 0, 0, 0, 0, 0 } }, + // Enkindle Phoenix + { 16516, { 650, 0, 0, 0, 0, 0, 0 } }, + // Verthunder II + { 16524, { 0, 0, 0, 0, 0, 0, 0 } }, + // Veraero II + { 16525, { 0, 0, 0, 0, 0, 0, 0 } }, + // Impact + { 16526, { 220, 0, 0, 0, 0, 0, 0 } }, + // Engagement + { 16527, { 150, 0, 0, 0, 0, 0, 0 } }, + // Enchanted Reprise + { 16528, { 300, 0, 0, 0, 0, 0, 0 } }, + // Reprise + { 16529, { 100, 0, 0, 0, 0, 0, 0 } }, + // Scorch + { 16530, { 700, 0, 0, 0, 0, 0, 0 } }, + // Afflatus Solace + { 16531, { 0, 0, 0, 0, 0, 700, 0 } }, + // Dia + { 16532, { 120, 0, 0, 0, 0, 0, 0 } }, + // Glare + { 16533, { 300, 0, 0, 0, 0, 0, 0 } }, + // Afflatus Rapture + { 16534, { 0, 0, 0, 0, 0, 300, 0 } }, + // Afflatus Misery + { 16535, { 900, 0, 0, 0, 0, 0, 0 } }, + // Temperance + { 16536, { 0, 0, 0, 0, 0, 0, 0 } }, + // Whispering Dawn + { 16537, { 0, 0, 0, 0, 0, 120, 0 } }, + // Fey Illumination + { 16538, { 0, 0, 0, 0, 0, 0, 0 } }, + // Art of War + { 16539, { 0, 0, 0, 0, 0, 0, 0 } }, + // Biolysis + { 16540, { 0, 0, 0, 0, 0, 0, 0 } }, + // Broil III + { 16541, { 280, 0, 0, 0, 0, 0, 0 } }, + // Recitation + { 16542, { 0, 0, 0, 0, 0, 0, 0 } }, + // Fey Blessing + { 16543, { 0, 0, 0, 0, 0, 350, 0 } }, + // Summon Seraph + { 16545, { 0, 0, 0, 0, 0, 0, 0 } }, + // Consolation + { 16546, { 0, 0, 0, 0, 0, 300, 0 } }, + // Firebird Trance + { 16549, { 0, 0, 0, 0, 0, 0, 0 } }, + // Divination + { 16552, { 0, 0, 0, 0, 0, 0, 0 } }, + // Celestial Opposition + { 16553, { 0, 0, 0, 0, 0, 200, 0 } }, + // Combust III + { 16554, { 0, 0, 0, 0, 0, 0, 0 } }, + // Malefic IV + { 16555, { 250, 0, 0, 0, 0, 0, 0 } }, + // Celestial Intersection + { 16556, { 0, 0, 0, 0, 0, 200, 0 } }, + // Horoscope + { 16557, { 0, 0, 0, 0, 0, 200, 0 } }, + // Horoscope + { 16558, { 0, 0, 0, 0, 0, 0, 0 } }, + // Neutral Sect + { 16559, { 0, 0, 0, 0, 0, 0, 0 } }, + // Ronkan Fire III + { 16574, { 430, 0, 0, 0, 0, 0, 0 } }, + // Ronkan Blizzard III + { 16575, { 240, 0, 0, 0, 0, 0, 0 } }, + // Ronkan Thunder III + { 16576, { 200, 0, 0, 0, 0, 0, 0 } }, + // Ronkan Flare + { 16577, { 460, 0, 0, 0, 0, 0, 0 } }, + // Falling Star + { 16578, { 1500, 0, 0, 0, 0, 0, 0 } }, + // Detonator + { 16766, { 0, 0, 0, 0, 0, 0, 0 } }, + // Fast Blade + { 16788, { 0, 0, 0, 0, 0, 0, 0 } }, + // Sunshadow + { 16789, { 0, 0, 0, 0, 0, 0, 0 } }, + // Assault I: Glittering Topaz + { 16791, { 0, 0, 0, 0, 0, 0, 0 } }, + // Assault II: Shining Topaz + { 16792, { 200, 0, 0, 0, 0, 0, 0 } }, + // Assault I: Downburst + { 16793, { 100, 0, 0, 0, 0, 0, 0 } }, + // Assault II: Glittering Emerald + { 16794, { 30, 0, 0, 0, 0, 0, 0 } }, + // Assault I: Earthen Armor + { 16795, { 0, 0, 0, 0, 0, 0, 0 } }, + // Assault II: Mountain Buster + { 16796, { 250, 0, 0, 0, 0, 0, 0 } }, + // Assault I: Aerial Slash + { 16797, { 150, 0, 0, 0, 0, 0, 0 } }, + // Assault II: Slipstream + { 16798, { 50, 0, 0, 0, 0, 0, 0 } }, + // Assault I: Crimson Cyclone + { 16799, { 250, 0, 0, 0, 0, 0, 0 } }, + // Assault II: Flaming Crush + { 16800, { 250, 0, 0, 0, 0, 0, 0 } }, + // Enkindle: Earthen Fury + { 16801, { 300, 0, 0, 0, 0, 0, 0 } }, + // Enkindle: Aerial Blast + { 16802, { 350, 0, 0, 0, 0, 0, 0 } }, + // Enkindle: Inferno + { 16803, { 300, 0, 0, 0, 0, 0, 0 } }, + // Rough Divide + { 16804, { 200, 0, 0, 0, 0, 0, 0 } }, + // Tactician + { 16889, { 0, 0, 0, 0, 0, 0, 0 } }, + // Swashbuckler + { 16984, { 0, 0, 0, 0, 0, 0, 0 } }, + // Greatest Eclipse + { 16985, { 0, 0, 0, 0, 0, 0, 0 } }, + // Ronkan Cure II + { 17000, { 0, 0, 0, 0, 0, 1300, 0 } }, + // Ronkan Medica + { 17001, { 0, 0, 0, 0, 0, 500, 0 } }, + // Ronkan Esuna + { 17002, { 0, 0, 0, 0, 0, 0, 0 } }, + // Ronkan Stone II + { 17003, { 200, 0, 0, 0, 0, 0, 0 } }, + // Ronkan Renew + { 17004, { 0, 0, 0, 0, 0, 0, 0 } }, + // Play + { 17055, { 0, 0, 0, 0, 0, 0, 0 } }, + // Gunmetal Soul + { 17105, { 0, 0, 0, 0, 0, 0, 0 } }, + // Crimson Lotus + { 17106, { 0, 0, 0, 0, 0, 0, 0 } }, + // Acidic Bite + { 17122, { 300, 0, 0, 0, 0, 0, 0 } }, + // Heavy Shot + { 17123, { 550, 0, 0, 0, 0, 0, 0 } }, + // Radiant Arrow + { 17124, { 1100, 0, 0, 0, 0, 0, 0 } }, + // Dulling Arrow + { 17125, { 0, 0, 0, 0, 0, 0, 0 } }, + // Aspected Benefic + { 17151, { 0, 0, 0, 0, 0, 200, 0 } }, + // Aspected Helios + { 17152, { 0, 0, 0, 0, 0, 200, 0 } }, + // Hypercharge + { 17209, { 0, 0, 0, 0, 0, 0, 0 } }, + // Summon Eos + { 17215, { 0, 0, 0, 0, 0, 0, 0 } }, + // Summon Selene + { 17216, { 0, 0, 0, 0, 0, 0, 0 } }, + // attack + { 17222, { 0, 0, 0, 0, 0, 0, 0 } }, + // Chivalrous Spirit + { 17236, { 0, 0, 0, 0, 0, 1200, 0 } }, + // Souldeep Invisibility + { 17291, { 0, 0, 0, 0, 0, 0, 0 } }, + // Spinning Edge + { 17413, { 0, 0, 0, 0, 0, 0, 0 } }, + // Gust Slash + { 17414, { 0, 0, 0, 0, 0, 0, 0 } }, + // Aeolian Edge + { 17415, { 0, 0, 0, 0, 0, 0, 0 } }, + // Shadow Fang + { 17416, { 0, 0, 0, 0, 0, 0, 0 } }, + // Armor Crush + { 17417, { 0, 0, 0, 0, 0, 0, 0 } }, + // Throwing Dagger + { 17418, { 0, 0, 0, 0, 0, 0, 0 } }, + // Death Blossom + { 17419, { 0, 0, 0, 0, 0, 0, 0 } }, + // Hakke Mujinsatsu + { 17420, { 0, 0, 0, 0, 0, 0, 0 } }, + // Hunter's Prudence + { 17596, { 0, 0, 0, 0, 0, 1000, 0 } }, + // Nebula + { 17839, { 0, 0, 0, 0, 0, 0, 0 } }, + // Bio + { 17864, { 0, 0, 0, 0, 0, 0, 0 } }, + // Bio II + { 17865, { 0, 0, 0, 0, 0, 0, 0 } }, + // Ruin + { 17869, { 160, 0, 0, 0, 0, 0, 0 } }, + // Ruin II + { 17870, { 0, 0, 0, 0, 0, 0, 0 } }, // Smackdown - { 17901, { 0, 0, 0, 0, 0, 0 } }, + { 17901, { 0, 0, 0, 0, 0, 0, 0 } }, // 攻撃 - { 18034, { 0, 0, 0, 0, 0, 0 } }, + { 18034, { 0, 0, 0, 0, 0, 0, 0 } }, // Ending - { 18073, { 0, 0, 0, 0, 0, 0 } }, - // Straight Shot - { 18190, { 0, 0, 0, 0, 0, 0 } }, - + { 18073, { 0, 0, 0, 0, 0, 0, 0 } }, + // Alpine Draft + { 18295, { 220, 0, 0, 0, 0, 0, 0 } }, + // Protean Wave + { 18296, { 220, 0, 0, 0, 0, 0, 0 } }, + // Northerlies + { 18297, { 220, 0, 0, 0, 0, 0, 0 } }, + // Electrogenesis + { 18298, { 220, 0, 0, 0, 0, 0, 0 } }, + // Kaltstrahl + { 18299, { 220, 0, 0, 0, 0, 0, 0 } }, + // Abyssal Transfixion + { 18300, { 220, 0, 0, 0, 0, 0, 0 } }, + // Chirp + { 18301, { 0, 0, 0, 0, 0, 0, 0 } }, + // Eerie Soundwave + { 18302, { 0, 0, 0, 0, 0, 0, 0 } }, + // Pom Cure + { 18303, { 0, 0, 0, 0, 0, 100, 0 } }, + // Gobskin + { 18304, { 0, 0, 0, 0, 0, 0, 0 } }, + // Magic Hammer + { 18305, { 250, 0, 0, 0, 0, 0, 0 } }, + // Avail + { 18306, { 0, 0, 0, 0, 0, 0, 0 } }, + // Frog Legs + { 18307, { 0, 0, 0, 0, 0, 0, 0 } }, + // Sonic Boom + { 18308, { 210, 0, 0, 0, 0, 0, 0 } }, + // Whistle + { 18309, { 0, 0, 0, 0, 0, 0, 0 } }, + // White Knight's Tour + { 18310, { 200, 0, 0, 0, 0, 0, 0 } }, + // Black Knight's Tour + { 18311, { 200, 0, 0, 0, 0, 0, 0 } }, + // Level 5 Death + { 18312, { 0, 0, 0, 0, 0, 0, 0 } }, + // Launcher + { 18313, { 0, 0, 0, 0, 0, 0, 0 } }, + // Perpetual Ray + { 18314, { 220, 0, 0, 0, 0, 0, 0 } }, + // Cactguard + { 18315, { 0, 0, 0, 0, 0, 0, 0 } }, + // Revenge Blast + { 18316, { 50, 0, 0, 0, 0, 0, 0 } }, + // Angel Whisper + { 18317, { 0, 0, 0, 0, 0, 0, 0 } }, + // Exuviation + { 18318, { 0, 0, 0, 0, 0, 50, 0 } }, + // Reflux + { 18319, { 220, 0, 0, 0, 0, 0, 0 } }, + // Devour + { 18320, { 250, 0, 0, 0, 0, 0, 0 } }, + // Condensed Libra + { 18321, { 0, 0, 0, 0, 0, 0, 0 } }, + // Aetherial Mimicry + { 18322, { 0, 0, 0, 0, 0, 0, 0 } }, + // Surpanakha + { 18323, { 200, 0, 0, 0, 0, 0, 0 } }, + // Quasar + { 18324, { 300, 0, 0, 0, 0, 0, 0 } }, + // J Kick + { 18325, { 300, 0, 0, 0, 0, 0, 0 } }, + // Doom Spike + { 18772, { 0, 0, 0, 0, 0, 0, 0 } }, + // Sonic Thrust + { 18773, { 0, 0, 0, 0, 0, 0, 0 } }, + // Coerthan Torment + { 18774, { 0, 0, 0, 0, 0, 0, 0 } }, + // Skydragon Dive + { 18775, { 800, 0, 0, 0, 0, 0, 0 } }, + // Ala Morn + { 18776, { 3000, 0, 0, 0, 0, 0, 0 } }, + // Drachenlance + { 18777, { 500, 0, 0, 0, 0, 0, 0 } }, + // Horrid Roar + { 18778, { 600, 0, 0, 0, 0, 0, 0 } }, + // Stardiver + { 18780, { 1500, 0, 0, 0, 0, 0, 0 } }, + // Dragonshadow Dive + { 18781, { 0, 0, 0, 0, 0, 0, 0 } }, + // Dragonshadow Dive + { 18782, { 0, 0, 0, 0, 0, 0, 0 } }, + // Ten + { 18805, { 0, 0, 0, 0, 0, 0, 0 } }, + // Chi + { 18806, { 0, 0, 0, 0, 0, 0, 0 } }, + // Jin + { 18807, { 0, 0, 0, 0, 0, 0, 0 } }, + // Fuma Shuriken + { 18873, { 500, 0, 0, 0, 0, 0, 0 } }, + // Fuma Shuriken + { 18874, { 500, 0, 0, 0, 0, 0, 0 } }, + // Fuma Shuriken + { 18875, { 500, 0, 0, 0, 0, 0, 0 } }, + // Katon + { 18876, { 500, 0, 0, 0, 0, 0, 0 } }, + // Raiton + { 18877, { 800, 0, 0, 0, 0, 0, 0 } }, + // Hyoton + { 18878, { 400, 0, 0, 0, 0, 0, 0 } }, + // Huton + { 18879, { 0, 0, 0, 0, 0, 0, 0 } }, + // Doton + { 18880, { 100, 0, 0, 0, 0, 0, 0 } }, + // Suiton + { 18881, { 600, 0, 0, 0, 0, 0, 0 } }, + // Gofu + { 19046, { 0, 0, 0, 0, 0, 0, 0 } }, + // Yagetsu + { 19047, { 0, 0, 0, 0, 0, 0, 0 } }, + // Aqua Vitae + { 19218, { 0, 0, 0, 0, 0, 0, 0 } }, + // attack + { 19221, { 0, 0, 0, 0, 0, 0, 0 } }, + // Aetherial Mimicry + { 19238, { 0, 0, 0, 0, 0, 0, 0 } }, + // Aetherial Mimicry + { 19239, { 0, 0, 0, 0, 0, 0, 0 } }, + // Aetherial Mimicry + { 19240, { 0, 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 index 7068c01e..138b511e 100644 --- a/src/world/Action/EffectBuilder.cpp +++ b/src/world/Action/EffectBuilder.cpp @@ -31,18 +31,17 @@ uint64_t EffectBuilder::getResultDelayMs() return Common::Util::getTimeMs() + 850; } -EffectResultPtr EffectBuilder::getResult( Entity::CharaPtr& chara ) +std::shared_ptr< std::vector< EffectResultPtr > > EffectBuilder::getResultList( 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() ); + auto resultList = std::make_shared< std::vector< EffectResultPtr > >(); - m_resolvedEffects[ chara->getId() ] = result; + m_resolvedEffects[ chara->getId() ] = resultList; - return result; + return resultList; } return it->second; @@ -50,43 +49,207 @@ EffectResultPtr EffectBuilder::getResult( Entity::CharaPtr& chara ) void EffectBuilder::healTarget( Entity::CharaPtr& target, uint32_t amount, Common::ActionHitSeverityType severity ) { - auto result = getResult( target ); - assert( result ); + auto resultList = getResultList( target ); + assert( resultList ); - result->heal( amount, severity ); + EffectResultPtr nextResult = make_EffectResult( target, getResultDelayMs() ); + nextResult->heal( amount, severity, false ); + resultList->push_back( std::move( nextResult ) ); +} + +void EffectBuilder::selfHeal( Entity::CharaPtr& target, Entity::CharaPtr& source, uint32_t amount, Common::ActionHitSeverityType severity ) +{ + auto resultList = getResultList( target ); + assert( resultList ); + + EffectResultPtr nextResult = make_EffectResult( source, getResultDelayMs() ); // heal the source actor + nextResult->heal( amount, severity, true ); + resultList->push_back( std::move( nextResult ) ); +} + +void EffectBuilder::restoreMP( Entity::CharaPtr& target, Entity::CharaPtr& source, uint32_t amount ) +{ + auto resultList = getResultList( target ); + assert( resultList ); + + EffectResultPtr nextResult = make_EffectResult( source, getResultDelayMs() ); // restore mp source actor + nextResult->restoreMP( amount ); + resultList->push_back( std::move( nextResult ) ); } void EffectBuilder::damageTarget( Entity::CharaPtr& target, uint32_t amount, Common::ActionHitSeverityType severity ) { - auto result = getResult( target ); - assert( result ); + auto resultList = getResultList( target ); + assert( resultList ); - result->damage( amount, severity ); + EffectResultPtr nextResult = make_EffectResult( target, getResultDelayMs() ); + nextResult->damage( amount, severity ); + resultList->push_back( std::move( nextResult ) ); +} + +void EffectBuilder::startCombo( Entity::CharaPtr& target, uint16_t actionId ) +{ + auto resultList = getResultList( target ); + assert( resultList ); + + EffectResultPtr nextResult = make_EffectResult( target, 0 ); + nextResult->startCombo( actionId ); + resultList->push_back( std::move( nextResult ) ); +} + +void EffectBuilder::comboVisualEffect( Entity::CharaPtr& target ) +{ + auto resultList = getResultList( target ); + assert( resultList ); + + EffectResultPtr nextResult = make_EffectResult( target, 0 ); + nextResult->comboVisualEffect(); + resultList->push_back( std::move( nextResult ) ); } void EffectBuilder::buildAndSendPackets() { + auto targetCount = m_resolvedEffects.size(); Logger::debug( "EffectBuilder result: " ); - Logger::debug( "Targets afflicted: {}", m_resolvedEffects.size() ); + Logger::debug( "Targets afflicted: {}", targetCount ); - for( auto it = m_resolvedEffects.begin(); it != m_resolvedEffects.end(); ) + auto globalSequence = m_sourceChara->getCurrentTerritory()->getNextEffectSequence(); + + while( m_resolvedEffects.size() > 0 ) { - auto result = it->second; - Logger::debug( " - id: {}", result->getTarget()->getId() ); + auto packet = buildNextEffectPacket( globalSequence ); + m_sourceChara->sendToInRangeSet( packet, true ); + } +} + +std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( uint32_t globalSequence ) +{ + auto remainingTargetCount = m_resolvedEffects.size(); + + if( remainingTargetCount > 1 ) // use AoeEffect packets + { + int packetSize = remainingTargetCount <= 8 ? 8 : + ( remainingTargetCount <= 16 ? 16 : + ( remainingTargetCount <= 24 ? 24 : 32 ) ); + + using EffectHeader = Server::FFXIVIpcAoeEffect< 8 >; // dummy type to access header part of the packet + + FFXIVPacketBasePtr effectPacket = nullptr; + EffectHeader* pHeader; + Common::EffectEntry* pEntry; + uint64_t* pEffectTargetId; + uint16_t* pFlag; + switch( packetSize ) + { + case 8: + { + auto p = makeZonePacket< Server::FFXIVIpcAoeEffect8 >( m_sourceChara->getId() ); + pHeader = ( EffectHeader* )( &( p->data() ) ); + pEntry = ( Common::EffectEntry* )( &( p->data().effects ) ); + pEffectTargetId = ( uint64_t* )( &( p->data().effectTargetId ) ); + pFlag = ( uint16_t* )( &( p->data().unkFlag ) ); + effectPacket = std::move( p ); + break; + } + case 16: + { + auto p = makeZonePacket< Server::FFXIVIpcAoeEffect16 >( m_sourceChara->getId() ); + pHeader = ( EffectHeader* )( &( p->data() ) ); + pEntry = ( Common::EffectEntry* )( &( p->data().effects ) ); + pEffectTargetId = ( uint64_t* )( &( p->data().effectTargetId ) ); + pFlag = ( uint16_t* )( &( p->data().unkFlag ) ); + effectPacket = std::move( p ); + break; + } + case 24: + { + auto p = makeZonePacket< Server::FFXIVIpcAoeEffect24 >( m_sourceChara->getId() ); + pHeader = ( EffectHeader* )( &( p->data() ) ); + pEntry = ( Common::EffectEntry* )( &( p->data().effects ) ); + pEffectTargetId = ( uint64_t* )( &( p->data().effectTargetId ) ); + pFlag = ( uint16_t* )( &( p->data().unkFlag ) ); + effectPacket = std::move( p ); + break; + } + case 32: + { + auto p = makeZonePacket< Server::FFXIVIpcAoeEffect32 >( m_sourceChara->getId() ); + pHeader = ( EffectHeader* )( &( p->data() ) ); + pEntry = ( Common::EffectEntry* )( &( p->data().effects ) ); + pEffectTargetId = ( uint64_t* )( &( p->data().effectTargetId ) ); + pFlag = ( uint16_t* )( &( p->data().unkFlag ) ); + effectPacket = std::move( p ); + break; + } + } + assert( effectPacket != nullptr ); + + pHeader->actionAnimationId = m_sourceChara->getId(); + pHeader->actionId = m_actionId; + pHeader->actionAnimationId = static_cast< uint16_t >( m_actionId ); + pHeader->animationTargetId = m_sourceChara->getId(); + pHeader->someTargetId = 0xE0000000; + pHeader->rotation = Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ); + pHeader->effectDisplayType = Common::ActionEffectDisplayType::ShowActionName; + pHeader->effectCount = static_cast< uint8_t >( remainingTargetCount > packetSize ? packetSize : remainingTargetCount ); + pHeader->sourceSequence = m_sequence; + pHeader->globalSequence = globalSequence; + + uint8_t targetIndex = 0; + for( auto it = m_resolvedEffects.begin(); it != m_resolvedEffects.end(); ) + { + auto resultList = it->second; + assert( resultList->size() > 0 ); + auto firstResult = resultList->data()[ 0 ]; + pEffectTargetId[ targetIndex ] = firstResult->getTarget()->getId(); + Logger::debug( " - id: {}", pEffectTargetId[ targetIndex ] ); + + for( auto i = 0; i < resultList->size(); i++ ) + { + auto result = resultList->data()[ i ]; + pEntry[ targetIndex * 8 + i ] = result->buildEffectEntry(); + m_sourceChara->getCurrentTerritory()->addEffectResult( std::move( result ) ); + } + resultList->clear(); + + it = m_resolvedEffects.erase( it ); + + targetIndex++; + + if( targetIndex == packetSize ) + break; + } + + pFlag[0] = 0x7FFF; + pFlag[1] = 0x7FFF; + pFlag[2] = 0x7FFF; + + return effectPacket; + } + else + { + auto resultList = m_resolvedEffects.begin()->second; + assert( resultList->size() > 0 ); + auto firstResult = resultList->data()[ 0 ]; + Logger::debug( " - id: {}", firstResult->getTarget()->getId() ); auto seq = m_sourceChara->getCurrentTerritory()->getNextEffectSequence(); - auto effectPacket = std::make_shared< Server::EffectPacket >( m_sourceChara->getId(), result->getTarget()->getId(), m_actionId ); + auto effectPacket = std::make_shared< Server::EffectPacket >( m_sourceChara->getId(), firstResult->getTarget()->getId(), m_actionId ); effectPacket->setRotation( Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ) ); effectPacket->setSequence( seq, m_sequence ); - effectPacket->addEffect( result->buildEffectEntry() ); + for( int i = 0; i < resultList->size(); i++ ) + { + auto result = resultList->data()[ i ]; + effectPacket->addEffect( result->buildEffectEntry() ); + m_sourceChara->getCurrentTerritory()->addEffectResult( std::move( result ) ); + } - m_sourceChara->sendToInRangeSet( effectPacket, true ); + resultList->clear(); - // add effect to territory - m_sourceChara->getCurrentTerritory()->addEffectResult( std::move( result ) ); + m_resolvedEffects.clear(); - it = m_resolvedEffects.erase( it ); + return effectPacket; } } \ No newline at end of file diff --git a/src/world/Action/EffectBuilder.h b/src/world/Action/EffectBuilder.h index d58bebfe..a4699bb6 100644 --- a/src/world/Action/EffectBuilder.h +++ b/src/world/Action/EffectBuilder.h @@ -15,23 +15,34 @@ namespace Sapphire::World::Action void healTarget( Entity::CharaPtr& target, uint32_t amount, Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalHeal ); + void selfHeal( Entity::CharaPtr& target, Entity::CharaPtr& source, uint32_t amount, + Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalHeal ); + + void restoreMP( Entity::CharaPtr& target, Entity::CharaPtr& source, uint32_t amount ); + void damageTarget( Entity::CharaPtr& target, uint32_t amount, Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalDamage ); + void startCombo( Entity::CharaPtr& target, uint16_t actionId ); + + void comboVisualEffect( Entity::CharaPtr& target ); + void buildAndSendPackets(); private: - EffectResultPtr getResult( Entity::CharaPtr& chara ); + std::shared_ptr< std::vector< EffectResultPtr > > getResultList( Entity::CharaPtr& chara ); uint64_t getResultDelayMs(); + std::shared_ptr< Sapphire::Network::Packets::FFXIVPacketBase > buildNextEffectPacket( uint32_t globalSequence ); + private: uint32_t m_actionId; uint16_t m_sequence; Entity::CharaPtr m_sourceChara; - std::unordered_map< uint32_t, EffectResultPtr > m_resolvedEffects; + std::unordered_map< uint32_t, std::shared_ptr< std::vector< EffectResultPtr > > > m_resolvedEffects; }; } diff --git a/src/world/Action/EffectResult.cpp b/src/world/Action/EffectResult.cpp index daf32155..8f5782ce 100644 --- a/src/world/Action/EffectResult.cpp +++ b/src/world/Action/EffectResult.cpp @@ -14,7 +14,8 @@ EffectResult::EffectResult( Entity::CharaPtr target, uint64_t runAfter ) : m_value( 0 ), m_severity( Common::ActionHitSeverityType::NormalDamage ), m_type( Common::ActionEffectType::Nothing ), - m_param( 0 ) + m_param( 0 ), + m_flag( 0 ) { } @@ -47,14 +48,36 @@ void EffectResult::damage( uint32_t amount, Common::ActionHitSeverityType severi m_type = Common::ActionEffectType::Damage; } -void EffectResult::heal( uint32_t amount, Sapphire::Common::ActionHitSeverityType severity ) +void EffectResult::heal( uint32_t amount, Sapphire::Common::ActionHitSeverityType severity, bool isSelfHeal ) { m_severity = severity; m_value = amount; + m_flag = isSelfHeal ? 0x80 : 0; // flag == 0x80 displays healing text at source actor m_type = Common::ActionEffectType::Heal; } +void EffectResult::restoreMP( uint32_t amount ) +{ + m_value = amount; + m_flag = 0x80; + + m_type = Common::ActionEffectType::MpGain; +} + +void EffectResult::startCombo( uint16_t actionId ) +{ + m_value = actionId; + m_flag = 0x80; + + m_type = Common::ActionEffectType::StartActionCombo; +} + +void EffectResult::comboVisualEffect() +{ + m_type = Common::ActionEffectType::ComboVisualEffect; +} + Common::EffectEntry EffectResult::buildEffectEntry() const { Common::EffectEntry entry{}; @@ -64,6 +87,7 @@ Common::EffectEntry EffectResult::buildEffectEntry() const entry.hitSeverity = m_severity; entry.effectType = m_type; entry.param = m_param; + entry.flags = m_flag; return entry; } @@ -84,6 +108,12 @@ void EffectResult::execute() break; } + case Common::ActionEffectType::MpGain: + { + m_target->restoreMP( m_value ); + break; + } + default: break; } diff --git a/src/world/Action/EffectResult.h b/src/world/Action/EffectResult.h index f1dd8b9c..3a93d13b 100644 --- a/src/world/Action/EffectResult.h +++ b/src/world/Action/EffectResult.h @@ -16,7 +16,10 @@ namespace Sapphire::World::Action explicit EffectResult( Entity::CharaPtr target, uint64_t delayMs ); void damage( uint32_t amount, Common::ActionHitSeverityType severity ); - void heal( uint32_t amount, Common::ActionHitSeverityType severity ); + void heal( uint32_t amount, Common::ActionHitSeverityType severity, bool isSelfHeal ); + void restoreMP( uint32_t amount ); + void startCombo( uint16_t actionId ); + void comboVisualEffect(); Entity::CharaPtr getTarget() const; @@ -40,6 +43,7 @@ namespace Sapphire::World::Action uint32_t m_value; uint8_t m_param; + uint8_t m_flag; }; } diff --git a/src/world/Actor/Chara.cpp b/src/world/Actor/Chara.cpp index cd187840..6adcfcc9 100644 --- a/src/world/Actor/Chara.cpp +++ b/src/world/Actor/Chara.cpp @@ -438,6 +438,18 @@ void Sapphire::Entity::Chara::heal( uint32_t amount ) sendStatusUpdate(); } +void Sapphire::Entity::Chara::restoreMP( uint32_t amount ) +{ + if( ( m_mp + amount ) > getMaxMp() ) + { + m_mp = getMaxMp(); + } + else + m_mp += amount; + + sendStatusUpdate(); +} + /*! Send an HpMpTp update to players in range ( and potentially to self ) TODO: poor naming, should be changed. Status is not HP. Also should be virtual diff --git a/src/world/Actor/Chara.h b/src/world/Actor/Chara.h index d9fea85b..697f5a6e 100644 --- a/src/world/Actor/Chara.h +++ b/src/world/Actor/Chara.h @@ -263,6 +263,8 @@ namespace Sapphire::Entity virtual void heal( uint32_t amount ); + virtual void restoreMP( uint32_t amount ); + virtual bool checkAction(); virtual void update( uint64_t tickCount ); diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 4ebe604d..4a6ab8d8 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -76,7 +76,8 @@ Sapphire::Entity::Player::Player( FrameworkPtr pFw ) : m_emoteMode( 0 ), m_directorInitialized( false ), m_onEnterEventDone( false ), - m_falling( false ) + m_falling( false ), + m_pQueuedAction( nullptr ) { m_id = 0; m_currentStance = Stance::Passive; @@ -2131,3 +2132,43 @@ Sapphire::Common::ActiveLand Sapphire::Entity::Player::getActiveLand() const { return m_activeLand; } + +bool Sapphire::Entity::Player::hasQueuedAction() const +{ + return m_pQueuedAction != nullptr; +} + +void Sapphire::Entity::Player::setQueuedAction( Sapphire::World::Action::ActionPtr pAction ) +{ + m_pQueuedAction = nullptr; // overwrite whatever is already there + m_pQueuedAction = std::move( pAction ); +} + +bool Sapphire::Entity::Player::checkAction() +{ + if( m_pCurrentAction == nullptr ) + return false; + + if( m_pCurrentAction->update() ) + { + if( m_pCurrentAction->isInterrupted() && m_pCurrentAction->getInterruptType() != Common::ActionInterruptType::DamageInterrupt ) + { + // we moved (or whatever not damage interrupt) so we don't want to execute queued cast + m_pQueuedAction = nullptr; + } + m_pCurrentAction = nullptr; + + if( hasQueuedAction() ) + { + sendDebug( "Queued skill start: {0}", m_pQueuedAction->getId() ); + if( m_pQueuedAction->hasCastTime() ) + { + setCurrentAction( m_pQueuedAction ); + } + m_pQueuedAction->start(); + m_pQueuedAction = nullptr; + } + } + + return true; +} \ No newline at end of file diff --git a/src/world/Actor/Player.h b/src/world/Actor/Player.h index efaf1f7d..9f40168c 100644 --- a/src/world/Actor/Player.h +++ b/src/world/Actor/Player.h @@ -643,6 +643,11 @@ namespace Sapphire::Entity /*! return a const pointer to the mount guide bitmask array */ const uint8_t* getMountGuideBitmask() const; + bool checkAction() override; + + bool hasQueuedAction() const; + + void setQueuedAction( World::Action::ActionPtr pAction ); // Spawn handling ////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -1002,6 +1007,8 @@ namespace Sapphire::Entity uint32_t m_inventorySequence; + World::Action::ActionPtr m_pQueuedAction; + private: using InventoryMap = std::map< uint16_t, Sapphire::ItemContainerPtr >; diff --git a/src/world/Manager/ActionMgr.cpp b/src/world/Manager/ActionMgr.cpp index 43d14170..2356d7b3 100644 --- a/src/world/Manager/ActionMgr.cpp +++ b/src/world/Manager/ActionMgr.cpp @@ -27,6 +27,8 @@ void World::Manager::ActionMgr::handlePlacedPlayerAction( Entity::Player& player auto action = Action::make_Action( player.getAsPlayer(), actionId, sequence, actionData, framework() ); + action->setPos( pos ); + if( !action->init() ) return; @@ -37,8 +39,6 @@ void World::Manager::ActionMgr::handlePlacedPlayerAction( Entity::Player& player return; } - action->setPos( pos ); - bootstrapAction( player, action, *actionData ); } @@ -50,6 +50,8 @@ void World::Manager::ActionMgr::handleTargetedPlayerAction( Entity::Player& play action->setTargetId( targetId ); + action->setPos( player.getPos() ); + if( !action->init() ) return; @@ -87,12 +89,20 @@ void World::Manager::ActionMgr::bootstrapAction( Entity::Player& player, return; } - // if we have a cast time we want to associate the action with the player so update is called - if( currentAction->hasCastTime() ) + if( player.getCurrentAction() ) { - player.setCurrentAction( currentAction ); + player.sendDebug( "Skill queued: {0}", currentAction->getId() ); + player.setQueuedAction( currentAction ); } + else + { + // if we have a cast time we want to associate the action with the player so update is called + if( currentAction->hasCastTime() ) + { + player.setCurrentAction( currentAction ); + } - // todo: what do in cases of swiftcast/etc? script callback? - currentAction->start(); + // todo: what do in cases of swiftcast/etc? script callback? + currentAction->start(); + } } \ No newline at end of file diff --git a/src/world/Network/PacketWrappers/EffectPacket.h b/src/world/Network/PacketWrappers/EffectPacket.h index 46c8338b..2306b066 100644 --- a/src/world/Network/PacketWrappers/EffectPacket.h +++ b/src/world/Network/PacketWrappers/EffectPacket.h @@ -25,13 +25,14 @@ namespace Sapphire::Network::Packets::Server m_data.effectTargetId = targetId; m_data.effectDisplayType = Common::ActionEffectDisplayType::ShowActionName; + + std::memset( m_data.effects, 0, sizeof(Common::EffectEntry) * 8 ); } void addEffect( const Common::EffectEntry& effect ) { assert( m_data.effectCount <= 8 ); - std::memset( m_data.effects, 0, sizeof( Common::EffectEntry ) * 8 ); std::memcpy( &m_data.effects[ m_data.effectCount * 8 ], &effect, sizeof( Common::EffectEntry ) ); m_data.effectCount++; } From eafb6f45b710142a2c37f0072bc8b2e4df0d56fd Mon Sep 17 00:00:00 2001 From: collett Date: Sun, 5 Jan 2020 17:26:49 +0900 Subject: [PATCH 2/8] oops --- src/world/Action/EffectBuilder.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/world/Action/EffectBuilder.cpp b/src/world/Action/EffectBuilder.cpp index 138b511e..b02a5df4 100644 --- a/src/world/Action/EffectBuilder.cpp +++ b/src/world/Action/EffectBuilder.cpp @@ -184,7 +184,6 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( uint32_ } assert( effectPacket != nullptr ); - pHeader->actionAnimationId = m_sourceChara->getId(); pHeader->actionId = m_actionId; pHeader->actionAnimationId = static_cast< uint16_t >( m_actionId ); pHeader->animationTargetId = m_sourceChara->getId(); From bf247276b55020fd12e1fca828f99a44eb502efa Mon Sep 17 00:00:00 2001 From: collett Date: Sun, 5 Jan 2020 20:49:50 +0900 Subject: [PATCH 3/8] Minor tweaks and code clean up. --- src/common/Common.h | 8 ++- src/world/Action/Action.cpp | 17 +++-- src/world/Action/EffectBuilder.cpp | 70 ++++++++----------- src/world/Action/EffectBuilder.h | 19 +++-- src/world/Action/EffectResult.cpp | 22 +++--- src/world/Action/EffectResult.h | 10 +-- src/world/Actor/Player.cpp | 3 +- .../Network/PacketWrappers/EffectPacket.h | 2 +- 8 files changed, 73 insertions(+), 78 deletions(-) diff --git a/src/common/Common.h b/src/common/Common.h index 46ce75e4..529284a2 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -629,7 +629,7 @@ namespace Sapphire::Common * @param value The actionid that starts/continues the combo. eg, 3617 will start a spinning slash and/or syphon strike combo */ StartActionCombo = 28, - ComboVisualEffect = 29, + ComboSucceed = 29, Knockback = 33, Mount = 38, VFX = 59, // links to VFX sheet @@ -645,6 +645,12 @@ namespace Sapphire::Common CritDirectHitDamage = 3 }; + enum class ActionEffectResultFlag : uint8_t + { + None = 0, + EffectOnSource = 0x80, + }; + enum ItemActionType : uint16_t { ItemActionVFX = 852, diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index 1c2f10aa..60900a53 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -468,14 +468,14 @@ void Action::Action::buildEffects() if( m_lutEntry.potency > 0 ) { auto dmg = calcDamage( isCorrectCombo() ? m_lutEntry.comboPotency : m_lutEntry.potency ); - m_effectBuilder->damageTarget( actor, dmg.first, dmg.second ); + m_effectBuilder->damage( actor, actor, dmg.first, dmg.second ); if( dmg.first > 0 ) actor->onActionHostile( m_pSource ); if( isCorrectCombo() && shouldShowComboEffect ) { - m_effectBuilder->comboVisualEffect( actor ); + m_effectBuilder->comboSucceed( actor ); shouldShowComboEffect = false; } @@ -483,12 +483,12 @@ void Action::Action::buildEffects() { if( m_lutEntry.curePotency > 0 ) // actions with self heal { - m_effectBuilder->selfHeal( actor, m_pSource, m_lutEntry.curePotency ); + m_effectBuilder->heal( actor, m_pSource, m_lutEntry.curePotency, Common::ActionHitSeverityType::NormalHeal, Common::ActionEffectResultFlag::EffectOnSource ); } if( m_lutEntry.restoreMPPercentage > 0 && shouldRestoreMP ) { - m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100 ); + m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100, Common::ActionEffectResultFlag::EffectOnSource ); shouldRestoreMP = false; } @@ -501,18 +501,17 @@ void Action::Action::buildEffects() else if( m_lutEntry.curePotency > 0 ) { // todo: calcHealing() - m_effectBuilder->healTarget( actor, m_lutEntry.curePotency ); + m_effectBuilder->heal( actor, actor, m_lutEntry.curePotency ); if( m_lutEntry.restoreMPPercentage > 0 && shouldRestoreMP ) { - // always restore caster mp I don't think there are any actions that can restore target MP post 5.0 - m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100 ); + m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100, Common::ActionEffectResultFlag::EffectOnSource ); shouldRestoreMP = false; } } else if( m_lutEntry.restoreMPPercentage > 0 && shouldRestoreMP ) { - m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100 ); + m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMaxMp() * m_lutEntry.restoreMPPercentage / 100, Common::ActionEffectResultFlag::EffectOnSource ); shouldRestoreMP = false; } } @@ -753,7 +752,7 @@ bool Action::Action::preFilterActor( Sapphire::Entity::Actor& actor ) const if( kind != ObjKind::BattleNpc && kind != ObjKind::Player ) return false; - if( m_lutEntry.potency > 0 && chara == m_pSource ) + if( m_lutEntry.potency > 0 && chara->getId() == m_pSource->getId() ) { // damage action shouldn't hit self return false; diff --git a/src/world/Action/EffectBuilder.cpp b/src/world/Action/EffectBuilder.cpp index b02a5df4..c7c231f0 100644 --- a/src/world/Action/EffectBuilder.cpp +++ b/src/world/Action/EffectBuilder.cpp @@ -47,43 +47,33 @@ std::shared_ptr< std::vector< EffectResultPtr > > EffectBuilder::getResultList( return it->second; } -void EffectBuilder::healTarget( Entity::CharaPtr& target, uint32_t amount, Common::ActionHitSeverityType severity ) +void EffectBuilder::heal( Entity::CharaPtr& effectTarget, Entity::CharaPtr& healingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag ) { - auto resultList = getResultList( target ); + auto resultList = getResultList( effectTarget ); assert( resultList ); - EffectResultPtr nextResult = make_EffectResult( target, getResultDelayMs() ); - nextResult->heal( amount, severity, false ); + EffectResultPtr nextResult = make_EffectResult( healingTarget, getResultDelayMs() ); + nextResult->heal( amount, severity, flag ); resultList->push_back( std::move( nextResult ) ); } -void EffectBuilder::selfHeal( Entity::CharaPtr& target, Entity::CharaPtr& source, uint32_t amount, Common::ActionHitSeverityType severity ) +void EffectBuilder::restoreMP( Entity::CharaPtr& target, Entity::CharaPtr& restoringTarget, uint32_t amount, Common::ActionEffectResultFlag flag ) { auto resultList = getResultList( target ); assert( resultList ); - EffectResultPtr nextResult = make_EffectResult( source, getResultDelayMs() ); // heal the source actor - nextResult->heal( amount, severity, true ); + EffectResultPtr nextResult = make_EffectResult( restoringTarget, getResultDelayMs() ); // restore mp source actor + nextResult->restoreMP( amount, flag ); resultList->push_back( std::move( nextResult ) ); } -void EffectBuilder::restoreMP( Entity::CharaPtr& target, Entity::CharaPtr& source, uint32_t amount ) +void EffectBuilder::damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag ) { - auto resultList = getResultList( target ); + auto resultList = getResultList( effectTarget ); assert( resultList ); - EffectResultPtr nextResult = make_EffectResult( source, getResultDelayMs() ); // restore mp source actor - nextResult->restoreMP( amount ); - resultList->push_back( std::move( nextResult ) ); -} - -void EffectBuilder::damageTarget( Entity::CharaPtr& target, uint32_t amount, Common::ActionHitSeverityType severity ) -{ - auto resultList = getResultList( target ); - assert( resultList ); - - EffectResultPtr nextResult = make_EffectResult( target, getResultDelayMs() ); - nextResult->damage( amount, severity ); + EffectResultPtr nextResult = make_EffectResult( damagingTarget, getResultDelayMs() ); + nextResult->damage( amount, severity, flag ); resultList->push_back( std::move( nextResult ) ); } @@ -97,13 +87,13 @@ void EffectBuilder::startCombo( Entity::CharaPtr& target, uint16_t actionId ) resultList->push_back( std::move( nextResult ) ); } -void EffectBuilder::comboVisualEffect( Entity::CharaPtr& target ) +void EffectBuilder::comboSucceed( Entity::CharaPtr& target ) { auto resultList = getResultList( target ); assert( resultList ); EffectResultPtr nextResult = make_EffectResult( target, 0 ); - nextResult->comboVisualEffect(); + nextResult->comboSucceed(); resultList->push_back( std::move( nextResult ) ); } @@ -144,40 +134,40 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( uint32_ case 8: { auto p = makeZonePacket< Server::FFXIVIpcAoeEffect8 >( m_sourceChara->getId() ); - pHeader = ( EffectHeader* )( &( p->data() ) ); - pEntry = ( Common::EffectEntry* )( &( p->data().effects ) ); - pEffectTargetId = ( uint64_t* )( &( p->data().effectTargetId ) ); - pFlag = ( uint16_t* )( &( p->data().unkFlag ) ); + pHeader = reinterpret_cast< EffectHeader* >( &p->data() ); + pEntry = reinterpret_cast< Common::EffectEntry* >( &p->data().effects ); + pEffectTargetId = reinterpret_cast< uint64_t* >( &p->data().effectTargetId ); + pFlag = reinterpret_cast< uint16_t* >( &p->data().unkFlag ); effectPacket = std::move( p ); break; } case 16: { auto p = makeZonePacket< Server::FFXIVIpcAoeEffect16 >( m_sourceChara->getId() ); - pHeader = ( EffectHeader* )( &( p->data() ) ); - pEntry = ( Common::EffectEntry* )( &( p->data().effects ) ); - pEffectTargetId = ( uint64_t* )( &( p->data().effectTargetId ) ); - pFlag = ( uint16_t* )( &( p->data().unkFlag ) ); + pHeader = reinterpret_cast< EffectHeader* >( &p->data() ); + pEntry = reinterpret_cast< Common::EffectEntry* >( &p->data().effects ); + pEffectTargetId = reinterpret_cast< uint64_t* >( &p->data().effectTargetId ); + pFlag = reinterpret_cast< uint16_t* >( &p->data().unkFlag ); effectPacket = std::move( p ); break; } case 24: { auto p = makeZonePacket< Server::FFXIVIpcAoeEffect24 >( m_sourceChara->getId() ); - pHeader = ( EffectHeader* )( &( p->data() ) ); - pEntry = ( Common::EffectEntry* )( &( p->data().effects ) ); - pEffectTargetId = ( uint64_t* )( &( p->data().effectTargetId ) ); - pFlag = ( uint16_t* )( &( p->data().unkFlag ) ); + pHeader = reinterpret_cast< EffectHeader* >( &p->data() ); + pEntry = reinterpret_cast< Common::EffectEntry* >( &p->data().effects ); + pEffectTargetId = reinterpret_cast< uint64_t* >( &p->data().effectTargetId ); + pFlag = reinterpret_cast< uint16_t* >( &p->data().unkFlag ); effectPacket = std::move( p ); break; } case 32: { auto p = makeZonePacket< Server::FFXIVIpcAoeEffect32 >( m_sourceChara->getId() ); - pHeader = ( EffectHeader* )( &( p->data() ) ); - pEntry = ( Common::EffectEntry* )( &( p->data().effects ) ); - pEffectTargetId = ( uint64_t* )( &( p->data().effectTargetId ) ); - pFlag = ( uint16_t* )( &( p->data().unkFlag ) ); + pHeader = reinterpret_cast< EffectHeader* >( &p->data() ); + pEntry = reinterpret_cast< Common::EffectEntry* >( &p->data().effects ); + pEffectTargetId = reinterpret_cast< uint64_t* >( &p->data().effectTargetId ); + pFlag = reinterpret_cast< uint16_t* >( &p->data().unkFlag ); effectPacket = std::move( p ); break; } @@ -228,7 +218,7 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( uint32_ else { auto resultList = m_resolvedEffects.begin()->second; - assert( resultList->size() > 0 ); + assert( !resultList->empty() ); auto firstResult = resultList->data()[ 0 ]; Logger::debug( " - id: {}", firstResult->getTarget()->getId() ); diff --git a/src/world/Action/EffectBuilder.h b/src/world/Action/EffectBuilder.h index a4699bb6..b2a76221 100644 --- a/src/world/Action/EffectBuilder.h +++ b/src/world/Action/EffectBuilder.h @@ -11,21 +11,20 @@ namespace Sapphire::World::Action public: EffectBuilder( Entity::CharaPtr source, uint32_t actionId, uint16_t sequence ); + void heal( Entity::CharaPtr& effectTarget, Entity::CharaPtr& healingTarget, uint32_t amount, + Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalHeal, + Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None); - void healTarget( Entity::CharaPtr& target, uint32_t amount, - Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalHeal ); + void restoreMP( Entity::CharaPtr& effectTarget, Entity::CharaPtr& restoringTarget, uint32_t amount, + Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None); - void selfHeal( Entity::CharaPtr& target, Entity::CharaPtr& source, uint32_t amount, - Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalHeal ); - - void restoreMP( Entity::CharaPtr& target, Entity::CharaPtr& source, uint32_t amount ); - - void damageTarget( Entity::CharaPtr& target, uint32_t amount, - Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalDamage ); + void damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, + Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalDamage, + Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None); void startCombo( Entity::CharaPtr& target, uint16_t actionId ); - void comboVisualEffect( Entity::CharaPtr& target ); + void comboSucceed( Entity::CharaPtr& target ); void buildAndSendPackets(); diff --git a/src/world/Action/EffectResult.cpp b/src/world/Action/EffectResult.cpp index 8f5782ce..85684496 100644 --- a/src/world/Action/EffectResult.cpp +++ b/src/world/Action/EffectResult.cpp @@ -15,7 +15,7 @@ EffectResult::EffectResult( Entity::CharaPtr target, uint64_t runAfter ) : m_severity( Common::ActionHitSeverityType::NormalDamage ), m_type( Common::ActionEffectType::Nothing ), m_param( 0 ), - m_flag( 0 ) + m_flag( Common::ActionEffectResultFlag::None ) { } @@ -40,27 +40,28 @@ void EffectResult::setParam( uint8_t param ) m_param = param; } -void EffectResult::damage( uint32_t amount, Common::ActionHitSeverityType severity ) +void EffectResult::damage( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag ) { m_severity = severity; m_value = amount; + m_flag = flag; m_type = Common::ActionEffectType::Damage; } -void EffectResult::heal( uint32_t amount, Sapphire::Common::ActionHitSeverityType severity, bool isSelfHeal ) +void EffectResult::heal( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag ) { m_severity = severity; m_value = amount; - m_flag = isSelfHeal ? 0x80 : 0; // flag == 0x80 displays healing text at source actor + m_flag = flag; m_type = Common::ActionEffectType::Heal; } -void EffectResult::restoreMP( uint32_t amount ) +void EffectResult::restoreMP( uint32_t amount, Common::ActionEffectResultFlag flag ) { m_value = amount; - m_flag = 0x80; + m_flag = flag; m_type = Common::ActionEffectType::MpGain; } @@ -68,14 +69,15 @@ void EffectResult::restoreMP( uint32_t amount ) void EffectResult::startCombo( uint16_t actionId ) { m_value = actionId; - m_flag = 0x80; + m_flag = Common::ActionEffectResultFlag::EffectOnSource; m_type = Common::ActionEffectType::StartActionCombo; } -void EffectResult::comboVisualEffect() +void EffectResult::comboSucceed() { - m_type = Common::ActionEffectType::ComboVisualEffect; + // no EffectOnSource flag on this + m_type = Common::ActionEffectType::ComboSucceed; } Common::EffectEntry EffectResult::buildEffectEntry() const @@ -87,7 +89,7 @@ Common::EffectEntry EffectResult::buildEffectEntry() const entry.hitSeverity = m_severity; entry.effectType = m_type; entry.param = m_param; - entry.flags = m_flag; + entry.flags = static_cast< uint8_t >( m_flag ); return entry; } diff --git a/src/world/Action/EffectResult.h b/src/world/Action/EffectResult.h index 3a93d13b..c3f642b3 100644 --- a/src/world/Action/EffectResult.h +++ b/src/world/Action/EffectResult.h @@ -15,11 +15,11 @@ namespace Sapphire::World::Action 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, bool isSelfHeal ); - void restoreMP( uint32_t amount ); + void damage( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None ); + void heal( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None ); + void restoreMP( uint32_t amount, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None ); void startCombo( uint16_t actionId ); - void comboVisualEffect(); + void comboSucceed(); Entity::CharaPtr getTarget() const; @@ -43,7 +43,7 @@ namespace Sapphire::World::Action uint32_t m_value; uint8_t m_param; - uint8_t m_flag; + Common::ActionEffectResultFlag m_flag; }; } diff --git a/src/world/Actor/Player.cpp b/src/world/Actor/Player.cpp index 4a6ab8d8..a6856127 100644 --- a/src/world/Actor/Player.cpp +++ b/src/world/Actor/Player.cpp @@ -2140,8 +2140,7 @@ bool Sapphire::Entity::Player::hasQueuedAction() const void Sapphire::Entity::Player::setQueuedAction( Sapphire::World::Action::ActionPtr pAction ) { - m_pQueuedAction = nullptr; // overwrite whatever is already there - m_pQueuedAction = std::move( pAction ); + m_pQueuedAction = std::move( pAction ); // overwrite previous queued action if any } bool Sapphire::Entity::Player::checkAction() diff --git a/src/world/Network/PacketWrappers/EffectPacket.h b/src/world/Network/PacketWrappers/EffectPacket.h index 2306b066..cb062f3f 100644 --- a/src/world/Network/PacketWrappers/EffectPacket.h +++ b/src/world/Network/PacketWrappers/EffectPacket.h @@ -26,7 +26,7 @@ namespace Sapphire::Network::Packets::Server m_data.effectDisplayType = Common::ActionEffectDisplayType::ShowActionName; - std::memset( m_data.effects, 0, sizeof(Common::EffectEntry) * 8 ); + std::memset( m_data.effects, 0, sizeof( Common::EffectEntry ) * 8 ); } void addEffect( const Common::EffectEntry& effect ) From 5cbff4f12b9452a05643bcfcf99694145959756e Mon Sep 17 00:00:00 2001 From: collett Date: Sun, 5 Jan 2020 20:54:49 +0900 Subject: [PATCH 4/8] more clean up --- src/world/Action/EffectBuilder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/Action/EffectBuilder.cpp b/src/world/Action/EffectBuilder.cpp index c7c231f0..3ab3e0dd 100644 --- a/src/world/Action/EffectBuilder.cpp +++ b/src/world/Action/EffectBuilder.cpp @@ -105,7 +105,7 @@ void EffectBuilder::buildAndSendPackets() auto globalSequence = m_sourceChara->getCurrentTerritory()->getNextEffectSequence(); - while( m_resolvedEffects.size() > 0 ) + while( !m_resolvedEffects.empty() ) { auto packet = buildNextEffectPacket( globalSequence ); m_sourceChara->sendToInRangeSet( packet, true ); @@ -188,7 +188,7 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( uint32_ for( auto it = m_resolvedEffects.begin(); it != m_resolvedEffects.end(); ) { auto resultList = it->second; - assert( resultList->size() > 0 ); + assert( !resultList->empty() ); auto firstResult = resultList->data()[ 0 ]; pEffectTargetId[ targetIndex ] = firstResult->getTarget()->getId(); Logger::debug( " - id: {}", pEffectTargetId[ targetIndex ] ); From 4b89c457906b53a68dc006532fc96cb67d953195 Mon Sep 17 00:00:00 2001 From: collett Date: Sun, 5 Jan 2020 21:31:54 +0900 Subject: [PATCH 5/8] local var rename --- src/world/Action/Action.cpp | 6 +++--- src/world/Action/EffectBuilder.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index 60900a53..20ce9ab8 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -461,7 +461,7 @@ void Action::Action::buildEffects() // when aoe, these effects are in the target whatever is hit first bool shouldRestoreMP = true; - bool shouldShowComboEffect = true; + bool shouldApplyComboSucceedEffect = true; for( auto& actor : m_hitActors ) { @@ -473,10 +473,10 @@ void Action::Action::buildEffects() if( dmg.first > 0 ) actor->onActionHostile( m_pSource ); - if( isCorrectCombo() && shouldShowComboEffect ) + if( isCorrectCombo() && shouldApplyComboSucceedEffect ) { m_effectBuilder->comboSucceed( actor ); - shouldShowComboEffect = false; + shouldApplyComboSucceedEffect = false; } if( !isComboAction() || isCorrectCombo() ) diff --git a/src/world/Action/EffectBuilder.cpp b/src/world/Action/EffectBuilder.cpp index 3ab3e0dd..761af0e3 100644 --- a/src/world/Action/EffectBuilder.cpp +++ b/src/world/Action/EffectBuilder.cpp @@ -172,7 +172,7 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( uint32_ break; } } - assert( effectPacket != nullptr ); + assert( effectPacket ); pHeader->actionId = m_actionId; pHeader->actionAnimationId = static_cast< uint16_t >( m_actionId ); From c319cb012c59b71f3633a9eb7e2e900ee22a81d2 Mon Sep 17 00:00:00 2001 From: collett Date: Mon, 6 Jan 2020 00:25:42 +0900 Subject: [PATCH 6/8] combo fix --- src/world/Action/Action.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index 20ce9ab8..6c13d8cb 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -393,8 +393,8 @@ void Action::Action::execute() // ignore it otherwise (ogcds, etc.) if( !m_actionData->preservesCombo ) { - // potential combo starter or correct combo from last action - if( ( !isComboAction() || isCorrectCombo() ) ) + // potential combo starter or correct combo from last action, must hit something to progress combo + if( !m_hitActors.empty() && ( !isComboAction() || isCorrectCombo() ) ) { m_pSource->setLastComboActionId( getId() ); } From e6c3e327f7cf4d6d0c8cb2b3c54b6c6de717c85a Mon Sep 17 00:00:00 2001 From: collett Date: Mon, 6 Jan 2020 04:29:45 +0900 Subject: [PATCH 7/8] Fix skill animation for other players. --- src/world/Action/Action.cpp | 20 +++++++++----------- src/world/Action/EffectBuilder.cpp | 25 ++++++++++++++++++++----- 2 files changed, 29 insertions(+), 16 deletions(-) diff --git a/src/world/Action/Action.cpp b/src/world/Action/Action.cpp index 6c13d8cb..4e456c5d 100644 --- a/src/world/Action/Action.cpp +++ b/src/world/Action/Action.cpp @@ -751,20 +751,18 @@ bool Action::Action::preFilterActor( Sapphire::Entity::Actor& actor ) const // todo: are there any server side eobjs that players can hit? if( kind != ObjKind::BattleNpc && kind != ObjKind::Player ) return false; - - if( m_lutEntry.potency > 0 && chara->getId() == m_pSource->getId() ) - { - // damage action shouldn't hit self + + if( !m_canTargetSelf && chara->getId() == m_pSource->getId() ) return false; - } - - if( ( m_lutEntry.potency > 0 || m_lutEntry.curePotency > 0 ) && !chara->isAlive() ) - { - // can't deal damage or heal a dead entity + + if( ( m_lutEntry.potency > 0 || m_lutEntry.curePotency > 0 ) && !chara->isAlive() ) // !m_canTargetDead not working for aoe return false; - } - // todo: handle things such based on canTargetX + if( m_lutEntry.potency > 0 && m_pSource->getObjKind() == chara->getObjKind() ) // !m_canTargetFriendly not working for aoe + return false; + + if( ( m_lutEntry.potency == 0 && m_lutEntry.curePotency > 0 ) && m_pSource->getObjKind() != chara->getObjKind() ) // !m_canTargetHostile not working for aoe + return false; return true; } diff --git a/src/world/Action/EffectBuilder.cpp b/src/world/Action/EffectBuilder.cpp index 761af0e3..a27ec2e6 100644 --- a/src/world/Action/EffectBuilder.cpp +++ b/src/world/Action/EffectBuilder.cpp @@ -105,11 +105,12 @@ void EffectBuilder::buildAndSendPackets() auto globalSequence = m_sourceChara->getCurrentTerritory()->getNextEffectSequence(); - while( !m_resolvedEffects.empty() ) + do // we want to send at least one packet even nothing is hit so other players can see { auto packet = buildNextEffectPacket( globalSequence ); m_sourceChara->sendToInRangeSet( packet, true ); } + while( !m_resolvedEffects.empty() ); } std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( uint32_t globalSequence ) @@ -118,9 +119,7 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( uint32_ if( remainingTargetCount > 1 ) // use AoeEffect packets { - int packetSize = remainingTargetCount <= 8 ? 8 : - ( remainingTargetCount <= 16 ? 16 : - ( remainingTargetCount <= 24 ? 24 : 32 ) ); + int packetSize = remainingTargetCount <= 8 ? 8 : ( remainingTargetCount <= 16 ? 16 : ( remainingTargetCount <= 24 ? 24 : 32 ) ); using EffectHeader = Server::FFXIVIpcAoeEffect< 8 >; // dummy type to access header part of the packet @@ -215,7 +214,7 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( uint32_ return effectPacket; } - else + else if ( remainingTargetCount == 1 ) // use Effect for single target { auto resultList = m_resolvedEffects.begin()->second; assert( !resultList->empty() ); @@ -239,6 +238,22 @@ std::shared_ptr< FFXIVPacketBase > EffectBuilder::buildNextEffectPacket( uint32_ m_resolvedEffects.clear(); + return effectPacket; + } + else // nothing is hit, this only happens when using aoe and AoeEffect8 is used on retail + { + auto effectPacket = makeZonePacket< Server::FFXIVIpcAoeEffect8 >( m_sourceChara->getId() ); + + effectPacket->data().actionId = m_actionId; + effectPacket->data().actionAnimationId = static_cast< uint16_t >( m_actionId ); + effectPacket->data().animationTargetId = m_sourceChara->getId(); + effectPacket->data().someTargetId = 0xE0000000; + effectPacket->data().rotation = Common::Util::floatToUInt16Rot( m_sourceChara->getRot() ); + effectPacket->data().effectDisplayType = Common::ActionEffectDisplayType::HideActionName; + effectPacket->data().effectCount = 0; + effectPacket->data().sourceSequence = m_sequence; + effectPacket->data().globalSequence = globalSequence; + return effectPacket; } } \ No newline at end of file From 26f23a1147b15da756ecdaccb699352e9dc4ed11 Mon Sep 17 00:00:00 2001 From: collett Date: Mon, 6 Jan 2020 17:52:45 +0900 Subject: [PATCH 8/8] no need to return the list --- src/world/Action/EffectBuilder.cpp | 35 ++++++++++-------------------- src/world/Action/EffectBuilder.h | 2 +- 2 files changed, 12 insertions(+), 25 deletions(-) diff --git a/src/world/Action/EffectBuilder.cpp b/src/world/Action/EffectBuilder.cpp index a27ec2e6..23765c27 100644 --- a/src/world/Action/EffectBuilder.cpp +++ b/src/world/Action/EffectBuilder.cpp @@ -31,70 +31,57 @@ uint64_t EffectBuilder::getResultDelayMs() return Common::Util::getTimeMs() + 850; } -std::shared_ptr< std::vector< EffectResultPtr > > EffectBuilder::getResultList( Entity::CharaPtr& chara ) +void EffectBuilder::moveToResultList( Entity::CharaPtr& chara, EffectResultPtr result ) { auto it = m_resolvedEffects.find( chara->getId() ); if( it == m_resolvedEffects.end() ) { - // create a new one and return it + // create a new one auto resultList = std::make_shared< std::vector< EffectResultPtr > >(); m_resolvedEffects[ chara->getId() ] = resultList; - return resultList; + resultList->push_back( std::move( result ) ); + + return; } - return it->second; + it->second->push_back( std::move( result ) ); } void EffectBuilder::heal( Entity::CharaPtr& effectTarget, Entity::CharaPtr& healingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag ) { - auto resultList = getResultList( effectTarget ); - assert( resultList ); - EffectResultPtr nextResult = make_EffectResult( healingTarget, getResultDelayMs() ); nextResult->heal( amount, severity, flag ); - resultList->push_back( std::move( nextResult ) ); + moveToResultList( effectTarget, nextResult ); } void EffectBuilder::restoreMP( Entity::CharaPtr& target, Entity::CharaPtr& restoringTarget, uint32_t amount, Common::ActionEffectResultFlag flag ) { - auto resultList = getResultList( target ); - assert( resultList ); - EffectResultPtr nextResult = make_EffectResult( restoringTarget, getResultDelayMs() ); // restore mp source actor nextResult->restoreMP( amount, flag ); - resultList->push_back( std::move( nextResult ) ); + moveToResultList( target, nextResult ); } void EffectBuilder::damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag ) { - auto resultList = getResultList( effectTarget ); - assert( resultList ); - EffectResultPtr nextResult = make_EffectResult( damagingTarget, getResultDelayMs() ); nextResult->damage( amount, severity, flag ); - resultList->push_back( std::move( nextResult ) ); + moveToResultList( effectTarget, nextResult ); } void EffectBuilder::startCombo( Entity::CharaPtr& target, uint16_t actionId ) { - auto resultList = getResultList( target ); - assert( resultList ); - EffectResultPtr nextResult = make_EffectResult( target, 0 ); nextResult->startCombo( actionId ); - resultList->push_back( std::move( nextResult ) ); + moveToResultList( target, nextResult ); } void EffectBuilder::comboSucceed( Entity::CharaPtr& target ) { - auto resultList = getResultList( target ); - assert( resultList ); - EffectResultPtr nextResult = make_EffectResult( target, 0 ); nextResult->comboSucceed(); - resultList->push_back( std::move( nextResult ) ); + moveToResultList( target, nextResult ); } void EffectBuilder::buildAndSendPackets() diff --git a/src/world/Action/EffectBuilder.h b/src/world/Action/EffectBuilder.h index b2a76221..dda471e2 100644 --- a/src/world/Action/EffectBuilder.h +++ b/src/world/Action/EffectBuilder.h @@ -30,7 +30,7 @@ namespace Sapphire::World::Action private: - std::shared_ptr< std::vector< EffectResultPtr > > getResultList( Entity::CharaPtr& chara ); + void moveToResultList( Entity::CharaPtr& chara, EffectResultPtr result ); uint64_t getResultDelayMs();