mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-05-28 20:27:46 +00:00
some aoe fixes
This commit is contained in:
parent
64f8be4512
commit
03df9ab4d5
3 changed files with 53 additions and 21 deletions
|
@ -1,5 +1,4 @@
|
||||||
#include "Action.h"
|
#include "Action.h"
|
||||||
#include "ActionLut.h"
|
|
||||||
#include "EffectBuilder.h"
|
#include "EffectBuilder.h"
|
||||||
|
|
||||||
#include <Inventory/Item.h>
|
#include <Inventory/Item.h>
|
||||||
|
@ -127,6 +126,15 @@ bool Action::Action::init()
|
||||||
|
|
||||||
// todo: add missing rows for secondaryCostType/secondaryCostType and rename the current rows to primaryCostX
|
// todo: add missing rows for secondaryCostType/secondaryCostType and rename the current rows to primaryCostX
|
||||||
|
|
||||||
|
if( ActionLut::validEntryExists( static_cast< uint16_t >( getId() ) ) )
|
||||||
|
{
|
||||||
|
m_lutEntry = ActionLut::getEntry( static_cast< uint16_t >( getId() ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::memset( &m_lutEntry, 0, sizeof( ActionEntry ) );
|
||||||
|
}
|
||||||
|
|
||||||
addDefaultActorFilters();
|
addDefaultActorFilters();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -428,7 +436,7 @@ void Action::Action::buildEffects()
|
||||||
snapshotAffectedActors( m_hitActors );
|
snapshotAffectedActors( m_hitActors );
|
||||||
|
|
||||||
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
|
auto pScriptMgr = m_pFw->get< Scripting::ScriptMgr >();
|
||||||
auto hasLutEntry = ActionLut::validEntryExists( static_cast< uint16_t >( getId() ) );
|
auto hasLutEntry = hasValidLutEntry();
|
||||||
|
|
||||||
if( !pScriptMgr->onExecute( *this ) && !hasLutEntry )
|
if( !pScriptMgr->onExecute( *this ) && !hasLutEntry )
|
||||||
{
|
{
|
||||||
|
@ -443,21 +451,19 @@ void Action::Action::buildEffects()
|
||||||
if( !hasLutEntry || m_hitActors.empty() )
|
if( !hasLutEntry || m_hitActors.empty() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
auto lutEntry = ActionLut::getEntry( static_cast< uint16_t >( getId() ) );
|
|
||||||
|
|
||||||
// no script exists but we have a valid lut entry
|
// no script exists but we have a valid lut entry
|
||||||
if( auto player = getSourceChara()->getAsPlayer() )
|
if( auto player = getSourceChara()->getAsPlayer() )
|
||||||
{
|
{
|
||||||
player->sendDebug( "Hit target: pot: {} (c: {}, f: {}, r: {}), heal pot: {}, mpp: {}",
|
player->sendDebug( "Hit target: pot: {} (c: {}, f: {}, r: {}), heal pot: {}, mpp: {}",
|
||||||
lutEntry.potency, lutEntry.comboPotency, lutEntry.flankPotency, lutEntry.rearPotency,
|
m_lutEntry.potency, m_lutEntry.comboPotency, m_lutEntry.flankPotency, m_lutEntry.rearPotency,
|
||||||
lutEntry.curePotency, lutEntry.restoreMPPercentage );
|
m_lutEntry.curePotency, m_lutEntry.restoreMPPercentage );
|
||||||
}
|
}
|
||||||
|
|
||||||
for( auto& actor : m_hitActors )
|
for( auto& actor : m_hitActors )
|
||||||
{
|
{
|
||||||
if( lutEntry.potency > 0 )
|
if( m_lutEntry.potency > 0 )
|
||||||
{
|
{
|
||||||
auto dmg = calcDamage( isCorrectCombo() ? lutEntry.comboPotency : lutEntry.potency );
|
auto dmg = calcDamage( isCorrectCombo() ? m_lutEntry.comboPotency : m_lutEntry.potency );
|
||||||
m_effectBuilder->damageTarget( actor, dmg.first, dmg.second );
|
m_effectBuilder->damageTarget( actor, dmg.first, dmg.second );
|
||||||
|
|
||||||
if( dmg.first > 0 )
|
if( dmg.first > 0 )
|
||||||
|
@ -470,18 +476,18 @@ void Action::Action::buildEffects()
|
||||||
|
|
||||||
if( !isComboAction() || isCorrectCombo() )
|
if( !isComboAction() || isCorrectCombo() )
|
||||||
{
|
{
|
||||||
if( lutEntry.curePotency > 0 ) // actions with self heal
|
if( m_lutEntry.curePotency > 0 ) // actions with self heal
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Calling m_effectBuilder->healTarget( m_pSource, lutEntry.curePotency ) seems to work fine,
|
Calling m_effectBuilder->healTarget( m_pSource, lutEntry.curePotency ) seems to work fine,
|
||||||
but it will end up sending two Effect packets to the client. However on retail everything is in one single packet.
|
but it will end up sending two Effect packets to the client. However on retail everything is in one single packet.
|
||||||
*/
|
*/
|
||||||
m_effectBuilder->selfHeal( actor, m_pSource, lutEntry.curePotency );
|
m_effectBuilder->selfHeal( actor, m_pSource, m_lutEntry.curePotency );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( lutEntry.restoreMPPercentage > 0 )
|
if( m_lutEntry.restoreMPPercentage > 0 )
|
||||||
{
|
{
|
||||||
m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMp() * lutEntry.restoreMPPercentage / 100 );
|
m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMp() * m_lutEntry.restoreMPPercentage / 100 );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !m_actionData->preservesCombo ) // we need something like m_actionData->hasNextComboAction
|
if( !m_actionData->preservesCombo ) // we need something like m_actionData->hasNextComboAction
|
||||||
|
@ -490,20 +496,20 @@ void Action::Action::buildEffects()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( lutEntry.curePotency > 0 )
|
else if( m_lutEntry.curePotency > 0 )
|
||||||
{
|
{
|
||||||
// todo: calcHealing()
|
// todo: calcHealing()
|
||||||
m_effectBuilder->healTarget( actor, lutEntry.curePotency );
|
m_effectBuilder->healTarget( actor, m_lutEntry.curePotency );
|
||||||
|
|
||||||
if( lutEntry.restoreMPPercentage > 0 )
|
if( m_lutEntry.restoreMPPercentage > 0 )
|
||||||
{
|
{
|
||||||
// always restore caster mp I don't think there are any actions that can restore target MP post 5.0
|
// always restore caster mp I don't think there are any actions that can restore target MP post 5.0
|
||||||
m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMp() * lutEntry.restoreMPPercentage / 100 );
|
m_effectBuilder->restoreMP( actor, m_pSource, m_pSource->getMp() * m_lutEntry.restoreMPPercentage / 100 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( lutEntry.restoreMPPercentage > 0 )
|
else if( m_lutEntry.restoreMPPercentage > 0 )
|
||||||
{
|
{
|
||||||
m_effectBuilder->restoreMP( m_pSource, m_pSource, m_pSource->getMp() * lutEntry.restoreMPPercentage / 100 );
|
m_effectBuilder->restoreMP( m_pSource, m_pSource, m_pSource->getMp() * m_lutEntry.restoreMPPercentage / 100 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -737,11 +743,24 @@ void Action::Action::addDefaultActorFilters()
|
||||||
bool Action::Action::preFilterActor( Sapphire::Entity::Actor& actor ) const
|
bool Action::Action::preFilterActor( Sapphire::Entity::Actor& actor ) const
|
||||||
{
|
{
|
||||||
auto kind = actor.getObjKind();
|
auto kind = actor.getObjKind();
|
||||||
|
auto chara = actor.getAsChara();
|
||||||
|
|
||||||
// todo: are there any server side eobjs that players can hit?
|
// todo: are there any server side eobjs that players can hit?
|
||||||
if( kind != ObjKind::BattleNpc && kind != ObjKind::Player )
|
if( kind != ObjKind::BattleNpc && kind != ObjKind::Player )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if( m_lutEntry.potency > 0 && chara == m_pSource )
|
||||||
|
{
|
||||||
|
// damage action shouldn't hit self
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ( m_lutEntry.potency > 0 || m_lutEntry.curePotency > 0 ) && !chara->isAlive() )
|
||||||
|
{
|
||||||
|
// can't deal damage or heal a dead entity
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// todo: handle things such based on canTargetX
|
// todo: handle things such based on canTargetX
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -761,3 +780,9 @@ Sapphire::Entity::CharaPtr Action::Action::getHitChara()
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Action::Action::hasValidLutEntry() const
|
||||||
|
{
|
||||||
|
return m_lutEntry.potency != 0 || m_lutEntry.comboPotency != 0 || m_lutEntry.flankPotency != 0 || m_lutEntry.frontPotency != 0 ||
|
||||||
|
m_lutEntry.rearPotency != 0 || m_lutEntry.curePotency != 0 || m_lutEntry.restoreMPPercentage != 0;
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
#define _ACTION_H_
|
#define _ACTION_H_
|
||||||
|
|
||||||
#include <Common.h>
|
#include <Common.h>
|
||||||
|
#include "ActionLut.h"
|
||||||
#include "Util/ActorFilter.h"
|
#include "Util/ActorFilter.h"
|
||||||
#include "ForwardsZone.h"
|
#include "ForwardsZone.h"
|
||||||
|
|
||||||
|
@ -146,6 +147,8 @@ namespace Sapphire::World::Action
|
||||||
|
|
||||||
bool preFilterActor( Entity::Actor& actor ) const;
|
bool preFilterActor( Entity::Actor& actor ) const;
|
||||||
|
|
||||||
|
bool hasValidLutEntry() const;
|
||||||
|
|
||||||
uint32_t m_id;
|
uint32_t m_id;
|
||||||
|
|
||||||
uint16_t m_sequence;
|
uint16_t m_sequence;
|
||||||
|
@ -186,6 +189,8 @@ namespace Sapphire::World::Action
|
||||||
|
|
||||||
std::vector< World::Util::ActorFilterPtr > m_actorFilters;
|
std::vector< World::Util::ActorFilterPtr > m_actorFilters;
|
||||||
std::vector< Entity::CharaPtr > m_hitActors;
|
std::vector< Entity::CharaPtr > m_hitActors;
|
||||||
|
|
||||||
|
ActionEntry m_lutEntry;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,8 @@ void World::Manager::ActionMgr::handlePlacedPlayerAction( Entity::Player& player
|
||||||
|
|
||||||
auto action = Action::make_Action( player.getAsPlayer(), actionId, sequence, actionData, framework() );
|
auto action = Action::make_Action( player.getAsPlayer(), actionId, sequence, actionData, framework() );
|
||||||
|
|
||||||
|
action->setPos( pos );
|
||||||
|
|
||||||
if( !action->init() )
|
if( !action->init() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -37,8 +39,6 @@ void World::Manager::ActionMgr::handlePlacedPlayerAction( Entity::Player& player
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
action->setPos( pos );
|
|
||||||
|
|
||||||
bootstrapAction( player, action, *actionData );
|
bootstrapAction( player, action, *actionData );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +50,8 @@ void World::Manager::ActionMgr::handleTargetedPlayerAction( Entity::Player& play
|
||||||
|
|
||||||
action->setTargetId( targetId );
|
action->setTargetId( targetId );
|
||||||
|
|
||||||
|
action->setPos( player.getPos() );
|
||||||
|
|
||||||
if( !action->init() )
|
if( !action->init() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue