1
Fork 0
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:
collett 2020-01-04 21:12:54 +09:00
parent 64f8be4512
commit 03df9ab4d5
3 changed files with 53 additions and 21 deletions

View file

@ -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;
@ -235,7 +243,7 @@ bool Action::Action::update()
if( !m_pTarget->isAlive() ) if( !m_pTarget->isAlive() )
{ {
// interrupt the cast if target died // interrupt the cast if target died
setInterrupted( Common::ActionInterruptType::RegularInterrupt ); setInterrupted( Common::ActionInterruptType::RegularInterrupt );
interrupt(); interrupt();
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;
}

View file

@ -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;
}; };
} }

View file

@ -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;