diff --git a/effect.lua b/effect.lua new file mode 100644 index 0000000000000000000000000000000000000000..a854eaf0cacdb466946d7d8b0a907b1a2b1fcfae --- /dev/null +++ b/effect.lua @@ -0,0 +1,219 @@ + +local mobile_effect = fk.CreateSkill{ + name = "mobile_effect", +} + +--[[ + 关于手刹特效: + 连斩特效:一回合内连续死亡的人数计入本回合连斩(无论凶手是谁甚至没有凶手) + 癫狂屠戮:对其他角色造成的伤害令体力减少3点 + 万军取首:对其他角色造成的伤害使其体力减少4点或者更多 + 医术高超:统计本回合对自己回复体力或者受到无来源体力回复的数,每超过2,播放一次特效并将计数mod 3 + 妙手回春:统计本轮内令他人回复体力的数,每超过2,播放特效并mod 3 +--]] + +local zy = { + "zy", "ZY", "zy", "ZY", "游客1316", "youko1316", +} + +---@param mvp ServerPlayer +local function getRank(mvp) + local room = mvp.room + local rank = 1 + local gameData = mvp._splayer:getGameData() + if not gameData then return 0 end + local tot, win = gameData:at(0), gameData:at(1) + local lose = tot - win + local exp = win * 5 + lose + if room.settings.gameMode ~= "m_1v2_mode" then exp = exp * 2 end + if exp > 30 then rank = rank + 1 end + if exp > 100 then rank = rank + 1 end + if exp > 200 then rank = rank + 1 end + if exp > 400 then rank = rank + 1 end + if exp > 1000 then rank = rank + 1 end + if exp > 1800 then rank = rank + 1 end + if exp > 3000 then rank = rank + 1 end + if exp > 5000 then rank = rank + 1 end + if exp > 10000 then rank = rank + 1 end + if exp > 40000 then rank = rank + 1 end + + if table.contains(zy, mvp._splayer:getScreenName()) then + rank = 0 + end + + return rank +end + +-- Rampage, Violence +mobile_effect:addEffect(fk.HpChanged, { + global = true, + priority = -1, + can_refresh = function (self, event, target, player, data) + return target == player and data.reason == "damage" and data.num <= -3 + and data.damageEvent and data.damageEvent.from and data.damageEvent.from ~= player + end, + on_refresh = function (self, event, target, player, data) + local room = player.room + if data.num == -3 then + room:doSuperLightBox("packages/mobile_effect/qml/Rampage.qml") + room:delay(100) + player:broadcastSkillInvoke(mobile_effect.name, 1) + room:delay(3700) + else + room:doSuperLightBox("packages/mobile_effect/qml/Violence.qml") + room:delay(400) + player:broadcastSkillInvoke(mobile_effect.name, 2) + room:delay(4000) + end + end, +}) + +-- Heal, Rescue +mobile_effect:addEffect(fk.HpRecover, { + global = true, + priority = -1, + can_refresh = function (self, event, target, player, data) + return target == player + end, + on_refresh = function (self, event, target, player, data) + local room = player.room + if data.recoverBy == player or data.recoverBy == nil then + local x = player:getMark("n_mobile_effect_heal-turn") + x = x + data.num + if x > 2 then + x = x % 3 + room:doSuperLightBox("packages/mobile_effect/qml/Heal.qml") + player:broadcastSkillInvoke(mobile_effect.name, 11) + room:delay(2200) + end + -- 这里用setMark是因为客户端无需知晓这个标记,顺便善用标记的自动清理 + -- 下面那个同理 + player:setMark("n_mobile_effect_heal-turn", x) + else + local from = data.recoverBy ---@type ServerPlayer + local x = from:getMark("n_mobile_effect_rescue-round") + if x == 0 then x = {} end + local k = tostring(player.id) -- 标记必须能用JSON表达才行,所以键必须字符串 + x[k] = (x[k] or 0) + data.num + if x[k] > 2 then + x[k] = x[k] % 3 + room:doSuperLightBox("packages/mobile_effect/qml/Rescue.qml") + player:broadcastSkillInvoke(mobile_effect.name, 12) + room:delay(2200) + end + from:setMark("n_mobile_effect_rescue-round", x) + end + end, +}) + +-- Kill Animation +mobile_effect:addEffect(fk.BeforeGameOverJudge, { + global = true, + priority = -1, + can_refresh = function (self, event, target, player, data) + return player == RoomInstance.current + end, + on_refresh = function (self, event, target, player, data) + local room = player.room + if not room:getTag("m_FirstBlood") then + room:setTag("m_FirstBlood", true) + room:doSuperLightBox("packages/mobile_effect/qml/FirstBlood.qml") + player:broadcastSkillInvoke(mobile_effect.name, 3) + room:delay(2700) + end + player:addMark("n_mobile_effect_kill-turn", 1) + local kills = player:getMark("n_mobile_effect_kill-turn") + if kills == 2 then + room:doSuperLightBox("packages/mobile_effect/qml/DoubleKill.qml") + player:broadcastSkillInvoke(mobile_effect.name, kills + 2) + room:delay(2800) + elseif kills == 3 then + room:doSuperLightBox("packages/mobile_effect/qml/TripleKill.qml") + player:broadcastSkillInvoke(mobile_effect.name, kills + 2) + room:delay(2800) + elseif kills == 4 then + room:doSuperLightBox("packages/mobile_effect/qml/QuadraKill.qml") + player:broadcastSkillInvoke(mobile_effect.name, kills + 2) + room:delay(3500) + elseif kills > 4 and kills <= 7 then + room:doSuperLightBox("packages/mobile_effect/qml/MoreKill.qml", { n = kills }) + player:broadcastSkillInvoke(mobile_effect.name, kills + 2) + room:delay(4000) + end + end, +}) + +-- MVP +mobile_effect:addEffect(fk.GameFinished, { + global = true, + priority = -1, + can_refresh = function (self, event, target, player, data) + return data and data ~= "" and player == RoomInstance.current + end, + on_refresh = function (self, event, target, player, data) + local room = player.room + local winners = data:split("+") + winners = table.filter(room.alive_players, function(p) ---@type ServerPlayer[] + return table.contains(winners, p.role) + end) + if #winners > 0 and math.random() > 0.05 then + local mvp = table.random(winners) + player:broadcastSkillInvoke(mobile_effect.name, 10) + local rank = getRank(mvp) + + local hasWinAudio = "" + local soundName = "" + local generals = {mvp.general} + if mvp.deputyGeneral ~= "" then + table.insert(generals, mvp.deputyGeneral) + end + for _, g in ipairs(generals) do + soundName = "./packages/" .. Fk.generals[g].package.extensionName .. "/audio/win/" .. g + if FileIO.exists(soundName .. ".mp3") then + hasWinAudio = g + break + end + end + room:doSuperLightBox("packages/mobile_effect/qml/MobileMvp.qml", { + general = hasWinAudio ~= "" and hasWinAudio or mvp.general, + screenName = mvp._splayer:getScreenName(), + rank = rank, + }) + room:delay(1100) + + if hasWinAudio ~= "" then + room:broadcastPlaySound(soundName) + else + local skill = Fk.skills[mvp.general .. "_win_audio"] -- 只兼容主将,不想管了 + if not skill then skill = table.random(Fk.generals[mvp.general].skills) end + if skill then mvp:broadcastSkillInvoke(skill.name) end + end + room:delay(2900) + end + end, +}) + +Fk:loadTranslationTable{ + ["$mobile_effect1"] = "癫狂屠戮!", + ["$mobile_effect2"] = "无双!万军取首!", + ["$mobile_effect3"] = "一破!卧龙出山!", + ["$mobile_effect4"] = "双连!一战成名!", + ["$mobile_effect5"] = "三连!举世皆惊!", + ["$mobile_effect6"] = "四连!天下无敌!", + ["$mobile_effect7"] = "五连!诛天灭地!", + ["$mobile_effect8"] = "六连!诛天灭地!", + ["$mobile_effect9"] = "七连!诛天灭地!", + ["$mobile_effect10"] = "(傲视群雄)", + ["$mobile_effect11"] = "医术高超~", + ["$mobile_effect12"] = "妙手回春~", + + ["Player Username"] = "玩家昵称", + ["TEC Score: "] = "技术分:", + ["ATK Score"] = "攻击分数", + ["Healing Score"] = "治疗分数", + ["Help Score"] = "辅助分数", + ["Situation Score"] = "局势分数", + ["Punishment Score"] = "惩罚扣分", +} + +return mobile_effect diff --git a/init.lua b/init.lua index 0b3d2f97e052cfa1959b0830df67c9a611dfe2fe..3bd60bccad62a2c7f4df10b7e228c4553654ba55 100644 --- a/init.lua +++ b/init.lua @@ -1,192 +1,4 @@ ---[[ - 关于手刹特效: - 连斩特效:一回合内连续死亡的人数计入本回合连斩(无论凶手是谁甚至没有凶手) - 癫狂屠戮:对其他角色造成的伤害令体力减少3点 - 万军取首:对其他角色造成的伤害使其体力减少4点或者更多 - 医术高超:统计本回合对自己回复体力或者受到无来源体力回复的数,每超过2,播放一次特效并将计数mod 3 - 妙手回春:统计本轮内令他人回复体力的数,每超过2,播放特效并mod 3 ---]] - -local zy = { - "zy", "ZY", "zy", "ZY", "游客1316", "youko1316", -} - ----@param mvp ServerPlayer -local function getRank(mvp) - local room = mvp.room - local rank = 1 - local gameData = mvp._splayer:getGameData() - if not gameData then return 0 end - local tot, win = gameData:at(0), gameData:at(1) - local lose = tot - win - local exp = win * 5 + lose - if room.settings.gameMode ~= "m_1v2_mode" then exp = exp * 2 end - if exp > 30 then rank = rank + 1 end - if exp > 100 then rank = rank + 1 end - if exp > 200 then rank = rank + 1 end - if exp > 400 then rank = rank + 1 end - if exp > 1000 then rank = rank + 1 end - if exp > 1800 then rank = rank + 1 end - if exp > 3000 then rank = rank + 1 end - if exp > 5000 then rank = rank + 1 end - if exp > 10000 then rank = rank + 1 end - if exp > 40000 then rank = rank + 1 end - - if table.contains(zy, mvp._splayer:getScreenName()) then - rank = 0 - end - - return rank -end - -local mobile_effect = fk.CreateTriggerSkill{ - name = "mobile_effect", - global = true, - priority = -1, - - refresh_events = { - fk.DamageInflicted, -- helper event - fk.HpChanged, -- Rampage, Violence - fk.HpRecover, -- Heal, Rescue - fk.BeforeGameOverJudge, -- Kill Animation - fk.GameFinished, -- MVP - }, - - can_refresh = function(self, event, target, player, data) - -- only trigger once - local ret = target == nil or target == player - if ret then - if event == fk.DamageInflicted then - self.can_rampage = data.from and data.from ~= data.to - return false - elseif event == fk.HpChanged then - return data.reason == "damage" and data.num <= -3 and self.can_rampage - elseif event == fk.HpRecover then - return true - elseif event == fk.BeforeGameOverJudge then - return true - elseif event == fk.GameFinished then - return data and data ~= "" and player == RoomInstance.current - end - end - end, - - on_refresh = function(self, event, target, player, data) - local room = RoomInstance - if event == fk.HpChanged then - if data.num == -3 then - room:doSuperLightBox("packages/mobile_effect/qml/Rampage.qml") - room:delay(100) - player:broadcastSkillInvoke(self.name, 1) - room:delay(3700) - else - room:doSuperLightBox("packages/mobile_effect/qml/Violence.qml") - room:delay(400) - player:broadcastSkillInvoke(self.name, 2) - room:delay(4000) - end - elseif event == fk.HpRecover then - local rec = data ---@type RecoverStruct - if rec.recoverBy == player or rec.recoverBy == nil then - local x = player:getMark("n_mobile_effect_heal-turn") - x = x + rec.num - if x > 2 then - x = x % 3 - room:doSuperLightBox("packages/mobile_effect/qml/Heal.qml") - player:broadcastSkillInvoke(self.name, 11) - room:delay(2200) - end - -- 这里用setMark是因为客户端无需知晓这个标记,顺便善用标记的自动清理 - -- 下面那个同理 - player:setMark("n_mobile_effect_heal-turn", x) - else - local from = rec.recoverBy ---@type ServerPlayer - local x = from:getMark("n_mobile_effect_rescue-round") - if x == 0 then x = {} end - local k = tostring(player.id) -- 标记必须能用JSON表达才行,所以键必须字符串 - x[k] = (x[k] or 0) + rec.num - if x[k] > 2 then - x[k] = x[k] % 3 - room:doSuperLightBox("packages/mobile_effect/qml/Rescue.qml") - player:broadcastSkillInvoke(self.name, 12) - room:delay(2200) - end - from:setMark("n_mobile_effect_rescue-round", x) - end - elseif event == fk.BeforeGameOverJudge then - if not room:getTag("m_FirstBlood") then - room:setTag("m_FirstBlood", true) - room:doSuperLightBox("packages/mobile_effect/qml/FirstBlood.qml") - player:broadcastSkillInvoke(self.name, 3) - room:delay(2700) - end - local current = room.current - current:addSkillUseHistory(self.name, 1) - local kills = current:usedSkillTimes(self.name, Player.HistoryTurn) - if kills == 2 then - room:doSuperLightBox("packages/mobile_effect/qml/DoubleKill.qml") - player:broadcastSkillInvoke(self.name, kills + 2) - room:delay(2800) - elseif kills == 3 then - room:doSuperLightBox("packages/mobile_effect/qml/TripleKill.qml") - player:broadcastSkillInvoke(self.name, kills + 2) - room:delay(2800) - elseif kills == 4 then - room:doSuperLightBox("packages/mobile_effect/qml/QuadraKill.qml") - player:broadcastSkillInvoke(self.name, kills + 2) - room:delay(3500) - elseif kills > 4 and kills <= 7 then - room:doSuperLightBox("packages/mobile_effect/qml/MoreKill.qml", { n = kills }) - player:broadcastSkillInvoke(self.name, kills + 2) - room:delay(4000) - end - elseif event == fk.GameFinished then - local winners = data:split("+") - winners = table.filter(room.alive_players, function(p) ---@type ServerPlayer[] - return table.contains(winners, p.role) - end) - if #winners > 0 and math.random() > 0.05 then - local mvp = table.random(winners) - player:broadcastSkillInvoke(self.name, 10) - local rank = getRank(mvp) - - room:doSuperLightBox("packages/mobile_effect/qml/MobileMvp.qml", { - general = mvp.general, - screenName = mvp._splayer:getScreenName(), - rank = rank, - }) - room:delay(1100) - local skill = Fk.skills[mvp.general .. "_win_audio"] - if not skill then skill = table.random(Fk.generals[mvp.general].skills) end - if skill then mvp:broadcastSkillInvoke(skill.name) end - room:delay(2900) - end - end - end, -} -mobile_effect.package = { extensionName = "mobile_effect" } - -Fk:loadTranslationTable{ - ["$mobile_effect1"] = "癫狂屠戮!", - ["$mobile_effect2"] = "无双!万军取首!", - ["$mobile_effect3"] = "一破!卧龙出山!", - ["$mobile_effect4"] = "双连!一战成名!", - ["$mobile_effect5"] = "三连!举世皆惊!", - ["$mobile_effect6"] = "四连!天下无敌!", - ["$mobile_effect7"] = "五连!诛天灭地!", - ["$mobile_effect8"] = "六连!诛天灭地!", - ["$mobile_effect9"] = "七连!诛天灭地!", - ["$mobile_effect10"] = "(傲视群雄)", - ["$mobile_effect11"] = "医术高超~", - ["$mobile_effect12"] = "妙手回春~", - - ["Player Username"] = "玩家昵称", - ["TEC Score: "] = "技术分:", - ["ATK Score"] = "攻击分数", - ["Healing Score"] = "治疗分数", - ["Help Score"] = "辅助分数", - ["Situation Score"] = "局势分数", - ["Punishment Score"] = "惩罚扣分", -} - -Fk:addSkill(mobile_effect) +local extension = Package:new("mobile_effect", Package.SpecialPack) +local effect = require("packages.mobile_effect.effect") +table.insert(extension.skill_skels, effect) +return extension