技能
最后更新于
Ability_Base :: class {
player: Player;
name: string;
icon: Texture_Asset;
current_cooldown: float;
type: typeid;
is_aimed_ability: bool;
mouse_position_on_press: v2;
keybind_override: Keybind;
disable_keybind: bool;
draw_but_dont_use_keybind: bool; // 显示按键提示,但输入由你自己处理。
#interface on_update :: proc(ability: Ability_Base, params: ref Ability_Update_Params);
#interface can_use :: proc(ability: Ability_Base) -> bool;
#interface on_draw_button :: proc(ability: Ability_Base, rect: Rect);
}
Ability_Update_Params :: struct : Interact_Result {
can_use: bool; // 冷却 + can_use + Player.ao_can_use_ability(如果存在)
drag_offset: v2; // 0..1
drag_direction: v2; // 单位方向
}
draw_ability_button :: proc(player: Player, $T: typeid, index: int);Dash_Ability :: class : Ability_Base {
on_init :: method() {
name = "冲刺";
icon = get_asset(Texture_Asset, "icons/dash.png");
}
can_use :: method() -> bool {
// 可选的额外限制(除冷却外)
return true;
}
on_update :: method(params: ref Ability_Update_Params) {
if params.clicked && params.can_use {
// 在这里应用玩法逻辑。此路径会经过客户端预测并在服务器上执行。
// ...
// 重要:在激活时设置冷却
current_cooldown = 1.5;
}
}
}keybind_sprint: Keybind;
ao_before_scene_load :: proc() {
keybind_sprint = Keybinds.register("冲刺", .LEFT_SHIFT);
}
Sprint_Ability :: class : Ability_Base {
on_init :: method() {
name = "冲刺";
draw_but_dont_use_keybind = true;
keybind_override = keybind_sprint;
}
on_update :: method(params: ref Ability_Update_Params) {
holding := Ability_Utilities.update_holding_ability(player, ref params, keybind_sprint);
player.is_sprinting = holding.active;
}
}Shoot_Ability :: class : Ability_Base {
on_init :: method() {
name = "射击";
is_aimed_ability = true;
disable_keybind = true;
}
on_update :: method(params: ref Ability_Update_Params) {
activation := Ability_Utilities.full_update_aimed_ability(player, ref params);
if activation.activate && params.can_use {
// activation.direction 是一个单位向量
// shoot_projectile(player.entity.world_position, activation.direction);
current_cooldown = 0.5;
}
}
}Roll_Ability :: class : Ability_Base {
on_init :: method() {
name = "翻滚";
is_aimed_ability = true;
}
on_update :: method(params: ref Ability_Update_Params) {
activation := Ability_Utilities.full_update_targeted_aimed_ability(player, this, ref params);
if activation.activate && params.can_use {
current_cooldown = 1.25;
}
}
}Player :: class : Player_Base {
ao_can_use_ability :: method(ability: Ability_Base) -> bool {
if health.is_dead return false;
return true;
}
}