From 67a5717541f70f8c2cecb4929347b894764176f3 Mon Sep 17 00:00:00 2001 From: Maru Date: Sun, 24 Sep 2017 21:02:29 -0300 Subject: [PATCH 01/29] AoE refactor; --- scripts/chai/global.inc | 9 ++- src/servers/Server_Common/Common.h | 25 ++++--- src/servers/Server_Zone/Actor/CalcBattle.cpp | 5 +- src/servers/Server_Zone/Actor/Player.cpp | 68 ++++++++----------- .../StatusEffect/StatusEffectContainer.cpp | 4 +- 5 files changed, 52 insertions(+), 59 deletions(-) diff --git a/scripts/chai/global.inc b/scripts/chai/global.inc index 48bdbe32..906a3a0b 100644 --- a/scripts/chai/global.inc +++ b/scripts/chai/global.inc @@ -228,6 +228,9 @@ global CURRENCY_TOMESTONELORE = 0X0E //////////////////////////////////////////////////////////// // Skill handle types //////////////////////////////////////////////////////////// -global STD_DAMAGE = 0X00 -global STD_HEAL = 0X01 -global STD_DOT = 0X02 \ No newline at end of file +global STD_DAMAGE = 0X03 +global STD_HEAL = 0X04 +global STD_MP_LOSS = 0X0A +global STD_MP_GAIN = 0X0B +global STD_TP_LOSS = 0X0C +global STD_TP_GAIN = 0X0D \ No newline at end of file diff --git a/src/servers/Server_Common/Common.h b/src/servers/Server_Common/Common.h index 752eb711..84c7125d 100644 --- a/src/servers/Server_Common/Common.h +++ b/src/servers/Server_Common/Common.h @@ -548,7 +548,7 @@ namespace Core { Unaspected = 7 // Doesn't imply magical unaspected damage - could be unaspected physical }; - enum struct ActionType : int8_t + enum class ActionType : int8_t { WeaponOverride = -1, // Needs more investigation (takes the damage type of the equipped weapon)? Unknown_0 = 0, @@ -562,7 +562,7 @@ namespace Core { LimitBreak = 8, }; - enum ActionEffectType : uint8_t + enum class ActionEffectType : uint8_t { Nothing = 0, Miss = 1, @@ -581,7 +581,7 @@ namespace Core { GpGain = 14 }; - enum ActionHitSeverityType : uint8_t + enum class ActionHitSeverityType : uint8_t { NormalDamage = 0, CritHeal = 0, @@ -591,6 +591,18 @@ namespace Core { CritDirectHitDamage = 3 }; + enum class AoeType + { + None, + SingleTarget, + TargetCircle, + Cone, + Line, + Unknown, + Unknown2, + GroundCircle, // for when you set aoe like asylum + }; + enum HandleActionType : uint8_t { Event, @@ -598,13 +610,6 @@ namespace Core { Teleport }; - enum HandleSkillType : uint8_t - { - StdDamage, - StdHeal, - StdDot, - }; - enum struct PlayerStateFlag : uint8_t { NoCombat, diff --git a/src/servers/Server_Zone/Actor/CalcBattle.cpp b/src/servers/Server_Zone/Actor/CalcBattle.cpp index f33c2e5c..9195412e 100644 --- a/src/servers/Server_Zone/Actor/CalcBattle.cpp +++ b/src/servers/Server_Zone/Actor/CalcBattle.cpp @@ -44,9 +44,6 @@ float CalcBattle::calculateBaseStat( PlayerPtr pPlayer ) base = 1.63f * level + 121.02f; // ARR Base Stat Formula (Off by one in several cases) else - // Old: base = 0.053f * ( level * level ) + ( 1.022f * level ) - 0.907f + 20; - // V1: base = 0.0523f * ( level * level ) + ( 1.04f * level ) + 19.405f; - // V2: base = 0.05223f * ( level * level ) + ( 1.0405f * level ) + 19.405f; base = 0.052602f * ( level * level ) + ( 1.0179f * level ) + 19.6f; return base; @@ -83,7 +80,7 @@ uint32_t CalcBattle::calculateMaxHp( PlayerPtr pPlayer ) else if ( level >= 50 ) approxBaseHp = 1700 + ( ( level - 50 ) * ( 1700 * 1.04325f ) ); else - approxBaseHp = paramGrowthInfoIt->second.mp_const * 0.7596f; + approxBaseHp = paramGrowthInfoIt->second.mp_const * 0.7667f; uint16_t result = static_cast< uint16_t >( floor( jobModHp * ( approxBaseHp / 100.0f ) ) + floor( hpMod / 100.0f * ( vitStat - baseStat ) ) ); diff --git a/src/servers/Server_Zone/Actor/Player.cpp b/src/servers/Server_Zone/Actor/Player.cpp index 49bc2ad3..d91be9bb 100644 --- a/src/servers/Server_Zone/Actor/Player.cpp +++ b/src/servers/Server_Zone/Actor/Player.cpp @@ -1518,30 +1518,35 @@ void Core::Entity::Player::handleScriptSkill( uint32_t type, uint32_t actionId, { sendDebug( std::to_string( pTarget.getId() ) ); sendDebug( "Handle script skill type: " + std::to_string( type ) ); - + auto actionInfoPtr = g_exdData.getActionInfo( actionId ); + sendDebug( actionInfoPtr->name ); + if ( actionInfoPtr->is_aoe ) + sendDebug( "is aoe: " + std::to_string( actionInfoPtr->is_aoe ) ); - switch( type ) + GamePacketNew< FFXIVIpcEffect, ServerZoneIpcType > effectPacket( getId() ); + effectPacket.data().targetId = pTarget.getId(); + effectPacket.data().actionAnimationId = actionId; + effectPacket.data().unknown_2 = 1; // This seems to have an effect on the "double-cast finish" animation + // effectPacket.data().unknown_3 = 1; + effectPacket.data().actionTextId = actionId; + effectPacket.data().numEffects = 1; + effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() ); + effectPacket.data().effectTarget = pTarget.getId(); + effectPacket.data().effects[0].value = 0; + effectPacket.data().effects[0].effectType = static_cast < ActionEffectType >( type ); + effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalDamage; + effectPacket.data().effects[0].unknown_3 = 7; + + switch ( type ) { - case Core::Common::HandleSkillType::StdDamage: + case 3: { sendDebug( "STD_DAMAGE" ); - GamePacketNew< FFXIVIpcEffect, ServerZoneIpcType > effectPacket( getId() ); - effectPacket.data().targetId = pTarget.getId(); - effectPacket.data().actionAnimationId = actionId; - effectPacket.data().unknown_2 = 1; // This seems to have an effect on the "double-cast finish" animation - // effectPacket.data().unknown_3 = 1; - effectPacket.data().actionTextId = actionId; - effectPacket.data().numEffects = 1; - effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() ); - effectPacket.data().effectTarget = pTarget.getId(); effectPacket.data().effects[0].value = static_cast< int16_t >( param1 ); - effectPacket.data().effects[0].effectType = ActionEffectType::Damage; - effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalDamage; - effectPacket.data().effects[0].unknown_3 = 7; sendToInRangeSet( effectPacket, true ); @@ -1553,25 +1558,15 @@ void Core::Entity::Player::handleScriptSkill( uint32_t type, uint32_t actionId, break; } - case Core::Common::HandleSkillType::StdHeal: + case 4: { uint32_t calculatedHeal = CalcBattle::calculateHealValue( getAsPlayer(), static_cast< uint32_t >( param1 ) ); - sendDebug( "STD_HEAL" ); - - GamePacketNew< FFXIVIpcEffect, ServerZoneIpcType > effectPacket( getId() ); - effectPacket.data().targetId = pTarget.getId(); - effectPacket.data().actionAnimationId = actionId; - effectPacket.data().unknown_2 = 1; // This seems to have an effect on the "double-cast finish" animation - // effectPacket.data().unknown_3 = 1; - effectPacket.data().actionTextId = actionId; - effectPacket.data().numEffects = 1; - effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() ); - effectPacket.data().effectTarget = pTarget.getId(); - effectPacket.data().effects[0].value = calculatedHeal; + effectPacket.data().effects[0].value = static_cast< int16_t >( calculatedHeal ); effectPacket.data().effects[0].effectType = ActionEffectType::Heal; effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalHeal; - effectPacket.data().effects[0].unknown_3 = 7; + + sendDebug( "STD_HEAL" ); sendToInRangeSet( effectPacket, true ); @@ -1580,9 +1575,10 @@ void Core::Entity::Player::handleScriptSkill( uint32_t type, uint32_t actionId, // todo: get proper packets: the following was just kind of thrown together from what we know // also toss AoE to another spot and make it generic - - if ( actionInfoPtr->is_aoe ) + sendDebug( actionInfoPtr->name ); + if ( actionInfoPtr->is_aoe ) { + sendDebug( "IS AOE LOL" ); for ( auto pCurAct : m_inRangePlayers ) { assert( pCurAct ); @@ -1591,20 +1587,12 @@ void Core::Entity::Player::handleScriptSkill( uint32_t type, uint32_t actionId, if ( Math::Util::distance( pTarget.getPos().x, pTarget.getPos().y, pTarget.getPos().z, pCurAct->getPos().x, pCurAct->getPos().y, pCurAct->getPos().z ) <= actionInfoPtr->radius ) { - GamePacketNew< FFXIVIpcEffect, ServerZoneIpcType > effectPacket( pCurAct->getId() ); effectPacket.data().targetId = pCurAct->getId(); effectPacket.data().unknown_1 = 1; // the magic trick for getting it to work - effectPacket.data().unknown_2 = 1; effectPacket.data().unknown_8 = 1; effectPacket.data().unknown_5 = 1; - effectPacket.data().actionAnimationId = actionId; effectPacket.data().actionTextId = 0; - effectPacket.data().numEffects = 1; effectPacket.data().effectTarget = pCurAct->getId(); - effectPacket.data().effects[0].value = calculatedHeal; - effectPacket.data().effects[0].effectType = ActionEffectType::Heal; - effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalHeal; - effectPacket.data().effects[0].unknown_3 = 7; pCurAct->sendToInRangeSet( effectPacket, true ); pCurAct->heal( calculatedHeal ); @@ -1618,7 +1606,7 @@ void Core::Entity::Player::handleScriptSkill( uint32_t type, uint32_t actionId, } default: - break; + break; } } diff --git a/src/servers/Server_Zone/StatusEffect/StatusEffectContainer.cpp b/src/servers/Server_Zone/StatusEffect/StatusEffectContainer.cpp index e842d0dc..c473aa54 100644 --- a/src/servers/Server_Zone/StatusEffect/StatusEffectContainer.cpp +++ b/src/servers/Server_Zone/StatusEffect/StatusEffectContainer.cpp @@ -194,13 +194,13 @@ void Core::StatusEffect::StatusEffectContainer::update() if( thisTickDmg != 0 ) { m_pOwner->takeDamage( thisTickDmg ); - m_pOwner->sendToInRangeSet( ActorControlPacket142( m_pOwner->getId(), HPFloatingText, 0, 3, thisTickDmg ) ); + m_pOwner->sendToInRangeSet( ActorControlPacket142( m_pOwner->getId(), HPFloatingText, 0, static_cast< uint8_t >( ActionEffectType::Damage ), thisTickDmg ) ); } if( thisTickHeal != 0 ) { m_pOwner->heal( thisTickDmg ); - m_pOwner->sendToInRangeSet( ActorControlPacket142( m_pOwner->getId(), HPFloatingText, 0, 4, thisTickHeal ) ); + m_pOwner->sendToInRangeSet( ActorControlPacket142( m_pOwner->getId(), HPFloatingText, 0, static_cast< uint8_t >( ActionEffectType::Heal ), thisTickHeal ) ); } } From 60a5dcd279aeb0b504064dbf5e82720e5634e1b7 Mon Sep 17 00:00:00 2001 From: amibu Date: Mon, 25 Sep 2017 18:05:33 +0200 Subject: [PATCH 02/29] Moved byte bool code into exd parser --- src/servers/Server_Common/Exd/ExdData.cpp | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/servers/Server_Common/Exd/ExdData.cpp b/src/servers/Server_Common/Exd/ExdData.cpp index 0c5fd98f..edb12add 100644 --- a/src/servers/Server_Common/Exd/ExdData.cpp +++ b/src/servers/Server_Common/Exd/ExdData.cpp @@ -344,21 +344,13 @@ bool Core::Data::ExdData::loadActionInfo() uint8_t points_type = getField< uint8_t >( fields, 30 ); // 30 uint16_t points_cost = getField< uint16_t >( fields, 31 ); // 31 - uint32_t instantval = getField< bool >( fields, 35 ); // 35 + bool is_instant = getField< bool >( fields, 35 ); // 35 uint16_t cast_time = getField< uint16_t >( fields, 36 ); // 36 uint16_t recast_time = getField< uint16_t >( fields, 37 ); // 37 int8_t model = getField< int8_t >( fields, 39 ); // 39: Action model uint8_t aspect = getField< uint8_t >( fields, 40 ); // 40: Action aspect - uint8_t typeshift = 0x6; - uint8_t mask = 1 << typeshift; - instantval &= mask; - bool final = ( instantval & mask ) == mask; - bool is_instant = final; - - - info->id = id; info->name = name; info->category = category; From 81a1c62212e8c05c655a96ecefa8650de609d71c Mon Sep 17 00:00:00 2001 From: amibu Date: Mon, 25 Sep 2017 18:06:17 +0200 Subject: [PATCH 03/29] Add compile time to !info --- .../DebugCommand/DebugCommandHandler.cpp | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp b/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp index 6a4f6e84..b3137453 100644 --- a/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp +++ b/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp @@ -239,25 +239,6 @@ void Core::DebugCommandHandler::set( char * data, Core::Entity::PlayerPtr pPlaye else pPlayer->setClassJob( static_cast ( id ) ); } - else if( subCommand == "no" ) - { - int32_t id; - - sscanf( params.c_str(), "%d", &id ); - - uint8_t typeshift = 0x6; - uint8_t mask = 1 << typeshift; - id &= mask; - bool final = ( id & mask ) == mask; - pPlayer->sendDebug( std::to_string(final) ); - } - else if( subCommand == "aaah" ) - { - int32_t id; - sscanf( params.c_str(), "%d", &id ); - - pPlayer->sendDebug( std::to_string( pPlayer->actionHasCastTime( id ) ) ); - } else if ( subCommand == "cfpenalty" ) { int32_t minutes; @@ -486,6 +467,7 @@ void Core::DebugCommandHandler::nudge( char * data, Entity::PlayerPtr pPlayer, b void Core::DebugCommandHandler::serverInfo( char * data, Core::Entity::PlayerPtr pPlayer, boost::shared_ptr< Core::DebugCommand > command ) { - pPlayer->sendDebug( "SapphireServer " + Version::VERSION + " - " + Version::GIT_HASH ); + pPlayer->sendDebug( "SapphireServer " + Version::VERSION + "\nRev: " + Version::GIT_HASH ); + pPlayer->sendDebug( "Compiled: " __DATE__ " " __TIME__ ); pPlayer->sendDebug( "Sessions: " + std::to_string( g_serverZone.getSessionCount() ) ); } From ee83faae73c9b5c03af671f924beada7f8a8d938 Mon Sep 17 00:00:00 2001 From: amibu Date: Mon, 25 Sep 2017 18:27:08 +0200 Subject: [PATCH 04/29] updated libraries --- src/libraries | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries b/src/libraries index 4e08821a..f24f9418 160000 --- a/src/libraries +++ b/src/libraries @@ -1 +1 @@ -Subproject commit 4e08821a45adbff969f6c4863bbe156d4229ffda +Subproject commit f24f9418a993c8359be74fbaf6e13bbabe21c99b From 64a9f4ed1e2e8f1785a9476efe99ac0a0f32029f Mon Sep 17 00:00:00 2001 From: Biscuit Boy Date: Wed, 27 Sep 2017 04:12:08 +1000 Subject: [PATCH 05/29] Added Some TerritoryIntendedUseTypes Added Some Territory Intended Use Types TODO: Add The Rest of The Territory Types and Have Better Names For Them --- src/servers/Server_Common/Common.h | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/servers/Server_Common/Common.h b/src/servers/Server_Common/Common.h index 752eb711..bdaf72c1 100644 --- a/src/servers/Server_Common/Common.h +++ b/src/servers/Server_Common/Common.h @@ -383,6 +383,29 @@ namespace Core { instance, }; + enum TerritoryIntendedUseType : uint8_t //ToDo: Add The Rest of The Territory Types and Have Better Names For Them + { + Town = 0, + OpenWorld = 1, + Inn = 2, + Dungeon = 3, + JailArea = 5, + Opening = 6, + BeforeTrialDung = 7, + AllianceRaid = 8, + OpenWorldInstanceBattle = 9, + Trial = 10, + HousingArea = 13, + HousingPrivateArea = 14, + MSQPrivateArea = 15, + Raids = 16, + RaidFights = 17, + ChocoboTutorial = 21, + Wedding = 22, + BeginnerTutorial = 27, + PalaceOfTheDead = 31, + }; + enum CharaLook : uint8_t { Race = 0x00, From adf0e1d61752d22047a908fba3a2c201c2614352 Mon Sep 17 00:00:00 2001 From: Biscuit Boy Date: Wed, 27 Sep 2017 04:29:48 +1000 Subject: [PATCH 06/29] Should of Fixed Build Changed Opening in TerritoryIntendedUseType to OpeningArea --- src/servers/Server_Common/Common.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/servers/Server_Common/Common.h b/src/servers/Server_Common/Common.h index bdaf72c1..15b0ccc6 100644 --- a/src/servers/Server_Common/Common.h +++ b/src/servers/Server_Common/Common.h @@ -390,7 +390,7 @@ namespace Core { Inn = 2, Dungeon = 3, JailArea = 5, - Opening = 6, + OpeningArea = 6, BeforeTrialDung = 7, AllianceRaid = 8, OpenWorldInstanceBattle = 9, From 64caa88872c7264073cf5b2236de8cfa3d3227dd Mon Sep 17 00:00:00 2001 From: Maru Date: Wed, 27 Sep 2017 04:31:41 -0300 Subject: [PATCH 07/29] Action Collision class (AoE, filtering); Refactoring script handler; Sorted action field + aoe_width property; --- scripts/chai/skill/thm/skillDef_147.chai | 18 +++ src/libraries | 2 +- src/servers/Server_Common/Common.h | 11 +- src/servers/Server_Common/Exd/ExdData.cpp | 89 ++++++------ src/servers/Server_Common/Exd/ExdData.h | 5 +- .../Server_Zone/Action/ActionCollision.cpp | 133 ++++++++++++++++++ .../Server_Zone/Action/ActionCollision.h | 37 +++++ src/servers/Server_Zone/Actor/Actor.cpp | 110 +++++++++++++++ src/servers/Server_Zone/Actor/Actor.h | 2 + src/servers/Server_Zone/Actor/CalcBattle.cpp | 1 + src/servers/Server_Zone/Actor/CalcBattle.h | 4 +- src/servers/Server_Zone/Actor/Player.cpp | 102 +------------- src/servers/Server_Zone/Actor/Player.h | 2 - src/servers/Server_Zone/ServerZone.cpp | 4 +- 14 files changed, 361 insertions(+), 159 deletions(-) create mode 100644 scripts/chai/skill/thm/skillDef_147.chai create mode 100644 src/servers/Server_Zone/Action/ActionCollision.cpp create mode 100644 src/servers/Server_Zone/Action/ActionCollision.h diff --git a/scripts/chai/skill/thm/skillDef_147.chai b/scripts/chai/skill/thm/skillDef_147.chai new file mode 100644 index 00000000..e36950a1 --- /dev/null +++ b/scripts/chai/skill/thm/skillDef_147.chai @@ -0,0 +1,18 @@ +// Skill Name: Fire II +// Skill ID: 147 + +class skillDef_147Def +{ + def skillDef_147Def() + { + + } + + def onFinish( player, target ) + { + player.handleScriptSkill( STD_DAMAGE, 147, 80, 0, target ); + } + +}; + +GLOBAL skillDef_147 = skillDef_147Def(); \ No newline at end of file diff --git a/src/libraries b/src/libraries index 4e08821a..376501b8 160000 --- a/src/libraries +++ b/src/libraries @@ -1 +1 @@ -Subproject commit 4e08821a45adbff969f6c4863bbe156d4229ffda +Subproject commit 376501b8f441bd6b6e75b1960b118aabd72fca9d diff --git a/src/servers/Server_Common/Common.h b/src/servers/Server_Common/Common.h index 84c7125d..62271360 100644 --- a/src/servers/Server_Common/Common.h +++ b/src/servers/Server_Common/Common.h @@ -562,7 +562,7 @@ namespace Core { LimitBreak = 8, }; - enum class ActionEffectType : uint8_t + enum ActionEffectType : uint8_t { Nothing = 0, Miss = 1, @@ -591,16 +591,17 @@ namespace Core { CritDirectHitDamage = 3 }; - enum class AoeType + enum class ActionCollisionType : uint8_t { None, SingleTarget, - TargetCircle, + Circle, Cone, - Line, + Box, Unknown, Unknown2, - GroundCircle, // for when you set aoe like asylum + PersistentArea, // for when you set aoe like asylum + Unknown3 }; enum HandleActionType : uint8_t diff --git a/src/servers/Server_Common/Exd/ExdData.cpp b/src/servers/Server_Common/Exd/ExdData.cpp index 0c5fd98f..eebb4fab 100644 --- a/src/servers/Server_Common/Exd/ExdData.cpp +++ b/src/servers/Server_Common/Exd/ExdData.cpp @@ -323,70 +323,65 @@ bool Core::Data::ExdData::loadActionInfo() continue; } - std::string name = getField< std::string >( fields, 0 ); // 0 - uint8_t category = getField< uint8_t >( fields, 3 ); // 3 + std::string name = getField< std::string >( fields, 0 ); // 0 + uint8_t category = getField< uint8_t >( fields, 3 ); // 3 - int8_t class_job = getField< int8_t >( fields, 10 ); // 10 - uint8_t unlock_level = getField< uint8_t >( fields, 11 ); // 11 - int8_t range = getField< int8_t >( fields, 13 ); // 13 - bool can_target_self = getField< bool >( fields, 14 ); // 14 - bool can_target_party = getField< bool>( fields, 15 ); // 15 - bool can_target_friendly = getField< bool >( fields, 16 ); // 16 - bool can_target_enemy = getField< bool >( fields, 17 ); // 17 + int8_t class_job = getField< int8_t >( fields, 10 ); // 10 + uint8_t unlock_level = getField< uint8_t >( fields, 11 ); // 11 + int8_t range = getField< int8_t >( fields, 13 ); // 13 + bool can_target_self = getField< bool >( fields, 14 ); // 14 + bool can_target_party = getField< bool>( fields, 15 ); // 15 + bool can_target_friendly = getField< bool >( fields, 16 ); // 16 + bool can_target_enemy = getField< bool >( fields, 17 ); // 17 - bool is_aoe = getField< bool >( fields, 20 ); // 20 + bool is_ground_aoe = getField< bool >( fields, 20 ); // 20 // Column 23: Seems to be related to raising skills (Raise, Resurrection, Reanimate) - bool can_target_ko = getField< bool >( fields, 24 ); // 24 + bool can_target_ko = getField< bool >( fields, 24 ); // 24 - uint8_t aoe_type = getField< uint8_t >( fields, 26 ); // 26 - uint8_t radius = getField< uint8_t >( fields, 27 ); // 27 + uint8_t aoe_type = getField< uint8_t >( fields, 26 ); // 26 + uint8_t aoe_range = getField< uint8_t >( fields, 27 ); // 27 + uint8_t aoe_width = getField< uint8_t >( fields, 28 ); // 28 - uint8_t points_type = getField< uint8_t >( fields, 30 ); // 30 - uint16_t points_cost = getField< uint16_t >( fields, 31 ); // 31 + uint8_t points_type = getField< uint8_t >( fields, 30 ); // 30 + uint16_t points_cost = getField< uint16_t >( fields, 31 ); // 31 - uint32_t instantval = getField< bool >( fields, 35 ); // 35 - uint16_t cast_time = getField< uint16_t >( fields, 36 ); // 36 - uint16_t recast_time = getField< uint16_t >( fields, 37 ); // 37 - - int8_t model = getField< int8_t >( fields, 39 ); // 39: Action model - uint8_t aspect = getField< uint8_t >( fields, 40 ); // 40: Action aspect - - uint8_t typeshift = 0x6; - uint8_t mask = 1 << typeshift; - instantval &= mask; - bool final = ( instantval & mask ) == mask; - bool is_instant = final; + bool is_instant = getField< bool >( fields, 35 ); // 35 + uint16_t cast_time = getField< uint16_t >( fields, 36 ); // 36 + uint16_t recast_time = getField< uint16_t >( fields, 37 ); // 37 + int8_t model = getField< int8_t >( fields, 39 ); // 39 + uint8_t aspect = getField< uint8_t >( fields, 40 ); // 40 - info->id = id; - info->name = name; - info->category = category; + info->id = id; + info->name = name; + info->category = category; - info->class_job = class_job; - info->unlock_level = unlock_level; - info->range = range; - info->can_target_self = can_target_self; - info->can_target_party = can_target_party; + info->class_job = class_job; + info->unlock_level = unlock_level; + info->range = range; + info->can_target_self = can_target_self; + info->can_target_party = can_target_party; info->can_target_friendly = can_target_friendly; - info->can_target_enemy = can_target_enemy; + info->can_target_enemy = can_target_enemy; - info->can_target_ko = can_target_ko; + info->can_target_ko = can_target_ko; - info->is_aoe = is_aoe; + info->is_ground_aoe = is_ground_aoe; - info->aoe_type = aoe_type; - info->radius = radius; + info->aoe_type = aoe_type; + info->aoe_range = aoe_range; + info->aoe_width = aoe_width; - info->points_type = points_type; - info->points_cost = points_cost; + info->points_type = points_type; + info->points_cost = points_cost; - info->is_instant = is_instant; - info->cast_time = cast_time * 100; - info->recast_time = recast_time * 100; + info->is_instant = is_instant; + info->cast_time = cast_time * 100; + info->recast_time = recast_time * 100; - info->model = model; - info->aspect = aspect; + info->model = model; + info->aspect = aspect; m_actionInfoMap.emplace( std::make_pair( info->id, info ) ); diff --git a/src/servers/Server_Common/Exd/ExdData.h b/src/servers/Server_Common/Exd/ExdData.h index a6376550..a23d21ff 100644 --- a/src/servers/Server_Common/Exd/ExdData.h +++ b/src/servers/Server_Common/Exd/ExdData.h @@ -233,12 +233,13 @@ namespace Core { bool can_target_friendly; // 16 bool can_target_enemy; // 17 - bool is_aoe; // 20 + bool is_ground_aoe; // 20 bool can_target_ko; // 24 uint8_t aoe_type; // 26 - uint8_t radius; // 27 + uint8_t aoe_range; // 27 + uint8_t aoe_width; // 28 uint8_t points_type; // 30 uint16_t points_cost; // 31 diff --git a/src/servers/Server_Zone/Action/ActionCollision.cpp b/src/servers/Server_Zone/Action/ActionCollision.cpp new file mode 100644 index 00000000..93168ba6 --- /dev/null +++ b/src/servers/Server_Zone/Action/ActionCollision.cpp @@ -0,0 +1,133 @@ +#include +#include +#include + +#include "ActionCollision.h" +#include +#include +#include +#include + +using namespace Core::Entity; +using namespace Core::Common; + +// todo: add filters for allies, enemies only etc + +bool ActionCollision::isActorCollisionValid( ActorPtr actorPtr, AoeFilter aoeFilter ) +{ + bool collisionApplicable = false; + switch ( aoeFilter ) + { + case AoeFilter::All: + { + collisionApplicable = true; + } + case AoeFilter::Players: + { + collisionApplicable = actorPtr->isPlayer(); + } + case AoeFilter::Allies: + { + // todo: implement ally NPCs + collisionApplicable = !actorPtr->isMob(); + } + case AoeFilter::Party: + { + // todo: implement party + collisionApplicable = actorPtr->isPlayer(); + } + case AoeFilter::Enemies: + { + collisionApplicable = actorPtr->isMob(); + } + } + + return ( collisionApplicable && actorPtr->isAlive() ); +} + +std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition, std::set< ActorPtr > actorsInRange, boost::shared_ptr< Core::Data::ActionInfo > actionInfo, AoeFilter aoeFilter ) +{ + std::set< ActorPtr > actorsCollided; + + switch ( static_cast< ActionCollisionType >( actionInfo->aoe_type ) ) + { + case ActionCollisionType::None: + case ActionCollisionType::SingleTarget: + { + // This is actually needed. There is "splash damage" in actions marked as single target. + // Notice how we're using aoe_width. How collision works for SingleTarget is unknown as of now. + // TODO: Isn't it possible to stack 2 players in the same spot and glitch the action collision this way? Investigate + for ( auto pActor : actorsInRange ) + { + // Make sure actor exists. If it doesn't we done goofed. + assert( pActor ); + + // Don't bother wasting on collision if actor doesn't apply for it + if ( !isActorCollisionValid( pActor, aoeFilter ) ) + break; + + // Test our collision from actor with the area generated by the action from the AoE data + if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->aoe_width ) ) + { + // Add it to the actors collided with the area + actorsCollided.insert( pActor ); + } + } + break; + } + case ActionCollisionType::Circle: + { + for ( auto pActor : actorsInRange ) + { + assert( pActor ); + + if ( !isActorCollisionValid( pActor, aoeFilter ) ) + break; + + if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->aoe_range ) ) + { + actorsCollided.insert( pActor ); + } + } + break; + } + case ActionCollisionType::Box: + { + for ( auto pActor : actorsInRange ) + { + assert( pActor ); + + if ( !isActorCollisionValid( pActor, aoeFilter ) ) + break; + + if ( boxCollision( pActor->getPos(), aoePosition, actionInfo->aoe_width, actionInfo->aoe_range ) ) + { + // todo: does this actually work? + + actorsCollided.insert( pActor ); + } + } + break; + } + default: + { + break; + } + } + + return actorsCollided; +} + +bool ActionCollision::radiusCollision( FFXIVARR_POSITION3 actorPosition, FFXIVARR_POSITION3 aoePosition, uint16_t radius ) +{ + return Core::Math::Util::distance( actorPosition.x, actorPosition.y, actorPosition.z, + aoePosition.x, aoePosition.y, aoePosition.z ) <= radius; +} + +bool ActionCollision::boxCollision( FFXIVARR_POSITION3 actorPosition, FFXIVARR_POSITION3 aoePosition, uint16_t width, uint16_t height ) +{ + return actorPosition.x < aoePosition.x + width && + actorPosition.x > aoePosition.x && + actorPosition.y < aoePosition.y + height && + actorPosition.y > aoePosition.y; +} \ No newline at end of file diff --git a/src/servers/Server_Zone/Action/ActionCollision.h b/src/servers/Server_Zone/Action/ActionCollision.h new file mode 100644 index 00000000..9cd92534 --- /dev/null +++ b/src/servers/Server_Zone/Action/ActionCollision.h @@ -0,0 +1,37 @@ +#ifndef _ACTIONCOLLISION_H +#define _ACTIONCOLLISION_H + +#include + +#include +#include "Action.h" + +namespace Core { + namespace Entity { + + enum class AoeFilter + { + All, // All actors in the AoE are applicable for collision + Players, // Only players + Allies, // Only allies (players, ally NPCs) + Party, // Only party members + Enemies // Only enemies + }; + + class ActionCollision + { + public: + + static bool isActorCollisionValid( ActorPtr actorPtr, AoeFilter aoeFilter ); + static std::set< ActorPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition, std::set< ActorPtr > actorsInRange, boost::shared_ptr< Data::ActionInfo > actionInfo, AoeFilter aoeFilter ); + + private: + static bool radiusCollision( Common::FFXIVARR_POSITION3 actorPosition, Common::FFXIVARR_POSITION3 aoePosition, uint16_t radius ); + static bool boxCollision( Common::FFXIVARR_POSITION3 actorPosition, Common::FFXIVARR_POSITION3 aoePosition, uint16_t width, uint16_t height ); + + }; + + } +} + +#endif \ No newline at end of file diff --git a/src/servers/Server_Zone/Actor/Actor.cpp b/src/servers/Server_Zone/Actor/Actor.cpp index 1b4e3c38..8a5b61a2 100644 --- a/src/servers/Server_Zone/Actor/Actor.cpp +++ b/src/servers/Server_Zone/Actor/Actor.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include "src/servers/Server_Zone/Forwards.h" #include "src/servers/Server_Zone/Action/Action.h" @@ -15,11 +16,14 @@ #include "src/servers/Server_Zone/StatusEffect/StatusEffectContainer.h" #include "src/servers/Server_Zone/StatusEffect/StatusEffect.h" +#include "src/servers/Server_Zone/Action/ActionCollision.h" #include "src/servers/Server_Zone/ServerZone.h" #include "src/servers/Server_Zone/Session.h" +#include "CalcBattle.h" #include "Player.h" extern Core::ServerZone g_serverZone; +extern Core::Data::ExdData g_exdData; using namespace Core::Common; using namespace Core::Network::Packets; @@ -620,6 +624,112 @@ void Core::Entity::Actor::autoAttack( ActorPtr pTarget ) } } +/*! +ChaiScript Skill Handler. + +\param GamePacketPtr to send +\param bool should be send to self? +*/ +void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint32_t actionId, uint64_t param1, uint64_t param2, Entity::Actor& pTarget ) +{ + + if ( isPlayer() ) + { + getAsPlayer()->sendDebug( std::to_string( pTarget.getId() ) ); + getAsPlayer()->sendDebug( "Handle script skill type: " + std::to_string( type ) ); + } + + + auto actionInfoPtr = g_exdData.getActionInfo( actionId ); + + // Prepare packet. This is seemingly common for all packets in the action handler. + + GamePacketNew< FFXIVIpcEffect, ServerZoneIpcType > effectPacket( getId() ); + effectPacket.data().targetId = pTarget.getId(); + effectPacket.data().actionAnimationId = actionId; + effectPacket.data().unknown_2 = 1; // This seems to have an effect on the "double-cast finish" animation + // effectPacket.data().unknown_3 = 1; + effectPacket.data().actionTextId = actionId; + effectPacket.data().numEffects = 1; + effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() ); + effectPacket.data().effectTarget = pTarget.getId(); + effectPacket.data().effects[0].value = 0; + effectPacket.data().effects[0].effectType = ActionEffectType::Damage; + effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalDamage; + effectPacket.data().effects[0].unknown_3 = 7; + + switch ( type ) + { + + case ActionEffectType::Damage: + { + + effectPacket.data().effects[0].value = static_cast< int16_t >( param1 ); + effectPacket.data().effects[0].effectType = ActionEffectType::Damage; + effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalDamage; + + std::set< ActorPtr > actorsCollided = ActionCollision::getActorsHitFromAction( pTarget.getPos(), getInRangeActors( true ), actionInfoPtr, AoeFilter::Enemies ); + + for ( auto pHitActor : actorsCollided ) + { + effectPacket.data().targetId = pHitActor->getId(); + effectPacket.data().unknown_1 = 1; // the magic trick for getting it to work + effectPacket.data().unknown_5 = 1; + effectPacket.data().unknown_8 = 1; + effectPacket.data().actionTextId = 0; + effectPacket.data().effectTarget = pHitActor->getId(); + effectPacket.data().effects[0].value = param1 + ( rand() % 15 ); + + pHitActor->sendToInRangeSet( effectPacket, true ); // todo: send to range of what? ourselves? when mob script hits this is going to be lacking + pHitActor->takeDamage( static_cast< uint32_t >( param1 ) ); + pHitActor->onActionHostile( shared_from_this() ); + + if ( isPlayer() ) + getAsPlayer()->sendDebug( "AoE hit actor " + pHitActor->getName() ); + } + + break; + } + + case ActionEffectType::Heal: + { + uint32_t calculatedHeal = Data::CalcBattle::calculateHealValue( getAsPlayer(), static_cast< uint32_t >( param1 ) ); + + effectPacket.data().effects[0].value = calculatedHeal; + effectPacket.data().effects[0].effectType = ActionEffectType::Heal; + effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalHeal; + + sendToInRangeSet( effectPacket, true ); + + // todo: get proper packets: the following was just kind of thrown together from what we know + + std::set< ActorPtr > actorsCollided = ActionCollision::getActorsHitFromAction( pTarget.getPos(), getInRangeActors( true ), actionInfoPtr, AoeFilter::Allies ); + + for ( auto pHitActor : actorsCollided ) + { + effectPacket.data().targetId = pHitActor->getId(); + effectPacket.data().unknown_1 = 1; // the magic trick for getting it to work + effectPacket.data().unknown_5 = 1; + effectPacket.data().unknown_8 = 1; + effectPacket.data().actionTextId = 0; + effectPacket.data().effectTarget = pHitActor->getId(); + effectPacket.data().effects[0].value = calculatedHeal + ( rand() % 15 ); + + pHitActor->sendToInRangeSet( effectPacket, true ); + pHitActor->heal( calculatedHeal ); + + if ( isPlayer() ) + getAsPlayer()->sendDebug( "AoE hit actor " + pHitActor->getName() ); + } + + break; + } + + default: + break; + } +} + /*! \param StatusEffectPtr to be applied to the actor */ void Core::Entity::Actor::addStatusEffect( StatusEffect::StatusEffectPtr pEffect ) { diff --git a/src/servers/Server_Zone/Actor/Actor.h b/src/servers/Server_Zone/Actor/Actor.h index de6b9118..fee4251a 100644 --- a/src/servers/Server_Zone/Actor/Actor.h +++ b/src/servers/Server_Zone/Actor/Actor.h @@ -231,6 +231,8 @@ public: void setStatus( ActorStatus status ); + void handleScriptSkill( uint32_t type, uint32_t actionId, uint64_t param1, uint64_t param2, Entity::Actor& target ); + virtual void autoAttack( ActorPtr pTarget ); virtual void spawn( PlayerPtr pTarget ) {} diff --git a/src/servers/Server_Zone/Actor/CalcBattle.cpp b/src/servers/Server_Zone/Actor/CalcBattle.cpp index 9195412e..d83ead39 100644 --- a/src/servers/Server_Zone/Actor/CalcBattle.cpp +++ b/src/servers/Server_Zone/Actor/CalcBattle.cpp @@ -5,6 +5,7 @@ #include "Player.h" #include +using namespace Core::Data; using namespace Core::Entity; extern Core::Data::ExdData g_exdData; diff --git a/src/servers/Server_Zone/Actor/CalcBattle.h b/src/servers/Server_Zone/Actor/CalcBattle.h index f4885725..0cbde694 100644 --- a/src/servers/Server_Zone/Actor/CalcBattle.h +++ b/src/servers/Server_Zone/Actor/CalcBattle.h @@ -5,8 +5,10 @@ #include "Actor.h" +using namespace Core::Entity; + namespace Core { -namespace Entity { +namespace Data { class CalcBattle { diff --git a/src/servers/Server_Zone/Actor/Player.cpp b/src/servers/Server_Zone/Actor/Player.cpp index d91be9bb..4c6e3fe6 100644 --- a/src/servers/Server_Zone/Actor/Player.cpp +++ b/src/servers/Server_Zone/Actor/Player.cpp @@ -216,7 +216,7 @@ void Core::Entity::Player::calculateStats() auto paramGrowthInfo = paramGrowthInfoIt->second; // TODO: put formula somewhere else... - float base = CalcBattle::calculateBaseStat( getAsPlayer() ); + float base = Data::CalcBattle::calculateBaseStat( getAsPlayer() ); m_baseStats.str = static_cast< uint32_t >( base * ( static_cast< float >( classInfo.mod_str ) / 100 ) + tribeInfo.mod_str ); m_baseStats.dex = static_cast< uint32_t >( base * ( static_cast< float >( classInfo.mod_dex ) / 100 ) + tribeInfo.mod_dex ); @@ -232,9 +232,9 @@ void Core::Entity::Player::calculateStats() m_baseStats.attackPotMagic = paramGrowthInfo.base_secondary; m_baseStats.healingPotMagic = paramGrowthInfo.base_secondary; - m_baseStats.max_mp = CalcBattle::calculateMaxMp( getAsPlayer() ); + m_baseStats.max_mp = Data::CalcBattle::calculateMaxMp( getAsPlayer() ); - m_baseStats.max_hp = CalcBattle::calculateMaxHp( getAsPlayer() ); + m_baseStats.max_hp = Data::CalcBattle::calculateMaxHp( getAsPlayer() ); if( m_mp > m_baseStats.max_mp ) m_mp = m_baseStats.max_mp; @@ -1514,102 +1514,6 @@ void Core::Entity::Player::autoAttack( ActorPtr pTarget ) } -void Core::Entity::Player::handleScriptSkill( uint32_t type, uint32_t actionId, uint64_t param1, uint64_t param2, Entity::Actor& pTarget ) -{ - sendDebug( std::to_string( pTarget.getId() ) ); - sendDebug( "Handle script skill type: " + std::to_string( type ) ); - - auto actionInfoPtr = g_exdData.getActionInfo( actionId ); - - sendDebug( actionInfoPtr->name ); - if ( actionInfoPtr->is_aoe ) - sendDebug( "is aoe: " + std::to_string( actionInfoPtr->is_aoe ) ); - - GamePacketNew< FFXIVIpcEffect, ServerZoneIpcType > effectPacket( getId() ); - effectPacket.data().targetId = pTarget.getId(); - effectPacket.data().actionAnimationId = actionId; - effectPacket.data().unknown_2 = 1; // This seems to have an effect on the "double-cast finish" animation - // effectPacket.data().unknown_3 = 1; - effectPacket.data().actionTextId = actionId; - effectPacket.data().numEffects = 1; - effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() ); - effectPacket.data().effectTarget = pTarget.getId(); - effectPacket.data().effects[0].value = 0; - effectPacket.data().effects[0].effectType = static_cast < ActionEffectType >( type ); - effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalDamage; - effectPacket.data().effects[0].unknown_3 = 7; - - switch ( type ) - { - - case 3: - { - sendDebug( "STD_DAMAGE" ); - - effectPacket.data().effects[0].value = static_cast< int16_t >( param1 ); - - sendToInRangeSet( effectPacket, true ); - - if ( !pTarget.isAlive() ) - break; - - pTarget.takeDamage( static_cast< uint32_t >( param1 ) ); - pTarget.onActionHostile( shared_from_this() ); - break; - } - - case 4: - { - uint32_t calculatedHeal = CalcBattle::calculateHealValue( getAsPlayer(), static_cast< uint32_t >( param1 ) ); - - effectPacket.data().effects[0].value = static_cast< int16_t >( calculatedHeal ); - effectPacket.data().effects[0].effectType = ActionEffectType::Heal; - effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalHeal; - - sendDebug( "STD_HEAL" ); - - sendToInRangeSet( effectPacket, true ); - - if ( !pTarget.isAlive() ) - break; - - // todo: get proper packets: the following was just kind of thrown together from what we know - // also toss AoE to another spot and make it generic - sendDebug( actionInfoPtr->name ); - if ( actionInfoPtr->is_aoe ) - { - sendDebug( "IS AOE LOL" ); - for ( auto pCurAct : m_inRangePlayers ) - { - assert( pCurAct ); - if ( !pCurAct->isAlive() ) - break; - - if ( Math::Util::distance( pTarget.getPos().x, pTarget.getPos().y, pTarget.getPos().z, pCurAct->getPos().x, pCurAct->getPos().y, pCurAct->getPos().z ) <= actionInfoPtr->radius ) - { - effectPacket.data().targetId = pCurAct->getId(); - effectPacket.data().unknown_1 = 1; // the magic trick for getting it to work - effectPacket.data().unknown_8 = 1; - effectPacket.data().unknown_5 = 1; - effectPacket.data().actionTextId = 0; - effectPacket.data().effectTarget = pCurAct->getId(); - - pCurAct->sendToInRangeSet( effectPacket, true ); - pCurAct->heal( calculatedHeal ); - sendDebug( "AoE hit actor " + pCurAct->getName() ); - } - } - } - - pTarget.heal( calculatedHeal ); - break; - } - - default: - break; - } -} - ///////////////////////////// // Content Finder diff --git a/src/servers/Server_Zone/Actor/Player.h b/src/servers/Server_Zone/Actor/Player.h index 907a5916..11104463 100644 --- a/src/servers/Server_Zone/Actor/Player.h +++ b/src/servers/Server_Zone/Actor/Player.h @@ -487,8 +487,6 @@ public: void setAutoattack( bool mode ); bool isAutoattackOn() const; - void handleScriptSkill( uint32_t type, uint32_t actionId, uint64_t param1, uint64_t param2, Entity::Actor& target ); - // Content Finder handling ////////////////////////////////////////////////////////////////////////////////////////////////////// /*! Get an unix time when the player can register into content finder again. */ diff --git a/src/servers/Server_Zone/ServerZone.cpp b/src/servers/Server_Zone/ServerZone.cpp index 16042e03..2ff42a92 100644 --- a/src/servers/Server_Zone/ServerZone.cpp +++ b/src/servers/Server_Zone/ServerZone.cpp @@ -218,11 +218,11 @@ void Core::ServerZone::run( int32_t argc, char* argv[] ) Network::HivePtr hive( new Network::Hive() ); Network::addServerToHive< Network::GameConnection >( m_ip, m_port, hive ); - g_scriptMgr.init(); - g_log.info( "ZoneMgr: Setting up zones" ); g_zoneMgr.createZones(); + g_scriptMgr.init(); + std::vector< std::thread > thread_list; thread_list.push_back( std::thread( std::bind( &Network::Hive::Run, hive.get() ) ) ); From ad2e93f5e62635b5fed1d9a89a142aa5b1b870b2 Mon Sep 17 00:00:00 2001 From: Maru Date: Thu, 28 Sep 2017 13:12:56 -0300 Subject: [PATCH 08/29] Happy little mistakes --- src/servers/Server_Zone/Action/ActionCollision.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/servers/Server_Zone/Action/ActionCollision.cpp b/src/servers/Server_Zone/Action/ActionCollision.cpp index 93168ba6..4c193fd7 100644 --- a/src/servers/Server_Zone/Action/ActionCollision.cpp +++ b/src/servers/Server_Zone/Action/ActionCollision.cpp @@ -21,24 +21,29 @@ bool ActionCollision::isActorCollisionValid( ActorPtr actorPtr, AoeFilter aoeFil case AoeFilter::All: { collisionApplicable = true; + break; } case AoeFilter::Players: { collisionApplicable = actorPtr->isPlayer(); + break; } case AoeFilter::Allies: { // todo: implement ally NPCs collisionApplicable = !actorPtr->isMob(); + break; } case AoeFilter::Party: { // todo: implement party collisionApplicable = actorPtr->isPlayer(); + break; } case AoeFilter::Enemies: { collisionApplicable = actorPtr->isMob(); + break; } } From 4bc6f023f18a3e8d95102492054365c1e1785b8f Mon Sep 17 00:00:00 2001 From: Maru Date: Thu, 28 Sep 2017 17:35:07 -0300 Subject: [PATCH 09/29] Merge --- src/servers/Server_Common/Common.h | 23 +++++++++++++++++++ src/servers/Server_Common/Exd/ExdData.cpp | 13 +++++++++++ .../DebugCommand/DebugCommandHandler.cpp | 22 ++---------------- 3 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/servers/Server_Common/Common.h b/src/servers/Server_Common/Common.h index 62271360..a2a243be 100644 --- a/src/servers/Server_Common/Common.h +++ b/src/servers/Server_Common/Common.h @@ -383,6 +383,29 @@ namespace Core { instance, }; + enum TerritoryIntendedUseType : uint8_t //ToDo: Add The Rest of The Territory Types and Have Better Names For Them + { + Town = 0, + OpenWorld = 1, + Inn = 2, + Dungeon = 3, + JailArea = 5, + OpeningArea = 6, + BeforeTrialDung = 7, + AllianceRaid = 8, + OpenWorldInstanceBattle = 9, + Trial = 10, + HousingArea = 13, + HousingPrivateArea = 14, + MSQPrivateArea = 15, + Raids = 16, + RaidFights = 17, + ChocoboTutorial = 21, + Wedding = 22, + BeginnerTutorial = 27, + PalaceOfTheDead = 31, + }; + enum CharaLook : uint8_t { Race = 0x00, diff --git a/src/servers/Server_Common/Exd/ExdData.cpp b/src/servers/Server_Common/Exd/ExdData.cpp index eebb4fab..17007e55 100644 --- a/src/servers/Server_Common/Exd/ExdData.cpp +++ b/src/servers/Server_Common/Exd/ExdData.cpp @@ -345,6 +345,7 @@ bool Core::Data::ExdData::loadActionInfo() uint8_t points_type = getField< uint8_t >( fields, 30 ); // 30 uint16_t points_cost = getField< uint16_t >( fields, 31 ); // 31 +<<<<<<< HEAD bool is_instant = getField< bool >( fields, 35 ); // 35 uint16_t cast_time = getField< uint16_t >( fields, 36 ); // 36 uint16_t recast_time = getField< uint16_t >( fields, 37 ); // 37 @@ -356,6 +357,18 @@ bool Core::Data::ExdData::loadActionInfo() info->id = id; info->name = name; info->category = category; +======= + bool is_instant = getField< bool >( fields, 35 ); // 35 + uint16_t cast_time = getField< uint16_t >( fields, 36 ); // 36 + uint16_t recast_time = getField< uint16_t >( fields, 37 ); // 37 + + int8_t model = getField< int8_t >( fields, 39 ); // 39: Action model + uint8_t aspect = getField< uint8_t >( fields, 40 ); // 40: Action aspect + + info->id = id; + info->name = name; + info->category = category; +>>>>>>> 08f4c7651fafdaf8f4d98868a94ab4688eb71379 info->class_job = class_job; info->unlock_level = unlock_level; diff --git a/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp b/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp index 6a4f6e84..b3137453 100644 --- a/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp +++ b/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp @@ -239,25 +239,6 @@ void Core::DebugCommandHandler::set( char * data, Core::Entity::PlayerPtr pPlaye else pPlayer->setClassJob( static_cast ( id ) ); } - else if( subCommand == "no" ) - { - int32_t id; - - sscanf( params.c_str(), "%d", &id ); - - uint8_t typeshift = 0x6; - uint8_t mask = 1 << typeshift; - id &= mask; - bool final = ( id & mask ) == mask; - pPlayer->sendDebug( std::to_string(final) ); - } - else if( subCommand == "aaah" ) - { - int32_t id; - sscanf( params.c_str(), "%d", &id ); - - pPlayer->sendDebug( std::to_string( pPlayer->actionHasCastTime( id ) ) ); - } else if ( subCommand == "cfpenalty" ) { int32_t minutes; @@ -486,6 +467,7 @@ void Core::DebugCommandHandler::nudge( char * data, Entity::PlayerPtr pPlayer, b void Core::DebugCommandHandler::serverInfo( char * data, Core::Entity::PlayerPtr pPlayer, boost::shared_ptr< Core::DebugCommand > command ) { - pPlayer->sendDebug( "SapphireServer " + Version::VERSION + " - " + Version::GIT_HASH ); + pPlayer->sendDebug( "SapphireServer " + Version::VERSION + "\nRev: " + Version::GIT_HASH ); + pPlayer->sendDebug( "Compiled: " __DATE__ " " __TIME__ ); pPlayer->sendDebug( "Sessions: " + std::to_string( g_serverZone.getSessionCount() ) ); } From b9619eddfe9531acd46c12630c6af7bf2c2b5f20 Mon Sep 17 00:00:00 2001 From: Biscuit Boy Date: Sun, 1 Oct 2017 04:14:54 +1000 Subject: [PATCH 10/29] Added All Coming To X Quests and Fixed Black Bars Fixed the Coming to Ul'dah and Coming to Limsa Quests, also Fixed the Openings having Black Bards and not being able to jump --- scripts/chai/opening/OpeningGridania.chai | 2 +- scripts/chai/opening/OpeningLimsa.chai | 1 - scripts/chai/opening/OpeningUldah.chai | 2 +- scripts/chai/quest/ManSea001.chai | 15 ++++++++------- scripts/chai/quest/ManWil001.chai | 23 ++++++++++++----------- 5 files changed, 22 insertions(+), 21 deletions(-) diff --git a/scripts/chai/opening/OpeningGridania.chai b/scripts/chai/opening/OpeningGridania.chai index fbaf1005..207cf8fe 100644 --- a/scripts/chai/opening/OpeningGridania.chai +++ b/scripts/chai/opening/OpeningGridania.chai @@ -34,7 +34,7 @@ class OpeningGridaniaDef def Scene00000( player ) { - player.eventPlay( this.id, 0, 0x2001, 0, 1, + player.eventPlay( this.id, 0, 0x04AC05, 0, 1, fun( player, eventId, param1, param2, param3 ) { player.setOpeningSequence( 1 ); diff --git a/scripts/chai/opening/OpeningLimsa.chai b/scripts/chai/opening/OpeningLimsa.chai index ebae5446..f7ab44c7 100644 --- a/scripts/chai/opening/OpeningLimsa.chai +++ b/scripts/chai/opening/OpeningLimsa.chai @@ -72,7 +72,6 @@ class OpeningLimsaLominsaDef player.eventPlay( this.id, 40, 1, 2, 1, fun( player, eventId, param1, param2, param3 ) { - player.eventFinish( eventId, UNLOCK ); if( player.getOpeningSequence() == 2 ) { // update the instance boundaries diff --git a/scripts/chai/opening/OpeningUldah.chai b/scripts/chai/opening/OpeningUldah.chai index 6c19e6c4..829bab1b 100644 --- a/scripts/chai/opening/OpeningUldah.chai +++ b/scripts/chai/opening/OpeningUldah.chai @@ -35,7 +35,7 @@ class OpeningUldahDef def Scene00000( player ) { - player.eventPlay( this.id, 0, 0x2001, 0, 1, + player.eventPlay( this.id, 0, 0x04AC05, 0, 1, fun( player, eventId, param1, param2, param3 ) { player.setOpeningSequence( 1 ); diff --git a/scripts/chai/quest/ManSea001.chai b/scripts/chai/quest/ManSea001.chai index c3af3b76..8c060bf2 100644 --- a/scripts/chai/quest/ManSea001.chai +++ b/scripts/chai/quest/ManSea001.chai @@ -51,11 +51,12 @@ class ManSea001Def // Available Scenes in this quest, not necessarly all are used def Scene00000( player ) { - player.eventPlay( this.id, 0, HIDE_HOTBAR, 0/*unk*/, 0/*unk*/, + player.eventPlay( this.id, 0, 0x2000, 0, 0, fun( player, eventId, param1, param2, param3 ) { if( param2 == 1 ) { + player.setOpeningSequence( 2 ); ManSea001.Scene00001( player ); } }); @@ -63,7 +64,7 @@ class ManSea001Def def Scene00001( player ) { - player.eventPlay( this.id, 1, HIDE_HOTBAR, 0/*unk*/, 0/*unk*/, + player.eventPlay( this.id, 1, 0xF8482EFB, 0, 0, fun( player, eventId, param1, param2, param3 ) { ManSea001.Scene00002( player ); @@ -81,13 +82,13 @@ class ManSea001Def def Scene00003( player ) { - player.eventPlay( this.id, 3, NONE, 0/*unk*/, 0/*unk*/, + player.eventPlay( this.id, 3, NONE, 0, 0, fun( player, eventId, param1, param2, param3 ) { player.questUpdate( ManSea001.id, 0x01 ); // add quest to player. // update the instance boundaries, call to the opening event - //player.eventPlay( ManSea001.OPENING_EVENT_HANDLER, 0x1E, HIDE_HOTBAR, 1, 0); + player.eventPlay( ManSea001.OPENING_EVENT_HANDLER, 0x1E, 0x2001, 1, 0); }); } @@ -107,7 +108,7 @@ class ManSea001Def def Scene00006( player ) { - player.eventPlay( this.id, 6, NONE, 0/*unk*/, 0/*unk*/, + player.eventPlay( this.id, 6, 0x20, 0/*unk*/, 0/*unk*/, fun( player, eventId, param1, param2, param3 ) { if( param2 == 1 ) @@ -141,7 +142,7 @@ class ManSea001Def def Scene00011( player ) { - player.eventPlay( this.id, 11, NONE, 0, 0, + player.eventPlay( this.id, 11, 0x2c02, 0, 0, fun( player, eventId, param1, param2, param3 ) { ManSea001.Scene00012( player ); @@ -150,7 +151,7 @@ class ManSea001Def def Scene00012( player ) { - player.eventPlay( this.id, 12, NONE, 0, 0, + player.eventPlay( this.id, 12, 0x20, 0, 0, fun( player, eventId, param1, param2, param3 ) { if( param2 == 1 ) diff --git a/scripts/chai/quest/ManWil001.chai b/scripts/chai/quest/ManWil001.chai index 1799e45a..da55f8c1 100644 --- a/scripts/chai/quest/ManWil001.chai +++ b/scripts/chai/quest/ManWil001.chai @@ -9,25 +9,25 @@ // Start NPC: 1003987 // End NPC: 1003988 -class ManWil001Def +class ManWil001Def { ////////////////////////////////////////////////////////////////////// // default ctor def ManWil001Def() { - // Basic quest information + // Basic quest information this.name = "Coming to Ul'dah"; this.id = 66130; // Quest vars / flags used // GetQuestUI8AL - // Steps in this quest ( 0 is before accepting, + // Steps in this quest ( 0 is before accepting, // 1 is first, 255 means ready for turning it in this.SEQ_0 = 0; this.SEQ_FINISH = 255; - // Quest rewards + // Quest rewards this.RewardExpFactor = 50; this.RewardGil = 103; @@ -49,11 +49,12 @@ class ManWil001Def // Available Scenes in this quest, not necessarly all are used def Scene00000( player ) { - player.eventPlay( this.id, 0, 0, 0, 0, + player.eventPlay( this.id, 0, 0x2000, 0, 0, fun( player, eventId, param1, param2, param3 ) { if( param2 == 1 ) // accept quest { + player.setOpeningSequence( 2 ); ManWil001.Scene00001( player ); } }); @@ -61,7 +62,7 @@ class ManWil001Def def Scene00001( player ) { - player.eventPlay( this.id, 1, 0, 0, 0, + player.eventPlay( this.id, 1, 0xF8482EFB, 0, 0, fun( player, eventId, param1, param2, param3 ) { ManWil001.Scene00002( player ); @@ -70,11 +71,11 @@ class ManWil001Def def Scene00002( player ) { - player.eventPlay( this.id, 2, 0, 0, 0, + player.eventPlay( this.id, 2, NONE, 0, 0, fun( player, eventId, param1, param2, param3 ) { - player.questUpdate( ManWil001.id, ManWil001Obj.SEQ_FINISH );// add quest to player. - player.eventPlay( ManWil001.OPENING_EVENT_HANDLER, 0x1E, 0x2001, 0, 0 ); + player.questUpdate( ManWil001.id, ManWil001.SEQ_FINISH );// add quest to player. + player.eventPlay( ManWil001.OPENING_EVENT_HANDLER, 0x1E, 0x2001, 0, 0 ); }); } @@ -85,7 +86,7 @@ class ManWil001Def def Scene00004( player ) { - player.eventPlay( this.id, 4, 0, 0, 0, + player.eventPlay( this.id, 4, 0x2c02, 0, 0, fun( player, eventId, param1, param2, param3 ) { ManWil001.Scene00005( player ); @@ -94,7 +95,7 @@ class ManWil001Def def Scene00005( player ) { - player.eventPlay( this.id, 5, 0/*flags*/, 0/*unk*/, 0/*unk*/, + player.eventPlay( this.id, 5, 0x20/*flags*/, 0/*unk*/, 0/*unk*/, fun( player, eventId, param1, param2, param3 ) { if( param2 == 1 ) // clicked finish button From e4187a35f300dd9b0eeaef577cb4f0e298262c7a Mon Sep 17 00:00:00 2001 From: Biscuit Boy Date: Sun, 1 Oct 2017 05:04:42 +1000 Subject: [PATCH 11/29] Fixed Close to Home (Archer) Fixed the Close to Home (Archer) Quest --- scripts/chai/quest/ManFst003.chai | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/scripts/chai/quest/ManFst003.chai b/scripts/chai/quest/ManFst003.chai index 8d592cff..403d18d3 100644 --- a/scripts/chai/quest/ManFst003.chai +++ b/scripts/chai/quest/ManFst003.chai @@ -9,11 +9,11 @@ // Start NPC: 1001140 // End NPC: 1000100 -class ManFst003Def +class ManFst003Def { def ManFst003Def() { - // Basic quest information + // Basic quest information this.name = "Close to Home"; this.id = 65659; @@ -24,13 +24,13 @@ class ManFst003Def // GetQuestUI8BL // GetQuestUI8CH - // Steps in this quest ( 0 is before accepting, + // Steps in this quest ( 0 is before accepting, // 1 is first, 255 means ready for turning it in this.SEQ_0 = 0; this.SEQ_1 = 1; this.SEQ_FINISH = 255; - // Quest rewards + // Quest rewards this.RewardExpFactor = 100; this.RewardGil = 107; @@ -74,7 +74,6 @@ class ManFst003Def def checkQuestCompletion( player, varIdx ) { - print( varIdx ); if (varIdx == 3) { player.questMessage(this.id, 1, 0, 0, 0 ); @@ -118,8 +117,8 @@ class ManFst003Def player.eventPlay( this.id, 1, 0x0EFB/*flags*/, 0/*unk*/, 0/*unk*/, fun( player, eventId, param1, param2, param3 ) { - player.setQuestUI8AL( ManFst004.id, 1 ); - ManFst003.checkQuestCompletion( player, 1 ); + player.setQuestUI8AL( ManFst003.id, 1 ); + ManFst003.checkQuestCompletion( player, 0 ); }); } @@ -128,7 +127,7 @@ class ManFst003Def player.eventPlay( this.id, 2, 0, 0, 0, fun( player, eventId, param1, param2, param3 ) { - player.setQuestUI8BH( ManFst004.id, 1 ); + player.setQuestUI8BH( ManFst003.id, 1 ); ManFst003.checkQuestCompletion( player, 3 ); }); } @@ -207,8 +206,8 @@ class ManFst003Def player.eventPlay( this.id, 100, 0x0EFB, 0, 0, fun( player, eventId, param1, param2, param3 ) { - player.setQuestUI8CH( ManFst004.id, 0 ); // remove key item, since we have just traded it - player.setQuestUI8BL( ManFst004.id, 1 ); + player.setQuestUI8CH( ManFst003.id, 0 ); // remove key item, since we have just traded it + player.setQuestUI8BL( ManFst003.id, 1 ); ManFst003.checkQuestCompletion(player, 2 ); }); } @@ -237,7 +236,6 @@ class ManFst003Def }, fun( player, eventId, additional ) {}, eventId ); - player.unlock(); } else if( actor == this.ACTOR2 ) { @@ -257,4 +255,3 @@ class ManFst003Def }; GLOBAL ManFst003 = ManFst003Def(); - From 15278c593ff05184a0534b9e158317da6eb0730f Mon Sep 17 00:00:00 2001 From: amibu Date: Sun, 1 Oct 2017 01:14:43 +0200 Subject: [PATCH 12/29] Basic invincibility --- src/servers/Server_Common/Common.h | 7 ++++ src/servers/Server_Zone/Actor/Actor.cpp | 32 +++++++++++++++++-- src/servers/Server_Zone/Actor/Actor.h | 6 ++++ src/servers/Server_Zone/Actor/BattleNpc.cpp | 2 ++ src/servers/Server_Zone/Actor/Player.cpp | 1 + .../Network/Handlers/GMCommandHandlers.cpp | 12 +++++++ 6 files changed, 57 insertions(+), 3 deletions(-) diff --git a/src/servers/Server_Common/Common.h b/src/servers/Server_Common/Common.h index 15b0ccc6..190e6b9f 100644 --- a/src/servers/Server_Common/Common.h +++ b/src/servers/Server_Common/Common.h @@ -628,6 +628,13 @@ namespace Core { StdDot, }; + enum InvincibilityType : uint8_t + { + InvincibilityNone = 0, + InvincibilityRefill = 1, + InvincibilityStayAlive = 2, + }; + enum struct PlayerStateFlag : uint8_t { NoCombat, diff --git a/src/servers/Server_Zone/Actor/Actor.cpp b/src/servers/Server_Zone/Actor/Actor.cpp index 1b4e3c38..fe358dc0 100644 --- a/src/servers/Server_Zone/Actor/Actor.cpp +++ b/src/servers/Server_Zone/Actor/Actor.cpp @@ -109,6 +109,12 @@ uint16_t Core::Entity::Actor::getGp() const return m_gp; } +/*! \return current GP */ +InvincibilityType Core::Entity::Actor::getInvincibilityType() const +{ + return m_invincibilityType; +} + /*! \return current class or job */ Core::Common::ClassJob Core::Entity::Actor::getClass() const { @@ -161,18 +167,21 @@ uint32_t Core::Entity::Actor::getMaxMp() const void Core::Entity::Actor::resetHp() { m_hp = getMaxHp(); + sendStatusUpdate( true ); } /*! \return reset mp to current max mp */ void Core::Entity::Actor::resetMp() { m_mp = getMaxMp(); + sendStatusUpdate(true); } /*! \param hp amount to set ( caps to maxHp ) */ void Core::Entity::Actor::setHp( uint32_t hp ) { m_hp = hp < getMaxHp() ? hp : getMaxHp(); + sendStatusUpdate(true); } /*! \param mp amount to set ( caps to maxMp ) */ @@ -181,12 +190,19 @@ void Core::Entity::Actor::setMp( uint32_t mp ) m_mp = mp < getMaxMp() ? mp : getMaxMp(); } -/*! \param mp amount to set ( caps to maxMp ) */ +/*! \param gp amount to set*/ void Core::Entity::Actor::setGp( uint32_t gp ) { m_gp = gp; } +/*! \param type invincibility type to set */ +void Core::Entity::Actor::setInvincibilityType( Common::InvincibilityType type ) +{ + m_invincibilityType = type; +} + + /*! \return current status of the actor */ Core::Entity::Actor::ActorStatus Core::Entity::Actor::getStatus() const { @@ -331,8 +347,18 @@ void Core::Entity::Actor::takeDamage( uint32_t damage ) { if( damage >= m_hp ) { - m_hp = 0; - die(); + switch( m_invincibilityType ) { + case InvincibilityNone: + setHp( 0 ); + die(); + break; + case InvincibilityRefill: + resetHp(); + break; + case InvincibilityStayAlive: + setHp( 0 ); + break; + } } else m_hp -= damage; diff --git a/src/servers/Server_Zone/Actor/Actor.h b/src/servers/Server_Zone/Actor/Actor.h index de6b9118..bf316c15 100644 --- a/src/servers/Server_Zone/Actor/Actor.h +++ b/src/servers/Server_Zone/Actor/Actor.h @@ -150,6 +150,8 @@ protected: Action::ActionPtr m_pCurrentAction; /*! Container for status effects */ StatusEffect::StatusEffectContainerPtr m_pStatusEffectContainer; + /*! Invincibility type */ + Common::InvincibilityType m_invincibilityType; public: Actor(); @@ -199,6 +201,8 @@ public: uint16_t getGp() const; + Common::InvincibilityType getInvincibilityType() const; + Common::ClassJob getClass() const; uint8_t getClassAsInt() const; @@ -225,6 +229,8 @@ public: void setGp( uint32_t gp ); + void setInvincibilityType( Common::InvincibilityType type ); + void die(); ActorStatus getStatus() const; diff --git a/src/servers/Server_Zone/Actor/BattleNpc.cpp b/src/servers/Server_Zone/Actor/BattleNpc.cpp index b9891203..1c5f9734 100644 --- a/src/servers/Server_Zone/Actor/BattleNpc.cpp +++ b/src/servers/Server_Zone/Actor/BattleNpc.cpp @@ -82,6 +82,8 @@ Core::Entity::BattleNpc::BattleNpc( uint32_t modelId, uint32_t nameid, const Com m_mobType = mobType; + m_invincibilityType = InvincibilityType::InvincibilityNone; + //m_type = static_cast< Common::ActorType >( type ); } diff --git a/src/servers/Server_Zone/Actor/Player.cpp b/src/servers/Server_Zone/Actor/Player.cpp index 49bc2ad3..03de3b3e 100644 --- a/src/servers/Server_Zone/Actor/Player.cpp +++ b/src/servers/Server_Zone/Actor/Player.cpp @@ -82,6 +82,7 @@ Core::Entity::Player::Player() : m_onlineStatus = 0; m_queuedZoneing = nullptr; m_status = ActorStatus::Idle; + m_invincibilityType = InvincibilityType::InvincibilityNone; memset( m_questTracking, 0, sizeof( m_questTracking ) ); memset( m_name, 0, sizeof( m_name ) ); diff --git a/src/servers/Server_Zone/Network/Handlers/GMCommandHandlers.cpp b/src/servers/Server_Zone/Network/Handlers/GMCommandHandlers.cpp index 973b4bb1..97746ed7 100644 --- a/src/servers/Server_Zone/Network/Handlers/GMCommandHandlers.cpp +++ b/src/servers/Server_Zone/Network/Handlers/GMCommandHandlers.cpp @@ -70,6 +70,7 @@ enum GmCommand Tp = 0x0066, Gp = 0x0067, Exp = 0x0068, + Inv = 0x006A, Item = 0x00C8, Gil = 0x00C9, @@ -352,6 +353,17 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac " was set to " + std::to_string( targetPlayer->getGcRankArray()[targetPlayer->getGc() - 1] ) ); break; } + case GmCommand::Inv: + { + if( targetActor->getInvincibilityType() == Common::InvincibilityType::InvincibilityRefill ) + targetActor->setInvincibilityType( Common::InvincibilityType::InvincibilityNone ); + else + targetActor->setInvincibilityType( Common::InvincibilityType::InvincibilityRefill ); + + pPlayer->sendNotice( "Invincibility for " + targetPlayer->getName() + + " was was switched." ); + break; + } default: pPlayer->sendUrgent( "GM1 Command not implemented: " + std::to_string( commandId ) ); From 606f6e126f396a129b39f758a290ea161d43323a Mon Sep 17 00:00:00 2001 From: amibu Date: Sun, 1 Oct 2017 01:19:41 +0200 Subject: [PATCH 13/29] Forgot a comment --- src/servers/Server_Zone/Actor/Actor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/servers/Server_Zone/Actor/Actor.cpp b/src/servers/Server_Zone/Actor/Actor.cpp index fe358dc0..fe8703e6 100644 --- a/src/servers/Server_Zone/Actor/Actor.cpp +++ b/src/servers/Server_Zone/Actor/Actor.cpp @@ -109,7 +109,7 @@ uint16_t Core::Entity::Actor::getGp() const return m_gp; } -/*! \return current GP */ +/*! \return current invincibility type */ InvincibilityType Core::Entity::Actor::getInvincibilityType() const { return m_invincibilityType; From c8216f05285a14a9b7ca942e60bdebb3bcc94984 Mon Sep 17 00:00:00 2001 From: amibu Date: Sun, 1 Oct 2017 01:20:36 +0200 Subject: [PATCH 14/29] Style fixes --- src/servers/Server_Zone/Actor/Actor.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/servers/Server_Zone/Actor/Actor.cpp b/src/servers/Server_Zone/Actor/Actor.cpp index fe8703e6..3967e7aa 100644 --- a/src/servers/Server_Zone/Actor/Actor.cpp +++ b/src/servers/Server_Zone/Actor/Actor.cpp @@ -174,26 +174,28 @@ void Core::Entity::Actor::resetHp() void Core::Entity::Actor::resetMp() { m_mp = getMaxMp(); - sendStatusUpdate(true); + sendStatusUpdate( true ); } /*! \param hp amount to set ( caps to maxHp ) */ void Core::Entity::Actor::setHp( uint32_t hp ) { m_hp = hp < getMaxHp() ? hp : getMaxHp(); - sendStatusUpdate(true); + sendStatusUpdate( true ); } /*! \param mp amount to set ( caps to maxMp ) */ void Core::Entity::Actor::setMp( uint32_t mp ) { m_mp = mp < getMaxMp() ? mp : getMaxMp(); + sendStatusUpdate( true ); } /*! \param gp amount to set*/ void Core::Entity::Actor::setGp( uint32_t gp ) { m_gp = gp; + sendStatusUpdate( true ); } /*! \param type invincibility type to set */ From 0245597c6d65358dedc3be288b6da2d644237819 Mon Sep 17 00:00:00 2001 From: amibu Date: Sun, 1 Oct 2017 01:23:44 +0200 Subject: [PATCH 15/29] More stuff i forgot --- src/servers/Server_Common/Common.h | 6 +++--- .../Server_Zone/Network/Handlers/GMCommandHandlers.cpp | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/servers/Server_Common/Common.h b/src/servers/Server_Common/Common.h index 190e6b9f..8bcb4a5f 100644 --- a/src/servers/Server_Common/Common.h +++ b/src/servers/Server_Common/Common.h @@ -630,9 +630,9 @@ namespace Core { enum InvincibilityType : uint8_t { - InvincibilityNone = 0, - InvincibilityRefill = 1, - InvincibilityStayAlive = 2, + InvincibilityNone, + InvincibilityRefill, + InvincibilityStayAlive, }; enum struct PlayerStateFlag : uint8_t diff --git a/src/servers/Server_Zone/Network/Handlers/GMCommandHandlers.cpp b/src/servers/Server_Zone/Network/Handlers/GMCommandHandlers.cpp index 97746ed7..36c1949a 100644 --- a/src/servers/Server_Zone/Network/Handlers/GMCommandHandlers.cpp +++ b/src/servers/Server_Zone/Network/Handlers/GMCommandHandlers.cpp @@ -361,7 +361,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac targetActor->setInvincibilityType( Common::InvincibilityType::InvincibilityRefill ); pPlayer->sendNotice( "Invincibility for " + targetPlayer->getName() + - " was was switched." ); + " was switched." ); break; } From 303f8090d0b91bffe9d8019f8648dc580ea9ce28 Mon Sep 17 00:00:00 2001 From: Mordred Date: Sun, 1 Oct 2017 01:42:07 +0200 Subject: [PATCH 16/29] Fixed playerStateFlags being wrongfully offset by 1 bit --- src/servers/Server_Common/Common.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/servers/Server_Common/Common.h b/src/servers/Server_Common/Common.h index 15b0ccc6..f573dfc6 100644 --- a/src/servers/Server_Common/Common.h +++ b/src/servers/Server_Common/Common.h @@ -630,6 +630,7 @@ namespace Core { enum struct PlayerStateFlag : uint8_t { + SomeFlag, NoCombat, Combat, Casting, From 598d038aea8259d475fa80758f77d2a3bd8fd895 Mon Sep 17 00:00:00 2001 From: Mordred Date: Sun, 1 Oct 2017 17:58:11 +0200 Subject: [PATCH 17/29] refactoring of server zone mainloop --- src/servers/Server_Common/Common.h | 7 ++-- src/servers/Server_Zone/ServerZone.cpp | 49 ++++++++++++++++---------- src/servers/Server_Zone/ServerZone.h | 6 ++++ 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/servers/Server_Common/Common.h b/src/servers/Server_Common/Common.h index f573dfc6..609496a9 100644 --- a/src/servers/Server_Common/Common.h +++ b/src/servers/Server_Common/Common.h @@ -638,9 +638,9 @@ namespace Core { StatusAffliction1, Occupied, Occupied1, - Occupied2, Occupied3, + BoundByDuty, Occupied4, DuelingArea, @@ -651,6 +651,7 @@ namespace Core { PreparingToCraft, Gathering, Fishing, + BeingRaised, BetweenAreas, Stealthed, @@ -661,9 +662,9 @@ namespace Core { BetweenAreas1, SystemError, LoggingOut, + InvalidLocation, WaitingForDuty, - BoundByDuty1, Mounting, WatchingCutscene, @@ -681,9 +682,9 @@ namespace Core { FreeTrail, BeingMoved, Mounting2, - StatusAffliction3, StatusAffliction4, + RegisteringRaceOrMatch, WaitingForRaceOrMatch, WaitingForTripleTriadMatch, diff --git a/src/servers/Server_Zone/ServerZone.cpp b/src/servers/Server_Zone/ServerZone.cpp index 16042e03..32d6b9e1 100644 --- a/src/servers/Server_Zone/ServerZone.cpp +++ b/src/servers/Server_Zone/ServerZone.cpp @@ -41,7 +41,8 @@ Core::LinkshellMgr g_linkshellMgr; Core::ServerZone::ServerZone( const std::string& configPath, uint16_t serverId ) - : m_configPath( configPath ) + : m_configPath( configPath ), + m_bRunning( true ) { m_pConfig = XMLConfigPtr( new XMLConfig ); } @@ -224,18 +225,32 @@ void Core::ServerZone::run( int32_t argc, char* argv[] ) g_zoneMgr.createZones(); std::vector< std::thread > thread_list; - thread_list.push_back( std::thread( std::bind( &Network::Hive::Run, hive.get() ) ) ); + thread_list.emplace_back( std::thread( std::bind( &Network::Hive::Run, hive.get() ) ) ); g_log.info( "Server listening on port: " + std::to_string( m_port ) ); g_log.info( "Ready for connections..." ); - while( true ) + mainLoop(); + + for( auto& thread_entry : thread_list ) { - std::this_thread::sleep_for( std::chrono::milliseconds( 50 ) ); + thread_entry.join(); + } + +} + +void Core::ServerZone::mainLoop() +{ + while( isRunning() ) + { + this_thread::sleep_for( chrono::milliseconds( 50 ) ); g_zoneMgr.updateZones(); - std::lock_guard lock( m_sessionMutex ); - for( auto sessionIt : m_sessionMap ) + + auto currTime = static_cast< uint32_t >( time( nullptr ) ); + + lock_guard< std::mutex > lock( this->m_sessionMutex ); + for( auto sessionIt : this->m_sessionMap ) { auto session = sessionIt.second; if( session && session->getPlayer() ) @@ -247,9 +262,9 @@ void Core::ServerZone::run( int32_t argc, char* argv[] ) } } - uint32_t currTime = static_cast< uint32_t >( time( nullptr ) ); - auto it = m_sessionMap.begin(); - for( ; it != m_sessionMap.end(); ) + + auto it = this->m_sessionMap.begin(); + for( ; it != this->m_sessionMap.end(); ) { uint32_t diff = currTime - it->second->getLastDataTime(); @@ -257,11 +272,11 @@ void Core::ServerZone::run( int32_t argc, char* argv[] ) if( diff > 20 ) { - g_log.info( "[" + std::to_string( it->second->getId() ) + "] Session time out" ); + g_log.info("[" + std::to_string(it->second->getId() ) + "] Session time out" ); it->second->close(); // if( it->second.unique() ) { - it = m_sessionMap.erase( it ); + it = this->m_sessionMap.erase(it ); } } else @@ -272,13 +287,6 @@ void Core::ServerZone::run( int32_t argc, char* argv[] ) } } - - // currently never reached, need a "stopServer" variable to break out of the above while loop - /*for( auto& thread_entry : thread_list ) - { - thread_entry.join(); - }*/ - } bool Core::ServerZone::createSession( uint32_t sessionId ) @@ -364,3 +372,8 @@ void Core::ServerZone::updateSession( std::string playerName ) it->second->loadPlayer(); } +bool Core::ServerZone::isRunning() const +{ + return m_bRunning; +} + diff --git a/src/servers/Server_Zone/ServerZone.h b/src/servers/Server_Zone/ServerZone.h index 2472c487..130d2f22 100644 --- a/src/servers/Server_Zone/ServerZone.h +++ b/src/servers/Server_Zone/ServerZone.h @@ -40,12 +40,18 @@ namespace Core { Entity::BattleNpcTemplatePtr getBnpcTemplate( std::string templateName ); + void mainLoop(); + + bool isRunning() const; + private: uint16_t m_port; std::string m_ip; + bool m_bRunning; + std::string m_configPath; XMLConfigPtr m_pConfig; From dda9fb2cc698bc193daa068b680ed4453a07a06d Mon Sep 17 00:00:00 2001 From: Mordred Date: Sun, 1 Oct 2017 18:38:58 +0200 Subject: [PATCH 18/29] Some refactoring and TODO tags --- src/servers/Server_Zone/Actor/BattleNpc.cpp | 9 +-- src/servers/Server_Zone/Actor/CalcBattle.cpp | 1 - src/servers/Server_Zone/Actor/Player.cpp | 67 +++---------------- src/servers/Server_Zone/Actor/PlayerEvent.cpp | 48 +++++++++++++ 4 files changed, 62 insertions(+), 63 deletions(-) diff --git a/src/servers/Server_Zone/Actor/BattleNpc.cpp b/src/servers/Server_Zone/Actor/BattleNpc.cpp index b9891203..6ec2a5d7 100644 --- a/src/servers/Server_Zone/Actor/BattleNpc.cpp +++ b/src/servers/Server_Zone/Actor/BattleNpc.cpp @@ -54,6 +54,7 @@ Core::Entity::BattleNpc::BattleNpc( uint32_t modelId, uint32_t nameid, const Com m_type = ActorType::BattleNpc; m_mode = MODE_IDLE; + m_targetId = INVALID_GAME_OBJECT_ID; m_maxHp = 150; m_maxMp = 100; @@ -229,7 +230,7 @@ void Core::Entity::BattleNpc::setOwner( Core::Entity::PlayerPtr pPlayer ) } else { - GamePacketNew< FFXIVIpcActorOwner, ServerZoneIpcType > setOwnerPacket(getId(), INVALID_GAME_OBJECT_ID); + GamePacketNew< FFXIVIpcActorOwner, ServerZoneIpcType > setOwnerPacket(getId(), INVALID_GAME_OBJECT_ID ); setOwnerPacket.data().type = 0x01; setOwnerPacket.data().actorId = INVALID_GAME_OBJECT_ID; sendToInRangeSet( setOwnerPacket ); @@ -251,15 +252,15 @@ bool Core::Entity::BattleNpc::moveTo( Common::FFXIVARR_POSITION3& pos ) // reached destination return true; - float rot = Math::Util::calcAngFrom(getPos().x, getPos().z, pos.x, pos.z); + float rot = Math::Util::calcAngFrom( getPos().x, getPos().z, pos.x, pos.z ); float newRot = PI - rot + (PI / 2); face( pos ); float angle = Math::Util::calcAngFrom( getPos().x, getPos().z, pos.x, pos.z ) + PI; - float x = static_cast< float >( cosf(angle) * 1.1f ); + float x = static_cast< float >( cosf( angle ) * 1.1f ); float y = ( getPos().y + pos.y ) * 0.5f; // fake value while there is no collision - float z = static_cast< float >( sinf(angle) * 1.1f ); + float z = static_cast< float >( sinf( angle ) * 1.1f ); Common::FFXIVARR_POSITION3 newPos; diff --git a/src/servers/Server_Zone/Actor/CalcBattle.cpp b/src/servers/Server_Zone/Actor/CalcBattle.cpp index f33c2e5c..1ef0f325 100644 --- a/src/servers/Server_Zone/Actor/CalcBattle.cpp +++ b/src/servers/Server_Zone/Actor/CalcBattle.cpp @@ -113,7 +113,6 @@ uint32_t CalcBattle::calculateMaxMp( PlayerPtr pPlayer ) return result; } - uint32_t CalcBattle::calculateHealValue( PlayerPtr pPlayer, uint32_t potency ) { auto classInfoIt = g_exdData.m_classJobInfoMap.find( pPlayer->getClass() ); diff --git a/src/servers/Server_Zone/Actor/Player.cpp b/src/servers/Server_Zone/Actor/Player.cpp index 49bc2ad3..a0f72be5 100644 --- a/src/servers/Server_Zone/Actor/Player.cpp +++ b/src/servers/Server_Zone/Actor/Player.cpp @@ -192,7 +192,7 @@ void Core::Entity::Player::prepareZoning( uint16_t targetZone, bool fadeOut, uin preparePacket.data().targetZone = targetZone; preparePacket.data().fadeOutTime = fadeOutTime; preparePacket.data().animation = animation; - preparePacket.data().fadeOut = fadeOut == true ? 1 : 0; + preparePacket.data().fadeOut = static_cast< uint8_t >( fadeOut ? 1 : 0 ); queuePacket( preparePacket ); } @@ -398,7 +398,7 @@ void Core::Entity::Player::setZone( uint32_t zoneId ) if( isLogin() ) { GamePacketNew< FFXIVIpcCFAvailableContents, ServerZoneIpcType > contentFinderList( getId() ); - for( auto i = 0; i < 72; i++ ) + for( auto i = 0; i < sizeof( contentFinderList.data().contents ); i++ ) { // unlock all contents for now contentFinderList.data().contents[i] = 0xFF; @@ -632,7 +632,9 @@ void Core::Entity::Player::gainExp( uint32_t amount ) if( ( currentExp + amount ) >= neededExpToLevel ) { // levelup - amount = ( currentExp + amount - neededExpToLevel ) > neededExpToLevelplus1 ? neededExpToLevelplus1 - 1 : ( currentExp + amount - neededExpToLevel ); + amount = ( currentExp + amount - neededExpToLevel ) > neededExpToLevelplus1 ? + neededExpToLevelplus1 - 1 : + ( currentExp + amount - neededExpToLevel ); setExp( amount ); gainLevel(); queuePacket( ActorControlPacket143( getId(), UpdateUiExp, static_cast< uint8_t >( getClass() ), amount ) ); @@ -791,50 +793,6 @@ void Core::Entity::Player::setLevelForClass( uint8_t level, Core::Common::ClassJ setSyncFlag( PlayerSyncFlags::ExpLevel ); } -void Core::Entity::Player::eventActionStart( uint32_t eventId, - uint32_t action, - ActionCallback finishCallback, - ActionCallback interruptCallback, - uint64_t additional ) -{ - Action::ActionPtr pEventAction( new Action::EventAction( shared_from_this(), eventId, action, - finishCallback, interruptCallback, additional ) ); - - setCurrentAction( pEventAction ); - auto pEvent = getEvent( eventId ); - - if( !pEvent && getEventCount() ) - { - // We're trying to play a nested event, need to start it first. - eventStart( getId(), eventId, Event::Event::Nest, 0, 0 ); - pEvent = getEvent( eventId ); - } - else if( !pEvent ) - { - g_log.error( "Could not find event " + std::to_string( eventId ) + ", event has not been started!" ); - return; - } - - if( pEvent ) - pEvent->setPlayedScene( true ); - pEventAction->onStart(); -} - - -void Core::Entity::Player::eventItemActionStart( uint32_t eventId, - uint32_t action, - ActionCallback finishCallback, - ActionCallback interruptCallback, - uint64_t additional ) -{ - Action::ActionPtr pEventItemAction( new Action::EventItemAction( shared_from_this(), eventId, action, - finishCallback, interruptCallback, additional ) ); - - setCurrentAction( pEventItemAction ); - - pEventItemAction->onStart(); -} - void Core::Entity::Player::sendModel() { ModelEquipPacket modelEquip( getAsPlayer() ); @@ -973,7 +931,7 @@ void Core::Entity::Player::setGcRankAt( uint8_t index, uint8_t rank ) setSyncFlag( PlayerSyncFlags::GC ); } -const uint8_t * Core::Entity::Player::getStateFlags() const +const uint8_t* Core::Entity::Player::getStateFlags() const { return m_stateFlags; } @@ -1086,21 +1044,16 @@ void Core::Entity::Player::update( int64_t currTime ) m_lastUpdate = currTime; - // @TODO needs to happen in a if check. Don't want autoattacking while an action is being performed. if( !checkAction() ) { - if( m_targetId ) + if( m_targetId && m_currentStance == Entity::Actor::Stance::Active && isAutoattackOn() ) { auto mainWeap = m_pInventory->getItemAt( Inventory::GearSet0, Inventory::EquipSlot::MainHand ); + // @TODO i dislike this, iterating over all in range actors when you already know the id of the actor you need... for( auto actor : m_inRangeActors ) { - if( isAutoattackOn() && - actor->getId() == m_targetId && - actor->isAlive() && - mainWeap && - m_currentStance == Entity::Actor::Stance::Active - ) + if( actor->getId() == m_targetId && actor->isAlive() && mainWeap ) { // default autoattack range // TODO make this dependant on bnpc size @@ -1644,9 +1597,7 @@ uint32_t Core::Entity::Player::getCFPenaltyMinutes() const // check if penalty timestamp already passed current time if (currentTimestamp > endTimestamp) - { return 0; - } auto deltaTime = endTimestamp - currentTimestamp; return static_cast< uint32_t > ( ceil( static_cast< float > (deltaTime) / 60 ) ); diff --git a/src/servers/Server_Zone/Actor/PlayerEvent.cpp b/src/servers/Server_Zone/Actor/PlayerEvent.cpp index f0bf77fe..721456e9 100644 --- a/src/servers/Server_Zone/Actor/PlayerEvent.cpp +++ b/src/servers/Server_Zone/Actor/PlayerEvent.cpp @@ -18,6 +18,10 @@ #include "src/servers/Server_Zone/Network/PacketWrappers/EventPlayPacket.h" #include "src/servers/Server_Zone/Network/PacketWrappers/EventFinishPacket.h" +#include "src/servers/Server_Zone/Action/EventAction.h" +#include "src/servers/Server_Zone/Action/EventItemAction.h" + +#include "src/servers/Server_Zone/Event/Event.h" #include "src/servers/Server_Zone/Event/Event.h" #include "Server_Zone/ServerZone.h" @@ -230,6 +234,50 @@ void Core::Entity::Player::eventFinish( uint32_t eventId, uint32_t freePlayer ) } } +void Core::Entity::Player::eventActionStart( uint32_t eventId, + uint32_t action, + ActionCallback finishCallback, + ActionCallback interruptCallback, + uint64_t additional ) +{ + Action::ActionPtr pEventAction( new Action::EventAction( shared_from_this(), eventId, action, + finishCallback, interruptCallback, additional ) ); + + setCurrentAction( pEventAction ); + auto pEvent = getEvent( eventId ); + + if( !pEvent && getEventCount() ) + { + // We're trying to play a nested event, need to start it first. + eventStart( getId(), eventId, Event::Event::Nest, 0, 0 ); + pEvent = getEvent( eventId ); + } + else if( !pEvent ) + { + g_log.error( "Could not find event " + std::to_string( eventId ) + ", event has not been started!" ); + return; + } + + if( pEvent ) + pEvent->setPlayedScene( true ); + pEventAction->onStart(); +} + + +void Core::Entity::Player::eventItemActionStart( uint32_t eventId, + uint32_t action, + ActionCallback finishCallback, + ActionCallback interruptCallback, + uint64_t additional ) +{ + Action::ActionPtr pEventItemAction( new Action::EventItemAction( shared_from_this(), eventId, action, + finishCallback, interruptCallback, additional ) ); + + setCurrentAction( pEventItemAction ); + + pEventItemAction->onStart(); +} + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void Core::Entity::Player::onLogin() From 57a1c2e8a6af408302a110b946a80fbd90e6dc90 Mon Sep 17 00:00:00 2001 From: Mordred Date: Sun, 1 Oct 2017 18:43:18 +0200 Subject: [PATCH 19/29] More refactoring, clean up --- src/servers/Server_Zone/Actor/Actor.cpp | 15 +++++++-------- src/servers/Server_Zone/Actor/BattleNpc.h | 2 +- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/servers/Server_Zone/Actor/Actor.cpp b/src/servers/Server_Zone/Actor/Actor.cpp index 1b4e3c38..dd350a4c 100644 --- a/src/servers/Server_Zone/Actor/Actor.cpp +++ b/src/servers/Server_Zone/Actor/Actor.cpp @@ -53,13 +53,13 @@ std::string Core::Entity::Actor::getName() const /*! \return true if the actor is of type player */ bool Core::Entity::Actor::isPlayer() const { - return ( m_type == ActorType::Player ? true : false ); + return m_type == ActorType::Player; } /*! \return true if the actor is of type mob */ bool Core::Entity::Actor::isMob() const { - return ( m_type == ActorType::BattleNpc ? true : false ); + return m_type == ActorType::BattleNpc; } /*! \return list of actors currently in range */ @@ -240,10 +240,7 @@ bool Core::Entity::Actor::face( const Common::FFXIVARR_POSITION3& p ) setRotation( newRot ); - if( oldRot != newRot ) - return true; - - return false; + return oldRot != newRot ? true : false; } /*! @@ -629,7 +626,8 @@ void Core::Entity::Actor::addStatusEffect( StatusEffect::StatusEffectPtr pEffect /*! \param StatusEffectPtr to be applied to the actor */ void Core::Entity::Actor::addStatusEffectById( uint32_t id, int32_t duration, Entity::Actor& pSource, uint16_t param ) { - StatusEffect::StatusEffectPtr effect( new StatusEffect::StatusEffect( id, pSource.shared_from_this(), shared_from_this(), duration, 3000 ) ); + StatusEffect::StatusEffectPtr effect( new StatusEffect::StatusEffect( id, pSource.shared_from_this(), + shared_from_this(), duration, 3000 ) ); effect->setParam( param ); addStatusEffect( effect ); } @@ -639,7 +637,8 @@ void Core::Entity::Actor::addStatusEffectByIdIfNotExist( uint32_t id, int32_t du { if( !m_pStatusEffectContainer->hasStatusEffect( id ) ) { - StatusEffect::StatusEffectPtr effect( new StatusEffect::StatusEffect( id, pSource.shared_from_this(), shared_from_this(), duration, 3000 ) ); + StatusEffect::StatusEffectPtr effect( new StatusEffect::StatusEffect( id, pSource.shared_from_this(), + shared_from_this(), duration, 3000 ) ); effect->setParam( param ); addStatusEffect( effect ); } diff --git a/src/servers/Server_Zone/Actor/BattleNpc.h b/src/servers/Server_Zone/Actor/BattleNpc.h index d13d082b..f74f9536 100644 --- a/src/servers/Server_Zone/Actor/BattleNpc.h +++ b/src/servers/Server_Zone/Actor/BattleNpc.h @@ -104,7 +104,7 @@ private: uint32_t m_unk2; std::set< HateListEntry* > m_hateList; ActorPtr m_pOwner; - int32_t m_timeOfDeath; + uint32_t m_timeOfDeath; uint32_t m_mobType; }; From ac752ab5248e115c79398a14901002f5c2249d9f Mon Sep 17 00:00:00 2001 From: Maru Date: Sun, 1 Oct 2017 21:50:09 -0300 Subject: [PATCH 20/29] ActionCollision implementation work; More definitions for actionInfo; Fix compiler warnings; --- src/servers/Server_Common/Exd/ExdData.cpp | 25 ++-- src/servers/Server_Common/Exd/ExdData.h | 6 + .../Server_Zone/Action/ActionCollision.cpp | 45 ++++---- .../Server_Zone/Action/ActionCollision.h | 6 +- src/servers/Server_Zone/Actor/Actor.cpp | 107 +++++++++++------- src/servers/Server_Zone/Actor/Player.h | 2 +- src/servers/Server_Zone/Actor/PlayerQuest.cpp | 8 +- .../Server_Zone/Inventory/Inventory.cpp | 6 +- src/servers/Server_Zone/Inventory/Inventory.h | 4 +- 9 files changed, 117 insertions(+), 92 deletions(-) diff --git a/src/servers/Server_Common/Exd/ExdData.cpp b/src/servers/Server_Common/Exd/ExdData.cpp index 17007e55..3eb295fd 100644 --- a/src/servers/Server_Common/Exd/ExdData.cpp +++ b/src/servers/Server_Common/Exd/ExdData.cpp @@ -345,30 +345,20 @@ bool Core::Data::ExdData::loadActionInfo() uint8_t points_type = getField< uint8_t >( fields, 30 ); // 30 uint16_t points_cost = getField< uint16_t >( fields, 31 ); // 31 -<<<<<<< HEAD + bool is_instant = getField< bool >( fields, 35 ); // 35 uint16_t cast_time = getField< uint16_t >( fields, 36 ); // 36 uint16_t recast_time = getField< uint16_t >( fields, 37 ); // 37 int8_t model = getField< int8_t >( fields, 39 ); // 39 uint8_t aspect = getField< uint8_t >( fields, 40 ); // 40 - + + uint16_t toggle_status_id = getField< uint16_t >( fields, 42 ); // 42 + bool affects_position = getField< bool >( fields, 47 ); // 47 info->id = id; info->name = name; info->category = category; -======= - bool is_instant = getField< bool >( fields, 35 ); // 35 - uint16_t cast_time = getField< uint16_t >( fields, 36 ); // 36 - uint16_t recast_time = getField< uint16_t >( fields, 37 ); // 37 - - int8_t model = getField< int8_t >( fields, 39 ); // 39: Action model - uint8_t aspect = getField< uint8_t >( fields, 40 ); // 40: Action aspect - - info->id = id; - info->name = name; - info->category = category; ->>>>>>> 08f4c7651fafdaf8f4d98868a94ab4688eb71379 info->class_job = class_job; info->unlock_level = unlock_level; @@ -382,6 +372,7 @@ bool Core::Data::ExdData::loadActionInfo() info->is_ground_aoe = is_ground_aoe; + info->aoe_type = aoe_type; info->aoe_range = aoe_range; info->aoe_width = aoe_width; @@ -396,6 +387,12 @@ bool Core::Data::ExdData::loadActionInfo() info->model = model; info->aspect = aspect; + info->toggle_status_id = toggle_status_id; + info->affects_position = affects_position; + + // If action type is SingleTarget with an AoE radius set, or if action type isn't SingleTarget + info->is_aoe = ( info->aoe_type == 1 && info->aoe_width != 0 ) || ( info->aoe_type != 1 ); + m_actionInfoMap.emplace( std::make_pair( info->id, info ) ); } diff --git a/src/servers/Server_Common/Exd/ExdData.h b/src/servers/Server_Common/Exd/ExdData.h index a23d21ff..f34e6b35 100644 --- a/src/servers/Server_Common/Exd/ExdData.h +++ b/src/servers/Server_Common/Exd/ExdData.h @@ -250,6 +250,12 @@ namespace Core { int8_t model; // 39 uint8_t aspect; // 40 + + uint16_t toggle_status_id; // 42 + + bool affects_position; // 47 + + bool is_aoe; // Internal only }; struct EventItemInfo diff --git a/src/servers/Server_Zone/Action/ActionCollision.cpp b/src/servers/Server_Zone/Action/ActionCollision.cpp index 4c193fd7..a0ab372e 100644 --- a/src/servers/Server_Zone/Action/ActionCollision.cpp +++ b/src/servers/Server_Zone/Action/ActionCollision.cpp @@ -11,46 +11,46 @@ using namespace Core::Entity; using namespace Core::Common; -// todo: add filters for allies, enemies only etc +// todo: add AoE actor limits (16, 32) -bool ActionCollision::isActorCollisionValid( ActorPtr actorPtr, AoeFilter aoeFilter ) +bool ActionCollision::isActorApplicable( ActorPtr actorPtr, TargetFilter targetFilter ) { - bool collisionApplicable = false; - switch ( aoeFilter ) + bool actorApplicable = false; + switch ( targetFilter ) { - case AoeFilter::All: + case TargetFilter::All: { - collisionApplicable = true; + actorApplicable = true; break; } - case AoeFilter::Players: + case TargetFilter::Players: { - collisionApplicable = actorPtr->isPlayer(); + actorApplicable = actorPtr->isPlayer(); break; } - case AoeFilter::Allies: + case TargetFilter::Allies: { // todo: implement ally NPCs - collisionApplicable = !actorPtr->isMob(); + actorApplicable = !actorPtr->isMob(); break; } - case AoeFilter::Party: + case TargetFilter::Party: { // todo: implement party - collisionApplicable = actorPtr->isPlayer(); + actorApplicable = actorPtr->isPlayer(); break; } - case AoeFilter::Enemies: + case TargetFilter::Enemies: { - collisionApplicable = actorPtr->isMob(); + actorApplicable = actorPtr->isMob(); break; } } - return ( collisionApplicable && actorPtr->isAlive() ); + return ( actorApplicable && actorPtr->isAlive() ); } -std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition, std::set< ActorPtr > actorsInRange, boost::shared_ptr< Core::Data::ActionInfo > actionInfo, AoeFilter aoeFilter ) +std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition, std::set< ActorPtr > actorsInRange, boost::shared_ptr< Core::Data::ActionInfo > actionInfo, TargetFilter targetFilter ) { std::set< ActorPtr > actorsCollided; @@ -61,15 +61,14 @@ std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXI { // This is actually needed. There is "splash damage" in actions marked as single target. // Notice how we're using aoe_width. How collision works for SingleTarget is unknown as of now. - // TODO: Isn't it possible to stack 2 players in the same spot and glitch the action collision this way? Investigate for ( auto pActor : actorsInRange ) { // Make sure actor exists. If it doesn't we done goofed. assert( pActor ); // Don't bother wasting on collision if actor doesn't apply for it - if ( !isActorCollisionValid( pActor, aoeFilter ) ) - break; + if ( !isActorApplicable( pActor, targetFilter ) ) + continue; // Test our collision from actor with the area generated by the action from the AoE data if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->aoe_width ) ) @@ -86,8 +85,8 @@ std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXI { assert( pActor ); - if ( !isActorCollisionValid( pActor, aoeFilter ) ) - break; + if ( !isActorApplicable( pActor, targetFilter ) ) + continue; if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->aoe_range ) ) { @@ -102,8 +101,8 @@ std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXI { assert( pActor ); - if ( !isActorCollisionValid( pActor, aoeFilter ) ) - break; + if ( !isActorApplicable( pActor, targetFilter ) ) + continue; if ( boxCollision( pActor->getPos(), aoePosition, actionInfo->aoe_width, actionInfo->aoe_range ) ) { diff --git a/src/servers/Server_Zone/Action/ActionCollision.h b/src/servers/Server_Zone/Action/ActionCollision.h index 9cd92534..cff25934 100644 --- a/src/servers/Server_Zone/Action/ActionCollision.h +++ b/src/servers/Server_Zone/Action/ActionCollision.h @@ -9,7 +9,7 @@ namespace Core { namespace Entity { - enum class AoeFilter + enum class TargetFilter { All, // All actors in the AoE are applicable for collision Players, // Only players @@ -22,8 +22,8 @@ namespace Core { { public: - static bool isActorCollisionValid( ActorPtr actorPtr, AoeFilter aoeFilter ); - static std::set< ActorPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition, std::set< ActorPtr > actorsInRange, boost::shared_ptr< Data::ActionInfo > actionInfo, AoeFilter aoeFilter ); + static bool isActorApplicable( ActorPtr actorPtr, TargetFilter targetFilter ); + static std::set< ActorPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition, std::set< ActorPtr > actorsInRange, boost::shared_ptr< Data::ActionInfo > actionInfo, TargetFilter targetFilter ); private: static bool radiusCollision( Common::FFXIVARR_POSITION3 actorPosition, Common::FFXIVARR_POSITION3 aoePosition, uint16_t radius ); diff --git a/src/servers/Server_Zone/Actor/Actor.cpp b/src/servers/Server_Zone/Actor/Actor.cpp index 8a5b61a2..b9d9e210 100644 --- a/src/servers/Server_Zone/Actor/Actor.cpp +++ b/src/servers/Server_Zone/Actor/Actor.cpp @@ -638,54 +638,67 @@ void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint32_t actionId, u getAsPlayer()->sendDebug( std::to_string( pTarget.getId() ) ); getAsPlayer()->sendDebug( "Handle script skill type: " + std::to_string( type ) ); } - auto actionInfoPtr = g_exdData.getActionInfo( actionId ); + // Todo: Effect packet generator. 90% of this is basically setting params and it's basically unreadable. // Prepare packet. This is seemingly common for all packets in the action handler. GamePacketNew< FFXIVIpcEffect, ServerZoneIpcType > effectPacket( getId() ); effectPacket.data().targetId = pTarget.getId(); effectPacket.data().actionAnimationId = actionId; + effectPacket.data().unknown_62 = 1; // Affects displaying action name next to number in floating text effectPacket.data().unknown_2 = 1; // This seems to have an effect on the "double-cast finish" animation - // effectPacket.data().unknown_3 = 1; effectPacket.data().actionTextId = actionId; effectPacket.data().numEffects = 1; effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() ); effectPacket.data().effectTarget = pTarget.getId(); - effectPacket.data().effects[0].value = 0; - effectPacket.data().effects[0].effectType = ActionEffectType::Damage; - effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalDamage; - effectPacket.data().effects[0].unknown_3 = 7; + // Todo: for each actor, calculate how much damage the calculated value should deal to them - 2-step damage calc. we only have 1-step switch ( type ) { case ActionEffectType::Damage: { - - effectPacket.data().effects[0].value = static_cast< int16_t >( param1 ); + effectPacket.data().effects[0].value = param1; effectPacket.data().effects[0].effectType = ActionEffectType::Damage; effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalDamage; + effectPacket.data().effects[0].unknown_3 = 7; - std::set< ActorPtr > actorsCollided = ActionCollision::getActorsHitFromAction( pTarget.getPos(), getInRangeActors( true ), actionInfoPtr, AoeFilter::Enemies ); - - for ( auto pHitActor : actorsCollided ) + if ( !actionInfoPtr->is_aoe ) { - effectPacket.data().targetId = pHitActor->getId(); - effectPacket.data().unknown_1 = 1; // the magic trick for getting it to work - effectPacket.data().unknown_5 = 1; - effectPacket.data().unknown_8 = 1; - effectPacket.data().actionTextId = 0; - effectPacket.data().effectTarget = pHitActor->getId(); - effectPacket.data().effects[0].value = param1 + ( rand() % 15 ); + // If action on this specific target is valid... + if ( isPlayer() && !ActionCollision::isActorApplicable( pTarget.shared_from_this(), TargetFilter::Enemies ) ) + break; - pHitActor->sendToInRangeSet( effectPacket, true ); // todo: send to range of what? ourselves? when mob script hits this is going to be lacking - pHitActor->takeDamage( static_cast< uint32_t >( param1 ) ); - pHitActor->onActionHostile( shared_from_this() ); + pTarget.takeDamage( static_cast< uint32_t >( param1 ) ); + pTarget.onActionHostile( shared_from_this() ); + sendToInRangeSet( effectPacket, true ); + } + else + { - if ( isPlayer() ) - getAsPlayer()->sendDebug( "AoE hit actor " + pHitActor->getName() ); + std::set< ActorPtr > actorsCollided = ActionCollision::getActorsHitFromAction( pTarget.getPos(), getInRangeActors( true ), actionInfoPtr, TargetFilter::Enemies ); + + for ( auto pHitActor : actorsCollided ) + { + effectPacket.data().targetId = pHitActor->getId(); + effectPacket.data().effectTarget = pHitActor->getId(); + + sendToInRangeSet( effectPacket, true ); // todo: send to range of what? ourselves? when mob script hits this is going to be lacking + pHitActor->takeDamage( static_cast< uint32_t >( param1 ) ); + pHitActor->onActionHostile( shared_from_this() ); + + // Debug + if ( isPlayer() ) + { + if ( pHitActor->isPlayer() ) { + getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) + " (" + pHitActor->getName() + ")" ); + } + else + getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) ); + } + } } break; @@ -699,29 +712,39 @@ void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint32_t actionId, u effectPacket.data().effects[0].effectType = ActionEffectType::Heal; effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalHeal; - sendToInRangeSet( effectPacket, true ); - - // todo: get proper packets: the following was just kind of thrown together from what we know - - std::set< ActorPtr > actorsCollided = ActionCollision::getActorsHitFromAction( pTarget.getPos(), getInRangeActors( true ), actionInfoPtr, AoeFilter::Allies ); - - for ( auto pHitActor : actorsCollided ) + if ( !actionInfoPtr->is_aoe ) { - effectPacket.data().targetId = pHitActor->getId(); - effectPacket.data().unknown_1 = 1; // the magic trick for getting it to work - effectPacket.data().unknown_5 = 1; - effectPacket.data().unknown_8 = 1; - effectPacket.data().actionTextId = 0; - effectPacket.data().effectTarget = pHitActor->getId(); - effectPacket.data().effects[0].value = calculatedHeal + ( rand() % 15 ); + if ( isPlayer() && !ActionCollision::isActorApplicable( pTarget.shared_from_this(), TargetFilter::Allies ) ) + break; - pHitActor->sendToInRangeSet( effectPacket, true ); - pHitActor->heal( calculatedHeal ); - - if ( isPlayer() ) - getAsPlayer()->sendDebug( "AoE hit actor " + pHitActor->getName() ); + sendToInRangeSet( effectPacket, true ); + pTarget.heal( calculatedHeal ); } + else + { + // todo: get proper packets: the following was just kind of thrown together from what we know. atm buggy (packets look "delayed" from client) + std::set< ActorPtr > actorsCollided = ActionCollision::getActorsHitFromAction( pTarget.getPos(), getInRangeActors( true ), actionInfoPtr, TargetFilter::Allies ); + + for ( auto pHitActor : actorsCollided ) + { + effectPacket.data().targetId = pTarget.getId(); + effectPacket.data().effectTarget = pHitActor->getId(); + + sendToInRangeSet( effectPacket, true ); + pHitActor->heal( calculatedHeal ); + + // Debug + if ( isPlayer() ) + { + if ( pHitActor->isPlayer() ) { + getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) + " (" + pHitActor->getName() + ")" ); + } + else + getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) ); + } + } + } break; } diff --git a/src/servers/Server_Zone/Actor/Player.h b/src/servers/Server_Zone/Actor/Player.h index 11104463..568419f9 100644 --- a/src/servers/Server_Zone/Actor/Player.h +++ b/src/servers/Server_Zone/Actor/Player.h @@ -103,7 +103,7 @@ public: /*! load data for currently active quests */ bool loadActiveQuests(); /*! update quest ( register it as active quest if new ) */ - void updateQuest( uint16_t questId, uint16_t sequence ); + void updateQuest( uint16_t questId, uint8_t sequence ); /*! return true if quest is currently active */ bool hasQuest( uint16_t questId ); /*! return the current quest sequence */ diff --git a/src/servers/Server_Zone/Actor/PlayerQuest.cpp b/src/servers/Server_Zone/Actor/PlayerQuest.cpp index c6038f61..668460a7 100644 --- a/src/servers/Server_Zone/Actor/PlayerQuest.cpp +++ b/src/servers/Server_Zone/Actor/PlayerQuest.cpp @@ -74,7 +74,7 @@ bool Core::Entity::Player::loadActiveQuests() void Core::Entity::Player::finishQuest( uint16_t questId ) { - int8_t idx = getQuestIndex( static_cast< uint16_t >( questId ) ); + int16_t idx = getQuestIndex( questId ); if( ( idx != -1 ) && ( m_activeQuests[idx] != nullptr ) ) { @@ -100,7 +100,7 @@ void Core::Entity::Player::finishQuest( uint16_t questId ) m_questTracking[ii] = -1; } - boost::shared_ptr pQuest = m_activeQuests[idx]; + boost::shared_ptr< QuestActive > pQuest = m_activeQuests[idx]; m_activeQuests[idx].reset(); m_freeQuestIdxQueue.push( idx ); @@ -123,7 +123,7 @@ void Core::Entity::Player::unfinishQuest( uint16_t questId ) void Core::Entity::Player::removeQuest( uint16_t questId ) { - int8_t idx = getQuestIndex( static_cast< uint16_t >( questId ) ); + int16_t idx = getQuestIndex( questId ); if( ( idx != -1 ) && ( m_activeQuests[idx] != nullptr ) ) { @@ -973,7 +973,7 @@ uint8_t Core::Entity::Player::getQuestSeq( uint16_t questId ) return 0; } -void Core::Entity::Player::updateQuest( uint16_t questId, uint16_t sequence ) +void Core::Entity::Player::updateQuest( uint16_t questId, uint8_t sequence ) { if( hasQuest( questId ) ) { diff --git a/src/servers/Server_Zone/Inventory/Inventory.cpp b/src/servers/Server_Zone/Inventory/Inventory.cpp index bffe043b..2b552583 100644 --- a/src/servers/Server_Zone/Inventory/Inventory.cpp +++ b/src/servers/Server_Zone/Inventory/Inventory.cpp @@ -440,14 +440,14 @@ bool Core::Inventory::removeCrystal( CrystalType type, uint32_t amount ) return true; } -bool Core::Inventory::isObtainable( uint32_t catalogId, uint16_t quantity ) +bool Core::Inventory::isObtainable( uint32_t catalogId, uint8_t quantity ) { return true; } -int16_t Core::Inventory::addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint16_t quantity ) +int16_t Core::Inventory::addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint8_t quantity ) { auto itemInfo = g_exdData.getItemInfo( catalogId ); @@ -587,7 +587,7 @@ void Core::Inventory::swapItem( uint16_t fromInventoryId, uint8_t fromSlotId, ui { updateContainer( fromInventoryId, fromSlotId, nullptr ); fromInventoryId = getArmoryToEquipSlot( toSlot ); - fromSlotId = m_inventoryMap[fromInventoryId]->getFreeSlot(); + fromSlotId = static_cast < uint8_t >( m_inventoryMap[fromInventoryId]->getFreeSlot() ); } auto containerTypeFrom = getContainerType( fromInventoryId ); diff --git a/src/servers/Server_Zone/Inventory/Inventory.h b/src/servers/Server_Zone/Inventory/Inventory.h index adc99715..63dab641 100644 --- a/src/servers/Server_Zone/Inventory/Inventory.h +++ b/src/servers/Server_Zone/Inventory/Inventory.h @@ -140,7 +140,7 @@ public: InvSlotPairVec getSlotsOfItemsInInventory( uint32_t catalogId ); InvSlotPair getFreeBagSlot(); - int16_t addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint16_t quantity = 1 ); + int16_t addItem( uint16_t inventoryId, int8_t slotId, uint32_t catalogId, uint8_t quantity = 1 ); void moveItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot ); void swapItem( uint16_t fromInventoryId, uint8_t fromSlotId, uint16_t toInventoryId, uint8_t toSlot ); void discardItem( uint16_t fromInventoryId, uint8_t fromSlotId ); @@ -175,7 +175,7 @@ public: bool addCrystal( CrystalType type, uint32_t amount ); /*! remove amount from the crystals of type */ bool removeCrystal( CrystalType type, uint32_t amount ); - bool isObtainable( uint32_t catalogId, uint16_t quantity ); + bool isObtainable( uint32_t catalogId, uint8_t quantity ); void updateCrystalDb(); From 76fd34a7d85626df9ba2b869c6e9ba1f21a9fbf8 Mon Sep 17 00:00:00 2001 From: amibu Date: Mon, 2 Oct 2017 13:56:04 +0200 Subject: [PATCH 21/29] No Scroll Bars --- bin/web/createUser.html | 2 +- bin/web/login.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/web/createUser.html b/bin/web/createUser.html index 5a82c96f..5d73e5d2 100644 --- a/bin/web/createUser.html +++ b/bin/web/createUser.html @@ -45,7 +45,7 @@ - +
diff --git a/bin/web/login.html b/bin/web/login.html index 1b94f909..6d32528d 100644 --- a/bin/web/login.html +++ b/bin/web/login.html @@ -45,7 +45,7 @@ - +
From 00f6441bf17ed9ba2499822533973a60af6edb34 Mon Sep 17 00:00:00 2001 From: amibu Date: Mon, 2 Oct 2017 16:00:12 +0200 Subject: [PATCH 22/29] Fixing Actor ID in Cast packet --- src/servers/Server_Zone/Action/ActionCast.cpp | 2 +- src/servers/Server_Zone/Action/ActionTeleport.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/servers/Server_Zone/Action/ActionCast.cpp b/src/servers/Server_Zone/Action/ActionCast.cpp index 16d07d8b..df132950 100644 --- a/src/servers/Server_Zone/Action/ActionCast.cpp +++ b/src/servers/Server_Zone/Action/ActionCast.cpp @@ -50,7 +50,7 @@ void Core::Action::ActionCast::onStart() m_pSource->getAsPlayer()->sendDebug( "onStart()" ); m_startTime = Util::getTimeMs(); - GamePacketNew< FFXIVIpcActorCast, ServerZoneIpcType > castPacket( getId() ); + GamePacketNew< FFXIVIpcActorCast, ServerZoneIpcType > castPacket( m_pSource->getId() ); castPacket.data().action_id = m_id; castPacket.data().unknown = 1; diff --git a/src/servers/Server_Zone/Action/ActionTeleport.cpp b/src/servers/Server_Zone/Action/ActionTeleport.cpp index 22705d71..998cf8fc 100644 --- a/src/servers/Server_Zone/Action/ActionTeleport.cpp +++ b/src/servers/Server_Zone/Action/ActionTeleport.cpp @@ -45,7 +45,7 @@ void Core::Action::ActionTeleport::onStart() m_startTime = Util::getTimeMs(); - GamePacketNew< FFXIVIpcActorCast, ServerZoneIpcType > castPacket( getId() ); + GamePacketNew< FFXIVIpcActorCast, ServerZoneIpcType > castPacket( m_pSource->getId() ); castPacket.data().action_id = 5; castPacket.data().unknown = 1; From 63b28c7621885797cbbc68307cbca3467ca2b376 Mon Sep 17 00:00:00 2001 From: amibu Date: Mon, 2 Oct 2017 16:00:26 +0200 Subject: [PATCH 23/29] Force model change debug command --- src/servers/Server_Zone/Actor/Player.cpp | 6 +++++ src/servers/Server_Zone/Actor/Player.h | 2 ++ .../DebugCommand/DebugCommandHandler.cpp | 22 +++++++++++++++++++ 3 files changed, 30 insertions(+) diff --git a/src/servers/Server_Zone/Actor/Player.cpp b/src/servers/Server_Zone/Actor/Player.cpp index 43416175..54b7270e 100644 --- a/src/servers/Server_Zone/Actor/Player.cpp +++ b/src/servers/Server_Zone/Actor/Player.cpp @@ -805,6 +805,12 @@ uint32_t Core::Entity::Player::getModelForSlot( Inventory::EquipSlot slot ) return m_modelEquip[slot]; } +void Core::Entity::Player::setModelForSlot( Inventory::EquipSlot slot, uint32_t val ) +{ + m_modelEquip[slot] = val; + setSyncFlag( PlayerSyncFlags::Status ); +} + uint64_t Core::Entity::Player::getModelMainWeapon() const { return m_modelMainWeapon; diff --git a/src/servers/Server_Zone/Actor/Player.h b/src/servers/Server_Zone/Actor/Player.h index 568419f9..1001251a 100644 --- a/src/servers/Server_Zone/Actor/Player.h +++ b/src/servers/Server_Zone/Actor/Player.h @@ -218,6 +218,8 @@ public: const uint32_t * getModelArray() const; /*! return the equipment model in a specified equipment slot */ uint32_t getModelForSlot( Inventory::EquipSlot slot ); + /*! set the equipment model in a specified equipment slot */ + void setModelForSlot( Inventory::EquipSlot slot, uint32_t val ); /*! return the current amount of currency of type */ uint32_t getCurrency( uint8_t type ) const; /*! add amount to the currency of type */ diff --git a/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp b/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp index b3137453..b6adea25 100644 --- a/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp +++ b/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp @@ -254,6 +254,20 @@ void Core::DebugCommandHandler::set( char * data, Core::Entity::PlayerPtr pPlaye pPlayer->setEorzeaTimeOffset( timestamp ); pPlayer->sendNotice( "Eorzea time offset: " + std::to_string( timestamp ) ); } + else if ( subCommand == "model" ) + { + uint32_t slot; + uint32_t val; + sscanf( params.c_str(), "%d %d %d", &slot, &val ); + + pPlayer->setModelForSlot( static_cast( slot ), val ); + pPlayer->sendModel(); + pPlayer->sendDebug( "Model updated" ); + } + else + { + pPlayer->sendUrgent( subCommand + " is not a valid SET command." ); + } } @@ -359,6 +373,10 @@ void Core::DebugCommandHandler::add( char * data, Core::Entity::PlayerPtr pPlaye pPlayer->queuePacket(controlPacket);*/ } + else + { + pPlayer->sendUrgent( subCommand + " is not a valid ADD command." ); + } } @@ -400,6 +418,10 @@ void Core::DebugCommandHandler::get( char * data, Core::Entity::PlayerPtr pPlaye std::to_string( map_id ) + "\nZoneID: " + std::to_string( pPlayer->getCurrentZone()->getId() ) + "\n" ); } + else + { + pPlayer->sendUrgent( subCommand + " is not a valid GET command." ); + } } From 08d79593a271244a9f608a369c08d7b2346ea37a Mon Sep 17 00:00:00 2001 From: amibu Date: Mon, 2 Oct 2017 16:02:28 +0200 Subject: [PATCH 24/29] Parameters were bad --- src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp b/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp index b6adea25..70c413c0 100644 --- a/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp +++ b/src/servers/Server_Zone/DebugCommand/DebugCommandHandler.cpp @@ -258,7 +258,7 @@ void Core::DebugCommandHandler::set( char * data, Core::Entity::PlayerPtr pPlaye { uint32_t slot; uint32_t val; - sscanf( params.c_str(), "%d %d %d", &slot, &val ); + sscanf( params.c_str(), "%d %d", &slot, &val ); pPlayer->setModelForSlot( static_cast( slot ), val ); pPlayer->sendModel(); From a404b191f1a436ef223e06b38cad54fdb3d0e796 Mon Sep 17 00:00:00 2001 From: Mordred Date: Mon, 2 Oct 2017 16:59:56 +0200 Subject: [PATCH 25/29] Fixed eventActions not having cast bars --- src/servers/Server_Zone/Action/EventAction.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/servers/Server_Zone/Action/EventAction.cpp b/src/servers/Server_Zone/Action/EventAction.cpp index 0de8a4de..00116ed4 100644 --- a/src/servers/Server_Zone/Action/EventAction.cpp +++ b/src/servers/Server_Zone/Action/EventAction.cpp @@ -53,8 +53,7 @@ void Core::Action::EventAction::onStart() if( m_pSource->isPlayer() ) { m_pSource->sendToInRangeSet( control, true ); - m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::NoCombat ); - m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Occupied1 ); + m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::SomeFlag ); m_pSource->getAsPlayer()->sendStateFlags(); } else @@ -85,8 +84,7 @@ void Core::Action::EventAction::onFinish() if( m_pSource->isPlayer() ) { - m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::NoCombat ); - m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 ); + m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::SomeFlag ); m_pSource->getAsPlayer()->sendStateFlags(); m_pSource->sendToInRangeSet( control, true ); } From 1be9d18059ad4247d9252fcb152af09b925021d3 Mon Sep 17 00:00:00 2001 From: Mordred Date: Tue, 3 Oct 2017 11:51:38 +0200 Subject: [PATCH 26/29] Added a generator for enums based on data in the exds --- CMakeLists.txt | 5 +- src/tools/exd_common_gen/CMakeLists.txt | 62 +++ src/tools/exd_common_gen/generated.h | 560 ++++++++++++++++++++++++ src/tools/exd_common_gen/main.cpp | 114 +++++ src/tools/quest_parser/CMakeLists.txt | 52 --- 5 files changed, 740 insertions(+), 53 deletions(-) create mode 100644 src/tools/exd_common_gen/CMakeLists.txt create mode 100644 src/tools/exd_common_gen/generated.h create mode 100644 src/tools/exd_common_gen/main.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 5e140bda..2e9a4b09 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,7 +37,8 @@ include( "cmake/compiler.cmake" ) include(GetGitRevisionDescription) get_git_head_revision(GIT_REFSPEC GIT_SHA1) git_describe(VERSION --tags --dirty=-d) -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/servers/Server_Common/Version.cpp.in" "${CMAKE_CURRENT_SOURCE_DIR}/src/servers/Server_Common/Version.cpp" @ONLY) +configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/servers/Server_Common/Version.cpp.in" + "${CMAKE_CURRENT_SOURCE_DIR}/src/servers/Server_Common/Version.cpp" @ONLY) ########################################################################## # Common include folders @@ -56,3 +57,5 @@ link_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/libraries/sapphire/datReader) add_subdirectory("src/servers") add_subdirectory("src/libraries/sapphire/datReader") +add_subdirectory("src/tools/exd_common_gen") +add_subdirectory("src/tools/quest_parser") diff --git a/src/tools/exd_common_gen/CMakeLists.txt b/src/tools/exd_common_gen/CMakeLists.txt new file mode 100644 index 00000000..a03bebf3 --- /dev/null +++ b/src/tools/exd_common_gen/CMakeLists.txt @@ -0,0 +1,62 @@ +cmake_minimum_required(VERSION 2.6) +cmake_policy(SET CMP0015 NEW) +project(Tool_ExdCommonGen) + +set(SAPPHIRE_BOOST_VER 1.63.0) +set(SAPPHIRE_BOOST_FOLDER_NAME boost_1_63_0) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/") + +include_directories("../../lib/ChaiScript-6.0.0/include/") + +include_directories("../../sapphire/datReader/") +include_directories("../../sapphire/") +include_directories("../") + +file(GLOB SERVER_PUBLIC_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*") +file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*") + + +if(UNIX) + include_directories("/usr/include/mysql/") + message(STATUS "Setting GCC flags") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -m32") + +else() + add_definitions(-D_WIN32_WINNT=0x601) + add_definitions(-D_CRT_SECURE_NO_WARNINGS) + include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../lib/MySQL/") + message(STATUS "Setting MSVC flags") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHc") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") + +endif() + +include_directories(${Boost_INCLUDE_DIR}) + +link_directories(${BOOST_LIBRARYDIR}) +link_directories(${SERVER_COMMON_DIR}) +link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../sapphire/datReader/) +link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../lib/MySQL) +link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../lib/zlib) + +#set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "../bin/") +add_executable(exd_common_gen ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES}) + +set_target_properties(exd_common_gen PROPERTIES + CXX_STANDARD 14 + CXX_STANDARD_REQUIRED ON + CXX_EXTENSIONS ON + RUNTIME_OUTPUT_DIRECTORY_DEBUG "${CMAKE_CURRENT_SOURCE_DIR}/../bin/" + RUNTIME_OUTPUT_DIRECTORY_RELEASE "${CMAKE_CURRENT_SOURCE_DIR}/../bin/" + RUNTIME_OUTPUT_DIRECTORY_RELWITHDEBINFO "${CMAKE_CURRENT_SOURCE_DIR}/../bin/" + RUNTIME_OUTPUT_DIRECTORY_MINSIZEREL "${CMAKE_CURRENT_SOURCE_DIR}/../bin/" +) + +if (UNIX) + target_link_libraries (exd_common_gen Common xivdat pthread mysqlclient dl z) +else() + target_link_libraries (exd_common_gen Common xivdat libmysql zlib1) +endif() + +target_link_libraries(exd_common_gen ${Boost_LIBRARIES} ${Boost_LIBRARIES}) + diff --git a/src/tools/exd_common_gen/generated.h b/src/tools/exd_common_gen/generated.h new file mode 100644 index 00000000..28b10c3b --- /dev/null +++ b/src/tools/exd_common_gen/generated.h @@ -0,0 +1,560 @@ +[14:21:11][info] Setting up EXD data +[14:21:12][info] /* This file has been automatically generated. + Changes will be lost upon regeneration. + To change the content edit tools/exd_common_gen */ +namespace Core { +namespace Common { + + /////////////////////////////////////////////////////////// + //ActionCategory.exd + enum ActionCategory : uint8_t + { + Autoattack = 1, + Spell = 2, + Weaponskill = 3, + Ability = 4, + Item = 5, + DoLAbility = 6, + DoHAbility = 7, + Event = 8, + LimitBreak = 9, + System = 10, + Artillery = 11, + Mount = 12, + Glamour = 13, + ItemManipulation = 14, + AdrenalineRush = 15, + }; + + /////////////////////////////////////////////////////////// + //BeastReputationRank.exd + enum BeastReputationRank : uint8_t + { + None = 0, + Neutral = 1, + Recognized = 2, + Friendly = 3, + Trusted = 4, + Respected = 5, + Honored = 6, + Sworn = 7, + Allied = 8, + }; + + /////////////////////////////////////////////////////////// + //BeastTribe.exd + enum BeastTribe : uint8_t + { + Amaljaa = 1, + Sylphs = 2, + Kobolds = 3, + Sahagin = 4, + Ixal = 5, + VanuVanu = 6, + Vath = 7, + Moogles = 8, + }; + + /////////////////////////////////////////////////////////// + //ClassJob.exd + enum ClassJob : uint8_t + { + Adventurer = 0, + Gladiator = 1, + Pugilist = 2, + Marauder = 3, + Lancer = 4, + Archer = 5, + Conjurer = 6, + Thaumaturge = 7, + Carpenter = 8, + Blacksmith = 9, + Armorer = 10, + Goldsmith = 11, + Leatherworker = 12, + Weaver = 13, + Alchemist = 14, + Culinarian = 15, + Miner = 16, + Botanist = 17, + Fisher = 18, + Paladin = 19, + Monk = 20, + Warrior = 21, + Dragoon = 22, + Bard = 23, + Whitemage = 24, + Blackmage = 25, + Arcanist = 26, + Summoner = 27, + Scholar = 28, + Rogue = 29, + Ninja = 30, + Machinist = 31, + Darkknight = 32, + Astrologian = 33, + Samurai = 34, + Redmage = 35, + }; + + /////////////////////////////////////////////////////////// + //ContentType.exd + enum ContentType : uint8_t + { + DutyRoulette = 1, + Dungeons = 2, + Guildhests = 3, + Trials = 4, + Raids = 5, + PvP = 6, + QuestBattles = 7, + FATEs = 8, + TreasureHunt = 9, + Levequests = 10, + GrandCompany = 11, + Companions = 12, + BeastTribeQuests = 13, + OverallCompletion = 14, + PlayerCommendation = 15, + DisciplesoftheLand = 16, + DisciplesoftheHand = 17, + RetainerVentures = 18, + GoldSaucer = 19, + DeepDungeons = 21, + WondrousTails = 24, + }; + + /////////////////////////////////////////////////////////// + //EmoteCategory.exd + enum EmoteCategory : uint8_t + { + General = 1, + Persistent = 2, + Expressions = 3, + }; + + /////////////////////////////////////////////////////////// + //ExVersion.exd + enum ExVersion : uint8_t + { + ARealmReborn = 0, + Heavensward = 1, + Stormblood = 2, + }; + + /////////////////////////////////////////////////////////// + //GrandCompany.exd + enum GrandCompany : uint8_t + { + None = 0, + Maelstrom = 1, + OrderoftheTwinAdder = 2, + ImmortalFlames = 3, + }; + + /////////////////////////////////////////////////////////// + //GuardianDeity.exd + enum GuardianDeity : uint8_t + { + HalonetheFury = 1, + MenphinatheLover = 2, + ThaliaktheScholar = 3, + NymeiatheSpinner = 4, + LlymlaentheNavigator = 5, + OschontheWanderer = 6, + ByregottheBuilder = 7, + RhalgrtheDestroyer = 8, + AzeymatheWarden = 9, + NaldthaltheTraders = 10, + NophicatheMatron = 11, + AlthyktheKeeper = 12, + }; + + /////////////////////////////////////////////////////////// + //ItemUICategory.exd + enum ItemUICategory : uint8_t + { + PugilistsArm = 1, + GladiatorsArm = 2, + MaraudersArm = 3, + ArchersArm = 4, + LancersArm = 5, + OnehandedThaumaturgesArm = 6, + TwohandedThaumaturgesArm = 7, + OnehandedConjurersArm = 8, + TwohandedConjurersArm = 9, + ArcanistsGrimoire = 10, + Shield = 11, + CarpentersPrimaryTool = 12, + CarpentersSecondaryTool = 13, + BlacksmithsPrimaryTool = 14, + BlacksmithsSecondaryTool = 15, + ArmorersPrimaryTool = 16, + ArmorersSecondaryTool = 17, + GoldsmithsPrimaryTool = 18, + GoldsmithsSecondaryTool = 19, + LeatherworkersPrimaryTool = 20, + LeatherworkersSecondaryTool = 21, + WeaversPrimaryTool = 22, + WeaversSecondaryTool = 23, + AlchemistsPrimaryTool = 24, + AlchemistsSecondaryTool = 25, + CulinariansPrimaryTool = 26, + CulinariansSecondaryTool = 27, + MinersPrimaryTool = 28, + MinersSecondaryTool = 29, + BotanistsPrimaryTool = 30, + BotanistsSecondaryTool = 31, + FishersPrimaryTool = 32, + FishingTackle = 33, + Head = 34, + Body = 35, + Legs = 36, + Hands = 37, + Feet = 38, + Waist = 39, + Necklace = 40, + Earrings = 41, + Bracelets = 42, + Ring = 43, + Medicine = 44, + Ingredient = 45, + Meal = 46, + Seafood = 47, + Stone = 48, + Metal = 49, + Lumber = 50, + Cloth = 51, + Leather = 52, + Bone = 53, + Reagent = 54, + Dye = 55, + Part = 56, + Furnishing = 57, + Materia = 58, + Crystal = 59, + Catalyst = 60, + Miscellany = 61, + SoulCrystal = 62, + Other = 63, + ConstructionPermit = 64, + Roof = 65, + ExteriorWall = 66, + Window = 67, + Door = 68, + RoofDecoration = 69, + ExteriorWallDecoration = 70, + Placard = 71, + Fence = 72, + InteriorWall = 73, + Flooring = 74, + CeilingLight = 75, + OutdoorFurnishing = 76, + Table = 77, + Tabletop = 78, + Wallmounted = 79, + Rug = 80, + Minion = 81, + Gardening = 82, + Demimateria = 83, + RoguesArm = 84, + SeasonalMiscellany = 85, + TripleTriadCard = 86, + DarkKnightsArm = 87, + MachinistsArm = 88, + AstrologiansArm = 89, + AirshipHull = 90, + AirshipRigging = 91, + AirshipAftcastle = 92, + AirshipForecastle = 93, + OrchestrionRoll = 94, + Painting = 95, + SamuraisArm = 96, + RedMagesArm = 97, + ScholarsArm = 98, + FishersSecondaryTool = 99, + }; + + /////////////////////////////////////////////////////////// + //ItemSearchCategory.exd + enum ItemSearchCategory : uint8_t + { + PrimaryArms = 1, + PrimaryTools = 2, + PrimaryTools1 = 3, + Armor = 4, + Accessories = 5, + Medicines = 6, + Materials = 7, + Other = 8, + PugilistsArms = 9, + GladiatorsArms = 10, + MaraudersArms = 11, + ArchersArms = 12, + LancersArms = 13, + ThaumaturgesArms = 14, + ConjurersArms = 15, + ArcanistsArms = 16, + Shields = 17, + ThrowingWeapons = 18, + CarpentersTools = 19, + BlacksmithsTools = 20, + ArmorersTools = 21, + GoldsmithsTools = 22, + LeatherworkersTools = 23, + WeaversTools = 24, + AlchemistsTools = 25, + CulinariansTools = 26, + MinersTools = 27, + BotanistsTools = 28, + FishersTools = 29, + FishingTackle = 30, + Head = 31, + Undershirts = 32, + Body = 33, + Undergarments = 34, + Legs = 35, + Hands = 36, + Feet = 37, + Waist = 38, + Necklaces = 39, + Earrings = 40, + Bracelets = 41, + Rings = 42, + Medicine = 43, + Ingredients = 44, + Meals = 45, + Seafood = 46, + Stone = 47, + Metal = 48, + Lumber = 49, + Cloth = 50, + Leather = 51, + Bone = 52, + Reagents = 53, + Dyes = 54, + WeaponParts = 55, + Furnishings = 56, + Materia = 57, + Crystals = 58, + Catalysts = 59, + Miscellany = 60, + SoulCrystals = 61, + Arrows = 62, + QuestItems = 63, + Other1 = 64, + ExteriorFixtures = 65, + InteriorFixtures = 66, + OutdoorFurnishings = 67, + ChairsandBeds = 68, + Tables = 69, + Tabletop = 70, + Wallmounted = 71, + Rugs = 72, + RoguesArms = 73, + SeasonalMiscellany = 74, + Minions = 75, + DarkKnightsArms = 76, + MachinistsArms = 77, + AstrologiansArms = 78, + AirshipComponents = 79, + OrchestrionComponents = 80, + GardeningItems = 81, + Paintings = 82, + SamuraisArms = 83, + RedMagesArms = 84, + ScholarsArms = 85, + }; + + /////////////////////////////////////////////////////////// + //OnlineStatus.exd + enum OnlineStatus : uint8_t + { + Producer = 1, + GameMaster = 2, + GameMaster1 = 3, + GameMaster2 = 4, + Disconnected = 5, + WaitingforFriendListApproval = 6, + WaitingforLinkshellApproval = 7, + WaitingforFreeCompanyApproval = 8, + NotFound = 9, + Offline = 10, + Mentor = 11, + Busy = 12, + PvP = 13, + PlayingTripleTriad = 14, + ViewingCutscene = 15, + UsingaChocoboPorter = 16, + AwayfromKeyboard = 17, + CameraMode = 18, + LookingforRepairs = 19, + LookingtoRepair = 20, + LookingtoMeldMateria = 21, + Roleplaying = 22, + LookingforParty = 23, + SwordforHire = 24, + WaitingforDutyFinder = 25, + RecruitingPartyMembers = 26, + Mentor1 = 27, + PvEMentor = 28, + TradeMentor = 29, + PvPMentor = 30, + Returner = 31, + NewAdventurer = 32, + AllianceLeader = 33, + AlliancePartyLeader = 34, + AlliancePartyMember = 35, + PartyLeader = 36, + PartyMember = 37, + PartyLeaderCrossworld = 38, + PartyMemberCrossworld = 39, + AnotherWorld = 40, + SharingDuty = 41, + SimilarDuty = 42, + InDuty = 43, + TrialAdventurer = 44, + FreeCompany = 45, + GrandCompany = 46, + Online = 47, + }; + + /////////////////////////////////////////////////////////// + //Race.exd + enum Race : uint8_t + { + Hyur = 1, + Elezen = 2, + Lalafell = 3, + Miqote = 4, + Roegadyn = 5, + AuRa = 6, + }; + + /////////////////////////////////////////////////////////// + //Tribe.exd + enum Tribe : uint8_t + { + Midlander = 1, + Highlander = 2, + Wildwood = 3, + Duskwight = 4, + Plainsfolk = 5, + Dunesfolk = 6, + SeekeroftheSun = 7, + KeeperoftheMoon = 8, + SeaWolf = 9, + Hellsguard = 10, + Raen = 11, + Xaela = 12, + }; + + /////////////////////////////////////////////////////////// + //Town.exd + enum Town : uint8_t + { + Nowheresville = 0, + LimsaLominsa = 1, + Gridania = 2, + Uldah = 3, + Ishgard = 4, + Kugane = 7, + }; + + /////////////////////////////////////////////////////////// + //Weather.exd + enum Weather : uint8_t + { + ClearSkies = 1, + FairSkies = 2, + Clouds = 3, + Fog = 4, + Wind = 5, + Gales = 6, + Rain = 7, + Showers = 8, + Thunder = 9, + Thunderstorms = 10, + DustStorms = 11, + Sandstorms = 12, + HotSpells = 13, + HeatWaves = 14, + Snow = 15, + Blizzards = 16, + Gloom = 17, + Auroras = 18, + Darkness = 19, + Tension = 20, + Clouds1 = 21, + StormClouds = 22, + RoughSeas = 23, + RoughSeas1 = 24, + Louring = 25, + HeatWaves1 = 26, + Gloom1 = 27, + Gales1 = 28, + Eruptions = 29, + FairSkies1 = 30, + FairSkies2 = 31, + FairSkies3 = 32, + FairSkies4 = 33, + FairSkies5 = 34, + Irradiance = 35, + CoreRadiation = 36, + CoreRadiation1 = 37, + CoreRadiation2 = 38, + CoreRadiation3 = 39, + ShelfClouds = 40, + ShelfClouds1 = 41, + ShelfClouds2 = 42, + ShelfClouds3 = 43, + Oppression = 44, + Oppression1 = 45, + Oppression2 = 46, + Oppression3 = 47, + Oppression4 = 48, + UmbralWind = 49, + UmbralStatic = 50, + Smoke = 51, + FairSkies6 = 52, + RoyalLevin = 53, + Hyperelectricity = 54, + RoyalLevin1 = 55, + Oppression5 = 56, + Thunder1 = 57, + Thunder2 = 58, + CutScene = 59, + Multiplicity = 60, + Multiplicity1 = 61, + Rain1 = 62, + FairSkies7 = 63, + Rain2 = 64, + FairSkies8 = 65, + Dragonstorm = 66, + Dragonstorm1 = 67, + Subterrain = 68, + Concordance = 69, + Concordance1 = 70, + BeyondTime = 71, + BeyondTime1 = 72, + BeyondTime2 = 73, + DemonicInfinity = 74, + DemonicInfinity1 = 75, + DemonicInfinity2 = 76, + DimensionalDisruption = 77, + DimensionalDisruption1 = 78, + DimensionalDisruption2 = 79, + Revelstorm = 80, + Revelstorm1 = 81, + EternalBliss = 82, + EternalBliss1 = 83, + Wyrmstorm = 84, + Wyrmstorm1 = 85, + Revelstorm2 = 86, + Quicklevin = 87, + Thunder3 = 88, + DimensionalDisruption3 = 89, + }; +} +} + diff --git a/src/tools/exd_common_gen/main.cpp b/src/tools/exd_common_gen/main.cpp new file mode 100644 index 00000000..5279e5d2 --- /dev/null +++ b/src/tools/exd_common_gen/main.cpp @@ -0,0 +1,114 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +Core::Logger g_log; +Core::Data::ExdData g_exdData; + + +//const std::string datLocation( "/opt/sapphire_3_15_0/bin/sqpack" ); +const std::string datLocation( "C:\\SquareEnix\\FINAL FANTASY XIV - A Realm Reborn\\game\\sqpack\\ffxiv" ); + +std::string generateEnum( const std::string& exd, int8_t nameIndex, const std::string& type, bool useLang = true ) +{ + + xiv::dat::GameData data( datLocation ); + xiv::exd::ExdData eData( data ); + + std::map< std::string, uint32_t> nameMap; + + std::string result = "\n ///////////////////////////////////////////////////////////\n"; + result += " //" + exd + ".exd\n"; + result += " enum " + exd + " : " + type + "\n"; + result += " {\n"; + auto lang = useLang ? xiv::exd::Language::en : xiv::exd::Language::none; + auto access = g_exdData.setupDatAccess( exd, lang ); + auto rows = access.get_rows(); + + for( auto row : rows ) + { + auto& fields = row.second; + uint32_t id = row.first; + auto test = boost::get< std::string >( &fields.at( nameIndex ) ); + if( !test ) + continue; + auto str = *test ; + str.erase( boost::remove_if( str, boost::is_any_of(",_-':!(){} \x02\x1f\x01\x03") ), str.end() ); + if( str.empty() ) + continue; + str[0] = std::toupper( str[0] ); + + auto it = nameMap.find( str ); + if( it != nameMap.end() ) + { + nameMap[str]++; + str = str + std::to_string( nameMap[str] ); + } + else + { + nameMap[str] = 0; + } + + result += " " + str + " = " + std::to_string( id ) + ",\n"; + + } + result += " };\n"; + + return result; + +} + +int main() +{ + + g_log.init(); + + + g_log.info( "Setting up EXD data" ); + if( !g_exdData.init( datLocation ) ) + { + g_log.fatal( "Error setting up EXD data " ); + return 0; + } + + std::string result = + "/* This file has been automatically generated.\n Changes will be lost upon regeneration.\n To change the content edit tools/exd_common_gen */\n"; + + + result += "namespace Core {\n"; + result += "namespace Common {\n"; + result += generateEnum( "ActionCategory", 0, "uint8_t" ); + result += generateEnum( "BeastReputationRank", 1, "uint8_t" ); + result += generateEnum( "BeastTribe", 10, "uint8_t" ); + result += generateEnum( "ClassJob", 0, "uint8_t" ); + result += generateEnum( "ContentType", 0, "uint8_t" ); + result += generateEnum( "EmoteCategory", 0, "uint8_t" ); + result += generateEnum( "ExVersion", 0, "uint8_t" ); + result += generateEnum( "GrandCompany", 0, "uint8_t" ); + result += generateEnum( "GuardianDeity", 0, "uint8_t" ); + result += generateEnum( "ItemUICategory", 0, "uint8_t" ); + result += generateEnum( "ItemSearchCategory", 0, "uint8_t" ); + result += generateEnum( "OnlineStatus", 2, "uint8_t" ); + result += generateEnum( "Race", 1, "uint8_t" ); + result += generateEnum( "Tribe", 0, "uint8_t" ); + result += generateEnum( "Town", 0, "uint8_t" ); + result += generateEnum( "Weather", 1, "uint8_t" ); + result += "}\n"; + result += "}\n"; + g_log.info( result ); + return 0; +} diff --git a/src/tools/quest_parser/CMakeLists.txt b/src/tools/quest_parser/CMakeLists.txt index 1a314ae9..5fd8176d 100644 --- a/src/tools/quest_parser/CMakeLists.txt +++ b/src/tools/quest_parser/CMakeLists.txt @@ -15,58 +15,6 @@ include_directories("../") file(GLOB SERVER_PUBLIC_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*") file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*") -set(SERVER_COMMON_DIR ../../sapphire/Server_Common) -set(Boost_USE_STATIC_LIBS ON) - -if(UNIX) - include_directories("/usr/include/mysql/") - message(STATUS "Setting GCC flags") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -m32") - - find_package(Boost ${SAPPHIRE_BOOST_VER} COMPONENTS log log_setup thread date_time filesystem system) - if(Boost_FOUND) - set(BOOST_LIBRARY_DIR ${Boost_LIBRARY_DIR}) - else() - if (EXISTS /opt/build_libs/${SAPPHIRE_BOOST_FOLDER_NAME}) - set(Boost_INCLUDE_DIR /opt/build_libs/${SAPPHIRE_BOOST_FOLDER_NAME}) - set(BOOST_LIBRARYDIR /opt/build_libs/${SAPPHIRE_BOOST_FOLDER_NAME}/stage/lib) - find_package(Boost ${SAPPHIRE_BOOST_VER} COMPONENTS log log_setup thread date_time filesystem system) - else() - message(FATAL_ERROR "Unable to find boost ${SAPPHIRE_BOOST_VER} package!") - endif() - endif() -else() - add_definitions(-D_WIN32_WINNT=0x601) - add_definitions(-D_CRT_SECURE_NO_WARNINGS) - include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../lib/MySQL/") - message(STATUS "Setting MSVC flags") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHc") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") - - if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/${SAPPHIRE_BOOST_FOLDER_NAME}) - message(STATUS "Using boost in /src/lib") - set(Boost_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/${SAPPHIRE_BOOST_FOLDER_NAME}) - set(BOOST_LIBRARYDIR ${CMAKE_CURRENT_SOURCE_DIR}/../../lib/${SAPPHIRE_BOOST_FOLDER_NAME}/lib32-msvc-14.0) - else() - find_package(Boost ${SAPPHIRE_BOOST_VER} COMPONENTS log log_setup thread date_time filesystem system) - if(Boost_FOUND) - set(BOOST_LIBRARY_DIR ${Boost_LIBRARY_DIR}) - elseif ((EXISTS $ENV{BOOST_ROOT_DIR}) AND (EXISTS $ENV{BOOST_LIB_DIR})) - set(Boost_INCLUDE_DIR $ENV{BOOST_ROOT_DIR}) - set(BOOST_LIBRARYDIR $ENV{BOOST_LIB_DIR}) - else() - message(FATAL_ERROR "SapphireError: Unable to find boost ${SAPPHIRE_BOOST_VER} package and environment variables BOOST_ROOT_DIR and BOOST_LIB_DIR not set!") - endif() - endif() -endif() - -include_directories(${Boost_INCLUDE_DIR}) - -link_directories(${BOOST_LIBRARYDIR}) -link_directories(${SERVER_COMMON_DIR}) -link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../sapphire/datReader/) -link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../lib/MySQL) -link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../lib/zlib) #set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "../bin/") add_executable(quest_parse ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES}) From 5e93cf116a8ee470012d5e63ffd3e641b52f27c9 Mon Sep 17 00:00:00 2001 From: Mordred Date: Tue, 3 Oct 2017 11:55:21 +0200 Subject: [PATCH 27/29] simplified cmakelist --- src/tools/exd_common_gen/CMakeLists.txt | 29 ------------------------- 1 file changed, 29 deletions(-) diff --git a/src/tools/exd_common_gen/CMakeLists.txt b/src/tools/exd_common_gen/CMakeLists.txt index a03bebf3..2d5839d9 100644 --- a/src/tools/exd_common_gen/CMakeLists.txt +++ b/src/tools/exd_common_gen/CMakeLists.txt @@ -6,39 +6,10 @@ set(SAPPHIRE_BOOST_VER 1.63.0) set(SAPPHIRE_BOOST_FOLDER_NAME boost_1_63_0) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../bin/") -include_directories("../../lib/ChaiScript-6.0.0/include/") - -include_directories("../../sapphire/datReader/") -include_directories("../../sapphire/") -include_directories("../") file(GLOB SERVER_PUBLIC_INCLUDE_FILES "${CMAKE_CURRENT_SOURCE_DIR}/*") file(GLOB SERVER_SOURCE_FILES "${CMAKE_CURRENT_SOURCE_DIR}*.c*") - -if(UNIX) - include_directories("/usr/include/mysql/") - message(STATUS "Setting GCC flags") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -m32") - -else() - add_definitions(-D_WIN32_WINNT=0x601) - add_definitions(-D_CRT_SECURE_NO_WARNINGS) - include_directories("${CMAKE_CURRENT_SOURCE_DIR}/../../lib/MySQL/") - message(STATUS "Setting MSVC flags") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHc") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP") - -endif() - -include_directories(${Boost_INCLUDE_DIR}) - -link_directories(${BOOST_LIBRARYDIR}) -link_directories(${SERVER_COMMON_DIR}) -link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../sapphire/datReader/) -link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../lib/MySQL) -link_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../lib/zlib) - #set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "../bin/") add_executable(exd_common_gen ${SERVER_PUBLIC_INCLUDE_FILES} ${SERVER_SOURCE_FILES}) From 0500512a165f42b860afb3df107954255ff57816 Mon Sep 17 00:00:00 2001 From: Mordred Date: Tue, 3 Oct 2017 12:06:12 +0200 Subject: [PATCH 28/29] However a windows.h include got in there... --- src/tools/quest_parser/main.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/quest_parser/main.cpp b/src/tools/quest_parser/main.cpp index d1ac6ca1..f4ec46b1 100644 --- a/src/tools/quest_parser/main.cpp +++ b/src/tools/quest_parser/main.cpp @@ -12,7 +12,6 @@ #include -#include Core::Logger g_log; Core::Data::ExdData g_exdData; From 280bd3081ba5a95e0283f7c88b431b316728f3b1 Mon Sep 17 00:00:00 2001 From: Mordred Date: Tue, 3 Oct 2017 12:09:51 +0200 Subject: [PATCH 29/29] Startup banner extracted to own function --- src/servers/Server_Zone/ServerZone.cpp | 15 ++++++++++----- src/servers/Server_Zone/ServerZone.h | 2 ++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/servers/Server_Zone/ServerZone.cpp b/src/servers/Server_Zone/ServerZone.cpp index eef00e5a..917a3302 100644 --- a/src/servers/Server_Zone/ServerZone.cpp +++ b/src/servers/Server_Zone/ServerZone.cpp @@ -188,11 +188,7 @@ void Core::ServerZone::run( int32_t argc, char* argv[] ) g_log.setLogPath( "log\\SapphireZone_" ); g_log.init(); - g_log.info( "===========================================================" ); - g_log.info( "Sapphire Server Project " ); - g_log.info( "Version: x.y.z" ); - g_log.info( "Compiled: " __DATE__ " " __TIME__ ); - g_log.info( "===========================================================" ); + printBanner(); if( !loadSettings( argc, argv ) ) { @@ -239,6 +235,15 @@ void Core::ServerZone::run( int32_t argc, char* argv[] ) } +void Core::ServerZone::printBanner() const +{ + g_log.info("===========================================================" ); + g_log.info( "Sapphire Server Project " ); + g_log.info( "Version: x.y.z" ); + g_log.info( "Compiled: " __DATE__ " " __TIME__ ); + g_log.info( "===========================================================" ); +} + void Core::ServerZone::mainLoop() { while( isRunning() ) diff --git a/src/servers/Server_Zone/ServerZone.h b/src/servers/Server_Zone/ServerZone.h index 130d2f22..73f90675 100644 --- a/src/servers/Server_Zone/ServerZone.h +++ b/src/servers/Server_Zone/ServerZone.h @@ -44,6 +44,8 @@ namespace Core { bool isRunning() const; + void printBanner() const; + private: