diff --git a/Fk/Pages/RoomLogic.js b/Fk/Pages/RoomLogic.js index 883a5b83..bc13e719 100644 --- a/Fk/Pages/RoomLogic.js +++ b/Fk/Pages/RoomLogic.js @@ -1231,6 +1231,20 @@ callbacks["Animate"] = (jsonData) => { animation.finished.connect(() => animation.destroy()); break; } + case "InvokeUltSkill": { + const id = data.player; + const photo = getPhoto(id); + if (!photo) { + return null; + } + + roomScene.bigAnim.source = "../RoomElement/UltSkillAnimation.qml"; + roomScene.bigAnim.item.loadData({ + skill_name: data.name, + general: photo.general, + }); + break; + } default: break; } diff --git a/Fk/RoomElement/UltSkillAnimation.qml b/Fk/RoomElement/UltSkillAnimation.qml new file mode 100644 index 00000000..03c25bd8 --- /dev/null +++ b/Fk/RoomElement/UltSkillAnimation.qml @@ -0,0 +1,203 @@ +import QtQuick +import QtQuick.Layouts +import Qt5Compat.GraphicalEffects + +Item { + id: root + anchors.fill: parent + property string generalName: "liubei" + property string skillName + + Rectangle { + id: mask + anchors.fill: parent + color: "black" + opacity: 0.5 + } + + GridLayout { + id: bg1 + columns: 20 + columnSpacing: 30 + rowSpacing: 70 + y: (root.height - height) / 2 + 25 + x: -300 + opacity: 0 + Repeater { + model: 40 + Text { + text: { + const o = "$" + skillName + (index % 2 + 1); + const p = Backend.translate(o); + if (o === p) { + return "Ultimate Skill Invoked!"; + } + return p; + } + color: "white" + font.pixelSize: 30 + font.family: fontLibian.name + } + } + } + + GridLayout { + id: bg2 + columns: 20 + columnSpacing: 30 + rowSpacing: 70 + y: (root.height - height) / 2 - 25 + x: -250 + opacity: 0 + Repeater { + model: 40 + Text { + text: { + const o = "$" + skillName + ((index + 1) % 2 + 1); + const p = Backend.translate(o); + if (o === p) { + return "Ultimate Skill Invoked!"; + } + return p; + } + color: "white" + font.pixelSize: 30 + font.family: fontLibian.name + } + } + } + + GeneralCardItem { + id: herocard + name: generalName + scale: 2.7 + x: root.width + 140 + anchors.verticalCenter: parent.verticalCenter + opacity: 0 + } + + Text { + topPadding: 5 + id: skill + text: Backend.translate(skillName) + font.family: fontLi2.name + font.pixelSize: 40 + x: root.width / 2 + 100 + y: root.height + 300 + color: "snow" + opacity: 0 + scale: 3 + style: Text.Outline + } + + ParallelAnimation { + running: true + PropertyAnimation { + target: bg1 + property: "x" + to: -200 + duration: 2000 + } + + PropertyAnimation { + target: bg2 + property: "x" + to: -350 + duration: 2000 + } + } + + SequentialAnimation { + id: anim + running: false + + ParallelAnimation { + PropertyAnimation { + targets: [ herocard, skill, bg1, bg2 ] + property: "opacity" + to: 1 + duration: 500 + } + + PropertyAnimation { + target: herocard + property: "scale" + to: 3.3 + duration: 500 + } + + PropertyAnimation { + target: herocard + property: "x" + to: (root.width - herocard.width) / 2 - 40 + duration: 500 + easing.type: Easing.InQuad + } + + PropertyAnimation { + target: skill + property: "y" + to: root.height / 2 + 120 + duration: 500 + } + } + + ParallelAnimation { + PropertyAnimation { + target: herocard + property: "x" + to: (root.width - herocard.width) / 2 - 120 + duration: 1000 + } + + PropertyAnimation { + target: skill + property: "y" + to: root.height / 2 + 80 + duration: 1000 + } + } + + ParallelAnimation { + PropertyAnimation { + targets: [ herocard, skill, mask, bg1, bg2 ] + property: "opacity" + to: 0 + duration: 500 + } + + PropertyAnimation { + target: herocard + property: "scale" + to: 2.7 + duration: 500 + } + + PropertyAnimation { + target: herocard + property: "x" + to: -100 - herocard.width + duration: 500 + easing.type: Easing.OutQuad + } + + PropertyAnimation { + target: skill + property: "y" + to: -300 + duration: 500 + easing.type: Easing.OutQuad + } + } + + onFinished: { + roomScene.bigAnim.source = ""; + } + } + + function loadData(data) { + generalName = data.general; + skillName = data.skill_name; + anim.running = true; + } +} diff --git a/lua/server/room.lua b/lua/server/room.lua index 076728b1..839d9d4e 100644 --- a/lua/server/room.lua +++ b/lua/server/room.lua @@ -944,22 +944,39 @@ end ---@param skill_name string @ 技能名 ---@param skill_type string | nil @ 技能的动画效果,默认是那个技能的anim_type function Room:notifySkillInvoked(player, skill_name, skill_type) + local bigAnim = false if not skill_type then local skill = Fk.skills[skill_name] if not skill then skill_type = "" end + + if skill.frequency == Skill.Limited or skill.frequency == Skill.Wake then + bigAnim = true + end + skill_type = skill.anim_type end + + if skill_type == "big" then bigAnim = true end + self:sendLog{ type = "#InvokeSkill", from = player.id, arg = skill_name, } - self:doAnimate("InvokeSkill", { - name = skill_name, - player = player.id, - skill_type = skill_type, - }) + if not bigAnim then + self:doAnimate("InvokeSkill", { + name = skill_name, + player = player.id, + skill_type = skill_type, + }) + else + self:doAnimate("InvokeUltSkill", { + name = skill_name, + player = player.id, + }) + self:delay(2000) + end end --- 播放从source指到targets的指示线效果。