1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-24 13:47:46 +00:00

remove most code related to the old action implementation

This commit is contained in:
NotAdam 2019-02-08 21:18:01 +11:00
parent c12348a52e
commit a90dfca45f
20 changed files with 56 additions and 1013 deletions

View file

@ -1,143 +0,0 @@
#include <Util/Util.h>
#include <Util/UtilMath.h>
#include <Exd/ExdDataGenerated.h>
#include "ActionCollision.h"
#include "Actor/Actor.h"
#include "Actor/Chara.h"
#include "Actor/Player.h"
#include <cmath>
#include <cassert>
using namespace Sapphire::Entity;
using namespace Sapphire::Common;
// todo: add AoE actor limits (16, 32)
bool ActionCollision::isActorApplicable( Actor& actor, TargetFilter targetFilter )
{
bool actorApplicable = false;
switch( targetFilter )
{
case TargetFilter::All:
{
actorApplicable = true;
break;
}
case TargetFilter::Players:
{
actorApplicable = actor.isPlayer();
break;
}
case TargetFilter::Allies:
{
// todo: implement ally NPCs
// actorApplicable = !chara.isBattleNpc();
break;
}
case TargetFilter::Party:
{
// todo: implement party
actorApplicable = actor.isPlayer();
break;
}
case TargetFilter::Enemies:
{
//actorApplicable = chara.isBattleNpc();
break;
}
}
return ( actorApplicable && actor.getAsChara()->isAlive() );
}
std::set< Sapphire::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition,
std::set< ActorPtr > actorsInRange,
std::shared_ptr< Sapphire::Data::Action > actionInfo,
TargetFilter targetFilter )
{
std::set< ActorPtr > actorsCollided;
switch( static_cast< ActionCollisionType >( actionInfo->castType ) )
{
case ActionCollisionType::None:
case ActionCollisionType::SingleTarget:
{
// This is actually needed. There is "splash damage" in actions marked as single target.
// Notice how we're using aoe_width. How collision works for SingleTarget is unknown as of now.
for( auto pActor : actorsInRange )
{
// Make sure actor exists. If it doesn't we done goofed.
assert( pActor );
// Don't bother wasting on collision if actor doesn't apply for it
if( !isActorApplicable( *pActor, targetFilter ) )
continue;
// Test our collision from actor with the area generated by the action from the AoE data
if( radiusCollision( pActor->getPos(), aoePosition, actionInfo->effectRange ) )
{
// Add it to the actors collided with the area
actorsCollided.insert( pActor );
}
}
break;
}
case ActionCollisionType::Circle:
{
for( auto pActor : actorsInRange )
{
assert( pActor );
if( !isActorApplicable( *pActor, targetFilter ) )
continue;
if( radiusCollision( pActor->getPos(), aoePosition, actionInfo->effectRange ) )
actorsCollided.insert( pActor );
}
break;
}
case ActionCollisionType::Box:
{
for( auto pActor : actorsInRange )
{
assert( pActor );
if( !isActorApplicable( *pActor, targetFilter ) )
continue;
if( boxCollision( pActor->getPos(), aoePosition, actionInfo->xAxisModifier, actionInfo->effectRange ) )
{
// todo: does this actually work?
actorsCollided.insert( pActor );
}
}
break;
}
default:
{
break;
}
}
return actorsCollided;
}
bool
ActionCollision::radiusCollision( FFXIVARR_POSITION3 actorPosition, FFXIVARR_POSITION3 aoePosition, uint16_t radius )
{
return Sapphire::Util::distance( actorPosition.x, actorPosition.y, actorPosition.z,
aoePosition.x, aoePosition.y, aoePosition.z ) <= radius;
}
bool ActionCollision::boxCollision( FFXIVARR_POSITION3 actorPosition, FFXIVARR_POSITION3 aoePosition, uint16_t width,
uint16_t height )
{
return actorPosition.x < aoePosition.x + width &&
actorPosition.x > aoePosition.x &&
actorPosition.y < aoePosition.y + height &&
actorPosition.y > aoePosition.y;
}

View file

@ -1,46 +0,0 @@
#ifndef _ACTIONCOLLISION_H
#define _ACTIONCOLLISION_H
#include <Common.h>
#include "ForwardsZone.h"
namespace Sapphire::Data
{
struct Action;
}
namespace Sapphire::Entity
{
enum class TargetFilter
{
All, // All actors in the AoE are applicable for collision
Players, // Only players
Allies, // Only allies (players, ally NPCs)
Party, // Only party members
Enemies // Only enemies
};
class ActionCollision
{
public:
static bool isActorApplicable( Actor& actor, TargetFilter targetFilter );
static std::set< ActorPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition,
std::set< ActorPtr > actorsInRange,
std::shared_ptr< Data::Action > actionInfo,
TargetFilter targetFilter );
private:
static bool radiusCollision( Common::FFXIVARR_POSITION3 actorPosition, Common::FFXIVARR_POSITION3 aoePosition,
uint16_t radius );
static bool boxCollision( Common::FFXIVARR_POSITION3 actorPosition, Common::FFXIVARR_POSITION3 aoePosition,
uint16_t width, uint16_t height );
};
}
#endif

View file

@ -1,107 +0,0 @@
#include <Common.h>
#include <Util/Util.h>
#include <Util/UtilMath.h>
#include <Logging/Logger.h>
#include <Network/CommonActorControl.h>
#include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/ActorControlPacket143.h"
#include "Network/PacketWrappers/ActorControlPacket144.h"
#include "Network/PacketWrappers/EffectPacket.h"
#include "Actor/Player.h"
#include "Script/ScriptMgr.h"
#include "ActionMount.h"
#include "Framework.h"
using namespace Sapphire::Common;
using namespace Sapphire::Network;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::Server;
using namespace Sapphire::Network::ActorControl;
extern Sapphire::Framework g_framework;
Sapphire::Action::ActionMount::ActionMount()
{
m_handleActionType = HandleActionType::Event;
}
Sapphire::Action::ActionMount::ActionMount( Entity::CharaPtr pActor, uint16_t mountId )
{
m_startTime = 0;
m_id = mountId;
m_handleActionType = HandleActionType::Spell;
m_castTime = 1000;
m_pSource = pActor;
m_bInterrupt = false;
}
Sapphire::Action::ActionMount::~ActionMount()
{
}
void Sapphire::Action::ActionMount::onStart()
{
if( !m_pSource )
return;
m_pSource->getAsPlayer()->sendDebug( "ActionMount::onStart()" );
m_startTime = Util::getTimeMs();
auto castPacket = makeZonePacket< FFXIVIpcActorCast >( getId() );
castPacket->data().action_id = m_id;
castPacket->data().skillType = Common::SkillType::MountSkill;
castPacket->data().unknown_1 = m_id;
// This is used for the cast bar above the target bar of the caster.
castPacket->data().cast_time = static_cast< float >( m_castTime / 1000 );
castPacket->data().target_id = m_pSource->getAsPlayer()->getId();
m_pSource->sendToInRangeSet( castPacket, true );
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting );
}
void Sapphire::Action::ActionMount::onFinish()
{
if( !m_pSource )
return;
auto pPlayer = m_pSource->getAsPlayer();
pPlayer->sendDebug( "ActionMount::onFinish()" );
pPlayer->unsetStateFlag( PlayerStateFlag::Casting );
auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), pPlayer->getId(), 4 );
effectPacket->setRotation( Util::floatToUInt16Rot( pPlayer->getRot() ) );
Server::EffectEntry effectEntry{};
effectEntry.effectType = ActionEffectType::Mount;
effectEntry.hitSeverity = ActionHitSeverityType::CritDamage;
effectEntry.value = m_id;
effectPacket->addEffect( effectEntry );
pPlayer->sendToInRangeSet( effectPacket, true );
pPlayer->mount( m_id );
}
void Sapphire::Action::ActionMount::onInterrupt()
{
if( !m_pSource )
return;
//m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 );
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting );
auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 1, m_id, 0 );
// Note: When cast interrupt from taking too much damage, set the last value to 1. This enables the cast interrupt effect. Example:
// auto control = ActorControlPacket142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 1, m_id, 0 );
m_pSource->sendToInRangeSet( control, true );
}

View file

@ -1,31 +0,0 @@
#ifndef _ACTIONMOUNT_H_
#define _ACTIONMOUNT_H_
#include "ForwardsZone.h"
#include "Action.h"
namespace Sapphire::Action
{
class ActionMount : public Action
{
private:
public:
ActionMount();
~ActionMount();
ActionMount( Entity::CharaPtr pActor, uint16_t mountId );
void onStart() override;
void onFinish() override;
void onInterrupt() override;
};
}
#endif

View file

@ -1,105 +0,0 @@
#include <Util/Util.h>
#include <Exd/ExdDataGenerated.h>
#include <Logging/Logger.h>
#include <Network/CommonActorControl.h>
#include <Util/UtilMath.h>
#include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/ActorControlPacket143.h"
#include "Network/PacketWrappers/EffectPacket.h"
#include "Actor/Player.h"
#include "ActionTeleport.h"
#include "Framework.h"
using namespace Sapphire::Common;
using namespace Sapphire::Network;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::Server;
using namespace Sapphire::Network::ActorControl;
Sapphire::Action::ActionTeleport::ActionTeleport()
{
m_handleActionType = HandleActionType::Event;
}
Sapphire::Action::ActionTeleport::ActionTeleport( Entity::CharaPtr pActor, uint16_t targetZone, uint16_t cost, FrameworkPtr pFw )
{
auto pExdData = pFw->get< Data::ExdDataGenerated >();
m_startTime = 0;
m_id = 5;
m_handleActionType = HandleActionType::Teleport;
m_castTime = pExdData->get< Sapphire::Data::Action >( 5 )->cast100ms * 100; // TODO: Add security checks.
m_pSource = pActor;
m_bInterrupt = false;
m_targetAetheryte = targetZone;
m_cost = cost;
}
Sapphire::Action::ActionTeleport::~ActionTeleport()
{
}
void Sapphire::Action::ActionTeleport::onStart()
{
if( !m_pSource )
return;
m_startTime = Util::getTimeMs();
auto castPacket = makeZonePacket< FFXIVIpcActorCast >( getId() );
castPacket->data().action_id = 5;
castPacket->data().unknown = 1;
castPacket->data().cast_time = 5.0f;
castPacket->data().target_id = m_pSource->getId();
m_pSource->sendToInRangeSet( castPacket, true );
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting );
}
void Sapphire::Action::ActionTeleport::onFinish()
{
if( !m_pSource )
return;
auto pPlayer = m_pSource->getAsPlayer();
// check we can finish teleporting
if( pPlayer->getCurrency( Common::CurrencyType::Gil ) < m_cost )
{
onInterrupt();
return;
}
pPlayer->removeCurrency( Common::CurrencyType::Gil, m_cost );
pPlayer->unsetStateFlag( PlayerStateFlag::Casting );
// TODO: not sure if this ever gets sent
//auto control = makeActorControl142( m_pSource->getId(), Common::ActorControlType::TeleportDone );
//m_pSource->sendToInRangeSet( control, false );
pPlayer->setZoningType( ZoneingType::Teleport );
auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), pPlayer->getId(), 5 );
effectPacket->setRotation( Util::floatToUInt16Rot( pPlayer->getRot() ) );
pPlayer->sendToInRangeSet( effectPacket, true );
pPlayer->teleport( m_targetAetheryte );
}
void Sapphire::Action::ActionTeleport::onInterrupt()
{
if( !m_pSource )
return;
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting );
auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 0x04, m_id, 0 );
m_pSource->sendToInRangeSet( control, true );
}

View file

@ -1,33 +0,0 @@
#ifndef _ACTIONTELEPORT_H_
#define _ACTIONTELEPORT_H_
#include "ForwardsZone.h"
#include "Action.h"
namespace Sapphire::Action
{
class ActionTeleport : public Action
{
private:
uint16_t m_targetAetheryte;
uint16_t m_cost;
public:
ActionTeleport();
~ActionTeleport();
ActionTeleport( Entity::CharaPtr pActor, uint16_t action, uint16_t cost, FrameworkPtr pFw );
void onStart() override;
void onFinish() override;
void onInterrupt() override;
};
}
#endif

View file

@ -1,138 +0,0 @@
#include <Util/Util.h>
#include <Logging/Logger.h>
#include <Exd/ExdDataGenerated.h>
#include <Network/CommonActorControl.h>
#include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/ActorControlPacket143.h"
#include "Actor/Player.h"
#include "EventAction.h"
#include "Framework.h"
using namespace Sapphire::Common;
using namespace Sapphire::Network;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::Server;
using namespace Sapphire::Network::ActorControl;
Sapphire::Action::EventAction::EventAction()
{
m_handleActionType = HandleActionType::Event;
}
Sapphire::Action::EventAction::EventAction( Entity::CharaPtr pActor, uint32_t eventId, uint16_t action,
ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional,
FrameworkPtr pFw )
{
m_additional = additional;
m_handleActionType = HandleActionType::Event;
m_eventId = eventId;
m_id = action;
m_pFw = pFw;
auto pExdData = pFw->get< Data::ExdDataGenerated >();
m_castTime = pExdData->get< Sapphire::Data::EventAction >( action )->castTime * 1000; // TODO: Add security checks.
m_onActionFinishClb = finishRef;
m_onActionInterruptClb = interruptRef;
m_pSource = pActor;
m_bInterrupt = false;
}
Sapphire::Action::EventAction::~EventAction()
{
}
void Sapphire::Action::EventAction::onStart()
{
if( !m_pSource )
return;
m_startTime = Util::getTimeMs();
auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastStart, 1, m_id, 0x4000004E );
if( m_pSource->isPlayer() )
{
m_pSource->sendToInRangeSet( control, true );
if( m_pSource->getAsPlayer()->hasStateFlag( PlayerStateFlag::InNpcEvent ) )
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::InNpcEvent );
}
else
m_pSource->sendToInRangeSet( control );
}
void Sapphire::Action::EventAction::onFinish()
{
if( !m_pSource )
return;
try
{
auto pEvent = m_pSource->getAsPlayer()->getEvent( m_eventId );
pEvent->setPlayedScene( false );
if( m_onActionFinishClb )
m_onActionFinishClb( *m_pSource->getAsPlayer(), m_eventId, m_additional );
auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastStart, 0, m_id );
if( !pEvent->hasPlayedScene() )
m_pSource->getAsPlayer()->eventFinish( m_eventId, 1 );
else
pEvent->setPlayedScene( false );
if( m_pSource->isPlayer() )
{
//m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied2 );
m_pSource->sendToInRangeSet( control, true );
}
else
m_pSource->sendToInRangeSet( control );
}
catch( std::exception& e )
{
Logger::error( e.what() );
}
}
void Sapphire::Action::EventAction::onInterrupt()
{
if( !m_pSource )
return;
try
{
auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 0x04, m_id );
if( m_pSource->isPlayer() )
{
auto control1 = makeActorControl143( m_pSource->getId(), ActorControlType::FreeEventPos, m_eventId );
//m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::NoCombat );
//m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Occupied1 );
m_pSource->sendToInRangeSet( control );
m_pSource->sendToInRangeSet( control1 );
m_pSource->getAsPlayer()->queuePacket( control1 );
m_pSource->getAsPlayer()->queuePacket( control );
m_pSource->getAsPlayer()->eventFinish( m_eventId, 1 );
}
else
m_pSource->sendToInRangeSet( control );
if( m_onActionInterruptClb )
m_onActionInterruptClb( *m_pSource->getAsPlayer(), m_eventId, m_additional );
}
catch( std::exception& e )
{
Logger::error( e.what() );
}
}

View file

@ -1,40 +0,0 @@
#ifndef _EVENTACTION_H_
#define _EVENTACTION_H_
#include <Common.h>
#include "ForwardsZone.h"
#include "Action.h"
namespace Sapphire::Action
{
class EventAction : public Action
{
public:
EventAction();
~EventAction();
EventAction( Entity::CharaPtr pActor, uint32_t eventId, uint16_t action,
ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional, FrameworkPtr pFw );
void onStart() override;
void onFinish() override;
void onInterrupt() override;
private:
uint32_t m_eventId;
uint64_t m_additional;
ActionCallback m_onActionFinishClb;
ActionCallback m_onActionInterruptClb;
};
}
#endif

View file

@ -1,115 +0,0 @@
#include <string.h>
#include <Util/Util.h>
#include <Util/UtilMath.h>
#include <Logging/Logger.h>
#include <Network/CommonActorControl.h>
#include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/ActorControlPacket143.h"
#include "Network/PacketWrappers/EffectPacket.h"
#include "Actor/Player.h"
#include "EventItemAction.h"
#include "Framework.h"
using namespace Sapphire::Common;
using namespace Sapphire::Network;
using namespace Sapphire::Network::Packets;
using namespace Sapphire::Network::Packets::Server;
using namespace Sapphire::Network::ActorControl;
Sapphire::Action::EventItemAction::EventItemAction()
{
m_handleActionType = HandleActionType::Event;
}
Sapphire::Action::EventItemAction::EventItemAction( Entity::CharaPtr pActor, uint32_t eventId, uint16_t action,
ActionCallback finishRef, ActionCallback interruptRef,
uint64_t additional )
{
m_additional = additional;
m_handleActionType = HandleActionType::Event;
m_eventId = eventId;
m_id = action;
// TODO: read the cast time from the action itself
m_castTime = 3000;
m_onActionFinishClb = finishRef;
m_onActionInterruptClb = interruptRef;
m_pSource = pActor;
m_bInterrupt = false;
}
Sapphire::Action::EventItemAction::~EventItemAction() = default;
void Sapphire::Action::EventItemAction::onStart()
{
if( !m_pSource )
return;
m_startTime = Util::getTimeMs();
auto castPacket = makeZonePacket< FFXIVIpcActorCast >( m_pSource->getId() );
castPacket->data().action_id = 1;
castPacket->data().unknown = 3;
castPacket->data().unknown_1 = m_id;
castPacket->data().cast_time = 3.0f;
castPacket->data().target_id = m_pSource->getId();
m_pSource->sendToInRangeSet( castPacket, true );
m_pSource->getAsPlayer()->setStateFlag( PlayerStateFlag::Casting );
}
void Sapphire::Action::EventItemAction::onFinish()
{
if( !m_pSource )
return;
try
{
auto effectPacket = std::make_shared< Server::EffectPacket >( m_pSource->getId(), m_additional, m_id );
effectPacket->setAnimationId( 1 );
effectPacket->setRotation( Util::floatToUInt16Rot( m_pSource->getRot() ) );
m_pSource->getAsPlayer()->unsetStateFlag( Common::PlayerStateFlag::Casting );
m_pSource->sendToInRangeSet( effectPacket, true );
if( m_onActionFinishClb )
m_onActionFinishClb( *m_pSource->getAsPlayer(), m_eventId, m_additional );
}
catch( std::exception& e )
{
Logger::error( e.what() );
}
}
void Sapphire::Action::EventItemAction::onInterrupt()
{
if( !m_pSource )
return;
try
{
auto control = makeActorControl142( m_pSource->getId(), ActorControlType::CastInterrupt, 0x219, 0x04, m_id );
if( m_pSource->isPlayer() )
{
m_pSource->getAsPlayer()->unsetStateFlag( PlayerStateFlag::Casting );
m_pSource->sendToInRangeSet( control, true );
}
else
m_pSource->sendToInRangeSet( control );
if( m_onActionInterruptClb )
m_onActionInterruptClb( *m_pSource->getAsPlayer(), m_eventId, m_additional );
}
catch( std::exception& e )
{
Logger::error( e.what() );
}
}

View file

@ -1,38 +0,0 @@
#ifndef _EVENTITEMACTION_H_
#define _EVENTITEMACTION_H_
#include "ForwardsZone.h"
#include "Action.h"
namespace Sapphire::Action
{
class EventItemAction : public Action
{
public:
EventItemAction();
~EventItemAction();
EventItemAction( Entity::CharaPtr pActor, uint32_t eventId, uint16_t action,
ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional );
void onStart() override;
void onFinish() override;
void onInterrupt() override;
private:
uint32_t m_eventId;
uint64_t m_additional;
ActionCallback m_onActionFinishClb;
ActionCallback m_onActionInterruptClb;
};
}
#endif

View file

@ -6,9 +6,6 @@
#include <Util/UtilMath.h>
#include <utility>
#include "Action/Action.h"
#include "Action/ActionCollision.h"
#include "Territory/Zone.h"
#include "Network/GameConnection.h"

View file

@ -23,7 +23,6 @@
#include "Navi/NaviProvider.h"
#include "StatusEffect/StatusEffect.h"
#include "Action/ActionCollision.h"
#include "ServerMgr.h"
#include "Session.h"
#include "Math/CalcBattle.h"

View file

@ -7,7 +7,6 @@
#include "Forwards.h"
#include "Action/Action.h"
#include "Territory/Zone.h"
@ -19,7 +18,7 @@
#include "Network/PacketWrappers/EffectPacket.h"
#include "StatusEffect/StatusEffect.h"
#include "Action/ActionCollision.h"
#include "Action/Action.h"
#include "ServerMgr.h"
#include "Session.h"
#include "Math/CalcBattle.h"
@ -431,145 +430,6 @@ void Sapphire::Entity::Chara::autoAttack( CharaPtr pTarget )
}
}
/*!
Skill Handler.
\param GamePacketPtr to send
\param bool should be send to self?
*/
void Sapphire::Entity::Chara::handleScriptSkill( uint32_t type, uint16_t actionId, uint64_t param1,
uint64_t param2, Entity::Chara& target )
{
auto pExdData = m_pFw->get< Data::ExdDataGenerated >();
if( isPlayer() )
{
getAsPlayer()->sendDebug( "{0}", target.getId() );
getAsPlayer()->sendDebug( "Handle script skill type: {0}", type );
}
auto actionInfoPtr = pExdData->get< Sapphire::Data::Action >( actionId );
// Todo: Effect packet generator. 90% of this is basically setting params and it's basically unreadable.
// Prepare packet. This is seemingly common for all packets in the action handler.
auto effectPacket = std::make_shared< Server::EffectPacket >( getId(), target.getId(), actionId );
effectPacket->setRotation( Util::floatToUInt16Rot( getRot() ) );
// Todo: for each actor, calculate how much damage the calculated value should deal to them - 2-step damage calc. we only have 1-step
switch( type )
{
case ActionEffectType::Damage:
{
Server::EffectEntry effectEntry{};
effectEntry.value = static_cast< uint16_t >( param1 );
effectEntry.effectType = ActionEffectType::Damage;
effectEntry.hitSeverity = ActionHitSeverityType::NormalDamage;
effectPacket->addEffect( effectEntry );
if( ( actionInfoPtr->castType == 1 && actionInfoPtr->effectRange != 0 ) ||
( actionInfoPtr->castType != 1 ) )
{
// If action on this specific target is valid...
if( isPlayer() && !ActionCollision::isActorApplicable( target, TargetFilter::Enemies ) )
break;
sendToInRangeSet( effectPacket, true );
if( target.isAlive() )
target.onActionHostile( getAsChara() );
target.takeDamage( static_cast< uint32_t >( param1 ) );
}
else
{
auto actorsCollided = ActionCollision::getActorsHitFromAction( target.getPos(), getInRangeActors( true ),
actionInfoPtr, TargetFilter::Enemies );
for( const auto& pHitActor : actorsCollided )
{
effectPacket->setTargetActor( pHitActor->getId() );
// todo: send to range of what? ourselves? when mob script hits this is going to be lacking
sendToInRangeSet( effectPacket, true );
if( pHitActor->getAsChara()->isAlive() )
pHitActor->getAsChara()->onActionHostile( getAsChara() );
pHitActor->getAsChara()->takeDamage( static_cast< uint32_t >( param1 ) );
// Debug
if( isPlayer() )
{
if( pHitActor->isPlayer() )
getAsPlayer()->sendDebug( "AoE hit actor#{0} ({1})", pHitActor->getId(), pHitActor->getAsChara()->getName() );
else
getAsPlayer()->sendDebug( "AoE hit actor#{0}", pHitActor->getId() );
}
}
}
break;
}
case ActionEffectType::Heal:
{
uint32_t calculatedHeal = Math::CalcBattle::calculateHealValue( getAsPlayer(),
static_cast< uint32_t >( param1 ),
m_pFw );
Server::EffectEntry effectEntry{};
effectEntry.value = calculatedHeal;
effectEntry.effectType = ActionEffectType::Heal;
effectEntry.hitSeverity = ActionHitSeverityType::NormalHeal;
effectPacket->addEffect( effectEntry );
if( ( actionInfoPtr->castType == 1 && actionInfoPtr->effectRange != 0 ) || actionInfoPtr->castType != 1 )
{
if( isPlayer() && !ActionCollision::isActorApplicable( target, TargetFilter::Allies ) )
break;
sendToInRangeSet( effectPacket, true );
target.heal( calculatedHeal );
}
else
{
// todo: get proper packets: the following was just kind of thrown together from what we know.
// atm buggy (packets look "delayed" from client)
auto actorsCollided = ActionCollision::getActorsHitFromAction( target.getPos(), getInRangeActors( true ),
actionInfoPtr, TargetFilter::Allies );
for( const auto& pHitActor : actorsCollided )
{
effectPacket->setTargetActor( pHitActor->getId() );
sendToInRangeSet( effectPacket, true );
pHitActor->getAsChara()->heal( calculatedHeal );
// Debug
if( isPlayer() )
{
if( pHitActor->isPlayer() )
getAsPlayer()->sendDebug( "AoE hit actor#{0} ({1})", pHitActor->getId(), pHitActor->getAsChara()->getName() );
else
getAsPlayer()->sendDebug( "AoE hit actor#{0}", pHitActor->getId() );
}
}
}
break;
}
default:
break;
}
}
/*! \param StatusEffectPtr to be applied to the actor */
void Sapphire::Entity::Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEffect )
{

View file

@ -212,9 +212,6 @@ namespace Sapphire::Entity
void setStatus( Common::ActorStatus status );
void
handleScriptSkill( uint32_t type, uint16_t actionId, uint64_t param1, uint64_t param2, Entity::Chara& target );
virtual void autoAttack( CharaPtr pTarget );
virtual void onDeath() {};

View file

@ -18,8 +18,6 @@
#include "Network/PacketWrappers/UpdateHpMpTpPacket.h"
#include "Network/PacketWrappers/EffectPacket.h"
#include "StatusEffect/StatusEffect.h"
#include "Action/ActionCollision.h"
#include "ServerMgr.h"
#include "Session.h"
#include "Math/CalcBattle.h"

View file

@ -34,11 +34,6 @@
#include "Script/ScriptMgr.h"
#include "Action/Action.h"
#include "Action/ActionTeleport.h"
#include "Action/EventAction.h"
#include "Action/EventItemAction.h"
#include "Math/CalcStats.h"
#include "Math/CalcBattle.h"
@ -1835,34 +1830,34 @@ void Sapphire::Entity::Player::emoteInterrupt()
void Sapphire::Entity::Player::teleportQuery( uint16_t aetheryteId, FrameworkPtr pFw )
{
auto pExdData = pFw->get< Data::ExdDataGenerated >();
// TODO: only register this action if enough gil is in possession
auto targetAetheryte = pExdData->get< Sapphire::Data::Aetheryte >( aetheryteId );
if( targetAetheryte )
{
auto fromAetheryte = pExdData->get< Sapphire::Data::Aetheryte >(
pExdData->get< Sapphire::Data::TerritoryType >( getZoneId() )->aetheryte );
// calculate cost - does not apply for favorite points or homepoints neither checks for aether tickets
auto cost = static_cast< uint16_t > (
( std::sqrt( std::pow( fromAetheryte->aetherstreamX - targetAetheryte->aetherstreamX, 2 ) +
std::pow( fromAetheryte->aetherstreamY - targetAetheryte->aetherstreamY, 2 ) ) / 2 ) + 100 );
// cap at 999 gil
cost = cost > uint16_t{ 999 } ? uint16_t{ 999 } : cost;
bool insufficientGil = getCurrency( Common::CurrencyType::Gil ) < cost;
// TODO: figure out what param1 really does
queuePacket( makeActorControl143( getId(), TeleportStart, insufficientGil ? 2 : 0, aetheryteId ) );
if( !insufficientGil )
{
Action::ActionPtr pActionTeleport;
pActionTeleport = Action::make_ActionTeleport( getAsPlayer(), aetheryteId, cost, pFw );
setCurrentAction( pActionTeleport );
}
}
// auto pExdData = pFw->get< Data::ExdDataGenerated >();
// // TODO: only register this action if enough gil is in possession
// auto targetAetheryte = pExdData->get< Sapphire::Data::Aetheryte >( aetheryteId );
//
// if( targetAetheryte )
// {
// auto fromAetheryte = pExdData->get< Sapphire::Data::Aetheryte >(
// pExdData->get< Sapphire::Data::TerritoryType >( getZoneId() )->aetheryte );
//
// // calculate cost - does not apply for favorite points or homepoints neither checks for aether tickets
// auto cost = static_cast< uint16_t > (
// ( std::sqrt( std::pow( fromAetheryte->aetherstreamX - targetAetheryte->aetherstreamX, 2 ) +
// std::pow( fromAetheryte->aetherstreamY - targetAetheryte->aetherstreamY, 2 ) ) / 2 ) + 100 );
//
// // cap at 999 gil
// cost = cost > uint16_t{ 999 } ? uint16_t{ 999 } : cost;
//
// bool insufficientGil = getCurrency( Common::CurrencyType::Gil ) < cost;
// // TODO: figure out what param1 really does
// queuePacket( makeActorControl143( getId(), TeleportStart, insufficientGil ? 2 : 0, aetheryteId ) );
//
// if( !insufficientGil )
// {
// Action::ActionPtr pActionTeleport;
// pActionTeleport = Action::make_ActionTeleport( getAsPlayer(), aetheryteId, cost, pFw );
// setCurrentAction( pActionTeleport );
// }
// }
}
uint8_t Sapphire::Entity::Player::getNextObjSpawnIndexForActorId( uint32_t actorId )

View file

@ -11,9 +11,6 @@
#include "Network/PacketWrappers/EventFinishPacket.h"
#include "Network/PacketWrappers/DirectorPlayScenePacket.h"
#include "Action/EventAction.h"
#include "Action/EventItemAction.h"
#include "Territory/Zone.h"
#include "ServerMgr.h"
#include "Framework.h"
@ -283,27 +280,27 @@ void Sapphire::Entity::Player::eventActionStart( uint32_t eventId,
ActionCallback interruptCallback,
uint64_t additional )
{
auto pEventAction = Action::make_EventAction( getAsChara(), eventId, action,
finishCallback, interruptCallback, additional, m_pFw );
setCurrentAction( pEventAction );
auto pEvent = getEvent( eventId );
if( !pEvent && getEventCount() )
{
// We're trying to play a nested event, need to start it first.
eventStart( getId(), eventId, Event::EventHandler::Nest, 0, 0 );
pEvent = getEvent( eventId );
}
else if( !pEvent )
{
Logger::error( "Could not find event #{0}, event has not been started!", eventId );
return;
}
if( pEvent )
pEvent->setPlayedScene( true );
pEventAction->onStart();
// auto pEventAction = Action::make_EventAction( getAsChara(), eventId, action,
// finishCallback, interruptCallback, additional, m_pFw );
//
// setCurrentAction( pEventAction );
// auto pEvent = getEvent( eventId );
//
// if( !pEvent && getEventCount() )
// {
// // We're trying to play a nested event, need to start it first.
// eventStart( getId(), eventId, Event::EventHandler::Nest, 0, 0 );
// pEvent = getEvent( eventId );
// }
// else if( !pEvent )
// {
// Logger::error( "Could not find event #{0}, event has not been started!", eventId );
// return;
// }
//
// if( pEvent )
// pEvent->setPlayedScene( true );
// pEventAction->onStart();
}
@ -313,12 +310,12 @@ void Sapphire::Entity::Player::eventItemActionStart( uint32_t eventId,
ActionCallback interruptCallback,
uint64_t additional )
{
Action::ActionPtr pEventItemAction = Action::make_EventItemAction( getAsChara(), eventId, action,
finishCallback, interruptCallback, additional );
setCurrentAction( pEventItemAction );
pEventItemAction->onStart();
// Action::ActionPtr pEventItemAction = Action::make_EventItemAction( getAsChara(), eventId, action,
// finishCallback, interruptCallback, additional );
//
// setCurrentAction( pEventItemAction );
//
// pEventItemAction->onStart();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

View file

@ -22,8 +22,6 @@
#include "Action/Action.h"
#include "Action/ActionCast.h"
#include "Action/ActionMount.h"
#include "Script/ScriptMgr.h"
#include "Session.h"

View file

@ -26,7 +26,6 @@
#include "Manager/EventMgr.h"
#include "Action/Action.h"
#include "Action/ActionTeleport.h"
#include "Session.h"

View file

@ -41,7 +41,6 @@
#include "Manager/RNGMgr.h"
#include "Action/Action.h"
#include "Action/ActionTeleport.h"
#include "Session.h"
#include "ServerMgr.h"