mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-28 15:17:46 +00:00
Add flags to StatusEffects
This commit is contained in:
parent
f4a3c9493b
commit
5bb8f11881
8 changed files with 121 additions and 11 deletions
|
@ -629,7 +629,7 @@
|
|||
},
|
||||
"44": {
|
||||
"name": "Vengeance",
|
||||
"potency": 50,
|
||||
"potency": 0,
|
||||
"comboPotency": 0,
|
||||
"flankPotency": 0,
|
||||
"frontPotency": 0,
|
||||
|
@ -638,7 +638,18 @@
|
|||
"restorePercentage": 0,
|
||||
"nextCombo": [],
|
||||
"statuses": {
|
||||
"caster": [],
|
||||
"caster": [
|
||||
{
|
||||
"id": 89,
|
||||
"duration": 20000,
|
||||
"modifiers": [
|
||||
{
|
||||
"modifier": "ReflectPhysical",
|
||||
"value": 50
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"target": []
|
||||
}
|
||||
},
|
||||
|
@ -1263,7 +1274,19 @@
|
|||
"restorePercentage": 0,
|
||||
"nextCombo": [],
|
||||
"statuses": {
|
||||
"caster": [],
|
||||
"caster": [
|
||||
{
|
||||
"id": 116,
|
||||
"duration": 10000,
|
||||
"flag": 4096,
|
||||
"modifiers": [
|
||||
{
|
||||
"modifier": "CriticalHitPercent",
|
||||
"value": 100
|
||||
}
|
||||
]
|
||||
}
|
||||
],
|
||||
"target": []
|
||||
}
|
||||
},
|
||||
|
|
|
@ -922,6 +922,23 @@ namespace Sapphire::Common
|
|||
ParryPercent = 1031
|
||||
};
|
||||
|
||||
enum class StatusEffectFlag : uint32_t
|
||||
{
|
||||
BuffCategory = 1,
|
||||
DebuffCategory = 2,
|
||||
Permanent = 4,
|
||||
IsGaze = 8,
|
||||
Transfiguration = 16,
|
||||
CanDispel = 32,
|
||||
LockActions = 64,
|
||||
LockControl = 128,
|
||||
LockMovement = 256,
|
||||
Invisibilty = 512,
|
||||
CanStatusOff = 1024,
|
||||
FcBuff = 2048,
|
||||
RemoveOnSuccessfulHit = 4096
|
||||
};
|
||||
|
||||
enum struct ActionAspect : uint8_t
|
||||
{
|
||||
None = 0, // Doesn't imply unaspected
|
||||
|
|
|
@ -41,6 +41,7 @@ struct StatusEntry
|
|||
{
|
||||
uint16_t id;
|
||||
int32_t duration;
|
||||
uint32_t flag;
|
||||
std::vector< StatusModifier > modifiers;
|
||||
};
|
||||
|
||||
|
@ -78,6 +79,7 @@ void to_json( nlohmann::ordered_json& j, const StatusEntry& statusEntry )
|
|||
j = nlohmann::ordered_json{
|
||||
{ "id", statusEntry.id },
|
||||
{ "duration", statusEntry.duration },
|
||||
{ "flag", statusEntry.flag },
|
||||
{ "modifiers", statusEntry.modifiers }
|
||||
};
|
||||
}
|
||||
|
|
|
@ -88,6 +88,7 @@ bool Action::Action::init()
|
|||
m_cooldownGroup = m_actionData->data().RecastGroup;
|
||||
m_range = m_actionData->data().SelectRange;
|
||||
m_effectRange = m_actionData->data().EffectRange;
|
||||
m_effectWidth = m_actionData->data().EffectWidth;
|
||||
m_category = static_cast< Common::ActionCategory >( m_actionData->data().Category );
|
||||
m_castType = static_cast< Common::CastType >( m_actionData->data().EffectType );
|
||||
m_aspect = static_cast< Common::ActionAspect >( m_actionData->data().AttackType );
|
||||
|
@ -119,7 +120,7 @@ bool Action::Action::init()
|
|||
m_primaryCostType = static_cast< Common::ActionPrimaryCostType >( m_actionData->data().CostType );
|
||||
m_primaryCost = m_actionData->data().CostValue;
|
||||
|
||||
/*if( !m_actionData->targetArea )
|
||||
if( !m_actionData->data().SelectGround )
|
||||
{
|
||||
// override pos to target position
|
||||
// todo: this is kinda dirty
|
||||
|
@ -131,7 +132,7 @@ bool Action::Action::init()
|
|||
break;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
// todo: add missing rows for secondaryCostType/secondaryCostType and rename the current rows to primaryCostX
|
||||
|
||||
|
@ -607,11 +608,17 @@ void Action::Action::handleAction()
|
|||
}
|
||||
}
|
||||
|
||||
if( m_lutEntry.statuses.caster.size() > 0 || m_lutEntry.statuses.target.size() > 0 )
|
||||
handleStatusEffects();
|
||||
// If we hit an enemy
|
||||
if( m_hitActors.size() > 0 && getHitChara()->getObjKind() != m_pSource->getObjKind() )
|
||||
{
|
||||
m_pSource->removeStatusEffectByFlag( Common::StatusEffectFlag::RemoveOnSuccessfulHit );
|
||||
}
|
||||
|
||||
handleJobAction();
|
||||
|
||||
if( m_lutEntry.statuses.caster.size() > 0 || m_lutEntry.statuses.target.size() > 0 )
|
||||
handleStatusEffects();
|
||||
|
||||
m_effectBuilder->buildAndSendPackets( m_hitActors );
|
||||
|
||||
// TODO: disabled, reset kills our queued actions
|
||||
|
@ -630,7 +637,7 @@ void Action::Action::handleStatusEffects()
|
|||
for( auto& status : m_lutEntry.statuses.caster )
|
||||
{
|
||||
applyStatusEffectSelf( status.id );
|
||||
m_pSource->addStatusEffectByIdIfNotExist( status.id, status.duration, *m_pSource, status.modifiers );
|
||||
m_pSource->addStatusEffectByIdIfNotExist( status.id, status.duration, *m_pSource, status );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -642,7 +649,7 @@ void Action::Action::handleStatusEffects()
|
|||
for( auto& status : m_lutEntry.statuses.target )
|
||||
{
|
||||
getEffectbuilder()->applyStatusEffect( actor, status.id, 0 );
|
||||
actor->addStatusEffectByIdIfNotExist( status.id, status.duration, *m_pSource, status.modifiers );
|
||||
actor->addStatusEffectByIdIfNotExist( status.id, status.duration, *m_pSource, status );
|
||||
}
|
||||
|
||||
if( actor->getStatusEffectMap().size() > 0 )
|
||||
|
@ -866,7 +873,6 @@ void Action::Action::addDefaultActorFilters()
|
|||
switch( m_castType )
|
||||
{
|
||||
case Common::CastType::SingleTarget:
|
||||
case Common::CastType::Type3:
|
||||
{
|
||||
auto filter = std::make_shared< World::Util::ActorFilterSingleTarget >( static_cast< uint32_t >( m_targetId ) );
|
||||
addActorFilter( filter );
|
||||
|
|
|
@ -572,6 +572,17 @@ void Sapphire::Entity::Chara::addStatusEffectByIdIfNotExist( uint32_t id, int32_
|
|||
addStatusEffect( effect );
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Chara::addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source,
|
||||
World::Action::StatusEntry& statusEntry, uint16_t param )
|
||||
{
|
||||
if( hasStatusEffect( id ) )
|
||||
return;
|
||||
|
||||
auto effect = StatusEffect::make_StatusEffect( id, source.getAsChara(), getAsChara(), duration, statusEntry, 3000 );
|
||||
effect->setParam( param );
|
||||
addStatusEffect( effect );
|
||||
}
|
||||
|
||||
int8_t Sapphire::Entity::Chara::getStatusEffectFreeSlot()
|
||||
{
|
||||
int8_t freeEffectSlot = -1;
|
||||
|
@ -614,6 +625,17 @@ void Sapphire::Entity::Chara::removeSingleStatusEffectById( uint32_t id )
|
|||
}
|
||||
}
|
||||
|
||||
void Sapphire::Entity::Chara::removeStatusEffectByFlag( Common::StatusEffectFlag flag )
|
||||
{
|
||||
for( auto effectIt = m_statusEffectMap.begin(); effectIt != m_statusEffectMap.end(); )
|
||||
{
|
||||
if( effectIt->second->getFlag() & static_cast< uint32_t >( flag ) )
|
||||
effectIt = removeStatusEffect( effectIt->first );
|
||||
else
|
||||
++effectIt;
|
||||
}
|
||||
}
|
||||
|
||||
std::map< uint8_t, Sapphire::StatusEffect::StatusEffectPtr >::iterator Sapphire::Entity::Chara::removeStatusEffect( uint8_t effectSlotId, bool sendOrder )
|
||||
{
|
||||
auto pEffectIt = m_statusEffectMap.find( effectSlotId );
|
||||
|
|
|
@ -114,6 +114,8 @@ namespace Sapphire::Entity
|
|||
|
||||
void removeSingleStatusEffectById( uint32_t id );
|
||||
|
||||
void removeStatusEffectByFlag( Common::StatusEffectFlag flag );
|
||||
|
||||
void updateStatusEffects();
|
||||
|
||||
bool hasStatusEffect( uint32_t id );
|
||||
|
@ -143,6 +145,8 @@ namespace Sapphire::Entity
|
|||
void addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param = 0 );
|
||||
void addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source, std::vector< World::Action::StatusModifier > modifiers,
|
||||
uint16_t param = 0 );
|
||||
void addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source, World::Action::StatusEntry& statusEntry,
|
||||
uint16_t param = 0 );
|
||||
|
||||
// remove a status effect by id
|
||||
void removeSingleStatusEffectFromId( uint32_t id );
|
||||
|
|
|
@ -28,6 +28,14 @@ Sapphire::StatusEffect::StatusEffect::StatusEffect( uint32_t id, Entity::CharaPt
|
|||
m_statusModifiers = std::move( modifiers );
|
||||
}
|
||||
|
||||
Sapphire::StatusEffect::StatusEffect::StatusEffect( uint32_t id, Entity::CharaPtr sourceActor, Entity::CharaPtr targetActor,
|
||||
uint32_t duration, World::Action::StatusEntry& statusEntry, uint32_t tickRate ) :
|
||||
StatusEffect( id, sourceActor, targetActor, duration, tickRate )
|
||||
{
|
||||
m_statusModifiers = statusEntry.modifiers;
|
||||
m_flag |= statusEntry.flag;
|
||||
}
|
||||
|
||||
Sapphire::StatusEffect::StatusEffect::StatusEffect( uint32_t id, Entity::CharaPtr sourceActor, Entity::CharaPtr targetActor,
|
||||
uint32_t duration, uint32_t tickRate ) :
|
||||
m_id( id ),
|
||||
|
@ -37,7 +45,8 @@ Sapphire::StatusEffect::StatusEffect::StatusEffect( uint32_t id, Entity::CharaPt
|
|||
m_modifiers( 0 ),
|
||||
m_startTime( 0 ),
|
||||
m_tickRate( tickRate ),
|
||||
m_lastTick( 0 )
|
||||
m_lastTick( 0 ),
|
||||
m_flag( 0 )
|
||||
{
|
||||
auto& exdData = Common::Service< Data::ExdData >::ref();
|
||||
auto entry = exdData.getRow< Excel::Status >( id );
|
||||
|
@ -52,6 +61,15 @@ Sapphire::StatusEffect::StatusEffect::StatusEffect( uint32_t id, Entity::CharaPt
|
|||
Util::eraseAll( m_name, '-' );
|
||||
Util::eraseAll( m_name, '(' );
|
||||
Util::eraseAll( m_name, ')' );
|
||||
|
||||
m_flag |= entry->data().Category;
|
||||
m_flag |= static_cast< uint32_t >( entry->data().Forever ) << static_cast< uint32_t >( Common::StatusEffectFlag::Permanent );
|
||||
m_flag |= static_cast< uint32_t >( entry->data().CanOff ) << static_cast< uint32_t >( Common::StatusEffectFlag::CanStatusOff );
|
||||
m_flag |= static_cast< uint32_t >( entry->data().NotAction ) << static_cast< uint32_t >( Common::StatusEffectFlag::LockActions );
|
||||
m_flag |= static_cast< uint32_t >( entry->data().NotControl ) << static_cast< uint32_t >( Common::StatusEffectFlag::LockControl );
|
||||
m_flag |= static_cast< uint32_t >( entry->data().NotMove ) << static_cast< uint32_t >( Common::StatusEffectFlag::LockMovement );
|
||||
m_flag |= static_cast< uint32_t >( entry->data().NotLookAt ) << static_cast< uint32_t >( Common::StatusEffectFlag::IsGaze );
|
||||
m_flag |= static_cast< uint32_t >( entry->data().FcAction ) << static_cast< uint32_t >( Common::StatusEffectFlag::FcBuff );
|
||||
}
|
||||
|
||||
|
||||
|
@ -192,6 +210,16 @@ uint64_t Sapphire::StatusEffect::StatusEffect::getStartTimeMs() const
|
|||
return m_startTime;
|
||||
}
|
||||
|
||||
uint32_t Sapphire::StatusEffect::StatusEffect::getFlag() const
|
||||
{
|
||||
return m_flag;
|
||||
}
|
||||
|
||||
void Sapphire::StatusEffect::StatusEffect::setFlag( uint32_t flag )
|
||||
{
|
||||
m_flag = flag;
|
||||
}
|
||||
|
||||
void Sapphire::StatusEffect::StatusEffect::setLastTick( uint64_t lastTick )
|
||||
{
|
||||
m_lastTick = lastTick;
|
||||
|
|
|
@ -14,6 +14,9 @@ public:
|
|||
StatusEffect( uint32_t id, Entity::CharaPtr sourceActor, Entity::CharaPtr targetActor,
|
||||
uint32_t duration, std::vector< World::Action::StatusModifier >& modifiers, uint32_t tickRate );
|
||||
|
||||
StatusEffect( uint32_t id, Entity::CharaPtr sourceActor, Entity::CharaPtr targetActor,
|
||||
uint32_t duration, World::Action::StatusEntry& statusEntry, uint32_t tickRate );
|
||||
|
||||
StatusEffect( uint32_t id, Entity::CharaPtr sourceActor, Entity::CharaPtr targetActor,
|
||||
uint32_t duration, uint32_t tickRate );
|
||||
|
||||
|
@ -47,10 +50,14 @@ public:
|
|||
|
||||
uint16_t getParam() const;
|
||||
|
||||
uint32_t getFlag() const;
|
||||
|
||||
void setLastTick( uint64_t lastTick );
|
||||
|
||||
void setParam( uint16_t param );
|
||||
|
||||
void setFlag( uint32_t flag );
|
||||
|
||||
void registerTickEffect( Common::ParamModifier type, uint32_t param );
|
||||
|
||||
std::pair< Common::ParamModifier, uint32_t > getTickEffect();
|
||||
|
@ -66,6 +73,7 @@ private:
|
|||
uint32_t m_tickRate;
|
||||
uint64_t m_lastTick;
|
||||
uint16_t m_param;
|
||||
uint32_t m_flag;
|
||||
std::string m_name;
|
||||
std::pair< Common::ParamModifier, uint32_t > m_currTickEffect;
|
||||
std::vector< World::Action::StatusModifier > m_statusModifiers;
|
||||
|
|
Loading…
Add table
Reference in a new issue