Files
2026-06-01 12:46:52 +02:00

338 lines
7.0 KiB
C++

#pragma once
#include <cmath>
#include <cstdio>
#include <vector>
#include "ArOption.h"
#include "ArTime.h"
#include "../dump/XException.h"
// 위치정보 타입 정의
struct ArPosition
{
ArPosition()
{
x = y = z = 0;
face = 0;
}
ArPosition( AR_UNIT _x, AR_UNIT _y, AR_UNIT _z = 0 )
{
x = _x;
y = _y;
z = _z;
face = 0;
}
unsigned GetRX() const { return ::GetRegionX( x ); };
unsigned GetRY() const { return ::GetRegionY( y ); };
AR_UNIT GetDistance( const ArPosition & pos ) const
{
AR_UNIT _x = pos.x - x;
AR_UNIT _y = pos.y - y;
return static_cast< AR_UNIT >( sqrt( (float) _x*_x + _y*_y ) );
}
/// 2010.10.13 - prodongi
AR_UNIT GetDistanceSqr( const ArPosition & pos ) const
{
AR_UNIT _x = pos.x - x;
AR_UNIT _y = pos.y - y;
return (_x*_x + _y*_y);
}
bool operator==( const ArPosition & rh ) const
{
if( (int)x != (int)rh.x ) return false;
if( (int)y != (int)rh.y ) return false;
if( (int)z != (int)rh.z ) return false;
return true;
}
AR_UNIT GetX() const { return x; }
AR_UNIT GetY() const { return y; }
AR_UNIT GetZ() const { return z; }
AR_UNIT x, y, z;
float face;
};
// 이동정보 타입 정의
struct ArMoveVector : ArPosition
{
struct MOVE_INFO
{
MOVE_INFO( ArPosition _end, AR_TIME _end_time ) : end( _end ), end_time( _end_time ) {}
ArPosition end;
AR_TIME end_time;
};
ArMoveVector()
{
bWithZMoving = bIsMoving = false;
speed = 0;
proc_time = start_time = 0;
bHasDirectionChanged = false;
}
// 시간 갭 t 를 준다. 이동이 끝나면 true, 여전히 이동해야 하면 false 리턴
bool Step( AR_TIME current_time )
{
if( proc_time >= current_time ) return false;
if( !bIsMoving ) return false;
for( std::vector< MOVE_INFO >::iterator it = ends.begin(); it != ends.end(); )
{
if( current_time >= (*it).end_time )
{
x = (*it).end.x;
y = (*it).end.y;
z = (*it).end.z;
proc_time = (*it).end_time;
it = ends.erase( it );
if( it != ends.end() )
{
SetDirection( (*it).end );
}
continue;
}
AR_TIME time_gap = current_time - proc_time;
float v = ( time_gap / (float)((*it).end_time - proc_time) );
x += ( (*it).end.x - x ) * v;
y += ( (*it).end.y - y ) * v;
if( bWithZMoving ) z += ( (*it).end.z - z ) * v;
break;
}
proc_time = current_time;
if( ends.size() < 1 || (ends.back().end.x == x && ends.back().end.y == y && ends.back().end.z == z) )
{
bIsMoving = false;
ends.clear();
return true;
}
return false;
};
void StopMove()
{
ends.clear();
bIsMoving = false;
}
void SetMultipleMove( const std::vector< ArPosition > & _to, unsigned char _speed, AR_TIME _start_time, AR_TIME current_time )
{
ends.clear();
if( _to.size() < 1 ) return;
speed = _speed;
if( !_start_time ) start_time = GetArTime();
else start_time = _start_time;
proc_time = start_time;
SetDirection( _to.front() );
AR_UNIT before_x, before_y;
AR_TIME _cur_start_time, _end_time;
_cur_start_time = start_time;
before_x = x;
before_y = y;
for( std::vector< ArPosition >::const_iterator it = _to.begin(); it != _to.end(); ++it )
{
AR_UNIT X = ( it->x - before_x );
AR_UNIT Y = ( it->y - before_y );
before_x = it->x;
before_y = it->y;
AR_UNIT length = AR_UNIT( sqrt( (double)X*X + Y*Y ) );
_cur_start_time = _end_time = _cur_start_time + AR_TIME( length / ((float)speed/SPEED_UNIT) );
ends.push_back( MOVE_INFO( (*it), _end_time ) );
}
bIsMoving = true;
}
void SetMove( const ArPosition & _to, unsigned char _speed, AR_TIME _start_time, AR_TIME current_time )
{
ends.clear();
speed = _speed;
if( !_start_time ) start_time = GetArTime();
else start_time = _start_time;
proc_time = start_time;
AR_UNIT X = ( _to.x - x );
AR_UNIT Y = ( _to.y - y );
SetDirection( _to );
AR_UNIT length = AR_UNIT( sqrt( (double)X*X + Y*Y ) );
AR_TIME end_time = start_time + AR_TIME( length / ((float)speed/SPEED_UNIT) );
ends.push_back( MOVE_INFO( _to, end_time ) );
bIsMoving = true;
}
void SetKnockBack( const ArPosition & _to, unsigned char _speed, AR_TIME _start_time, AR_TIME current_time )
{
ends.clear();
speed = _speed;
if( !_start_time ) start_time = GetArTime();
else start_time = _start_time;
proc_time = start_time;
AR_UNIT X = ( _to.x - x );
AR_UNIT Y = ( _to.y - y );
AR_UNIT length = AR_UNIT( sqrt( (double)X*X + Y*Y ) );
AR_TIME end_time = start_time + AR_TIME( length / ((float)speed/SPEED_UNIT) );
ends.push_back( MOVE_INFO( _to, end_time ) );
bIsMoving = true;
}
AR_UNIT GetTX() const
{
if( ends.size() )
return ends.back().end.x;
return x;
}
AR_UNIT GetTY() const
{
if( ends.size() )
return ends.back().end.y;
return y;
}
AR_UNIT GetTZ() const
{
if( ends.size() )
return ends.back().end.z;
return z;
}
AR_UNIT GetX() const { return x; };
AR_UNIT GetY() const { return y; };
AR_UNIT GetZ() const { return z; };
float GetFace() const { return face; }; //라디안~
void SetFace( float _face ) { face = _face; }
short GetDegree() const { return short( 180/3.141592 * GetFace() ); };
void SetDirection( const ArPosition & _to )
{
AR_UNIT X = ( _to.x - x );
AR_UNIT Y = ( _to.y - y );
// sonador 1.8.6 덩치큰 몬스터 공격 방향 오류 수정
if( X == 0.0f && Y == 0.0f )
return;
float face1 = ::atan2( Y, X );
bHasDirectionChanged = true;
direction = _to;
SetFace( face1 );
}
void SetCurrentXY( AR_UNIT _x, AR_UNIT _y ) { x = _x; y = _y; };
void SetCurrentZ( AR_UNIT _z ) { z = _z; };
void SetCurrentXYZ( AR_UNIT _x, AR_UNIT _y, AR_UNIT _z ) { x = _x; y = _y; z = _z; };
const ArPosition & GetPos() const { return *this; };
const ArPosition & GetTargetPos() const
{
if( ends.size() )
return ends.back().end;
return *this;
}
DWORD GetTargetPosTime()
{
if( ends.size() )
return ends.back().end_time;
return 0;
}
DWORD GetProcTime()
{
return proc_time;
}
const std::vector< ArMoveVector::MOVE_INFO > & GetTargetPosList() const
{
return ends;
}
bool IsMoving() const { return bIsMoving; };
bool IsMoving( AR_TIME t ) const { return bIsMoving ? ( ends.size() ? ends.back().end_time > t : false ) : false; };
void SetMoving( bool bMoving ) { bIsMoving = bMoving; }
bool HasDirectionChanged() { return bHasDirectionChanged; };
const ArPosition & GetDirection() { bHasDirectionChanged = false; return direction; };
void SetCurrentPos( const ArPosition & pos ) { x = pos.x; y = pos.y; z = pos.z; face = pos.face; };
AR_TIME GetStartTime() const { return start_time; };
unsigned char GetSpeed() const { return speed; };
size_t GetWayPointCount() const { return ends.size(); };
void setSpeed(unsigned char _speed) { speed = _speed; }
private:
bool bIsMoving;
bool bWithZMoving;
unsigned char speed;
AR_TIME start_time; // 시작시간
AR_TIME proc_time; // 마지막으로 step 밟은 시간
std::vector< MOVE_INFO > ends;
bool bHasDirectionChanged;
ArPosition direction;
};