|  |  |  | 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 | 
					
						
							|  |  |  |     if has_buff("hit_down"): | 
					
						
							|  |  |  |         battle.add_attack(character.id(), character.id(), status.move_dir, ResourceManager.cfg_attack_rebound) | 
					
						
							|  |  |  |         remove_buff("hit_down") | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         remove_buff("floating") | 
					
						
							|  |  |  |         add_buff("stagger", 3) | 
					
						
							|  |  |  |     return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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: 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 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_end_stagger(rate)->void: status.is_stagger = false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 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 * 5) - 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 |