1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-05-07 11:17:46 +00:00

Cleaned up bnppc code, fixed effect packet

This commit is contained in:
Mordred 2019-01-19 01:15:17 +01:00
parent 77c4403a2c
commit 38acccea57
7 changed files with 121 additions and 124 deletions

View file

@ -531,8 +531,7 @@ namespace Sapphire::Common
Unaspected = 7 // Doesn't imply magical unaspected damage - could be unaspected physical
};
enum class ActionType :
int8_t
enum class ActionType : int8_t
{
WeaponOverride = -1, // Needs more investigation (takes the damage type of the equipped weapon)?
Unknown_0 = 0,
@ -546,8 +545,7 @@ namespace Sapphire::Common
LimitBreak = 8,
};
enum ActionEffectType :
uint8_t
enum ActionEffectType : uint8_t
{
Nothing = 0,
Miss = 1,
@ -568,8 +566,7 @@ namespace Sapphire::Common
Mount = 38
};
enum class ActionHitSeverityType :
uint8_t
enum class ActionHitSeverityType : uint8_t
{
NormalDamage = 0,
CritHeal = 0,
@ -579,16 +576,14 @@ namespace Sapphire::Common
CritDirectHitDamage = 3
};
enum ActionEffectDisplayType :
uint8_t
enum ActionEffectDisplayType : uint8_t
{
HideActionName = 0,
ShowActionName = 1,
ShowItemName = 2,
};
enum class ActionCollisionType :
uint8_t
enum class ActionCollisionType : uint8_t
{
None,
SingleTarget,
@ -601,32 +596,28 @@ namespace Sapphire::Common
Unknown3
};
enum HandleActionType :
uint8_t
enum HandleActionType : uint8_t
{
Event,
Spell,
Teleport
};
enum HandleSkillType :
uint8_t
enum HandleSkillType : uint8_t
{
StdDamage,
StdHeal,
StdDot,
};
enum InvincibilityType :
uint8_t
enum InvincibilityType : uint8_t
{
InvincibilityNone,
InvincibilityRefill,
InvincibilityStayAlive,
};
enum PlayerStateFlag :
uint8_t
enum PlayerStateFlag : uint8_t
{
HideUILockChar = 0, // as the name suggests, hides the ui and logs the char...
InCombat = 1, // in Combat, locks gearchange/return/teleport
@ -642,8 +633,7 @@ namespace Sapphire::Common
};
enum struct FateStatus :
uint8_t
enum struct FateStatus : uint8_t
{
Active = 2,
Inactive = 4,
@ -651,8 +641,7 @@ namespace Sapphire::Common
Completed = 8,
};
enum struct ChatType :
uint16_t
enum struct ChatType : uint16_t
{
LogKindError,
ServerDebug,

View file

@ -402,34 +402,48 @@ struct EffectEntry
struct EffectHeader
{
uint64_t animationTargetId; // who the animation targets
uint32_t actionId; // what the casting player casts, shown in battle log/ui
uint32_t globalEffectCounter; // seems to only increment on retail?
float animationLockTime; // maybe? doesn't seem to do anything
float animationLockTime; // maybe? doesn't seem to do anything
uint32_t someTargetId; // always 00 00 00 E0, 0x0E000000 is the internal def for INVALID TARGET ID
uint16_t hiddenAnimation; // if 0, always shows animation, otherwise hides it. counts up by 1 for each animation skipped on a caster
uint16_t rotation;
uint16_t actionAnimationId; // the animation that is played by the casting character
uint8_t unknown1E; // can be 0,1,2 - maybe other values? - doesn't do anything?
uint8_t variation; // variation in the animation
Common::ActionEffectDisplayType effectDisplayType;
uint8_t unknown20; // is read by handler, runs code which gets the LODWORD of animationLockTime (wtf?)
uint8_t effectCount; // ignores effects if 0, otherwise parses all of them
uint16_t padding_21;
uint32_t padding_22[2];
};
struct FFXIVIpcEffect :
FFXIVIpcBasePacket< Effect >
struct FFXIVIpcEffect : FFXIVIpcBasePacket< Effect >
{
EffectHeader header;
uint64_t animationTargetId; // who the animation targets
EffectEntry effects[8];
uint32_t actionId; // what the casting player casts, shown in battle log/ui
uint32_t globalEffectCounter; // seems to only increment on retail?
float animationLockTime; // maybe? doesn't seem to do anything
uint32_t someTargetId; // always 00 00 00 E0, 0x0E000000 is the internal def for INVALID TARGET ID
uint16_t hiddenAnimation; // if 0, always shows animation, otherwise hides it. counts up by 1 for each animation skipped on a caster
uint16_t rotation;
uint16_t actionAnimationId; // the animation that is played by the casting character
uint8_t variation; // variation in the animation
Common::ActionEffectDisplayType effectDisplayType;
uint8_t unknown20; // is read by handler, runs code which gets the LODWORD of animationLockTime (wtf?)
uint8_t effectCount; // ignores effects if 0, otherwise parses all of them
uint16_t padding_21;
uint16_t padding_22[3];
uint8_t effects[8*8];
uint16_t padding_6A[3];

View file

@ -180,13 +180,13 @@ void Sapphire::Entity::BNpc::hateListClear()
auto it = m_hateList.begin();
for( auto listEntry : m_hateList )
{
//if( isInRangeSet( listEntry->m_pActor ) )
//deaggro( listEntry->m_pActor );
if( isInRangeSet( listEntry->m_pChara ) )
deaggro( listEntry->m_pChara );
}
m_hateList.clear();
}
Sapphire::Entity::ActorPtr Sapphire::Entity::BNpc::hateListGetHighest()
Sapphire::Entity::CharaPtr Sapphire::Entity::BNpc::hateListGetHighest()
{
auto it = m_hateList.begin();
uint32_t maxHate = 0;
@ -201,25 +201,25 @@ Sapphire::Entity::ActorPtr Sapphire::Entity::BNpc::hateListGetHighest()
}
if( entry && maxHate != 0 )
return entry->m_pActor;
return entry->m_pChara;
return nullptr;
}
void Sapphire::Entity::BNpc::hateListAdd( Sapphire::Entity::ActorPtr pActor, int32_t hateAmount )
void Sapphire::Entity::BNpc::hateListAdd( Sapphire::Entity::CharaPtr pChara, int32_t hateAmount )
{
auto hateEntry = std::make_shared< HateListEntry >();
hateEntry->m_hateAmount = hateAmount;
hateEntry->m_pActor = pActor;
hateEntry->m_pChara = pChara;
m_hateList.insert( hateEntry );
}
void Sapphire::Entity::BNpc::hateListUpdate( Sapphire::Entity::ActorPtr pActor, int32_t hateAmount )
void Sapphire::Entity::BNpc::hateListUpdate( Sapphire::Entity::CharaPtr pChara, int32_t hateAmount )
{
for( auto listEntry : m_hateList )
{
if( listEntry->m_pActor == pActor )
if( listEntry->m_pChara == pChara )
{
listEntry->m_hateAmount += hateAmount;
return;
@ -228,21 +228,21 @@ void Sapphire::Entity::BNpc::hateListUpdate( Sapphire::Entity::ActorPtr pActor,
auto hateEntry = std::make_shared< HateListEntry >();
hateEntry->m_hateAmount = hateAmount;
hateEntry->m_pActor = pActor;
hateEntry->m_pChara = pChara;
m_hateList.insert( hateEntry );
}
void Sapphire::Entity::BNpc::hateListRemove( Sapphire::Entity::ActorPtr pActor )
void Sapphire::Entity::BNpc::hateListRemove( Sapphire::Entity::CharaPtr pChara )
{
for( auto listEntry : m_hateList )
{
if( listEntry->m_pActor == pActor )
if( listEntry->m_pChara == pChara )
{
m_hateList.erase( listEntry );
if( pActor->isPlayer() )
if( pChara->isPlayer() )
{
PlayerPtr tmpPlayer = pActor->getAsPlayer();
PlayerPtr tmpPlayer = pChara->getAsPlayer();
//tmpPlayer->onMobDeaggro( getAsBattleNpc() );
}
return;
@ -250,47 +250,51 @@ void Sapphire::Entity::BNpc::hateListRemove( Sapphire::Entity::ActorPtr pActor )
}
}
bool Sapphire::Entity::BNpc::hateListHasActor( Sapphire::Entity::ActorPtr pActor )
bool Sapphire::Entity::BNpc::hateListHasActor( Sapphire::Entity::CharaPtr pChara )
{
for( auto listEntry : m_hateList )
{
if( listEntry->m_pActor == pActor )
if( listEntry->m_pChara == pChara )
return true;
}
return false;
}
void Sapphire::Entity::BNpc::aggro( Sapphire::Entity::ActorPtr pActor )
void Sapphire::Entity::BNpc::aggro( Sapphire::Entity::CharaPtr pChara )
{
m_lastAttack = Util::getTimeMs();
hateListUpdate( pActor, 1 );
hateListUpdate( pChara, 1 );
changeTarget( pActor->getId() );
changeTarget( pChara->getId() );
setStance( Stance::Active );
m_state = BNpcState::Combat;
if( pActor->isPlayer() )
if( pChara->isPlayer() )
{
PlayerPtr tmpPlayer = pActor->getAsPlayer();
PlayerPtr tmpPlayer = pChara->getAsPlayer();
tmpPlayer->queuePacket( makeActorControl142( getId(), ActorControlType::ToggleWeapon, 0, 1, 1 ) );
//tmpPlayer->onMobAggro( getAsBattleNpc() );
}
}
void Sapphire::Entity::BNpc::deaggro( Sapphire::Entity::ActorPtr pActor )
void Sapphire::Entity::BNpc::deaggro( Sapphire::Entity::CharaPtr pChara )
{
if( !hateListHasActor( pActor ) )
hateListRemove( pActor );
if( !hateListHasActor( pChara ) )
hateListRemove( pChara );
if( pActor->isPlayer() )
if( pChara->isPlayer() )
{
PlayerPtr tmpPlayer = pActor->getAsPlayer();
PlayerPtr tmpPlayer = pChara->getAsPlayer();
//tmpPlayer->onMobDeaggro( getAsBattleNpc() );
}
}
void Sapphire::Entity::BNpc::update( int64_t currTime )
{
const uint8_t minActorDistance = 4;
const uint8_t aggroRange = 8;
const uint8_t maxDistanceToOrigin = 30;
switch( m_state )
{
case BNpcState::Retreat:
@ -302,52 +306,47 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
case BNpcState::Idle:
{
CharaPtr pClosestActor = getClosestChara();
CharaPtr pClosestChara = getClosestChara();
if( ( pClosestActor != nullptr ) && pClosestActor->isAlive() )
if( pClosestChara && pClosestChara->isAlive() )
{
auto distance = Util::distance( getPos().x, getPos().y, getPos().z,
pClosestActor->getPos().x,
pClosestActor->getPos().y,
pClosestActor->getPos().z );
pClosestChara->getPos().x,
pClosestChara->getPos().y,
pClosestChara->getPos().z );
if( distance < 8 && pClosestActor->isPlayer() )
aggro( pClosestActor );
//if( distance < 8 && getbehavior() == 2 )
if( distance < aggroRange && pClosestChara->isPlayer() )
aggro( pClosestChara );
//if( distance < aggroRange && getbehavior() == 2 )
// aggro( pClosestActor );
}
}
case BNpcState::Combat:
{
auto pActor = hateListGetHighest();
if( !pActor )
auto pHatedActor = hateListGetHighest();
if( !pHatedActor )
return;
auto pClosestActor = pActor->getAsChara();
auto distanceOrig = Util::distance( getPos().x, getPos().y, getPos().z,
m_spawnPos.x,
m_spawnPos.y,
m_spawnPos.z );
if( pClosestActor && !pClosestActor->isAlive() )
if( pHatedActor && !pHatedActor->isAlive() )
{
hateListRemove( pClosestActor );
pActor = hateListGetHighest();
if( pActor )
pClosestActor = pActor->getAsChara();
else
pClosestActor.reset();
hateListRemove( pHatedActor );
pHatedActor = hateListGetHighest();
}
if( pClosestActor != nullptr )
if( pHatedActor )
{
auto distance = Util::distance( getPos().x, getPos().y, getPos().z,
pClosestActor->getPos().x,
pClosestActor->getPos().y,
pClosestActor->getPos().z );
pHatedActor->getPos().x,
pHatedActor->getPos().y,
pHatedActor->getPos().z );
if( distanceOrig > 30 )
if( distanceOrig > maxDistanceToOrigin )
{
hateListClear();
changeTarget( INVALID_GAME_OBJECT_ID );
@ -357,14 +356,14 @@ void Sapphire::Entity::BNpc::update( int64_t currTime )
break;
}
if( distance > 4 )
moveTo( pClosestActor->getPos() );
if( distance > minActorDistance )
moveTo( pHatedActor->getPos() );
else
{
if( face( pClosestActor->getPos() ) )
if( face( pHatedActor->getPos() ) )
sendPositionUpdate();
// in combat range. ATTACK!
autoAttack( pClosestActor );
autoAttack( pHatedActor );
}
}
else

View file

@ -16,7 +16,7 @@ namespace Sapphire::Entity
typedef struct
{
uint32_t m_hateAmount;
ActorPtr m_pActor;
CharaPtr m_pChara;
} HateListEntry;
enum class BNpcState
@ -67,14 +67,14 @@ namespace Sapphire::Entity
void setState( BNpcState state );
void hateListClear();
ActorPtr hateListGetHighest();
void hateListAdd( ActorPtr pActor, int32_t hateAmount );
void hateListUpdate( ActorPtr pActor, int32_t hateAmount );
void hateListRemove( ActorPtr pActor );
bool hateListHasActor( ActorPtr pActor );
CharaPtr hateListGetHighest();
void hateListAdd( CharaPtr pChara, int32_t hateAmount );
void hateListUpdate( CharaPtr pChara, int32_t hateAmount );
void hateListRemove( CharaPtr pChara );
bool hateListHasActor( CharaPtr pChara );
void aggro( ActorPtr pActor );
void deaggro( ActorPtr pActor );
void aggro( CharaPtr pChara );
void deaggro( CharaPtr pChara );
void update( int64_t currTime ) override;

View file

@ -38,7 +38,7 @@ Sapphire::Entity::Chara::Chara( ObjKind type, FrameworkPtr pFw ) :
Actor( type ),
m_pose( 0 ),
m_targetId( INVALID_GAME_OBJECT_ID ),
m_pFw( pFw )
m_pFw( std::move( std::move( pFw ) ) )
{
// initialize the free slot queue
for( uint8_t i = 0; i < MAX_STATUS_EFFECTS; i++ )
@ -48,8 +48,7 @@ Sapphire::Entity::Chara::Chara( ObjKind type, FrameworkPtr pFw ) :
}
Sapphire::Entity::Chara::~Chara()
{
}
= default;
/*! \return the actors name */
std::string Sapphire::Entity::Chara::getName() const
@ -375,7 +374,7 @@ Sapphire::Action::ActionPtr Sapphire::Entity::Chara::getCurrentAction() const
/*! \param ActionPtr of the action to be registered */
void Sapphire::Entity::Chara::setCurrentAction( Sapphire::Action::ActionPtr pAction )
{
m_pCurrentAction = pAction;
m_pCurrentAction = std::move( pAction );
}
/*!
@ -398,36 +397,31 @@ void Sapphire::Entity::Chara::autoAttack( CharaPtr pTarget )
m_lastAttack = tick;
srand( static_cast< uint32_t >( tick ) );
uint16_t damage = static_cast< uint16_t >( 10 + rand() % 12 );
uint32_t variation = static_cast< uint32_t >( 0 + rand() % 4 );
auto damage = static_cast< uint16_t >( 10 + rand() % 12 );
auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), pTarget->getId(), 0x336 );
auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), pTarget->getId(), 7 );
effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) );
Server::EffectEntry effectEntry{};
effectEntry.value = damage;
effectEntry.effectType = ActionEffectType::Damage;
effectEntry.hitSeverity = static_cast< ActionHitSeverityType >( variation );
effectEntry.hitSeverity = ActionHitSeverityType::NormalDamage;
effectPacket->addEffect( effectEntry );
sendToInRangeSet( effectPacket );
if( isPlayer() )
getAsPlayer()->queuePacket( effectPacket );
pTarget->takeDamage( damage );
}
}
/*!
ChaiScript Skill Handler.
Skill Handler.
\param GamePacketPtr to send
\param bool should be send to self?
*/
void Sapphire::Entity::Chara::handleScriptSkill( uint32_t type, uint16_t actionId, uint64_t param1,
uint64_t param2, Entity::Chara& target )
uint64_t param2, Entity::Chara& target )
{
auto pExdData = m_pFw->get< Data::ExdDataGenerated >();
if( isPlayer() )
@ -534,7 +528,7 @@ void Sapphire::Entity::Chara::handleScriptSkill( uint32_t type, uint16_t actionI
auto actorsCollided = ActionCollision::getActorsHitFromAction( target.getPos(), getInRangeActors( true ),
actionInfoPtr, TargetFilter::Allies );
for( auto pHitActor : actorsCollided )
for( const auto& pHitActor : actorsCollided )
{
effectPacket->setTargetActor( pHitActor->getId() );
@ -599,7 +593,7 @@ void Sapphire::Entity::Chara::addStatusEffectById( uint32_t id, int32_t duration
/*! \param StatusEffectPtr to be applied to the actor */
void Sapphire::Entity::Chara::addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source,
uint16_t param )
uint16_t param )
{
if( hasStatusEffect( id ) )
return;
@ -781,8 +775,6 @@ void Sapphire::Entity::Chara::updateStatusEffects()
bool Sapphire::Entity::Chara::hasStatusEffect( uint32_t id )
{
if( m_statusEffectMap.find( id ) != m_statusEffectMap.end() )
return true;
return false;
return m_statusEffectMap.find( id ) != m_statusEffectMap.end();
}

View file

@ -1474,7 +1474,7 @@ void Sapphire::Entity::Player::autoAttack( CharaPtr pTarget )
auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), pTarget->getId(), 8 );
effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) );
Server::EffectEntry entry;
Server::EffectEntry entry{};
entry.value = damage;
entry.effectType = Common::ActionEffectType::Damage;
entry.hitSeverity = Common::ActionHitSeverityType::NormalDamage;
@ -1488,7 +1488,7 @@ void Sapphire::Entity::Player::autoAttack( CharaPtr pTarget )
auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), pTarget->getId(), 7 );
effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) );
Server::EffectEntry entry;
Server::EffectEntry entry{};
entry.value = damage;
entry.effectType = Common::ActionEffectType::Damage;
entry.hitSeverity = Common::ActionHitSeverityType::NormalDamage;

View file

@ -17,25 +17,28 @@ namespace Sapphire::Network::Packets::Server
EffectPacket( uint64_t sourceId, uint32_t targetId, uint32_t actionId ) :
ZoneChannelPacket< FFXIVIpcEffect >( static_cast< uint32_t >( sourceId ), targetId )
{
m_data.header.actionId = actionId;
m_data.header.actionAnimationId = static_cast< uint16_t >( actionId );
m_data.effectCount = 0;
m_data.actionId = actionId;
m_data.actionAnimationId = static_cast< uint16_t >( actionId );
m_data.header.animationTargetId = targetId;
m_data.animationTargetId = targetId;
m_data.effectTargetId = targetId;
m_data.header.effectDisplayType = Common::ActionEffectDisplayType::ShowActionName;
m_data.effectDisplayType = Common::ActionEffectDisplayType::ShowActionName;
}
void addEffect( const Server::EffectEntry& effect )
{
assert( m_data.header.effectCount <= 8 );
assert( m_data.effectCount <= 8 );
std::memcpy( &m_data.effects[ m_data.header.effectCount++ ], &effect, sizeof( Server::EffectEntry ) );
std::memset( m_data.effects, 0, sizeof( Server::EffectEntry ) * 8 );
std::memcpy( &m_data.effects[ m_data.effectCount * 8 ], &effect, sizeof( Server::EffectEntry ) );
m_data.effectCount++;
}
void setAnimationId( uint16_t animationId )
{
m_data.header.actionAnimationId = animationId;
m_data.actionAnimationId = animationId;
}
void setEffectFlags( uint32_t effectFlags )
@ -45,12 +48,12 @@ namespace Sapphire::Network::Packets::Server
void setRotation( uint16_t rotation )
{
m_data.header.rotation = rotation;
m_data.rotation = rotation;
}
void setTargetActor( const uint32_t targetId )
{
m_data.header.animationTargetId = targetId;
m_data.animationTargetId = targetId;
m_data.effectTargetId = targetId;
FFXIVPacketBase::setTargetActor( targetId );