1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-30 08:07:46 +00:00

Renaming classes in preperation of actor rework

This commit is contained in:
Mordred 2018-02-20 22:46:44 +01:00
parent ba511a23e2
commit 9a4e7533c6
54 changed files with 1749 additions and 1774 deletions

View file

@ -33,10 +33,10 @@ switch( commandId )
case 0x01: // Toggle sheathe case 0x01: // Toggle sheathe
{ {
if ( param11 == 1 ) if ( param11 == 1 )
pPlayer->setStance( Entity::Actor::Stance::Active ); pPlayer->setStance( Entity::Chara::Stance::Active );
else else
{ {
pPlayer->setStance( Entity::Actor::Stance::Passive ); pPlayer->setStance( Entity::Chara::Stance::Passive );
pPlayer->setAutoattack( false ); pPlayer->setAutoattack( false );
} }

View file

@ -34,11 +34,11 @@ namespace Core
namespace Entity namespace Entity
{ {
class Actor; class Chara;
class Player; class Player;
class BattleNpc; class BattleNpc;
typedef boost::shared_ptr<Actor> ActorPtr; typedef boost::shared_ptr<Chara> ActorPtr;
typedef boost::shared_ptr<Player> PlayerPtr; typedef boost::shared_ptr<Player> PlayerPtr;
typedef boost::shared_ptr<BattleNpc> BattleNpcPtr; typedef boost::shared_ptr<BattleNpc> BattleNpcPtr;
} }

View file

@ -22,7 +22,7 @@ Core::Common::HandleActionType Core::Action::Action::getHandleActionType() const
return m_handleActionType; return m_handleActionType;
} }
Core::Entity::ActorPtr Core::Action::Action::getTargetActor() const Core::Entity::CharaPtr Core::Action::Action::getTargetChara() const
{ {
return m_pTarget; return m_pTarget;
} }
@ -57,7 +57,7 @@ void Core::Action::Action::setCastTime( uint32_t castTime )
m_castTime = castTime; m_castTime = castTime;
} }
Core::Entity::ActorPtr Core::Action::Action::getActionSource() const Core::Entity::CharaPtr Core::Action::Action::getActionSource() const
{ {
return m_pSource; return m_pSource;
} }

View file

@ -18,7 +18,7 @@ namespace Action {
Common::HandleActionType getHandleActionType() const; Common::HandleActionType getHandleActionType() const;
Entity::ActorPtr getTargetActor() const; Entity::CharaPtr getTargetChara() const;
bool isInterrupted() const; bool isInterrupted() const;
@ -32,7 +32,7 @@ namespace Action {
void setCastTime( uint32_t castTime ); void setCastTime( uint32_t castTime );
Entity::ActorPtr getActionSource() const; Entity::CharaPtr getActionSource() const;
virtual void onStart() {}; virtual void onStart() {};
virtual void onFinish() {}; virtual void onFinish() {};
@ -48,8 +48,8 @@ namespace Action {
uint64_t m_startTime; uint64_t m_startTime;
uint32_t m_castTime; uint32_t m_castTime;
Entity::ActorPtr m_pSource; Entity::CharaPtr m_pSource;
Entity::ActorPtr m_pTarget; Entity::CharaPtr m_pTarget;
bool m_bInterrupt; bool m_bInterrupt;

View file

@ -26,7 +26,7 @@ Core::Action::ActionCast::ActionCast()
m_handleActionType = Common::HandleActionType::Event; m_handleActionType = Common::HandleActionType::Event;
} }
Core::Action::ActionCast::ActionCast( Entity::ActorPtr pActor, Entity::ActorPtr pTarget, uint16_t actionId ) Core::Action::ActionCast::ActionCast( Entity::CharaPtr pActor, Entity::CharaPtr pTarget, uint16_t actionId )
{ {
m_startTime = 0; m_startTime = 0;
m_id = actionId; m_id = actionId;

View file

@ -15,7 +15,7 @@ namespace Action {
ActionCast(); ActionCast();
~ActionCast(); ~ActionCast();
ActionCast( Entity::ActorPtr pActor, Entity::ActorPtr pTarget, uint16_t actionId ); ActionCast( Entity::CharaPtr pActor, Entity::CharaPtr pTarget, uint16_t actionId );
void onStart() override; void onStart() override;
void onFinish() override; void onFinish() override;

View file

@ -2,7 +2,7 @@
#include <common/Util/UtilMath.h> #include <common/Util/UtilMath.h>
#include "ActionCollision.h" #include "ActionCollision.h"
#include "Actor/Actor.h" #include "Actor/Chara.h"
#include "Actor/Player.h" #include "Actor/Player.h"
#include <cmath> #include <cmath>
@ -13,7 +13,7 @@ using namespace Core::Common;
// todo: add AoE actor limits (16, 32) // todo: add AoE actor limits (16, 32)
bool ActionCollision::isActorApplicable( Actor& actor, TargetFilter targetFilter ) bool ActionCollision::isActorApplicable( Chara& chara, TargetFilter targetFilter )
{ {
bool actorApplicable = false; bool actorApplicable = false;
switch( targetFilter ) switch( targetFilter )
@ -25,37 +25,37 @@ bool ActionCollision::isActorApplicable( Actor& actor, TargetFilter targetFilter
} }
case TargetFilter::Players: case TargetFilter::Players:
{ {
actorApplicable = actor.isPlayer(); actorApplicable = chara.isPlayer();
break; break;
} }
case TargetFilter::Allies: case TargetFilter::Allies:
{ {
// todo: implement ally NPCs // todo: implement ally NPCs
actorApplicable = !actor.isBattleNpc(); actorApplicable = !chara.isBattleNpc();
break; break;
} }
case TargetFilter::Party: case TargetFilter::Party:
{ {
// todo: implement party // todo: implement party
actorApplicable = actor.isPlayer(); actorApplicable = chara.isPlayer();
break; break;
} }
case TargetFilter::Enemies: case TargetFilter::Enemies:
{ {
actorApplicable = actor.isBattleNpc(); actorApplicable = chara.isBattleNpc();
break; break;
} }
} }
return ( actorApplicable && actor.isAlive() ); return ( actorApplicable && chara.isAlive() );
} }
std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition, std::set< Core::Entity::CharaPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition,
std::set< ActorPtr > actorsInRange, std::set< CharaPtr > actorsInRange,
boost::shared_ptr< Core::Data::Action > actionInfo, boost::shared_ptr< Core::Data::Action > actionInfo,
TargetFilter targetFilter ) TargetFilter targetFilter )
{ {
std::set< ActorPtr > actorsCollided; std::set< CharaPtr > actorsCollided;
switch( static_cast< ActionCollisionType >( actionInfo->castType ) ) switch( static_cast< ActionCollisionType >( actionInfo->castType ) )
{ {

View file

@ -4,7 +4,7 @@
#include <common/Common.h> #include <common/Common.h>
#include <common/Exd/ExdDataGenerated.h> #include <common/Exd/ExdDataGenerated.h>
#include "Actor/Actor.h" #include "Actor/Chara.h"
#include "Action.h" #include "Action.h"
namespace Core { namespace Core {
@ -23,9 +23,9 @@ namespace Entity {
{ {
public: public:
static bool isActorApplicable( Actor& actor, TargetFilter targetFilter ); static bool isActorApplicable( Chara& actor, TargetFilter targetFilter );
static std::set< ActorPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition, static std::set< CharaPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition,
std::set< ActorPtr > actorsInRange, std::set< CharaPtr > actorsInRange,
boost::shared_ptr< Data::Action > actionInfo, boost::shared_ptr< Data::Action > actionInfo,
TargetFilter targetFilter ); TargetFilter targetFilter );

View file

@ -24,7 +24,7 @@ Core::Action::ActionMount::ActionMount()
m_handleActionType = HandleActionType::Event; m_handleActionType = HandleActionType::Event;
} }
Core::Action::ActionMount::ActionMount( Entity::ActorPtr pActor, uint16_t mountId ) Core::Action::ActionMount::ActionMount( Entity::CharaPtr pActor, uint16_t mountId )
{ {
m_startTime = 0; m_startTime = 0;
m_id = mountId; m_id = mountId;

View file

@ -15,7 +15,7 @@ namespace Action {
ActionMount(); ActionMount();
~ActionMount(); ~ActionMount();
ActionMount( Entity::ActorPtr pActor, uint16_t mountId ); ActionMount( Entity::CharaPtr pActor, uint16_t mountId );
void onStart() override; void onStart() override;
void onFinish() override; void onFinish() override;

View file

@ -21,7 +21,7 @@ Core::Action::ActionTeleport::ActionTeleport()
m_handleActionType = HandleActionType::Event; m_handleActionType = HandleActionType::Event;
} }
Core::Action::ActionTeleport::ActionTeleport( Entity::ActorPtr pActor, uint16_t targetZone, uint16_t cost ) Core::Action::ActionTeleport::ActionTeleport( Entity::CharaPtr pActor, uint16_t targetZone, uint16_t cost )
{ {
m_startTime = 0; m_startTime = 0;
m_id = 5; m_id = 5;

View file

@ -17,7 +17,7 @@ namespace Action {
ActionTeleport(); ActionTeleport();
~ActionTeleport(); ~ActionTeleport();
ActionTeleport( Entity::ActorPtr pActor, uint16_t action, uint16_t cost ); ActionTeleport( Entity::CharaPtr pActor, uint16_t action, uint16_t cost );
void onStart() override; void onStart() override;
void onFinish() override; void onFinish() override;

View file

@ -21,7 +21,7 @@ Core::Action::EventAction::EventAction()
m_handleActionType = HandleActionType::Event; m_handleActionType = HandleActionType::Event;
} }
Core::Action::EventAction::EventAction( Entity::ActorPtr pActor, uint32_t eventId, uint16_t action, Core::Action::EventAction::EventAction( Entity::CharaPtr pActor, uint32_t eventId, uint16_t action,
ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional ) ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional )
{ {
m_additional = additional; m_additional = additional;

View file

@ -16,7 +16,7 @@ namespace Action {
EventAction(); EventAction();
~EventAction(); ~EventAction();
EventAction( Entity::ActorPtr pActor, uint32_t eventId, uint16_t action, EventAction( Entity::CharaPtr pActor, uint32_t eventId, uint16_t action,
ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional ); ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional );
void onStart() override; void onStart() override;

View file

@ -22,7 +22,7 @@ Core::Action::EventItemAction::EventItemAction()
m_handleActionType = HandleActionType::Event; m_handleActionType = HandleActionType::Event;
} }
Core::Action::EventItemAction::EventItemAction( Entity::ActorPtr pActor, uint32_t eventId, uint16_t action, Core::Action::EventItemAction::EventItemAction( Entity::CharaPtr pActor, uint32_t eventId, uint16_t action,
ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional ) ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional )
{ {
m_additional = additional; m_additional = additional;

View file

@ -14,7 +14,7 @@ namespace Action {
EventItemAction(); EventItemAction();
~EventItemAction(); ~EventItemAction();
EventItemAction( Entity::ActorPtr pActor, uint32_t eventId, uint16_t action, EventItemAction( Entity::CharaPtr pActor, uint32_t eventId, uint16_t action,
ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional ); ActionCallback finishRef, ActionCallback interruptRef, uint64_t additional );
void onStart() override; void onStart() override;

File diff suppressed because it is too large Load diff

View file

@ -1,11 +1,10 @@
#ifndef _ACTOR_H_ #ifndef _GAME_OBJECT_H_
#define _ACTOR_H_ #define _GAME_OBJECT_H_
#include <common/Common.h> #include <common/Common.h>
#include <boost/enable_shared_from_this.hpp> #include <boost/enable_shared_from_this.hpp>
#include "Forwards.h" #include "Forwards.h"
#include "GameObject.h"
#include <set> #include <set>
#include <map> #include <map>
#include <queue> #include <queue>
@ -14,280 +13,68 @@ namespace Core {
namespace Entity { namespace Entity {
/*! /*!
\class Actor \class GameObject
\brief Base class for all actors \brief Base class for all actor/objects
*/ */
class Actor : public GameObject class Actor : public boost::enable_shared_from_this< Actor >
{ {
public: public:
enum Stance : uint8_t enum ObjKind : uint8_t
{ {
Passive = 0, None = 0x00,
Active = 1, Player = 0x01,
BattleNpc = 0x02,
EventNpc = 0x03,
Treasure = 0x04,
Aetheryte = 0x05,
GatheringPoint = 0x06,
EventObj = 0x07,
Mount = 0x08,
Companion = 0x09,
Retainer = 0x0A,
Area = 0x0B,
Housing = 0x0C,
Cutscene = 0x0D,
CardStand = 0x0E,
}; };
enum DisplayFlags : uint16_t
{
ActiveStance = 0x001,
Invisible = 0x020,
HideHead = 0x040,
HideWeapon = 0x080,
Faded = 0x100,
Visor = 0x800,
};
enum struct ActorStatus : uint8_t
{
Idle = 0x01,
Dead = 0x02,
Sitting = 0x03,
Mounted = 0x04,
Crafting = 0x05,
Gathering = 0x06,
Melding = 0x07,
SMachine = 0x08
};
struct ActorStats
{
uint32_t max_mp = 0;
uint32_t max_hp = 0;
uint32_t str = 0;
uint32_t dex = 0;
uint32_t vit = 0;
uint32_t inte = 0;
uint32_t mnd = 0;
uint32_t pie = 0;
uint32_t tenacity = 0;
uint32_t attack = 0;
uint32_t defense = 0;
uint32_t accuracy = 0;
uint32_t spellSpeed = 0;
uint32_t magicDefense = 0;
uint32_t critHitRate = 0;
uint32_t resistSlash = 0;
uint32_t resistPierce = 0;
uint32_t resistBlunt = 0;
uint32_t attackPotMagic = 0;
uint32_t healingPotMagic = 0;
uint32_t determination = 0;
uint32_t skillSpeed = 0;
uint32_t resistSlow = 0;
uint32_t resistSilence = 0;
uint32_t resistBlind = 0;
uint32_t resistPoison = 0;
uint32_t resistStun = 0;
uint32_t resistSleep = 0;
uint32_t resistBind = 0;
uint32_t resistHeavy = 0;
uint32_t resistFire = 0;
uint32_t resistIce = 0;
uint32_t resistWind = 0;
uint32_t resistEarth = 0;
uint32_t resistLightning = 0;
uint32_t resistWater = 0;
} m_baseStats;
protected: protected:
char m_name[34]; /*! Position of the object */
/*! Id of the zone the actor currently is in */ Common::FFXIVARR_POSITION3 m_pos;
uint32_t m_zoneId; /*! Rotation of the object */
/*! Ptr to the ZoneObj the actor belongs to */ float m_rot;
ZonePtr m_pCurrentZone; /*! Id of the actor */
/*! Last tick time for the actor ( in ms ) */ uint32_t m_id;
uint64_t m_lastTickTime; /*! Type of the actor */
/*! Last time the actor performed an autoAttack ( in ms ) */ ObjKind m_objKind;
uint64_t m_lastAttack;
/*! Last time the actor was updated ( in ms ) */
uint64_t m_lastUpdate;
/*! Current stance of the actor */
Stance m_currentStance;
/*! Current staus of the actor */
ActorStatus m_status;
/*! Max HP of the actor ( based on job / class ) */
uint32_t m_maxHp;
/*! Max MP of the actor ( based on job / class ) */
uint32_t m_maxMp;
/*! Current HP of the actor */
uint32_t m_hp;
/*! Current MP of the actor */
uint32_t m_mp;
/*! Current TP of the actor */
uint16_t m_tp;
/*! Current GP of the actor */
uint16_t m_gp;
/*! Additional look info of the actor */
uint8_t m_customize[26];
/*! Current class of the actor */
Common::ClassJob m_class;
/*! Id of the currently selected target actor */
uint64_t m_targetId;
/*! Ptr to a queued action */
Action::ActionPtr m_pCurrentAction;
/*! Invincibility type */
Common::InvincibilityType m_invincibilityType;
/*! Status effects */
const uint8_t MAX_STATUS_EFFECTS = 30;
std::queue< uint8_t > m_statusEffectFreeSlotQueue;
std::vector< std::pair< uint8_t, uint32_t> > m_statusEffectList;
std::map< uint8_t, StatusEffect::StatusEffectPtr > m_statusEffectMap;
std::set< ActorPtr > m_inRangeActors;
std::set< PlayerPtr > m_inRangePlayers;
public: public:
Actor( ObjKind type ); explicit Actor( ObjKind type );
virtual ~Actor() {};
virtual ~Actor() override; virtual void spawn( PlayerPtr pTarget ) {}
virtual void despawn( PlayerPtr pTarget ) {}
virtual void calculateStats() {}; uint32_t getId() const;
/// Status effect functions ObjKind getObjKind() const;
void addStatusEffect( StatusEffect::StatusEffectPtr pEffect );
void removeStatusEffect( uint8_t effectSlotId );
void removeSingleStatusEffectById( uint32_t id );
void updateStatusEffects();
bool hasStatusEffect( uint32_t id ); Common::FFXIVARR_POSITION3& getPos();
void setPos( const Common::FFXIVARR_POSITION3& pos );
void setPos( float x, float y, float z );
int8_t getStatusEffectFreeSlot(); float getRot() const;
void statusEffectFreeSlot( uint8_t slotId ); void setRot( float rot );
std::map< uint8_t, Core::StatusEffect::StatusEffectPtr > getStatusEffectMap() const; bool isPlayer() const;
bool isBattleNpc() const;
void sendStatusEffectUpdate(); bool isEventNpc() const;
// add a status effect by id
void addStatusEffectById( uint32_t id, int32_t duration, Entity::Actor& pSource, uint16_t param = 0 );
// add a status effect by id if it doesn't exist
void addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Actor& pSource, uint16_t param = 0 );
// remove a status effect by id
void removeSingleStatusEffectFromId( uint32_t id );
/// End Status Effect Functions
void setPosition( const Common::FFXIVARR_POSITION3& pos );
void setPosition( float x, float y, float z );
void setRotation( float rot );
float getRotation() const;
std::string getName() const;
std::set< ActorPtr > getInRangeActors( bool includeSelf = false );
bool face( const Common::FFXIVARR_POSITION3& p );
Stance getStance() const;
void setStance( Stance stance );
ActorStats getStats() const;
uint32_t getHp() const;
uint32_t getMp() const;
uint16_t getTp() const;
uint16_t getGp() const;
Common::InvincibilityType getInvincibilityType() const;
Common::ClassJob getClass() const;
uint8_t getClassAsInt() const;
void setClass( Common::ClassJob classJob );
void setTargetId( uint64_t targetId );
uint64_t getTargetId() const;
bool isAlive() const;
virtual uint32_t getMaxHp() const;
virtual uint32_t getMaxMp() const;
void resetHp();
void resetMp();
void setHp( uint32_t hp );
void setMp( uint32_t mp );
void setGp( uint32_t gp );
void setInvincibilityType( Common::InvincibilityType type );
void die();
ActorStatus getStatus() const;
void setStatus( ActorStatus status );
void handleScriptSkill( uint32_t type, uint16_t actionId, uint64_t param1, uint64_t param2, Entity::Actor& target );
virtual void autoAttack( ActorPtr pTarget );
virtual void onRemoveInRangeActor( Actor& pActor ) {}
virtual void onDeath() {};
virtual void onDamageTaken( Actor& pSource ) {};
virtual void onActionHostile( Actor& source ) {};
virtual void onActionFriendly( Actor& pSource ) {};
virtual void onTick() {};
virtual void changeTarget( uint64_t targetId );
virtual uint8_t getLevel() const;
virtual void sendStatusUpdate( bool toSelf = true );
virtual void takeDamage( uint32_t damage );
virtual void heal( uint32_t amount );
virtual bool checkAction();
virtual void update( int64_t currTime ) {};
Action::ActionPtr getCurrentAction() const;
void setCurrentAction( Action::ActionPtr pAction );
///// 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 );
// 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;
void setCurrentZone( ZonePtr currZone );
// get the current cell of a region the actor is in
Cell* getCell() const;
// set the current cell
void setCell( Cell* pCell );
Core::Cell* m_pCell;
CharaPtr getAsChara();
PlayerPtr getAsPlayer();
BattleNpcPtr getAsBattleNpc();
EventNpcPtr getAsEventNpc();
}; };
} }

View file

@ -26,7 +26,7 @@ extern Core::Data::ExdDataGenerated g_exdDataGen;
uint32_t Core::Entity::BattleNpc::m_nextID = 1149241694; uint32_t Core::Entity::BattleNpc::m_nextID = 1149241694;
Core::Entity::BattleNpc::BattleNpc() : Core::Entity::BattleNpc::BattleNpc() :
Actor( ObjKind::BattleNpc ) Chara( ObjKind::BattleNpc )
{ {
m_id = 0; m_id = 0;
m_status = ActorStatus::Idle; m_status = ActorStatus::Idle;
@ -40,7 +40,7 @@ Core::Entity::BattleNpc::~BattleNpc()
Core::Entity::BattleNpc::BattleNpc( uint16_t modelId, uint16_t nameid, const Common::FFXIVARR_POSITION3& spawnPos, Core::Entity::BattleNpc::BattleNpc( uint16_t modelId, uint16_t nameid, const Common::FFXIVARR_POSITION3& spawnPos,
uint16_t bnpcBaseId, uint32_t type, uint8_t level, uint8_t behaviour, uint16_t bnpcBaseId, uint32_t type, uint8_t level, uint8_t behaviour,
uint32_t mobType ) : uint32_t mobType ) :
Actor( ObjKind::BattleNpc ) Chara( ObjKind::BattleNpc )
{ {
BattleNpc::m_nextID++; BattleNpc::m_nextID++;
m_id = BattleNpc::m_nextID; m_id = BattleNpc::m_nextID;
@ -177,16 +177,16 @@ uint8_t Core::Entity::BattleNpc::getbehavior() const
return m_behavior; return m_behavior;
} }
void Core::Entity::BattleNpc::hateListAdd( Actor& actor, int32_t hateAmount ) void Core::Entity::BattleNpc::hateListAdd( Chara& actor, int32_t hateAmount )
{ {
auto hateEntry = new HateListEntry(); auto hateEntry = new HateListEntry();
hateEntry->m_hateAmount = hateAmount; hateEntry->m_hateAmount = hateAmount;
hateEntry->m_pActor = actor.getAsActor(); hateEntry->m_pChara = actor.getAsChara();
m_hateList.insert( hateEntry ); m_hateList.insert( hateEntry );
} }
Core::Entity::ActorPtr Core::Entity::BattleNpc::hateListGetHighest() Core::Entity::CharaPtr Core::Entity::BattleNpc::hateListGetHighest()
{ {
auto it = m_hateList.begin(); auto it = m_hateList.begin();
@ -202,7 +202,7 @@ Core::Entity::ActorPtr Core::Entity::BattleNpc::hateListGetHighest()
} }
if( entry && maxHate != 0 ) if( entry && maxHate != 0 )
return entry->m_pActor; return entry->m_pChara;
return nullptr; return nullptr;
} }
@ -274,7 +274,7 @@ bool Core::Entity::BattleNpc::moveTo( Common::FFXIVARR_POSITION3& pos )
} }
void Core::Entity::BattleNpc::aggro( Actor& actor ) void Core::Entity::BattleNpc::aggro( Chara& actor )
{ {
m_lastAttack = Util::getTimeMs(); m_lastAttack = Util::getTimeMs();
@ -292,7 +292,7 @@ void Core::Entity::BattleNpc::aggro( Actor& actor )
} }
} }
void Core::Entity::BattleNpc::deaggro( Actor& actor ) void Core::Entity::BattleNpc::deaggro( Chara& actor )
{ {
if( !hateListHasActor( actor ) ) if( !hateListHasActor( actor ) )
hateListRemove( actor ); hateListRemove( actor );
@ -309,8 +309,8 @@ void Core::Entity::BattleNpc::hateListClear()
auto it = m_hateList.begin(); auto it = m_hateList.begin();
for( ; it != m_hateList.end(); ++it ) for( ; it != m_hateList.end(); ++it )
{ {
if( isInRangeSet( ( *it )->m_pActor ) ) if( isInRangeSet( ( *it )->m_pChara ) )
deaggro( *( *it )->m_pActor ); deaggro( *( *it )->m_pChara );
HateListEntry* tmpListEntry = ( *it ); HateListEntry* tmpListEntry = ( *it );
delete tmpListEntry; delete tmpListEntry;
} }
@ -318,12 +318,12 @@ void Core::Entity::BattleNpc::hateListClear()
} }
void Core::Entity::BattleNpc::hateListRemove( Actor& actor ) void Core::Entity::BattleNpc::hateListRemove( Chara& actor )
{ {
auto it = m_hateList.begin(); auto it = m_hateList.begin();
for( ; it != m_hateList.end(); ++it ) for( ; it != m_hateList.end(); ++it )
{ {
if( ( *it )->m_pActor->getId() == actor.getId() ) if( ( *it )->m_pChara->getId() == actor.getId() )
{ {
HateListEntry* pEntry = *it; HateListEntry* pEntry = *it;
m_hateList.erase( it ); m_hateList.erase( it );
@ -338,12 +338,12 @@ void Core::Entity::BattleNpc::hateListRemove( Actor& actor )
} }
} }
bool Core::Entity::BattleNpc::hateListHasActor( Actor& actor ) bool Core::Entity::BattleNpc::hateListHasActor( Chara& actor )
{ {
auto it = m_hateList.begin(); auto it = m_hateList.begin();
for( ; it != m_hateList.end(); ++it ) for( ; it != m_hateList.end(); ++it )
{ {
if( ( *it )->m_pActor->getId() == actor.getId() ) if( ( *it )->m_pChara->getId() == actor.getId() )
return true; return true;
} }
return false; return false;
@ -359,13 +359,13 @@ uint32_t Core::Entity::BattleNpc::getNameId() const
return m_nameId; return m_nameId;
} }
void Core::Entity::BattleNpc::hateListUpdate( Actor& actor, int32_t hateAmount ) void Core::Entity::BattleNpc::hateListUpdate( Chara& actor, int32_t hateAmount )
{ {
auto it = m_hateList.begin(); auto it = m_hateList.begin();
for( ; it != m_hateList.end(); ++it ) for( ; it != m_hateList.end(); ++it )
{ {
if( ( *it )->m_pActor->getId() == actor.getId() ) if( ( *it )->m_pChara->getId() == actor.getId() )
{ {
( *it )->m_hateAmount += hateAmount; ( *it )->m_hateAmount += hateAmount;
return; return;
@ -374,7 +374,7 @@ void Core::Entity::BattleNpc::hateListUpdate( Actor& actor, int32_t hateAmount )
auto hateEntry = new HateListEntry(); auto hateEntry = new HateListEntry();
hateEntry->m_hateAmount = hateAmount; hateEntry->m_hateAmount = hateAmount;
hateEntry->m_pActor = actor.getAsActor(); hateEntry->m_pChara = actor.getAsChara();
m_hateList.insert( hateEntry ); m_hateList.insert( hateEntry );
} }
@ -396,7 +396,7 @@ void Core::Entity::BattleNpc::onDeath()
uint32_t totalHate = 0; uint32_t totalHate = 0;
for( auto& pHateEntry : m_hateList ) for( auto& pHateEntry : m_hateList )
{ {
if( pHateEntry->m_pActor->isPlayer() ) if( pHateEntry->m_pChara->isPlayer() )
{ {
if( pHateEntry->m_hateAmount < minHate ) if( pHateEntry->m_hateAmount < minHate )
minHate = pHateEntry->m_hateAmount; minHate = pHateEntry->m_hateAmount;
@ -412,9 +412,9 @@ void Core::Entity::BattleNpc::onDeath()
{ {
// todo: this is pure retarded // todo: this is pure retarded
// todo: check for companion // todo: check for companion
if( pHateEntry->m_pActor->isPlayer() ) // && pHateEntry->m_hateAmount >= plsBeHatedThisMuchAtLeast ) if( pHateEntry->m_pChara->isPlayer() ) // && pHateEntry->m_hateAmount >= plsBeHatedThisMuchAtLeast )
{ {
uint8_t level = pHateEntry->m_pActor->getLevel(); uint8_t level = pHateEntry->m_pChara->getLevel();
auto levelDiff = static_cast< int32_t >( this->m_level ) - level; auto levelDiff = static_cast< int32_t >( this->m_level ) - level;
auto cappedLevelDiff = Math::Util::clamp( levelDiff, 1, 6 ); auto cappedLevelDiff = Math::Util::clamp( levelDiff, 1, 6 );
@ -439,7 +439,7 @@ void Core::Entity::BattleNpc::onDeath()
// todo: this is actually retarded, we need real rand() // todo: this is actually retarded, we need real rand()
srand( static_cast< uint32_t > ( time( nullptr ) ) ); srand( static_cast< uint32_t > ( time( nullptr ) ) );
auto pPlayer = pHateEntry->m_pActor->getAsPlayer(); auto pPlayer = pHateEntry->m_pChara->getAsPlayer();
pPlayer->gainExp( exp ); pPlayer->gainExp( exp );
pPlayer->onMobKill( m_nameId ); pPlayer->onMobKill( m_nameId );
} }
@ -448,7 +448,7 @@ void Core::Entity::BattleNpc::onDeath()
hateListClear(); hateListClear();
} }
void Core::Entity::BattleNpc::onActionHostile( Actor& source ) void Core::Entity::BattleNpc::onActionHostile( Chara& source )
{ {
if( hateListGetHighest() == nullptr ) if( hateListGetHighest() == nullptr )
@ -458,7 +458,7 @@ void Core::Entity::BattleNpc::onActionHostile( Actor& source )
setOwner( source.getAsPlayer() ); setOwner( source.getAsPlayer() );
} }
Core::Entity::ActorPtr Core::Entity::BattleNpc::getClaimer() const Core::Entity::CharaPtr Core::Entity::BattleNpc::getClaimer() const
{ {
return m_pOwner; return m_pOwner;
} }
@ -501,46 +501,46 @@ void Core::Entity::BattleNpc::update( int64_t currTime )
case MODE_IDLE: case MODE_IDLE:
{ {
ActorPtr pClosestActor = getClosestActor(); CharaPtr pClosestChara = getClosestChara();
if( pClosestActor && pClosestActor->isAlive() ) if( pClosestChara && pClosestChara->isAlive() )
{ {
distance = Math::Util::distance( getPos().x, getPos().y, getPos().z, distance = Math::Util::distance( getPos().x, getPos().y, getPos().z,
pClosestActor->getPos().x, pClosestChara->getPos().x,
pClosestActor->getPos().y, pClosestChara->getPos().y,
pClosestActor->getPos().z ); pClosestChara->getPos().z );
//if( distance < 8 && getbehavior() == 2 ) //if( distance < 8 && getbehavior() == 2 )
// aggro( pClosestActor ); // aggro( pClosestChara );
} }
} }
break; break;
case MODE_COMBAT: case MODE_COMBAT:
{ {
ActorPtr pClosestActor = hateListGetHighest(); CharaPtr pClosestChara = hateListGetHighest();
if( pClosestActor != nullptr && !pClosestActor->isAlive() ) if( pClosestChara != nullptr && !pClosestChara->isAlive() )
{ {
hateListRemove( *pClosestActor ); hateListRemove( *pClosestChara );
pClosestActor = hateListGetHighest(); pClosestChara = hateListGetHighest();
} }
if( pClosestActor != nullptr ) if( pClosestChara != nullptr )
{ {
distance = Math::Util::distance( getPos().x, getPos().y, getPos().z, distance = Math::Util::distance( getPos().x, getPos().y, getPos().z,
pClosestActor->getPos().x, pClosestChara->getPos().x,
pClosestActor->getPos().y, pClosestChara->getPos().y,
pClosestActor->getPos().z ); pClosestChara->getPos().z );
if( distance > 4 ) if( distance > 4 )
moveTo( pClosestActor->getPos() ); moveTo( pClosestChara->getPos() );
else else
{ {
if( face( pClosestActor->getPos() ) ) if( face( pClosestChara->getPos() ) )
sendPositionUpdate(); sendPositionUpdate();
// in combat range. ATTACK! // in combat range. ATTACK!
autoAttack( pClosestActor ); autoAttack( pClosestChara );
} }
} }
else else

View file

@ -1,7 +1,7 @@
#ifndef _BATTLENPC_H #ifndef _BATTLENPC_H
#define _BATTLENPC_H #define _BATTLENPC_H
#include "Actor.h" #include "Chara.h"
namespace Core { namespace Core {
namespace Entity { namespace Entity {
@ -16,11 +16,11 @@ enum StateMode
typedef struct typedef struct
{ {
uint32_t m_hateAmount; uint32_t m_hateAmount;
ActorPtr m_pActor; CharaPtr m_pChara;
} HateListEntry; } HateListEntry;
// class for Mobs inheriting from Actor // class for Mobs inheriting from Chara
class BattleNpc : public Actor class BattleNpc : public Chara
{ {
public: public:
BattleNpc(); BattleNpc();
@ -52,12 +52,12 @@ public:
uint8_t getbehavior() const; uint8_t getbehavior() const;
void hateListAdd( Actor& actor, int32_t hateAmount ); void hateListAdd( Chara& actor, int32_t hateAmount );
void hateListUpdate( Actor& actor, int32_t hateAmount ); void hateListUpdate( Chara& actor, int32_t hateAmount );
void hateListRemove( Actor& actor ); void hateListRemove( Chara& actor );
bool hateListHasActor( Actor& actor ); bool hateListHasActor( Chara& actor );
void resetPos(); void resetPos();
@ -65,19 +65,19 @@ public:
void hateListClear(); void hateListClear();
ActorPtr hateListGetHighest(); CharaPtr hateListGetHighest();
void aggro( Actor& actor ); void aggro( Chara& actor );
void deaggro( Actor& actor ); void deaggro( Chara& actor );
void setOwner( PlayerPtr pPlayer ); void setOwner( PlayerPtr pPlayer );
void onDeath() override; void onDeath() override;
void onActionHostile( Actor& source ) override; void onActionHostile( Chara& source ) override;
ActorPtr getClaimer() const; CharaPtr getClaimer() const;
void sendPositionUpdate(); void sendPositionUpdate();
@ -103,7 +103,7 @@ private:
uint32_t m_unk1; uint32_t m_unk1;
uint32_t m_unk2; uint32_t m_unk2;
std::set< HateListEntry* > m_hateList; std::set< HateListEntry* > m_hateList;
ActorPtr m_pOwner; CharaPtr m_pOwner;
uint32_t m_timeOfDeath; uint32_t m_timeOfDeath;
uint32_t m_mobType; uint32_t m_mobType;

View file

@ -0,0 +1,974 @@
#include <common/Util/Util.h>
#include <common/Util/UtilMath.h>
#include <common/Network/PacketContainer.h>
#include <common/Exd/ExdDataGenerated.h>
#include <common/Network/GamePacket.h>
#include "Forwards.h"
#include "Action/Action.h"
#include "Zone/Zone.h"
#include "Network/GameConnection.h"
#include "Network/PacketWrappers/ActorControlPacket142.h"
#include "Network/PacketWrappers/ActorControlPacket143.h"
#include "Network/PacketWrappers/ActorControlPacket144.h"
#include "Network/PacketWrappers/UpdateHpMpTpPacket.h"
#include "StatusEffect/StatusEffect.h"
#include "Action/ActionCollision.h"
#include "ServerZone.h"
#include "Session.h"
#include "Math/CalcBattle.h"
#include "Chara.h"
#include "Player.h"
#include "Zone/TerritoryMgr.h"
extern Core::ServerZone g_serverZone;
extern Core::Data::ExdDataGenerated g_exdDataGen;
extern Core::TerritoryMgr g_territoryMgr;
using namespace Core::Common;
using namespace Core::Network::Packets;
using namespace Core::Network::Packets::Server;
Core::Entity::Chara::Chara( ObjKind type ) :
Actor( type )
{
// initialize the free slot queue
for( uint8_t i = 0; i < MAX_STATUS_EFFECTS; i++ )
{
m_statusEffectFreeSlotQueue.push( i );
}
}
Core::Entity::Chara::~Chara()
{
}
/*! \return the actors name */
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
{
return m_currentStance;
}
/*! \return actor stats */
Core::Entity::Chara::ActorStats Core::Entity::Chara::getStats() const
{
return m_baseStats;
}
/*! \return current HP */
uint32_t Core::Entity::Chara::getHp() const
{
return m_hp;
}
/*! \return current MP */
uint32_t Core::Entity::Chara::getMp() const
{
return m_mp;
}
/*! \return current TP */
uint16_t Core::Entity::Chara::getTp() const
{
return m_tp;
}
/*! \return current GP */
uint16_t Core::Entity::Chara::getGp() const
{
return m_gp;
}
/*! \return current invincibility type */
InvincibilityType Core::Entity::Chara::getInvincibilityType() const
{
return m_invincibilityType;
}
/*! \return current class or job */
Core::Common::ClassJob Core::Entity::Chara::getClass() const
{
return m_class;
}
/*! \return current class or job as int32_t ( this feels pointless ) */
uint8_t Core::Entity::Chara::getClassAsInt() const
{
return static_cast< uint8_t >( m_class );
}
/*! \param ClassJob to set */
void Core::Entity::Chara::setClass( Common::ClassJob classJob )
{
m_class = classJob;
}
/*! \param Id of the target to set */
void Core::Entity::Chara::setTargetId( uint64_t targetId )
{
m_targetId = targetId;
}
/*! \return Id of the current target */
uint64_t Core::Entity::Chara::getTargetId() const
{
return m_targetId;
}
/*! \return True if the actor is alive */
bool Core::Entity::Chara::isAlive() const
{
return ( m_hp > 0 );
}
/*! \return max hp for the actor */
uint32_t Core::Entity::Chara::getMaxHp() const
{
return m_baseStats.max_hp;
}
/*! \return max mp for the actor */
uint32_t Core::Entity::Chara::getMaxMp() const
{
return m_baseStats.max_mp;
}
/*! \return reset hp to current max hp */
void Core::Entity::Chara::resetHp()
{
m_hp = getMaxHp();
sendStatusUpdate( true );
}
/*! \return reset mp to current max mp */
void Core::Entity::Chara::resetMp()
{
m_mp = getMaxMp();
sendStatusUpdate( true );
}
/*! \param hp amount to set ( caps to maxHp ) */
void Core::Entity::Chara::setHp( uint32_t hp )
{
m_hp = hp < getMaxHp() ? hp : getMaxHp();
sendStatusUpdate( true );
}
/*! \param mp amount to set ( caps to maxMp ) */
void Core::Entity::Chara::setMp( uint32_t mp )
{
m_mp = mp < getMaxMp() ? mp : getMaxMp();
sendStatusUpdate( true );
}
/*! \param gp amount to set*/
void Core::Entity::Chara::setGp( uint32_t gp )
{
m_gp = gp;
sendStatusUpdate( true );
}
/*! \param type invincibility type to set */
void Core::Entity::Chara::setInvincibilityType( Common::InvincibilityType type )
{
m_invincibilityType = type;
}
/*! \return current status of the actor */
Core::Entity::Chara::ActorStatus Core::Entity::Chara::getStatus() const
{
return m_status;
}
/*! \param status to set */
void Core::Entity::Chara::setStatus( ActorStatus status )
{
m_status = status;
}
/*!
Performs necessary steps to mark an actor dead.
Sets hp/mp/tp, sets status, plays animation and fires onDeath event
*/
void Core::Entity::Chara::die()
{
m_status = ActorStatus::Dead;
m_hp = 0;
m_mp = 0;
m_tp = 0;
// fire onDeath event
onDeath();
// if the actor is a player, the update needs to be send to himself too
bool selfNeedsUpdate = isPlayer();
sendToInRangeSet( ActorControlPacket142( m_id, SetStatus, static_cast< uint8_t >( ActorStatus::Dead ) ), selfNeedsUpdate );
// TODO: not all actor show the death animation when they die, some quest npcs might just despawn
// although that might be handled by setting the HP to 1 and doing some script magic
sendToInRangeSet( ActorControlPacket142( m_id, DeathAnimation, 0, 0, 0, 0x20 ), selfNeedsUpdate );
}
/*!
Calculates and sets the rotation to look towards a specified
position
\param Position to look towards
*/
bool Core::Entity::Chara::face( const Common::FFXIVARR_POSITION3& p )
{
float oldRot = getRotation();
float rot = Math::Util::calcAngFrom( getPos().x, getPos().z, p.x, p.z );
float newRot = PI - rot + ( PI / 2 );
m_pCell = nullptr;
setRotation( newRot );
return oldRot != newRot ? true : false;
}
/*!
Sets the actors position and notifies the zone to propagate the change
\param Position to set
*/
void Core::Entity::Chara::setPosition( const Common::FFXIVARR_POSITION3& pos )
{
m_pos = pos;
m_pCurrentZone->updateActorPosition( *this );
}
void Core::Entity::Chara::setPosition( float x, float y, float z )
{
m_pos.x = x;
m_pos.y = y;
m_pos.z = z;
m_pCurrentZone->updateActorPosition( *this );
}
/*!
Set and propagate the actor stance to in range players
( not the actor himself )
\param stance to set
*/
void Core::Entity::Chara::setStance( Stance stance )
{
m_currentStance = stance;
sendToInRangeSet( ActorControlPacket142( m_id, ToggleAggro, stance, 1 ) );
}
/*!
Check if an action is queued for execution, if so update it
and if fully performed, clean up again.
\return true if a queued action has been updated
*/
bool Core::Entity::Chara::checkAction()
{
if( m_pCurrentAction == nullptr )
return false;
if( m_pCurrentAction->update() )
m_pCurrentAction.reset();
return true;
}
/*!
Change the current target and propagate to in range players
\param target actor id
*/
void Core::Entity::Chara::changeTarget( uint64_t targetId )
{
setTargetId( targetId );
sendToInRangeSet( ActorControlPacket144( m_id, SetTarget, 0, 0, 0, 0, targetId ) );
}
/*!
Dummy function \return 0
*/
uint8_t Core::Entity::Chara::getLevel() const
{
return 0;
}
/*!
Let an actor take damage and perform necessary steps
according to resulting hp, propagates new hp value to players
in range
TODO: eventually this needs to distinguish between physical and
magical dmg and take status effects into account
\param amount of damage to be taken
*/
void Core::Entity::Chara::takeDamage( uint32_t damage )
{
if( damage >= m_hp )
{
switch( m_invincibilityType ) {
case InvincibilityNone:
setHp( 0 );
die();
break;
case InvincibilityRefill:
resetHp();
break;
case InvincibilityStayAlive:
setHp( 0 );
break;
}
}
else
m_hp -= damage;
sendStatusUpdate( false );
}
/*!
Let an actor get healed and perform necessary steps
according to resulting hp, propagates new hp value to players
in range
\param amount of hp to be healed
*/
void Core::Entity::Chara::heal( uint32_t amount )
{
if( ( m_hp + amount ) > getMaxHp() )
{
m_hp = getMaxHp();
}
else
m_hp += amount;
sendStatusUpdate( false );
}
/*!
Send an HpMpTp update to players in range ( and potentially to self )
TODO: poor naming, should be changed. Status is not HP. Also should be virtual
so players can have their own version and we can abolish the param.
\param true if the update should also be sent to the actor ( player ) himself
*/
void Core::Entity::Chara::sendStatusUpdate( bool toSelf )
{
UpdateHpMpTpPacket updateHpPacket( *this );
sendToInRangeSet( updateHpPacket );
}
/*! \return ActionPtr of the currently registered action, or nullptr */
Core::Action::ActionPtr Core::Entity::Chara::getCurrentAction() const
{
return m_pCurrentAction;
}
/*! \param ActionPtr of the action to be registered */
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
{
return m_pCurrentZone;
}
/*! \param ZonePtr to the zone to be set as current */
void Core::Entity::Chara::setCurrentZone( ZonePtr currZone )
{
m_pCurrentZone = currZone;
}
/*!
Get the current cell of a region the actor is in
\return Cell*
*/
Core::Cell * Core::Entity::Chara::getCell() const
{
return m_pCell;
}
/*!
Set the current cell the actor is in
\param Cell* for the cell to be set
*/
void Core::Entity::Chara::setCell( Cell * pCell )
{
m_pCell = pCell;
}
/*!
Autoattack prototype implementation
TODO: move the check if the autoAttack can be performed to the callee
also rename autoAttack to autoAttack as that is more elaborate
On top of that, this only solves attacks from melee classes.
Will have to be extended for ranged attacks.
\param ActorPtr the autoAttack is performed on
*/
void Core::Entity::Chara::autoAttack( CharaPtr pTarget )
{
uint64_t tick = Util::getTimeMs();
if( ( tick - m_lastAttack ) > 2500 )
{
pTarget->onActionHostile( *this );
m_lastAttack = tick;
srand( static_cast< uint32_t >( tick ) );
uint16_t damage = static_cast< uint16_t >( 10 + rand() % 12 );
uint32_t variation = static_cast< uint32_t >( 0 + rand() % 4 );
ZoneChannelPacket< FFXIVIpcEffect > effectPacket( getId() );
effectPacket.data().targetId = pTarget->getId();
effectPacket.data().actionAnimationId = 0x366;
effectPacket.data().unknown_2 = variation;
// effectPacket.data().unknown_3 = 1;
effectPacket.data().actionTextId = 0x366;
effectPacket.data().numEffects = 1;
effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() );
effectPacket.data().effectTarget = pTarget->getId();
effectPacket.data().effects[0].value = damage;
effectPacket.data().effects[0].effectType = ActionEffectType::Damage;
effectPacket.data().effects[0].hitSeverity = static_cast< ActionHitSeverityType >( variation );
effectPacket.data().effects[0].unknown_3 = 7;
sendToInRangeSet( effectPacket );
if( isPlayer() )
getAsPlayer()->queuePacket( effectPacket );
pTarget->takeDamage( damage );
}
}
/*!
ChaiScript Skill Handler.
\param GamePacketPtr to send
\param bool should be send to self?
*/
void Core::Entity::Chara::handleScriptSkill( uint32_t type, uint16_t actionId, uint64_t param1,
uint64_t param2, Entity::Chara& target )
{
if( isPlayer() )
{
getAsPlayer()->sendDebug( std::to_string( target.getId() ) );
getAsPlayer()->sendDebug( "Handle script skill type: " + std::to_string( type ) );
}
auto actionInfoPtr = g_exdDataGen.get< Core::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.
ZoneChannelPacket< FFXIVIpcEffect > effectPacket( getId() );
effectPacket.data().targetId = target.getId();
effectPacket.data().actionAnimationId = actionId;
effectPacket.data().unknown_62 = 1; // Affects displaying action name next to number in floating text
effectPacket.data().unknown_2 = 1; // This seems to have an effect on the "double-cast finish" animation
effectPacket.data().actionTextId = actionId;
effectPacket.data().numEffects = 1;
effectPacket.data().rotation = Math::Util::floatToUInt16Rot( getRotation() );
effectPacket.data().effectTarget = target.getId();
// 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:
{
effectPacket.data().effects[0].value = static_cast< uint16_t >( param1 );
effectPacket.data().effects[0].effectType = ActionEffectType::Damage;
effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalDamage;
effectPacket.data().effects[0].unknown_3 = 7;
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( *this );
target.takeDamage( static_cast< uint32_t >( param1 ) );
}
else
{
auto actorsCollided = ActionCollision::getActorsHitFromAction( target.getPos(), getInRangeCharas(true),
actionInfoPtr, TargetFilter::Enemies );
for( const auto& pHitActor : actorsCollided )
{
effectPacket.data().targetId = pHitActor->getId();
effectPacket.data().effectTarget = pHitActor->getId();
// todo: send to range of what? ourselves? when mob script hits this is going to be lacking
sendToInRangeSet( effectPacket, true );
if( pHitActor->isAlive() )
pHitActor->onActionHostile( *this );
pHitActor->takeDamage( static_cast< uint32_t >( param1 ) );
// Debug
if ( isPlayer() )
{
if ( pHitActor->isPlayer() )
getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) + " (" + pHitActor->getName() + ")" );
else
getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) );
}
}
}
break;
}
case ActionEffectType::Heal:
{
uint32_t calculatedHeal = Math::CalcBattle::calculateHealValue( getAsPlayer(), static_cast< uint32_t >( param1 ) );
effectPacket.data().effects[0].value = calculatedHeal;
effectPacket.data().effects[0].effectType = ActionEffectType::Heal;
effectPacket.data().effects[0].hitSeverity = ActionHitSeverityType::NormalHeal;
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(), getInRangeCharas(true),
actionInfoPtr, TargetFilter::Allies );
for( auto pHitActor : actorsCollided )
{
effectPacket.data().targetId = target.getId();
effectPacket.data().effectTarget = pHitActor->getId();
sendToInRangeSet( effectPacket, true );
pHitActor->heal( calculatedHeal );
// Debug
if( isPlayer() )
{
if( pHitActor->isPlayer() )
getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) + " (" + pHitActor->getName() + ")" );
else
getAsPlayer()->sendDebug( "AoE hit actor " + std::to_string( pHitActor->getId() ) );
}
}
}
break;
}
default:
break;
}
}
/*! \param StatusEffectPtr to be applied to the actor */
void Core::Entity::Chara::addStatusEffect( StatusEffect::StatusEffectPtr pEffect )
{
int8_t nextSlot = getStatusEffectFreeSlot();
// if there is no slot left, do not add the effect
if( nextSlot == -1 )
return;
pEffect->applyStatus();
m_statusEffectMap[nextSlot] = pEffect;
ZoneChannelPacket< Server::FFXIVIpcAddStatusEffect > statusEffectAdd( getId() );
statusEffectAdd.data().actor_id = pEffect->getTargetActorId();
statusEffectAdd.data().actor_id1 = pEffect->getSrcActorId();
statusEffectAdd.data().current_hp = getHp();
statusEffectAdd.data().current_mp = getMp();
statusEffectAdd.data().current_tp = getTp();
statusEffectAdd.data().duration = static_cast< float >( pEffect->getDuration() ) / 1000;
statusEffectAdd.data().effect_id = pEffect->getId();
statusEffectAdd.data().effect_index = nextSlot;
statusEffectAdd.data().max_hp = getMaxHp();
statusEffectAdd.data().max_mp = getMaxMp();
statusEffectAdd.data().max_something = 1;
//statusEffectAdd.data().unknown2 = 28;
statusEffectAdd.data().param = pEffect->getParam();
sendToInRangeSet( statusEffectAdd, isPlayer() );
}
/*! \param StatusEffectPtr to be applied to the actor */
void Core::Entity::Chara::addStatusEffectById( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param )
{
auto effect = StatusEffect::make_StatusEffect( id, source.getAsChara(), getAsChara(), duration, 3000 );
effect->setParam( param );
addStatusEffect( effect );
}
/*! \param StatusEffectPtr to be applied to the actor */
void Core::Entity::Chara::addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param )
{
if( hasStatusEffect( id ) )
return;
auto effect = StatusEffect::make_StatusEffect( id, source.getAsChara(), getAsChara(), duration, 3000 );
effect->setParam( param );
addStatusEffect( effect );
}
float Core::Entity::Chara::getRotation() const
{
return m_rot;
}
void Core::Entity::Chara::setRotation( float rot )
{
m_rot = rot;
}
int8_t Core::Entity::Chara::getStatusEffectFreeSlot()
{
int8_t freeEffectSlot = -1;
if( m_statusEffectFreeSlotQueue.empty() )
return freeEffectSlot;
freeEffectSlot = m_statusEffectFreeSlotQueue.front();
m_statusEffectFreeSlotQueue.pop();
return freeEffectSlot;
}
void Core::Entity::Chara::statusEffectFreeSlot( uint8_t slotId )
{
m_statusEffectFreeSlotQueue.push( slotId );
}
void Core::Entity::Chara::removeSingleStatusEffectById( uint32_t id )
{
for( auto effectIt : m_statusEffectMap )
{
if( effectIt.second->getId() == id )
{
removeStatusEffect( effectIt.first );
break;
}
}
}
void Core::Entity::Chara::removeStatusEffect( uint8_t effectSlotId )
{
auto pEffectIt = m_statusEffectMap.find( effectSlotId );
if( pEffectIt == m_statusEffectMap.end() )
return;
statusEffectFreeSlot( effectSlotId );
auto pEffect = pEffectIt->second;
pEffect->removeStatus();
sendToInRangeSet( ActorControlPacket142( getId(), StatusEffectLose, pEffect->getId() ), isPlayer() );
m_statusEffectMap.erase( effectSlotId );
sendStatusEffectUpdate();
}
std::map< uint8_t, Core::StatusEffect::StatusEffectPtr > Core::Entity::Chara::getStatusEffectMap() const
{
return m_statusEffectMap;
}
void Core::Entity::Chara::sendStatusEffectUpdate()
{
uint64_t currentTimeMs = Util::getTimeMs();
ZoneChannelPacket< Server::FFXIVIpcStatusEffectList > statusEffectList( getId() );
statusEffectList.data().current_hp = getHp();
statusEffectList.data().current_mp = getMp();
statusEffectList.data().currentTp = getTp();
statusEffectList.data().max_hp = getMaxHp();
statusEffectList.data().max_mp = getMaxMp();
uint8_t slot = 0;
for( auto effectIt : m_statusEffectMap )
{
float timeLeft = static_cast< float >( effectIt.second->getDuration() -
( currentTimeMs - effectIt.second->getStartTimeMs() ) ) / 1000;
statusEffectList.data().effect[slot].duration = timeLeft;
statusEffectList.data().effect[slot].effect_id = effectIt.second->getId();
statusEffectList.data().effect[slot].sourceActorId = effectIt.second->getSrcActorId();
slot++;
}
sendToInRangeSet( statusEffectList, isPlayer() );
}
void Core::Entity::Chara::updateStatusEffects()
{
uint64_t currentTimeMs = Util::getTimeMs();
uint32_t thisTickDmg = 0;
uint32_t thisTickHeal = 0;
for( auto effectIt : m_statusEffectMap )
{
uint8_t effectIndex = effectIt.first;
auto effect = effectIt.second;
uint64_t lastTick = effect->getLastTickMs();
uint64_t startTime = effect->getStartTimeMs();
uint32_t duration = effect->getDuration();
uint32_t tickRate = effect->getTickRate();
if( ( currentTimeMs - startTime ) > duration )
{
// remove status effect
removeStatusEffect( effectIndex );
// break because removing invalidates iterators
break;
}
if( ( currentTimeMs - lastTick ) > tickRate )
{
effect->setLastTick( currentTimeMs );
effect->onTick();
auto thisEffect = effect->getTickEffect();
switch( thisEffect.first )
{
case 1:
{
thisTickDmg += thisEffect.second;
break;
}
case 2:
{
thisTickHeal += thisEffect.second;
break;
}
}
}
}
if( thisTickDmg != 0 )
{
takeDamage( thisTickDmg );
sendToInRangeSet( ActorControlPacket142( getId(), HPFloatingText, 0, static_cast< uint8_t >( ActionEffectType::Damage ), thisTickDmg ) );
}
if( thisTickHeal != 0 )
{
heal( thisTickDmg );
sendToInRangeSet( ActorControlPacket142( getId(), HPFloatingText, 0, static_cast< uint8_t >( ActionEffectType::Heal ), thisTickHeal ) );
}
}
bool Core::Entity::Chara::hasStatusEffect( uint32_t id )
{
if( m_statusEffectMap.find( id ) != m_statusEffectMap.end() )
return true;
return false;
}

View file

@ -0,0 +1,295 @@
#ifndef _ACTOR_H_
#define _ACTOR_H_
#include <common/Common.h>
#include <boost/enable_shared_from_this.hpp>
#include "Forwards.h"
#include "Actor.h"
#include <set>
#include <map>
#include <queue>
namespace Core {
namespace Entity {
/*!
\class Chara
\brief Base class for all animate actors
*/
class Chara : public Actor
{
public:
enum Stance : uint8_t
{
Passive = 0,
Active = 1,
};
enum DisplayFlags : uint16_t
{
ActiveStance = 0x001,
Invisible = 0x020,
HideHead = 0x040,
HideWeapon = 0x080,
Faded = 0x100,
Visor = 0x800,
};
enum struct ActorStatus : uint8_t
{
Idle = 0x01,
Dead = 0x02,
Sitting = 0x03,
Mounted = 0x04,
Crafting = 0x05,
Gathering = 0x06,
Melding = 0x07,
SMachine = 0x08
};
struct ActorStats
{
uint32_t max_mp = 0;
uint32_t max_hp = 0;
uint32_t str = 0;
uint32_t dex = 0;
uint32_t vit = 0;
uint32_t inte = 0;
uint32_t mnd = 0;
uint32_t pie = 0;
uint32_t tenacity = 0;
uint32_t attack = 0;
uint32_t defense = 0;
uint32_t accuracy = 0;
uint32_t spellSpeed = 0;
uint32_t magicDefense = 0;
uint32_t critHitRate = 0;
uint32_t resistSlash = 0;
uint32_t resistPierce = 0;
uint32_t resistBlunt = 0;
uint32_t attackPotMagic = 0;
uint32_t healingPotMagic = 0;
uint32_t determination = 0;
uint32_t skillSpeed = 0;
uint32_t resistSlow = 0;
uint32_t resistSilence = 0;
uint32_t resistBlind = 0;
uint32_t resistPoison = 0;
uint32_t resistStun = 0;
uint32_t resistSleep = 0;
uint32_t resistBind = 0;
uint32_t resistHeavy = 0;
uint32_t resistFire = 0;
uint32_t resistIce = 0;
uint32_t resistWind = 0;
uint32_t resistEarth = 0;
uint32_t resistLightning = 0;
uint32_t resistWater = 0;
} m_baseStats;
protected:
char m_name[34];
/*! Id of the zone the actor currently is in */
uint32_t m_zoneId;
/*! Ptr to the ZoneObj the actor belongs to */
ZonePtr m_pCurrentZone;
/*! Last tick time for the actor ( in ms ) */
uint64_t m_lastTickTime;
/*! Last time the actor performed an autoAttack ( in ms ) */
uint64_t m_lastAttack;
/*! Last time the actor was updated ( in ms ) */
uint64_t m_lastUpdate;
/*! Current stance of the actor */
Stance m_currentStance;
/*! Current staus of the actor */
ActorStatus m_status;
/*! Max HP of the actor ( based on job / class ) */
uint32_t m_maxHp;
/*! Max MP of the actor ( based on job / class ) */
uint32_t m_maxMp;
/*! Current HP of the actor */
uint32_t m_hp;
/*! Current MP of the actor */
uint32_t m_mp;
/*! Current TP of the actor */
uint16_t m_tp;
/*! Current GP of the actor */
uint16_t m_gp;
/*! Additional look info of the actor */
uint8_t m_customize[26];
/*! Current class of the actor */
Common::ClassJob m_class;
/*! Id of the currently selected target actor */
uint64_t m_targetId;
/*! Ptr to a queued action */
Action::ActionPtr m_pCurrentAction;
/*! Invincibility type */
Common::InvincibilityType m_invincibilityType;
/*! Status effects */
const uint8_t MAX_STATUS_EFFECTS = 30;
std::queue< uint8_t > m_statusEffectFreeSlotQueue;
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 );
virtual ~Chara() override;
virtual void calculateStats() {};
/// Status effect functions
void addStatusEffect( StatusEffect::StatusEffectPtr pEffect );
void removeStatusEffect( uint8_t effectSlotId );
void removeSingleStatusEffectById( uint32_t id );
void updateStatusEffects();
bool hasStatusEffect( uint32_t id );
int8_t getStatusEffectFreeSlot();
void statusEffectFreeSlot( uint8_t slotId );
std::map< uint8_t, Core::StatusEffect::StatusEffectPtr > getStatusEffectMap() const;
void sendStatusEffectUpdate();
// add a status effect by id
void addStatusEffectById( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param = 0 );
// add a status effect by id if it doesn't exist
void addStatusEffectByIdIfNotExist( uint32_t id, int32_t duration, Entity::Chara& source, uint16_t param = 0 );
// remove a status effect by id
void removeSingleStatusEffectFromId( uint32_t id );
/// End Status Effect Functions
void setPosition( const Common::FFXIVARR_POSITION3& pos );
void setPosition( float x, float y, float z );
void setRotation( float rot );
float getRotation() const;
std::string getName() const;
std::set< CharaPtr > getInRangeCharas( bool includeSelf = false );
bool face( const Common::FFXIVARR_POSITION3& p );
Stance getStance() const;
void setStance( Stance stance );
ActorStats getStats() const;
uint32_t getHp() const;
uint32_t getMp() const;
uint16_t getTp() const;
uint16_t getGp() const;
Common::InvincibilityType getInvincibilityType() const;
Common::ClassJob getClass() const;
uint8_t getClassAsInt() const;
void setClass( Common::ClassJob classJob );
void setTargetId( uint64_t targetId );
uint64_t getTargetId() const;
bool isAlive() const;
virtual uint32_t getMaxHp() const;
virtual uint32_t getMaxMp() const;
void resetHp();
void resetMp();
void setHp( uint32_t hp );
void setMp( uint32_t mp );
void setGp( uint32_t gp );
void setInvincibilityType( Common::InvincibilityType type );
void die();
ActorStatus getStatus() const;
void setStatus( 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 onRemoveInRangeChara( Chara& pActor ) {}
virtual void onDeath() {};
virtual void onDamageTaken( Chara& pSource ) {};
virtual void onActionHostile( Chara& source ) {};
virtual void onActionFriendly( Chara& pSource ) {};
virtual void onTick() {};
virtual void changeTarget( uint64_t targetId );
virtual uint8_t getLevel() const;
virtual void sendStatusUpdate( bool toSelf = true );
virtual void takeDamage( uint32_t damage );
virtual void heal( uint32_t amount );
virtual bool checkAction();
virtual void update( int64_t currTime ) {};
Action::ActionPtr getCurrentAction() const;
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 );
// get the current cell of a region the actor is in
Cell* getCell() const;
// set the current cell
void setCell( Cell* pCell );
Core::Cell* m_pCell;
};
}
}
#endif

View file

@ -24,7 +24,7 @@ extern Core::Logger g_log;
uint32_t Core::Entity::EventNpc::m_nextID = 1249241694; uint32_t Core::Entity::EventNpc::m_nextID = 1249241694;
Core::Entity::EventNpc::EventNpc() : Core::Entity::EventNpc::EventNpc() :
Actor( ObjKind::EventNpc ) Chara( ObjKind::EventNpc )
{ {
m_id = 0; m_id = 0;
m_status = ActorStatus::Idle; m_status = ActorStatus::Idle;
@ -36,7 +36,7 @@ Core::Entity::EventNpc::~EventNpc()
} }
Core::Entity::EventNpc::EventNpc( uint32_t enpcId, const Common::FFXIVARR_POSITION3& spawnPos, float rotation ) : Core::Entity::EventNpc::EventNpc( uint32_t enpcId, const Common::FFXIVARR_POSITION3& spawnPos, float rotation ) :
Actor( ObjKind::EventNpc ) Chara( ObjKind::EventNpc )
{ {
EventNpc::m_nextID++; EventNpc::m_nextID++;
m_id = EventNpc::m_nextID; m_id = EventNpc::m_nextID;

View file

@ -1,13 +1,13 @@
#ifndef _EVENTNPC_H #ifndef _EVENTNPC_H
#define _EVENTNPC_H #define _EVENTNPC_H
#include "Actor.h" #include "Chara.h"
namespace Core { namespace Core {
namespace Entity { namespace Entity {
// class for Mobs inheriting from Actor // class for Mobs inheriting from Chara
class EventNpc : public Actor class EventNpc : public Chara
{ {
public: public:
EventNpc(); EventNpc();

View file

@ -1,94 +0,0 @@
#include "GameObject.h"
#include "Player.h"
#include "Actor.h"
#include "BattleNpc.h"
#include "EventNpc.h"
Core::Entity::GameObject::GameObject( ObjKind type ) :
m_objKind( type )
{
}
uint32_t Core::Entity::GameObject::getId() const
{
return m_id;
}
Core::Entity::GameObject::ObjKind Core::Entity::GameObject::getObjKind() const
{
return m_objKind;
}
Core::Common::FFXIVARR_POSITION3& Core::Entity::GameObject::getPos()
{
return m_pos;
}
void Core::Entity::GameObject::setPos( float x, float y, float z )
{
m_pos.x = x;
m_pos.y = y;
m_pos.z = z;
}
void Core::Entity::GameObject::setPos( const Core::Common::FFXIVARR_POSITION3& pos )
{
m_pos = pos;
}
float Core::Entity::GameObject::getRot() const
{
return m_rot;
}
void Core::Entity::GameObject::setRot( float rot )
{
m_rot = rot;
}
bool Core::Entity::GameObject::isPlayer() const
{
return m_objKind == ObjKind::Player;
}
bool Core::Entity::GameObject::isBattleNpc() const
{
return m_objKind == ObjKind::BattleNpc;
}
bool Core::Entity::GameObject::isEventNpc() const
{
return m_objKind == ObjKind::EventNpc;
}
/*! \return pointer to this instance as ActorPtr */
Core::Entity::ActorPtr Core::Entity::GameObject::getAsActor()
{
return boost::dynamic_pointer_cast< Entity::Actor, Entity::GameObject >( shared_from_this() );
}
/*! \return pointer to this instance as PlayerPtr */
Core::Entity::PlayerPtr Core::Entity::GameObject::getAsPlayer()
{
if( !isPlayer() )
return nullptr;
return boost::dynamic_pointer_cast< Entity::Player, Entity::GameObject >( shared_from_this() );
}
/*! \return pointer to this instance as BattleNpcPtr */
Core::Entity::BattleNpcPtr Core::Entity::GameObject::getAsBattleNpc()
{
if( !isBattleNpc() )
return nullptr;
return boost::dynamic_pointer_cast< Entity::BattleNpc, Entity::GameObject >( shared_from_this() );
}
/*! \return pointer to this instance as EventNpcPtr */
Core::Entity::EventNpcPtr Core::Entity::GameObject::getAsEventNpc()
{
if( !isEventNpc() )
return nullptr;
return boost::dynamic_pointer_cast< Entity::EventNpc, Entity::GameObject >( shared_from_this() );
}

View file

@ -1,82 +0,0 @@
#ifndef _GAME_OBJECT_H_
#define _GAME_OBJECT_H_
#include <common/Common.h>
#include <boost/enable_shared_from_this.hpp>
#include "Forwards.h"
#include <set>
#include <map>
#include <queue>
namespace Core {
namespace Entity {
/*!
\class GameObject
\brief Base class for all actor/objects
*/
class GameObject : public boost::enable_shared_from_this< GameObject >
{
public:
enum ObjKind : uint8_t
{
None = 0x00,
Player = 0x01,
BattleNpc = 0x02,
EventNpc = 0x03,
Treasure = 0x04,
Aetheryte = 0x05,
GatheringPoint = 0x06,
EventObj = 0x07,
Mount = 0x08,
Companion = 0x09,
Retainer = 0x0A,
Area = 0x0B,
Housing = 0x0C,
Cutscene = 0x0D,
CardStand = 0x0E,
};
protected:
/*! Position of the object */
Common::FFXIVARR_POSITION3 m_pos;
/*! Rotation of the object */
float m_rot;
/*! Id of the actor */
uint32_t m_id;
/*! Type of the actor */
ObjKind m_objKind;
public:
explicit GameObject( ObjKind type );
virtual ~GameObject() {};
virtual void spawn( PlayerPtr pTarget ) {}
virtual void despawn( PlayerPtr pTarget ) {}
uint32_t getId() const;
ObjKind getObjKind() const;
Common::FFXIVARR_POSITION3& getPos();
void setPos( const Common::FFXIVARR_POSITION3& pos );
void setPos( float x, float y, float z );
float getRot() const;
void setRot( float rot );
bool isPlayer() const;
bool isBattleNpc() const;
bool isEventNpc() const;
ActorPtr getAsActor();
PlayerPtr getAsPlayer();
BattleNpcPtr getAsBattleNpc();
EventNpcPtr getAsEventNpc();
};
}
}
#endif

View file

@ -2,7 +2,7 @@
#include "Zone/InstanceContent.h" #include "Zone/InstanceContent.h"
Core::Entity::InstanceObject::InstanceObject( uint32_t objectId, uint32_t mapLinkId ) : Core::Entity::InstanceObject::InstanceObject( uint32_t objectId, uint32_t mapLinkId ) :
Core::Entity::GameObject( ObjKind::EventObj ), Core::Entity::Actor( ObjKind::EventObj ),
m_mapLinkId( mapLinkId ), m_mapLinkId( mapLinkId ),
m_state( 0 ) m_state( 0 )
{ {

View file

@ -1,13 +1,13 @@
#ifndef SAPPHIRE_INSTANCEOBJECT_H #ifndef SAPPHIRE_INSTANCEOBJECT_H
#define SAPPHIRE_INSTANCEOBJECT_H #define SAPPHIRE_INSTANCEOBJECT_H
#include "GameObject.h" #include "Actor.h"
namespace Core namespace Core
{ {
namespace Entity namespace Entity
{ {
class InstanceObject : public GameObject class InstanceObject : public Actor
{ {
public: public:
InstanceObject( uint32_t objectId, uint32_t mapLinkId ); InstanceObject( uint32_t objectId, uint32_t mapLinkId );

View file

@ -55,7 +55,7 @@ using namespace Core::Network::Packets::Server;
// player constructor // player constructor
Core::Entity::Player::Player() : Core::Entity::Player::Player() :
Actor( ObjKind::Player ), Chara( ObjKind::Player ),
m_lastWrite( 0 ), m_lastWrite( 0 ),
m_lastPing( 0 ), m_lastPing( 0 ),
m_bIsLogin( false ), m_bIsLogin( false ),
@ -829,10 +829,10 @@ void Core::Entity::Player::despawn( Entity::PlayerPtr pTarget )
pPlayer->queuePacket( ActorControlPacket143( getId(), DespawnZoneScreenMsg, 0x04, getId(), 0x01 ) ); pPlayer->queuePacket( ActorControlPacket143( getId(), DespawnZoneScreenMsg, 0x04, getId(), 0x01 ) );
} }
Core::Entity::ActorPtr Core::Entity::Player::lookupTargetById( uint64_t targetId ) Core::Entity::CharaPtr Core::Entity::Player::lookupTargetById( uint64_t targetId )
{ {
ActorPtr targetActor; CharaPtr targetActor;
auto inRange = getInRangeActors( true ); auto inRange = getInRangeCharas(true);
for( auto actor : inRange ) for( auto actor : inRange )
{ {
if( actor->getId() == targetId ) if( actor->getId() == targetId )
@ -1000,12 +1000,12 @@ void Core::Entity::Player::update( int64_t currTime )
if( !checkAction() ) if( !checkAction() )
{ {
if( m_targetId && m_currentStance == Entity::Actor::Stance::Active && isAutoattackOn() ) if( m_targetId && m_currentStance == Entity::Chara::Stance::Active && isAutoattackOn() )
{ {
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_inRangeCharas )
{ {
if( actor->getId() == m_targetId && actor->isAlive() && mainWeap ) if( actor->getId() == m_targetId && actor->isAlive() && mainWeap )
{ {
@ -1408,7 +1408,7 @@ uint8_t Core::Entity::Player::getEquipDisplayFlags() const
void Core::Entity::Player::mount( uint32_t id ) void Core::Entity::Player::mount( uint32_t id )
{ {
m_mount = id; m_mount = id;
sendToInRangeSet( ActorControlPacket142( getId(), ActorControlType::SetStatus, static_cast< uint8_t >( Entity::Actor::ActorStatus::Mounted )), true ); sendToInRangeSet( ActorControlPacket142( getId(), ActorControlType::SetStatus, static_cast< uint8_t >( Entity::Chara::ActorStatus::Mounted )), true );
sendToInRangeSet( ActorControlPacket143( getId(), 0x39e, 12 ), true ); //? sendToInRangeSet( ActorControlPacket143( getId(), 0x39e, 12 ), true ); //?
ZoneChannelPacket< FFXIVIpcMount > mountPacket( getId() ); ZoneChannelPacket< FFXIVIpcMount > mountPacket( getId() );
@ -1419,7 +1419,7 @@ void Core::Entity::Player::mount( uint32_t id )
void Core::Entity::Player::dismount() void Core::Entity::Player::dismount()
{ {
sendToInRangeSet( ActorControlPacket142( getId(), ActorControlType::SetStatus, sendToInRangeSet( ActorControlPacket142( getId(), ActorControlType::SetStatus,
static_cast< uint8_t >( Entity::Actor::ActorStatus::Idle )), true ); static_cast< uint8_t >( Entity::Chara::ActorStatus::Idle )), true );
sendToInRangeSet( ActorControlPacket143( getId(), ActorControlType::Dismount, 1 ), true ); sendToInRangeSet( ActorControlPacket143( getId(), ActorControlType::Dismount, 1 ), true );
m_mount = 0; m_mount = 0;
} }
@ -1429,7 +1429,7 @@ uint8_t Core::Entity::Player::getCurrentMount() const
return m_mount; return m_mount;
} }
void Core::Entity::Player::autoAttack( ActorPtr pTarget ) void Core::Entity::Player::autoAttack( CharaPtr pTarget )
{ {
auto mainWeap = m_pInventory->getItemAt( Inventory::GearSet0, auto mainWeap = m_pInventory->getItemAt( Inventory::GearSet0,
@ -1663,15 +1663,15 @@ void Core::Entity::Player::finishZoning()
case ZoneingType::Return: case ZoneingType::Return:
case ZoneingType::ReturnDead: case ZoneingType::ReturnDead:
{ {
if( getStatus() == Entity::Actor::ActorStatus::Dead ) if( getStatus() == Entity::Chara::ActorStatus::Dead )
{ {
resetHp(); resetHp();
resetMp(); resetMp();
setStatus( Entity::Actor::ActorStatus::Idle ); setStatus( Entity::Chara::ActorStatus::Idle );
sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01, 0x01, 0, 111 ), true ); sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01, 0x01, 0, 111 ), true );
sendToInRangeSet( ActorControlPacket142( getId(), SetStatus, sendToInRangeSet( ActorControlPacket142( getId(), SetStatus,
static_cast< uint8_t >( Entity::Actor::ActorStatus::Idle ) ), true ); static_cast< uint8_t >( Entity::Chara::ActorStatus::Idle ) ), true );
} }
else else
sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01, 0x00, 0, 111 ), true ); sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01, 0x00, 0, 111 ), true );

View file

@ -5,7 +5,7 @@
#include <common/Common.h> #include <common/Common.h>
#include "Actor.h" #include "Chara.h"
#include "Inventory/Inventory.h" #include "Inventory/Inventory.h"
#include "Event/EventHandler.h" #include "Event/EventHandler.h"
#include <map> #include <map>
@ -33,7 +33,7 @@ struct QueuedZoning
* Inheriting from Actor * Inheriting from Actor
* *
*/ */
class Player : public Actor class Player : public Chara
{ {
public: public:
/*! Contructor */ /*! Contructor */
@ -42,7 +42,7 @@ public:
/*! Destructor */ /*! Destructor */
~Player(); ~Player();
void autoAttack( ActorPtr pTarget ) override; void autoAttack( CharaPtr pTarget ) override;
// EventHandlers // EventHandlers
////////////////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////////////////
@ -526,7 +526,7 @@ public:
bool actionHasCastTime( uint32_t actionId ); bool actionHasCastTime( uint32_t actionId );
Core::Entity::ActorPtr lookupTargetById( uint64_t targetId ); Core::Entity::CharaPtr lookupTargetById( uint64_t targetId );
bool isLogin() const; bool isLogin() const;
void setIsLogin( bool bIsLogin ); void setIsLogin( bool bIsLogin );

View file

@ -227,7 +227,7 @@ void Core::Entity::Player::eventActionStart( uint32_t eventId,
ActionCallback interruptCallback, ActionCallback interruptCallback,
uint64_t additional ) uint64_t additional )
{ {
auto pEventAction = Action::make_EventAction( getAsActor(), eventId, action, auto pEventAction = Action::make_EventAction( getAsChara(), eventId, action,
finishCallback, interruptCallback, additional ); finishCallback, interruptCallback, additional );
setCurrentAction( pEventAction ); setCurrentAction( pEventAction );
@ -257,7 +257,7 @@ void Core::Entity::Player::eventItemActionStart( uint32_t eventId,
ActionCallback interruptCallback, ActionCallback interruptCallback,
uint64_t additional ) uint64_t additional )
{ {
Action::ActionPtr pEventItemAction = Action::make_EventItemAction( getAsActor(), eventId, action, Action::ActionPtr pEventItemAction = Action::make_EventItemAction( getAsChara(), eventId, action,
finishCallback, interruptCallback, additional ); finishCallback, interruptCallback, additional );
setCurrentAction( pEventItemAction ); setCurrentAction( pEventItemAction );

View file

@ -34,8 +34,8 @@ namespace Core
namespace Entity namespace Entity
{ {
TYPE_FORWARD( GameObject );
TYPE_FORWARD( Actor ); TYPE_FORWARD( Actor );
TYPE_FORWARD( Chara );
TYPE_FORWARD( Player ); TYPE_FORWARD( Player );
TYPE_FORWARD( BattleNpc ); TYPE_FORWARD( BattleNpc );
TYPE_FORWARD( EventNpc ); TYPE_FORWARD( EventNpc );

View file

@ -2,7 +2,7 @@
#include <common/Exd/ExdDataGenerated.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Common.h> #include <common/Common.h>
#include "Actor/Actor.h" #include "Actor/Chara.h"
#include "Actor/Player.h" #include "Actor/Player.h"
#include "CalcBattle.h" #include "CalcBattle.h"

View file

@ -2,7 +2,7 @@
#define _CALCBATTLE_H #define _CALCBATTLE_H
#include <common/Common.h> #include <common/Common.h>
#include "Actor/Actor.h" #include "Actor/Chara.h"
using namespace Core::Entity; using namespace Core::Entity;

View file

@ -2,7 +2,7 @@
#include <common/Exd/ExdDataGenerated.h> #include <common/Exd/ExdDataGenerated.h>
#include <common/Common.h> #include <common/Common.h>
#include "Actor/Actor.h" #include "Actor/Chara.h"
#include "Actor/Player.h" #include "Actor/Player.h"
#include "CalcStats.h" #include "CalcStats.h"

View file

@ -2,7 +2,7 @@
#define _CALCSTATS_H #define _CALCSTATS_H
#include <common/Common.h> #include <common/Common.h>
#include "Actor/Actor.h" #include "Actor/Chara.h"
using namespace Core::Entity; using namespace Core::Entity;

View file

@ -119,10 +119,10 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in
case ClientTrigger::ToggleSeathe: // Toggle sheathe case ClientTrigger::ToggleSeathe: // Toggle sheathe
{ {
if ( param11 == 1 ) if ( param11 == 1 )
player.setStance( Entity::Actor::Stance::Active ); player.setStance( Entity::Chara::Stance::Active );
else else
{ {
player.setStance( Entity::Actor::Stance::Passive ); player.setStance( Entity::Chara::Stance::Passive );
player.setAutoattack( false ); player.setAutoattack( false );
} }
@ -135,7 +135,7 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in
if ( param11 == 1 ) if ( param11 == 1 )
{ {
player.setAutoattack( true ); player.setAutoattack( true );
player.setStance( Entity::Actor::Stance::Active ); player.setStance( Entity::Chara::Stance::Active );
} }
else else
player.setAutoattack( false ); player.setAutoattack( false );

View file

@ -37,7 +37,7 @@ void Core::Network::GameConnection::eventHandlerTalk( const Packets::GamePacket&
std::string eventName = "onTalk"; std::string eventName = "onTalk";
std::string objName = Event::getEventName( eventId ); std::string objName = Event::getEventName( eventId );
player.sendDebug( "Actor: " + player.sendDebug( "Chara: " +
std::to_string( actorId ) + " -> " + std::to_string( actorId ) + " -> " +
std::to_string( Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ) ) + std::to_string( Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ) ) +
" \neventId: " + " \neventId: " +
@ -72,7 +72,7 @@ void Core::Network::GameConnection::eventHandlerEmote( const Packets::GamePacket
std::string eventName = "onEmote"; std::string eventName = "onEmote";
std::string objName = Event::getEventName( eventId ); std::string objName = Event::getEventName( eventId );
player.sendDebug( "Actor: " + player.sendDebug( "Chara: " +
std::to_string( actorId ) + " -> " + std::to_string( actorId ) + " -> " +
std::to_string( Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ) ) + std::to_string( Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ) ) +
" \neventId: " + " \neventId: " +

View file

@ -104,7 +104,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
", params: " + std::to_string( param1 ) + ", " + ", params: " + std::to_string( param1 ) + ", " +
std::to_string( param2 ) + ", " + std::to_string( param3 ) ); std::to_string( param2 ) + ", " + std::to_string( param3 ) );
Core::Entity::ActorPtr targetActor; Core::Entity::CharaPtr targetActor;
if( player.getId() == param3 ) if( player.getId() == param3 )
@ -113,7 +113,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
} }
else else
{ {
auto inRange = player.getInRangeActors(); auto inRange = player.getInRangeCharas();
for( auto actor : inRange ) for( auto actor : inRange )
{ {
if( actor->getId() == param3 ) if( actor->getId() == param3 )
@ -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->getInRangeCharas();
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->getInRangeCharas();
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->getInRangeCharas();
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.getInRangeCharas();
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() );
@ -466,7 +466,7 @@ void Core::Network::GameConnection::gm2Handler( const Packets::GamePacket& inPac
g_log.debug( player.getName() + " used GM2 commandId: " + std::to_string( commandId ) + ", params: " + param1 ); g_log.debug( player.getName() + " used GM2 commandId: " + std::to_string( commandId ) + ", params: " + param1 );
auto targetSession = g_serverZone.getSession( param1 ); auto targetSession = g_serverZone.getSession( param1 );
Core::Entity::ActorPtr targetActor; Core::Entity::CharaPtr targetActor;
if( targetSession != nullptr ) if( targetSession != nullptr )
{ {
@ -496,11 +496,11 @@ void Core::Network::GameConnection::gm2Handler( const Packets::GamePacket& inPac
{ {
targetPlayer->resetHp(); targetPlayer->resetHp();
targetPlayer->resetMp(); targetPlayer->resetMp();
targetPlayer->setStatus( Entity::Actor::ActorStatus::Idle ); targetPlayer->setStatus( Entity::Chara::ActorStatus::Idle );
targetPlayer->sendToInRangeSet( ActorControlPacket143( player.getId(), ZoneIn, 0x01, 0x01, 0, 113 ), true ); targetPlayer->sendToInRangeSet( ActorControlPacket143( player.getId(), ZoneIn, 0x01, 0x01, 0, 113 ), true );
targetPlayer->sendToInRangeSet( ActorControlPacket142( player.getId(), SetStatus, targetPlayer->sendToInRangeSet( ActorControlPacket142( player.getId(), SetStatus,
static_cast< uint8_t >( Entity::Actor::ActorStatus::Idle ) ), true ); static_cast< uint8_t >( Entity::Chara::ActorStatus::Idle ) ), true );
player.sendNotice( "Raised " + targetPlayer->getName() ); player.sendNotice( "Raised " + targetPlayer->getName() );
break; break;
} }

View file

@ -75,7 +75,7 @@ void Core::Network::GameConnection::skillHandler( const Packets::GamePacket& inP
} }
else else
{ {
Core::Entity::ActorPtr targetActor = player.getAsPlayer(); Core::Entity::CharaPtr targetActor = player.getAsPlayer();
if( targetId != player.getId() ) if( targetId != player.getId() )
{ {
targetActor = player.lookupTargetById( targetId ); targetActor = player.lookupTargetById( targetId );

View file

@ -21,14 +21,14 @@ class MoveActorPacket :
public ZoneChannelPacket< FFXIVIpcActorMove > public ZoneChannelPacket< FFXIVIpcActorMove >
{ {
public: public:
MoveActorPacket( Entity::Actor& actor, uint8_t unk1, uint8_t unk2, uint8_t unk3, uint16_t unk4 ) : MoveActorPacket( Entity::Chara& actor, uint8_t unk1, uint8_t unk2, uint8_t unk3, uint16_t unk4 ) :
ZoneChannelPacket< FFXIVIpcActorMove >( actor.getId(), actor.getId() ) ZoneChannelPacket< FFXIVIpcActorMove >( actor.getId(), actor.getId() )
{ {
initialize( actor, unk1, unk2, unk3, unk4 ); initialize( actor, unk1, unk2, unk3, unk4 );
}; };
private: private:
void initialize( Entity::Actor& actor, uint8_t unk1, uint8_t unk2, uint8_t unk3, uint16_t unk4 ) void initialize( Entity::Chara& actor, uint8_t unk1, uint8_t unk2, uint8_t unk3, uint16_t unk4 )
{ {
m_data.rotation = Math::Util::floatToUInt8Rot( actor.getRotation() ); m_data.rotation = Math::Util::floatToUInt8Rot( actor.getRotation() );

View file

@ -90,22 +90,22 @@ namespace Server {
if( player.getZoningType() != Common::ZoneingType::None ) if( player.getZoningType() != Common::ZoneingType::None )
{ {
m_data.displayFlags |= Entity::Actor::DisplayFlags::Invisible; m_data.displayFlags |= Entity::Chara::DisplayFlags::Invisible;
} }
if( player.getEquipDisplayFlags() & Core::Common::EquipDisplayFlags::HideHead ) if( player.getEquipDisplayFlags() & Core::Common::EquipDisplayFlags::HideHead )
{ {
m_data.displayFlags |= Entity::Actor::DisplayFlags::HideHead; m_data.displayFlags |= Entity::Chara::DisplayFlags::HideHead;
} }
if( player.getEquipDisplayFlags() & Core::Common::EquipDisplayFlags::HideWeapon ) if( player.getEquipDisplayFlags() & Core::Common::EquipDisplayFlags::HideWeapon )
{ {
m_data.displayFlags |= Entity::Actor::DisplayFlags::HideWeapon; m_data.displayFlags |= Entity::Chara::DisplayFlags::HideWeapon;
} }
if( player.getEquipDisplayFlags() & Core::Common::EquipDisplayFlags::Visor ) if( player.getEquipDisplayFlags() & Core::Common::EquipDisplayFlags::Visor )
{ {
m_data.displayFlags |= Entity::Actor::DisplayFlags::Visor; m_data.displayFlags |= Entity::Chara::DisplayFlags::Visor;
} }
m_data.currentMount = player.getCurrentMount(); m_data.currentMount = player.getCurrentMount();

View file

@ -2,7 +2,7 @@
#define _UPDATEHPMPTP_H #define _UPDATEHPMPTP_H
#include <common/Network/GamePacketNew.h> #include <common/Network/GamePacketNew.h>
#include <Actor/Actor.h> #include <Actor/Chara.h>
#include "Forwards.h" #include "Forwards.h"
namespace Core { namespace Core {
@ -17,14 +17,14 @@ class UpdateHpMpTpPacket :
public ZoneChannelPacket< FFXIVIpcUpdateHpMpTp > public ZoneChannelPacket< FFXIVIpcUpdateHpMpTp >
{ {
public: public:
UpdateHpMpTpPacket( Entity::Actor& actor ) : UpdateHpMpTpPacket( Entity::Chara& actor ) :
ZoneChannelPacket< FFXIVIpcUpdateHpMpTp >( actor.getId(), actor.getId() ) ZoneChannelPacket< FFXIVIpcUpdateHpMpTp >( actor.getId(), actor.getId() )
{ {
initialize( actor ); initialize( actor );
}; };
private: private:
void initialize( Entity::Actor& actor ) void initialize( Entity::Chara& actor )
{ {
m_data.hp = actor.getHp(); m_data.hp = actor.getHp();
m_data.mp = actor.getMp(); m_data.mp = actor.getMp();

View file

@ -5,7 +5,7 @@
#include <typeinfo> #include <typeinfo>
#include <typeindex> #include <typeindex>
#include <Actor/Actor.h> #include <Actor/Chara.h>
#include <Actor/Player.h> #include <Actor/Player.h>
#include <StatusEffect/StatusEffect.h> #include <StatusEffect/StatusEffect.h>
#include <Zone/InstanceContent.h> #include <Zone/InstanceContent.h>
@ -53,14 +53,14 @@ public:
ScriptObject( effectId, typeid( StatusEffectScript ).hash_code() ) ScriptObject( effectId, typeid( StatusEffectScript ).hash_code() )
{ } { }
virtual void onTick( Entity::Actor& actor ) { } virtual void onTick( Entity::Chara& actor ) { }
virtual void onApply( Entity::Actor& actor ) { } virtual void onApply( Entity::Chara& actor ) { }
virtual void onRemove( Entity::Actor& actor ) { } virtual void onRemove( Entity::Chara& actor ) { }
virtual void onExpire( Entity::Actor& actor ) { } virtual void onExpire( Entity::Chara& actor ) { }
virtual void onPlayerCollision( Entity::Actor& actor, Entity::Actor& actorHit ) { } virtual void onPlayerCollision( Entity::Chara& actor, Entity::Chara& actorHit ) { }
virtual void onPlayerFinishCast( Entity::Actor& actor ) { } virtual void onPlayerFinishCast( Entity::Chara& actor ) { }
virtual void onPlayerDamaged( Entity::Actor& actor ) { } virtual void onPlayerDamaged( Entity::Chara& actor ) { }
virtual void onPlayerDeath( Entity::Actor& actor ) { } virtual void onPlayerDeath( Entity::Chara& actor ) { }
}; };
@ -71,9 +71,9 @@ public:
ScriptObject( abilityId, typeid( ActionScript ).hash_code() ) ScriptObject( abilityId, typeid( ActionScript ).hash_code() )
{ } { }
virtual void onStart( Entity::Actor& sourceActor, Entity::Actor& targetActor ) { } virtual void onStart( Entity::Chara& sourceActor, Entity::Chara& targetActor ) { }
virtual void onCastFinish( Entity::Player& player, Entity::Actor& targetActor ) { } virtual void onCastFinish( Entity::Player& player, Entity::Chara& targetActor ) { }
virtual void onInterrupt( Entity::Actor& sourceActor/*, Core::Entity::Actor targetActor*/ ) { } virtual void onInterrupt( Entity::Chara& sourceActor/*, Core::Entity::Chara targetActor*/ ) { }
}; };

View file

@ -275,7 +275,7 @@ bool Core::Scripting::ScriptManager::onMobKill( Entity::Player& player, uint16_t
return true; return true;
} }
bool Core::Scripting::ScriptManager::onCastFinish( Entity::Player& player, Entity::ActorPtr pTarget, uint32_t actionId ) bool Core::Scripting::ScriptManager::onCastFinish( Entity::Player& player, Entity::CharaPtr pTarget, uint32_t actionId )
{ {
auto script = m_nativeScriptManager->getScript< ActionScript >( actionId ); auto script = m_nativeScriptManager->getScript< ActionScript >( actionId );
@ -284,7 +284,7 @@ bool Core::Scripting::ScriptManager::onCastFinish( Entity::Player& player, Entit
return true; return true;
} }
bool Core::Scripting::ScriptManager::onStatusReceive( Entity::ActorPtr pActor, uint32_t effectId ) bool Core::Scripting::ScriptManager::onStatusReceive( Entity::CharaPtr pActor, uint32_t effectId )
{ {
auto script = m_nativeScriptManager->getScript< StatusEffectScript >( effectId ); auto script = m_nativeScriptManager->getScript< StatusEffectScript >( effectId );
@ -300,30 +300,30 @@ bool Core::Scripting::ScriptManager::onStatusReceive( Entity::ActorPtr pActor, u
return false; return false;
} }
bool Core::Scripting::ScriptManager::onStatusTick( Entity::ActorPtr pActor, Core::StatusEffect::StatusEffect& effect ) bool Core::Scripting::ScriptManager::onStatusTick( Entity::CharaPtr pChara, Core::StatusEffect::StatusEffect& effect )
{ {
auto script = m_nativeScriptManager->getScript< StatusEffectScript >( effect.getId() ); auto script = m_nativeScriptManager->getScript< StatusEffectScript >( effect.getId() );
if( script ) if( script )
{ {
if( pActor->isPlayer() ) if( pChara->isPlayer() )
pActor->getAsPlayer()->sendDebug( "Calling status tick for statusid: " + std::to_string( effect.getId() ) ); pChara->getAsPlayer()->sendDebug( "Calling status tick for statusid: " + std::to_string( effect.getId() ) );
script->onTick( *pActor ); script->onTick( *pChara );
return true; return true;
} }
return false; return false;
} }
bool Core::Scripting::ScriptManager::onStatusTimeOut( Entity::ActorPtr pActor, uint32_t effectId ) bool Core::Scripting::ScriptManager::onStatusTimeOut( Entity::CharaPtr pChara, uint32_t effectId )
{ {
auto script = m_nativeScriptManager->getScript< StatusEffectScript >( effectId ); auto script = m_nativeScriptManager->getScript< StatusEffectScript >( effectId );
if( script ) if( script )
{ {
if( pActor->isPlayer() ) if( pChara->isPlayer() )
pActor->getAsPlayer()->sendDebug( "Calling status timeout for statusid: " + std::to_string( effectId ) ); pChara->getAsPlayer()->sendDebug( "Calling status timeout for statusid: " + std::to_string( effectId ) );
script->onExpire( *pActor ); script->onExpire( *pChara );
return true; return true;
} }

View file

@ -48,11 +48,11 @@ namespace Core
bool onMobKill( Entity::Player& player, uint16_t nameId ); bool onMobKill( Entity::Player& player, uint16_t nameId );
bool onCastFinish( Entity::Player& pPlayer, Entity::ActorPtr pTarget, uint32_t actionId ); bool onCastFinish( Entity::Player& pPlayer, Entity::CharaPtr pTarget, uint32_t actionId );
bool onStatusReceive( Entity::ActorPtr pActor, uint32_t effectId ); bool onStatusReceive( Entity::CharaPtr pActor, uint32_t effectId );
bool onStatusTick( Entity::ActorPtr pActor, Core::StatusEffect::StatusEffect& effect ); bool onStatusTick( Entity::CharaPtr pActor, Core::StatusEffect::StatusEffect& effect );
bool onStatusTimeOut( Entity::ActorPtr pActor, uint32_t effectId ); bool onStatusTimeOut( Entity::CharaPtr pActor, uint32_t effectId );
bool onZoneInit( ZonePtr pZone ); bool onZoneInit( ZonePtr pZone );

View file

@ -3,7 +3,7 @@
#include <Script/NativeScriptApi.h> #include <Script/NativeScriptApi.h>
#include <Forwards.h> #include <Forwards.h>
#include <Actor/Actor.h> #include <Actor/Chara.h>
#include <Actor/Player.h> #include <Actor/Player.h>
#include <Event/EventHelper.h> #include <Event/EventHelper.h>

View file

@ -6,7 +6,7 @@ public:
ActionSprint3() : ActionScript( 3 ) ActionSprint3() : ActionScript( 3 )
{} {}
void onCastFinish( Core::Entity::Player& player, Core::Entity::Actor& targetActor ) override void onCastFinish( Core::Entity::Player& player, Core::Entity::Chara& targetActor ) override
{ {
player.addStatusEffectByIdIfNotExist( 50, 20000, player, 30 ); player.addStatusEffectByIdIfNotExist( 50, 20000, player, 30 );
} }

View file

@ -6,7 +6,7 @@
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include <algorithm> #include <algorithm>
#include "Actor/Actor.h" #include "Actor/Chara.h"
#include "StatusEffect.h" #include "StatusEffect.h"
#include "Script/ScriptManager.h" #include "Script/ScriptManager.h"
@ -20,7 +20,7 @@ using namespace Core::Network::Packets::Server;
extern Core::Scripting::ScriptManager g_scriptMgr; extern Core::Scripting::ScriptManager g_scriptMgr;
Core::StatusEffect::StatusEffect::StatusEffect( uint32_t id, Entity::ActorPtr sourceActor, Entity::ActorPtr targetActor, Core::StatusEffect::StatusEffect::StatusEffect( uint32_t id, Entity::CharaPtr sourceActor, Entity::CharaPtr targetActor,
uint32_t duration, uint32_t tickRate ) uint32_t duration, uint32_t tickRate )
: m_id( id ) : m_id( id )
, m_sourceActor( sourceActor ) , m_sourceActor( sourceActor )

View file

@ -14,7 +14,7 @@ namespace StatusEffect
class StatusEffect class StatusEffect
{ {
public: public:
StatusEffect( uint32_t id, Entity::ActorPtr sourceActor, Entity::ActorPtr targetActor, StatusEffect( uint32_t id, Entity::CharaPtr sourceActor, Entity::CharaPtr targetActor,
uint32_t duration, uint32_t tickRate ); uint32_t duration, uint32_t tickRate );
~StatusEffect(); ~StatusEffect();
@ -39,8 +39,8 @@ public:
private: private:
uint32_t m_id; uint32_t m_id;
Entity::ActorPtr m_sourceActor; Entity::CharaPtr m_sourceActor;
Entity::ActorPtr m_targetActor; Entity::CharaPtr m_targetActor;
uint32_t m_duration; uint32_t m_duration;
uint64_t m_startTime; uint64_t m_startTime;
uint32_t m_tickRate; uint32_t m_tickRate;

View file

@ -1,101 +1,86 @@
#include "Cell.h" #include "Cell.h"
#include "Actor/Actor.h" #include "Actor/Chara.h"
#include "Actor/BattleNpc.h" #include "Actor/BattleNpc.h"
#include "Forwards.h" #include "Forwards.h"
#include "Zone.h" #include "Zone.h"
// TODO: the entire zone / areahandling is a bit outdated ( in parts i used this for the 1.0 iteration ) // TODO: the entire zone / areahandling is a bit outdated ( in parts i used this for the 1.0 iteration )
// likely this could be greatly improved or redone // likely this could be greatly improved or redone
namespace Core
{
Core::Cell::Cell() :
Cell::Cell() m_bActive( false ),
: m_bActive(false) m_bLoaded( false ),
, m_bLoaded(false) m_playerCount( 0 ),
, m_playerCount(0) m_bUnloadPending( false )
, m_bUnloadPending(false)
{ {
m_bForcedActive = false; m_bForcedActive = false;
} }
Cell::~Cell() Core::Cell::~Cell()
{ {
removeActors(); removeCharas();
} }
void Cell::init(uint32_t x, uint32_t y, ZonePtr pZone) void Core::Cell::init( uint32_t x, uint32_t y, ZonePtr pZone )
{ {
//Console->outDebOnly("[Region:%X] Initializing a new cell[%i/%i]", pRegion->getId(), x, y ); //Console->outDebOnly("[Region:%X] Initializing a new cell[%i/%i]", pRegion->getId(), x, y );
m_pZone = pZone; m_pZone = pZone;
m_posX = x; m_posX = x;
m_posY = y; m_posY = y;
m_actors.clear(); m_charas.clear();
} }
void Cell::loadActors(CellCache* pCC) void Core::Cell::loadCharas( CellCache* pCC )
{ {
m_bLoaded = true; m_bLoaded = true;
assert( pCC ); assert( pCC );
for( auto entry : pCC->battleNpcCache ) for( auto entry : pCC->battleNpcCache )
{ {
entry->setCurrentZone( m_pZone ); entry->setCurrentZone( m_pZone );
m_pZone->pushActor( entry ); m_pZone->pushActor( entry );
} }
} }
void Cell::addActor(Entity::ActorPtr pAct) void Core::Cell::addChara( Entity::CharaPtr pAct )
{ {
if( pAct->isPlayer() ) if( pAct->isPlayer() )
{
//Console->outDebOnly("[Region:%X] Adding player %i to cell[%i/%i]", m_pZone->getId(), pAct->getId(), m_posX, m_posY);
++m_playerCount; ++m_playerCount;
m_charas.insert(pAct);
} }
m_actors.insert(pAct); void Core::Cell::removeChara( Entity::CharaPtr pAct )
}
void Cell::removeActor(Entity::ActorPtr pAct)
{ {
if( pAct->isPlayer() ) if( pAct->isPlayer() )
{
//->outDebOnly("[Region:%X] Removing player %i from cell[%i/%i]", m_pZone->getId(), pAct->getId(), m_posX, m_posY);
--m_playerCount; --m_playerCount;
m_charas.erase(pAct);
} }
m_actors.erase(pAct); void Core::Cell::setActivity( bool state )
}
void Cell::setActivity(bool state)
{ {
if( !m_bActive && state ) if( !m_bActive && state )
{ {
// Move all objects to active set. // Move all objects to active set.
for(auto itr = m_actors.begin(); itr != m_actors.end(); ++itr) //for( auto itr = m_charas.begin(); itr != m_charas.end(); ++itr )
{ //{
} //}
if( m_bUnloadPending ) if( m_bUnloadPending )
{
cancelPendingUnload(); cancelPendingUnload();
}
} }
else if( m_bActive && !state ) else if( m_bActive && !state )
{ {
// Move all objects from active set. // Move all objects from active set.
for(auto itr = m_actors.begin(); itr != m_actors.end(); ++itr) //for(auto itr = m_charas.begin(); itr != m_charas.end(); ++itr)
{ //{
} //}
} }
@ -103,15 +88,16 @@ namespace Core
m_bActive = state; m_bActive = state;
} }
void Cell::removeActors()
void Core::Cell::removeCharas()
{ {
//uint32_t ltime = getMSTime(); //uint32_t ltime = getMSTime();
m_actors.clear(); m_charas.clear();
//This time it's simpler! We just remove everything //This time it's simpler! We just remove everything
Entity::ActorPtr pAct; //do this outside the loop! Entity::ActorPtr pAct; //do this outside the loop!
for(auto itr = m_actors.begin(); itr != m_actors.end();) for( auto itr = m_charas.begin(); itr != m_charas.end(); )
{ {
pAct = (*itr); pAct = (*itr);
itr++; itr++;
@ -132,40 +118,29 @@ namespace Core
m_bLoaded = false; m_bLoaded = false;
} }
void Core::Cell::queueUnloadPending()
void Cell::queueUnloadPending()
{ {
if( m_bUnloadPending ) if( m_bUnloadPending )
{
return; return;
}
m_bUnloadPending = true; m_bUnloadPending = true;
} }
void Cell::cancelPendingUnload() void Core::Cell::cancelPendingUnload()
{ {
if( !m_bUnloadPending ) if( !m_bUnloadPending )
{
return; return;
} }
} void Core::Cell::unload()
void Cell::unload()
{ {
assert( m_bUnloadPending ); assert( m_bUnloadPending );
if( m_bActive ) if( m_bActive )
{
return; return;
}
removeActors(); removeCharas();
m_bUnloadPending = false; m_bUnloadPending = false;
} }
}

View file

@ -15,7 +15,7 @@ namespace Core {
std::vector< Entity::BattleNpcPtr > battleNpcCache; std::vector< Entity::BattleNpcPtr > battleNpcCache;
}; };
typedef std::set< Entity::ActorPtr > ActorSet; typedef std::set< Entity::CharaPtr > CharaSet;
class Cell class Cell
{ {
@ -25,7 +25,7 @@ namespace Core {
bool m_bForcedActive; bool m_bForcedActive;
uint16_t m_posX; uint16_t m_posX;
uint16_t m_posY; uint16_t m_posY;
ActorSet m_actors; CharaSet m_charas;
bool m_bActive; bool m_bActive;
bool m_bLoaded; bool m_bLoaded;
bool m_bUnloadPending; bool m_bUnloadPending;
@ -39,15 +39,15 @@ namespace Core {
void init( uint32_t x, uint32_t y, ZonePtr pZone ); void init( uint32_t x, uint32_t y, ZonePtr pZone );
void addActor(Entity::ActorPtr pAct); void addChara( Entity::CharaPtr pAct );
void removeActor(Entity::ActorPtr pAct); void removeChara( Entity::CharaPtr pAct );
void loadActors(CellCache* pCC); void loadCharas( CellCache *pCC );
bool hasActor(Entity::ActorPtr pAct) bool hasChara( Entity::CharaPtr pAct )
{ {
return (m_actors.find(pAct) != m_actors.end()); return (m_charas.find(pAct) != m_charas.end());
} }
bool hasPlayers() const bool hasPlayers() const
@ -55,21 +55,21 @@ namespace Core {
return ((m_playerCount > 0) ? true : false); return ((m_playerCount > 0) ? true : false);
} }
size_t getActorCount() const size_t getCharaCount() const
{ {
return m_actors.size(); return m_charas.size();
} }
void removeActors(); void removeCharas();
ActorSet::iterator begin() CharaSet::iterator begin()
{ {
return m_actors.begin(); return m_charas.begin();
} }
ActorSet::iterator end() CharaSet::iterator end()
{ {
return m_actors.end(); return m_charas.end();
} }
void setActivity(bool state); void setActivity(bool state);

View file

@ -16,7 +16,7 @@
#include "TerritoryMgr.h" #include "TerritoryMgr.h"
#include "Session.h" #include "Session.h"
#include "Actor/Actor.h" #include "Actor/Chara.h"
#include "Actor/Player.h" #include "Actor/Player.h"
#include "Actor/BattleNpc.h" #include "Actor/BattleNpc.h"
#include "Actor/EventNpc.h" #include "Actor/EventNpc.h"
@ -268,10 +268,10 @@ Core::Common::Weather Core::Zone::getNextWeather()
return Common::Weather::FairSkies; return Common::Weather::FairSkies;
} }
void Core::Zone::pushActor( Entity::ActorPtr pActor ) void Core::Zone::pushActor( Entity::CharaPtr pChara )
{ {
float mx = pActor->getPos().x; float mx = pChara->getPos().x;
float my = pActor->getPos().z; float my = pChara->getPos().z;
uint32_t cx = getPosX( mx ); uint32_t cx = getPosX( mx );
uint32_t cy = getPosY( my ); uint32_t cy = getPosY( my );
@ -282,12 +282,12 @@ void Core::Zone::pushActor( Entity::ActorPtr pActor )
pCell->init( cx, cy, shared_from_this() ); pCell->init( cx, cy, shared_from_this() );
} }
pCell->addActor( pActor ); pCell->addChara(pChara);
pActor->setCell( pCell ); pChara->setCell( pCell );
uint32_t cellX = getPosX( pActor->getPos().x ); uint32_t cellX = getPosX( pChara->getPos().x );
uint32_t cellY = getPosY( pActor->getPos().z ); uint32_t cellY = getPosY( pChara->getPos().z );
uint32_t endX = cellX <= _sizeX ? cellX + 1 : ( _sizeX - 1 ); uint32_t endX = cellX <= _sizeX ? cellX + 1 : ( _sizeX - 1 );
uint32_t endY = cellY <= _sizeY ? cellY + 1 : ( _sizeY - 1 ); uint32_t endY = cellY <= _sizeY ? cellY + 1 : ( _sizeY - 1 );
@ -301,13 +301,13 @@ void Core::Zone::pushActor( Entity::ActorPtr pActor )
{ {
pCell = getCell( posX, posY ); pCell = getCell( posX, posY );
if( pCell ) if( pCell )
updateInRangeSet( pActor, pCell ); updateInRangeSet( pChara, pCell );
} }
} }
if( pActor->isPlayer() ) if( pChara->isPlayer() )
{ {
auto pPlayer = pActor->getAsPlayer(); auto pPlayer = pChara->getAsPlayer();
auto pSession = g_serverZone.getSession( pPlayer->getId() ); auto pSession = g_serverZone.getSession( pPlayer->getId() );
if( pSession ) if( pSession )
@ -315,17 +315,17 @@ void Core::Zone::pushActor( Entity::ActorPtr pActor )
m_playerMap[pPlayer->getId()] = pPlayer; m_playerMap[pPlayer->getId()] = pPlayer;
updateCellActivity( cx, cy, 2 ); updateCellActivity( cx, cy, 2 );
} }
else if( pActor->isBattleNpc() ) else if( pChara->isBattleNpc() )
{ {
Entity::BattleNpcPtr pBNpc = pActor->getAsBattleNpc(); Entity::BattleNpcPtr pBNpc = pChara->getAsBattleNpc();
m_BattleNpcMap[pBNpc->getId()] = pBNpc; m_BattleNpcMap[pBNpc->getId()] = pBNpc;
pBNpc->setPosition( pBNpc->getPos() ); pBNpc->setPosition( pBNpc->getPos() );
} }
else if( pActor->isEventNpc() ) else if( pChara->isEventNpc() )
{ {
Entity::EventNpcPtr pENpc = pActor->getAsEventNpc(); Entity::EventNpcPtr pENpc = pChara->getAsEventNpc();
m_EventNpcMap[pENpc->getId()] = pENpc; m_EventNpcMap[pENpc->getId()] = pENpc;
pENpc->setPosition( pENpc->getPos() ); pENpc->setPosition( pENpc->getPos() );
} }
@ -333,37 +333,37 @@ void Core::Zone::pushActor( Entity::ActorPtr pActor )
} }
void Core::Zone::removeActor( Entity::ActorPtr pActor ) void Core::Zone::removeActor( Entity::CharaPtr pChara )
{ {
if( pActor->m_pCell ) if( pChara->m_pCell )
{ {
pActor->m_pCell->removeActor( pActor ); pChara->m_pCell->removeChara(pChara);
pActor->m_pCell = nullptr; pChara->m_pCell = nullptr;
} }
if( pActor->isPlayer() ) if( pChara->isPlayer() )
{ {
// If it's a player and he's inside boundaries - update his nearby cells // If it's a player and he's inside boundaries - update his nearby cells
if( pActor->getPos().x <= _maxX && pActor->getPos().x >= _minX && if( pChara->getPos().x <= _maxX && pChara->getPos().x >= _minX &&
pActor->getPos().z <= _maxY && pActor->getPos().z >= _minY ) pChara->getPos().z <= _maxY && pChara->getPos().z >= _minY )
{ {
uint32_t x = getPosX( pActor->getPos().x ); uint32_t x = getPosX( pChara->getPos().x );
uint32_t y = getPosY( pActor->getPos().z ); uint32_t y = getPosY( pChara->getPos().z );
updateCellActivity( x, y, 3 ); updateCellActivity( x, y, 3 );
} }
m_playerMap.erase( pActor->getId() ); m_playerMap.erase( pChara->getId() );
onLeaveTerritory( *pActor->getAsPlayer() ); onLeaveTerritory( *pChara->getAsPlayer() );
} }
else if( pActor->isBattleNpc() ) else if( pChara->isBattleNpc() )
m_BattleNpcMap.erase( pActor->getId() ); m_BattleNpcMap.erase( pChara->getId() );
// remove from lists of other actors // remove from lists of other actors
pActor->removeFromInRange(); pChara->removeFromInRange();
pActor->clearInRangeSet(); pChara->clearInRangeSet();
} }
@ -601,7 +601,7 @@ void Core::Zone::updateCellActivity( uint32_t x, uint32_t y, int32_t radius )
CellCache * pCC = getCellCacheAndCreate( posX, posY ); CellCache * pCC = getCellCacheAndCreate( posX, posY );
if( pCC ) if( pCC )
pCell->loadActors( pCC ); pCell->loadCharas(pCC);
} }
} }
else else
@ -615,7 +615,7 @@ void Core::Zone::updateCellActivity( uint32_t x, uint32_t y, int32_t radius )
{ {
CellCache * pCC = getCellCacheAndCreate( posX, posY ); CellCache * pCC = getCellCacheAndCreate( posX, posY );
if( pCC ) if( pCC )
pCell->loadActors( pCC ); pCell->loadCharas(pCC);
} }
} }
else if( !isCellActive( posX, posY ) && pCell->isActive() ) else if( !isCellActive( posX, posY ) && pCell->isActive() )
@ -625,7 +625,7 @@ void Core::Zone::updateCellActivity( uint32_t x, uint32_t y, int32_t radius )
} }
} }
void Core::Zone::updateActorPosition( Entity::Actor &actor ) void Core::Zone::updateActorPosition( Entity::Chara &actor )
{ {
if( actor.getCurrentZone() != shared_from_this() ) if( actor.getCurrentZone() != shared_from_this() )
@ -652,9 +652,9 @@ void Core::Zone::updateActorPosition( Entity::Actor &actor )
{ {
if( pOldCell ) if( pOldCell )
pOldCell->removeActor( actor.getAsActor() ); pOldCell->removeChara(actor.getAsChara());
pCell->addActor( actor.getAsActor() ); pCell->addChara(actor.getAsChara());
actor.m_pCell = pCell; actor.m_pCell = pCell;
// if player we need to update cell activity // if player we need to update cell activity
@ -686,13 +686,13 @@ void Core::Zone::updateActorPosition( Entity::Actor &actor )
{ {
pCell = getCell( posX, posY ); pCell = getCell( posX, posY );
if( pCell ) if( pCell )
updateInRangeSet( actor.getAsActor(), pCell ); updateInRangeSet( actor.getAsChara(), pCell );
} }
} }
} }
void Core::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell ) void Core::Zone::updateInRangeSet( Entity::CharaPtr pChara, Cell* pCell )
{ {
if( pCell == nullptr ) if( pCell == nullptr )
return; return;
@ -701,33 +701,33 @@ void Core::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell )
if( g_territoryMgr.isPrivateTerritory( getTerritoryId() ) ) if( g_territoryMgr.isPrivateTerritory( getTerritoryId() ) )
return; return;
Entity::ActorPtr pCurAct; Entity::CharaPtr pCurAct;
auto iter = pCell->m_actors.begin(); auto iter = pCell->m_charas.begin();
float fRange = 70.0f; float fRange = 70.0f;
int32_t count = 0; int32_t count = 0;
while( iter != pCell->m_actors.end() ) while( iter != pCell->m_charas.end() )
{ {
pCurAct = *iter; pCurAct = *iter;
++iter; ++iter;
if( !pCurAct || pCurAct == pActor ) if( !pCurAct || pCurAct == pChara )
continue; continue;
float distance = Math::Util::distance( pCurAct->getPos().x, pCurAct->getPos().y, pCurAct->getPos().z, float distance = Math::Util::distance( pCurAct->getPos().x, pCurAct->getPos().y, pCurAct->getPos().z,
pActor->getPos().x, pActor->getPos().y, pActor->getPos().z ); pChara->getPos().x, pChara->getPos().y, pChara->getPos().z );
bool isInRange = ( fRange == 0.0f || distance <= fRange ); bool isInRange = ( fRange == 0.0f || distance <= fRange );
bool isInRangeSet = pActor->isInRangeSet( pCurAct ); bool isInRangeSet = pChara->isInRangeSet( pCurAct );
// Add if we are not ourself and range == 0 or distance is withing range. // Add if we are not ourself and range == 0 or distance is withing range.
if( isInRange && !isInRangeSet ) if( isInRange && !isInRangeSet )
{ {
if( pActor->isPlayer() ) if( pChara->isPlayer() )
{ {
auto pOwnPlayer = pActor->getAsPlayer(); auto pOwnPlayer = pChara->getAsPlayer();
if( !pOwnPlayer->isLoadingComplete() ) if( !pOwnPlayer->isLoadingComplete() )
continue; continue;
@ -737,8 +737,8 @@ void Core::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell )
if( count > 12 ) if( count > 12 )
break; break;
pActor->addInRangeActor( pCurAct ); pChara->addInRangeChara( pCurAct );
pCurAct->addInRangeActor( pActor ); pCurAct->addInRangeChara( pChara );
// spawn the actor for the player // spawn the actor for the player
pCurAct->spawn( pOwnPlayer ); pCurAct->spawn( pOwnPlayer );
@ -748,34 +748,34 @@ void Core::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell )
if( !pPlayer->isLoadingComplete() ) if( !pPlayer->isLoadingComplete() )
continue; continue;
pActor->spawn( pPlayer ); pChara->spawn( pPlayer );
} }
} }
else if( ( pActor->isBattleNpc() || pActor->isEventNpc() ) && pCurAct->isPlayer() && pActor->isAlive() ) else if( ( pChara->isBattleNpc() || pChara->isEventNpc() ) && pCurAct->isPlayer() && pChara->isAlive() )
{ {
auto pPlayer = pCurAct->getAsPlayer(); auto pPlayer = pCurAct->getAsPlayer();
if( pPlayer->isLoadingComplete() ) if( pPlayer->isLoadingComplete() )
{ {
pActor->spawn( pPlayer ); pChara->spawn( pPlayer );
pCurAct->addInRangeActor( pActor ); pCurAct->addInRangeChara( pChara );
pActor->addInRangeActor( pCurAct ); pChara->addInRangeChara( pCurAct );
} }
} }
else else
{ {
pActor->addInRangeActor( pCurAct ); pChara->addInRangeChara( pCurAct );
pCurAct->addInRangeActor( pActor ); pCurAct->addInRangeChara( pChara );
} }
} }
else if( !isInRange && isInRangeSet ) else if( !isInRange && isInRangeSet )
{ {
pCurAct->removeInRangeActor( *pActor ); pCurAct->removeInRangeChara( *pChara );
if( pActor->getCurrentZone() != pCurAct->getCurrentZone() ) if( pChara->getCurrentZone() != pCurAct->getCurrentZone() )
continue; continue;
pActor->removeInRangeActor( *pCurAct ); pChara->removeInRangeChara( *pCurAct );
} }
} }
} }

View file

@ -86,17 +86,17 @@ public:
Common::Weather getNextWeather(); Common::Weather getNextWeather();
void pushActor( Entity::ActorPtr pActor ); void pushActor( Entity::CharaPtr pActor );
void removeActor( Entity::ActorPtr pActor ); void removeActor( Entity::CharaPtr pActor );
void updateActorPosition( Entity::Actor &pActor ); void updateActorPosition( Entity::Chara &pActor );
bool isCellActive( uint32_t x, uint32_t y ); bool isCellActive( uint32_t x, uint32_t y );
void updateCellActivity( uint32_t x, uint32_t y, int32_t radius ); void updateCellActivity( uint32_t x, uint32_t y, int32_t radius );
void updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell ); void updateInRangeSet( Entity::CharaPtr pActor, Cell* pCell );
void queueOutPacketForRange( Entity::Player& sourcePlayer, uint32_t range, Network::Packets::GamePacketPtr pPacketEntry ); void queueOutPacketForRange( Entity::Player& sourcePlayer, uint32_t range, Network::Packets::GamePacketPtr pPacketEntry );