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) 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"): character.add_attack(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_status("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 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_recoveres://config/attack/rebound.tres") character.set_status("mp_sub", status.mp_sub+mp_add) 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