2024-12-27 23:19:08 +00:00
using CodeStage.AntiCheat.ObscuredTypes ;
2025-01-13 02:40:17 +00:00
using System ;
2025-01-02 17:53:08 +00:00
using System.Collections ;
2024-12-15 01:39:39 +00:00
using UnityEngine ;
using UnityEngine.AI ;
using UnityEngine.ResourceManagement.AsyncOperations ;
2025-01-13 02:40:17 +00:00
using Random = UnityEngine . Random ;
2024-12-15 01:39:39 +00:00
public class PCActor : MyActor
{
2025-08-09 13:10:17 +00:00
public Transform [ ] tfs_weapon ;
2024-12-15 01:39:39 +00:00
2025-02-18 05:59:11 +00:00
bool isUI ;
2024-12-15 01:39:39 +00:00
float t_RecoverHPTime = 10f , t_RecoverMPTime = 10f , t_autoskill = 0.5f ;
float t_HP = 0f , t_MP = 0f ;
ObscuredFloat [ ] arr_magicCoolTime = new ObscuredFloat [ ] { 0f , 0f , 0f , 0f , 0f , 0f } ;
ObscuredFloat [ ] arr_magicMaxCoolTime = new ObscuredFloat [ ] { 0f , 0f , 0f , 0f , 0f , 0f } ;
SkillListTableData [ ] arr_magicData = new SkillListTableData [ 6 ] ;
SkillCard [ ] arr_PCSkillCard ;
2025-08-09 13:10:17 +00:00
public int JoystickStatus = 0 ; // 0 조이스틱 x, 1 조이스틱 + run 애님, 2 조이스틱만
2024-12-15 01:39:39 +00:00
ObscuredFloat m_AvoidCoolTime ;
protected ClassConfigTableData m_ClassData ;
2026-09-06 23:24:25 +00:00
// ── PD #762 (2026-09-06) 공격 모션 전진 이동 ───────────────────────────────
// 원래 Actor.Move(float) 는 에디터 로그만 남기는 빈 스텁이었고, 클립의 루트 전진
// (Sword&Shield_Attack1~3 = +0.78 / +1.73 / +1.62 m 실측)은 Animator.applyRootMotion = 0
// 때문에 전부 버려져 "모션만 크고 위치는 제자리" 였다.
// 여기서 클립이 넘겨 준 거리를 WL.Combat.AttackStepDriver 로 넘겨 NavMeshAgent 로 밀어 준다.
// 설정 에셋(WLCombatMotionSettings)이 없거나 스위치를 끄면 즉시 예전 동작으로 돌아간다(C8).
public override void Move ( float b )
{
base . Move ( b ) ;
if ( b < = 0f | | IsStop | | IsDead ( ) | | IsCC ( ) ) return ;
WL . Combat . AttackRootMotion . Ensure ( this ) ; // PD #789 (모델 교체 등으로 빠졌을 때 재부착)
WL . Combat . AttackStepDriver . Begin ( this , b ) ;
}
/// <summary>
/// 전진을 계속해도 되는 상태인가. AttackStepDriver 가 매 프레임 묻는다.
/// IsStop 이 Actor 의 protected 라 밖에서 못 읽으므로 여기서 한 번에 판정한다.
/// </summary>
public bool WL_CanAttackStep ( )
{
2026-10-18 15:09:05 +00:00
// WL #888 — IsStop 대신 「조이스틱 조종 중(1)」만 막는다: 섬 진입(원본 MainToFarm)이 IsStop 을 켠 채 두어
// 조이스틱을 한 번 쓰기 전까지 자동 전투의 공격 · 방패 치기 전진이 0 이었다(2026-10-17 실측 apply 0).
return JoystickStatus ! = 1 & & ! IsDead ( ) & & ! IsCC ( ) & & Get_CurAnim ( ) > = eAnim . Attack ;
2026-09-06 23:24:25 +00:00
}
2026-10-18 15:09:05 +00:00
/// <summary>WL #893 — 지금 직업의 공격 가능 거리(= ClassConfig f_AttackRange · Change_Class 가 갱신 · MyActor.Get_AttackReach 와 같은 출처). 흰색 사거리 원이 읽는다.</summary>
public float WL_AttackRange { get { return m_NavStopDistance ; } }
2026-09-06 23:24:25 +00:00
// ── PD #787 (2026-09-06) 대쉬 후 공격 ─────────────────────────────────────
// WL.Combat.DashDriver 가 Actor 의 protected 멤버(IsStop · m_Stat · StopMove_Imm ·
// Play_Run · Play_Attack)에 접근할 수 없어, 필요한 최소 동작만 여기서 공개한다.
// 값·스위치의 SOT 는 WLCombatMotionSettings 에셋이다(C45).
/// <summary>지금 대쉬해도 되는 상태인가. 조이스틱 입력이 있으면 플레이어 조작이 우선이라 막는다.</summary>
public bool WL_CanDash ( )
{
return ! IsStop & & ! IsDead ( ) & & ! IsCC ( ) & & JoystickStatus = = 0 & & Get_CurAnim ( ) < eAnim . Attack ;
}
/// <summary>NavMesh 경로 이동을 끊는다(대쉬는 NavMeshAgent.Move 로 직접 민다 — 두 이동이 싸우지 않게).</summary>
public void WL_StopNavMove ( ) { StopMove_Imm ( false ) ; }
/// <summary>대쉬 도착 즉시 공격(대기 없음). 공격 속도는 기존 자동 교전과 같은 값을 쓴다.</summary>
public void WL_PlayAttackNow ( ) { Play_Attack ( 0 , ( float ) m_Stat . Get_Stat ( eStat . FinalAttackSpeed ) ) ; }
/// <summary>대쉬로 못 붙었을 때 기존 달리기 추적으로 돌려준다.</summary>
public void WL_PlayRunNow ( ) { Play_Run ( ) ; }
2026-10-18 15:09:05 +00:00
/// <summary>WL #900 — i 칸 스킬을 원본 자동 시전(Update :98-105)과 같은 규칙(쿨 · 자동 간격 · 사거리 · CC)으로 지금 쓴다. 성공하면 true(대쉬 도착 즉시 시전).</summary>
public bool WL_TryAutoSkillNow ( int i , bool ignoreAutoGap = false )
{
if ( arr_magicData = = null | | i < 0 | | i > = arr_magicData . Length ) return false ;
var d = arr_magicData [ i ] ;
if ( DSUtil . CheckNull ( d ) | | d . e_SkillType = = eSkillType . Passive | | arr_magicCoolTime [ i ] > 0f | | ( ! ignoreAutoGap & & t_autoskill > 0f ) ) return false ;
if ( IsStop | | ! m_Auto | | IsDead ( ) | | IsCC ( ) | | CurAnim > = eAnim . Skill | | ! isTarget ) return false ;
if ( Vector3 . Distance ( Get_position ( ) , m_Target . Get_position ( ) ) > d . f_SkillRange ) return false ;
if ( ! Use_Skill ( d , m_Auto , i ) ) return false ;
arr_magicCoolTime [ i ] = arr_magicMaxCoolTime [ i ] ;
t_autoskill = Random . Range ( 2f , 3f ) ;
return true ;
}
2025-02-11 00:15:02 +00:00
protected override void OnDestroy ( )
{
base . OnDestroy ( ) ;
2025-02-23 03:53:51 +00:00
if ( ! m_Enemy & & ! isUI )
{
MyValue . MyPC = null ;
2025-03-12 05:13:36 +00:00
if ( ! DSUtil . CheckNull ( MyValue . m_RealCamera ) )
2025-03-23 00:23:25 +00:00
MyValue . m_RealCamera . Set_Target ( null ) ;
2025-02-23 03:53:51 +00:00
}
2025-02-11 00:15:02 +00:00
}
2024-12-15 01:39:39 +00:00
protected override void Update ( )
{
if ( ! DSUtil . CheckNull ( arr_PCSkillCard ) & & arr_PCSkillCard . Length > 0 )
{
for ( int i = 0 ; i < arr_magicCoolTime . Length ; i + + )
{
if ( DSUtil . CheckNull ( arr_magicData [ i ] ) | | arr_magicData [ i ] . e_SkillType = = eSkillType . Passive ) continue ;
arr_magicCoolTime [ i ] - = Time . deltaTime ;
if ( arr_magicCoolTime [ i ] < = 0f ) arr_magicCoolTime [ i ] = 0f ;
arr_magicCoolTime [ i ] . RandomizeCryptoKey ( ) ;
if ( ! IsEnemy ( ) )
arr_PCSkillCard [ i ] . Set_CoolTime ( arr_magicCoolTime [ i ] , arr_magicMaxCoolTime [ i ] , i ) ;
2025-07-21 07:50:32 +00:00
if ( ! IsStop & & m_Auto & & ! IsDead ( ) & & ! DSUtil . CheckNull ( arr_magicData [ i ] ) & & arr_magicCoolTime [ i ] < = 0f & & t_autoskill < = 0f & & ! IsCC ( ) & & CurAnim < eAnim . Skill & &
2025-02-08 22:22:31 +00:00
isTarget & & Vector3 . Distance ( Get_position ( ) , m_Target . Get_position ( ) ) < = arr_magicData [ i ] . f_SkillRange )
2024-12-15 01:39:39 +00:00
{
if ( Use_Skill ( arr_magicData [ i ] , m_Auto , i ) )
{
arr_magicCoolTime [ i ] = arr_magicMaxCoolTime [ i ] ;
t_autoskill = Random . Range ( 2f , 3f ) ;
}
}
}
t_autoskill - = Time . deltaTime ;
}
t_HP + = Time . deltaTime ;
if ( t_HP > = t_RecoverHPTime )
{
t_HP = 0f ;
if ( ! DSUtil . CheckNull ( m_Stat ) )
{
var hpper = ( float ) ( m_Stat . Get_Stat ( eStat . HP ) / m_Stat . Get_Stat ( eStat . MaxHP ) ) ;
if ( hpper < = m_Stat . Get_Stat ( eStat . HeroBuffHP ) )
m_Stat . Set_Stat ( true , eStat . HP , m_Stat . Get_Stat ( eStat . FinalHPRegen ) + m_Stat . Get_Stat ( eStat . HP_REGEN ) * m_Stat . Get_Stat ( eStat . HeroBuff_HP_REGEN_Multiplier ) ) ;
else
m_Stat . Set_Stat ( true , eStat . HP , m_Stat . Get_Stat ( eStat . FinalHPRegen ) ) ;
}
}
t_MP + = Time . deltaTime ;
if ( t_MP > = t_RecoverMPTime + ( dic_ccData . ContainsKey ( eCC . MPRecoverTime ) & & dic_ccData [ eCC . MPRecoverTime ] . CCTime > 0 ? dic_ccData [ eCC . MPRecoverTime ] . CCDmg : 0 ) )
{
t_MP = 0f ;
if ( ! DSUtil . CheckNull ( m_Stat ) )
m_Stat . Set_Stat ( true , eStat . MP , m_Stat . Get_Stat ( eStat . FinalMPRegen ) ) ;
}
if ( m_AvoidCoolTime > 0f )
{
m_AvoidCoolTime - = Time . deltaTime ;
m_AvoidCoolTime . RandomizeCryptoKey ( ) ;
2025-01-14 05:12:32 +00:00
if ( ! DSUtil . CheckNull ( NewGameUI . Ins ) ) NewGameUI . Ins . m_BattleUI . Set_Avoid ( m_AvoidCoolTime ) ;
2024-12-15 01:39:39 +00:00
}
Update_Move ( ) ;
2025-01-13 23:43:30 +00:00
if ( JoystickStatus > 0 | | IsStop | | IsDead ( ) ) return ;
2024-12-15 01:39:39 +00:00
base . Update ( ) ;
2025-05-07 21:37:46 +00:00
// 2023. 02. 19. ?뺤씤?? ?ы깉李얜뒗 濡쒖쭅(?먮옒???ㅽ뀒?댁????덉뿀?붾뜲, 留덈???湲곗뼲?쇰줈 諛붽뺨????濡쒖쭅 ?꾩슂?놁뼱吏?
2024-12-15 01:39:39 +00:00
//if (m_Target == null && m_AutoTarget && MobInfo.Ins.m_PortalMgr != null && MobInfo.Ins.m_PortalMgr.go_portal.activeInHierarchy && m_NavMeshAgent.stoppingDistance > 0f)
//{
// Set_AutoBraking(false);
// Set_Path(MobInfo.Ins.m_PortalMgr.go_portal.transform.position);
//}
}
public override void Set ( bool isEnemy , Actor owner , ServerData sdata , int _id , bool _isstop , bool _ui = false )
{
2025-01-26 18:16:16 +00:00
m_Role = eRole . PC ;
2025-01-14 05:12:32 +00:00
if ( DSUtil . CheckNull ( arr_PCSkillCard ) & & ! DSUtil . CheckNull ( NewGameUI . Ins ) )
arr_PCSkillCard = NewGameUI . Ins . m_BattleUI . skillCards ;
2024-12-15 01:39:39 +00:00
if ( ! DSUtil . CheckNull ( arr_PCSkillCard ) )
2025-05-07 21:37:46 +00:00
{ // ?ㅽ궗 ?ㅼ젙
2024-12-15 01:39:39 +00:00
for ( int i = 0 ; i < arr_PCSkillCard . Length ; i + + )
{
var skillData = table_skilllist . Ins . Get_Data_orNull ( sdata . Get_EquipSkillID ( i ) ) ;
arr_PCSkillCard [ i ] . Set ( skillData ) ;
arr_PCSkillCard [ i ] . Set_CardType ( eUICardType . Use ) ;
dic_MagicData . Add ( i , new UseMagicInfo { m_uiIndex = i , m_SkillTableData = skillData , } ) ;
}
}
2024-12-23 00:36:04 +00:00
2026-10-18 15:09:05 +00:00
if ( ! isEnemy & & ! _ui & & sdata ! = null & & ReferenceEquals ( sdata , ServerInfo . Ins . m_ServerData ) ) _id = WL . Combat . Weapon . WLWeaponClassApplier . ResolveSpawnClass ( _id ) ; // WL #851 — 내 PC 는 처음부터 장착 무기의 직업으로(씬 전환 때 무기 교체가 보이지 않게)
2024-12-15 01:39:39 +00:00
base . Set ( isEnemy , owner , sdata , _id , _isstop , _ui ) ;
2025-04-02 04:15:38 +00:00
Change_Class ( table_classconfig . Ins . Get_Data_orNull ( _id ) , _ui ) ;
2024-12-15 01:39:39 +00:00
2026-09-06 23:24:25 +00:00
// #768 — 플레이어의 이동 차단(충돌) 범위. 값은 설정 에셋에서 읽는다(C45 · 프리팹 46개 개별 편집 금지).
WL . Settings . WLCollisionTuning . ApplyPC ( m_NavMeshAgent ) ;
WL . Combat . AttackRootMotion . Ensure ( this ) ; // PD #789 공격 클립 루트모션 재현
2024-12-15 01:39:39 +00:00
isSurviveTime = false ;
}
2025-02-18 05:59:11 +00:00
public void Set_UIPC ( ) { isUI = true ; }
2024-12-15 01:39:39 +00:00
public override void ReSet ( )
{
base . ReSet ( ) ;
Set_Stat ( true ) ;
2025-05-07 21:37:46 +00:00
// ?뚯뒪???ㅽ꺈
2025-02-21 04:46:10 +00:00
//m_Stat.Set_Stat(true, eStat.CRI, 1f);
//m_Stat.Set_Stat(true, eStat.M_CRI, 1f);
2025-02-21 04:45:42 +00:00
//////////////
2024-12-15 01:39:39 +00:00
t_autoskill = Random . Range ( 2f , 3f ) ;
m_Auto = m_ServerData . Get_Common ( eCommon . Auto ) = = 1 ;
for ( int i = 0 ; i < arr_magicCoolTime . Length ; i + + )
arr_magicCoolTime [ i ] = 0f ;
for ( int i = 0 ; i < arr_magicData . Length ; i + + )
arr_magicData [ i ] = table_skilllist . Ins . Get_Data_orNull ( m_ServerData . Get_EquipSkillID ( i ) ) ;
for ( int i = 0 ; i < arr_magicMaxCoolTime . Length ; i + + )
arr_magicMaxCoolTime [ i ] = arr_magicData [ i ] ! = null ? arr_magicData [ i ] . Get_CoolTime ( m_Stat . Get_Stat ( eStat . COOLTIME_Multiplier ) ) : 0f ;
t_HP = t_MP = 0f ;
m_bImmortal = m_bCanDodge = false ;
if ( ! m_Enemy )
{
MyValue . MyPC = this ;
2025-08-09 13:10:17 +00:00
//// 카메라 위치 잡기
2024-12-15 01:39:39 +00:00
//var curStageData = InGameInfo.Ins.Get_CurStageData();
//var viewcam = LoadMapMgr.Ins.Get_ViewCamera("ViewCamera");
//var maincam = Camera.main;
//if (InGameInfo.Ins.IsGameMode(eGameMode.Lobby) && viewcam != null)
//{
// InGameTouchInfo.Ins.m_RealCamera.enabled = false;
// maincam.fieldOfView = viewcam.fieldOfView;
// maincam.backgroundColor = viewcam.backgroundColor;
// maincam.transform.position = viewcam.transform.position;
// maincam.transform.rotation = viewcam.transform.rotation;
//}
#if UNITY_EDITOR
2026-10-19 16:48:59 +00:00
if ( WL . SkillTest . WLTestScene . Active | |
2024-12-15 01:39:39 +00:00
UnityEngine . SceneManagement . SceneManager . GetActiveScene ( ) . name = = "Settings" )
return ;
#endif
LoadMapMgr . Ins . Get_PortalPos ( MyValue . MyChoiceMapData , Set_Warp ) ;
2025-01-25 21:04:01 +00:00
var dgData = MyValue . MyChoiceMapData . Get_DungeonMapData_orNull ( ) ;
2025-02-04 00:25:38 +00:00
if ( ! DSUtil . CheckNull ( dgData ) )
2025-01-25 21:04:01 +00:00
{
2025-02-04 00:25:38 +00:00
if ( dgData . e_DungeonType = = eDungeon . d2_Maze )
LoadMapMgr . Ins . Set_MazeMap ( MyValue . MyChoiceMapData . n_PortalIndex ) ;
if ( dgData . e_DungeonType = = eDungeon . d2_Maze | | dgData . e_DungeonType = = eDungeon . d4_Wave )
LoadMapMgr . Ins . Set_MazeNextPortal ( MyValue . MyChoiceMapData . n_PortalIndex , false ) ;
2025-01-25 21:04:01 +00:00
}
2024-12-15 01:39:39 +00:00
}
else
2025-05-07 21:37:46 +00:00
LoadMapMgr . Ins . Get_PortalPos ( MyValue . MyChoiceMapData , Set_Warp ) ; // TODO ?뺤씤??: PvP ??寃쎌슦 ???꾩튂 ?↔린
2024-12-15 01:39:39 +00:00
}
2025-02-13 04:40:04 +00:00
public override void On_Regen ( bool reincarnation = false , float healrate = 1f )
2024-12-15 01:39:39 +00:00
{
2025-02-13 04:40:04 +00:00
base . On_Regen ( reincarnation , healrate ) ;
2024-12-15 01:39:39 +00:00
Del_Target ( true ) ;
Del_Magic ( ) ;
Play_Idle ( ) ;
ActorInfo . Ins . All_Stop ( false ) ;
2025-08-09 13:10:17 +00:00
OptionInfo . Ins . Set_PCMove ( this , true ) ;
JoystickStatus = 0 ;
2024-12-15 01:39:39 +00:00
}
protected override bool IsAvoidCoolTime ( ) { return m_AvoidCoolTime > 0f ; }
protected override void Set_AvoidCoolTime ( ) { m_AvoidCoolTime = table_GlobalValue . Ins . Get_Int ( "f_AvoidCoolTime" ) ; }
2025-03-07 06:50:46 +00:00
public void StartCam ( Action < Vector3 > actGetPos )
2024-12-15 01:39:39 +00:00
{
Camera . main . fieldOfView = 60f ;
LoadMapMgr . Ins . Get_PortalPos ( MyValue . MyChoiceMapData , portalpos = >
{
2025-03-09 23:46:04 +00:00
var mzd = LoadMapMgr . Ins . Get_MapZoneData ( MyValue . MyChoiceMapData ) ;
2026-10-18 15:09:05 +00:00
// WL #845 (2026-10-12) — 섬(WL 카메라 리그)에서는 MainCamera 에 RealCamera 가 없어 null → 예외 팝업. 원본 카메라가 없으면 연출만 건너뛴다.
if ( MyValue . m_RealCamera ! = null & & mzd ! = null ) MyValue . m_RealCamera . Set_Target ( transform , mzd . CamRot_Portal ) ;
2025-03-07 06:50:46 +00:00
actGetPos ? . Invoke ( portalpos ) ;
2025-01-27 02:05:25 +00:00
} ) ;
}
float Get_RealCamRotAround ( Vector3 portalpos )
{
2025-03-09 23:46:04 +00:00
//Vector3 targetPosition = portalpos;
2025-05-07 21:37:46 +00:00
//Vector3 cameraPosition = portalpos - Vector3.forward; // ?꾩옱 移대찓?쇱쓽 ?꾩튂
2024-12-15 01:39:39 +00:00
2025-03-09 23:46:04 +00:00
//Vector3 relativePosition = targetPosition - cameraPosition;
//return Mathf.Atan2(relativePosition.x, relativePosition.z) * Mathf.Rad2Deg;
return 0f ;
2024-12-15 01:39:39 +00:00
}
public override void Get_Damage ( DamageInfo _dinfo )
{
2025-05-07 21:37:46 +00:00
//_dinfo.Damage = 1; // ?뚯뒪??: 留덈? ??二쎄쾶
2026-09-08 17:12:33 +00:00
WL . Combat . Survival . Survival . TakeDamage ( this , _dinfo , base . Get_Damage ) ; // WL #813i 무적 해제 게이트(원본 = base.Get_Damage(_dinfo) · SO off 면 그대로 base 호출)
2024-12-15 01:39:39 +00:00
if ( ! IsEnemy ( ) & & _dinfo . Damage > = Get_MaxHP ( ) * 0.5d & & ! isSurviveTime )
StartCoroutine ( Co_Survive ( 5f ) ) ;
}
bool isSurviveTime = false ;
IEnumerator Co_Survive ( float _time )
{
isSurviveTime = true ;
yield return new WaitForSeconds ( _time ) ;
2025-05-07 21:37:46 +00:00
if ( ! IsDead ( ) ) ServerInfo . Ins . m_ServerData . Add_Item ( new ItemData ( eItem . Title , 55 , 1 ) ) ; // 移?샇 : 吏???몄썡??蹂댁씤
2024-12-15 01:39:39 +00:00
isSurviveTime = false ;
}
public override void Set_MagicCoolTime ( float _time , int _index )
{
arr_magicCoolTime [ _index ] = _time ;
arr_magicCoolTime [ _index ] . RandomizeCryptoKey ( ) ;
}
public override void Set_SkillCoolTime ( bool add , int skillid , float rate )
{
for ( int i = 0 ; i < arr_magicData . Length ; i + + )
{
if ( arr_magicData [ i ] . n_SkillID = = skillid )
{
if ( add )
arr_magicCoolTime [ i ] + = arr_magicMaxCoolTime [ i ] * rate ;
else
arr_magicCoolTime [ i ] - = arr_magicMaxCoolTime [ i ] * rate ;
break ;
}
}
}
protected override bool Check_MagicCoolTime ( int _index ) { return arr_magicCoolTime [ _index ] < = 0f ; }
public void Init_UI ( Transform _parent )
{
DSUtil . Set_Transform_withParent ( transform , _parent ) ;
transform . localEulerAngles = Vector3 . up * 180f ;
DSUtil . ChangeLayersRecursively ( transform , "UI" ) ;
}
public override void BossRaidCard_AddDmg ( double _dmg )
{
}
public override void BossRaidCard_HP ( )
{
}
2025-01-02 02:40:44 +00:00
public void Set_Obj ( )
{
string animControllerPath ;
if ( InGameInfo . Ins . IsGameMode ( eGameMode . Lobby ) )
{
transform . localScale = Vector3 . one ;
animControllerPath = "Assets/Res_Addr/Animations/pcanim_lobby.controller" ;
}
else
{
transform . localScale = m_ClassData . f_Scale * Vector3 . one ;
animControllerPath = m_ClassData . s_AnimationController ;
}
AddrResourceMgr . Ins . LoadObject < RuntimeAnimatorController > ( animControllerPath , handle = >
{
m_animation . runtimeAnimatorController = handle . Result ;
} ) ;
if ( ! InGameInfo . Ins . IsGameMode ( eGameMode . Lobby ) )
Change_Weapon ( ) ;
}
public void Change_Weapon ( )
2024-12-15 01:39:39 +00:00
{
for ( int i = 0 ; i < tfs_weapon . Length ; i + + )
{
if ( tfs_weapon [ i ] . childCount > 0 )
{
for ( int j = 0 ; j < tfs_weapon [ i ] . childCount ; j + + )
Destroy ( tfs_weapon [ i ] . GetChild ( j ) . gameObject ) ;
}
}
2025-01-02 02:40:44 +00:00
var wData = table_equipitemlist . Ins . Get_Data_orNull ( m_ServerData . Get_EqiupmentEquip ( eItem . WeaponCostume ) > 0 ?
m_ServerData . Get_EqiupmentEquip ( eItem . WeaponCostume ) : m_ServerData . Get_EqiupmentEquip ( eItem . Weapon ) ) ;
m_AttackType = DSUtil . CheckNull ( wData ) ? eAttackType . Physics : wData . e_EquipAttribute ;
2024-12-15 01:39:39 +00:00
2025-01-02 02:40:44 +00:00
for ( int i = 0 ; i < 2 ; i + + )
{
var prefab = i = = 0 ? m_ClassData . s_WeaponLHPrefab : m_ClassData . s_WeaponRHPrefab ;
2025-05-07 21:37:46 +00:00
var index = i = = 0 ? m_ClassData . n_WeaponLHIndex : m_ClassData . n_WeaponRHIndex ;
2025-01-02 02:40:44 +00:00
if ( ! string . IsNullOrEmpty ( prefab ) )
2024-12-15 01:39:39 +00:00
{
2025-01-02 02:40:44 +00:00
var fullpath = $"Assets/Res_Addr/Weapon/{prefab}.prefab" ;
2025-05-07 21:37:46 +00:00
Make_Weapon ( fullpath , tfs_weapon [ index ] , Vector3 . zero , Vector3 . one ) ;
2024-12-15 01:39:39 +00:00
}
}
}
2025-01-02 17:08:46 +00:00
void Make_Weapon ( string fullpath , Transform tfparent , Vector3 localpos , Vector3 scale , bool ui = false )
2024-12-15 01:39:39 +00:00
{
AddrResourceMgr . Ins . LoadObject < GameObject > ( fullpath , handle = >
{
if ( handle . IsDone & & handle . Status = = AsyncOperationStatus . Succeeded )
{
var w = DSUtil . Get_Clone ( handle . Result ) ;
AddrResourceMgr . Ins . Set_AddressableReleaseSelf ( w ) ;
DSUtil . Set_Transform_withParent ( w . transform , tfparent , localpos , scale ) ;
if ( ui ) DSUtil . ChangeLayersRecursively ( w . transform , "UI" ) ;
}
} ) ;
}
2025-04-02 04:15:38 +00:00
public void Change_Class ( ClassConfigTableData classdata , bool _ui )
{
2025-04-02 23:29:27 +00:00
m_ID = classdata . n_ClassID ;
2025-04-02 04:15:38 +00:00
m_ClassData = classdata ;
m_NavStopDistance = m_ClassData . f_AttackRange ;
Set_Obj ( ) ;
if ( ! _ui )
{
ReSet ( ) ;
Set_MoveSpeed ( true , m_Stat . Get_Stat ( eStat . FinalMoveSpeed ) ) ;
}
f_FindEnemyRange = table_GlobalValue . Ins . Get_Float ( "f_PC_FindEnemyRange" ) + ( float ) m_Stat . Get_Stat ( eStat . AttackRange_Up ) ;
}
2024-12-15 01:39:39 +00:00
protected override void Set_Script ( )
{
CameraShake . Ins . VibrateForTime ( 0.1f ) ;
}
float move_dist = 0f ;
public override void Run_byJoystick ( Vector3 _pos )
{
2026-10-18 15:09:05 +00:00
if ( WL . Combat . Weapon . WLSkillCancel . BlockMove ( this ) ) return ; // WL #908 점프 스킬 중 · 이동 키를 누른 채 쓴 스킬의 발동 전 = 이동 입력 무시(Resources/WL/WLSkillCancel.json)
2024-12-15 01:39:39 +00:00
if ( m_bCanDodge )
{
if ( ! IsDead ( ) & & CurAnim ! = eAnim . Dodge )
{
transform . LookAt ( transform . position + _pos ) ;
Play_Dodge ( ) ;
}
}
else
{
//if (IsDead() || CurAnim >= eAnim.Skill1 || IsCC())
2025-02-11 00:15:02 +00:00
if ( CurAnim = = eAnim . Dodge | | IsDead ( ) | | IsCC ( ) )
2024-12-15 01:39:39 +00:00
return ;
2025-01-13 23:43:30 +00:00
if ( JoystickStatus ! = 2 )
Play_RunAnim ( ) ;
2024-12-15 01:39:39 +00:00
Del_Magic ( ) ;
Del_Target ( ) ;
transform . LookAt ( Get_position ( ) + _pos ) ;
if ( m_NavMeshAgent . isOnNavMesh )
{
m_NavMeshAgent . ResetPath ( ) ;
m_NavMeshAgent . stoppingDistance = 0f ;
var before = Get_position ( ) ;
m_NavMeshAgent . speed = m_NavSpeed ;
var mov = Get_MoveSpeed ( ) * Time . deltaTime * _pos ;
m_NavMeshAgent . Move ( mov ) ;
var after = Get_position ( ) ;
move_dist + = Vector3 . Distance ( before , after ) ;
if ( move_dist > = 1f )
{
move_dist - = 1f ;
2025-05-07 21:37:46 +00:00
m_ServerData . Add_TitleCondition ( 74 , 75 ) ; // 移?샇 : 諛쒕줈 嫄룸뒗, 諛쒕줈 ?곕뒗
2024-12-15 01:39:39 +00:00
}
}
}
}
public override void Set_AutoBraking ( bool _active )
{
2026-10-18 15:09:05 +00:00
if ( WL . Combat . Weapon . WLSkillCancel . DeferBrake ( this , _active ) ) return ; // WL #908 이동 입력을 무시하는 동안의 누름 · 뗌은 스킬이 풀릴 때 적용
2025-02-11 00:15:02 +00:00
if ( CurAnim = = eAnim . Dodge | | IsDead ( ) | | IsCC ( ) ) return ;
2024-12-15 01:39:39 +00:00
if ( _active )
{
2026-10-18 15:09:05 +00:00
if ( WL . Combat . Weapon . WLSkillFollow . DeferBrake ( this ) ) return ; // WL #885 회전하며 이동 스킬(조이스틱 상태 2) 중 손을 떼도 회전 동작 유지 — 스킬 끝에 다시 부른다
2024-12-15 01:39:39 +00:00
IsStop = false ;
Play_Idle ( ) ;
m_NavMeshAgent . stoppingDistance = m_NavStopDistance ;
m_NavMeshAgent . angularSpeed = 300f ;
}
else
{
IsStop = true ;
Del_Target ( ) ;
m_NavMeshAgent . ResetPath ( ) ;
m_NavMeshAgent . stoppingDistance = 0f ;
}
}
2025-01-13 23:43:30 +00:00
public override void Set_JoystickStatus ( int status )
{
2025-05-03 23:06:28 +00:00
if ( IsMainPC ( ) )
{
if ( JoystickStatus = = 2 & & status < 3 ) return ;
JoystickStatus = status = = 3 ? 0 : status ;
}
2025-01-13 23:43:30 +00:00
}
2024-12-15 01:39:39 +00:00
public bool Check_Path ( Vector3 pos )
{
if ( ! IsCC ( ) )
{
NavMeshPath path = new NavMeshPath ( ) ;
if ( m_NavMeshAgent . isOnNavMesh & & m_NavMeshAgent . CalculatePath ( pos , path ) )
return path . status = = NavMeshPathStatus . PathComplete ;
}
return false ;
}
protected override void Set_Die ( )
{
base . Set_Die ( ) ;
ActorInfo . Ins . All_Stop ( true ) ;
2025-03-17 00:08:46 +00:00
//NewGameUI.Ins.m_GuideQuestUI.Add_GuideQuest(ePurpose.DieOrQuit);
2025-02-02 05:19:34 +00:00
DungeonInfo . Ins . Sub_WaveLife ( ) ;
2025-03-04 23:42:24 +00:00
MonsterSimpleInfo . Ins . Set_DelLockTarget ( true ) ;
2026-09-08 17:12:33 +00:00
WL . Combat . Survival . DeathFlow . OnPCDied ( this ) ; // WL #813i 사망 연출 → 부활 요청 → 존 시작점 On_Regen(SO off 면 즉시 반환)
2024-12-15 01:39:39 +00:00
}
2025-01-13 02:40:17 +00:00
protected override IEnumerator Co_ScaleControl ( bool returntoOriginalScale , float targetscale , Action actComplete = null )
{
if ( returntoOriginalScale ) targetscale = m_ClassData . f_Scale ;
Vector3 target = Vector3 . one * targetscale ;
float t = 0f ;
while ( t < 1f )
{
yield return null ;
t + = Time . deltaTime ;
transform . localScale = Vector3 . Lerp ( transform . localScale , target , t ) ;
}
transform . localScale = Vector3 . one * targetscale ;
actComplete ? . Invoke ( ) ;
}
2025-01-15 22:32:07 +00:00
protected override void Weapon_OnOff ( bool active )
{
for ( int i = 0 ; i < tfs_weapon . Length ; i + + )
{
if ( tfs_weapon [ i ] . childCount > 0 )
{
for ( int j = 0 ; j < tfs_weapon [ i ] . childCount ; j + + )
tfs_weapon [ i ] . GetChild ( j ) . gameObject . SetActive ( active ) ;
}
}
}
2025-05-01 21:41:01 +00:00
public override void Play_Attack ( int _attack , float _as , Action actsuccess = null )
{
base . Play_Attack ( _attack , _as , ( ) = >
{
2025-06-20 22:23:07 +00:00
// 애니메이션 Event ShowEffect 로 변경 (확장성 및 공격 속도 고려)
//if (!string.IsNullOrEmpty(m_ClassData.s_SlashPrefab))
// Set_Coroutine(() =>
// {
// InGameInfo.Ins.Show_Effect(m_ClassData.s_SlashPrefab, Get_position(), transform.eulerAngles);
// }, m_ClassData.f_SlashStartDelay);
2025-05-01 21:41:01 +00:00
} ) ;
}
2024-12-15 01:39:39 +00:00
}