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:
parent
ba511a23e2
commit
9a4e7533c6
54 changed files with 1749 additions and 1774 deletions
|
@ -33,10 +33,10 @@ switch( commandId )
|
|||
case 0x01: // Toggle sheathe
|
||||
{
|
||||
if ( param11 == 1 )
|
||||
pPlayer->setStance( Entity::Actor::Stance::Active );
|
||||
pPlayer->setStance( Entity::Chara::Stance::Active );
|
||||
else
|
||||
{
|
||||
pPlayer->setStance( Entity::Actor::Stance::Passive );
|
||||
pPlayer->setStance( Entity::Chara::Stance::Passive );
|
||||
pPlayer->setAutoattack( false );
|
||||
}
|
||||
|
||||
|
|
|
@ -34,11 +34,11 @@ namespace Core
|
|||
|
||||
namespace Entity
|
||||
{
|
||||
class Actor;
|
||||
class Chara;
|
||||
class Player;
|
||||
class BattleNpc;
|
||||
|
||||
typedef boost::shared_ptr<Actor> ActorPtr;
|
||||
typedef boost::shared_ptr<Chara> ActorPtr;
|
||||
typedef boost::shared_ptr<Player> PlayerPtr;
|
||||
typedef boost::shared_ptr<BattleNpc> BattleNpcPtr;
|
||||
}
|
||||
|
|
|
@ -22,7 +22,7 @@ Core::Common::HandleActionType Core::Action::Action::getHandleActionType() const
|
|||
return m_handleActionType;
|
||||
}
|
||||
|
||||
Core::Entity::ActorPtr Core::Action::Action::getTargetActor() const
|
||||
Core::Entity::CharaPtr Core::Action::Action::getTargetChara() const
|
||||
{
|
||||
return m_pTarget;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ void Core::Action::Action::setCastTime( uint32_t castTime )
|
|||
m_castTime = castTime;
|
||||
}
|
||||
|
||||
Core::Entity::ActorPtr Core::Action::Action::getActionSource() const
|
||||
Core::Entity::CharaPtr Core::Action::Action::getActionSource() const
|
||||
{
|
||||
return m_pSource;
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace Action {
|
|||
|
||||
Common::HandleActionType getHandleActionType() const;
|
||||
|
||||
Entity::ActorPtr getTargetActor() const;
|
||||
Entity::CharaPtr getTargetChara() const;
|
||||
|
||||
bool isInterrupted() const;
|
||||
|
||||
|
@ -32,7 +32,7 @@ namespace Action {
|
|||
|
||||
void setCastTime( uint32_t castTime );
|
||||
|
||||
Entity::ActorPtr getActionSource() const;
|
||||
Entity::CharaPtr getActionSource() const;
|
||||
|
||||
virtual void onStart() {};
|
||||
virtual void onFinish() {};
|
||||
|
@ -48,8 +48,8 @@ namespace Action {
|
|||
uint64_t m_startTime;
|
||||
uint32_t m_castTime;
|
||||
|
||||
Entity::ActorPtr m_pSource;
|
||||
Entity::ActorPtr m_pTarget;
|
||||
Entity::CharaPtr m_pSource;
|
||||
Entity::CharaPtr m_pTarget;
|
||||
|
||||
bool m_bInterrupt;
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ Core::Action::ActionCast::ActionCast()
|
|||
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_id = actionId;
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace Action {
|
|||
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 onFinish() override;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include <common/Util/UtilMath.h>
|
||||
|
||||
#include "ActionCollision.h"
|
||||
#include "Actor/Actor.h"
|
||||
#include "Actor/Chara.h"
|
||||
#include "Actor/Player.h"
|
||||
|
||||
#include <cmath>
|
||||
|
@ -13,7 +13,7 @@ using namespace Core::Common;
|
|||
|
||||
// todo: add AoE actor limits (16, 32)
|
||||
|
||||
bool ActionCollision::isActorApplicable( Actor& actor, TargetFilter targetFilter )
|
||||
bool ActionCollision::isActorApplicable( Chara& chara, TargetFilter targetFilter )
|
||||
{
|
||||
bool actorApplicable = false;
|
||||
switch( targetFilter )
|
||||
|
@ -25,37 +25,37 @@ bool ActionCollision::isActorApplicable( Actor& actor, TargetFilter targetFilter
|
|||
}
|
||||
case TargetFilter::Players:
|
||||
{
|
||||
actorApplicable = actor.isPlayer();
|
||||
actorApplicable = chara.isPlayer();
|
||||
break;
|
||||
}
|
||||
case TargetFilter::Allies:
|
||||
{
|
||||
// todo: implement ally NPCs
|
||||
actorApplicable = !actor.isBattleNpc();
|
||||
actorApplicable = !chara.isBattleNpc();
|
||||
break;
|
||||
}
|
||||
case TargetFilter::Party:
|
||||
{
|
||||
// todo: implement party
|
||||
actorApplicable = actor.isPlayer();
|
||||
actorApplicable = chara.isPlayer();
|
||||
break;
|
||||
}
|
||||
case TargetFilter::Enemies:
|
||||
{
|
||||
actorApplicable = actor.isBattleNpc();
|
||||
actorApplicable = chara.isBattleNpc();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ( actorApplicable && actor.isAlive() );
|
||||
return ( actorApplicable && chara.isAlive() );
|
||||
}
|
||||
|
||||
std::set< Core::Entity::ActorPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition,
|
||||
std::set< ActorPtr > actorsInRange,
|
||||
std::set< Core::Entity::CharaPtr > ActionCollision::getActorsHitFromAction( FFXIVARR_POSITION3 aoePosition,
|
||||
std::set< CharaPtr > actorsInRange,
|
||||
boost::shared_ptr< Core::Data::Action > actionInfo,
|
||||
TargetFilter targetFilter )
|
||||
{
|
||||
std::set< ActorPtr > actorsCollided;
|
||||
std::set< CharaPtr > actorsCollided;
|
||||
|
||||
switch( static_cast< ActionCollisionType >( actionInfo->castType ) )
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <common/Common.h>
|
||||
#include <common/Exd/ExdDataGenerated.h>
|
||||
|
||||
#include "Actor/Actor.h"
|
||||
#include "Actor/Chara.h"
|
||||
#include "Action.h"
|
||||
|
||||
namespace Core {
|
||||
|
@ -23,9 +23,9 @@ namespace Entity {
|
|||
{
|
||||
public:
|
||||
|
||||
static bool isActorApplicable( Actor& actor, TargetFilter targetFilter );
|
||||
static std::set< ActorPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition,
|
||||
std::set< ActorPtr > actorsInRange,
|
||||
static bool isActorApplicable( Chara& actor, TargetFilter targetFilter );
|
||||
static std::set< CharaPtr > getActorsHitFromAction( Common::FFXIVARR_POSITION3 aoePosition,
|
||||
std::set< CharaPtr > actorsInRange,
|
||||
boost::shared_ptr< Data::Action > actionInfo,
|
||||
TargetFilter targetFilter );
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ Core::Action::ActionMount::ActionMount()
|
|||
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_id = mountId;
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace Action {
|
|||
ActionMount();
|
||||
~ActionMount();
|
||||
|
||||
ActionMount( Entity::ActorPtr pActor, uint16_t mountId );
|
||||
ActionMount( Entity::CharaPtr pActor, uint16_t mountId );
|
||||
|
||||
void onStart() override;
|
||||
void onFinish() override;
|
||||
|
|
|
@ -21,7 +21,7 @@ Core::Action::ActionTeleport::ActionTeleport()
|
|||
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_id = 5;
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace Action {
|
|||
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 onFinish() override;
|
||||
|
|
|
@ -21,7 +21,7 @@ Core::Action::EventAction::EventAction()
|
|||
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 )
|
||||
{
|
||||
m_additional = additional;
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace Action {
|
|||
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 );
|
||||
|
||||
void onStart() override;
|
||||
|
|
|
@ -22,7 +22,7 @@ Core::Action::EventItemAction::EventItemAction()
|
|||
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 )
|
||||
{
|
||||
m_additional = additional;
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace Action {
|
|||
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 );
|
||||
|
||||
void onStart() override;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,11 +1,10 @@
|
|||
#ifndef _ACTOR_H_
|
||||
#define _ACTOR_H_
|
||||
#ifndef _GAME_OBJECT_H_
|
||||
#define _GAME_OBJECT_H_
|
||||
|
||||
#include <common/Common.h>
|
||||
#include <boost/enable_shared_from_this.hpp>
|
||||
|
||||
#include "Forwards.h"
|
||||
#include "GameObject.h"
|
||||
#include <set>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
|
@ -14,282 +13,70 @@ namespace Core {
|
|||
namespace Entity {
|
||||
|
||||
/*!
|
||||
\class Actor
|
||||
\brief Base class for all actors
|
||||
\class GameObject
|
||||
\brief Base class for all actor/objects
|
||||
|
||||
*/
|
||||
class Actor : public GameObject
|
||||
{
|
||||
public:
|
||||
enum Stance : uint8_t
|
||||
class Actor : public boost::enable_shared_from_this< Actor >
|
||||
{
|
||||
Passive = 0,
|
||||
Active = 1,
|
||||
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 Actor( ObjKind type );
|
||||
virtual ~Actor() {};
|
||||
|
||||
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;
|
||||
|
||||
CharaPtr getAsChara();
|
||||
PlayerPtr getAsPlayer();
|
||||
BattleNpcPtr getAsBattleNpc();
|
||||
EventNpcPtr getAsEventNpc();
|
||||
};
|
||||
|
||||
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< ActorPtr > m_inRangeActors;
|
||||
std::set< PlayerPtr > m_inRangePlayers;
|
||||
|
||||
public:
|
||||
Actor( ObjKind type );
|
||||
|
||||
virtual ~Actor() 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::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;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -26,7 +26,7 @@ extern Core::Data::ExdDataGenerated g_exdDataGen;
|
|||
uint32_t Core::Entity::BattleNpc::m_nextID = 1149241694;
|
||||
|
||||
Core::Entity::BattleNpc::BattleNpc() :
|
||||
Actor( ObjKind::BattleNpc )
|
||||
Chara( ObjKind::BattleNpc )
|
||||
{
|
||||
m_id = 0;
|
||||
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,
|
||||
uint16_t bnpcBaseId, uint32_t type, uint8_t level, uint8_t behaviour,
|
||||
uint32_t mobType ) :
|
||||
Actor( ObjKind::BattleNpc )
|
||||
Chara( ObjKind::BattleNpc )
|
||||
{
|
||||
BattleNpc::m_nextID++;
|
||||
m_id = BattleNpc::m_nextID;
|
||||
|
@ -177,16 +177,16 @@ uint8_t Core::Entity::BattleNpc::getbehavior() const
|
|||
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();
|
||||
hateEntry->m_hateAmount = hateAmount;
|
||||
hateEntry->m_pActor = actor.getAsActor();
|
||||
hateEntry->m_pChara = actor.getAsChara();
|
||||
|
||||
m_hateList.insert( hateEntry );
|
||||
}
|
||||
|
||||
Core::Entity::ActorPtr Core::Entity::BattleNpc::hateListGetHighest()
|
||||
Core::Entity::CharaPtr Core::Entity::BattleNpc::hateListGetHighest()
|
||||
{
|
||||
|
||||
auto it = m_hateList.begin();
|
||||
|
@ -202,7 +202,7 @@ Core::Entity::ActorPtr Core::Entity::BattleNpc::hateListGetHighest()
|
|||
}
|
||||
|
||||
if( entry && maxHate != 0 )
|
||||
return entry->m_pActor;
|
||||
return entry->m_pChara;
|
||||
|
||||
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();
|
||||
|
@ -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 ) )
|
||||
hateListRemove( actor );
|
||||
|
@ -309,8 +309,8 @@ void Core::Entity::BattleNpc::hateListClear()
|
|||
auto it = m_hateList.begin();
|
||||
for( ; it != m_hateList.end(); ++it )
|
||||
{
|
||||
if( isInRangeSet( ( *it )->m_pActor ) )
|
||||
deaggro( *( *it )->m_pActor );
|
||||
if( isInRangeSet( ( *it )->m_pChara ) )
|
||||
deaggro( *( *it )->m_pChara );
|
||||
HateListEntry* tmpListEntry = ( *it );
|
||||
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();
|
||||
for( ; it != m_hateList.end(); ++it )
|
||||
{
|
||||
if( ( *it )->m_pActor->getId() == actor.getId() )
|
||||
if( ( *it )->m_pChara->getId() == actor.getId() )
|
||||
{
|
||||
HateListEntry* pEntry = *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();
|
||||
for( ; it != m_hateList.end(); ++it )
|
||||
{
|
||||
if( ( *it )->m_pActor->getId() == actor.getId() )
|
||||
if( ( *it )->m_pChara->getId() == actor.getId() )
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -359,13 +359,13 @@ uint32_t Core::Entity::BattleNpc::getNameId() const
|
|||
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();
|
||||
for( ; it != m_hateList.end(); ++it )
|
||||
{
|
||||
if( ( *it )->m_pActor->getId() == actor.getId() )
|
||||
if( ( *it )->m_pChara->getId() == actor.getId() )
|
||||
{
|
||||
( *it )->m_hateAmount += hateAmount;
|
||||
return;
|
||||
|
@ -374,7 +374,7 @@ void Core::Entity::BattleNpc::hateListUpdate( Actor& actor, int32_t hateAmount )
|
|||
|
||||
auto hateEntry = new HateListEntry();
|
||||
hateEntry->m_hateAmount = hateAmount;
|
||||
hateEntry->m_pActor = actor.getAsActor();
|
||||
hateEntry->m_pChara = actor.getAsChara();
|
||||
m_hateList.insert( hateEntry );
|
||||
}
|
||||
|
||||
|
@ -396,7 +396,7 @@ void Core::Entity::BattleNpc::onDeath()
|
|||
uint32_t totalHate = 0;
|
||||
for( auto& pHateEntry : m_hateList )
|
||||
{
|
||||
if( pHateEntry->m_pActor->isPlayer() )
|
||||
if( pHateEntry->m_pChara->isPlayer() )
|
||||
{
|
||||
if( pHateEntry->m_hateAmount < minHate )
|
||||
minHate = pHateEntry->m_hateAmount;
|
||||
|
@ -412,9 +412,9 @@ void Core::Entity::BattleNpc::onDeath()
|
|||
{
|
||||
// todo: this is pure retarded
|
||||
// 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 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()
|
||||
srand( static_cast< uint32_t > ( time( nullptr ) ) );
|
||||
|
||||
auto pPlayer = pHateEntry->m_pActor->getAsPlayer();
|
||||
auto pPlayer = pHateEntry->m_pChara->getAsPlayer();
|
||||
pPlayer->gainExp( exp );
|
||||
pPlayer->onMobKill( m_nameId );
|
||||
}
|
||||
|
@ -448,7 +448,7 @@ void Core::Entity::BattleNpc::onDeath()
|
|||
hateListClear();
|
||||
}
|
||||
|
||||
void Core::Entity::BattleNpc::onActionHostile( Actor& source )
|
||||
void Core::Entity::BattleNpc::onActionHostile( Chara& source )
|
||||
{
|
||||
|
||||
if( hateListGetHighest() == nullptr )
|
||||
|
@ -458,7 +458,7 @@ void Core::Entity::BattleNpc::onActionHostile( Actor& source )
|
|||
setOwner( source.getAsPlayer() );
|
||||
}
|
||||
|
||||
Core::Entity::ActorPtr Core::Entity::BattleNpc::getClaimer() const
|
||||
Core::Entity::CharaPtr Core::Entity::BattleNpc::getClaimer() const
|
||||
{
|
||||
return m_pOwner;
|
||||
}
|
||||
|
@ -501,46 +501,46 @@ void Core::Entity::BattleNpc::update( int64_t currTime )
|
|||
|
||||
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,
|
||||
pClosestActor->getPos().x,
|
||||
pClosestActor->getPos().y,
|
||||
pClosestActor->getPos().z );
|
||||
pClosestChara->getPos().x,
|
||||
pClosestChara->getPos().y,
|
||||
pClosestChara->getPos().z );
|
||||
|
||||
//if( distance < 8 && getbehavior() == 2 )
|
||||
// aggro( pClosestActor );
|
||||
// aggro( pClosestChara );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case MODE_COMBAT:
|
||||
{
|
||||
ActorPtr pClosestActor = hateListGetHighest();
|
||||
CharaPtr pClosestChara = hateListGetHighest();
|
||||
|
||||
if( pClosestActor != nullptr && !pClosestActor->isAlive() )
|
||||
if( pClosestChara != nullptr && !pClosestChara->isAlive() )
|
||||
{
|
||||
hateListRemove( *pClosestActor );
|
||||
pClosestActor = hateListGetHighest();
|
||||
hateListRemove( *pClosestChara );
|
||||
pClosestChara = hateListGetHighest();
|
||||
}
|
||||
|
||||
if( pClosestActor != nullptr )
|
||||
if( pClosestChara != nullptr )
|
||||
{
|
||||
distance = Math::Util::distance( getPos().x, getPos().y, getPos().z,
|
||||
pClosestActor->getPos().x,
|
||||
pClosestActor->getPos().y,
|
||||
pClosestActor->getPos().z );
|
||||
pClosestChara->getPos().x,
|
||||
pClosestChara->getPos().y,
|
||||
pClosestChara->getPos().z );
|
||||
|
||||
if( distance > 4 )
|
||||
moveTo( pClosestActor->getPos() );
|
||||
moveTo( pClosestChara->getPos() );
|
||||
else
|
||||
{
|
||||
if( face( pClosestActor->getPos() ) )
|
||||
if( face( pClosestChara->getPos() ) )
|
||||
sendPositionUpdate();
|
||||
// in combat range. ATTACK!
|
||||
autoAttack( pClosestActor );
|
||||
autoAttack( pClosestChara );
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#ifndef _BATTLENPC_H
|
||||
#define _BATTLENPC_H
|
||||
|
||||
#include "Actor.h"
|
||||
#include "Chara.h"
|
||||
|
||||
namespace Core {
|
||||
namespace Entity {
|
||||
|
@ -16,11 +16,11 @@ enum StateMode
|
|||
typedef struct
|
||||
{
|
||||
uint32_t m_hateAmount;
|
||||
ActorPtr m_pActor;
|
||||
CharaPtr m_pChara;
|
||||
} HateListEntry;
|
||||
|
||||
// class for Mobs inheriting from Actor
|
||||
class BattleNpc : public Actor
|
||||
// class for Mobs inheriting from Chara
|
||||
class BattleNpc : public Chara
|
||||
{
|
||||
public:
|
||||
BattleNpc();
|
||||
|
@ -52,12 +52,12 @@ public:
|
|||
|
||||
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 hateListRemove( Actor& actor );
|
||||
void hateListUpdate( Chara& actor, int32_t hateAmount );
|
||||
void hateListRemove( Chara& actor );
|
||||
|
||||
bool hateListHasActor( Actor& actor );
|
||||
bool hateListHasActor( Chara& actor );
|
||||
|
||||
void resetPos();
|
||||
|
||||
|
@ -65,19 +65,19 @@ public:
|
|||
|
||||
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 onDeath() override;
|
||||
|
||||
void onActionHostile( Actor& source ) override;
|
||||
void onActionHostile( Chara& source ) override;
|
||||
|
||||
ActorPtr getClaimer() const;
|
||||
CharaPtr getClaimer() const;
|
||||
|
||||
void sendPositionUpdate();
|
||||
|
||||
|
@ -103,7 +103,7 @@ private:
|
|||
uint32_t m_unk1;
|
||||
uint32_t m_unk2;
|
||||
std::set< HateListEntry* > m_hateList;
|
||||
ActorPtr m_pOwner;
|
||||
CharaPtr m_pOwner;
|
||||
uint32_t m_timeOfDeath;
|
||||
uint32_t m_mobType;
|
||||
|
||||
|
|
974
src/servers/sapphire_zone/Actor/Chara.cpp
Normal file
974
src/servers/sapphire_zone/Actor/Chara.cpp
Normal 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;
|
||||
}
|
295
src/servers/sapphire_zone/Actor/Chara.h
Normal file
295
src/servers/sapphire_zone/Actor/Chara.h
Normal 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
|
|
@ -24,7 +24,7 @@ extern Core::Logger g_log;
|
|||
uint32_t Core::Entity::EventNpc::m_nextID = 1249241694;
|
||||
|
||||
Core::Entity::EventNpc::EventNpc() :
|
||||
Actor( ObjKind::EventNpc )
|
||||
Chara( ObjKind::EventNpc )
|
||||
{
|
||||
m_id = 0;
|
||||
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 ) :
|
||||
Actor( ObjKind::EventNpc )
|
||||
Chara( ObjKind::EventNpc )
|
||||
{
|
||||
EventNpc::m_nextID++;
|
||||
m_id = EventNpc::m_nextID;
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#ifndef _EVENTNPC_H
|
||||
#define _EVENTNPC_H
|
||||
|
||||
#include "Actor.h"
|
||||
#include "Chara.h"
|
||||
|
||||
namespace Core {
|
||||
namespace Entity {
|
||||
|
||||
// class for Mobs inheriting from Actor
|
||||
class EventNpc : public Actor
|
||||
// class for Mobs inheriting from Chara
|
||||
class EventNpc : public Chara
|
||||
{
|
||||
public:
|
||||
EventNpc();
|
||||
|
|
|
@ -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() );
|
||||
}
|
|
@ -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
|
|
@ -2,7 +2,7 @@
|
|||
#include "Zone/InstanceContent.h"
|
||||
|
||||
Core::Entity::InstanceObject::InstanceObject( uint32_t objectId, uint32_t mapLinkId ) :
|
||||
Core::Entity::GameObject( ObjKind::EventObj ),
|
||||
Core::Entity::Actor( ObjKind::EventObj ),
|
||||
m_mapLinkId( mapLinkId ),
|
||||
m_state( 0 )
|
||||
{
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
#ifndef SAPPHIRE_INSTANCEOBJECT_H
|
||||
#define SAPPHIRE_INSTANCEOBJECT_H
|
||||
|
||||
#include "GameObject.h"
|
||||
#include "Actor.h"
|
||||
|
||||
namespace Core
|
||||
{
|
||||
namespace Entity
|
||||
{
|
||||
class InstanceObject : public GameObject
|
||||
class InstanceObject : public Actor
|
||||
{
|
||||
public:
|
||||
InstanceObject( uint32_t objectId, uint32_t mapLinkId );
|
||||
|
|
|
@ -55,7 +55,7 @@ using namespace Core::Network::Packets::Server;
|
|||
|
||||
// player constructor
|
||||
Core::Entity::Player::Player() :
|
||||
Actor( ObjKind::Player ),
|
||||
Chara( ObjKind::Player ),
|
||||
m_lastWrite( 0 ),
|
||||
m_lastPing( 0 ),
|
||||
m_bIsLogin( false ),
|
||||
|
@ -250,7 +250,7 @@ void Core::Entity::Player::calculateStats()
|
|||
}
|
||||
|
||||
|
||||
void Core::Entity::Player::setAutoattack(bool mode)
|
||||
void Core::Entity::Player::setAutoattack( bool mode )
|
||||
{
|
||||
m_bAutoattack = mode;
|
||||
m_lastAttack = Util::getTimeMs();
|
||||
|
@ -829,10 +829,10 @@ void Core::Entity::Player::despawn( Entity::PlayerPtr pTarget )
|
|||
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;
|
||||
auto inRange = getInRangeActors( true );
|
||||
CharaPtr targetActor;
|
||||
auto inRange = getInRangeCharas(true);
|
||||
for( auto actor : inRange )
|
||||
{
|
||||
if( actor->getId() == targetId )
|
||||
|
@ -1000,12 +1000,12 @@ void Core::Entity::Player::update( int64_t currTime )
|
|||
|
||||
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 );
|
||||
|
||||
// @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 )
|
||||
{
|
||||
|
@ -1408,7 +1408,7 @@ uint8_t Core::Entity::Player::getEquipDisplayFlags() const
|
|||
void Core::Entity::Player::mount( uint32_t 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 ); //?
|
||||
|
||||
ZoneChannelPacket< FFXIVIpcMount > mountPacket( getId() );
|
||||
|
@ -1419,7 +1419,7 @@ void Core::Entity::Player::mount( uint32_t id )
|
|||
void Core::Entity::Player::dismount()
|
||||
{
|
||||
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 );
|
||||
m_mount = 0;
|
||||
}
|
||||
|
@ -1429,7 +1429,7 @@ uint8_t Core::Entity::Player::getCurrentMount() const
|
|||
return m_mount;
|
||||
}
|
||||
|
||||
void Core::Entity::Player::autoAttack( ActorPtr pTarget )
|
||||
void Core::Entity::Player::autoAttack( CharaPtr pTarget )
|
||||
{
|
||||
|
||||
auto mainWeap = m_pInventory->getItemAt( Inventory::GearSet0,
|
||||
|
@ -1663,15 +1663,15 @@ void Core::Entity::Player::finishZoning()
|
|||
case ZoneingType::Return:
|
||||
case ZoneingType::ReturnDead:
|
||||
{
|
||||
if( getStatus() == Entity::Actor::ActorStatus::Dead )
|
||||
if( getStatus() == Entity::Chara::ActorStatus::Dead )
|
||||
{
|
||||
resetHp();
|
||||
resetMp();
|
||||
setStatus( Entity::Actor::ActorStatus::Idle );
|
||||
setStatus( Entity::Chara::ActorStatus::Idle );
|
||||
|
||||
sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01, 0x01, 0, 111 ), true );
|
||||
sendToInRangeSet( ActorControlPacket142( getId(), SetStatus,
|
||||
static_cast< uint8_t >( Entity::Actor::ActorStatus::Idle ) ), true );
|
||||
static_cast< uint8_t >( Entity::Chara::ActorStatus::Idle ) ), true );
|
||||
}
|
||||
else
|
||||
sendToInRangeSet( ActorControlPacket143( getId(), ZoneIn, 0x01, 0x00, 0, 111 ), true );
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
#include <common/Common.h>
|
||||
|
||||
#include "Actor.h"
|
||||
#include "Chara.h"
|
||||
#include "Inventory/Inventory.h"
|
||||
#include "Event/EventHandler.h"
|
||||
#include <map>
|
||||
|
@ -33,7 +33,7 @@ struct QueuedZoning
|
|||
* Inheriting from Actor
|
||||
*
|
||||
*/
|
||||
class Player : public Actor
|
||||
class Player : public Chara
|
||||
{
|
||||
public:
|
||||
/*! Contructor */
|
||||
|
@ -42,7 +42,7 @@ public:
|
|||
/*! Destructor */
|
||||
~Player();
|
||||
|
||||
void autoAttack( ActorPtr pTarget ) override;
|
||||
void autoAttack( CharaPtr pTarget ) override;
|
||||
|
||||
// EventHandlers
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -526,7 +526,7 @@ public:
|
|||
|
||||
bool actionHasCastTime( uint32_t actionId );
|
||||
|
||||
Core::Entity::ActorPtr lookupTargetById( uint64_t targetId );
|
||||
Core::Entity::CharaPtr lookupTargetById( uint64_t targetId );
|
||||
|
||||
bool isLogin() const;
|
||||
void setIsLogin( bool bIsLogin );
|
||||
|
|
|
@ -227,7 +227,7 @@ void Core::Entity::Player::eventActionStart( uint32_t eventId,
|
|||
ActionCallback interruptCallback,
|
||||
uint64_t additional )
|
||||
{
|
||||
auto pEventAction = Action::make_EventAction( getAsActor(), eventId, action,
|
||||
auto pEventAction = Action::make_EventAction( getAsChara(), eventId, action,
|
||||
finishCallback, interruptCallback, additional );
|
||||
|
||||
setCurrentAction( pEventAction );
|
||||
|
@ -257,7 +257,7 @@ void Core::Entity::Player::eventItemActionStart( uint32_t eventId,
|
|||
ActionCallback interruptCallback,
|
||||
uint64_t additional )
|
||||
{
|
||||
Action::ActionPtr pEventItemAction = Action::make_EventItemAction( getAsActor(), eventId, action,
|
||||
Action::ActionPtr pEventItemAction = Action::make_EventItemAction( getAsChara(), eventId, action,
|
||||
finishCallback, interruptCallback, additional );
|
||||
|
||||
setCurrentAction( pEventItemAction );
|
||||
|
|
|
@ -34,8 +34,8 @@ namespace Core
|
|||
|
||||
namespace Entity
|
||||
{
|
||||
TYPE_FORWARD( GameObject );
|
||||
TYPE_FORWARD( Actor );
|
||||
TYPE_FORWARD( Chara );
|
||||
TYPE_FORWARD( Player );
|
||||
TYPE_FORWARD( BattleNpc );
|
||||
TYPE_FORWARD( EventNpc );
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <common/Exd/ExdDataGenerated.h>
|
||||
#include <common/Common.h>
|
||||
#include "Actor/Actor.h"
|
||||
#include "Actor/Chara.h"
|
||||
#include "Actor/Player.h"
|
||||
#include "CalcBattle.h"
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define _CALCBATTLE_H
|
||||
|
||||
#include <common/Common.h>
|
||||
#include "Actor/Actor.h"
|
||||
#include "Actor/Chara.h"
|
||||
|
||||
using namespace Core::Entity;
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include <common/Exd/ExdDataGenerated.h>
|
||||
#include <common/Common.h>
|
||||
#include "Actor/Actor.h"
|
||||
#include "Actor/Chara.h"
|
||||
#include "Actor/Player.h"
|
||||
|
||||
#include "CalcStats.h"
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define _CALCSTATS_H
|
||||
|
||||
#include <common/Common.h>
|
||||
#include "Actor/Actor.h"
|
||||
#include "Actor/Chara.h"
|
||||
|
||||
using namespace Core::Entity;
|
||||
|
||||
|
|
|
@ -119,10 +119,10 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in
|
|||
case ClientTrigger::ToggleSeathe: // Toggle sheathe
|
||||
{
|
||||
if ( param11 == 1 )
|
||||
player.setStance( Entity::Actor::Stance::Active );
|
||||
player.setStance( Entity::Chara::Stance::Active );
|
||||
else
|
||||
{
|
||||
player.setStance( Entity::Actor::Stance::Passive );
|
||||
player.setStance( Entity::Chara::Stance::Passive );
|
||||
player.setAutoattack( false );
|
||||
}
|
||||
|
||||
|
@ -135,7 +135,7 @@ void Core::Network::GameConnection::actionHandler( const Packets::GamePacket& in
|
|||
if ( param11 == 1 )
|
||||
{
|
||||
player.setAutoattack( true );
|
||||
player.setStance( Entity::Actor::Stance::Active );
|
||||
player.setStance( Entity::Chara::Stance::Active );
|
||||
}
|
||||
else
|
||||
player.setAutoattack( false );
|
||||
|
|
|
@ -37,7 +37,7 @@ void Core::Network::GameConnection::eventHandlerTalk( const Packets::GamePacket&
|
|||
std::string eventName = "onTalk";
|
||||
std::string objName = Event::getEventName( eventId );
|
||||
|
||||
player.sendDebug( "Actor: " +
|
||||
player.sendDebug( "Chara: " +
|
||||
std::to_string( actorId ) + " -> " +
|
||||
std::to_string( Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ) ) +
|
||||
" \neventId: " +
|
||||
|
@ -72,7 +72,7 @@ void Core::Network::GameConnection::eventHandlerEmote( const Packets::GamePacket
|
|||
std::string eventName = "onEmote";
|
||||
std::string objName = Event::getEventName( eventId );
|
||||
|
||||
player.sendDebug( "Actor: " +
|
||||
player.sendDebug( "Chara: " +
|
||||
std::to_string( actorId ) + " -> " +
|
||||
std::to_string( Event::mapEventActorToRealActor( static_cast< uint32_t >( actorId ) ) ) +
|
||||
" \neventId: " +
|
||||
|
|
|
@ -104,7 +104,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
|
|||
", params: " + std::to_string( param1 ) + ", " +
|
||||
std::to_string( param2 ) + ", " + std::to_string( param3 ) );
|
||||
|
||||
Core::Entity::ActorPtr targetActor;
|
||||
Core::Entity::CharaPtr targetActor;
|
||||
|
||||
|
||||
if( player.getId() == param3 )
|
||||
|
@ -113,7 +113,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
|
|||
}
|
||||
else
|
||||
{
|
||||
auto inRange = player.getInRangeActors();
|
||||
auto inRange = player.getInRangeCharas();
|
||||
for( auto actor : inRange )
|
||||
{
|
||||
if( actor->getId() == param3 )
|
||||
|
@ -138,7 +138,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
|
|||
targetPlayer->setLookAt( CharaLook::Race, param1 );
|
||||
player.sendNotice( "Race for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) );
|
||||
targetPlayer->spawn( targetPlayer );
|
||||
auto inRange = targetPlayer->getInRangeActors();
|
||||
auto inRange = targetPlayer->getInRangeCharas();
|
||||
for( auto actor : inRange )
|
||||
{
|
||||
targetPlayer->despawn( actor->getAsPlayer() );
|
||||
|
@ -151,7 +151,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
|
|||
targetPlayer->setLookAt( CharaLook::Tribe, param1 );
|
||||
player.sendNotice( "Tribe for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) );
|
||||
targetPlayer->spawn( targetPlayer );
|
||||
auto inRange = targetPlayer->getInRangeActors();
|
||||
auto inRange = targetPlayer->getInRangeCharas();
|
||||
for( auto actor : inRange )
|
||||
{
|
||||
targetPlayer->despawn( actor->getAsPlayer() );
|
||||
|
@ -164,7 +164,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
|
|||
targetPlayer->setLookAt( CharaLook::Gender, param1 );
|
||||
player.sendNotice( "Sex for " + targetPlayer->getName() + " was set to " + std::to_string( param1 ) );
|
||||
targetPlayer->spawn( targetPlayer );
|
||||
auto inRange = targetActor->getInRangeActors();
|
||||
auto inRange = targetActor->getInRangeCharas();
|
||||
for( auto actor : inRange )
|
||||
{
|
||||
targetPlayer->despawn( actor->getAsPlayer() );
|
||||
|
@ -439,7 +439,7 @@ void Core::Network::GameConnection::gm1Handler( const Packets::GamePacket& inPac
|
|||
case GmCommand::Jump:
|
||||
{
|
||||
|
||||
auto inRange = player.getInRangeActors();
|
||||
auto inRange = player.getInRangeCharas();
|
||||
|
||||
player.changePosition( targetActor->getPos().x, targetActor->getPos().y, targetActor->getPos().z,
|
||||
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 );
|
||||
|
||||
auto targetSession = g_serverZone.getSession( param1 );
|
||||
Core::Entity::ActorPtr targetActor;
|
||||
Core::Entity::CharaPtr targetActor;
|
||||
|
||||
if( targetSession != nullptr )
|
||||
{
|
||||
|
@ -496,11 +496,11 @@ void Core::Network::GameConnection::gm2Handler( const Packets::GamePacket& inPac
|
|||
{
|
||||
targetPlayer->resetHp();
|
||||
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( 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() );
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ void Core::Network::GameConnection::skillHandler( const Packets::GamePacket& inP
|
|||
}
|
||||
else
|
||||
{
|
||||
Core::Entity::ActorPtr targetActor = player.getAsPlayer();
|
||||
Core::Entity::CharaPtr targetActor = player.getAsPlayer();
|
||||
if( targetId != player.getId() )
|
||||
{
|
||||
targetActor = player.lookupTargetById( targetId );
|
||||
|
|
|
@ -21,14 +21,14 @@ class MoveActorPacket :
|
|||
public ZoneChannelPacket< FFXIVIpcActorMove >
|
||||
{
|
||||
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() )
|
||||
{
|
||||
initialize( actor, unk1, unk2, unk3, unk4 );
|
||||
};
|
||||
|
||||
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() );
|
||||
|
|
|
@ -90,22 +90,22 @@ namespace Server {
|
|||
|
||||
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 )
|
||||
{
|
||||
m_data.displayFlags |= Entity::Actor::DisplayFlags::HideHead;
|
||||
m_data.displayFlags |= Entity::Chara::DisplayFlags::HideHead;
|
||||
}
|
||||
|
||||
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 )
|
||||
{
|
||||
m_data.displayFlags |= Entity::Actor::DisplayFlags::Visor;
|
||||
m_data.displayFlags |= Entity::Chara::DisplayFlags::Visor;
|
||||
}
|
||||
|
||||
m_data.currentMount = player.getCurrentMount();
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#define _UPDATEHPMPTP_H
|
||||
|
||||
#include <common/Network/GamePacketNew.h>
|
||||
#include <Actor/Actor.h>
|
||||
#include <Actor/Chara.h>
|
||||
#include "Forwards.h"
|
||||
|
||||
namespace Core {
|
||||
|
@ -17,14 +17,14 @@ class UpdateHpMpTpPacket :
|
|||
public ZoneChannelPacket< FFXIVIpcUpdateHpMpTp >
|
||||
{
|
||||
public:
|
||||
UpdateHpMpTpPacket( Entity::Actor& actor ) :
|
||||
UpdateHpMpTpPacket( Entity::Chara& actor ) :
|
||||
ZoneChannelPacket< FFXIVIpcUpdateHpMpTp >( actor.getId(), actor.getId() )
|
||||
{
|
||||
initialize( actor );
|
||||
};
|
||||
|
||||
private:
|
||||
void initialize( Entity::Actor& actor )
|
||||
void initialize( Entity::Chara& actor )
|
||||
{
|
||||
m_data.hp = actor.getHp();
|
||||
m_data.mp = actor.getMp();
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
#include <typeinfo>
|
||||
#include <typeindex>
|
||||
|
||||
#include <Actor/Actor.h>
|
||||
#include <Actor/Chara.h>
|
||||
#include <Actor/Player.h>
|
||||
#include <StatusEffect/StatusEffect.h>
|
||||
#include <Zone/InstanceContent.h>
|
||||
|
@ -53,14 +53,14 @@ public:
|
|||
ScriptObject( effectId, typeid( StatusEffectScript ).hash_code() )
|
||||
{ }
|
||||
|
||||
virtual void onTick( Entity::Actor& actor ) { }
|
||||
virtual void onApply( Entity::Actor& actor ) { }
|
||||
virtual void onRemove( Entity::Actor& actor ) { }
|
||||
virtual void onExpire( Entity::Actor& actor ) { }
|
||||
virtual void onPlayerCollision( Entity::Actor& actor, Entity::Actor& actorHit ) { }
|
||||
virtual void onPlayerFinishCast( Entity::Actor& actor ) { }
|
||||
virtual void onPlayerDamaged( Entity::Actor& actor ) { }
|
||||
virtual void onPlayerDeath( Entity::Actor& actor ) { }
|
||||
virtual void onTick( Entity::Chara& actor ) { }
|
||||
virtual void onApply( Entity::Chara& actor ) { }
|
||||
virtual void onRemove( Entity::Chara& actor ) { }
|
||||
virtual void onExpire( Entity::Chara& actor ) { }
|
||||
virtual void onPlayerCollision( Entity::Chara& actor, Entity::Chara& actorHit ) { }
|
||||
virtual void onPlayerFinishCast( Entity::Chara& actor ) { }
|
||||
virtual void onPlayerDamaged( Entity::Chara& actor ) { }
|
||||
virtual void onPlayerDeath( Entity::Chara& actor ) { }
|
||||
};
|
||||
|
||||
|
||||
|
@ -71,9 +71,9 @@ public:
|
|||
ScriptObject( abilityId, typeid( ActionScript ).hash_code() )
|
||||
{ }
|
||||
|
||||
virtual void onStart( Entity::Actor& sourceActor, Entity::Actor& targetActor ) { }
|
||||
virtual void onCastFinish( Entity::Player& player, Entity::Actor& targetActor ) { }
|
||||
virtual void onInterrupt( Entity::Actor& sourceActor/*, Core::Entity::Actor targetActor*/ ) { }
|
||||
virtual void onStart( Entity::Chara& sourceActor, Entity::Chara& targetActor ) { }
|
||||
virtual void onCastFinish( Entity::Player& player, Entity::Chara& targetActor ) { }
|
||||
virtual void onInterrupt( Entity::Chara& sourceActor/*, Core::Entity::Chara targetActor*/ ) { }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -275,7 +275,7 @@ bool Core::Scripting::ScriptManager::onMobKill( Entity::Player& player, uint16_t
|
|||
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 );
|
||||
|
||||
|
@ -284,7 +284,7 @@ bool Core::Scripting::ScriptManager::onCastFinish( Entity::Player& player, Entit
|
|||
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 );
|
||||
|
||||
|
@ -300,30 +300,30 @@ bool Core::Scripting::ScriptManager::onStatusReceive( Entity::ActorPtr pActor, u
|
|||
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() );
|
||||
if( script )
|
||||
{
|
||||
if( pActor->isPlayer() )
|
||||
pActor->getAsPlayer()->sendDebug( "Calling status tick for statusid: " + std::to_string( effect.getId() ) );
|
||||
if( pChara->isPlayer() )
|
||||
pChara->getAsPlayer()->sendDebug( "Calling status tick for statusid: " + std::to_string( effect.getId() ) );
|
||||
|
||||
script->onTick( *pActor );
|
||||
script->onTick( *pChara );
|
||||
return true;
|
||||
}
|
||||
|
||||
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 );
|
||||
if( script )
|
||||
{
|
||||
if( pActor->isPlayer() )
|
||||
pActor->getAsPlayer()->sendDebug( "Calling status timeout for statusid: " + std::to_string( effectId ) );
|
||||
if( pChara->isPlayer() )
|
||||
pChara->getAsPlayer()->sendDebug( "Calling status timeout for statusid: " + std::to_string( effectId ) );
|
||||
|
||||
script->onExpire( *pActor );
|
||||
script->onExpire( *pChara );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -48,11 +48,11 @@ namespace Core
|
|||
|
||||
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 onStatusTick( Entity::ActorPtr pActor, Core::StatusEffect::StatusEffect& effect );
|
||||
bool onStatusTimeOut( Entity::ActorPtr pActor, uint32_t effectId );
|
||||
bool onStatusReceive( Entity::CharaPtr pActor, uint32_t effectId );
|
||||
bool onStatusTick( Entity::CharaPtr pActor, Core::StatusEffect::StatusEffect& effect );
|
||||
bool onStatusTimeOut( Entity::CharaPtr pActor, uint32_t effectId );
|
||||
|
||||
bool onZoneInit( ZonePtr pZone );
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <Script/NativeScriptApi.h>
|
||||
#include <Forwards.h>
|
||||
#include <Actor/Actor.h>
|
||||
#include <Actor/Chara.h>
|
||||
#include <Actor/Player.h>
|
||||
#include <Event/EventHelper.h>
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@ public:
|
|||
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 );
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
#include <boost/algorithm/string.hpp>
|
||||
#include <algorithm>
|
||||
|
||||
#include "Actor/Actor.h"
|
||||
#include "Actor/Chara.h"
|
||||
|
||||
#include "StatusEffect.h"
|
||||
#include "Script/ScriptManager.h"
|
||||
|
@ -20,7 +20,7 @@ using namespace Core::Network::Packets::Server;
|
|||
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 )
|
||||
: m_id( id )
|
||||
, m_sourceActor( sourceActor )
|
||||
|
|
|
@ -14,7 +14,7 @@ namespace StatusEffect
|
|||
class StatusEffect
|
||||
{
|
||||
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 );
|
||||
|
||||
~StatusEffect();
|
||||
|
@ -39,8 +39,8 @@ public:
|
|||
|
||||
private:
|
||||
uint32_t m_id;
|
||||
Entity::ActorPtr m_sourceActor;
|
||||
Entity::ActorPtr m_targetActor;
|
||||
Entity::CharaPtr m_sourceActor;
|
||||
Entity::CharaPtr m_targetActor;
|
||||
uint32_t m_duration;
|
||||
uint64_t m_startTime;
|
||||
uint32_t m_tickRate;
|
||||
|
|
|
@ -1,171 +1,146 @@
|
|||
#include "Cell.h"
|
||||
|
||||
#include "Actor/Actor.h"
|
||||
#include "Actor/Chara.h"
|
||||
#include "Actor/BattleNpc.h"
|
||||
#include "Forwards.h"
|
||||
#include "Zone.h"
|
||||
|
||||
|
||||
// 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
|
||||
namespace Core
|
||||
|
||||
Core::Cell::Cell() :
|
||||
m_bActive( false ),
|
||||
m_bLoaded( false ),
|
||||
m_playerCount( 0 ),
|
||||
m_bUnloadPending( false )
|
||||
{
|
||||
m_bForcedActive = false;
|
||||
}
|
||||
|
||||
Core::Cell::~Cell()
|
||||
{
|
||||
removeCharas();
|
||||
}
|
||||
|
||||
Cell::Cell()
|
||||
: m_bActive(false)
|
||||
, m_bLoaded(false)
|
||||
, m_playerCount(0)
|
||||
, m_bUnloadPending(false)
|
||||
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 );
|
||||
m_pZone = pZone;
|
||||
m_posX = x;
|
||||
m_posY = y;
|
||||
|
||||
m_charas.clear();
|
||||
}
|
||||
|
||||
void Core::Cell::loadCharas( CellCache* pCC )
|
||||
{
|
||||
m_bLoaded = true;
|
||||
assert( pCC );
|
||||
|
||||
for( auto entry : pCC->battleNpcCache )
|
||||
{
|
||||
m_bForcedActive = false;
|
||||
entry->setCurrentZone( m_pZone );
|
||||
m_pZone->pushActor( entry );
|
||||
}
|
||||
}
|
||||
|
||||
Cell::~Cell()
|
||||
void Core::Cell::addChara( Entity::CharaPtr pAct )
|
||||
{
|
||||
if( pAct->isPlayer() )
|
||||
++m_playerCount;
|
||||
|
||||
m_charas.insert(pAct);
|
||||
}
|
||||
|
||||
void Core::Cell::removeChara( Entity::CharaPtr pAct )
|
||||
{
|
||||
if( pAct->isPlayer() )
|
||||
--m_playerCount;
|
||||
|
||||
m_charas.erase(pAct);
|
||||
}
|
||||
|
||||
void Core::Cell::setActivity( bool state )
|
||||
{
|
||||
if( !m_bActive && state )
|
||||
{
|
||||
removeActors();
|
||||
}
|
||||
// Move all objects to active set.
|
||||
//for( auto itr = m_charas.begin(); itr != m_charas.end(); ++itr )
|
||||
//{
|
||||
|
||||
void Cell::init(uint32_t x, uint32_t y, ZonePtr pZone)
|
||||
{
|
||||
//Console->outDebOnly("[Region:%X] Initializing a new cell[%i/%i]", pRegion->getId(), x, y );
|
||||
m_pZone = pZone;
|
||||
m_posX = x;
|
||||
m_posY = y;
|
||||
//}
|
||||
|
||||
m_actors.clear();
|
||||
}
|
||||
|
||||
void Cell::loadActors(CellCache* pCC)
|
||||
{
|
||||
|
||||
m_bLoaded = true;
|
||||
assert(pCC);
|
||||
|
||||
for( auto entry : pCC->battleNpcCache )
|
||||
{
|
||||
|
||||
entry->setCurrentZone( m_pZone );
|
||||
m_pZone->pushActor( entry );
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void Cell::addActor(Entity::ActorPtr pAct)
|
||||
{
|
||||
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_actors.insert(pAct);
|
||||
}
|
||||
|
||||
void Cell::removeActor(Entity::ActorPtr pAct)
|
||||
{
|
||||
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_actors.erase(pAct);
|
||||
}
|
||||
|
||||
void Cell::setActivity(bool state)
|
||||
{
|
||||
if(!m_bActive && state)
|
||||
{
|
||||
// Move all objects to active set.
|
||||
for(auto itr = m_actors.begin(); itr != m_actors.end(); ++itr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
if(m_bUnloadPending)
|
||||
{
|
||||
cancelPendingUnload();
|
||||
}
|
||||
|
||||
}
|
||||
else if(m_bActive && !state)
|
||||
{
|
||||
// Move all objects from active set.
|
||||
for(auto itr = m_actors.begin(); itr != m_actors.end(); ++itr)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
m_bActive = state;
|
||||
if( m_bUnloadPending )
|
||||
cancelPendingUnload();
|
||||
|
||||
}
|
||||
void Cell::removeActors()
|
||||
else if( m_bActive && !state )
|
||||
{
|
||||
//uint32_t ltime = getMSTime();
|
||||
// Move all objects from active set.
|
||||
//for(auto itr = m_charas.begin(); itr != m_charas.end(); ++itr)
|
||||
//{
|
||||
|
||||
m_actors.clear();
|
||||
//}
|
||||
|
||||
//This time it's simpler! We just remove everything
|
||||
Entity::ActorPtr pAct; //do this outside the loop!
|
||||
for(auto itr = m_actors.begin(); itr != m_actors.end();)
|
||||
{
|
||||
pAct = (*itr);
|
||||
itr++;
|
||||
|
||||
if(!pAct)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(m_bUnloadPending)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_playerCount = 0;
|
||||
m_bLoaded = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Cell::queueUnloadPending()
|
||||
{
|
||||
if(m_bUnloadPending)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
m_bUnloadPending = true;
|
||||
|
||||
}
|
||||
|
||||
void Cell::cancelPendingUnload()
|
||||
{
|
||||
|
||||
if(!m_bUnloadPending)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void Cell::unload()
|
||||
{
|
||||
|
||||
assert(m_bUnloadPending);
|
||||
if(m_bActive)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
removeActors();
|
||||
m_bUnloadPending = false;
|
||||
}
|
||||
m_bActive = state;
|
||||
|
||||
}
|
||||
|
||||
void Core::Cell::removeCharas()
|
||||
{
|
||||
//uint32_t ltime = getMSTime();
|
||||
|
||||
m_charas.clear();
|
||||
|
||||
//This time it's simpler! We just remove everything
|
||||
Entity::ActorPtr pAct; //do this outside the loop!
|
||||
for( auto itr = m_charas.begin(); itr != m_charas.end(); )
|
||||
{
|
||||
pAct = (*itr);
|
||||
itr++;
|
||||
|
||||
if(!pAct)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if(m_bUnloadPending)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
m_playerCount = 0;
|
||||
m_bLoaded = false;
|
||||
}
|
||||
|
||||
void Core::Cell::queueUnloadPending()
|
||||
{
|
||||
if( m_bUnloadPending )
|
||||
return;
|
||||
|
||||
m_bUnloadPending = true;
|
||||
|
||||
}
|
||||
|
||||
void Core::Cell::cancelPendingUnload()
|
||||
{
|
||||
if( !m_bUnloadPending )
|
||||
return;
|
||||
}
|
||||
|
||||
void Core::Cell::unload()
|
||||
{
|
||||
|
||||
assert( m_bUnloadPending );
|
||||
if( m_bActive )
|
||||
return;
|
||||
|
||||
removeCharas();
|
||||
m_bUnloadPending = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ namespace Core {
|
|||
std::vector< Entity::BattleNpcPtr > battleNpcCache;
|
||||
};
|
||||
|
||||
typedef std::set< Entity::ActorPtr > ActorSet;
|
||||
typedef std::set< Entity::CharaPtr > CharaSet;
|
||||
|
||||
class Cell
|
||||
{
|
||||
|
@ -25,9 +25,9 @@ namespace Core {
|
|||
bool m_bForcedActive;
|
||||
uint16_t m_posX;
|
||||
uint16_t m_posY;
|
||||
ActorSet m_actors;
|
||||
CharaSet m_charas;
|
||||
bool m_bActive;
|
||||
bool m_bLoaded;
|
||||
bool m_bLoaded;
|
||||
bool m_bUnloadPending;
|
||||
|
||||
uint16_t m_playerCount;
|
||||
|
@ -37,17 +37,17 @@ namespace Core {
|
|||
Cell();
|
||||
~Cell();
|
||||
|
||||
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
|
||||
|
@ -55,21 +55,21 @@ namespace Core {
|
|||
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);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "TerritoryMgr.h"
|
||||
|
||||
#include "Session.h"
|
||||
#include "Actor/Actor.h"
|
||||
#include "Actor/Chara.h"
|
||||
#include "Actor/Player.h"
|
||||
#include "Actor/BattleNpc.h"
|
||||
#include "Actor/EventNpc.h"
|
||||
|
@ -268,10 +268,10 @@ Core::Common::Weather Core::Zone::getNextWeather()
|
|||
return Common::Weather::FairSkies;
|
||||
}
|
||||
|
||||
void Core::Zone::pushActor( Entity::ActorPtr pActor )
|
||||
void Core::Zone::pushActor( Entity::CharaPtr pChara )
|
||||
{
|
||||
float mx = pActor->getPos().x;
|
||||
float my = pActor->getPos().z;
|
||||
float mx = pChara->getPos().x;
|
||||
float my = pChara->getPos().z;
|
||||
uint32_t cx = getPosX( mx );
|
||||
uint32_t cy = getPosY( my );
|
||||
|
||||
|
@ -282,12 +282,12 @@ void Core::Zone::pushActor( Entity::ActorPtr pActor )
|
|||
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 cellY = getPosY( pActor->getPos().z );
|
||||
uint32_t cellX = getPosX( pChara->getPos().x );
|
||||
uint32_t cellY = getPosY( pChara->getPos().z );
|
||||
|
||||
uint32_t endX = cellX <= _sizeX ? cellX + 1 : ( _sizeX - 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 );
|
||||
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() );
|
||||
if( pSession )
|
||||
|
@ -315,17 +315,17 @@ void Core::Zone::pushActor( Entity::ActorPtr pActor )
|
|||
m_playerMap[pPlayer->getId()] = pPlayer;
|
||||
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;
|
||||
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;
|
||||
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 );
|
||||
pActor->m_pCell = nullptr;
|
||||
pChara->m_pCell->removeChara(pChara);
|
||||
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( pActor->getPos().x <= _maxX && pActor->getPos().x >= _minX &&
|
||||
pActor->getPos().z <= _maxY && pActor->getPos().z >= _minY )
|
||||
if( pChara->getPos().x <= _maxX && pChara->getPos().x >= _minX &&
|
||||
pChara->getPos().z <= _maxY && pChara->getPos().z >= _minY )
|
||||
{
|
||||
uint32_t x = getPosX( pActor->getPos().x );
|
||||
uint32_t y = getPosY( pActor->getPos().z );
|
||||
uint32_t x = getPosX( pChara->getPos().x );
|
||||
uint32_t y = getPosY( pChara->getPos().z );
|
||||
updateCellActivity( x, y, 3 );
|
||||
}
|
||||
m_playerMap.erase( pActor->getId() );
|
||||
m_playerMap.erase( pChara->getId() );
|
||||
|
||||
onLeaveTerritory( *pActor->getAsPlayer() );
|
||||
onLeaveTerritory( *pChara->getAsPlayer() );
|
||||
|
||||
}
|
||||
else if( pActor->isBattleNpc() )
|
||||
m_BattleNpcMap.erase( pActor->getId() );
|
||||
else if( pChara->isBattleNpc() )
|
||||
m_BattleNpcMap.erase( pChara->getId() );
|
||||
|
||||
// remove from lists of other actors
|
||||
pActor->removeFromInRange();
|
||||
pActor->clearInRangeSet();
|
||||
pChara->removeFromInRange();
|
||||
pChara->clearInRangeSet();
|
||||
|
||||
}
|
||||
|
||||
|
@ -601,7 +601,7 @@ void Core::Zone::updateCellActivity( uint32_t x, uint32_t y, int32_t radius )
|
|||
|
||||
CellCache * pCC = getCellCacheAndCreate( posX, posY );
|
||||
if( pCC )
|
||||
pCell->loadActors( pCC );
|
||||
pCell->loadCharas(pCC);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -615,7 +615,7 @@ void Core::Zone::updateCellActivity( uint32_t x, uint32_t y, int32_t radius )
|
|||
{
|
||||
CellCache * pCC = getCellCacheAndCreate( posX, posY );
|
||||
if( pCC )
|
||||
pCell->loadActors( pCC );
|
||||
pCell->loadCharas(pCC);
|
||||
}
|
||||
}
|
||||
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() )
|
||||
|
@ -652,9 +652,9 @@ void Core::Zone::updateActorPosition( Entity::Actor &actor )
|
|||
{
|
||||
|
||||
if( pOldCell )
|
||||
pOldCell->removeActor( actor.getAsActor() );
|
||||
pOldCell->removeChara(actor.getAsChara());
|
||||
|
||||
pCell->addActor( actor.getAsActor() );
|
||||
pCell->addChara(actor.getAsChara());
|
||||
actor.m_pCell = pCell;
|
||||
|
||||
// if player we need to update cell activity
|
||||
|
@ -686,13 +686,13 @@ void Core::Zone::updateActorPosition( Entity::Actor &actor )
|
|||
{
|
||||
pCell = getCell( posX, posY );
|
||||
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 )
|
||||
return;
|
||||
|
@ -701,33 +701,33 @@ void Core::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell )
|
|||
if( g_territoryMgr.isPrivateTerritory( getTerritoryId() ) )
|
||||
return;
|
||||
|
||||
Entity::ActorPtr pCurAct;
|
||||
Entity::CharaPtr pCurAct;
|
||||
|
||||
auto iter = pCell->m_actors.begin();
|
||||
auto iter = pCell->m_charas.begin();
|
||||
|
||||
float fRange = 70.0f;
|
||||
int32_t count = 0;
|
||||
while( iter != pCell->m_actors.end() )
|
||||
while( iter != pCell->m_charas.end() )
|
||||
{
|
||||
pCurAct = *iter;
|
||||
++iter;
|
||||
|
||||
if( !pCurAct || pCurAct == pActor )
|
||||
if( !pCurAct || pCurAct == pChara )
|
||||
continue;
|
||||
|
||||
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 isInRangeSet = pActor->isInRangeSet( pCurAct );
|
||||
bool isInRangeSet = pChara->isInRangeSet( pCurAct );
|
||||
|
||||
// Add if we are not ourself and range == 0 or distance is withing range.
|
||||
if( isInRange && !isInRangeSet )
|
||||
{
|
||||
|
||||
if( pActor->isPlayer() )
|
||||
if( pChara->isPlayer() )
|
||||
{
|
||||
auto pOwnPlayer = pActor->getAsPlayer();
|
||||
auto pOwnPlayer = pChara->getAsPlayer();
|
||||
|
||||
if( !pOwnPlayer->isLoadingComplete() )
|
||||
continue;
|
||||
|
@ -737,8 +737,8 @@ void Core::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell )
|
|||
if( count > 12 )
|
||||
break;
|
||||
|
||||
pActor->addInRangeActor( pCurAct );
|
||||
pCurAct->addInRangeActor( pActor );
|
||||
pChara->addInRangeChara( pCurAct );
|
||||
pCurAct->addInRangeChara( pChara );
|
||||
// spawn the actor for the player
|
||||
pCurAct->spawn( pOwnPlayer );
|
||||
|
||||
|
@ -748,34 +748,34 @@ void Core::Zone::updateInRangeSet( Entity::ActorPtr pActor, Cell* pCell )
|
|||
if( !pPlayer->isLoadingComplete() )
|
||||
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();
|
||||
if( pPlayer->isLoadingComplete() )
|
||||
{
|
||||
pActor->spawn( pPlayer );
|
||||
pCurAct->addInRangeActor( pActor );
|
||||
pActor->addInRangeActor( pCurAct );
|
||||
pChara->spawn( pPlayer );
|
||||
pCurAct->addInRangeChara( pChara );
|
||||
pChara->addInRangeChara( pCurAct );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pActor->addInRangeActor( pCurAct );
|
||||
pCurAct->addInRangeActor( pActor );
|
||||
pChara->addInRangeChara( pCurAct );
|
||||
pCurAct->addInRangeChara( pChara );
|
||||
}
|
||||
}
|
||||
else if( !isInRange && isInRangeSet )
|
||||
{
|
||||
pCurAct->removeInRangeActor( *pActor );
|
||||
pCurAct->removeInRangeChara( *pChara );
|
||||
|
||||
if( pActor->getCurrentZone() != pCurAct->getCurrentZone() )
|
||||
if( pChara->getCurrentZone() != pCurAct->getCurrentZone() )
|
||||
continue;
|
||||
|
||||
pActor->removeInRangeActor( *pCurAct );
|
||||
pChara->removeInRangeChara( *pCurAct );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,17 +86,17 @@ public:
|
|||
|
||||
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 );
|
||||
|
||||
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 );
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue