mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-23 10:17:44 +00:00
Merge fab2af1fa3
into bf3368224a
This commit is contained in:
commit
96e4afd200
18 changed files with 498 additions and 79 deletions
|
@ -504,6 +504,8 @@
|
||||||
{
|
{
|
||||||
"id": 85,
|
"id": 85,
|
||||||
"duration": 24000,
|
"duration": 24000,
|
||||||
|
"maxDuration": 60000,
|
||||||
|
"statusRefreshPolicy": 48,
|
||||||
"modifiers": [
|
"modifiers": [
|
||||||
{
|
{
|
||||||
"modifier": "DamageDealtPercent",
|
"modifier": "DamageDealtPercent",
|
||||||
|
@ -2039,7 +2041,20 @@
|
||||||
"nextCombo": [],
|
"nextCombo": [],
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"caster": [],
|
"caster": [],
|
||||||
"target": []
|
"target": [
|
||||||
|
{
|
||||||
|
"id": 150,
|
||||||
|
"duration": 30000,
|
||||||
|
"statusRefreshPolicy": 17,
|
||||||
|
"flag": 8192,
|
||||||
|
"modifiers": [
|
||||||
|
{
|
||||||
|
"modifier": "TickHeal",
|
||||||
|
"value": 50
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"134": {
|
"134": {
|
||||||
|
@ -2099,7 +2114,20 @@
|
||||||
"nextCombo": [],
|
"nextCombo": [],
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"caster": [],
|
"caster": [],
|
||||||
"target": []
|
"target": [
|
||||||
|
{
|
||||||
|
"id": 158,
|
||||||
|
"duration": 21000,
|
||||||
|
"statusRefreshPolicy": 17,
|
||||||
|
"flag": 8192,
|
||||||
|
"modifiers": [
|
||||||
|
{
|
||||||
|
"modifier": "TickHeal",
|
||||||
|
"value": 150
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"138": {
|
"138": {
|
||||||
|
|
|
@ -937,7 +937,18 @@ namespace Sapphire::Common
|
||||||
Invisibilty = 512,
|
Invisibilty = 512,
|
||||||
CanStatusOff = 1024,
|
CanStatusOff = 1024,
|
||||||
FcBuff = 2048,
|
FcBuff = 2048,
|
||||||
RemoveOnSuccessfulHit = 4096
|
RemoveOnSuccessfulHit = 4096,
|
||||||
|
ReplaceSameCaster = 8192
|
||||||
|
};
|
||||||
|
|
||||||
|
enum class StatusRefreshPolicy : uint8_t
|
||||||
|
{
|
||||||
|
Stack = 0,
|
||||||
|
ReplaceOrApply = 1,
|
||||||
|
Extend = 2,
|
||||||
|
ExtendOrApply = 3,
|
||||||
|
Reject = 4,
|
||||||
|
Custom = 255
|
||||||
};
|
};
|
||||||
|
|
||||||
enum struct ActionAspect : uint8_t
|
enum struct ActionAspect : uint8_t
|
||||||
|
|
|
@ -398,7 +398,18 @@
|
||||||
"restorePercentage": 0,
|
"restorePercentage": 0,
|
||||||
"nextCombo": [],
|
"nextCombo": [],
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"caster": [],
|
"caster": [
|
||||||
|
{
|
||||||
|
"id": 83,
|
||||||
|
"duration": 20000,
|
||||||
|
"modifiers": [
|
||||||
|
{
|
||||||
|
"modifier": "DefensePercent",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"target": []
|
"target": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -414,7 +425,18 @@
|
||||||
"nextCombo": [],
|
"nextCombo": [],
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"caster": [],
|
"caster": [],
|
||||||
"target": []
|
"target": [
|
||||||
|
{
|
||||||
|
"id": 244,
|
||||||
|
"duration": 30000,
|
||||||
|
"modifiers": [
|
||||||
|
{
|
||||||
|
"modifier": "TickDamage",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"34": {
|
"34": {
|
||||||
|
@ -478,7 +500,18 @@
|
||||||
45
|
45
|
||||||
],
|
],
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"caster": [],
|
"caster": [
|
||||||
|
{
|
||||||
|
"id": 85,
|
||||||
|
"duration": 24000,
|
||||||
|
"modifiers": [
|
||||||
|
{
|
||||||
|
"modifier": "DamageDealtPercent",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"target": []
|
"target": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -493,7 +526,18 @@
|
||||||
"restorePercentage": 0,
|
"restorePercentage": 0,
|
||||||
"nextCombo": [],
|
"nextCombo": [],
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"caster": [],
|
"caster": [
|
||||||
|
{
|
||||||
|
"id": 86,
|
||||||
|
"duration": 20000,
|
||||||
|
"modifiers": [
|
||||||
|
{
|
||||||
|
"modifier": "AttackPowerPercent",
|
||||||
|
"value": 50
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"target": []
|
"target": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -523,7 +567,18 @@
|
||||||
"restorePercentage": 0,
|
"restorePercentage": 0,
|
||||||
"nextCombo": [],
|
"nextCombo": [],
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"caster": [],
|
"caster": [
|
||||||
|
{
|
||||||
|
"id": 87,
|
||||||
|
"duration": 20000,
|
||||||
|
"modifiers": [
|
||||||
|
{
|
||||||
|
"modifier": "HPPercent",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"target": []
|
"target": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -583,7 +638,18 @@
|
||||||
"restorePercentage": 0,
|
"restorePercentage": 0,
|
||||||
"nextCombo": [],
|
"nextCombo": [],
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"caster": [],
|
"caster": [
|
||||||
|
{
|
||||||
|
"id": 89,
|
||||||
|
"duration": 20000,
|
||||||
|
"modifiers": [
|
||||||
|
{
|
||||||
|
"modifier": "ReflectPhysical",
|
||||||
|
"value": 50
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"target": []
|
"target": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -643,7 +709,34 @@
|
||||||
"restorePercentage": 0,
|
"restorePercentage": 0,
|
||||||
"nextCombo": [],
|
"nextCombo": [],
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"caster": [],
|
"caster": [
|
||||||
|
{
|
||||||
|
"id": 91,
|
||||||
|
"duration": 0,
|
||||||
|
"modifiers": [
|
||||||
|
{
|
||||||
|
"modifier": "HPPercent",
|
||||||
|
"value": 25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"modifier": "DamageDealtPercent",
|
||||||
|
"value": -25
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"modifier": "HealingMagicRecoveryPercent",
|
||||||
|
"value": 20
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"modifier": "AccuracyPercent",
|
||||||
|
"value": 5
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"modifier": "EnmityPercent",
|
||||||
|
"value": 20
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"target": []
|
"target": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -1176,7 +1269,19 @@
|
||||||
"restorePercentage": 0,
|
"restorePercentage": 0,
|
||||||
"nextCombo": [],
|
"nextCombo": [],
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"caster": [],
|
"caster": [
|
||||||
|
{
|
||||||
|
"id": 116,
|
||||||
|
"duration": 10000,
|
||||||
|
"flag": 4096,
|
||||||
|
"modifiers": [
|
||||||
|
{
|
||||||
|
"modifier": "CriticalHitPercent",
|
||||||
|
"value": 100
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
"target": []
|
"target": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -2394,7 +2499,18 @@
|
||||||
"nextCombo": [],
|
"nextCombo": [],
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"caster": [],
|
"caster": [],
|
||||||
"target": []
|
"target": [
|
||||||
|
{
|
||||||
|
"id": 179,
|
||||||
|
"duration": 18000,
|
||||||
|
"modifiers": [
|
||||||
|
{
|
||||||
|
"modifier": "TickDamage",
|
||||||
|
"value": 40
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"165": {
|
"165": {
|
||||||
|
@ -2454,7 +2570,38 @@
|
||||||
"nextCombo": [],
|
"nextCombo": [],
|
||||||
"statuses": {
|
"statuses": {
|
||||||
"caster": [],
|
"caster": [],
|
||||||
"target": []
|
"target": [
|
||||||
|
{
|
||||||
|
"id": 180,
|
||||||
|
"duration": 24000,
|
||||||
|
"modifiers": [
|
||||||
|
{
|
||||||
|
"modifier": "TickDamage",
|
||||||
|
"value": 35
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 191,
|
||||||
|
"duration": 24000,
|
||||||
|
"modifiers": [
|
||||||
|
{
|
||||||
|
"modifier": "HealingRecoveryPercent",
|
||||||
|
"value": -20
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": 240,
|
||||||
|
"duration": 24000,
|
||||||
|
"modifiers": [
|
||||||
|
{
|
||||||
|
"modifier": "HeavyPercent",
|
||||||
|
"value": 40
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"169": {
|
"169": {
|
||||||
|
|
|
@ -41,6 +41,8 @@ struct StatusEntry
|
||||||
{
|
{
|
||||||
uint16_t id;
|
uint16_t id;
|
||||||
uint32_t duration;
|
uint32_t duration;
|
||||||
|
uint32_t maxDuration;
|
||||||
|
uint8_t statusRefreshPolicy;
|
||||||
uint32_t flag;
|
uint32_t flag;
|
||||||
std::vector< StatusModifier > modifiers;
|
std::vector< StatusModifier > modifiers;
|
||||||
};
|
};
|
||||||
|
@ -79,6 +81,8 @@ void to_json( nlohmann::ordered_json& j, const StatusEntry& statusEntry )
|
||||||
j = nlohmann::ordered_json{
|
j = nlohmann::ordered_json{
|
||||||
{ "id", statusEntry.id },
|
{ "id", statusEntry.id },
|
||||||
{ "duration", statusEntry.duration },
|
{ "duration", statusEntry.duration },
|
||||||
|
{ "maxDuration", statusEntry.maxDuration },
|
||||||
|
{ "statusRefreshPolicy", statusEntry.statusRefreshPolicy },
|
||||||
{ "flag", statusEntry.flag },
|
{ "flag", statusEntry.flag },
|
||||||
{ "modifiers", statusEntry.modifiers }
|
{ "modifiers", statusEntry.modifiers }
|
||||||
};
|
};
|
||||||
|
@ -98,7 +102,7 @@ void to_json( nlohmann::ordered_json& j, const ActionEntry& action )
|
||||||
{ "nextCombo", action.nextCombo },
|
{ "nextCombo", action.nextCombo },
|
||||||
{ "statuses", {
|
{ "statuses", {
|
||||||
{ "caster", action.statuses.caster },
|
{ "caster", action.statuses.caster },
|
||||||
{ "target", action.statuses.target },
|
{ "target", action.statuses.target }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -32,6 +32,8 @@
|
||||||
#include <Service.h>
|
#include <Service.h>
|
||||||
#include "WorldServer.h"
|
#include "WorldServer.h"
|
||||||
|
|
||||||
|
#include "StatusEffect/StatusEffect.h"
|
||||||
|
|
||||||
#include "Job/Warrior.h"
|
#include "Job/Warrior.h"
|
||||||
|
|
||||||
using namespace Sapphire;
|
using namespace Sapphire;
|
||||||
|
@ -607,6 +609,89 @@ void Action::Action::buildActionResults()
|
||||||
// m_effectBuilder.reset();
|
// m_effectBuilder.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Action::Action::applyStatusEffect( bool isSelf, Entity::CharaPtr& target, Entity::CharaPtr& source, World::Action::StatusEntry& status, bool statusToSource )
|
||||||
|
{
|
||||||
|
auto pActionBuilder = getActionResultBuilder();
|
||||||
|
|
||||||
|
if( !pActionBuilder )
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto hasSameStatus = false;
|
||||||
|
auto hasSameStatusFromSameCaster = false;
|
||||||
|
Sapphire::StatusEffect::StatusEffectPtr referenceStatus = nullptr;
|
||||||
|
|
||||||
|
for( auto const& entry : statusToSource ? source->getStatusEffectMap() : target->getStatusEffectMap() )
|
||||||
|
{
|
||||||
|
auto statusEffect = entry.second;
|
||||||
|
if( statusEffect->getId() == status.id )
|
||||||
|
{
|
||||||
|
hasSameStatus = true;
|
||||||
|
|
||||||
|
if( !referenceStatus )
|
||||||
|
referenceStatus = statusEffect;
|
||||||
|
|
||||||
|
if( statusEffect->getSrcActorId() == source->getId() )
|
||||||
|
{
|
||||||
|
hasSameStatusFromSameCaster = true;
|
||||||
|
referenceStatus = statusEffect;
|
||||||
|
break;;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto policy = getStatusRefreshPolicy( status.statusRefreshPolicy, isSelf );
|
||||||
|
switch( policy )
|
||||||
|
{
|
||||||
|
case Common::StatusRefreshPolicy::Stack:
|
||||||
|
{
|
||||||
|
pActionBuilder->applyStatusEffect( target, status.id, status.duration, 0, std::move( status.modifiers ), status.flag, statusToSource, false );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Common::StatusRefreshPolicy::ReplaceOrApply:
|
||||||
|
{
|
||||||
|
if( (status.flag & static_cast< uint32_t >( Common::StatusEffectFlag::ReplaceSameCaster ) && hasSameStatusFromSameCaster) || hasSameStatus )
|
||||||
|
pActionBuilder->replaceStatusEffect( referenceStatus, target, status.id, status.duration, 0, std::move( status.modifiers ), status.flag, statusToSource );
|
||||||
|
else
|
||||||
|
pActionBuilder->applyStatusEffect( target, status.id, status.duration, 0, std::move( status.modifiers ), status.flag, statusToSource, true );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Common::StatusRefreshPolicy::Extend:
|
||||||
|
case Common::StatusRefreshPolicy::ExtendOrApply:
|
||||||
|
{
|
||||||
|
int64_t remainingDuration = 0;
|
||||||
|
if( hasSameStatus )
|
||||||
|
{
|
||||||
|
remainingDuration = static_cast< int64_t >( referenceStatus->getDuration() ) - ( Common::Util::getTimeMs() - referenceStatus->getStartTimeMs() );
|
||||||
|
if( remainingDuration < 0 )
|
||||||
|
remainingDuration = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( hasSameStatus || policy == Common::StatusRefreshPolicy::ExtendOrApply )
|
||||||
|
{
|
||||||
|
pActionBuilder->applyStatusEffect( target, status.id, std::min( status.duration + remainingDuration, static_cast< int64_t >( status.maxDuration ) ), 0, std::move( status.modifiers ), status.flag, statusToSource, true );
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Common::StatusRefreshPolicy::Reject:
|
||||||
|
{
|
||||||
|
if( !hasSameStatus )
|
||||||
|
{
|
||||||
|
pActionBuilder->applyStatusEffect( target, status.id, status.duration, 0, std::move( status.modifiers ), status.flag, statusToSource, true );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// add function to ActionBuilder for No Effect effect
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case Common::StatusRefreshPolicy::Custom:
|
||||||
|
{
|
||||||
|
// script should handle it
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Action::Action::handleStatusEffects()
|
void Action::Action::handleStatusEffects()
|
||||||
{
|
{
|
||||||
auto pActionBuilder = getActionResultBuilder();
|
auto pActionBuilder = getActionResultBuilder();
|
||||||
|
@ -622,7 +707,12 @@ void Action::Action::handleStatusEffects()
|
||||||
{
|
{
|
||||||
for( auto& status : m_lutEntry.statuses.caster )
|
for( auto& status : m_lutEntry.statuses.caster )
|
||||||
{
|
{
|
||||||
pActionBuilder->applyStatusEffectSelf( status.id, status.duration, 0, std::move( status.modifiers ), status.flag, true );
|
/*if( m_hitActors[ 0 ] ) // might need a firstValidVictim?
|
||||||
|
applyStatusEffect( true, m_hitActors[ 0 ], m_pSource, status, true );
|
||||||
|
// pActionBuilder->applyStatusEffectSelf( status.id, status.duration, 0, std::move( status.modifiers ), status.flag, true ); // statusToSource true
|
||||||
|
else if( m_lutEntry.potency == 0 )*/
|
||||||
|
applyStatusEffect( true, m_pSource, m_pSource, status, true );
|
||||||
|
// pActionBuilder->applyStatusEffectSelf( status.id, status.duration, 0, std::move( status.modifiers ), status.flag, true );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -633,7 +723,8 @@ void Action::Action::handleStatusEffects()
|
||||||
{
|
{
|
||||||
for( auto& status : m_lutEntry.statuses.target )
|
for( auto& status : m_lutEntry.statuses.target )
|
||||||
{
|
{
|
||||||
pActionBuilder->applyStatusEffect( actor, status.id, status.duration, 0, std::move( status.modifiers ), status.flag, true );
|
applyStatusEffect( false, actor, m_pSource, status );
|
||||||
|
// pActionBuilder->applyStatusEffect( actor, status.id, status.duration, 0, std::move( status.modifiers ), status.flag, true );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !actor->getStatusEffectMap().empty() )
|
if( !actor->getStatusEffectMap().empty() )
|
||||||
|
|
|
@ -113,6 +113,8 @@ namespace Sapphire::World::Action
|
||||||
|
|
||||||
void buildActionResults();
|
void buildActionResults();
|
||||||
|
|
||||||
|
void applyStatusEffect( bool isSelf, Entity::CharaPtr& target, Entity::CharaPtr& source, World::Action::StatusEntry& status, bool statusToSource = false );
|
||||||
|
|
||||||
void handleStatusEffects();
|
void handleStatusEffects();
|
||||||
|
|
||||||
void handleJobAction();
|
void handleJobAction();
|
||||||
|
|
|
@ -27,3 +27,9 @@ const ActionEntry& ActionLut::getEntry( uint16_t actionId )
|
||||||
|
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Sapphire::Common::StatusRefreshPolicy Sapphire::World::Action::getStatusRefreshPolicy( uint8_t statusRefreshPolicy, bool sameSource )
|
||||||
|
{
|
||||||
|
uint8_t policy = sameSource ? statusRefreshPolicy >> 4 : statusRefreshPolicy & 0x0F;
|
||||||
|
return static_cast< Sapphire::Common::StatusRefreshPolicy >( policy );
|
||||||
|
}
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
|
||||||
|
@ -18,6 +17,8 @@ namespace Sapphire::World::Action
|
||||||
{
|
{
|
||||||
uint16_t id;
|
uint16_t id;
|
||||||
uint32_t duration;
|
uint32_t duration;
|
||||||
|
uint32_t maxDuration;
|
||||||
|
uint8_t statusRefreshPolicy;
|
||||||
uint32_t flag;
|
uint32_t flag;
|
||||||
std::vector< StatusModifier > modifiers;
|
std::vector< StatusModifier > modifiers;
|
||||||
};
|
};
|
||||||
|
@ -51,4 +52,6 @@ namespace Sapphire::World::Action
|
||||||
|
|
||||||
static Lut m_actionLut;
|
static Lut m_actionLut;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Sapphire::Common::StatusRefreshPolicy getStatusRefreshPolicy( uint8_t statusRefreshPolicy, bool sameSource );
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,10 @@ namespace Sapphire::World::Action
|
||||||
{
|
{
|
||||||
j.at( "id" ).get_to( statusEntry.id );
|
j.at( "id" ).get_to( statusEntry.id );
|
||||||
j.at( "duration" ).get_to( statusEntry.duration );
|
j.at( "duration" ).get_to( statusEntry.duration );
|
||||||
|
if( j.contains( "maxDuration" ) )
|
||||||
|
j.at( "maxDuration" ).get_to( statusEntry.maxDuration );
|
||||||
|
if( j.contains( "statusRefreshPolicy" ) )
|
||||||
|
j.at( "statusRefreshPolicy" ).get_to( statusEntry.statusRefreshPolicy );
|
||||||
if( j.contains( "flag" ) )
|
if( j.contains( "flag" ) )
|
||||||
j.at( "flag" ).get_to( statusEntry.flag );
|
j.at( "flag" ).get_to( statusEntry.flag );
|
||||||
if( j.contains( "modifiers" ) )
|
if( j.contains( "modifiers" ) )
|
||||||
|
|
|
@ -9,6 +9,8 @@
|
||||||
#include "Actor/Player.h"
|
#include "Actor/Player.h"
|
||||||
#include "StatusEffect/StatusEffect.h"
|
#include "StatusEffect/StatusEffect.h"
|
||||||
|
|
||||||
|
#include "Network/Util/PacketUtil.h"
|
||||||
|
|
||||||
using namespace Sapphire;
|
using namespace Sapphire;
|
||||||
using namespace Sapphire::Common;
|
using namespace Sapphire::Common;
|
||||||
using namespace Sapphire::World::Action;
|
using namespace Sapphire::World::Action;
|
||||||
|
@ -72,19 +74,21 @@ void ActionResult::applyStatusEffect( uint32_t id, int32_t duration, Entity::Cha
|
||||||
m_result.Arg2 = param;
|
m_result.Arg2 = param;
|
||||||
m_result.Type = CalcResultType::TypeSetStatus;
|
m_result.Type = CalcResultType::TypeSetStatus;
|
||||||
|
|
||||||
m_bOverrideStatus = shouldOverride;
|
m_bShouldOverride = shouldOverride;
|
||||||
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, source.getAsChara(), m_target, duration, 3000 );
|
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, source.getAsChara(), m_target, duration, 3000 );
|
||||||
m_pStatus->setParam( param );
|
m_pStatus->setParam( param );
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResult::applyStatusEffect( uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param,
|
void ActionResult::applyStatusEffect( uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param,
|
||||||
const std::vector< StatusModifier >& modifiers, uint32_t flag, bool shouldOverride )
|
const std::vector< StatusModifier >& modifiers, uint32_t flag, bool statusToSource, bool shouldOverride )
|
||||||
{
|
{
|
||||||
m_result.Value = static_cast< int16_t >( id );
|
m_result.Value = static_cast< int16_t >( id );
|
||||||
m_result.Arg2 = param;
|
m_result.Arg2 = param;
|
||||||
m_result.Type = CalcResultType::TypeSetStatus;
|
m_result.Type = statusToSource ? CalcResultType::TypeSetStatusMe : CalcResultType::TypeSetStatus;
|
||||||
|
if( statusToSource )
|
||||||
|
m_result.Flag = static_cast< uint8_t >( ActionResultFlag::EffectOnSource );
|
||||||
|
|
||||||
m_bOverrideStatus = shouldOverride;
|
m_bShouldOverride = shouldOverride;
|
||||||
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, source.getAsChara(), m_target, duration, modifiers, flag, 3000 );
|
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, source.getAsChara(), m_target, duration, modifiers, flag, 3000 );
|
||||||
m_pStatus->setParam( param );
|
m_pStatus->setParam( param );
|
||||||
}
|
}
|
||||||
|
@ -96,7 +100,7 @@ void ActionResult::applyStatusEffectSelf( uint32_t id, int32_t duration, uint8_t
|
||||||
m_result.Type = CalcResultType::TypeSetStatusMe;
|
m_result.Type = CalcResultType::TypeSetStatusMe;
|
||||||
m_result.Flag = static_cast< uint8_t >( ActionResultFlag::EffectOnSource );
|
m_result.Flag = static_cast< uint8_t >( ActionResultFlag::EffectOnSource );
|
||||||
|
|
||||||
m_bOverrideStatus = shouldOverride;
|
m_bShouldOverride = shouldOverride;
|
||||||
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, m_target, m_target, duration, 3000 );
|
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, m_target, m_target, duration, 3000 );
|
||||||
m_pStatus->setParam( param );
|
m_pStatus->setParam( param );
|
||||||
}
|
}
|
||||||
|
@ -109,11 +113,27 @@ void ActionResult::applyStatusEffectSelf( uint32_t id, int32_t duration, uint8_t
|
||||||
m_result.Type = CalcResultType::TypeSetStatusMe;
|
m_result.Type = CalcResultType::TypeSetStatusMe;
|
||||||
m_result.Flag = static_cast< uint8_t >( Common::ActionResultFlag::EffectOnSource );
|
m_result.Flag = static_cast< uint8_t >( Common::ActionResultFlag::EffectOnSource );
|
||||||
|
|
||||||
m_bOverrideStatus = shouldOverride;
|
m_bShouldOverride = shouldOverride;
|
||||||
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, m_target, m_target, duration, modifiers, flag, 3000 );
|
m_pStatus = Sapphire::StatusEffect::make_StatusEffect( id, m_target, m_target, duration, modifiers, flag, 3000 );
|
||||||
m_pStatus->setParam( param );
|
m_pStatus->setParam( param );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ActionResult::replaceStatusEffect( Sapphire::StatusEffect::StatusEffectPtr& pOldStatus, uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param,
|
||||||
|
const std::vector< StatusModifier >& modifiers, uint32_t flag, bool statusToSource )
|
||||||
|
{
|
||||||
|
applyStatusEffect( id, duration, source, param, modifiers, flag, statusToSource, false );
|
||||||
|
m_pOldStatus = std::move( pOldStatus );
|
||||||
|
m_pStatus->setSlot( m_pOldStatus->getSlot() );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionResult::replaceStatusEffectSelf( Sapphire::StatusEffect::StatusEffectPtr& pOldStatus, uint32_t id, int32_t duration, uint8_t param,
|
||||||
|
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag )
|
||||||
|
{
|
||||||
|
applyStatusEffectSelf( id, duration, param, modifiers, flag, false );
|
||||||
|
m_pOldStatus = std::move( pOldStatus );
|
||||||
|
m_pStatus->setSlot( m_pOldStatus->getSlot() );
|
||||||
|
}
|
||||||
|
|
||||||
void ActionResult::mount( uint16_t mountId )
|
void ActionResult::mount( uint16_t mountId )
|
||||||
{
|
{
|
||||||
m_result.Value = static_cast< int16_t >( mountId );
|
m_result.Value = static_cast< int16_t >( mountId );
|
||||||
|
@ -161,7 +181,22 @@ void ActionResult::execute()
|
||||||
case CalcResultType::TypeSetStatus:
|
case CalcResultType::TypeSetStatus:
|
||||||
case CalcResultType::TypeSetStatusMe:
|
case CalcResultType::TypeSetStatusMe:
|
||||||
{
|
{
|
||||||
if( !m_bOverrideStatus )
|
for( auto const& entry : m_target->getStatusEffectMap() )
|
||||||
|
{
|
||||||
|
auto statusEffect = entry.second;
|
||||||
|
if( statusEffect->getId() == m_result.Value && m_bShouldOverride && statusEffect->getSrcActorId() == m_pStatus->getSrcActorId() )
|
||||||
|
{
|
||||||
|
statusEffect->refresh( m_pStatus->getDuration() );
|
||||||
|
m_pStatus->setSlot( statusEffect->getSlot() );
|
||||||
|
|
||||||
|
Network::Util::Packet::sendHudParam( *m_target );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if( m_pOldStatus )
|
||||||
|
m_target->replaceSingleStatusEffect( m_pOldStatus->getSlot(), m_pStatus );
|
||||||
|
else if( !m_bShouldOverride )
|
||||||
m_target->addStatusEffectByIdIfNotExist( m_pStatus );
|
m_target->addStatusEffectByIdIfNotExist( m_pStatus );
|
||||||
else
|
else
|
||||||
m_target->addStatusEffectById( m_pStatus );
|
m_target->addStatusEffectById( m_pStatus );
|
||||||
|
|
|
@ -22,10 +22,14 @@ namespace Sapphire::World::Action
|
||||||
void comboSucceed();
|
void comboSucceed();
|
||||||
void applyStatusEffect( uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param, bool shouldOverride );
|
void applyStatusEffect( uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param, bool shouldOverride );
|
||||||
void applyStatusEffect( uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param,
|
void applyStatusEffect( uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param,
|
||||||
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag, bool shouldOverride );
|
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag, bool statusToSource, bool shouldOverride );
|
||||||
void applyStatusEffectSelf( uint32_t id, int32_t duration, uint8_t param, bool shouldOverride );
|
void applyStatusEffectSelf( uint32_t id, int32_t duration, uint8_t param, bool shouldOverride );
|
||||||
void applyStatusEffectSelf( uint32_t id, int32_t duration, uint8_t param, const std::vector< World::Action::StatusModifier >& modifiers,
|
void applyStatusEffectSelf( uint32_t id, int32_t duration, uint8_t param, const std::vector< World::Action::StatusModifier >& modifiers,
|
||||||
uint32_t flag, bool shouldOverride );
|
uint32_t flag, bool shouldOverride );
|
||||||
|
void replaceStatusEffect( Sapphire::StatusEffect::StatusEffectPtr& pOldStatus, uint32_t id, int32_t duration, Entity::Chara& source, uint8_t param,
|
||||||
|
const std::vector< StatusModifier >& modifiers, uint32_t flag, bool statusToSource );
|
||||||
|
void replaceStatusEffectSelf( Sapphire::StatusEffect::StatusEffectPtr& pOldStatus, uint32_t id, int32_t duration, uint8_t param,
|
||||||
|
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag );
|
||||||
void mount( uint16_t mountId );
|
void mount( uint16_t mountId );
|
||||||
|
|
||||||
Entity::CharaPtr getTarget() const;
|
Entity::CharaPtr getTarget() const;
|
||||||
|
@ -40,8 +44,9 @@ namespace Sapphire::World::Action
|
||||||
|
|
||||||
Common::CalcResultParam m_result;
|
Common::CalcResultParam m_result;
|
||||||
|
|
||||||
bool m_bOverrideStatus { false };
|
bool m_bShouldOverride { false };
|
||||||
Sapphire::StatusEffect::StatusEffectPtr m_pStatus;
|
Sapphire::StatusEffect::StatusEffectPtr m_pStatus;
|
||||||
|
Sapphire::StatusEffect::StatusEffectPtr m_pOldStatus;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#include "ActionResultBuilder.h"
|
#include "ActionResultBuilder.h"
|
||||||
#include "ActionResult.h"
|
#include "ActionResult.h"
|
||||||
|
|
||||||
#include <Actor/Player.h>
|
#include <Actor/Player.h>
|
||||||
|
@ -94,10 +94,10 @@ void ActionResultBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionResultBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param,
|
void ActionResultBuilder::applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param,
|
||||||
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag, bool shouldOverride )
|
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag, bool statusToSource, bool shouldOverride )
|
||||||
{
|
{
|
||||||
ActionResultPtr nextResult = make_ActionResult( target );
|
ActionResultPtr nextResult = make_ActionResult( target );
|
||||||
nextResult->applyStatusEffect( statusId, duration, *m_sourceChara, param, modifiers, flag, shouldOverride );
|
nextResult->applyStatusEffect( statusId, duration, *m_sourceChara, param, modifiers, flag, statusToSource, shouldOverride );
|
||||||
addResultToActor( target, nextResult );
|
addResultToActor( target, nextResult );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +116,22 @@ void ActionResultBuilder::applyStatusEffectSelf( uint16_t statusId, uint32_t dur
|
||||||
addResultToActor( m_sourceChara, nextResult );
|
addResultToActor( m_sourceChara, nextResult );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ActionResultBuilder::replaceStatusEffect( Sapphire::StatusEffect::StatusEffectPtr& pOldStatus, Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param,
|
||||||
|
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag, bool statusToSource )
|
||||||
|
{
|
||||||
|
ActionResultPtr nextResult = make_ActionResult( target );
|
||||||
|
nextResult->replaceStatusEffect( pOldStatus, statusId, duration, *m_sourceChara, param, modifiers, flag, statusToSource );
|
||||||
|
addResultToActor( target, nextResult );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ActionResultBuilder::replaceStatusEffectSelf( Sapphire::StatusEffect::StatusEffectPtr& pOldStatus, uint16_t statusId, uint32_t duration, uint8_t param,
|
||||||
|
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag )
|
||||||
|
{
|
||||||
|
ActionResultPtr nextResult = make_ActionResult( m_sourceChara );
|
||||||
|
nextResult->replaceStatusEffectSelf( pOldStatus, statusId, duration, param, modifiers, flag );
|
||||||
|
addResultToActor( m_sourceChara, nextResult );
|
||||||
|
}
|
||||||
|
|
||||||
void ActionResultBuilder::mount( Entity::CharaPtr& target, uint16_t mountId )
|
void ActionResultBuilder::mount( Entity::CharaPtr& target, uint16_t mountId )
|
||||||
{
|
{
|
||||||
ActionResultPtr nextResult = make_ActionResult( target );
|
ActionResultPtr nextResult = make_ActionResult( target );
|
||||||
|
|
|
@ -28,11 +28,14 @@ namespace Sapphire::World::Action
|
||||||
|
|
||||||
void applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param, bool shouldOverride = false );
|
void applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param, bool shouldOverride = false );
|
||||||
void applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param,
|
void applyStatusEffect( Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param,
|
||||||
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag = 0, bool shouldOverride = false );
|
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag = 0, bool statusToSource = false, bool shouldOverride = false );
|
||||||
void applyStatusEffectSelf( uint16_t statusId, uint32_t duration, uint8_t param, bool shouldOverride = false );
|
void applyStatusEffectSelf( uint16_t statusId, uint32_t duration, uint8_t param, bool shouldOverride = false );
|
||||||
void applyStatusEffectSelf( uint16_t statusId, uint32_t duration, uint8_t param, const std::vector< World::Action::StatusModifier >& modifiers,
|
void applyStatusEffectSelf( uint16_t statusId, uint32_t duration, uint8_t param, const std::vector< World::Action::StatusModifier >& modifiers,
|
||||||
uint32_t flag = 0, bool shouldOverride = false );
|
uint32_t flag = 0, bool shouldOverride = false );
|
||||||
|
void replaceStatusEffect( Sapphire::StatusEffect::StatusEffectPtr& pOldStatus, Entity::CharaPtr& target, uint16_t statusId, uint32_t duration, uint8_t param,
|
||||||
|
const std::vector< StatusModifier >& modifiers, uint32_t flag = 0, bool statusToSource = false );
|
||||||
|
void replaceStatusEffectSelf( Sapphire::StatusEffect::StatusEffectPtr& pOldStatus, uint16_t statusId, uint32_t duration, uint8_t param,
|
||||||
|
const std::vector< World::Action::StatusModifier >& modifiers, uint32_t flag = 0 );
|
||||||
void mount( Entity::CharaPtr& target, uint16_t mountId );
|
void mount( Entity::CharaPtr& target, uint16_t mountId );
|
||||||
|
|
||||||
void sendActionResults( const std::vector< Entity::CharaPtr >& targetList );
|
void sendActionResults( const std::vector< Entity::CharaPtr >& targetList );
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include <Action/CommonAction.h>
|
#include <Action/CommonAction.h>
|
||||||
#include <Action/Action.h>
|
#include <Action/Action.h>
|
||||||
#include <Actor/Player.h>
|
#include <Actor/Player.h>
|
||||||
|
#include <StatusEffect/StatusEffect.h>
|
||||||
|
|
||||||
using namespace Sapphire;
|
using namespace Sapphire;
|
||||||
using namespace Sapphire::World::Action;
|
using namespace Sapphire::World::Action;
|
||||||
|
@ -29,6 +30,7 @@ void Warrior::onAction( Entity::Player& player, Action& action )
|
||||||
|
|
||||||
void Warrior::handleWrath( Entity::Player& player, Action& action )
|
void Warrior::handleWrath( Entity::Player& player, Action& action )
|
||||||
{
|
{
|
||||||
|
Sapphire::StatusEffect::StatusEffectPtr oldStatus = nullptr;
|
||||||
auto effectToApply = Wrath;
|
auto effectToApply = Wrath;
|
||||||
auto parry = 2;
|
auto parry = 2;
|
||||||
auto asChara = player.getAsChara();
|
auto asChara = player.getAsChara();
|
||||||
|
@ -38,33 +40,45 @@ void Warrior::handleWrath( Entity::Player& player, Action& action )
|
||||||
if( !pActionBuilder )
|
if( !pActionBuilder )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if( player.hasStatusEffect( Wrath ) )
|
auto statusMap = player.getStatusEffectMap();
|
||||||
|
|
||||||
|
for( const auto& effectIt : statusMap )
|
||||||
{
|
{
|
||||||
player.replaceSingleStatusEffectById( Wrath );
|
if( effectIt.second->getId() == Wrath )
|
||||||
effectToApply = WrathII;
|
{
|
||||||
parry += 2;
|
oldStatus = effectIt.second;
|
||||||
}
|
effectToApply = WrathII;
|
||||||
else if( player.hasStatusEffect( WrathII ) )
|
parry += 2;
|
||||||
{
|
break;
|
||||||
player.replaceSingleStatusEffectById( WrathII );
|
}
|
||||||
effectToApply = WrathIII;
|
else if( effectIt.second->getId() == WrathII )
|
||||||
parry += 2;
|
{
|
||||||
}
|
oldStatus = effectIt.second;
|
||||||
else if( player.hasStatusEffect( WrathIII ) )
|
effectToApply = WrathIII;
|
||||||
{
|
parry += 2;
|
||||||
player.replaceSingleStatusEffectById( WrathIII );
|
break;
|
||||||
effectToApply = WrathIV;
|
}
|
||||||
parry += 2;
|
else if( effectIt.second->getId() == WrathIII )
|
||||||
}
|
{
|
||||||
else if( player.hasStatusEffect( WrathIV ) )
|
oldStatus = effectIt.second;
|
||||||
{
|
effectToApply = WrathIV;
|
||||||
player.replaceSingleStatusEffectById( WrathIV );
|
parry += 2;
|
||||||
effectToApply = Infuriated;
|
break;
|
||||||
parry += 2;
|
}
|
||||||
|
else if( effectIt.second->getId() == WrathIV )
|
||||||
|
{
|
||||||
|
oldStatus = effectIt.second;
|
||||||
|
effectToApply = Infuriated;
|
||||||
|
parry += 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !player.hasStatusEffect( Infuriated ) )
|
if( !player.hasStatusEffect( Infuriated ) )
|
||||||
{
|
{
|
||||||
pActionBuilder->applyStatusEffectSelf( effectToApply, 30000, 0, { StatusModifier{ Common::ParamModifier::ParryPercent, parry } }, 0, false );
|
if( oldStatus )
|
||||||
|
pActionBuilder->replaceStatusEffectSelf( oldStatus, effectToApply, 30000, 0, { StatusModifier{ Common::ParamModifier::ParryPercent, parry } } );
|
||||||
|
else
|
||||||
|
pActionBuilder->applyStatusEffectSelf( effectToApply, 30000, 0, { StatusModifier{ Common::ParamModifier::ParryPercent, parry } } );
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -49,12 +49,6 @@ Chara::Chara( ObjKind type ) :
|
||||||
m_lastAttack = Common::Util::getTimeMs();
|
m_lastAttack = Common::Util::getTimeMs();
|
||||||
|
|
||||||
m_bonusStats.fill( 0 );
|
m_bonusStats.fill( 0 );
|
||||||
|
|
||||||
// initialize the free slot queue
|
|
||||||
for( uint8_t i = 0; i < MAX_STATUS_EFFECTS; i++ )
|
|
||||||
{
|
|
||||||
m_statusEffectFreeSlotQueue.push( i );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Chara::~Chara() = default;
|
Chara::~Chara() = default;
|
||||||
|
@ -521,18 +515,31 @@ int8_t Chara::getStatusEffectFreeSlot()
|
||||||
{
|
{
|
||||||
int8_t freeEffectSlot = -1;
|
int8_t freeEffectSlot = -1;
|
||||||
|
|
||||||
if( m_statusEffectFreeSlotQueue.empty() )
|
if( m_statusEffectSlots.size() >= MAX_STATUS_EFFECTS )
|
||||||
return freeEffectSlot;
|
return freeEffectSlot;
|
||||||
|
|
||||||
freeEffectSlot = static_cast< int8_t >( m_statusEffectFreeSlotQueue.front() );
|
if( m_statusEffectSlots.empty() )
|
||||||
m_statusEffectFreeSlotQueue.pop();
|
freeEffectSlot = 0;
|
||||||
|
else
|
||||||
|
freeEffectSlot = static_cast< int8_t >( *m_statusEffectSlots.rbegin() + 1 );
|
||||||
|
|
||||||
|
m_statusEffectSlots.insert( freeEffectSlot );
|
||||||
|
|
||||||
|
Logger::warn( "Slot id being added: {}", freeEffectSlot );
|
||||||
|
|
||||||
return freeEffectSlot;
|
return freeEffectSlot;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chara::statusEffectFreeSlot( uint8_t slotId )
|
void Chara::statusEffectFreeSlot( uint8_t slotId )
|
||||||
{
|
{
|
||||||
m_statusEffectFreeSlotQueue.push( slotId );
|
m_statusEffectSlots.erase( slotId );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Chara::replaceSingleStatusEffect( uint32_t slotId, StatusEffect::StatusEffectPtr pStatus )
|
||||||
|
{
|
||||||
|
pStatus->setSlot( slotId );
|
||||||
|
m_statusEffectMap[ slotId ] = pStatus;
|
||||||
|
pStatus->applyStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Chara::replaceSingleStatusEffectById( uint32_t id )
|
void Chara::replaceSingleStatusEffectById( uint32_t id )
|
||||||
|
@ -588,7 +595,7 @@ void Chara::removeStatusEffectByFlag( Common::StatusEffectFlag flag )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::map< uint8_t, Sapphire::StatusEffect::StatusEffectPtr >::iterator Chara::removeStatusEffect( uint8_t effectSlotId, bool sendOrder )
|
std::map< uint8_t, Sapphire::StatusEffect::StatusEffectPtr >::iterator Chara::removeStatusEffect( uint8_t effectSlotId, bool updateStatus )
|
||||||
{
|
{
|
||||||
auto pEffectIt = m_statusEffectMap.find( effectSlotId );
|
auto pEffectIt = m_statusEffectMap.find( effectSlotId );
|
||||||
if( pEffectIt == m_statusEffectMap.end() )
|
if( pEffectIt == m_statusEffectMap.end() )
|
||||||
|
@ -599,11 +606,35 @@ std::map< uint8_t, Sapphire::StatusEffect::StatusEffectPtr >::iterator Chara::re
|
||||||
auto pEffect = pEffectIt->second;
|
auto pEffect = pEffectIt->second;
|
||||||
pEffect->removeStatus();
|
pEffect->removeStatus();
|
||||||
|
|
||||||
if( sendOrder )
|
if( updateStatus )
|
||||||
|
{
|
||||||
Network::Util::Packet::sendActorControl( getInRangePlayerIds( isPlayer() ), getId(), StatusEffectLose, pEffect->getId() );
|
Network::Util::Packet::sendActorControl( getInRangePlayerIds( isPlayer() ), getId(), StatusEffectLose, pEffect->getId() );
|
||||||
|
Network::Util::Packet::sendHudParam( *this );
|
||||||
|
}
|
||||||
|
|
||||||
auto it = m_statusEffectMap.erase( pEffectIt );
|
auto it = m_statusEffectMap.erase( pEffectIt );
|
||||||
Network::Util::Packet::sendHudParam( *this );
|
|
||||||
|
for( auto effectIt = it; effectIt != m_statusEffectMap.end(); )
|
||||||
|
{
|
||||||
|
// if the status is *after* the one being removed, shift the slots down by one
|
||||||
|
auto shifted_slot = effectIt->first - 1;
|
||||||
|
|
||||||
|
auto node_slot = m_statusEffectSlots.extract( effectIt->first );
|
||||||
|
node_slot.value() = shifted_slot;
|
||||||
|
m_statusEffectSlots.insert( std::move( node_slot ) );
|
||||||
|
|
||||||
|
auto node_status = m_statusEffectMap.extract( effectIt->first );
|
||||||
|
node_status.key() = shifted_slot;
|
||||||
|
m_statusEffectMap.insert( std::move( node_status ) );
|
||||||
|
|
||||||
|
effectIt->second->setSlot( effectIt->second->getSlot() - 1 );
|
||||||
|
|
||||||
|
Logger::warn( "Shifted slot {} to slot: {}", effectSlotId, shifted_slot );
|
||||||
|
++effectIt;
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger::warn( "Slot id being freed: {}", effectSlotId );
|
||||||
|
|
||||||
return it;
|
return it;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -86,9 +86,9 @@ namespace Sapphire::Entity
|
||||||
|
|
||||||
/*! Status effects */
|
/*! Status effects */
|
||||||
const uint8_t MAX_STATUS_EFFECTS = 30;
|
const uint8_t MAX_STATUS_EFFECTS = 30;
|
||||||
std::queue< uint8_t > m_statusEffectFreeSlotQueue;
|
|
||||||
std::vector< std::pair< uint8_t, uint32_t > > m_statusEffectList;
|
std::vector< std::pair< uint8_t, uint32_t > > m_statusEffectList;
|
||||||
std::map< uint8_t, StatusEffect::StatusEffectPtr > m_statusEffectMap;
|
std::map< uint8_t, StatusEffect::StatusEffectPtr > m_statusEffectMap;
|
||||||
|
std::set< uint8_t > m_statusEffectSlots;
|
||||||
|
|
||||||
/*! Detour Crowd AgentId */
|
/*! Detour Crowd AgentId */
|
||||||
uint32_t m_agentId;
|
uint32_t m_agentId;
|
||||||
|
@ -108,7 +108,9 @@ namespace Sapphire::Entity
|
||||||
/// Status effect functions
|
/// Status effect functions
|
||||||
void addStatusEffect( StatusEffect::StatusEffectPtr pEffect );
|
void addStatusEffect( StatusEffect::StatusEffectPtr pEffect );
|
||||||
|
|
||||||
std::map< uint8_t, StatusEffect::StatusEffectPtr >::iterator removeStatusEffect( uint8_t effectSlotId, bool sendOrder = true );
|
std::map< uint8_t, StatusEffect::StatusEffectPtr >::iterator removeStatusEffect( uint8_t effectSlotId, bool updateStatus = true );
|
||||||
|
|
||||||
|
void replaceSingleStatusEffect( uint32_t slotId, StatusEffect::StatusEffectPtr pStatus );
|
||||||
|
|
||||||
void replaceSingleStatusEffectById( uint32_t id );
|
void replaceSingleStatusEffectById( uint32_t id );
|
||||||
|
|
||||||
|
|
|
@ -147,14 +147,17 @@ void Sapphire::StatusEffect::StatusEffect::applyStatus()
|
||||||
m_startTime = Util::getTimeMs();
|
m_startTime = Util::getTimeMs();
|
||||||
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
auto& scriptMgr = Common::Service< Scripting::ScriptMgr >::ref();
|
||||||
|
|
||||||
for( const auto& mod : m_statusModifiers )
|
if( m_modifiers.empty() )
|
||||||
{
|
{
|
||||||
if( mod.modifier != Common::ParamModifier::TickDamage && mod.modifier != Common::ParamModifier::TickHeal )
|
for( const auto& mod : m_statusModifiers )
|
||||||
setModifier( mod.modifier, mod.value );
|
{
|
||||||
else if( mod.modifier == Common::ParamModifier::TickDamage )
|
if( mod.modifier != Common::ParamModifier::TickDamage && mod.modifier != Common::ParamModifier::TickHeal )
|
||||||
registerTickEffect( mod.modifier, mod.value );
|
setModifier( mod.modifier, mod.value );
|
||||||
else if( mod.modifier == Common::ParamModifier::TickHeal )
|
else if( mod.modifier == Common::ParamModifier::TickDamage )
|
||||||
registerTickEffect( mod.modifier, mod.value );
|
registerTickEffect( mod.modifier, mod.value );
|
||||||
|
else if( mod.modifier == Common::ParamModifier::TickHeal )
|
||||||
|
registerTickEffect( mod.modifier, mod.value );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_targetActor->calculateStats();
|
m_targetActor->calculateStats();
|
||||||
|
@ -237,3 +240,14 @@ void Sapphire::StatusEffect::StatusEffect::setSlot( uint8_t slot )
|
||||||
{
|
{
|
||||||
m_slot = slot;
|
m_slot = slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Sapphire::StatusEffect::StatusEffect::refresh()
|
||||||
|
{
|
||||||
|
applyStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sapphire::StatusEffect::StatusEffect::refresh( uint32_t newDuration )
|
||||||
|
{
|
||||||
|
m_duration = newDuration;
|
||||||
|
refresh();
|
||||||
|
}
|
|
@ -67,6 +67,8 @@ public:
|
||||||
uint8_t getSlot() const;
|
uint8_t getSlot() const;
|
||||||
void setSlot( uint8_t slot );
|
void setSlot( uint8_t slot );
|
||||||
|
|
||||||
|
void refresh( uint32_t newDuration );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t m_id;
|
uint32_t m_id;
|
||||||
Entity::CharaPtr m_sourceActor;
|
Entity::CharaPtr m_sourceActor;
|
||||||
|
@ -83,6 +85,7 @@ private:
|
||||||
std::unordered_map< Common::ParamModifier, int32_t > m_modifiers;
|
std::unordered_map< Common::ParamModifier, int32_t > m_modifiers;
|
||||||
uint8_t m_slot;
|
uint8_t m_slot;
|
||||||
|
|
||||||
|
void refresh();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue