You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
5.9 KiB
GDScript

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