|  |  |  | extends CharacterBody3D | 
					
						
							|  |  |  | class_name Character | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @onready var collision = (%Collision) | 
					
						
							|  |  |  | @onready var status = (%Status as Status) | 
					
						
							|  |  |  | @onready var view = (%View as View) | 
					
						
							|  |  |  | @onready var buff = (%Buff as Buff) | 
					
						
							|  |  |  | @onready var skill = (%Skill as Skill) | 
					
						
							|  |  |  | @onready var battle = (%Battle as Battle) | 
					
						
							|  |  |  | @onready var effect = (%Effect as Effect) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func init(id:int,cfg:CharacterCfg,team:Enum.ETeam): | 
					
						
							|  |  |  | 	status.id = id | 
					
						
							|  |  |  | 	status.team = team | 
					
						
							|  |  |  | 	status.cfg = cfg | 
					
						
							|  |  |  | 	var half_height = Setting.pixel_size * cfg.sprite_harf_height | 
					
						
							|  |  |  | 	var height = half_height * 2 | 
					
						
							|  |  |  | 	var width = Setting.pixel_size * cfg.sprite_width | 
					
						
							|  |  |  | 	var body_scale = Vector3(width,height,width) | 
					
						
							|  |  |  | 	collision.position = Vector3(0,half_height,0) | 
					
						
							|  |  |  | 	collision.scale = body_scale | 
					
						
							|  |  |  | 	status.basic_offset = Vector3(0,half_height,0) | 
					
						
							|  |  |  | 	status.ui_offset = Vector3(0,height*1.1,0) | 
					
						
							|  |  |  | 	status.ui_center_offset = Vector3(0,half_height,0) | 
					
						
							|  |  |  | 	status.radius = width | 
					
						
							|  |  |  | 	status.height = height | 
					
						
							|  |  |  | 	view.init(cfg.sprite_frames) | 
					
						
							|  |  |  | 	skill.init() | 
					
						
							|  |  |  | 	effect.init(cfg.type,body_scale) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | func init_after(): | 
					
						
							|  |  |  | 	var cfg = status.cfg as CharacterCfg | 
					
						
							|  |  |  | 	set_status("hp_max",cfg.hp_max) | 
					
						
							|  |  |  | 	set_status("hp",cfg.hp_max) | 
					
						
							|  |  |  | 	set_status("shield_max",cfg.shield.shield_max) | 
					
						
							|  |  |  | 	set_status("shield",cfg.shield.shield_max) | 
					
						
							|  |  |  | 	set_status("stun_max",cfg.stun.stun_max) | 
					
						
							|  |  |  | 	set_status("stun",0) | 
					
						
							|  |  |  | 	set_status("mp_max",cfg.mp.mp_max) | 
					
						
							|  |  |  | 	set_status("mp",0) | 
					
						
							|  |  |  | 	set_status("mp_sub_max",cfg.mp.mp_sub_max) | 
					
						
							|  |  |  | 	set_status("mp_sub",0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func set_material(material:ShaderMaterial,material_sub:ShaderMaterial): | 
					
						
							|  |  |  | 	view.material_override = material | 
					
						
							|  |  |  | 	view.material_override.next_pass = material_sub | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func is_on_stair()->bool: | 
					
						
							|  |  |  | 	if velocity.x > 0: | 
					
						
							|  |  |  | 		if raycast_stair(Vector3.RIGHT):return true | 
					
						
							|  |  |  | 	elif velocity.x < 0: | 
					
						
							|  |  |  | 		if raycast_stair(Vector3.LEFT):return true | 
					
						
							|  |  |  | 	if velocity.z > 0: | 
					
						
							|  |  |  | 		if raycast_stair(Vector3.BACK):return true | 
					
						
							|  |  |  | 	elif velocity.z < 0: | 
					
						
							|  |  |  | 		if raycast_stair(Vector3.FORWARD):return true | 
					
						
							|  |  |  | 	return false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func raycast_stair(dir:Vector3)->bool: | 
					
						
							|  |  |  | 	var width = Setting.pixel_size * status.cfg.sprite_width | 
					
						
							|  |  |  | 	var from = position + Vector3.UP * Setting.pixel_size * 6 + dir * width * 0.4 | 
					
						
							|  |  |  | 	var to = from + dir * width * 0.2 | 
					
						
							|  |  |  | 	var up = to + Vector3.UP * Setting.pixel_size * 4 | 
					
						
							|  |  |  | 	return Util.raycast_wall(from,to) and Util.raycast_wall(up,to)  | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #==getter== | 
					
						
							|  |  |  | func id()->int:return status.id | 
					
						
							|  |  |  | func cfg()->CharacterCfg:return status.cfg | 
					
						
							|  |  |  | func team()->Enum.ETeam:return status.team | 
					
						
							|  |  |  | func pos2D()->Vector2:return Vector2(position.x,position.z) | 
					
						
							|  |  |  | func pos()->Vector3:return position | 
					
						
							|  |  |  | func radius()->float:return status.radius | 
					
						
							|  |  |  | func height()->float:return status.height | 
					
						
							|  |  |  | func view_pos()->Vector3:return position + view.position | 
					
						
							|  |  |  | func ui_pos()->Vector3:return position + status.ui_offset | 
					
						
							|  |  |  | func ui_pos_center()->Vector3:return position + status.ui_center_offset | 
					
						
							|  |  |  | func target()->int:return status.target | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #==interface== | 
					
						
							|  |  |  | func get_status(status_name:String):return status.get_status(status_name) | 
					
						
							|  |  |  | func set_status(status_name:String,value):status.set_status(status_name,value) | 
					
						
							|  |  |  | func set_pos(pos:Vector3):position = pos;SignalManager.character_pos_changed.emit(id(),pos()) | 
					
						
							|  |  |  | func move_to(dir:Vector2):set_status("move_dir",dir) | 
					
						
							|  |  |  | func move_stop():set_status("move_dir",Vector2.ZERO) | 
					
						
							|  |  |  | func add_buff(buff_name:String,duration:float,ignore_pause:bool=false):buff.add_buff(buff_name,duration,ignore_pause) | 
					
						
							|  |  |  | func remove_buff(buff_name:String):buff.remove_buff(buff_name) | 
					
						
							|  |  |  | func has_buff(buff_name:String)->bool:return buff.has_buff(buff_name) | 
					
						
							|  |  |  | func set_hit_move(hit_back_dir:Vector2,hit_back_speed:float,hit_up_speed:float):status.hit_back_dir = hit_back_dir;status.hit_back_speed = hit_back_speed;status.hit_up_speed = hit_up_speed | 
					
						
							|  |  |  | func cancel_skill():skill.cancel_skill() | 
					
						
							|  |  |  | func set_view_trigger(trigger_name:String):status.set("trigger_%s"%trigger_name,true) | 
					
						
							|  |  |  | func add_attack(from:int,dir:Vector2,attack:AttackCfg):battle.add_attack(from,dir,attack) | 
					
						
							|  |  |  | func show_hit_text(value:String):SignalManager.character_hit_text.emit(id(),value) | 
					
						
							|  |  |  | func show_hit_damage(value:float):SignalManager.character_hit_damage.emit(id(),value) | 
					
						
							|  |  |  | func add_mp(value:float):battle.add_mp(value) | 
					
						
							|  |  |  | func set_target(target:int):set_status("target",target) | 
					
						
							|  |  |  | func cast_particle(resource:Resource):effect.cast_particle(resource) |