1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-02 08:57:44 +00:00

Merge pull request #629 from collett8192/misc_fix

enum/struct/packet updates, fix dot/hot tick, remove incorrect initial delay for player autoattacks.
This commit is contained in:
Adam 2020-01-20 09:15:21 +11:00 committed by GitHub
commit 91974b4e71
11 changed files with 73 additions and 74 deletions

View file

@ -412,7 +412,7 @@ namespace Sapphire::Common
struct StatusEffect
{
uint16_t effect_id;
uint16_t unknown1;
uint16_t param;
float duration;
uint32_t sourceActorId;
};
@ -591,9 +591,10 @@ namespace Sapphire::Common
// 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,
Slashing = 1,
Piercing = 2,
@ -623,6 +624,8 @@ namespace Sapphire::Common
TpGain = 13,
GpGain = 14,
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.
*
@ -649,7 +652,9 @@ namespace Sapphire::Common
enum class ActionEffectResultFlag : uint8_t
{
None = 0,
Absorbed = 0x04,
EffectOnSource = 0x80,
Reflected = 0xA0,
};
enum ItemActionType : uint16_t

View file

@ -160,7 +160,7 @@ namespace Sapphire::Network::Packets
PlayerStateFlags = 0x02C6, // updated 5.18
PlayerClassInfo = 0x01B0, // updated 5.18
ModelEquip = 0x0170, // updated 5.11
ModelEquip = 0x02E6, // updated 5.18
Examine = 0x0366, // updated 5.18
CharaNameReq = 0x0116, // updated 5.18

View file

@ -422,7 +422,8 @@ namespace Sapphire::Network::Packets::Server
uint16_t current_mp;
uint16_t max_mp;
uint16_t currentTp;
uint16_t unknown1;
uint8_t shieldPercentage;
uint8_t unknown1;
Common::StatusEffect effect[30];
uint32_t padding;
};
@ -439,27 +440,18 @@ namespace Sapphire::Network::Packets::Server
*/
struct FFXIVIpcEffectResult : FFXIVIpcBasePacket< EffectResult >
{
uint32_t unknown;
uint32_t globalSequence;
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 max_hp;
uint16_t current_mp;
uint16_t unknown1;
uint16_t current_tp;
uint16_t max_mp;
uint8_t unknown2;
uint8_t unknown1;
uint8_t classId;
uint8_t unknown4;
uint8_t unkFlag;
uint16_t unknown6;
uint8_t shieldPercentage;
uint8_t entryCount;
uint16_t unknown2;
struct StatusEntry
{
@ -467,12 +459,12 @@ namespace Sapphire::Network::Packets::Server
uint8_t unknown3;
uint16_t id;
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;
uint32_t sourceActorId;
} statusEntries[4];
uint32_t unknown7;
uint32_t unknown5;
};
/**

View file

@ -565,7 +565,7 @@ bool Action::Action::playerPreCheck( Entity::Player& player )
return false;
// npc actions/non player actions
if( m_actionData->classJob == -1 )
if( m_actionData->classJob == -1 && !m_actionData->isRoleAction )
return false;
if( player.getLevel() < m_actionData->classJobLevel )
@ -574,7 +574,7 @@ bool Action::Action::playerPreCheck( Entity::Player& player )
auto currentClass = player.getClass();
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
auto exdData = m_pFw->get< Data::ExdDataGenerated >();

View file

@ -396,6 +396,7 @@ void Sapphire::Entity::BNpc::deaggro( Sapphire::Entity::CharaPtr pChara )
void Sapphire::Entity::BNpc::onTick()
{
Chara::onTick();
if( m_state == BNpcState::Retreat )
{
regainHp();

View file

@ -44,6 +44,7 @@ Sapphire::Entity::Chara::Chara( ObjKind type, FrameworkPtr pFw ) :
m_lastTickTime = 0;
m_lastUpdate = 0;
m_lastAttack = Util::getTimeMs();
m_bonusStats.fill( 0 );
@ -354,6 +355,8 @@ bool Sapphire::Entity::Chara::checkAction()
void Sapphire::Entity::Chara::update( uint64_t tickCount )
{
updateStatusEffects();
if( std::difftime( static_cast< time_t >( tickCount ), m_lastTickTime ) > 3000 )
{
onTick();
@ -532,16 +535,15 @@ void Sapphire::Entity::Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEf
auto statusEffectAdd = makeZonePacket< FFXIVIpcEffectResult >( getId() );
statusEffectAdd->data().globalSequence = getCurrentTerritory()->getNextEffectSequence();
statusEffectAdd->data().actor_id = pEffect->getTargetActorId();
statusEffectAdd->data().current_hp = getHp();
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_mp = static_cast< uint16_t >( getMaxMp() );
//statusEffectAdd->data().max_something = 1;
//statusEffectAdd->data().unknown2 = 28;
statusEffectAdd->data().classId = static_cast< uint8_t >(getClass());
statusEffectAdd->data().unkFlag = 1;
statusEffectAdd->data().classId = static_cast< uint8_t >( getClass() );
statusEffectAdd->data().entryCount = 1;
auto& status = statusEffectAdd->data().statusEntries[0];
@ -681,9 +683,6 @@ void Sapphire::Entity::Chara::updateStatusEffects()
{
uint64_t currentTimeMs = Util::getTimeMs();
uint32_t thisTickDmg = 0;
uint32_t thisTickHeal = 0;
for( auto effectIt : m_statusEffectMap )
{
uint8_t effectIndex = effectIt.first;
@ -694,7 +693,7 @@ void Sapphire::Entity::Chara::updateStatusEffects()
uint32_t duration = effect->getDuration();
uint32_t tickRate = effect->getTickRate();
if( ( currentTimeMs - startTime ) > duration )
if( duration > 0 && ( currentTimeMs - startTime ) > duration )
{
// remove status effect
removeStatusEffect( effectIndex );
@ -706,41 +705,7 @@ void Sapphire::Entity::Chara::updateStatusEffects()
{
effect->setLastTick( currentTimeMs );
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 );
}
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 );
}
}

View file

@ -251,7 +251,7 @@ namespace Sapphire::Entity
virtual void onActionFriendly( Chara& pSource ) {};
virtual void onTick() {};
virtual void onTick();
virtual void changeTarget( uint64_t targetId );

View file

@ -306,7 +306,6 @@ void Sapphire::Entity::Player::calculateStats()
void Sapphire::Entity::Player::setAutoattack( bool mode )
{
m_bAutoattack = mode;
m_lastAttack = Util::getTimeMs();
}
bool Sapphire::Entity::Player::isAutoattackOn() const
@ -1100,8 +1099,6 @@ void Sapphire::Entity::Player::update( uint64_t tickCount )
if( !isAlive() )
return;
updateStatusEffects();
m_lastUpdate = tickCount;
if( !checkAction() )

View file

@ -370,7 +370,7 @@ void Sapphire::Entity::Player::onDeath()
// TODO: slightly ugly here and way too static. Needs too be done properly
void Sapphire::Entity::Player::onTick()
{
Chara::onTick();
// add 3 seconds to total play time
m_playTime += 3;

View file

@ -96,7 +96,7 @@ namespace Sapphire::Network::Packets::Server
( currentTimeMs -
effect.second->getStartTimeMs() ) ) / 1000;
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();
}
};

View file

@ -142,7 +142,7 @@ namespace Sapphire::Network::Packets::Server
( currentTimeMs -
effect.second->getStartTimeMs() ) ) / 1000;
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();
}
};