mirror of
https://github.com/SapphireServer/Sapphire.git
synced 2025-04-23 13:17:45 +00:00
Changeing base access type of actors to gameobject
This commit is contained in:
parent
7fddb75c46
commit
4457a45aa3
11 changed files with 199 additions and 190 deletions
|
@ -2,6 +2,7 @@
|
||||||
#include <common/Util/UtilMath.h>
|
#include <common/Util/UtilMath.h>
|
||||||
|
|
||||||
#include "ActionCollision.h"
|
#include "ActionCollision.h"
|
||||||
|
#include "Actor/GameObject.h"
|
||||||
#include "Actor/Actor.h"
|
#include "Actor/Actor.h"
|
||||||
#include "Actor/Player.h"
|
#include "Actor/Player.h"
|
||||||
|
|
||||||
|
@ -51,7 +52,7 @@ bool ActionCollision::isActorApplicable( Actor& actor, TargetFilter targetFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition,
|
std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition,
|
||||||
std::set< ActorPtr > actorsInRange,
|
std::set< GameObjectPtr > gameObjectsInRange,
|
||||||
boost::shared_ptr< Core::Data::Action > actionInfo,
|
boost::shared_ptr< Core::Data::Action > actionInfo,
|
||||||
TargetFilter targetFilter )
|
TargetFilter targetFilter )
|
||||||
{
|
{
|
||||||
|
@ -64,52 +65,52 @@ std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXI
|
||||||
{
|
{
|
||||||
// This is actually needed. There is "splash damage" in actions marked as single target.
|
// 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.
|
// Notice how we're using aoe_width. How collision works for SingleTarget is unknown as of now.
|
||||||
for( auto pActor : actorsInRange )
|
for( auto pActor : gameObjectsInRange )
|
||||||
{
|
{
|
||||||
// Make sure actor exists. If it doesn't we done goofed.
|
// Make sure actor exists. If it doesn't we done goofed.
|
||||||
assert( pActor );
|
assert( pActor );
|
||||||
|
|
||||||
// Don't bother wasting on collision if actor doesn't apply for it
|
// Don't bother wasting on collision if actor doesn't apply for it
|
||||||
if ( !isActorApplicable( *pActor, targetFilter ) )
|
if ( !isActorApplicable( *pActor->getAsActor(), targetFilter ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// Test our collision from actor with the area generated by the action from the AoE data
|
// Test our collision from actor with the area generated by the action from the AoE data
|
||||||
if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->effectRange ) )
|
if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->effectRange ) )
|
||||||
{
|
{
|
||||||
// Add it to the actors collided with the area
|
// Add it to the actors collided with the area
|
||||||
actorsCollided.insert( pActor );
|
//actorsCollided.insert( pActor );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ActionCollisionType::Circle:
|
case ActionCollisionType::Circle:
|
||||||
{
|
{
|
||||||
for( auto pActor : actorsInRange )
|
for( auto pActor : gameObjectsInRange )
|
||||||
{
|
{
|
||||||
assert( pActor );
|
assert( pActor );
|
||||||
|
|
||||||
if ( !isActorApplicable( *pActor, targetFilter ) )
|
if ( !isActorApplicable( *pActor->getAsActor(), targetFilter ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->effectRange ) )
|
//if ( radiusCollision( pActor->getPos(), aoePosition, actionInfo->effectRange ) )
|
||||||
actorsCollided.insert( pActor );
|
//actorsCollided.insert( pActor );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ActionCollisionType::Box:
|
case ActionCollisionType::Box:
|
||||||
{
|
{
|
||||||
for( auto pActor : actorsInRange )
|
for( auto pActor : gameObjectsInRange )
|
||||||
{
|
{
|
||||||
assert( pActor );
|
assert( pActor );
|
||||||
|
|
||||||
if ( !isActorApplicable( *pActor, targetFilter ) )
|
if ( !isActorApplicable( *pActor->getAsActor(), targetFilter ) )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ( boxCollision( pActor->getPos(), aoePosition, actionInfo->xAxisModifier, actionInfo->effectRange ) )
|
if ( boxCollision( pActor->getPos(), aoePosition, actionInfo->xAxisModifier, actionInfo->effectRange ) )
|
||||||
{
|
{
|
||||||
// todo: does this actually work?
|
// todo: does this actually work?
|
||||||
|
|
||||||
actorsCollided.insert( pActor );
|
//actorsCollided.insert( pActor );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace Entity {
|
||||||
|
|
||||||
static bool isActorApplicable( Actor& actor, TargetFilter targetFilter );
|
static bool isActorApplicable( Actor& actor, TargetFilter targetFilter );
|
||||||
static std::set< ActorPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition,
|
static std::set< ActorPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition,
|
||||||
std::set< ActorPtr > actorsInRange,
|
std::set< GameObjectPtr > gameObjectsInRange,
|
||||||
boost::shared_ptr< Data::Action > actionInfo,
|
boost::shared_ptr< Data::Action > actionInfo,
|
||||||
TargetFilter targetFilter );
|
TargetFilter targetFilter );
|
||||||
|
|
||||||
|
|
|
@ -52,17 +52,6 @@ std::string Core::Entity::Actor::getName() const
|
||||||
return std::string( m_name );
|
return std::string( m_name );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \return list of actors currently in range */
|
|
||||||
std::set< Core::Entity::ActorPtr > Core::Entity::Actor::getInRangeActors( bool includeSelf )
|
|
||||||
{
|
|
||||||
auto tempInRange = m_inRangeActors;
|
|
||||||
|
|
||||||
if( includeSelf )
|
|
||||||
tempInRange.insert( getAsActor() );
|
|
||||||
|
|
||||||
return tempInRange;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \return current stance of the actors */
|
/*! \return current stance of the actors */
|
||||||
Core::Entity::Actor::Stance Core::Entity::Actor::getStance() const
|
Core::Entity::Actor::Stance Core::Entity::Actor::getStance() const
|
||||||
{
|
{
|
||||||
|
@ -396,48 +385,6 @@ void Core::Entity::Actor::setCurrentAction( Core::Action::ActionPtr pAction )
|
||||||
m_pCurrentAction = 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::Actor::isInRangeSet( ActorPtr pActor ) const
|
|
||||||
{
|
|
||||||
return !( m_inRangeActors.find( pActor ) == m_inRangeActors.end() );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \return ActorPtr of the closest actor in range, if none, nullptr */
|
|
||||||
Core::Entity::ActorPtr Core::Entity::Actor::getClosestActor()
|
|
||||||
{
|
|
||||||
if( m_inRangeActors.empty() )
|
|
||||||
// no actors in range, don't bother
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
ActorPtr tmpActor = nullptr;
|
|
||||||
|
|
||||||
// arbitrary high number
|
|
||||||
float minDistance = 10000;
|
|
||||||
|
|
||||||
for( const auto& pCurAct : m_inRangeActors )
|
|
||||||
{
|
|
||||||
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
|
Send a packet to all players in range, potentially to self if set and is player
|
||||||
|
|
||||||
|
@ -471,80 +418,6 @@ void Core::Entity::Actor::sendToInRangeSet( Network::Packets::GamePacketPtr pPac
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*!
|
|
||||||
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_inRangeActors.insert( pActor );
|
|
||||||
|
|
||||||
if( pActor->isPlayer() )
|
|
||||||
{
|
|
||||||
auto pPlayer = pActor->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_inRangeActors.erase( actor.getAsActor() );
|
|
||||||
|
|
||||||
// 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_inRangeActors.size() > 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
void Core::Entity::Actor::removeFromInRange()
|
|
||||||
{
|
|
||||||
if( !hasInRangeActor() )
|
|
||||||
return;
|
|
||||||
|
|
||||||
Entity::ActorPtr pCurAct;
|
|
||||||
|
|
||||||
for( auto& pCurAct : m_inRangeActors )
|
|
||||||
{
|
|
||||||
pCurAct->removeInRangeActor( *this );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Clear the whole in range set, this does no cleanup */
|
|
||||||
void Core::Entity::Actor::clearInRangeSet()
|
|
||||||
{
|
|
||||||
m_inRangeActors.clear();
|
|
||||||
m_inRangePlayers.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! \return ZonePtr to the current zone, nullptr if not set */
|
/*! \return ZonePtr to the current zone, nullptr if not set */
|
||||||
Core::ZonePtr Core::Entity::Actor::getCurrentZone() const
|
Core::ZonePtr Core::Entity::Actor::getCurrentZone() const
|
||||||
{
|
{
|
||||||
|
@ -682,7 +555,7 @@ void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint16_t actionId, u
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
||||||
auto actorsCollided = ActionCollision::getActorsHitFromAction( target.getPos(), getInRangeActors( true ),
|
auto actorsCollided = ActionCollision::getActorsHitFromAction( target.getPos(), getInRangeGameObjects( true ),
|
||||||
actionInfoPtr, TargetFilter::Enemies );
|
actionInfoPtr, TargetFilter::Enemies );
|
||||||
|
|
||||||
for( const auto& pHitActor : actorsCollided )
|
for( const auto& pHitActor : actorsCollided )
|
||||||
|
@ -734,7 +607,7 @@ void Core::Entity::Actor::handleScriptSkill( uint32_t type, uint16_t actionId, u
|
||||||
// todo: get proper packets: the following was just kind of thrown together from what we know.
|
// todo: get proper packets: the following was just kind of thrown together from what we know.
|
||||||
// atm buggy (packets look "delayed" from client)
|
// atm buggy (packets look "delayed" from client)
|
||||||
|
|
||||||
auto actorsCollided = ActionCollision::getActorsHitFromAction( target.getPos(), getInRangeActors( true ),
|
auto actorsCollided = ActionCollision::getActorsHitFromAction( target.getPos(), getInRangeGameObjects( true ),
|
||||||
actionInfoPtr, TargetFilter::Allies );
|
actionInfoPtr, TargetFilter::Allies );
|
||||||
|
|
||||||
for( auto pHitActor : actorsCollided )
|
for( auto pHitActor : actorsCollided )
|
||||||
|
|
|
@ -139,9 +139,6 @@ protected:
|
||||||
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< ActorPtr > m_inRangeActors;
|
|
||||||
std::set< PlayerPtr > m_inRangePlayers;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Actor( ObjKind type );
|
Actor( ObjKind type );
|
||||||
|
|
||||||
|
@ -182,8 +179,6 @@ public:
|
||||||
|
|
||||||
std::string getName() const;
|
std::string getName() const;
|
||||||
|
|
||||||
std::set< ActorPtr > getInRangeActors( bool includeSelf = false );
|
|
||||||
|
|
||||||
bool face( const Common::FFXIVARR_POSITION3& p );
|
bool face( const Common::FFXIVARR_POSITION3& p );
|
||||||
|
|
||||||
Stance getStance() const;
|
Stance getStance() const;
|
||||||
|
@ -233,8 +228,6 @@ public:
|
||||||
|
|
||||||
virtual void autoAttack( ActorPtr pTarget );
|
virtual void autoAttack( ActorPtr pTarget );
|
||||||
|
|
||||||
virtual void onRemoveInRangeActor( Actor& pActor ) {}
|
|
||||||
|
|
||||||
virtual void onDeath() {};
|
virtual void onDeath() {};
|
||||||
virtual void onDamageTaken( Actor& pSource ) {};
|
virtual void onDamageTaken( Actor& pSource ) {};
|
||||||
virtual void onActionHostile( Actor& source ) {};
|
virtual void onActionHostile( Actor& source ) {};
|
||||||
|
@ -255,27 +248,8 @@ public:
|
||||||
|
|
||||||
///// IN RANGE LOGIC /////
|
///// IN RANGE LOGIC /////
|
||||||
|
|
||||||
// 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 );
|
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& pActor );
|
|
||||||
|
|
||||||
// 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;
|
ZonePtr getCurrentZone() const;
|
||||||
|
|
||||||
void setCurrentZone( ZonePtr currZone );
|
void setCurrentZone( ZonePtr currZone );
|
||||||
|
|
|
@ -501,9 +501,13 @@ void Core::Entity::BattleNpc::update( int64_t currTime )
|
||||||
|
|
||||||
case MODE_IDLE:
|
case MODE_IDLE:
|
||||||
{
|
{
|
||||||
ActorPtr pClosestActor = getClosestActor();
|
// this is bad, it should be getClosesPlayer
|
||||||
|
GameObjectPtr pClosestActor = getClosestGameObject();
|
||||||
|
|
||||||
if( pClosestActor && pClosestActor->isAlive() )
|
if( !pClosestActor->isPlayer() )
|
||||||
|
break;
|
||||||
|
|
||||||
|
if( pClosestActor && pClosestActor->getAsPlayer()->isAlive() )
|
||||||
{
|
{
|
||||||
distance = Math::Util::distance( getPos().x, getPos().y, getPos().z,
|
distance = Math::Util::distance( getPos().x, getPos().y, getPos().z,
|
||||||
pClosestActor->getPos().x,
|
pClosestActor->getPos().x,
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
#include "GameObject.h"
|
#include "GameObject.h"
|
||||||
|
|
||||||
|
#include <common/Util/Util.h>
|
||||||
|
#include <common/Util/UtilMath.h>
|
||||||
|
|
||||||
#include "Player.h"
|
#include "Player.h"
|
||||||
#include "Actor.h"
|
#include "Actor.h"
|
||||||
#include "BattleNpc.h"
|
#include "BattleNpc.h"
|
||||||
|
@ -63,6 +66,131 @@ bool Core::Entity::GameObject::isEventNpc() const
|
||||||
return m_objKind == ObjKind::EventNpc;
|
return m_objKind == ObjKind::EventNpc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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::GameObject::addInRangeGameObject( GameObjectPtr pGameObject )
|
||||||
|
{
|
||||||
|
|
||||||
|
// if this is null, something went wrong
|
||||||
|
assert( pGameObject );
|
||||||
|
|
||||||
|
// add actor to in range set
|
||||||
|
m_inRangeGameObjects.insert( { pGameObject } );
|
||||||
|
|
||||||
|
if( pGameObject->isPlayer() )
|
||||||
|
{
|
||||||
|
auto pPlayer = pGameObject->getAsPlayer();
|
||||||
|
|
||||||
|
// if actor is a player, add it to the in range player set
|
||||||
|
m_inRangePlayers.insert( pGameObject->getAsPlayer() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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::GameObject::removeInRangeGameObject( GameObject& gameObject )
|
||||||
|
{
|
||||||
|
// call virtual event
|
||||||
|
onRemoveInRangeGameObject( gameObject );
|
||||||
|
|
||||||
|
// remove actor from in range actor set
|
||||||
|
m_inRangeGameObjects.erase( gameObject.shared_from_this() );
|
||||||
|
|
||||||
|
// if actor is a player, despawn ourself for him
|
||||||
|
// TODO: move to virtual onRemove?
|
||||||
|
if( isPlayer() )
|
||||||
|
gameObject.despawn( getAsPlayer() );
|
||||||
|
|
||||||
|
if( gameObject.isPlayer() )
|
||||||
|
m_inRangePlayers.erase( gameObject.getAsPlayer() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \return true if there is at least one actor in the in range set */
|
||||||
|
bool Core::Entity::GameObject::hasInRangeGameObject() const
|
||||||
|
{
|
||||||
|
return ( m_inRangeGameObjects.size() > 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
void Core::Entity::GameObject::removeFromInRange()
|
||||||
|
{
|
||||||
|
if( !hasInRangeGameObject() )
|
||||||
|
return;
|
||||||
|
|
||||||
|
for( auto& pCurAct : m_inRangeGameObjects )
|
||||||
|
{
|
||||||
|
pCurAct->removeInRangeGameObject( *this );
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! Clear the whole in range set, this does no cleanup */
|
||||||
|
void Core::Entity::GameObject::clearInRangeSet()
|
||||||
|
{
|
||||||
|
m_inRangeGameObjects.clear();
|
||||||
|
m_inRangePlayers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \return list of actors currently in range */
|
||||||
|
std::set< Core::Entity::GameObjectPtr > Core::Entity::GameObject::getInRangeGameObjects( bool includeSelf )
|
||||||
|
{
|
||||||
|
auto tempInRange = m_inRangeGameObjects;
|
||||||
|
|
||||||
|
if( includeSelf )
|
||||||
|
tempInRange.insert( { shared_from_this() } );
|
||||||
|
|
||||||
|
return tempInRange;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*!
|
||||||
|
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::GameObject::isInRangeSet( GameObjectPtr pGameObject ) const
|
||||||
|
{
|
||||||
|
return !( m_inRangeGameObjects.find( pGameObject ) == m_inRangeGameObjects.end() );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \return ActorPtr of the closest actor in range, if none, nullptr */
|
||||||
|
Core::Entity::GameObjectPtr Core::Entity::GameObject::getClosestGameObject()
|
||||||
|
{
|
||||||
|
if( m_inRangeGameObjects.empty() )
|
||||||
|
// no actors in range, don't bother
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
GameObjectPtr tmpActor = nullptr;
|
||||||
|
|
||||||
|
// arbitrary high number
|
||||||
|
float minDistance = 10000;
|
||||||
|
|
||||||
|
for( const auto& pCurAct : m_inRangeGameObjects )
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
/*! \return pointer to this instance as ActorPtr */
|
/*! \return pointer to this instance as ActorPtr */
|
||||||
Core::Entity::ActorPtr Core::Entity::GameObject::getAsActor()
|
Core::Entity::ActorPtr Core::Entity::GameObject::getAsActor()
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,6 +49,9 @@ namespace Entity {
|
||||||
/*! Type of the actor */
|
/*! Type of the actor */
|
||||||
ObjKind m_objKind;
|
ObjKind m_objKind;
|
||||||
|
|
||||||
|
std::set< GameObjectPtr > m_inRangeGameObjects;
|
||||||
|
std::set< PlayerPtr > m_inRangePlayers;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit GameObject( ObjKind type );
|
explicit GameObject( ObjKind type );
|
||||||
virtual ~GameObject() {};
|
virtual ~GameObject() {};
|
||||||
|
@ -56,6 +59,29 @@ namespace Entity {
|
||||||
virtual void spawn( PlayerPtr pTarget ) {}
|
virtual void spawn( PlayerPtr pTarget ) {}
|
||||||
virtual void despawn( PlayerPtr pTarget ) {}
|
virtual void despawn( PlayerPtr pTarget ) {}
|
||||||
|
|
||||||
|
virtual void onRemoveInRangeGameObject( GameObject &pGameObject ) {}
|
||||||
|
|
||||||
|
// add an actor to in range set
|
||||||
|
void addInRangeGameObject( GameObjectPtr pGameObject );
|
||||||
|
|
||||||
|
// remove an actor from the in range set
|
||||||
|
void removeInRangeGameObject( GameObject& pGameObject );
|
||||||
|
|
||||||
|
// return true if there is at least one actor in the in range set
|
||||||
|
bool hasInRangeGameObject() const;
|
||||||
|
|
||||||
|
void removeFromInRange();
|
||||||
|
|
||||||
|
// clear the whole in range set, this does no cleanup
|
||||||
|
virtual void clearInRangeSet();
|
||||||
|
|
||||||
|
std::set< GameObjectPtr > getInRangeGameObjects( bool includeSelf = false );
|
||||||
|
|
||||||
|
// check if another actor is in the actors in range set
|
||||||
|
bool isInRangeSet( GameObjectPtr pGameObject ) const;
|
||||||
|
|
||||||
|
GameObjectPtr getClosestGameObject();
|
||||||
|
|
||||||
uint32_t getId() const;
|
uint32_t getId() const;
|
||||||
|
|
||||||
ObjKind getObjKind() const;
|
ObjKind getObjKind() const;
|
||||||
|
|
|
@ -831,14 +831,14 @@ void Core::Entity::Player::despawn( Entity::PlayerPtr pTarget )
|
||||||
|
|
||||||
Core::Entity::ActorPtr Core::Entity::Player::lookupTargetById( uint64_t targetId )
|
Core::Entity::ActorPtr Core::Entity::Player::lookupTargetById( uint64_t targetId )
|
||||||
{
|
{
|
||||||
ActorPtr targetActor;
|
GameObjectPtr targetActor;
|
||||||
auto inRange = getInRangeActors( true );
|
auto inRange = getInRangeGameObjects(true);
|
||||||
for( auto actor : inRange )
|
for( auto actor : inRange )
|
||||||
{
|
{
|
||||||
if( actor->getId() == targetId )
|
if( actor->getId() == targetId )
|
||||||
targetActor = actor;
|
targetActor = actor;
|
||||||
}
|
}
|
||||||
return targetActor;
|
return targetActor->getAsActor();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Core::Entity::Player::setLastPing( uint32_t ping )
|
void Core::Entity::Player::setLastPing( uint32_t ping )
|
||||||
|
@ -1005,9 +1005,12 @@ void Core::Entity::Player::update( int64_t currTime )
|
||||||
auto mainWeap = m_pInventory->getItemAt( Inventory::GearSet0, Inventory::EquipSlot::MainHand );
|
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...
|
// @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_inRangeActors )
|
for( auto actor : m_inRangeGameObjects )
|
||||||
{
|
{
|
||||||
if( actor->getId() == m_targetId && actor->isAlive() && mainWeap )
|
if( actor->getId() != m_targetId || !actor->isBattleNpc() )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if( actor->getAsBattleNpc()->isAlive() && mainWeap )
|
||||||
{
|
{
|
||||||
// default autoattack range
|
// default autoattack range
|
||||||
// TODO make this dependant on bnpc size
|
// TODO make this dependant on bnpc size
|
||||||
|
@ -1027,7 +1030,7 @@ void Core::Entity::Player::update( int64_t currTime )
|
||||||
if( ( currTime - m_lastAttack ) > mainWeap->getDelay() )
|
if( ( currTime - m_lastAttack ) > mainWeap->getDelay() )
|
||||||
{
|
{
|
||||||
m_lastAttack = currTime;
|
m_lastAttack = currTime;
|
||||||
autoAttack( actor );
|
autoAttack( actor->getAsBattleNpc() );
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -113,11 +113,11 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
auto inRange = player.getInRangeActors();
|
auto inRange = player.getInRangeGameObjects();
|
||||||
for( auto actor : inRange )
|
for( auto actor : inRange )
|
||||||
{
|
{
|
||||||
if( actor->getId() == param3 )
|
if( actor->getId() == param3 )
|
||||||
targetActor = actor;
|
targetActor = actor->getAsActor();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -138,7 +138,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
|
||||||
targetPlayer->setLookAt( CharaLook::Race, param1 );
|
targetPlayer->setLookAt( CharaLook::Race, param1 );
|
||||||
player.sendNotice( "Race for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) );
|
player.sendNotice( "Race for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) );
|
||||||
targetPlayer->spawn( targetPlayer );
|
targetPlayer->spawn( targetPlayer );
|
||||||
auto inRange = targetPlayer->getInRangeActors();
|
auto inRange = targetPlayer->getInRangeGameObjects();
|
||||||
for( auto actor : inRange )
|
for( auto actor : inRange )
|
||||||
{
|
{
|
||||||
targetPlayer->despawn( actor->getAsPlayer() );
|
targetPlayer->despawn( actor->getAsPlayer() );
|
||||||
|
@ -151,7 +151,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
|
||||||
targetPlayer->setLookAt( CharaLook::Tribe, param1 );
|
targetPlayer->setLookAt( CharaLook::Tribe, param1 );
|
||||||
player.sendNotice( "Tribe for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) );
|
player.sendNotice( "Tribe for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) );
|
||||||
targetPlayer->spawn( targetPlayer );
|
targetPlayer->spawn( targetPlayer );
|
||||||
auto inRange = targetPlayer->getInRangeActors();
|
auto inRange = targetPlayer->getInRangeGameObjects();
|
||||||
for( auto actor : inRange )
|
for( auto actor : inRange )
|
||||||
{
|
{
|
||||||
targetPlayer->despawn( actor->getAsPlayer() );
|
targetPlayer->despawn( actor->getAsPlayer() );
|
||||||
|
@ -164,7 +164,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
|
||||||
targetPlayer->setLookAt( CharaLook::Gender, param1 );
|
targetPlayer->setLookAt( CharaLook::Gender, param1 );
|
||||||
player.sendNotice( "Sex for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) );
|
player.sendNotice( "Sex for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) );
|
||||||
targetPlayer->spawn( targetPlayer );
|
targetPlayer->spawn( targetPlayer );
|
||||||
auto inRange = targetActor->getInRangeActors();
|
auto inRange = targetActor->getInRangeGameObjects();
|
||||||
for( auto actor : inRange )
|
for( auto actor : inRange )
|
||||||
{
|
{
|
||||||
targetPlayer->despawn( actor->getAsPlayer() );
|
targetPlayer->despawn( actor->getAsPlayer() );
|
||||||
|
@ -439,7 +439,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
|
||||||
case GmCommand::Jump:
|
case GmCommand::Jump:
|
||||||
{
|
{
|
||||||
|
|
||||||
auto inRange = player.getInRangeActors();
|
auto inRange = player.getInRangeGameObjects();
|
||||||
|
|
||||||
player.changePosition( targetActor->getPos().x, targetActor->getPos().y, targetActor->getPos().z,
|
player.changePosition( targetActor->getPos().x, targetActor->getPos().y, targetActor->getPos().z,
|
||||||
targetActor->getRotation() );
|
targetActor->getRotation() );
|
||||||
|
|
|
@ -190,7 +190,7 @@ void Core::Network::GameConnection::updatePositionHandler( const Packets::GamePa
|
||||||
player.getCurrentAction()->setInterrupted();
|
player.getCurrentAction()->setInterrupted();
|
||||||
|
|
||||||
// if no one is in range, don't bother trying to send a position update
|
// if no one is in range, don't bother trying to send a position update
|
||||||
if( !player.hasInRangeActor() )
|
if( !player.hasInRangeGameObject() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
uint8_t unk = inPacket.getValAt< uint8_t >( 0x29 );
|
uint8_t unk = inPacket.getValAt< uint8_t >( 0x29 );
|
||||||
|
|
|
@ -737,8 +737,8 @@ void Core::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell )
|
||||||
if( count > 12 )
|
if( count > 12 )
|
||||||
break;
|
break;
|
||||||
|
|
||||||
pActor->addInRangeActor( pCurAct );
|
pActor->addInRangeGameObject( pCurAct );
|
||||||
pCurAct->addInRangeActor( pActor );
|
pCurAct->addInRangeGameObject( pActor );
|
||||||
// spawn the actor for the player
|
// spawn the actor for the player
|
||||||
pCurAct->spawn( pOwnPlayer );
|
pCurAct->spawn( pOwnPlayer );
|
||||||
|
|
||||||
|
@ -758,24 +758,24 @@ void Core::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell )
|
||||||
if( pPlayer->isLoadingComplete() )
|
if( pPlayer->isLoadingComplete() )
|
||||||
{
|
{
|
||||||
pActor->spawn( pPlayer );
|
pActor->spawn( pPlayer );
|
||||||
pCurAct->addInRangeActor( pActor );
|
pCurAct->addInRangeGameObject( pActor );
|
||||||
pActor->addInRangeActor( pCurAct );
|
pActor->addInRangeGameObject( pCurAct );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
pActor->addInRangeActor( pCurAct );
|
pActor->addInRangeGameObject( pCurAct );
|
||||||
pCurAct->addInRangeActor( pActor );
|
pCurAct->addInRangeGameObject( pActor );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( !isInRange && isInRangeSet )
|
else if( !isInRange && isInRangeSet )
|
||||||
{
|
{
|
||||||
pCurAct->removeInRangeActor( *pActor );
|
pCurAct->removeInRangeGameObject( *pActor );
|
||||||
|
|
||||||
if( pActor->getCurrentZone() != pCurAct->getCurrentZone() )
|
if( pActor->getCurrentZone() != pCurAct->getCurrentZone() )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
pActor->removeInRangeActor( *pCurAct );
|
pActor->removeInRangeGameObject( *pCurAct );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue