mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-02 16:57:47 +00:00
enum/struct/packet updates, fix dot/hot tick, remove incorrect initial delay for player autoattacks.
This commit is contained in:
parent
3fb6657d7d
commit
60e701dbdd
11 changed files with 73 additions and 74 deletions
|
@ -412,7 +412,7 @@ namespace Sapphire::Common
|
||||||
struct StatusEffect
|
struct StatusEffect
|
||||||
{
|
{
|
||||||
uint16_t effect_id;
|
uint16_t effect_id;
|
||||||
uint16_t unknown1;
|
uint16_t param;
|
||||||
float duration;
|
float duration;
|
||||||
uint32_t sourceActorId;
|
uint32_t sourceActorId;
|
||||||
};
|
};
|
||||||
|
@ -591,9 +591,10 @@ namespace Sapphire::Common
|
||||||
// DRGGauge3Eyes = 76,
|
// DRGGauge3Eyes = 76,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class ActionType : int8_t
|
enum class AttackType : int8_t
|
||||||
{
|
{
|
||||||
WeaponOverride = -1, // Needs more investigation (takes the damage type of the equipped weapon)?
|
//WeaponOverride = -1, // Needs more investigation (takes the damage type of the equipped weapon)?
|
||||||
|
Physical = -1, // seems to be the case
|
||||||
Unknown_0 = 0,
|
Unknown_0 = 0,
|
||||||
Slashing = 1,
|
Slashing = 1,
|
||||||
Piercing = 2,
|
Piercing = 2,
|
||||||
|
@ -623,6 +624,8 @@ namespace Sapphire::Common
|
||||||
TpGain = 13,
|
TpGain = 13,
|
||||||
GpGain = 14,
|
GpGain = 14,
|
||||||
ApplyStatusEffect = 15,
|
ApplyStatusEffect = 15,
|
||||||
|
//ApplyStatusEffect2 = 16, // thin air uses this one but works fine with 15 wtf?
|
||||||
|
StatusNoEffect = 21,
|
||||||
/*!
|
/*!
|
||||||
* @brief Tells the client that it should show combo indicators on actions.
|
* @brief Tells the client that it should show combo indicators on actions.
|
||||||
*
|
*
|
||||||
|
@ -649,7 +652,9 @@ namespace Sapphire::Common
|
||||||
enum class ActionEffectResultFlag : uint8_t
|
enum class ActionEffectResultFlag : uint8_t
|
||||||
{
|
{
|
||||||
None = 0,
|
None = 0,
|
||||||
|
Absorbed = 0x04,
|
||||||
EffectOnSource = 0x80,
|
EffectOnSource = 0x80,
|
||||||
|
Reflected = 0xA0,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum ItemActionType : uint16_t
|
enum ItemActionType : uint16_t
|
||||||
|
|
|
@ -160,7 +160,7 @@ namespace Sapphire::Network::Packets
|
||||||
PlayerStateFlags = 0x02C6, // updated 5.18
|
PlayerStateFlags = 0x02C6, // updated 5.18
|
||||||
PlayerClassInfo = 0x01B0, // updated 5.18
|
PlayerClassInfo = 0x01B0, // updated 5.18
|
||||||
|
|
||||||
ModelEquip = 0x0170, // updated 5.11
|
ModelEquip = 0x02E6, // updated 5.18
|
||||||
Examine = 0x0366, // updated 5.18
|
Examine = 0x0366, // updated 5.18
|
||||||
CharaNameReq = 0x0116, // updated 5.18
|
CharaNameReq = 0x0116, // updated 5.18
|
||||||
|
|
||||||
|
|
|
@ -422,7 +422,8 @@ namespace Sapphire::Network::Packets::Server
|
||||||
uint16_t current_mp;
|
uint16_t current_mp;
|
||||||
uint16_t max_mp;
|
uint16_t max_mp;
|
||||||
uint16_t currentTp;
|
uint16_t currentTp;
|
||||||
uint16_t unknown1;
|
uint8_t shieldPercentage;
|
||||||
|
uint8_t unknown1;
|
||||||
Common::StatusEffect effect[30];
|
Common::StatusEffect effect[30];
|
||||||
uint32_t padding;
|
uint32_t padding;
|
||||||
};
|
};
|
||||||
|
@ -439,27 +440,18 @@ namespace Sapphire::Network::Packets::Server
|
||||||
*/
|
*/
|
||||||
struct FFXIVIpcEffectResult : FFXIVIpcBasePacket< EffectResult >
|
struct FFXIVIpcEffectResult : FFXIVIpcBasePacket< EffectResult >
|
||||||
{
|
{
|
||||||
uint32_t unknown;
|
uint32_t globalSequence;
|
||||||
uint32_t actor_id;
|
uint32_t actor_id;
|
||||||
//uint8_t unknown1;
|
|
||||||
//uint8_t unknown2;
|
|
||||||
//uint16_t padding1;
|
|
||||||
//uint32_t current_hp;
|
|
||||||
//uint16_t current_mp;
|
|
||||||
//uint16_t current_tp;
|
|
||||||
//uint32_t max_hp;
|
|
||||||
//uint16_t max_mp;
|
|
||||||
//uint16_t max_something;
|
|
||||||
uint32_t current_hp;
|
uint32_t current_hp;
|
||||||
uint32_t max_hp;
|
uint32_t max_hp;
|
||||||
uint16_t current_mp;
|
uint16_t current_mp;
|
||||||
uint16_t unknown1;
|
uint16_t current_tp;
|
||||||
uint16_t max_mp;
|
uint16_t max_mp;
|
||||||
uint8_t unknown2;
|
uint8_t unknown1;
|
||||||
uint8_t classId;
|
uint8_t classId;
|
||||||
uint8_t unknown4;
|
uint8_t shieldPercentage;
|
||||||
uint8_t unkFlag;
|
uint8_t entryCount;
|
||||||
uint16_t unknown6;
|
uint16_t unknown2;
|
||||||
|
|
||||||
struct StatusEntry
|
struct StatusEntry
|
||||||
{
|
{
|
||||||
|
@ -467,12 +459,12 @@ namespace Sapphire::Network::Packets::Server
|
||||||
uint8_t unknown3;
|
uint8_t unknown3;
|
||||||
uint16_t id;
|
uint16_t id;
|
||||||
uint16_t param;
|
uint16_t param;
|
||||||
uint16_t unknown5; // Sort this out (old right half of power/param property)
|
uint16_t unknown4; // Sort this out (old right half of power/param property)
|
||||||
float duration;
|
float duration;
|
||||||
uint32_t sourceActorId;
|
uint32_t sourceActorId;
|
||||||
} statusEntries[4];
|
} statusEntries[4];
|
||||||
|
|
||||||
uint32_t unknown7;
|
uint32_t unknown5;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -565,7 +565,7 @@ bool Action::Action::playerPreCheck( Entity::Player& player )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// npc actions/non player actions
|
// npc actions/non player actions
|
||||||
if( m_actionData->classJob == -1 )
|
if( m_actionData->classJob == -1 && !m_actionData->isRoleAction )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if( player.getLevel() < m_actionData->classJobLevel )
|
if( player.getLevel() < m_actionData->classJobLevel )
|
||||||
|
@ -574,7 +574,7 @@ bool Action::Action::playerPreCheck( Entity::Player& player )
|
||||||
auto currentClass = player.getClass();
|
auto currentClass = player.getClass();
|
||||||
auto actionClass = static_cast< Common::ClassJob >( m_actionData->classJob );
|
auto actionClass = static_cast< Common::ClassJob >( m_actionData->classJob );
|
||||||
|
|
||||||
if( actionClass != Common::ClassJob::Adventurer && currentClass != actionClass )
|
if( actionClass != Common::ClassJob::Adventurer && currentClass != actionClass && !m_actionData->isRoleAction )
|
||||||
{
|
{
|
||||||
// check if not a base class action
|
// check if not a base class action
|
||||||
auto exdData = m_pFw->get< Data::ExdDataGenerated >();
|
auto exdData = m_pFw->get< Data::ExdDataGenerated >();
|
||||||
|
|
|
@ -396,6 +396,7 @@ void Sapphire::Entity::BNpc::deaggro( Sapphire::Entity::CharaPtr pChara )
|
||||||
|
|
||||||
void Sapphire::Entity::BNpc::onTick()
|
void Sapphire::Entity::BNpc::onTick()
|
||||||
{
|
{
|
||||||
|
Chara::onTick();
|
||||||
if( m_state == BNpcState::Retreat )
|
if( m_state == BNpcState::Retreat )
|
||||||
{
|
{
|
||||||
regainHp();
|
regainHp();
|
||||||
|
|
|
@ -44,6 +44,7 @@ Sapphire::Entity::Chara::Chara( ObjKind type, FrameworkPtr pFw ) :
|
||||||
|
|
||||||
m_lastTickTime = 0;
|
m_lastTickTime = 0;
|
||||||
m_lastUpdate = 0;
|
m_lastUpdate = 0;
|
||||||
|
m_lastAttack = Util::getTimeMs();
|
||||||
|
|
||||||
m_bonusStats.fill( 0 );
|
m_bonusStats.fill( 0 );
|
||||||
|
|
||||||
|
@ -354,6 +355,8 @@ bool Sapphire::Entity::Chara::checkAction()
|
||||||
|
|
||||||
void Sapphire::Entity::Chara::update( uint64_t tickCount )
|
void Sapphire::Entity::Chara::update( uint64_t tickCount )
|
||||||
{
|
{
|
||||||
|
updateStatusEffects();
|
||||||
|
|
||||||
if( std::difftime( static_cast< time_t >( tickCount ), m_lastTickTime ) > 3000 )
|
if( std::difftime( static_cast< time_t >( tickCount ), m_lastTickTime ) > 3000 )
|
||||||
{
|
{
|
||||||
onTick();
|
onTick();
|
||||||
|
@ -532,16 +535,15 @@ void Sapphire::Entity::Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEf
|
||||||
|
|
||||||
auto statusEffectAdd = makeZonePacket< FFXIVIpcEffectResult >( getId() );
|
auto statusEffectAdd = makeZonePacket< FFXIVIpcEffectResult >( getId() );
|
||||||
|
|
||||||
|
statusEffectAdd->data().globalSequence = getCurrentTerritory()->getNextEffectSequence();
|
||||||
statusEffectAdd->data().actor_id = pEffect->getTargetActorId();
|
statusEffectAdd->data().actor_id = pEffect->getTargetActorId();
|
||||||
statusEffectAdd->data().current_hp = getHp();
|
statusEffectAdd->data().current_hp = getHp();
|
||||||
statusEffectAdd->data().current_mp = static_cast< uint16_t >( getMp() );
|
statusEffectAdd->data().current_mp = static_cast< uint16_t >( getMp() );
|
||||||
//statusEffectAdd->data().current_tp = getTp();
|
statusEffectAdd->data().current_tp = getTp();
|
||||||
statusEffectAdd->data().max_hp = getMaxHp();
|
statusEffectAdd->data().max_hp = getMaxHp();
|
||||||
statusEffectAdd->data().max_mp = static_cast< uint16_t >( getMaxMp() );
|
statusEffectAdd->data().max_mp = static_cast< uint16_t >( getMaxMp() );
|
||||||
//statusEffectAdd->data().max_something = 1;
|
statusEffectAdd->data().classId = static_cast< uint8_t >( getClass() );
|
||||||
//statusEffectAdd->data().unknown2 = 28;
|
statusEffectAdd->data().entryCount = 1;
|
||||||
statusEffectAdd->data().classId = static_cast< uint8_t >(getClass());
|
|
||||||
statusEffectAdd->data().unkFlag = 1;
|
|
||||||
|
|
||||||
auto& status = statusEffectAdd->data().statusEntries[0];
|
auto& status = statusEffectAdd->data().statusEntries[0];
|
||||||
|
|
||||||
|
@ -681,9 +683,6 @@ void Sapphire::Entity::Chara::updateStatusEffects()
|
||||||
{
|
{
|
||||||
uint64_t currentTimeMs = Util::getTimeMs();
|
uint64_t currentTimeMs = Util::getTimeMs();
|
||||||
|
|
||||||
uint32_t thisTickDmg = 0;
|
|
||||||
uint32_t thisTickHeal = 0;
|
|
||||||
|
|
||||||
for( auto effectIt : m_statusEffectMap )
|
for( auto effectIt : m_statusEffectMap )
|
||||||
{
|
{
|
||||||
uint8_t effectIndex = effectIt.first;
|
uint8_t effectIndex = effectIt.first;
|
||||||
|
@ -694,7 +693,7 @@ void Sapphire::Entity::Chara::updateStatusEffects()
|
||||||
uint32_t duration = effect->getDuration();
|
uint32_t duration = effect->getDuration();
|
||||||
uint32_t tickRate = effect->getTickRate();
|
uint32_t tickRate = effect->getTickRate();
|
||||||
|
|
||||||
if( ( currentTimeMs - startTime ) > duration )
|
if( duration > 0 && ( currentTimeMs - startTime ) > duration )
|
||||||
{
|
{
|
||||||
// remove status effect
|
// remove status effect
|
||||||
removeStatusEffect( effectIndex );
|
removeStatusEffect( effectIndex );
|
||||||
|
@ -706,41 +705,7 @@ void Sapphire::Entity::Chara::updateStatusEffects()
|
||||||
{
|
{
|
||||||
effect->setLastTick( currentTimeMs );
|
effect->setLastTick( currentTimeMs );
|
||||||
effect->onTick();
|
effect->onTick();
|
||||||
|
|
||||||
auto thisEffect = effect->getTickEffect();
|
|
||||||
|
|
||||||
switch( thisEffect.first )
|
|
||||||
{
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
thisTickDmg += thisEffect.second;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
{
|
|
||||||
thisTickHeal += thisEffect.second;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if( thisTickDmg != 0 )
|
|
||||||
{
|
|
||||||
takeDamage( thisTickDmg );
|
|
||||||
sendToInRangeSet( makeActorControl( getId(), HPFloatingText, 0,
|
|
||||||
static_cast< uint8_t >( ActionEffectType::Damage ), thisTickDmg ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
if( thisTickHeal != 0 )
|
|
||||||
{
|
|
||||||
heal( thisTickDmg );
|
|
||||||
sendToInRangeSet( makeActorControl( getId(), HPFloatingText, 0,
|
|
||||||
static_cast< uint8_t >( ActionEffectType::Heal ), thisTickHeal ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -944,3 +909,42 @@ uint32_t Sapphire::Entity::Chara::getStatValue( Sapphire::Common::BaseParam base
|
||||||
|
|
||||||
return value + getBonusStat( baseParam );
|
return value + getBonusStat( baseParam );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sapphire::Entity::Chara::onTick()
|
||||||
|
{
|
||||||
|
uint32_t thisTickDmg = 0;
|
||||||
|
uint32_t thisTickHeal = 0;
|
||||||
|
|
||||||
|
for( auto effectIt : m_statusEffectMap )
|
||||||
|
{
|
||||||
|
auto thisEffect = effectIt.second->getTickEffect();
|
||||||
|
switch( thisEffect.first )
|
||||||
|
{
|
||||||
|
case 1:
|
||||||
|
{
|
||||||
|
thisTickDmg += thisEffect.second;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
thisTickHeal += thisEffect.second;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( thisTickDmg != 0 )
|
||||||
|
{
|
||||||
|
takeDamage( thisTickDmg );
|
||||||
|
sendToInRangeSet( makeActorControl( getId(), HPFloatingText, 0,
|
||||||
|
static_cast< uint8_t >( ActionEffectType::Damage ), thisTickDmg ), true );
|
||||||
|
}
|
||||||
|
|
||||||
|
if( thisTickHeal != 0 )
|
||||||
|
{
|
||||||
|
heal( thisTickHeal );
|
||||||
|
sendToInRangeSet( makeActorControl( getId(), HPFloatingText, 0,
|
||||||
|
static_cast< uint8_t >( ActionEffectType::Heal ), thisTickHeal ), true );
|
||||||
|
}
|
||||||
|
}
|
|
@ -251,7 +251,7 @@ namespace Sapphire::Entity
|
||||||
|
|
||||||
virtual void onActionFriendly( Chara& pSource ) {};
|
virtual void onActionFriendly( Chara& pSource ) {};
|
||||||
|
|
||||||
virtual void onTick() {};
|
virtual void onTick();
|
||||||
|
|
||||||
virtual void changeTarget( uint64_t targetId );
|
virtual void changeTarget( uint64_t targetId );
|
||||||
|
|
||||||
|
|
|
@ -306,7 +306,6 @@ void Sapphire::Entity::Player::calculateStats()
|
||||||
void Sapphire::Entity::Player::setAutoattack( bool mode )
|
void Sapphire::Entity::Player::setAutoattack( bool mode )
|
||||||
{
|
{
|
||||||
m_bAutoattack = mode;
|
m_bAutoattack = mode;
|
||||||
m_lastAttack = Util::getTimeMs();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Sapphire::Entity::Player::isAutoattackOn() const
|
bool Sapphire::Entity::Player::isAutoattackOn() const
|
||||||
|
@ -1100,8 +1099,6 @@ void Sapphire::Entity::Player::update( uint64_t tickCount )
|
||||||
if( !isAlive() )
|
if( !isAlive() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
updateStatusEffects();
|
|
||||||
|
|
||||||
m_lastUpdate = tickCount;
|
m_lastUpdate = tickCount;
|
||||||
|
|
||||||
if( !checkAction() )
|
if( !checkAction() )
|
||||||
|
|
|
@ -370,7 +370,7 @@ void Sapphire::Entity::Player::onDeath()
|
||||||
// TODO: slightly ugly here and way too static. Needs too be done properly
|
// TODO: slightly ugly here and way too static. Needs too be done properly
|
||||||
void Sapphire::Entity::Player::onTick()
|
void Sapphire::Entity::Player::onTick()
|
||||||
{
|
{
|
||||||
|
Chara::onTick();
|
||||||
// add 3 seconds to total play time
|
// add 3 seconds to total play time
|
||||||
m_playTime += 3;
|
m_playTime += 3;
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ namespace Sapphire::Network::Packets::Server
|
||||||
( currentTimeMs -
|
( currentTimeMs -
|
||||||
effect.second->getStartTimeMs() ) ) / 1000;
|
effect.second->getStartTimeMs() ) ) / 1000;
|
||||||
m_data.effect[ effect.first ].sourceActorId = effect.second->getSrcActorId();
|
m_data.effect[ effect.first ].sourceActorId = effect.second->getSrcActorId();
|
||||||
m_data.effect[ effect.first ].unknown1 = effect.second->getParam();
|
m_data.effect[ effect.first ].param = effect.second->getParam();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -142,7 +142,7 @@ namespace Sapphire::Network::Packets::Server
|
||||||
( currentTimeMs -
|
( currentTimeMs -
|
||||||
effect.second->getStartTimeMs() ) ) / 1000;
|
effect.second->getStartTimeMs() ) ) / 1000;
|
||||||
m_data.effect[ effect.first ].sourceActorId = effect.second->getSrcActorId();
|
m_data.effect[ effect.first ].sourceActorId = effect.second->getSrcActorId();
|
||||||
m_data.effect[ effect.first ].unknown1 = effect.second->getParam();
|
m_data.effect[ effect.first ].param = effect.second->getParam();
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue