mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-04 17:57:47 +00:00
Merge pull request #925 from collett8192/Sapphire5.58_action
attackType, minor fixes and merge 5.58 main
This commit is contained in:
commit
4ceb771a16
16 changed files with 164 additions and 83 deletions
|
@ -1084,7 +1084,7 @@ namespace Sapphire::Common
|
||||||
{
|
{
|
||||||
SingleTarget = 1,
|
SingleTarget = 1,
|
||||||
CircularAOE = 2,
|
CircularAOE = 2,
|
||||||
Type3 = 3, // another single target? no idea how to call it
|
ConeAOE = 3,
|
||||||
RectangularAOE = 4,
|
RectangularAOE = 4,
|
||||||
CircularAoEPlaced = 7
|
CircularAoEPlaced = 7
|
||||||
};
|
};
|
||||||
|
@ -1373,6 +1373,12 @@ namespace Sapphire::Common
|
||||||
GetGil = 9, // p1: gil
|
GetGil = 9, // p1: gil
|
||||||
EmptyCoffer = 11, // seems like no param
|
EmptyCoffer = 11, // seems like no param
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ItemFlag
|
||||||
|
{
|
||||||
|
FlagNone = 0,
|
||||||
|
FlagHq = 1,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -241,7 +241,7 @@ void Sapphire::Db::ZoneDbConnection::doPrepareStatements()
|
||||||
CONNECTION_BOTH );
|
CONNECTION_BOTH );
|
||||||
|
|
||||||
prepareStatement( CHARA_ITEMGLOBAL_UP,
|
prepareStatement( CHARA_ITEMGLOBAL_UP,
|
||||||
"UPDATE charaglobalitem SET stack = ?, durability = ?, stain = ? WHERE ItemId = ?;",
|
"UPDATE charaglobalitem SET stack = ?, durability = ?, flags = ?, reservedFlag = ?, stain = ? WHERE ItemId = ?;",
|
||||||
CONNECTION_BOTH );
|
CONNECTION_BOTH );
|
||||||
|
|
||||||
prepareStatement( CHARA_ITEMGLOBAL_DELETE,
|
prepareStatement( CHARA_ITEMGLOBAL_DELETE,
|
||||||
|
|
|
@ -573,17 +573,24 @@ void Action::Action::buildEffects()
|
||||||
|
|
||||||
if( dmg.first > 0 )
|
if( dmg.first > 0 )
|
||||||
{
|
{
|
||||||
|
auto attackTypeEffect = m_actionData->attackType;
|
||||||
|
if( attackTypeEffect == -1 )
|
||||||
|
{
|
||||||
|
//maybe set it base on job?
|
||||||
|
attackTypeEffect = 0;
|
||||||
|
}
|
||||||
|
|
||||||
dmg.first = actor->applyShieldProtection( dmg.first );
|
dmg.first = actor->applyShieldProtection( dmg.first );
|
||||||
if( blocked > 0 )
|
if( blocked > 0 )
|
||||||
m_effectBuilder->blockedDamage( actor, actor, dmg.first, static_cast< uint16_t >( blocked / originalDamage * 100 ) , dmg.first == 0 ? Common::ActionEffectResultFlag::Absorbed : Common::ActionEffectResultFlag::None, getExecutionDelay() + victimCounter * 100 );
|
m_effectBuilder->blockedDamage( actor, actor, dmg.first, static_cast< uint16_t >( blocked / originalDamage * 100 ), attackTypeEffect, dmg.first == 0 ? Common::ActionEffectResultFlag::Absorbed : Common::ActionEffectResultFlag::None, getExecutionDelay() + victimCounter * 100 );
|
||||||
else if (parried > 0 )
|
else if (parried > 0 )
|
||||||
m_effectBuilder->parriedDamage( actor, actor, dmg.first, static_cast< uint16_t >( parried / originalDamage * 100 ), dmg.first == 0 ? Common::ActionEffectResultFlag::Absorbed : Common::ActionEffectResultFlag::None, getExecutionDelay() + victimCounter * 100 );
|
m_effectBuilder->parriedDamage( actor, actor, dmg.first, static_cast< uint16_t >( parried / originalDamage * 100 ), attackTypeEffect, dmg.first == 0 ? Common::ActionEffectResultFlag::Absorbed : Common::ActionEffectResultFlag::None, getExecutionDelay() + victimCounter * 100 );
|
||||||
else
|
else
|
||||||
m_effectBuilder->damage( actor, actor, dmg.first, dmg.second, dmg.first == 0 ? Common::ActionEffectResultFlag::Absorbed : Common::ActionEffectResultFlag::None, getExecutionDelay() + victimCounter * 100 );
|
m_effectBuilder->damage( actor, actor, dmg.first, attackTypeEffect, dmg.second, dmg.first == 0 ? Common::ActionEffectResultFlag::Absorbed : Common::ActionEffectResultFlag::None, getExecutionDelay() + victimCounter * 100 );
|
||||||
auto reflectDmg = Math::CalcStats::calcDamageReflect( m_pSource, actor, dmg.first, getActionTypeFilterFromAttackType( attackType ) );
|
auto reflectDmg = Math::CalcStats::calcDamageReflect( m_pSource, actor, dmg.first, getActionTypeFilterFromAttackType( attackType ) );
|
||||||
if( reflectDmg.first > 0 )
|
if( reflectDmg.first > 0 )
|
||||||
{
|
{
|
||||||
m_effectBuilder->damage( actor, m_pSource, reflectDmg.first, reflectDmg.second, Common::ActionEffectResultFlag::Reflected, getExecutionDelay() + victimCounter * 100 );
|
m_effectBuilder->damage( actor, m_pSource, reflectDmg.first, attackTypeEffect, reflectDmg.second, Common::ActionEffectResultFlag::Reflected, getExecutionDelay() + victimCounter * 100 );
|
||||||
}
|
}
|
||||||
|
|
||||||
auto absorb = Math::CalcStats::calcAbsorbHP( m_pSource, dmg.first );
|
auto absorb = Math::CalcStats::calcAbsorbHP( m_pSource, dmg.first );
|
||||||
|
@ -1124,7 +1131,6 @@ void Action::Action::addDefaultActorFilters()
|
||||||
switch( m_castType )
|
switch( m_castType )
|
||||||
{
|
{
|
||||||
case Common::CastType::SingleTarget:
|
case Common::CastType::SingleTarget:
|
||||||
case Common::CastType::Type3:
|
|
||||||
{
|
{
|
||||||
auto filter = std::make_shared< World::Util::ActorFilterSingleTarget >( static_cast< uint32_t >( m_targetId ) );
|
auto filter = std::make_shared< World::Util::ActorFilterSingleTarget >( static_cast< uint32_t >( m_targetId ) );
|
||||||
|
|
||||||
|
@ -1134,6 +1140,7 @@ void Action::Action::addDefaultActorFilters()
|
||||||
}
|
}
|
||||||
|
|
||||||
case Common::CastType::CircularAOE:
|
case Common::CastType::CircularAOE:
|
||||||
|
case Common::CastType::ConeAOE:
|
||||||
{
|
{
|
||||||
auto filter = std::make_shared< World::Util::ActorFilterInRange >( m_pos, m_effectRange );
|
auto filter = std::make_shared< World::Util::ActorFilterInRange >( m_pos, m_effectRange );
|
||||||
|
|
||||||
|
@ -1269,7 +1276,10 @@ bool Action::Action::isWeaponSkill() const
|
||||||
|
|
||||||
bool Action::Action::isAttackTypePhysical( Common::AttackType attackType )
|
bool Action::Action::isAttackTypePhysical( Common::AttackType attackType )
|
||||||
{
|
{
|
||||||
return attackType == Common::AttackType::Physical;
|
return attackType == Common::AttackType::Physical ||
|
||||||
|
attackType == Common::AttackType::Slashing ||
|
||||||
|
attackType == Common::AttackType::Piercing ||
|
||||||
|
attackType == Common::AttackType::Blunt;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Action::Action::isAttackTypeMagical( Common::AttackType attackType )
|
bool Action::Action::isAttackTypeMagical( Common::AttackType attackType )
|
||||||
|
|
|
@ -64,24 +64,24 @@ void EffectBuilder::dodge( Entity::CharaPtr& effectTarget, Entity::CharaPtr& dod
|
||||||
moveToResultList( effectTarget, nextResult );
|
moveToResultList( effectTarget, nextResult );
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectBuilder::damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag, uint64_t resultDelayMs )
|
void EffectBuilder::damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, uint8_t attackType, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag, uint64_t resultDelayMs )
|
||||||
{
|
{
|
||||||
EffectResultPtr nextResult = make_EffectResult( damagingTarget, Common::Util::getTimeMs() + resultDelayMs );
|
EffectResultPtr nextResult = make_EffectResult( damagingTarget, Common::Util::getTimeMs() + resultDelayMs );
|
||||||
nextResult->damage( amount, severity, flag );
|
nextResult->damage( amount, severity, attackType, flag );
|
||||||
moveToResultList( effectTarget, nextResult );
|
moveToResultList( effectTarget, nextResult );
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectBuilder::blockedDamage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, uint16_t rate, Common::ActionEffectResultFlag flag, uint64_t resultDelayMs )
|
void EffectBuilder::blockedDamage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, uint16_t rate, uint8_t attackType, Common::ActionEffectResultFlag flag, uint64_t resultDelayMs )
|
||||||
{
|
{
|
||||||
EffectResultPtr nextResult = make_EffectResult( damagingTarget, Common::Util::getTimeMs() + resultDelayMs );
|
EffectResultPtr nextResult = make_EffectResult( damagingTarget, Common::Util::getTimeMs() + resultDelayMs );
|
||||||
nextResult->blockedDamage( amount, rate, flag );
|
nextResult->blockedDamage( amount, rate, attackType, flag );
|
||||||
moveToResultList( effectTarget, nextResult );
|
moveToResultList( effectTarget, nextResult );
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectBuilder::parriedDamage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, uint16_t rate, Common::ActionEffectResultFlag flag, uint64_t resultDelayMs )
|
void EffectBuilder::parriedDamage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, uint16_t rate, uint8_t attackType, Common::ActionEffectResultFlag flag, uint64_t resultDelayMs )
|
||||||
{
|
{
|
||||||
EffectResultPtr nextResult = make_EffectResult( damagingTarget, Common::Util::getTimeMs() + resultDelayMs );
|
EffectResultPtr nextResult = make_EffectResult( damagingTarget, Common::Util::getTimeMs() + resultDelayMs );
|
||||||
nextResult->parriedDamage( amount, rate, flag );
|
nextResult->parriedDamage( amount, rate, attackType, flag );
|
||||||
moveToResultList( effectTarget, nextResult );
|
moveToResultList( effectTarget, nextResult );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,14 +22,14 @@ namespace Sapphire::World::Action
|
||||||
|
|
||||||
void dodge( Entity::CharaPtr& effectTarget, Entity::CharaPtr& dodgingTarget, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
|
void dodge( Entity::CharaPtr& effectTarget, Entity::CharaPtr& dodgingTarget, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
|
||||||
|
|
||||||
void damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount,
|
void damage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, uint8_t attackType,
|
||||||
Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalDamage,
|
Common::ActionHitSeverityType severity = Common::ActionHitSeverityType::NormalDamage,
|
||||||
Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None, uint64_t resultDelayMs = 600 );
|
Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None, uint64_t resultDelayMs = 600 );
|
||||||
|
|
||||||
void blockedDamage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, uint16_t rate,
|
void blockedDamage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, uint16_t rate, uint8_t attackType,
|
||||||
Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None, uint64_t resultDelayMs = 600 );
|
Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None, uint64_t resultDelayMs = 600 );
|
||||||
|
|
||||||
void parriedDamage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, uint16_t rate,
|
void parriedDamage( Entity::CharaPtr& effectTarget, Entity::CharaPtr& damagingTarget, uint32_t amount, uint16_t rate, uint8_t attackType,
|
||||||
Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None, uint64_t resultDelayMs = 600 );
|
Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None, uint64_t resultDelayMs = 600 );
|
||||||
|
|
||||||
void startCombo( Entity::CharaPtr& target, uint16_t actionId );
|
void startCombo( Entity::CharaPtr& target, uint16_t actionId );
|
||||||
|
|
|
@ -62,28 +62,31 @@ void EffectResult::dodge( Common::ActionEffectResultFlag flag )
|
||||||
m_type = Common::ActionEffectType::Miss;
|
m_type = Common::ActionEffectType::Miss;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectResult::damage( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag )
|
void EffectResult::damage( uint32_t amount, Common::ActionHitSeverityType severity, uint8_t attackType, Common::ActionEffectResultFlag flag )
|
||||||
{
|
{
|
||||||
m_param0 = static_cast< uint8_t >( severity );
|
m_param0 = static_cast< uint8_t >( severity );
|
||||||
|
m_param1 = attackType;
|
||||||
m_value = amount;
|
m_value = amount;
|
||||||
m_flag = flag;
|
m_flag = flag;
|
||||||
|
|
||||||
m_type = Common::ActionEffectType::Damage;
|
m_type = Common::ActionEffectType::Damage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectResult::blockedDamage( uint32_t amount, uint16_t rate, Common::ActionEffectResultFlag flag )
|
void EffectResult::blockedDamage( uint32_t amount, uint16_t rate, uint8_t attackType, Common::ActionEffectResultFlag flag )
|
||||||
{
|
{
|
||||||
m_value = amount;
|
m_value = amount;
|
||||||
m_flag = flag;
|
m_flag = flag;
|
||||||
|
m_param1 = attackType;
|
||||||
m_param2 = rate;
|
m_param2 = rate;
|
||||||
|
|
||||||
m_type = Common::ActionEffectType::BlockedDamage;
|
m_type = Common::ActionEffectType::BlockedDamage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectResult::parriedDamage( uint32_t amount, uint16_t rate, Common::ActionEffectResultFlag flag )
|
void EffectResult::parriedDamage( uint32_t amount, uint16_t rate, uint8_t attackType, Common::ActionEffectResultFlag flag )
|
||||||
{
|
{
|
||||||
m_value = amount;
|
m_value = amount;
|
||||||
m_flag = flag;
|
m_flag = flag;
|
||||||
|
m_param1 = attackType;
|
||||||
m_param2 = rate;
|
m_param2 = rate;
|
||||||
|
|
||||||
m_type = Common::ActionEffectType::ParriedDamage;
|
m_type = Common::ActionEffectType::ParriedDamage;
|
||||||
|
|
|
@ -19,9 +19,9 @@ namespace Sapphire::World::Action
|
||||||
explicit EffectResult( Entity::CharaPtr target, uint64_t delayMs );
|
explicit EffectResult( Entity::CharaPtr target, uint64_t delayMs );
|
||||||
|
|
||||||
void dodge( Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
|
void dodge( Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
|
||||||
void damage( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
|
void damage( uint32_t amount, Common::ActionHitSeverityType severity, uint8_t attackType, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
|
||||||
void blockedDamage( uint32_t amount, uint16_t rate, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
|
void blockedDamage( uint32_t amount, uint16_t rate, uint8_t attackType, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
|
||||||
void parriedDamage( uint32_t amount, uint16_t rate, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
|
void parriedDamage( uint32_t amount, uint16_t rate, uint8_t attackType, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
|
||||||
void heal( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
|
void heal( uint32_t amount, Common::ActionHitSeverityType severity, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
|
||||||
void restoreMP( uint32_t amount, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
|
void restoreMP( uint32_t amount, Common::ActionEffectResultFlag flag = Common::ActionEffectResultFlag::None );
|
||||||
void startCombo( uint16_t actionId );
|
void startCombo( uint16_t actionId );
|
||||||
|
|
|
@ -793,6 +793,10 @@ void Sapphire::Entity::Chara::setAgentId( uint32_t agentId )
|
||||||
m_agentId = agentId;
|
m_agentId = agentId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Sapphire::Entity::Chara::canBlock()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
float Sapphire::Entity::Chara::getRadius() const
|
float Sapphire::Entity::Chara::getRadius() const
|
||||||
{
|
{
|
||||||
|
|
|
@ -250,6 +250,8 @@ namespace Sapphire::Entity
|
||||||
|
|
||||||
virtual void autoAttack( CharaPtr pTarget );
|
virtual void autoAttack( CharaPtr pTarget );
|
||||||
|
|
||||||
|
virtual bool canBlock();
|
||||||
|
|
||||||
virtual void onDeath() {};
|
virtual void onDeath() {};
|
||||||
|
|
||||||
virtual void onDamageTaken( Chara& pSource ) {};
|
virtual void onDamageTaken( Chara& pSource ) {};
|
||||||
|
|
|
@ -2420,6 +2420,16 @@ void Sapphire::Entity::Player::clearBuyBackMap()
|
||||||
m_shopBuyBackMap.clear();
|
m_shopBuyBackMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Sapphire::Entity::Player::canBlock()
|
||||||
|
{
|
||||||
|
if( auto item = getEquippedSecondaryWeapon() )
|
||||||
|
{
|
||||||
|
if( item->getCategory() == ItemUICategory::Shield )
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Sapphire::Entity::Player::gaugeClear()
|
void Sapphire::Entity::Player::gaugeClear()
|
||||||
{
|
{
|
||||||
std::memset( &m_gauge, 0, sizeof( m_gauge ) );
|
std::memset( &m_gauge, 0, sizeof( m_gauge ) );
|
||||||
|
|
|
@ -136,7 +136,7 @@ namespace Sapphire::Entity
|
||||||
|
|
||||||
void checkEvent( uint32_t eventId );
|
void checkEvent( uint32_t eventId );
|
||||||
|
|
||||||
|
bool canBlock() override;
|
||||||
|
|
||||||
// Events
|
// Events
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -340,7 +340,7 @@ namespace Sapphire::Entity
|
||||||
void equipSoulCrystal( ItemPtr pItem, bool updateClass );
|
void equipSoulCrystal( ItemPtr pItem, bool updateClass );
|
||||||
|
|
||||||
/*! unequip a soul crystal, returning to the base class*/
|
/*! unequip a soul crystal, returning to the base class*/
|
||||||
void unequipSoulCrystal( ItemPtr pItem );
|
void unequipSoulCrystal();
|
||||||
|
|
||||||
/*! get player ilvl */
|
/*! get player ilvl */
|
||||||
uint16_t getItemLevel() const;
|
uint16_t getItemLevel() const;
|
||||||
|
|
|
@ -148,9 +148,9 @@ void Sapphire::Entity::Player::equipSoulCrystal( ItemPtr pItem, bool updateJob )
|
||||||
|
|
||||||
void Sapphire::Entity::Player::updateModels( GearSetSlot equipSlotId, const Sapphire::ItemPtr& pItem, bool updateClass )
|
void Sapphire::Entity::Player::updateModels( GearSetSlot equipSlotId, const Sapphire::ItemPtr& pItem, bool updateClass )
|
||||||
{
|
{
|
||||||
uint64_t model = pItem->getModelId1();
|
uint64_t model = pItem ? pItem->getModelId1() : 0;
|
||||||
uint64_t model2 = pItem->getModelId2();
|
uint64_t model2 = pItem ? pItem->getModelId2() : 0;
|
||||||
uint64_t stain = pItem->getStain();
|
uint64_t stain = pItem ? pItem->getStain() : 0;
|
||||||
|
|
||||||
switch( equipSlotId )
|
switch( equipSlotId )
|
||||||
{
|
{
|
||||||
|
@ -172,7 +172,10 @@ void Sapphire::Entity::Player::updateModels( GearSetSlot equipSlotId, const Sapp
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SoulCrystal:
|
case SoulCrystal:
|
||||||
equipSoulCrystal( pItem, updateClass );
|
if( pItem )
|
||||||
|
equipSoulCrystal( pItem, updateClass );
|
||||||
|
else
|
||||||
|
unequipSoulCrystal();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Waist:
|
case Waist:
|
||||||
|
@ -265,15 +268,12 @@ void Sapphire::Entity::Player::unequipItem( Common::GearSetSlot equipSlotId, Ite
|
||||||
|
|
||||||
if( sendUpdate )
|
if( sendUpdate )
|
||||||
{
|
{
|
||||||
|
updateModels( equipSlotId, nullptr, true );
|
||||||
sendModel();
|
sendModel();
|
||||||
|
|
||||||
m_itemLevel = calculateEquippedGearItemLevel();
|
m_itemLevel = calculateEquippedGearItemLevel();
|
||||||
sendItemLevel();
|
sendItemLevel();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( equipSlotId == SoulCrystal )
|
|
||||||
unequipSoulCrystal( pItem );
|
|
||||||
|
|
||||||
auto baseParams = pItem->getBaseParams();
|
auto baseParams = pItem->getBaseParams();
|
||||||
for( auto i = 0; i < 6; ++i )
|
for( auto i = 0; i < 6; ++i )
|
||||||
{
|
{
|
||||||
|
@ -293,7 +293,7 @@ void Sapphire::Entity::Player::unequipItem( Common::GearSetSlot equipSlotId, Ite
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sapphire::Entity::Player::unequipSoulCrystal( ItemPtr pItem )
|
void Sapphire::Entity::Player::unequipSoulCrystal()
|
||||||
{
|
{
|
||||||
auto& exdData = Common::Service< Sapphire::Data::ExdDataGenerated >::ref();
|
auto& exdData = Common::Service< Sapphire::Data::ExdDataGenerated >::ref();
|
||||||
|
|
||||||
|
@ -547,38 +547,6 @@ void Sapphire::Entity::Player::writeInventory( InventoryType type )
|
||||||
db.execute( query );
|
db.execute( query );
|
||||||
}
|
}
|
||||||
|
|
||||||
void Sapphire::Entity::Player::updateItemDb( Sapphire::ItemPtr pItem ) const
|
|
||||||
{
|
|
||||||
if( pItem->getUId() == 0 )
|
|
||||||
writeItemDb( pItem );
|
|
||||||
|
|
||||||
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
|
||||||
auto stmt = db.getPreparedStatement( Db::CHARA_ITEMGLOBAL_UP );
|
|
||||||
|
|
||||||
// todo: add more fields
|
|
||||||
stmt->setInt( 1, pItem->getStackSize() );
|
|
||||||
stmt->setInt( 2, pItem->getDurability() );
|
|
||||||
stmt->setInt( 3, pItem->getStain() );
|
|
||||||
|
|
||||||
stmt->setInt64( 4, pItem->getUId() );
|
|
||||||
|
|
||||||
db.directExecute( stmt );
|
|
||||||
}
|
|
||||||
|
|
||||||
void Sapphire::Entity::Player::deleteItemDb( Sapphire::ItemPtr item ) const
|
|
||||||
{
|
|
||||||
if( item->getUId() == 0 )
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
|
||||||
auto stmt = db.getPreparedStatement( Db::CHARA_ITEMGLOBAL_DELETE );
|
|
||||||
|
|
||||||
stmt->setInt64( 1, item->getUId() );
|
|
||||||
|
|
||||||
db.directExecute( stmt );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Sapphire::Entity::Player::isObtainable( uint32_t catalogId, uint8_t quantity )
|
bool Sapphire::Entity::Player::isObtainable( uint32_t catalogId, uint8_t quantity )
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -748,7 +716,19 @@ Sapphire::Entity::Player::moveItem( uint16_t fromInventoryId, uint8_t fromSlotId
|
||||||
auto& itemMap = m_storageMap[ fromInventoryId ]->getItemMap();
|
auto& itemMap = m_storageMap[ fromInventoryId ]->getItemMap();
|
||||||
|
|
||||||
if( tmpItem == nullptr )
|
if( tmpItem == nullptr )
|
||||||
|
{
|
||||||
|
sendUrgent( "trying to move EMPTY item from [container{}, slot{}] to [container{}, slot{}], potential client desync, no action is performed.",
|
||||||
|
fromInventoryId, fromSlotId, toInventoryId, toSlot );
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( auto target = m_storageMap[ toInventoryId ]->getItem( toSlot ) )
|
||||||
|
{
|
||||||
|
sendUrgent( "trying to move item from [container{}, slot{}] to NON-EMPTY [container{}, slot{}], potential client desync, swapItem is performed instead.",
|
||||||
|
fromInventoryId, fromSlotId, toInventoryId, toSlot );
|
||||||
|
swapItem( fromInventoryId, fromSlotId, toInventoryId, toSlot, sendUpdate );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
itemMap[ fromSlotId ].reset();
|
itemMap[ fromSlotId ].reset();
|
||||||
|
|
||||||
|
@ -885,8 +865,28 @@ void Sapphire::Entity::Player::swapItem( uint16_t fromInventoryId, uint8_t fromS
|
||||||
auto toItem = m_storageMap[ toInventoryId ]->getItem( toSlot );
|
auto toItem = m_storageMap[ toInventoryId ]->getItem( toSlot );
|
||||||
auto& itemMap = m_storageMap[ fromInventoryId ]->getItemMap();
|
auto& itemMap = m_storageMap[ fromInventoryId ]->getItemMap();
|
||||||
|
|
||||||
if( fromItem == nullptr || toItem == nullptr )
|
if( fromItem == nullptr && toItem == nullptr )
|
||||||
|
{
|
||||||
|
sendUrgent( "trying to swap TWO EMPTY ITEMS from [container{}, slot{}] to [container{}, slot{}], potential client desync, no action is performed.",
|
||||||
|
fromInventoryId, fromSlotId, toInventoryId, toSlot );
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fromItem != nullptr && toItem == nullptr )
|
||||||
|
{
|
||||||
|
sendUrgent( "trying to swap item from [container{}, slot{}] to EMPTY [container{}, slot{}], potential client desync, moveItem is performed instead.",
|
||||||
|
fromInventoryId, fromSlotId, toInventoryId, toSlot );
|
||||||
|
moveItem( fromInventoryId, fromSlotId, toInventoryId, toSlot, sendUpdate );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( fromItem == nullptr && toItem != nullptr )
|
||||||
|
{
|
||||||
|
sendUrgent( "trying to swap EMPTY item from [container{}, slot{}] to [container{}, slot{}], potential client desync, moveItem is performed instead.",
|
||||||
|
fromInventoryId, fromSlotId, toInventoryId, toSlot );
|
||||||
|
moveItem( toInventoryId, toSlot, fromInventoryId, fromSlotId, sendUpdate ); // we are moving the non-empty toSlot back to fromSlot.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// An item is being moved from bag0-3 to equippment, meaning
|
// An item is being moved from bag0-3 to equippment, meaning
|
||||||
// the swapped out item will be placed in the matching armory.
|
// the swapped out item will be placed in the matching armory.
|
||||||
|
|
|
@ -650,10 +650,13 @@ void Sapphire::Entity::Player::writeItemDb( Sapphire::ItemPtr pItem ) const
|
||||||
auto& itemMgr = Common::Service< World::Manager::ItemMgr >::ref();
|
auto& itemMgr = Common::Service< World::Manager::ItemMgr >::ref();
|
||||||
|
|
||||||
uint8_t flags = 0;
|
uint8_t flags = 0;
|
||||||
|
if( pItem->isHq() )
|
||||||
|
flags |= Common::ItemFlag::FlagHq;
|
||||||
pItem->setUId( itemMgr.getNextUId() );
|
pItem->setUId( itemMgr.getNextUId() );
|
||||||
std::string sql = "INSERT INTO charaglobalitem ( CharacterId, itemId, catalogId, stack, flags ) VALUES ( " +
|
std::string sql = "INSERT INTO charaglobalitem ( CharacterId, itemId, reservedFlag, catalogId, stack, flags ) VALUES ( " +
|
||||||
std::to_string( getId() ) + ", " +
|
std::to_string( getId() ) + ", " +
|
||||||
std::to_string( pItem->getUId() ) + ", " +
|
std::to_string( pItem->getUId() ) + ", " +
|
||||||
|
std::to_string( pItem->getReservedFlag() ) + ", " +
|
||||||
std::to_string( pItem->getId() ) + ", " +
|
std::to_string( pItem->getId() ) + ", " +
|
||||||
std::to_string( pItem->getStackSize() ) + ", " +
|
std::to_string( pItem->getStackSize() ) + ", " +
|
||||||
std::to_string( flags ) + ");";
|
std::to_string( flags ) + ");";
|
||||||
|
@ -661,6 +664,46 @@ void Sapphire::Entity::Player::writeItemDb( Sapphire::ItemPtr pItem ) const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sapphire::Entity::Player::updateItemDb( Sapphire::ItemPtr pItem ) const
|
||||||
|
{
|
||||||
|
if( pItem->getUId() == 0 )
|
||||||
|
{
|
||||||
|
writeItemDb( pItem );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t flags = 0;
|
||||||
|
if( pItem->isHq() )
|
||||||
|
flags |= Common::ItemFlag::FlagHq;
|
||||||
|
|
||||||
|
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
||||||
|
auto stmt = db.getPreparedStatement( Db::CHARA_ITEMGLOBAL_UP );
|
||||||
|
|
||||||
|
// todo: add more fields
|
||||||
|
stmt->setInt( 1, pItem->getStackSize() );
|
||||||
|
stmt->setInt( 2, pItem->getDurability() );
|
||||||
|
stmt->setInt( 3, flags );
|
||||||
|
stmt->setInt( 4, pItem->getReservedFlag() );
|
||||||
|
stmt->setInt( 5, pItem->getStain() );
|
||||||
|
|
||||||
|
stmt->setInt64( 6, pItem->getUId() );
|
||||||
|
|
||||||
|
db.directExecute( stmt );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sapphire::Entity::Player::deleteItemDb( Sapphire::ItemPtr item ) const
|
||||||
|
{
|
||||||
|
if( item->getUId() == 0 )
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto& db = Common::Service< Db::DbWorkerPool< Db::ZoneDbConnection > >::ref();
|
||||||
|
auto stmt = db.getPreparedStatement( Db::CHARA_ITEMGLOBAL_DELETE );
|
||||||
|
|
||||||
|
stmt->setInt64( 1, item->getUId() );
|
||||||
|
|
||||||
|
db.directExecute( stmt );
|
||||||
|
}
|
||||||
|
|
||||||
bool Sapphire::Entity::Player::loadInventory()
|
bool Sapphire::Entity::Player::loadInventory()
|
||||||
{
|
{
|
||||||
auto& itemMgr = Common::Service< World::Manager::ItemMgr >::ref();
|
auto& itemMgr = Common::Service< World::Manager::ItemMgr >::ref();
|
||||||
|
|
|
@ -132,15 +132,16 @@ Sapphire::ItemPtr Sapphire::World::Manager::ItemMgr::loadItem( uint64_t uId )
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
auto itemInfo = exdData.get< Sapphire::Data::Item >( itemRes->getUInt( 1 ) );
|
auto itemInfo = exdData.get< Sapphire::Data::Item >( itemRes->getUInt( 1 ) );
|
||||||
bool isHq = itemRes->getUInt( 3 ) == 1;
|
bool isHq = itemRes->getUInt( 5 ) & Common::ItemFlag::FlagHq;
|
||||||
|
|
||||||
ItemPtr pItem = make_Item( uId,
|
ItemPtr pItem = make_Item( uId,
|
||||||
itemRes->getUInt( 1 ),
|
itemRes->getUInt( 1 ),
|
||||||
isHq );
|
isHq );
|
||||||
|
|
||||||
pItem->setStackSize( itemRes->getUInt( 2 ) );
|
pItem->setStackSize( itemRes->getUInt( 2 ) );
|
||||||
pItem->setStain( itemRes->getUInt16( 13 ) );
|
pItem->setReservedFlag( itemRes->getUInt( 3 ) );
|
||||||
pItem->setDurability( itemRes->getInt16( 6 ) );
|
pItem->setDurability( itemRes->getInt16( 6 ) );
|
||||||
|
pItem->setStain( itemRes->getUInt16( 13 ) );
|
||||||
|
|
||||||
return pItem;
|
return pItem;
|
||||||
}
|
}
|
||||||
|
|
|
@ -183,14 +183,16 @@ uint32_t CalcStats::calculateMaxHp( PlayerPtr pPlayer )
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
float CalcStats::dodgeProbability( const Sapphire::Entity::Chara& chara )
|
float CalcStats::dodgeProbability( Sapphire::Entity::Chara& chara )
|
||||||
{
|
{
|
||||||
// dummy value: 5% for players.
|
// dummy value: 5% for players.
|
||||||
return chara.isPlayer() ? 5 : 0;
|
return chara.isPlayer() ? 5 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
float CalcStats::blockProbability( const Chara& chara )
|
float CalcStats::blockProbability( Chara& chara )
|
||||||
{
|
{
|
||||||
|
if( !chara.canBlock() )
|
||||||
|
return 0;
|
||||||
auto level = chara.getLevel();
|
auto level = chara.getLevel();
|
||||||
auto blockRate = static_cast< float >( chara.getStatValue( Common::BaseParam::BlockRate ) );
|
auto blockRate = static_cast< float >( chara.getStatValue( Common::BaseParam::BlockRate ) );
|
||||||
auto levelVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::DIV ] );
|
auto levelVal = static_cast< float >( levelTable[ level ][ Common::LevelTableEntry::DIV ] );
|
||||||
|
@ -205,7 +207,7 @@ float CalcStats::blockProbability( const Chara& chara )
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
float CalcStats::parryProbability( const Sapphire::Entity::Chara& chara )
|
float CalcStats::parryProbability( Sapphire::Entity::Chara& chara )
|
||||||
{
|
{
|
||||||
// dummy value: 10% for players.
|
// dummy value: 10% for players.
|
||||||
float result = chara.isPlayer() ? 10 : 0;
|
float result = chara.isPlayer() ? 10 : 0;
|
||||||
|
@ -844,7 +846,7 @@ float CalcStats::calcAbsorbHP( Sapphire::Entity::CharaPtr pChara, float damage )
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CalcStats::calcDodge( const Sapphire::Entity::Chara& chara )
|
bool CalcStats::calcDodge( Sapphire::Entity::Chara& chara )
|
||||||
{
|
{
|
||||||
if( dodgeProbability( chara ) > getRandomNumber0To100() )
|
if( dodgeProbability( chara ) > getRandomNumber0To100() )
|
||||||
{
|
{
|
||||||
|
@ -853,7 +855,7 @@ bool CalcStats::calcDodge( const Sapphire::Entity::Chara& chara )
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float CalcStats::calcBlock( const Sapphire::Entity::Chara& chara, float damage )
|
float CalcStats::calcBlock( Sapphire::Entity::Chara& chara, float damage )
|
||||||
{
|
{
|
||||||
if( blockProbability( chara ) > getRandomNumber0To100() )
|
if( blockProbability( chara ) > getRandomNumber0To100() )
|
||||||
{
|
{
|
||||||
|
@ -862,7 +864,7 @@ float CalcStats::calcBlock( const Sapphire::Entity::Chara& chara, float damage )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
float CalcStats::calcParry( const Sapphire::Entity::Chara& chara, float damage )
|
float CalcStats::calcParry( Sapphire::Entity::Chara& chara, float damage )
|
||||||
{
|
{
|
||||||
if( parryProbability( chara ) > getRandomNumber0To100() )
|
if( parryProbability( chara ) > getRandomNumber0To100() )
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,14 +16,14 @@ namespace Sapphire::Math
|
||||||
|
|
||||||
static uint32_t calculateMaxHp( Sapphire::Entity::PlayerPtr pPlayer );
|
static uint32_t calculateMaxHp( Sapphire::Entity::PlayerPtr pPlayer );
|
||||||
|
|
||||||
static float dodgeProbability( const Sapphire::Entity::Chara& chara );
|
static float dodgeProbability( Sapphire::Entity::Chara& chara );
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Calculates the probability of a block happening
|
* @brief Calculates the probability of a block happening
|
||||||
*/
|
*/
|
||||||
static float blockProbability( const Sapphire::Entity::Chara& chara );
|
static float blockProbability( Sapphire::Entity::Chara& chara );
|
||||||
|
|
||||||
static float parryProbability( const Sapphire::Entity::Chara& chara );
|
static float parryProbability( Sapphire::Entity::Chara& chara );
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* @brief Calculates the probability of a direct hit happening
|
* @brief Calculates the probability of a direct hit happening
|
||||||
|
@ -155,11 +155,11 @@ namespace Sapphire::Math
|
||||||
|
|
||||||
static float calcAbsorbHP( Sapphire::Entity::CharaPtr pChara, float damage );
|
static float calcAbsorbHP( Sapphire::Entity::CharaPtr pChara, float damage );
|
||||||
|
|
||||||
static bool calcDodge( const Sapphire::Entity::Chara& chara );
|
static bool calcDodge( Sapphire::Entity::Chara& chara );
|
||||||
|
|
||||||
static float calcBlock( const Sapphire::Entity::Chara& chara, float damage );
|
static float calcBlock( Sapphire::Entity::Chara& chara, float damage );
|
||||||
|
|
||||||
static float calcParry( const Sapphire::Entity::Chara& chara, float damage );
|
static float calcParry( Sapphire::Entity::Chara& chara, float damage );
|
||||||
|
|
||||||
static float getRandomNumber0To100();
|
static float getRandomNumber0To100();
|
||||||
private:
|
private:
|
||||||
|
|
Loading…
Add table
Reference in a new issue