|  |  |  | extends Node3D | 
					
						
							|  |  |  | class_name Buff | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @onready var character = (get_owner() as Character) | 
					
						
							|  |  |  | @onready var status = (%Status as Status) | 
					
						
							|  |  |  | @onready var effect = (%Effect as Effect) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BuffInfo: | 
					
						
							|  |  |  | 	var name : String | 
					
						
							|  |  |  | 	var duration_max : float | 
					
						
							|  |  |  | 	var duration : float | 
					
						
							|  |  |  | 	var ignore_pause : bool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var buff_map = {} #命中信息 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func _process(delta): | 
					
						
							|  |  |  | 	for buff_name in buff_map: | 
					
						
							|  |  |  | 		var buff_info = buff_map[buff_name] | 
					
						
							|  |  |  | 		if has_buff("pause") and buff_name!="pause" and !buff_info.ignore_pause: | 
					
						
							|  |  |  | 			continue | 
					
						
							|  |  |  | 		if buff_info.duration_max == -1: | 
					
						
							|  |  |  | 			trigger_buff_effect(buff_info,"update") | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			if buff_info.duration == 0: | 
					
						
							|  |  |  | 				trigger_buff_effect(buff_info,"second") | 
					
						
							|  |  |  | 			buff_info.duration += delta | 
					
						
							|  |  |  | 			if buff_info.duration >= buff_info.duration_max: | 
					
						
							|  |  |  | 				remove_buff(buff_name) | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				trigger_buff_effect(buff_info,"update") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func trigger_buff_effect(buff:BuffInfo,trigger_name:String): | 
					
						
							|  |  |  | 	var buff_name = buff.name | 
					
						
							|  |  |  | 	var function_name = "on_%s_%s" % [trigger_name,buff_name] | 
					
						
							|  |  |  | 	if has_method(function_name): | 
					
						
							|  |  |  | 		var rate = buff.duration/buff.duration_max | 
					
						
							|  |  |  | 		call(function_name,rate) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func has_buff(buff_name:String) -> bool: | 
					
						
							|  |  |  | 	return buff_name in buff_map | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | func add_buff(buff_name:String,duration:float,ignore_pause:bool=false): | 
					
						
							|  |  |  | 	var buff : BuffInfo | 
					
						
							|  |  |  | 	if buff_name in buff_map: | 
					
						
							|  |  |  | 		buff = buff_map[buff_name] | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		buff = BuffInfo.new() | 
					
						
							|  |  |  | 		buff.name = buff_name | 
					
						
							|  |  |  | 		buff_map[buff_name] = buff | 
					
						
							|  |  |  | 	buff.duration_max = duration | 
					
						
							|  |  |  | 	buff.duration = 0 | 
					
						
							|  |  |  | 	buff.ignore_pause = ignore_pause | 
					
						
							|  |  |  | 	trigger_buff_effect(buff,"start") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func remove_buff(buff_name:String): | 
					
						
							|  |  |  | 	if buff_name in buff_map: | 
					
						
							|  |  |  | 		var buff = buff_map[buff_name] | 
					
						
							|  |  |  | 		trigger_buff_effect(buff,"end") | 
					
						
							|  |  |  | 		buff_map.erase(buff_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #==具体实现== | 
					
						
							|  |  |  | #位移 | 
					
						
							|  |  |  | func on_end_hit_back(rate):status.hit_back_speed = 0 | 
					
						
							|  |  |  | func on_end_hit_up(rate):status.hit_up_speed = 0 | 
					
						
							|  |  |  | func on_start_jumping(rate):status.is_jumping = true | 
					
						
							|  |  |  | func on_end_jumping(rate):status.is_jumping = false | 
					
						
							|  |  |  | func on_start_rising(rate):status.is_rising = true | 
					
						
							|  |  |  | func on_end_rising(rate):status.is_rising = false | 
					
						
							|  |  |  | func on_start_floating(rate):status.is_floating = true;add_buff("rising",0.1) | 
					
						
							|  |  |  | func on_update_floating(rate): | 
					
						
							|  |  |  | 	if not status.is_on_floor or status.is_rising: | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	if has_buff("hit_down"): | 
					
						
							|  |  |  | 		character.add_attack(character.id(),status.move_dir,ResourceManager.cfg_attack_rebound) | 
					
						
							|  |  |  | 		remove_buff("hit_down") | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		remove_buff("floating") | 
					
						
							|  |  |  | 		add_buff("stagger",3) | 
					
						
							|  |  |  | func on_end_floating(rate):status.is_floating = false | 
					
						
							|  |  |  | 		 | 
					
						
							|  |  |  | #战斗状态 | 
					
						
							|  |  |  | func on_start_die(rate):status.is_dead = true;SignalManager.character_die.emit(status.id) | 
					
						
							|  |  |  | func on_end_die(rate):add_buff("die2",-1) | 
					
						
							|  |  |  | func on_update_die2(rate):if status.is_on_floor:remove_buff("die2") | 
					
						
							|  |  |  | func on_end_die2(rate):effect.cast_corpse();Global.character_mgr.destroy_character(status.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_start_stagger(rate):status.is_stagger = true | 
					
						
							|  |  |  | func on_end_stagger(rate):status.is_stagger = false | 
					
						
							|  |  |  | func on_end_shield_recover_cd(rate):add_buff("shield_recover",-1) | 
					
						
							|  |  |  | func on_update_shield_recover(rate): | 
					
						
							|  |  |  | 	var shield_add = get_process_delta_time() * status.cfg.shield.recover_speed | 
					
						
							|  |  |  | 	shield_add = min(status.shield_max - status.shield,shield_add) | 
					
						
							|  |  |  | 	if shield_add == status.shield_max - status.shield: | 
					
						
							|  |  |  | 		remove_buff("shield_recover") | 
					
						
							|  |  |  | 	character.set_status("shield",status.shield+shield_add) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_mp_recover_cd(rate):add_buff("mp_recover",-1) | 
					
						
							|  |  |  | func on_update_mp_recover(rate): | 
					
						
							|  |  |  | 	var mp_add = get_process_delta_time() * status.cfg.mp.recover_speed | 
					
						
							|  |  |  | 	if mp_add == 0: | 
					
						
							|  |  |  | 		remove_buff("mp_recover") | 
					
						
							|  |  |  | 	elif mp_add > 0: | 
					
						
							|  |  |  | 		mp_add = min(status.mp_sub_max - status.mp_sub,mp_add) | 
					
						
							|  |  |  | 		character.add_mp(mp_add) | 
					
						
							|  |  |  | 	elif mp_add < 0: | 
					
						
							|  |  |  | 		mp_add = max(-status.mp_sub , mp_add) | 
					
						
							|  |  |  | 		if mp_add == 0: | 
					
						
							|  |  |  | 			remove_buff("mp_recover") | 
					
						
							|  |  |  | 	character.set_status("mp_sub",status.mp_sub+mp_add) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_stun_recover_break_cd(rate):add_buff("stun_recover_break",-1) | 
					
						
							|  |  |  | func on_update_stun_recover_break(rate): | 
					
						
							|  |  |  | 	var stun_sub = get_process_delta_time() * status.cfg.stun.recover_break_speed | 
					
						
							|  |  |  | 	stun_sub = min(status.stun,stun_sub) | 
					
						
							|  |  |  | 	character.set_status("stun",status.stun-stun_sub) | 
					
						
							|  |  |  | 	if status.stun == 0: | 
					
						
							|  |  |  | 		remove_buff("stun_recover_break") | 
					
						
							|  |  |  | 		character.set_status("is_stun",false) | 
					
						
							|  |  |  | 	 | 
					
						
							|  |  |  | func on_end_stun_recover_cd(rate):add_buff("stun_recover",-1) | 
					
						
							|  |  |  | func on_update_stun_recover(rate): | 
					
						
							|  |  |  | 	var stun_sub = get_process_delta_time() * status.cfg.stun.recover_speed | 
					
						
							|  |  |  | 	stun_sub = min(status.stun,stun_sub) | 
					
						
							|  |  |  | 	character.set_status("stun",status.stun-stun_sub) | 
					
						
							|  |  |  | 	if status.stun == 0: | 
					
						
							|  |  |  | 		remove_buff("stun_recover") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #表现 | 
					
						
							|  |  |  | func on_start_freeze(rate):status.is_pause = true | 
					
						
							|  |  |  | func on_end_freeze(rate):status.is_pause = false | 
					
						
							|  |  |  | func on_second_pause(rate):status.is_pause = true | 
					
						
							|  |  |  | func on_end_pause(rate):status.is_pause = false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_start_flash_white(rate):status.flash_white_rate = 1 | 
					
						
							|  |  |  | func on_update_flash_white(rate):status.flash_white_rate = 1 - rate | 
					
						
							|  |  |  | func on_end_flash_white(rate):status.flash_white_rate = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_update_shake_x(rate):status.shake_offset = Vector3((sin(rate * PI * 4) - 0.5)*0.02,0,0); | 
					
						
							|  |  |  | func on_end_shake_x(rate):status.shake_offset = Vector3.ZERO | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_start_deformation(rate): | 
					
						
							|  |  |  | 	status.deformation_dir=Vector2(status.hit_back_speed,status.hit_up_speed) | 
					
						
							|  |  |  | 	status.deformation_rate = 1; | 
					
						
							|  |  |  | func on_update_deformation(rate):status.deformation_rate = 1 - rate | 
					
						
							|  |  |  | func on_end_deformation(rate):status.deformation_rate = 0 | 
					
						
							|  |  |  | 
 |