From 6e5737f4015419a0dbcfa72221d3d5df9307ffee Mon Sep 17 00:00:00 2001 From: Mordred Date: Thu, 22 Feb 2018 15:31:10 +0100 Subject: [PATCH] Actors are now used as base for any entity --- src/common/Common.h | 10 - .../Network/PacketDef/Zone/ServerZoneDef.h | 4 +- .../sapphire_zone/Action/ActionCollision.cpp | 15 +- .../sapphire_zone/Action/ActionCollision.h | 6 +- src/servers/sapphire_zone/Actor/Actor.cpp | 174 ++++++++++++++++- src/servers/sapphire_zone/Actor/Actor.h | 32 +++ src/servers/sapphire_zone/Actor/Chara.cpp | 182 ++---------------- src/servers/sapphire_zone/Actor/Chara.h | 44 ++--- src/servers/sapphire_zone/Actor/Player.cpp | 13 +- src/servers/sapphire_zone/Actor/Player.h | 2 +- .../Network/Handlers/GMCommandHandlers.cpp | 22 +-- .../Network/Handlers/SkillHandler.cpp | 6 +- .../PacketWrappers/PlayerSpawnPacket.h | 2 +- src/servers/sapphire_zone/Zone/Zone.cpp | 28 +-- 14 files changed, 278 insertions(+), 262 deletions(-) diff --git a/src/common/Common.h b/src/common/Common.h index 2a62c6ef..6d5b204d 100644 --- a/src/common/Common.h +++ b/src/common/Common.h @@ -708,16 +708,6 @@ namespace Common { MountSkill = 0xD, }; - /*! ModelType as found in eventsystemdefine.exd */ - enum ModelType : uint8_t - { - Human = 1, - DemiHuman = 2, - Monster = 3, - SharedGroup = 4, - Parts = 5 - }; - typedef std::vector< PlayerStateFlag > PlayerStateFlagList; } /* Common */ diff --git a/src/common/Network/PacketDef/Zone/ServerZoneDef.h b/src/common/Network/PacketDef/Zone/ServerZoneDef.h index 572b08fb..0b32b0b4 100644 --- a/src/common/Network/PacketDef/Zone/ServerZoneDef.h +++ b/src/common/Network/PacketDef/Zone/ServerZoneDef.h @@ -382,7 +382,7 @@ struct FFXIVIpcPlayerSpawn : FFXIVIpcBasePacket uint8_t spawnIndex; uint8_t state; uint8_t persistantEmote; - uint8_t type; // modelType -> eventSystemDefine + uint8_t modelType; // modelType -> eventSystemDefine uint8_t subtype; uint8_t voice; uint16_t u25c; @@ -458,7 +458,7 @@ struct FFXIVIpcNpcSpawn : FFXIVIpcBasePacket uint8_t spawnIndex; uint8_t state; uint8_t persistantEmote; - uint8_t type; + uint8_t modelType; uint8_t subtype; uint8_t voice; uint16_t u25c; diff --git a/src/servers/sapphire_zone/Action/ActionCollision.cpp b/src/servers/sapphire_zone/Action/ActionCollision.cpp index 86ac4933..defb184a 100644 --- a/src/servers/sapphire_zone/Action/ActionCollision.cpp +++ b/src/servers/sapphire_zone/Action/ActionCollision.cpp @@ -2,6 +2,7 @@ #include #include "ActionCollision.h" +#include "Actor/Actor.h" #include "Actor/Chara.h" #include "Actor/Player.h" @@ -13,7 +14,7 @@ using namespace Core::Common; // todo: add AoE actor limits (16, 32) -bool ActionCollision::isActorApplicable( Chara& chara, TargetFilter targetFilter ) +bool ActionCollision::isActorApplicable( Actor& actor, TargetFilter targetFilter ) { bool actorApplicable = false; switch( targetFilter ) @@ -25,7 +26,7 @@ bool ActionCollision::isActorApplicable( Chara& chara, TargetFilter targetFilter } case TargetFilter::Players: { - actorApplicable = chara.isPlayer(); + actorApplicable = actor.isPlayer(); break; } case TargetFilter::Allies: @@ -37,7 +38,7 @@ bool ActionCollision::isActorApplicable( Chara& chara, TargetFilter targetFilter case TargetFilter::Party: { // todo: implement party - actorApplicable = chara.isPlayer(); + actorApplicable = actor.isPlayer(); break; } case TargetFilter::Enemies: @@ -47,15 +48,15 @@ bool ActionCollision::isActorApplicable( Chara& chara, TargetFilter targetFilter } } - return ( actorApplicable && chara.isAlive() ); + return ( actorApplicable && actor.getAsChara()->isAlive() ); } -std::set< Core::Entity::CharaPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition, - std::set< CharaPtr > actorsInRange, +std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition, + std::set< ActorPtr > actorsInRange, boost::shared_ptr< Core::Data::Action > actionInfo, TargetFilter targetFilter ) { - std::set< CharaPtr > actorsCollided; + std::set< ActorPtr > actorsCollided; switch( static_cast< ActionCollisionType >( actionInfo->castType ) ) { diff --git a/src/servers/sapphire_zone/Action/ActionCollision.h b/src/servers/sapphire_zone/Action/ActionCollision.h index 470a31f2..13cddd44 100644 --- a/src/servers/sapphire_zone/Action/ActionCollision.h +++ b/src/servers/sapphire_zone/Action/ActionCollision.h @@ -23,9 +23,9 @@ namespace Entity { { public: - static bool isActorApplicable( Chara& actor, TargetFilter targetFilter ); - static std::set< CharaPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition, - std::set< CharaPtr > actorsInRange, + static bool isActorApplicable( Actor& actor, TargetFilter targetFilter ); + static std::set< ActorPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition, + std::set< ActorPtr > actorsInRange, boost::shared_ptr< Data::Action > actionInfo, TargetFilter targetFilter ); diff --git a/src/servers/sapphire_zone/Actor/Actor.cpp b/src/servers/sapphire_zone/Actor/Actor.cpp index 3890dd40..fc13ddc8 100644 --- a/src/servers/sapphire_zone/Actor/Actor.cpp +++ b/src/servers/sapphire_zone/Actor/Actor.cpp @@ -1,7 +1,17 @@ #include "Actor.h" -#include "Player.h" +#include +#include +#include +#include + #include "Chara.h" +#include "Network/GameConnection.h" +#include "Player.h" +#include "ServerZone.h" +#include "Session.h" + +extern Core::ServerZone g_serverZone; Core::Entity::Actor::Actor( ObjKind type ) : m_objKind( type ) @@ -65,3 +75,165 @@ Core::Entity::PlayerPtr Core::Entity::Actor::getAsPlayer() return boost::dynamic_pointer_cast< Entity::Player, Entity::Actor >( shared_from_this() ); } +/*! +Add a given actor to the fitting in range set according to type +but also to the global actor map + +\param ActorPtr to add +*/ +void Core::Entity::Actor::addInRangeActor( ActorPtr pActor ) +{ + + // if this is null, something went wrong + assert( pActor ); + + // add actor to in range set + m_inRangeActor.insert( pActor ); + + if( pActor->isPlayer() ) + { + auto pPlayer = pActor->getAsPlayer(); + + pPlayer->spawn( getAsPlayer() ); + + // if actor is a player, add it to the in range player set + m_inRangePlayers.insert( pPlayer ); + } +} + +/*! +Remove a given actor from the matching in range set according to type +but also to the global actor map + +\param ActorPtr to remove +*/ +void Core::Entity::Actor::removeInRangeActor( Actor& actor ) +{ + // call virtual event + onRemoveInRangeActor( actor ); + + // remove actor from in range actor set + m_inRangeActor.erase( actor.shared_from_this() ); + + // if actor is a player, despawn ourself for him + // TODO: move to virtual onRemove? + if( isPlayer() ) + actor.despawn( getAsPlayer() ); + + if( actor.isPlayer() ) + m_inRangePlayers.erase( actor.getAsPlayer() ); +} + +/*! \return true if there is at least one actor in the in range set */ +bool Core::Entity::Actor::hasInRangeActor() const +{ + return ( m_inRangeActor.size() > 0 ); +} + +void Core::Entity::Actor::removeFromInRange() +{ + if( !hasInRangeActor() ) + return; + + Entity::ActorPtr pCurAct; + + for( auto& pCurAct : m_inRangeActor ) + { + pCurAct->removeInRangeActor( *this ); + } + +} + +/*! +check if a given actor is in the actors in range set + +\param ActorPtr to be checked for +\return true if the actor was found +*/ +bool Core::Entity::Actor::isInRangeSet( ActorPtr pActor ) const +{ + return !( m_inRangeActor.find( pActor ) == m_inRangeActor.end() ); +} + +/*! \return ActorPtr of the closest actor in range, if none, nullptr */ +Core::Entity::ActorPtr Core::Entity::Actor::getClosestActor() +{ + if( m_inRangeActor.empty() ) + // no actors in range, don't bother + return nullptr; + + ActorPtr tmpActor = nullptr; + + // arbitrary high number + float minDistance = 10000; + + for( const auto& pCurAct : m_inRangeActor ) + { + float distance = Math::Util::distance( getPos().x, + getPos().y, + getPos().z, + pCurAct->getPos().x, + pCurAct->getPos().y, + pCurAct->getPos().z ); + + if( distance < minDistance ) + { + minDistance = distance; + tmpActor = pCurAct; + } + } + + return tmpActor; +} + + +/*! Clear the whole in range set, this does no cleanup */ +void Core::Entity::Actor::clearInRangeSet() +{ + m_inRangeActor.clear(); + m_inRangePlayers.clear(); +} + +/*! +Send a packet to all players in range, potentially to self if set and is player + +\param GamePacketPtr to send +\param bool should be send to self? +*/ +void Core::Entity::Actor::sendToInRangeSet( Network::Packets::GamePacketPtr pPacket, bool bToSelf ) +{ + + if( bToSelf && isPlayer() ) + { + auto pPlayer = getAsPlayer(); + + auto pSession = g_serverZone.getSession( pPlayer->getId() ); + + // it might be that the player DC'd in which case the session would be invalid + if( pSession ) + pSession->getZoneConnection()->queueOutPacket( pPacket ); + } + + if( m_inRangePlayers.empty() ) + return; + + for( const auto &pCurAct : m_inRangePlayers ) + { + assert( pCurAct ); + pPacket->setValAt< uint32_t >( 0x04, m_id ); + pPacket->setValAt< uint32_t >( 0x08, pCurAct->getId() ); + // it might be that the player DC'd in which case the session would be invalid + pCurAct->queuePacket( pPacket ); + } +} + +/*! \return list of actors currently in range */ +std::set< Core::Entity::ActorPtr > Core::Entity::Actor::getInRangeActors( bool includeSelf ) +{ + auto tempInRange = m_inRangeActor; + + if( includeSelf ) + tempInRange.insert( shared_from_this() ); + + return tempInRange; +} \ No newline at end of file diff --git a/src/servers/sapphire_zone/Actor/Actor.h b/src/servers/sapphire_zone/Actor/Actor.h index 3127bf3e..555a9fc9 100644 --- a/src/servers/sapphire_zone/Actor/Actor.h +++ b/src/servers/sapphire_zone/Actor/Actor.h @@ -49,6 +49,10 @@ namespace Entity { /*! Type of the actor */ ObjKind m_objKind; + /*! list of various actors in range */ + std::set< ActorPtr > m_inRangeActor; + std::set< PlayerPtr > m_inRangePlayers; + public: explicit Actor( ObjKind type ); virtual ~Actor() {}; @@ -69,6 +73,34 @@ namespace Entity { bool isPlayer() const; + ///// IN RANGE LOGIC /////////////////////////////// + virtual void onRemoveInRangeActor( Actor& pActor ) {} + + // check if another actor is in the actors in range set + bool isInRangeSet( ActorPtr pActor ) const; + + ActorPtr getClosestActor(); + + void sendToInRangeSet( Network::Packets::GamePacketPtr pPacket, bool bToSelf = false ); + + // add an actor to in range set + void addInRangeActor( ActorPtr pActor ); + + // remove an actor from the in range set + void removeInRangeActor( Actor& actor ); + + // return true if there is at least one actor in the in range set + bool hasInRangeActor() const; + + void removeFromInRange(); + + // clear the whole in range set, this does no cleanup + virtual void clearInRangeSet(); + + std::set< ActorPtr > getInRangeActors( bool includeSelf = false ); + + //////////////////////////////////////////////////// + CharaPtr getAsChara(); PlayerPtr getAsPlayer(); }; diff --git a/src/servers/sapphire_zone/Actor/Chara.cpp b/src/servers/sapphire_zone/Actor/Chara.cpp index a7162f4e..588ef935 100644 --- a/src/servers/sapphire_zone/Actor/Chara.cpp +++ b/src/servers/sapphire_zone/Actor/Chara.cpp @@ -52,16 +52,6 @@ std::string Core::Entity::Chara::getName() const return std::string( m_name ); } -/*! \return list of actors currently in range */ -std::set< Core::Entity::CharaPtr > Core::Entity::Chara::getInRangeCharas( bool includeSelf ) -{ - auto tempInRange = m_inRangeCharas; - - if( includeSelf ) - tempInRange.insert( getAsChara() ); - - return tempInRange; - } /*! \return current stance of the actors */ Core::Entity::Chara::Stance Core::Entity::Chara::getStance() const @@ -396,155 +386,6 @@ void Core::Entity::Chara::setCurrentAction( Core::Action::ActionPtr pAction ) m_pCurrentAction = pAction; } -/*! -check if a given actor is in the actors in range set - -\param ActorPtr to be checked for -\return true if the actor was found -*/ -bool Core::Entity::Chara::isInRangeSet( CharaPtr pChara ) const -{ - return !( m_inRangeCharas.find( pChara ) == m_inRangeCharas.end() ); -} - -/*! \return ActorPtr of the closest actor in range, if none, nullptr */ -Core::Entity::CharaPtr Core::Entity::Chara::getClosestChara() -{ - if( m_inRangeCharas.empty() ) - // no actors in range, don't bother - return nullptr; - - CharaPtr tmpActor = nullptr; - - // arbitrary high number - float minDistance = 10000; - - for( const auto& pCurAct : m_inRangeCharas ) - { - float distance = Math::Util::distance( getPos().x, - getPos().y, - getPos().z, - pCurAct->getPos().x, - pCurAct->getPos().y, - pCurAct->getPos().z ); - - if( distance < minDistance ) - { - minDistance = distance; - tmpActor = pCurAct; - } - } - - return tmpActor; -} - -/*! -Send a packet to all players in range, potentially to self if set and is player - -\param GamePacketPtr to send -\param bool should be send to self? -*/ -void Core::Entity::Chara::sendToInRangeSet( Network::Packets::GamePacketPtr pPacket, bool bToSelf ) -{ - - if( bToSelf && isPlayer() ) - { - auto pPlayer = getAsPlayer(); - - auto pSession = g_serverZone.getSession( pPlayer->getId() ); - - // it might be that the player DC'd in which case the session would be invalid - if( pSession ) - pSession->getZoneConnection()->queueOutPacket( pPacket ); - } - - if( m_inRangePlayers.empty() ) - return; - - for( const auto &pCurAct : m_inRangePlayers ) - { - assert( pCurAct ); - pPacket->setValAt< uint32_t >( 0x04, m_id ); - pPacket->setValAt< uint32_t >( 0x08, pCurAct->m_id ); - // it might be that the player DC'd in which case the session would be invalid - pCurAct->queuePacket( pPacket ); - } -} - -/*! -Add a given actor to the fitting in range set according to type -but also to the global actor map - -\param ActorPtr to add -*/ -void Core::Entity::Chara::addInRangeChara( CharaPtr pChara ) -{ - - // if this is null, something went wrong - assert( pChara ); - - // add actor to in range set - m_inRangeCharas.insert( pChara ); - - if( pChara->isPlayer() ) - { - auto pPlayer = pChara->getAsPlayer(); - - // if actor is a player, add it to the in range player set - m_inRangePlayers.insert( pPlayer ); - } -} - -/*! -Remove a given actor from the matching in range set according to type -but also to the global actor map - -\param ActorPtr to remove -*/ -void Core::Entity::Chara::removeInRangeChara( Chara& chara ) -{ - // call virtual event - onRemoveInRangeChara( chara ); - - // remove actor from in range actor set - m_inRangeCharas.erase( chara.getAsChara() ); - - // if actor is a player, despawn ourself for him - // TODO: move to virtual onRemove? - if( isPlayer() ) - chara.despawn( getAsPlayer() ); - - if( chara.isPlayer() ) - m_inRangePlayers.erase( chara.getAsPlayer() ); -} - -/*! \return true if there is at least one actor in the in range set */ -bool Core::Entity::Chara::hasInRangeActor() const -{ - return ( m_inRangeCharas.size() > 0 ); -} - -void Core::Entity::Chara::removeFromInRange() -{ - if( !hasInRangeActor() ) - return; - - Entity::ActorPtr pCurAct; - - for( auto& pCurAct : m_inRangeCharas ) - { - pCurAct->removeInRangeChara( *this ); - } - -} - -/*! Clear the whole in range set, this does no cleanup */ -void Core::Entity::Chara::clearInRangeSet() -{ - m_inRangeCharas.clear(); - m_inRangePlayers.clear(); -} - /*! \return ZonePtr to the current zone, nullptr if not set */ Core::ZonePtr Core::Entity::Chara::getCurrentZone() const { @@ -682,7 +523,7 @@ void Core::Entity::Chara::handleScriptSkill( uint32_t type, uint16_t actionId, u else { - auto actorsCollided = ActionCollision::getActorsHitFromAction( target.getPos(), getInRangeCharas(true), + auto actorsCollided = ActionCollision::getActorsHitFromAction( target.getPos(), getInRangeActors( true ), actionInfoPtr, TargetFilter::Enemies ); for( const auto& pHitActor : actorsCollided ) @@ -694,16 +535,17 @@ void Core::Entity::Chara::handleScriptSkill( uint32_t type, uint16_t actionId, u sendToInRangeSet( effectPacket, true ); - if( pHitActor->isAlive() ) - pHitActor->onActionHostile( *this ); + if( pHitActor->getAsChara()->isAlive() ) + pHitActor->getAsChara()->onActionHostile( *this ); - pHitActor->takeDamage( static_cast< uint32_t >( param1 ) ); + pHitActor->getAsChara()->takeDamage( static_cast< uint32_t >( param1 ) ); // Debug if ( isPlayer() ) { if ( pHitActor->isPlayer() ) - getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) + " (" + pHitActor->getName() + ")" ); + getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) + + " (" + pHitActor->getAsChara()->getName() + ")" ); else getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) ); } @@ -734,7 +576,7 @@ void Core::Entity::Chara::handleScriptSkill( uint32_t type, uint16_t actionId, u // 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(), getInRangeCharas(true), + auto actorsCollided = ActionCollision::getActorsHitFromAction( target.getPos(), getInRangeActors(true), actionInfoPtr, TargetFilter::Allies ); for( auto pHitActor : actorsCollided ) @@ -743,13 +585,14 @@ void Core::Entity::Chara::handleScriptSkill( uint32_t type, uint16_t actionId, u effectPacket.data().effectTarget = pHitActor->getId(); sendToInRangeSet( effectPacket, true ); - pHitActor->heal( calculatedHeal ); + pHitActor->getAsChara()->heal( calculatedHeal ); // Debug if( isPlayer() ) { if( pHitActor->isPlayer() ) - getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) + " (" + pHitActor->getName() + ")" ); + getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) + + " (" + pHitActor->getAsChara()->getName() + ")" ); else getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) ); } @@ -972,3 +815,8 @@ bool Core::Entity::Chara::hasStatusEffect( uint32_t id ) return true; return false; } + +Chara::ModelType Chara::getModelType() const +{ + return m_modelType; +} diff --git a/src/servers/sapphire_zone/Actor/Chara.h b/src/servers/sapphire_zone/Actor/Chara.h index 116288f5..d24c96e2 100644 --- a/src/servers/sapphire_zone/Actor/Chara.h +++ b/src/servers/sapphire_zone/Actor/Chara.h @@ -49,6 +49,16 @@ public: SMachine = 0x08 }; + /*! ModelType as found in eventsystemdefine.exd */ + enum ModelType : uint8_t + { + Human = 1, + DemiHuman = 2, + Monster = 3, + SharedGroup = 4, + Parts = 5 + }; + struct ActorStats { uint32_t max_mp = 0; @@ -132,6 +142,8 @@ protected: Action::ActionPtr m_pCurrentAction; /*! Invincibility type */ Common::InvincibilityType m_invincibilityType; + /*! Type of model to use, humanoid for actors that use look data */ + ModelType m_modelType; /*! Status effects */ const uint8_t MAX_STATUS_EFFECTS = 30; @@ -139,9 +151,6 @@ protected: std::vector< std::pair< uint8_t, uint32_t> > m_statusEffectList; std::map< uint8_t, StatusEffect::StatusEffectPtr > m_statusEffectMap; - std::set< CharaPtr > m_inRangeCharas; - std::set< PlayerPtr > m_inRangePlayers; - public: Chara( ObjKind type ); @@ -182,8 +191,6 @@ public: std::string getName() const; - std::set< CharaPtr > getInRangeCharas( bool includeSelf = false ); - bool face( const Common::FFXIVARR_POSITION3& p ); Stance getStance() const; @@ -201,6 +208,8 @@ public: Common::ClassJob getClass() const; + ModelType getModelType() const; + uint8_t getClassAsInt() const; void setClass( Common::ClassJob classJob ); @@ -233,8 +242,6 @@ public: virtual void autoAttack( CharaPtr pTarget ); - virtual void onRemoveInRangeChara( Chara& pActor ) {} - virtual void onDeath() {}; virtual void onDamageTaken( Chara& pSource ) {}; virtual void onActionHostile( Chara& source ) {}; @@ -253,29 +260,6 @@ public: void setCurrentAction( Action::ActionPtr pAction ); - ///// IN RANGE LOGIC ///// - - // check if another actor is in the actors in range set - bool isInRangeSet( CharaPtr pChara ) const; - - CharaPtr getClosestChara(); - - void sendToInRangeSet( Network::Packets::GamePacketPtr pPacket, bool bToSelf = false ); - - // add an actor to in range set - void addInRangeChara( CharaPtr pChara ); - - // remove an actor from the in range set - void removeInRangeChara( Chara& chara ); - - // return true if there is at least one actor in the in range set - bool hasInRangeActor() const; - - void removeFromInRange(); - - // clear the whole in range set, this does no cleanup - virtual void clearInRangeSet(); - ZonePtr getCurrentZone() const; void setCurrentZone( ZonePtr currZone ); diff --git a/src/servers/sapphire_zone/Actor/Player.cpp b/src/servers/sapphire_zone/Actor/Player.cpp index 941ba949..46cb3280 100644 --- a/src/servers/sapphire_zone/Actor/Player.cpp +++ b/src/servers/sapphire_zone/Actor/Player.cpp @@ -80,6 +80,7 @@ Core::Entity::Player::Player() : m_queuedZoneing = nullptr; m_status = ActorStatus::Idle; m_invincibilityType = InvincibilityType::InvincibilityNone; + m_modelType = ModelType::Human; memset( m_questTracking, 0, sizeof( m_questTracking ) ); memset( m_name, 0, sizeof( m_name ) ); @@ -819,10 +820,10 @@ void Core::Entity::Player::despawn( Entity::PlayerPtr pTarget ) pPlayer->queuePacket( ActorControlPacket143( getId(), DespawnZoneScreenMsg, 0x04, getId(), 0x01 ) ); } -Core::Entity::CharaPtr Core::Entity::Player::lookupTargetById( uint64_t targetId ) +Core::Entity::ActorPtr Core::Entity::Player::lookupTargetById( uint64_t targetId ) { - CharaPtr targetActor; - auto inRange = getInRangeCharas(true); + ActorPtr targetActor; + auto inRange = getInRangeActors(true); for( auto actor : inRange ) { if( actor->getId() == targetId ) @@ -995,9 +996,9 @@ void Core::Entity::Player::update( int64_t currTime ) auto mainWeap = m_pInventory->getItemAt( Inventory::GearSet0, Inventory::EquipSlot::MainHand ); // @TODO i dislike this, iterating over all in range actors when you already know the id of the actor you need... - for( auto actor : m_inRangeCharas ) + for( auto actor : m_inRangeActor ) { - if( actor->getId() == m_targetId && actor->isAlive() && mainWeap ) + if( actor->getId() == m_targetId && actor->getAsChara()->isAlive() && mainWeap ) { // default autoattack range // TODO make this dependant on bnpc size @@ -1017,7 +1018,7 @@ void Core::Entity::Player::update( int64_t currTime ) if( ( currTime - m_lastAttack ) > mainWeap->getDelay() ) { m_lastAttack = currTime; - autoAttack( actor ); + autoAttack( actor->getAsChara() ); } } diff --git a/src/servers/sapphire_zone/Actor/Player.h b/src/servers/sapphire_zone/Actor/Player.h index 07c18827..e1f57e1d 100644 --- a/src/servers/sapphire_zone/Actor/Player.h +++ b/src/servers/sapphire_zone/Actor/Player.h @@ -519,7 +519,7 @@ public: bool actionHasCastTime( uint32_t actionId ); - Core::Entity::CharaPtr lookupTargetById( uint64_t targetId ); + Core::Entity::ActorPtr lookupTargetById( uint64_t targetId ); bool isLogin() const; void setIsLogin( bool bIsLogin ); diff --git a/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp b/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp index 63c19006..578b2ad6 100644 --- a/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp +++ b/src/servers/sapphire_zone/Network/Handlers/GMCommandHandlers.cpp @@ -104,7 +104,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac ", params: " + std::to_string( param1 ) + ", " + std::to_string( param2 ) + ", " + std::to_string( param3 ) ); - Core::Entity::CharaPtr targetActor; + Core::Entity::ActorPtr targetActor; if( player.getId() == param3 ) @@ -113,7 +113,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac } else { - auto inRange = player.getInRangeCharas(); + auto inRange = player.getInRangeActors(); for( auto actor : inRange ) { if( actor->getId() == param3 ) @@ -138,7 +138,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac targetPlayer->setLookAt( CharaLook::Race, param1 ); player.sendNotice( "Race for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) ); targetPlayer->spawn( targetPlayer ); - auto inRange = targetPlayer->getInRangeCharas(); + auto inRange = targetPlayer->getInRangeActors(); for( auto actor : inRange ) { targetPlayer->despawn( actor->getAsPlayer() ); @@ -151,7 +151,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac targetPlayer->setLookAt( CharaLook::Tribe, param1 ); player.sendNotice( "Tribe for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) ); targetPlayer->spawn( targetPlayer ); - auto inRange = targetPlayer->getInRangeCharas(); + auto inRange = targetPlayer->getInRangeActors(); for( auto actor : inRange ) { targetPlayer->despawn( actor->getAsPlayer() ); @@ -164,7 +164,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac targetPlayer->setLookAt( CharaLook::Gender, param1 ); player.sendNotice( "Sex for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) ); targetPlayer->spawn( targetPlayer ); - auto inRange = targetActor->getInRangeCharas(); + auto inRange = targetActor->getInRangeActors(); for( auto actor : inRange ) { targetPlayer->despawn( actor->getAsPlayer() ); @@ -216,7 +216,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac } case GmCommand::Kill: { - targetActor->takeDamage( 9999999 ); + targetActor->getAsChara()->takeDamage( 9999999 ); player.sendNotice( "Killed " + std::to_string( targetActor->getId() ) ); break; } @@ -266,10 +266,10 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac } case GmCommand::Inv: { - if( targetActor->getInvincibilityType() == Common::InvincibilityType::InvincibilityRefill ) - targetActor->setInvincibilityType( Common::InvincibilityType::InvincibilityNone ); + if( targetActor->getAsChara()->getInvincibilityType() == Common::InvincibilityType::InvincibilityRefill ) + targetActor->getAsChara()->setInvincibilityType( Common::InvincibilityType::InvincibilityNone ); else - targetActor->setInvincibilityType( Common::InvincibilityType::InvincibilityRefill ); + targetActor->getAsChara()->setInvincibilityType( Common::InvincibilityType::InvincibilityRefill ); player.sendNotice( "Invincibility for " + targetPlayer->getName() + " was switched." ); @@ -439,10 +439,10 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac case GmCommand::Jump: { - auto inRange = player.getInRangeCharas(); + auto inRange = player.getInRangeActors(); player.changePosition( targetActor->getPos().x, targetActor->getPos().y, targetActor->getPos().z, - targetActor->getRotation() ); + targetActor->getRot() ); player.sendNotice( "Jumping to " + targetPlayer->getName() + " in range." ); break; diff --git a/src/servers/sapphire_zone/Network/Handlers/SkillHandler.cpp b/src/servers/sapphire_zone/Network/Handlers/SkillHandler.cpp index ac964471..c566556d 100644 --- a/src/servers/sapphire_zone/Network/Handlers/SkillHandler.cpp +++ b/src/servers/sapphire_zone/Network/Handlers/SkillHandler.cpp @@ -75,7 +75,7 @@ void Core::Network::GameConnection::skillHandler( const Packets::GamePacket& inP } else { - Core::Entity::CharaPtr targetActor = player.getAsPlayer(); + Core::Entity::ActorPtr targetActor = player.getAsPlayer(); if( targetId != player.getId() ) { targetActor = player.lookupTargetById( targetId ); @@ -83,11 +83,11 @@ void Core::Network::GameConnection::skillHandler( const Packets::GamePacket& inP if( !player.actionHasCastTime( action ) ) { - g_scriptMgr.onCastFinish( player, targetActor, action ); + g_scriptMgr.onCastFinish( player, targetActor->getAsChara(), action ); } else { - auto pActionCast = Action::make_ActionCast( player.getAsPlayer(), targetActor, action ); + auto pActionCast = Action::make_ActionCast( player.getAsPlayer(), targetActor->getAsChara(), action ); player.setCurrentAction( pActionCast ); player.sendDebug( "setCurrentAction()" ); player.getCurrentAction()->onStart(); diff --git a/src/servers/sapphire_zone/Network/PacketWrappers/PlayerSpawnPacket.h b/src/servers/sapphire_zone/Network/PacketWrappers/PlayerSpawnPacket.h index e940e53a..7aa01d61 100644 --- a/src/servers/sapphire_zone/Network/PacketWrappers/PlayerSpawnPacket.h +++ b/src/servers/sapphire_zone/Network/PacketWrappers/PlayerSpawnPacket.h @@ -76,7 +76,7 @@ namespace Server { //m_data.u23 = 0x04; //m_data.u24 = 256; m_data.state = static_cast< uint8_t >( player.getStatus() ); - m_data.type = 1; + m_data.modelType = player.getModelType(); if( target.getId() == player.getId() ) { m_data.spawnIndex = 0x00; diff --git a/src/servers/sapphire_zone/Zone/Zone.cpp b/src/servers/sapphire_zone/Zone/Zone.cpp index e7056c57..f8c7c58f 100644 --- a/src/servers/sapphire_zone/Zone/Zone.cpp +++ b/src/servers/sapphire_zone/Zone/Zone.cpp @@ -602,27 +602,15 @@ void Core::Zone::updateInRangeSet( Entity::CharaPtr pChara, Cell* pCell ) // Add if range == 0 or distance is withing range. if( isInRange && !isInRangeSet ) { - if( pChara->isPlayer() ) - { - auto pOwnPlayer = pChara->getAsPlayer(); - if( !pOwnPlayer->isLoadingComplete() ) - continue; - // spawn the actor for the player - pCurAct->spawn( pOwnPlayer ); - } + if( pChara->isPlayer() && !pChara->getAsPlayer()->isLoadingComplete() ) + continue; - if( pCurAct->isPlayer() ) - { - auto pPlayer = pCurAct->getAsPlayer(); - if( !pPlayer->isLoadingComplete() ) - continue; + if( pCurAct->isPlayer() && !pCurAct->getAsPlayer()->isLoadingComplete() ) + continue; - pChara->spawn( pPlayer ); - } - - pChara->addInRangeChara( pCurAct ); - pCurAct->addInRangeChara( pChara ); + pChara->addInRangeActor( pCurAct ); + pCurAct->addInRangeActor( pChara ); // this is a hack to limit actor spawn in one packetset if( count++ > 12 ) @@ -630,8 +618,8 @@ void Core::Zone::updateInRangeSet( Entity::CharaPtr pChara, Cell* pCell ) } else if( !isInRange && isInRangeSet ) { - pCurAct->removeInRangeChara( *pChara ); - pChara->removeInRangeChara( *pCurAct ); + pCurAct->removeInRangeActor( *pChara ); + pChara->removeInRangeActor( *pCurAct ); } } }