|  |  |  | extends Node3D | 
					
						
							|  |  |  | class_name Buff | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @onready var character: Character = (get_owner() as Character) | 
					
						
							|  |  |  | @onready var status: Status = (%Status as Status) | 
					
						
							|  |  |  | @onready var effect: Effect = (%Effect as Effect) | 
					
						
							|  |  |  | @onready var battle: Battle = (%Battle as Battle) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class BuffInfo: | 
					
						
							|  |  |  | 	var name: String | 
					
						
							|  |  |  | 	var duration_max: float | 
					
						
							|  |  |  | 	var duration: float | 
					
						
							|  |  |  | 	var ignore_pause: bool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var buff_map: Dictionary = {} #buff信息 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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: | 
					
						
							|  |  |  | 				buff_info.duration = buff_info.duration_max | 
					
						
							|  |  |  | 				trigger_buff_effect(buff_info, "update") | 
					
						
							|  |  |  | 				remove_buff(buff_name) | 
					
						
							|  |  |  | 			else: | 
					
						
							|  |  |  | 				trigger_buff_effect(buff_info, "update") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func trigger_buff_effect(buff: BuffInfo, trigger_name: String): | 
					
						
							|  |  |  | 	var buff_name: String     = buff.name | 
					
						
							|  |  |  | 	var function_name: String = "on_%s_%s" % [trigger_name, buff_name] | 
					
						
							|  |  |  | 	if has_method(function_name): | 
					
						
							|  |  |  | 		var rate: float = 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)->void: status.hit_back_speed = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_hit_up(rate)->void: status.hit_up_speed = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_start_jumping(rate)->void: status.is_jumping = true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_jumping(rate)->void: status.is_jumping = false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_start_rising(rate)->void: status.is_rising = true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_rising(rate)->void: status.is_rising = false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_start_floating(rate)->void: | 
					
						
							|  |  |  | 	status.is_floating = true | 
					
						
							|  |  |  | 	add_buff("rising", 0.1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_update_floating(rate) -> void: | 
					
						
							|  |  |  | 	if not status.is_on_floor or status.is_rising: | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	remove_buff("floating") | 
					
						
							|  |  |  | 	add_buff("stagger", 3) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_floating(rate)->void: status.is_floating = false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #战斗状态 | 
					
						
							|  |  |  | func on_start_die(rate)->void: | 
					
						
							|  |  |  | 	status.is_dead = true | 
					
						
							|  |  |  | 	SignalManager.character_die.emit(status.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_die(rate)->void: add_buff("die2", -1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_update_die2(rate)->void: if status.is_on_floor and not status.is_rising: remove_buff("die2") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_die2(rate)->void: | 
					
						
							|  |  |  | 	effect.cast_corpse() | 
					
						
							|  |  |  | 	Global.character_mgr.destroy_character(status.id) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_start_stagger(rate)->void: | 
					
						
							|  |  |  | 	status.is_stagger = true | 
					
						
							|  |  |  | 	status.set_skill_break_level_add(-1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_stagger(rate)->void: | 
					
						
							|  |  |  | 	status.is_stagger = false | 
					
						
							|  |  |  | 	status.set_skill_break_level_add(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_shield_recover_cd(rate)->void: add_buff("shield_recover", -1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_update_shield_recover(rate)->void: | 
					
						
							|  |  |  | 	var shield_add: float = 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_shield( status.shield+shield_add) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_mp_recover_cd(rate)->void: add_buff("mp_recover", -1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_update_mp_recover(rate)->void: | 
					
						
							|  |  |  | 	var mp_add: float = get_process_delta_time() * status.cfg.mp.recover_speed | 
					
						
							|  |  |  | 	character.add_mp_sub(mp_add, false) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_update_charging(rate)->void: | 
					
						
							|  |  |  | 	var mp_add: float = get_process_delta_time() * status.cfg.mp.charging_speed | 
					
						
							|  |  |  | 	character.add_mp_sub(mp_add, true) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_stun_recover_break_cd(rate)->void: add_buff("stun_recover_break", -1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_update_stun_recover_break(rate)->void: | 
					
						
							|  |  |  | 	var stun_sub: float = 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)->void: add_buff("stun_recover", -1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_update_stun_recover(rate)->void: | 
					
						
							|  |  |  | 	var stun_sub: float = 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_update_weapon_index_change(rate)->void: character.set_status("weapon_index_change_rate", rate) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_weapon_index_change(rate)->void: | 
					
						
							|  |  |  | 	var weapon_index: int = status.weapon_index + status.weapon_index_change_dir | 
					
						
							|  |  |  | 	var weapon_len: int   = len(status.weapon_list) | 
					
						
							|  |  |  | 	weapon_index = (weapon_index % weapon_len + weapon_len) % weapon_len | 
					
						
							|  |  |  | 	character.set_status("weapon_index", weapon_index) | 
					
						
							|  |  |  | 	character.set_status("weapon_index_change_dir", 0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | #表现 | 
					
						
							|  |  |  | func on_start_freeze(rate)->void: status.is_pause = true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_freeze(rate)->void: status.is_pause = false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_second_pause(rate)->void: status.is_pause = true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_pause(rate)->void: status.is_pause = false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_start_flash_white(rate)->void: status.flash_white_rate = 1 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_update_flash_white(rate)->void: status.flash_white_rate = 1 - rate | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_flash_white(rate)->void: status.flash_white_rate = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_update_shake_x(rate)->void: | 
					
						
							|  |  |  | 	var shake_rate: float = 0.5 * status.pause_time | 
					
						
							|  |  |  | 	status.shake_offset = Vector3((sin(rate * PI * 6) - 0.5)*shake_rate, 0, 0); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_shake_x(rate)->void: status.shake_offset = Vector3.ZERO | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_start_deformation(rate)->void: status.deformation_rate = 1; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_update_deformation(rate)->void: status.deformation_rate = 1 - rate | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_deformation(rate)->void: status.deformation_rate = 0 |