mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-03 17:27:47 +00:00
Merge pull request #103 from itsmaru/master
Prototype AoE skill handling; Action Effect definitions and a bit of refactoring;
This commit is contained in:
commit
7a4aa5590c
11 changed files with 172 additions and 51 deletions
18
scripts/chai/skill/cnj/skillDef_124.chai
Normal file
18
scripts/chai/skill/cnj/skillDef_124.chai
Normal file
|
@ -0,0 +1,18 @@
|
|||
// Skill Name: Medica
|
||||
// Skill ID: 124
|
||||
|
||||
class skillDef_124Def
|
||||
{
|
||||
def skillDef_124Def()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
def onFinish( player, target )
|
||||
{
|
||||
player.handleScriptSkill( STD_HEAL, 124, 300, 0, player );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
GLOBAL skillDef_124 = skillDef_124Def();
|
19
scripts/chai/skill/cnj/skillDef_133.chai
Normal file
19
scripts/chai/skill/cnj/skillDef_133.chai
Normal file
|
@ -0,0 +1,19 @@
|
|||
// Skill Name: Medica II
|
||||
// Skill ID: 133
|
||||
|
||||
class skillDef_133Def
|
||||
{
|
||||
def skillDef_133Def()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
def onFinish( player, target )
|
||||
{
|
||||
player.handleScriptSkill( STD_HEAL, 133, 200, 0, player );
|
||||
target.addStatusEffectByIdIfNotExist( 150, 30000, player, 50 );
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
GLOBAL skillDef_133 = skillDef_133Def();
|
|
@ -571,6 +571,35 @@ namespace Core {
|
|||
LimitBreak = 8,
|
||||
};
|
||||
|
||||
enum ActionEffectType : uint8_t
|
||||
{
|
||||
Nothing = 0,
|
||||
Miss = 1,
|
||||
FullResist = 2,
|
||||
Damage = 3,
|
||||
Heal = 4,
|
||||
BlockedDamage = 5,
|
||||
ParriedDamage = 6,
|
||||
Invulnerable = 7,
|
||||
NoEffectText = 8,
|
||||
Unknown_0 = 9,
|
||||
MpLoss = 10,
|
||||
MpGain = 11,
|
||||
TpLoss = 12,
|
||||
TpGain = 13,
|
||||
GpGain = 14
|
||||
};
|
||||
|
||||
enum ActionHitSeverityType : uint8_t
|
||||
{
|
||||
NormalDamage = 0,
|
||||
CritHeal = 0,
|
||||
CritDamage = 1,
|
||||
NormalHeal = 1,
|
||||
DirectHitDamage = 2,
|
||||
CritDirectHitDamage = 3
|
||||
};
|
||||
|
||||
enum HandleActionType : uint8_t
|
||||
{
|
||||
Event,
|
||||
|
|
|
@ -315,8 +315,7 @@ bool Core::Data::ExdData::loadActionInfo()
|
|||
for( auto row : rows )
|
||||
{
|
||||
auto& fields = row.second;
|
||||
|
||||
ActionInfo info{ 0 };
|
||||
auto info = boost::make_shared< ActionInfo >();
|
||||
|
||||
uint32_t id = row.first;
|
||||
if( id == 0 )
|
||||
|
@ -360,36 +359,36 @@ bool Core::Data::ExdData::loadActionInfo()
|
|||
|
||||
|
||||
|
||||
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.can_target_friendly = can_target_friendly;
|
||||
info.can_target_enemy = can_target_enemy;
|
||||
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_ko = can_target_ko;
|
||||
info->can_target_ko = can_target_ko;
|
||||
|
||||
info.is_aoe = is_aoe;
|
||||
info->is_aoe = is_aoe;
|
||||
|
||||
info.aoe_type = aoe_type;
|
||||
info.radius = radius;
|
||||
info->aoe_type = aoe_type;
|
||||
info->radius = radius;
|
||||
|
||||
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[id] = info;
|
||||
m_actionInfoMap.emplace( std::make_pair( info->id, info ) );
|
||||
|
||||
}
|
||||
|
||||
|
@ -464,6 +463,22 @@ boost::shared_ptr< Core::Data::AetheryteInfo >
|
|||
|
||||
}
|
||||
|
||||
boost::shared_ptr< Core::Data::ActionInfo >
|
||||
Core::Data::ExdData::getActionInfo( uint32_t actionId )
|
||||
{
|
||||
try
|
||||
{
|
||||
return m_actionInfoMap[actionId];
|
||||
}
|
||||
catch ( ... )
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
||||
}
|
||||
|
||||
boost::shared_ptr< Core::Data::CustomTalkInfo >
|
||||
Core::Data::ExdData::getCustomTalkInfo( uint32_t customTalkId )
|
||||
{
|
||||
|
|
|
@ -299,7 +299,7 @@ namespace Core {
|
|||
std::map<uint8_t, ClassJobInfo> m_classJobInfoMap;
|
||||
std::map<uint32_t, ParamGrowthInfo> m_paramGrowthInfoMap;
|
||||
std::map<uint16_t, EventActionInfo> m_EventActionInfoMap;
|
||||
std::map<uint16_t, ActionInfo> m_actionInfoMap;
|
||||
std::map<uint16_t, boost::shared_ptr< ActionInfo > > m_actionInfoMap;
|
||||
std::map<uint16_t, StatusEffectInfo> m_statusEffectInfoMap;
|
||||
std::map<uint32_t, boost::shared_ptr< AetheryteInfo > > m_aetheryteInfoMap;
|
||||
std::map<uint32_t, TribeInfo > m_tribeInfoMap;
|
||||
|
@ -317,6 +317,7 @@ namespace Core {
|
|||
boost::shared_ptr< OpeningInfo > getOpeningInfo( uint32_t openingId );
|
||||
boost::shared_ptr< CustomTalkInfo > getCustomTalkInfo( uint32_t customTalkId );
|
||||
boost::shared_ptr< AetheryteInfo > getAetheryteInfo( uint32_t aetheryteId );
|
||||
boost::shared_ptr< ActionInfo > getActionInfo( uint32_t actionId );
|
||||
boost::shared_ptr< PlaceNameInfo > getPlaceNameInfo( uint32_t placeNameId );
|
||||
boost::shared_ptr< ItemInfo > getItemInfo( uint32_t catalogId );
|
||||
boost::shared_ptr< RaceInfo > getRaceInfo( uint32_t raceId );
|
||||
|
|
|
@ -301,12 +301,12 @@ struct FFXIVIpcUpdateHpMpTp : FFXIVIpcBasePacket<UpdateHpMpTp>
|
|||
*/
|
||||
struct effectEntry
|
||||
{
|
||||
uint8_t unknown_1;
|
||||
uint8_t unknown_2;
|
||||
Common::ActionEffectType effectType;
|
||||
Common::ActionHitSeverityType hitSeverity;
|
||||
uint8_t unknown_3;
|
||||
int8_t bonusPercent;
|
||||
int16_t param1;
|
||||
uint8_t unknown_5;
|
||||
int16_t value;
|
||||
uint8_t valueMultiplier; // This multiplies whatever value is in the 'value' param by 10. Possibly a workaround for big numbers
|
||||
uint8_t unknown_6;
|
||||
};
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ Core::Action::ActionCast::ActionCast( Entity::ActorPtr pActor, Entity::ActorPtr
|
|||
m_startTime = 0;
|
||||
m_id = actionId;
|
||||
m_handleActionType = HandleActionType::Spell;
|
||||
m_castTime = g_exdData.m_actionInfoMap[actionId].cast_time; // TODO: Add security checks.
|
||||
m_castTime = g_exdData.getActionInfo( actionId )->cast_time; // TODO: Add security checks.
|
||||
m_pSource = pActor;
|
||||
m_pTarget = pTarget;
|
||||
m_bInterrupt = false;
|
||||
|
|
|
@ -26,7 +26,7 @@ Core::Action::ActionTeleport::ActionTeleport( Entity::ActorPtr pActor, uint16_t
|
|||
m_startTime = 0;
|
||||
m_id = 5;
|
||||
m_handleActionType = HandleActionType::Teleport;
|
||||
m_castTime = g_exdData.m_actionInfoMap[5].cast_time; // TODO: Add security checks.
|
||||
m_castTime = g_exdData.getActionInfo(5)->cast_time; // TODO: Add security checks.
|
||||
m_pSource = pActor;
|
||||
m_bInterrupt = false;
|
||||
m_targetAetheryte = targetZone;
|
||||
|
|
|
@ -595,7 +595,7 @@ void Core::Entity::Actor::autoAttack( ActorPtr pTarget )
|
|||
srand( static_cast< uint32_t >( tick ) );
|
||||
|
||||
uint32_t damage = 10 + rand() % 12;
|
||||
uint32_t variation = 0 + rand() % 3;
|
||||
uint32_t variation = 0 + rand() % 4;
|
||||
|
||||
GamePacketNew< FFXIVIpcEffect, ServerZoneIpcType > effectPacket( getId() );
|
||||
effectPacket.data().targetId = pTarget->getId();
|
||||
|
@ -606,9 +606,9 @@ void Core::Entity::Actor::autoAttack( ActorPtr pTarget )
|
|||
effectPacket.data().numEffects = 1;
|
||||
effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() );
|
||||
effectPacket.data().effectTarget = pTarget->getId();
|
||||
effectPacket.data().effects[0].param1 = damage;
|
||||
effectPacket.data().effects[0].unknown_1 = 3;
|
||||
effectPacket.data().effects[0].unknown_2 = 1;
|
||||
effectPacket.data().effects[0].value = damage;
|
||||
effectPacket.data().effects[0].effectType = ActionEffectType::Damage;
|
||||
effectPacket.data().effects[0].hitSeverity = static_cast< ActionHitSeverityType >( variation );
|
||||
effectPacket.data().effects[0].unknown_3 = 7;
|
||||
|
||||
sendToInRangeSet( effectPacket );
|
||||
|
|
|
@ -980,10 +980,11 @@ const uint8_t * Core::Entity::Player::getStateFlags() const
|
|||
|
||||
bool Core::Entity::Player::actionHasCastTime( uint32_t actionId ) //TODO: Add logic for special cases
|
||||
{
|
||||
if( g_exdData.m_actionInfoMap[actionId].is_instant )
|
||||
auto actionInfoPtr = g_exdData.getActionInfo( actionId );
|
||||
if( actionInfoPtr->is_instant )
|
||||
return false;
|
||||
|
||||
if( g_exdData.m_actionInfoMap[actionId].cast_time == 0 )
|
||||
if( actionInfoPtr->cast_time == 0 )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
|
@ -1481,9 +1482,9 @@ void Core::Entity::Player::autoAttack( ActorPtr pTarget )
|
|||
effectPacket.data().rotation = Math::Util::floatToUInt16Rot(getRotation());
|
||||
effectPacket.data().effectTargetId = pTarget->getId();
|
||||
effectPacket.data().effectTarget = pTarget->getId();
|
||||
effectPacket.data().effects[0].param1 = damage;
|
||||
effectPacket.data().effects[0].unknown_1 = 3;
|
||||
effectPacket.data().effects[0].unknown_2 = 1;
|
||||
effectPacket.data().effects[0].value = damage;
|
||||
effectPacket.data().effects[0].effectType = Common::ActionEffectType::Damage;
|
||||
effectPacket.data().effects[0].hitSeverity = Common::ActionHitSeverityType::NormalDamage;
|
||||
effectPacket.data().effects[0].unknown_3 = 7;
|
||||
|
||||
sendToInRangeSet(effectPacket, true);
|
||||
|
@ -1501,9 +1502,9 @@ void Core::Entity::Player::autoAttack( ActorPtr pTarget )
|
|||
effectPacket.data().actionTextId = 7;
|
||||
effectPacket.data().rotation = Math::Util::floatToUInt16Rot(getRotation());
|
||||
effectPacket.data().effectTarget = pTarget->getId();
|
||||
effectPacket.data().effects[0].param1 = damage;
|
||||
effectPacket.data().effects[0].unknown_1 = 3;
|
||||
effectPacket.data().effects[0].unknown_2 = 2;
|
||||
effectPacket.data().effects[0].value = damage;
|
||||
effectPacket.data().effects[0].effectType = Common::ActionEffectType::Damage;
|
||||
effectPacket.data().effects[0].hitSeverity = Common::ActionHitSeverityType::NormalDamage;
|
||||
effectPacket.data().effects[0].unknown_3 = 71;
|
||||
|
||||
sendToInRangeSet(effectPacket, true);
|
||||
|
@ -1518,6 +1519,9 @@ 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 );
|
||||
|
||||
|
||||
switch( type )
|
||||
{
|
||||
|
||||
|
@ -1534,9 +1538,9 @@ void Core::Entity::Player::handleScriptSkill( uint32_t type, uint32_t actionId,
|
|||
effectPacket.data().numEffects = 1;
|
||||
effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() );
|
||||
effectPacket.data().effectTarget = pTarget.getId();
|
||||
effectPacket.data().effects[0].param1 = static_cast< int16_t >( param1 );
|
||||
effectPacket.data().effects[0].unknown_1 = 3;
|
||||
effectPacket.data().effects[0].unknown_2 = 1;
|
||||
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 );
|
||||
|
@ -1564,9 +1568,9 @@ void Core::Entity::Player::handleScriptSkill( uint32_t type, uint32_t actionId,
|
|||
effectPacket.data().numEffects = 1;
|
||||
effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() );
|
||||
effectPacket.data().effectTarget = pTarget.getId();
|
||||
effectPacket.data().effects[0].param1 = calculatedHeal;
|
||||
effectPacket.data().effects[0].unknown_1 = 4;
|
||||
effectPacket.data().effects[0].unknown_2 = 1;
|
||||
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;
|
||||
|
||||
sendToInRangeSet( effectPacket, true );
|
||||
|
@ -1574,6 +1578,41 @@ void Core::Entity::Player::handleScriptSkill( uint32_t type, uint32_t actionId,
|
|||
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
|
||||
|
||||
if ( actionInfoPtr->is_aoe )
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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 );
|
||||
sendDebug( "AoE hit actor " + pCurAct->getName() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pTarget.heal( calculatedHeal );
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ void Core::Network::GameConnection::skillHandler( const Packets::GamePacket& inP
|
|||
std::string actionIdStr = boost::str( boost::format( "%|04X|" ) % action );
|
||||
pPlayer->sendDebug( "---------------------------------------" );
|
||||
pPlayer->sendDebug( "ActionHandler ( " + actionIdStr + " | " +
|
||||
g_exdData.m_actionInfoMap[action].name +
|
||||
g_exdData.getActionInfo( action )->name +
|
||||
" | " + std::to_string( targetId ) + " )" );
|
||||
|
||||
pPlayer->queuePacket( ActorControlPacket142( pPlayer->getId(), ActorControlType::ActionStart, 0x01, action ) );
|
||||
|
|
Loading…
Add table
Reference in a new issue