Files
Leviathan/Library/Internal/include/mmo/ArObject.h
T
2026-06-01 12:46:52 +02:00

198 lines
5.0 KiB
C++

#pragma once
#include "ArMove.h"
#include "ArOption.h"
#include "ArSchedulerObject.h"
#include "../logging/FileLog.h"
// 위치를 가지고 있는 모든 오브젝트의 근간
// 기본적인 위치와 타입, uid 를 가지고 있다.
struct ArObject : public ArSchedulerObject
{
enum ObjectType { STATIC_OBJECT, MOVABLE_OBJECT, CLIENT_OBJECT };
ObjectType GetObjectType() const { return static_cast< ObjectType >( m_nArObjectType ); }
int region_index; // Region 의 컨테이너중 몇번째에 위치하는지 기록. (사용시 빨리 접근하기 위해)
ArObject( ObjectType t = STATIC_OBJECT )
: m_nArObjectType( static_cast< unsigned char >( t ) )
, pTag( NULL )
, region_index( -1 )
, bIsNearClient( false )
, bIsDeleted( false )
, layer( 0 )
, bIsInWorld( false )
{
prev_rx = prev_ry = -1;
bIsRegionChanging = false;
nListIndex = nActiveIndex = 0;
pRegion = NULL;
lastStepTime = 0;
}
inline AR_UNIT GetX() const { return mv.GetX(); };
inline AR_UNIT GetY() const { return mv.GetY(); };
inline AR_UNIT GetZ() const { return mv.GetZ(); };
inline unsigned char GetLayer() const { return layer; };
void AddNoise( int r1, int r2, int v )
{
AR_UNIT prev_x = mv.x;
AR_UNIT prev_y = mv.y;
unsigned prev_rx = mv.GetRX();
unsigned prev_ry = mv.GetRY();
mv.x += ( r1%v - v/2 );
mv.y += ( r2%v - v/2 );
if( mv.GetRX() != prev_rx ) mv.x = prev_x;
if( mv.GetRY() != prev_ry ) mv.y = prev_y;
}
inline const ArPosition & GetPos() const { return mv.GetPos(); };
inline const ArMoveVector & GetMv() const { return mv; };
inline unsigned GetRX() const { return mv.GetRX(); };
inline unsigned GetRY() const { return mv.GetRY(); };
ArPosition GetCurrentPosition( AR_TIME t ) const
{
if( !IsMoving() ) return GetPos();
ArMoveVector _mv = mv;
_mv.Step( t );
return _mv.GetPos();
}
/*
virtual void SetCurrentXYZ( AR_UNIT x, AR_UNIT y, AR_UNIT z )
{
mv.SetCurrentXYZ( x, y, z );
}
void SetCurrentLayer( unsigned char layer )
{
mv.SetCurrentLayer( layer );
}*/
inline void SetTag( void *p ) { pTag = p; };
inline void* GetTag() { return pTag; };
inline bool IsMoving() const { return ( mv.IsMoving() && IsInWorld() ); };
inline bool IsMoving( AR_TIME t ) const { return mv.IsMoving( t ); };
inline bool IsInWorld() const { return bIsInWorld; };
// 시간 t 만큼 이동한다.
bool Step( AR_TIME t )
{
bool bRtn = mv.Step( t );
if( bRtn )
{
mv.SetCurrentPos( mv.GetTargetPos() );
}
lastStepTime = t;
return bRtn;
}
// 이동 세팅
void SetMove( const ArPosition & _to, unsigned char _speed, AR_TIME _start_time = 0 )
{
mv.SetMove( _to, _speed, _start_time, GetArTime() );
lastStepTime = mv.GetStartTime();
}
void SetMultipleMove( const std::vector< ArPosition > & _to, unsigned char _speed, AR_TIME _start_time = 0 )
{
mv.SetMultipleMove( _to, _speed, _start_time, GetArTime() );
lastStepTime = mv.GetStartTime();
}
// 이동 세팅
void SetMove( AR_UNIT _x, AR_UNIT _y, unsigned char _speed, AR_TIME _start_time = 0 )
{
mv.SetMove( ArPosition( _x, _y ), _speed, _start_time, GetArTime() );
lastStepTime = mv.GetStartTime();
}
void StopMove()
{
mv.StopMove();
}
float GetFace() const { return mv.GetFace(); }
void SetFace( float face ) { mv.SetFace( face ); }
AR_UNIT GetTX() const { return mv.GetTargetPos().x; }
AR_UNIT GetTY() const { return mv.GetTargetPos().y; }
AR_UNIT GetTZ() const { return mv.GetTargetPos().z; }
const std::vector< ArMoveVector::MOVE_INFO > & GetTargetPosList() const { return mv.GetTargetPosList(); }
const ArPosition & GetTargetPos() const { return mv.GetTargetPos(); }
unsigned char GetSpeed() const { return mv.GetSpeed(); }
AR_TIME GetStartTime() const { return mv.GetStartTime(); }
void SetDirection( const ArPosition & _to ) { mv.SetDirection( _to ); }
bool IsLookingRegion( unsigned rx, unsigned ry ) const
{
if( IsVisibleRegion( GetRX(), GetRY(), rx, ry ) ) return true;
if( IsVisibleRegion( prev_rx, prev_ry, rx, ry ) ) return true;
return false;
}
void SetCurrentXY( AR_UNIT x, AR_UNIT y )
{
if( prev_rx > -1 )
{
prev_rx = mv.GetRX();
prev_ry = mv.GetRY();
}
mv.SetCurrentXY( x, y );
}
void SetCurrentZ( AR_UNIT z ) { mv.z = z; }
void SetCurrentLayer( unsigned char _layer ) { layer = _layer; }
volatile bool bIsInWorld;
volatile bool bIsNearClient; // 근처에 플레이어가 있을수 있다는 의미. false 라면 명백히 플레이어 없음.
int prev_rx, prev_ry;
bool bIsRegionChanging;
AR_TIME lastStepTime;
struct ArRegion * pRegion;
size_t nListIndex;
size_t nActiveIndex;
protected:
virtual ~ArObject()
{
assert( !bIsDeleted );
bIsDeleted = true;
}
unsigned char m_nArObjectType;
void * pTag;
ArMoveVector mv;
unsigned char layer;
bool bIsDeleted;
};
// 오브젝트에 뭔가를 하기 위한 기본 Functor. 템플릿이 아니라 순수가상함수임.
struct ArObjectFunctor
{
virtual void operator()( ArObject *pObj ) const = 0;
};