From 9ae119028ca03a18760b074651364a26eea4e8d5 Mon Sep 17 00:00:00 2001 From: notify Date: Thu, 13 Apr 2023 20:17:39 +0800 Subject: [PATCH] Enhancement (#116) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 给Card堆一个伤害牌属性 能添加虚拟牌为子卡 封装了“视为使用xx牌”的函数 护甲机制 interaction现在可以作为一个函数,以实现动态化 冰属性伤害 使用牌堆中的牌不再报错 --- image/photo/magatama/shield.png | Bin 0 -> 3164 bytes lua/client/client.lua | 4 +- lua/client/client_util.lua | 53 +++----- lua/client/i18n/zh_CN.lua | 1 + lua/core/card.lua | 15 ++- lua/core/general.lua | 2 + lua/core/player.lua | 47 +++++++ lua/core/util.lua | 12 +- lua/fk_ex.lua | 122 ++++++------------ lua/freekill.lua | 4 +- lua/server/events/hp.lua | 75 +++++++---- lua/server/gamelogic.lua | 2 + lua/server/room.lua | 43 ++++++ lua/server/serverplayer.lua | 1 + lua/server/system_enum.lua | 1 + packages/maneuvering/init.lua | 3 + packages/standard_cards/init.lua | 4 + packages/test/init.lua | 34 ++--- qml/Pages/Room.qml | 4 + qml/Pages/RoomElement/GeneralCardItem.qml | 12 ++ qml/Pages/RoomElement/Photo.qml | 2 + qml/Pages/RoomElement/PhotoElement/HpBar.qml | 18 ++- qml/Pages/RoomElement/PhotoElement/Shield.qml | 22 ++++ 23 files changed, 307 insertions(+), 174 deletions(-) create mode 100644 image/photo/magatama/shield.png create mode 100644 qml/Pages/RoomElement/PhotoElement/Shield.qml diff --git a/image/photo/magatama/shield.png b/image/photo/magatama/shield.png new file mode 100644 index 0000000000000000000000000000000000000000..d68ef5eff9d5d0f28a4d448c81ecb221fb4ba2a9 GIT binary patch literal 3164 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 0) end + preprocessCardSpec(spec) + if spec.attack_range then + assert(type(spec.attack_range) == "number" and spec.attack_range >= 0) + end local card = Weapon:new(spec.name, spec.suit, spec.number, spec.attack_range) - card.skill = spec.skill or defaultCardSkill - card.special_skills = spec.special_skills - card.equip_skill = spec.equip_skill - - if spec.on_install then card.onInstall = spec.on_install end - if spec.on_uninstall then card.onUninstall = spec.on_uninstall end + readCardSpecToCard(card, spec) + readCardSpecToEquip(card, spec) return card end ---@param spec CardSpec ---@return Armor function fk.CreateArmor(spec) - assert(type(spec.name) == "string" or type(spec.class_name) == "string") - if not spec.name then spec.name = spec.class_name - elseif not spec.class_name then spec.class_name = spec.name end - if spec.suit then assert(type(spec.suit) == "number") end - if spec.number then assert(type(spec.number) == "number") end - + preprocessCardSpec(spec) local card = Armor:new(spec.name, spec.suit, spec.number) - card.skill = spec.skill or defaultCardSkill - card.equip_skill = spec.equip_skill - card.special_skills = spec.special_skills - - if spec.on_install then card.onInstall = spec.on_install end - if spec.on_uninstall then card.onUninstall = spec.on_uninstall end + readCardSpecToCard(card, spec) + readCardSpecToEquip(card, spec) return card end ---@param spec CardSpec ---@return DefensiveRide function fk.CreateDefensiveRide(spec) - assert(type(spec.name) == "string" or type(spec.class_name) == "string") - if not spec.name then spec.name = spec.class_name - elseif not spec.class_name then spec.class_name = spec.name end - if spec.suit then assert(type(spec.suit) == "number") end - if spec.number then assert(type(spec.number) == "number") end - + preprocessCardSpec(spec) local card = DefensiveRide:new(spec.name, spec.suit, spec.number) - card.skill = spec.skill or defaultCardSkill - card.special_skills = spec.special_skills - card.equip_skill = spec.equip_skill - - if spec.on_install then card.onInstall = spec.on_install end - if spec.on_uninstall then card.onUninstall = spec.on_uninstall end + readCardSpecToCard(card, spec) + readCardSpecToEquip(card, spec) return card end ---@param spec CardSpec ---@return OffensiveRide function fk.CreateOffensiveRide(spec) - assert(type(spec.name) == "string" or type(spec.class_name) == "string") - if not spec.name then spec.name = spec.class_name - elseif not spec.class_name then spec.class_name = spec.name end - if spec.suit then assert(type(spec.suit) == "number") end - if spec.number then assert(type(spec.number) == "number") end - + preprocessCardSpec(spec) local card = OffensiveRide:new(spec.name, spec.suit, spec.number) - card.skill = spec.skill or defaultCardSkill - card.special_skills = spec.special_skills - card.equip_skill = spec.equip_skill - - if spec.on_install then card.onInstall = spec.on_install end - if spec.on_uninstall then card.onUninstall = spec.on_uninstall end + readCardSpecToCard(card, spec) + readCardSpecToEquip(card, spec) return card end ---@param spec CardSpec ---@return Treasure function fk.CreateTreasure(spec) - assert(type(spec.name) == "string" or type(spec.class_name) == "string") - if not spec.name then spec.name = spec.class_name - elseif not spec.class_name then spec.class_name = spec.name end - if spec.suit then assert(type(spec.suit) == "number") end - if spec.number then assert(type(spec.number) == "number") end - + preprocessCardSpec(spec) local card = Treasure:new(spec.name, spec.suit, spec.number) - card.skill = spec.skill or defaultCardSkill - card.special_skills = spec.special_skills - card.equip_skill = spec.equip_skill - - if spec.on_install then card.onInstall = spec.on_install end - if spec.on_uninstall then card.onUninstall = spec.on_uninstall end + readCardSpecToCard(card, spec) + readCardSpecToEquip(card, spec) return card end diff --git a/lua/freekill.lua b/lua/freekill.lua index 774303c6..f0800a54 100644 --- a/lua/freekill.lua +++ b/lua/freekill.lua @@ -17,8 +17,8 @@ json = require "json" math.randomseed(os.time()) -- 加载实用类,让Lua编写起来更轻松。 -local GroupUtils = require "core.util" -TargetGroup, AimGroup = table.unpack(GroupUtils) +local Utils = require "core.util" +TargetGroup, AimGroup, Util = table.unpack(Utils) dofile "lua/core/debug.lua" -- 加载游戏核心类 diff --git a/lua/server/events/hp.lua b/lua/server/events/hp.lua index 1643fef3..5014e60c 100644 --- a/lua/server/events/hp.lua +++ b/lua/server/events/hp.lua @@ -1,5 +1,36 @@ -- SPDX-License-Identifier: GPL-3.0-or-later +local damage_nature_table = { + [fk.NormalDamage] = "normal_damage", + [fk.FireDamage] = "fire_damage", + [fk.ThunderDamage] = "thunder_damage", + [fk.IceDamage] = "ice_damage", +} + +local function sendDamageLog(room, damageStruct) + if damageStruct.from then + room:sendLog{ + type = "#Damage", + to = {damageStruct.from.id}, + from = damageStruct.to.id, + arg = damageStruct.damage, + arg2 = damage_nature_table[damageStruct.damageType], + } + else + room:sendLog{ + type = "#DamageWithNoFrom", + from = damageStruct.to.id, + arg = damageStruct.damage, + arg2 = damage_nature_table[damageStruct.damageType], + } + end + room:sendLogEvent("Damage", { + to = damageStruct.to.id, + damageType = damage_nature_table[damageStruct.damageType], + damageNum = damageStruct.damage, + }) +end + GameEvent.functions[GameEvent.ChangeHp] = function(self) local player, num, reason, skillName, damageStruct = table.unpack(self.data) local self = self.room @@ -25,32 +56,7 @@ GameEvent.functions[GameEvent.ChangeHp] = function(self) self:broadcastProperty(player, "hp") if reason == "damage" then - local damage_nature_table = { - [fk.NormalDamage] = "normal_damage", - [fk.FireDamage] = "fire_damage", - [fk.ThunderDamage] = "thunder_damage", - } - if damageStruct.from then - self:sendLog{ - type = "#Damage", - to = {damageStruct.from.id}, - from = player.id, - arg = 0 - num, - arg2 = damage_nature_table[damageStruct.damageType], - } - else - self:sendLog{ - type = "#DamageWithNoFrom", - from = player.id, - arg = 0 - num, - arg2 = damage_nature_table[damageStruct.damageType], - } - end - self:sendLogEvent("Damage", { - to = player.id, - damageType = damage_nature_table[damageStruct.damageType], - damageNum = damageStruct.damage, - }) + sendDamageLog(self, damageStruct) elseif reason == "loseHp" then self:sendLog{ type = "#LoseHP", @@ -125,8 +131,21 @@ GameEvent.functions[GameEvent.Damage] = function(self) return false end - if not self:changeHp(damageStruct.to, -damageStruct.damage, "damage", damageStruct.skillName, damageStruct) then - self.logic:breakEvent(false) + -- 先扣减护甲,再扣体力值 + local shield_to_lose = math.min(damageStruct.damage, damageStruct.to.shield) + self:changeShield(damageStruct.to, -shield_to_lose) + + if shield_to_lose < damageStruct.damage then + if not self:changeHp( + damageStruct.to, + shield_to_lose - damageStruct.damage, + "damage", + damageStruct.skillName, + damageStruct) then + self.logic:breakEvent(false) + end + else + sendDamageLog(self, damageStruct) end stages = { diff --git a/lua/server/gamelogic.lua b/lua/server/gamelogic.lua index ef34baba..d52717a4 100644 --- a/lua/server/gamelogic.lua +++ b/lua/server/gamelogic.lua @@ -122,6 +122,7 @@ function GameLogic:prepareForStart() local general = Fk.generals[p.general] p.maxHp = general.maxHp p.hp = general.hp + p.shield = general.shield -- TODO: setup AI here if p.role ~= "lord" then @@ -132,6 +133,7 @@ function GameLogic:prepareForStart() end room:broadcastProperty(p, "maxHp") room:broadcastProperty(p, "hp") + room:broadcastProperty(p, "shield") end local allCardIds = Fk:getAllCardIds() diff --git a/lua/server/room.lua b/lua/server/room.lua index 01cd7b10..e10aeceb 100644 --- a/lua/server/room.lua +++ b/lua/server/room.lua @@ -1882,6 +1882,39 @@ function Room:responseCard(cardResponseEvent) return execGameEvent(GameEvent.RespondCard, cardResponseEvent) end +---@param card_name string @ 想要视为使用的牌名 +---@param subcards integer[] @ 子卡,可以留空或者直接nil +---@param from ServerPlayer @ 使用来源 +---@param tos ServerPlayer | ServerPlayer[] @ 目标角色(列表) +---@param skillName string @ 技能名 +---@param extra boolean @ 是否计入次数 +function Room:useVirtualCard(card_name, subcards, from, tos, skillName, extra) + local card = Fk:cloneCard(card_name) + card.skillName = skillName + + if from:prohibitUse(card) then return false end + + if tos.class then tos = { tos } end + for i, p in ipairs(tos) do + if from:isProhibited(p, card) then + table.remove(tos, i) + end + end + + if #tos == 0 then return false end + + if subcards then card:addSubcards(Card:getIdList(subcards)) end + + local use = {} ---@type CardUseStruct + use.from = from.id + use.tos = table.map(tos, function(p) return { p.id } end) + use.card = card + use.extraUse = extra + self:useCard(use) + + return true +end + ------------------------------------------------------------------------ -- 移动牌 ------------------------------------------------------------------------ @@ -1992,6 +2025,16 @@ function Room:changeHp(player, num, reason, skillName, damageStruct) return execGameEvent(GameEvent.ChangeHp, player, num, reason, skillName, damageStruct) end +--- 改变玩家的护甲数 +---@param player ServerPlayer +---@param num integer @ 变化量 +function Room:changeShield(player, num) + if num == 0 then return end + player.shield = math.max(player.shield + num, 0) + player.shield = math.min(player.shield, 5) + self:broadcastProperty(player, "shield") +end + --- 令一名玩家失去体力。 ---@param player ServerPlayer @ 玩家 ---@param num integer @ 失去的数量 diff --git a/lua/server/serverplayer.lua b/lua/server/serverplayer.lua index df1b7383..06e985d6 100644 --- a/lua/server/serverplayer.lua +++ b/lua/server/serverplayer.lua @@ -141,6 +141,7 @@ function ServerPlayer:marshal(player) room:notifyProperty(player, self, "maxHp") room:notifyProperty(player, self, "hp") + room:notifyProperty(player, self, "shield") room:notifyProperty(player, self, "gender") room:notifyProperty(player, self, "kingdom") diff --git a/lua/server/system_enum.lua b/lua/server/system_enum.lua index 2144fc84..bb648f9e 100644 --- a/lua/server/system_enum.lua +++ b/lua/server/system_enum.lua @@ -51,6 +51,7 @@ fk.NormalDamage = 1 fk.ThunderDamage = 2 fk.FireDamage = 3 +fk.IceDamage = 4 --- DamageStruct 用来描述和伤害事件有关的数据。 ---@class DamageStruct diff --git a/packages/maneuvering/init.lua b/packages/maneuvering/init.lua index e9f8167d..0b51bf00 100644 --- a/packages/maneuvering/init.lua +++ b/packages/maneuvering/init.lua @@ -27,6 +27,7 @@ local thunderSlashSkill = fk.CreateActiveSkill{ local thunderSlash = fk.CreateBasicCard{ name = "thunder__slash", skill = thunderSlashSkill, + is_damage_card = true, } extension:addCards{ @@ -64,6 +65,7 @@ local fireSlashSkill = fk.CreateActiveSkill{ local fireSlash = fk.CreateBasicCard{ name = "fire__slash", skill = fireSlashSkill, + is_damage_card = true, } extension:addCards{ @@ -259,6 +261,7 @@ local fireAttackSkill = fk.CreateActiveSkill{ local fireAttack = fk.CreateTrickCard{ name = "fire_attack", skill = fireAttackSkill, + is_damage_card = true, } extension:addCards{ fireAttack:clone(Card.Heart, 2), diff --git a/packages/standard_cards/init.lua b/packages/standard_cards/init.lua index 52e41b70..d8c91040 100644 --- a/packages/standard_cards/init.lua +++ b/packages/standard_cards/init.lua @@ -37,6 +37,7 @@ local slash = fk.CreateBasicCard{ name = "slash", number = 7, suit = Card.Spade, + is_damage_card = true, skill = slashSkill, } @@ -310,6 +311,7 @@ local duel = fk.CreateTrickCard{ name = "duel", suit = Card.Spade, number = 1, + is_damage_card = true, skill = duelSkill, } @@ -452,6 +454,7 @@ local savageAssault = fk.CreateTrickCard{ name = "savage_assault", suit = Card.Spade, number = 7, + is_damage_card = true, skill = savageAssaultSkill, } @@ -499,6 +502,7 @@ local archeryAttack = fk.CreateTrickCard{ name = "archery_attack", suit = Card.Heart, number = 1, + is_damage_card = true, skill = archeryAttackSkill, } diff --git a/packages/test/init.lua b/packages/test/init.lua index c533ad2a..7dce5589 100644 --- a/packages/test/init.lua +++ b/packages/test/init.lua @@ -63,11 +63,11 @@ local test_active = fk.CreateActiveSkill{ return true end, card_filter = function(self, card) - if self.interaction.data == "joy" then + -- if self.interaction.data == "joy" then --local c = Fk:getCardById(card) --return Self:getPileNameOfId(card) == self.name and c.color == Card.Red return true - end + -- end end, card_num = 2, target_filter = function() return true end, @@ -86,11 +86,12 @@ local test_active = fk.CreateActiveSkill{ -- room:takeAG(from, id) -- room:delay(2000) -- room:closeAG(from) - local cards = room:askForCardsChosen(from, from, 2, 3, "hej", "") - from:addToPile(self.name, cards) - from.kingdom = "wei" - room:broadcastProperty(from, "kingdom") + -- local cards = room:askForCardsChosen(from, from, 2, 3, "hej", "") + -- from:addToPile(self.name, cards) + -- from.kingdom = "wei" + -- room:broadcastProperty(from, "kingdom") -- p(cards) + room:useVirtualCard("slash", nil, from, room:getOtherPlayers(from), self.name, true) end, } local test_vs = fk.CreateViewAsSkill{ @@ -98,16 +99,18 @@ local test_vs = fk.CreateViewAsSkill{ card_filter = function(self, to_select, selected) return #selected == 0 end, - interaction = UI.ComboBox { - choices = { - "ex_nihilo", - "duel", - "snatch", - "dismantlement", - "savage_assault", - "archery_attack", + interaction = function(self) + return UI.ComboBox { + choices = { + "ex_nihilo", + "duel", + "snatch", + "dismantlement", + "savage_assault", + "archery_attack", + } } - }, + end, view_as = function(self, cards) if #cards ~= 1 then return nil @@ -120,6 +123,7 @@ local test_vs = fk.CreateViewAsSkill{ end, } local test2 = General(extension, "mouxusheng", "wu", 4, 4, General.Female) +test2.shield = 4 test2:addSkill("rende") test2:addSkill(cheat) test2:addSkill(test_active) diff --git a/qml/Pages/Room.qml b/qml/Pages/Room.qml index cb1c6b34..cd45c9a5 100644 --- a/qml/Pages/Room.qml +++ b/qml/Pages/Room.qml @@ -192,6 +192,7 @@ Item { netstate: model.netstate maxHp: model.maxHp hp: model.hp + shield: model.shield seatNumber: model.seatNumber dead: model.dead dying: model.dying @@ -256,6 +257,7 @@ Item { self.kingdom: dashboardModel.kingdom self.netstate: dashboardModel.netstate self.maxHp: dashboardModel.maxHp + self.shield: dashboardModel.shield self.hp: dashboardModel.hp self.seatNumber: dashboardModel.seatNumber self.dead: dashboardModel.dead @@ -785,6 +787,7 @@ Item { netstate: "online", maxHp: 0, hp: 0, + shield: 0, seatNumber: 1, dead: false, dying: false, @@ -808,6 +811,7 @@ Item { netstate: "online", maxHp: 0, hp: 0, + shield: 0, seatNumber: i + 1, dead: false, dying: false, diff --git a/qml/Pages/RoomElement/GeneralCardItem.qml b/qml/Pages/RoomElement/GeneralCardItem.qml index 6c493c37..b0f64d7b 100644 --- a/qml/Pages/RoomElement/GeneralCardItem.qml +++ b/qml/Pages/RoomElement/GeneralCardItem.qml @@ -1,6 +1,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later import QtQuick +import "PhotoElement" import "../skin-bank.js" as SkinBank /* Layout of general card: @@ -18,6 +19,7 @@ CardItem { property string kingdom property int hp property int maxHp + property int shieldNum property string pkgName: "" name: "" // description: Sanguosha.getGeneralDescription(name) @@ -40,6 +42,7 @@ CardItem { y: 4 spacing: 1 Repeater { + id: hpRepeater model: (hp > 5 || hp !== maxHp) ? 1 : hp Image { source: SkinBank.getGeneralCardDir(kingdom) + kingdom + "-magatama" @@ -56,6 +59,14 @@ CardItem { } } + Shield { + anchors.right: parent.right + anchors.top: parent.top + anchors.topMargin: hpRepeater.model > 4 ? 16 : 0 + scale: 0.8 + value: shieldNum + } + Text { width: 20 height: 80 @@ -114,6 +125,7 @@ CardItem { kingdom = data.kingdom; hp = data.hp; maxHp = data.maxHp; + shieldNum = data.shield; let splited = name.split("__"); if (splited.length > 1) { diff --git a/qml/Pages/RoomElement/Photo.qml b/qml/Pages/RoomElement/Photo.qml index 782ca637..f44cd12a 100644 --- a/qml/Pages/RoomElement/Photo.qml +++ b/qml/Pages/RoomElement/Photo.qml @@ -20,6 +20,7 @@ Item { property alias handcards: handcardAreaItem.length property int maxHp: 0 property int hp: 0 + property int shield: 0 property int seatNumber: 1 property bool dead: false property bool dying: false @@ -150,6 +151,7 @@ Item { x: 8 value: root.hp maxValue: root.maxHp + shieldNum: root.shield anchors.bottom: parent.bottom anchors.bottomMargin: 36 } diff --git a/qml/Pages/RoomElement/PhotoElement/HpBar.qml b/qml/Pages/RoomElement/PhotoElement/HpBar.qml index 1a9ec896..e011ea02 100644 --- a/qml/Pages/RoomElement/PhotoElement/HpBar.qml +++ b/qml/Pages/RoomElement/PhotoElement/HpBar.qml @@ -2,23 +2,31 @@ import QtQuick import ".." +import "../../skin-bank.js" as SkinBank Column { id: root property int maxValue: 4 property int value: 4 property var colors: ["#F4180E", "#F4180E", "#E3B006", "#25EC27"] + property int shieldNum: 0 + + Shield { + id: shield + value: shieldNum + } Repeater { id: repeater - model: maxValue <= 4 ? maxValue : 0 + model: column.visible ? 0 : maxValue Magatama { state: (maxValue - 1 - index) >= value ? 0 : (value >= 3 || value >= maxValue ? 3 : (value <= 0 ? 0 : value)) } } Column { - visible: maxValue > 4 + id: column + visible: maxValue > 4 || value > maxValue || (shieldNum > 0 && maxValue > 3) spacing: -4 Magatama { @@ -43,11 +51,15 @@ Column { GlowText { id: splitter + height: 12 width: root.width text: "/" z: -10 + rotation: 40 color: hpItem.color - font: hpItem.font + font.family: fontLibian.name + font.pixelSize: 14 + font.bold: true horizontalAlignment: hpItem.horizontalAlignment glow.color: hpItem.glow.color diff --git a/qml/Pages/RoomElement/PhotoElement/Shield.qml b/qml/Pages/RoomElement/PhotoElement/Shield.qml new file mode 100644 index 00000000..75c2c8c3 --- /dev/null +++ b/qml/Pages/RoomElement/PhotoElement/Shield.qml @@ -0,0 +1,22 @@ +import QtQuick +import "../../skin-bank.js" as SkinBank + +Image { + id: root + property int value: 0 + width: 20 + height: 21 + visible: (value > 0) + source: SkinBank.MAGATAMA_DIR + "shield" + + Text { + text: value + anchors.horizontalCenter: parent.horizontalCenter + y: -2 + font.family: fontLibian.name + font.pixelSize: 20 + font.bold: true + color: "white" + style: Text.Outline + } +}