mirror of
https://github.com/Qsgs-Fans/FreeKill.git
synced 2024-11-15 19:22:25 +08:00
parent
a51806f902
commit
b0c2855389
|
@ -133,6 +133,16 @@ function GetAllPiles(id)
|
|||
return json.encode(ClientInstance:getPlayerById(id).special_cards or {})
|
||||
end
|
||||
|
||||
function GetPlayerSkills(id)
|
||||
local p = ClientInstance:getPlayerById(id)
|
||||
return json.encode(table.map(p.player_skills, function(s)
|
||||
return s.visible and {
|
||||
name = s.name,
|
||||
description = Fk:getDescription(s.name),
|
||||
} or nil
|
||||
end))
|
||||
end
|
||||
|
||||
---@param card string | integer
|
||||
---@param player integer
|
||||
function CanUseCard(card, player)
|
||||
|
|
|
@ -117,6 +117,10 @@ function Card:initialize(name, suit, number, color)
|
|||
setmetatable(self, mt)
|
||||
end
|
||||
|
||||
function Card:__tostring()
|
||||
return string.format("%s[%s %d]", self.name, self:getSuitString(), self.number)
|
||||
end
|
||||
|
||||
--- 克隆特定卡牌并赋予花色与点数。
|
||||
---
|
||||
--- 会将skill/special_skills/equip_skill继承到克隆牌中。
|
||||
|
|
|
@ -93,6 +93,10 @@ function Player:initialize()
|
|||
self.fixedDistance = {}
|
||||
end
|
||||
|
||||
function Player:__tostring()
|
||||
return string.format("%s #%d", self.id < 0 and "Bot" or "Player", math.abs(self.id))
|
||||
end
|
||||
|
||||
--- 设置角色、体力、技能。
|
||||
---@param general General @ 角色类型
|
||||
---@param setHp boolean @ 是否设置体力
|
||||
|
|
|
@ -70,7 +70,7 @@ end
|
|||
---@return boolean @ returns true if trigger is broken
|
||||
function TriggerSkill:cost(event, target, player, data)
|
||||
local ret = false
|
||||
if self.frequency == Skill.Compulsory then
|
||||
if self.frequency == Skill.Compulsory or self.frequency == Skill.Wake then
|
||||
return true
|
||||
end
|
||||
|
||||
|
|
|
@ -131,6 +131,23 @@ function table.simpleClone(self)
|
|||
return ret
|
||||
end
|
||||
|
||||
-- similar to table.clone but convert all class/instances to string
|
||||
function table.cloneWithoutClass(self)
|
||||
local ret = {}
|
||||
for k, v in pairs(self) do
|
||||
if type(v) == "table" then
|
||||
if v.class or v.super then
|
||||
ret[k] = tostring(v)
|
||||
else
|
||||
ret[k] = table.cloneWithoutClass(v)
|
||||
end
|
||||
else
|
||||
ret[k] = v
|
||||
end
|
||||
end
|
||||
return ret
|
||||
end
|
||||
|
||||
-- if table does not contain the element, we insert it
|
||||
function table:insertIfNeed(element)
|
||||
if not table.contains(self, element) then
|
||||
|
|
|
@ -37,3 +37,25 @@ dofile "lua/server/events/pindian.lua"
|
|||
-- TODO: fix this
|
||||
GameEvent.BreakEvent = 999
|
||||
|
||||
local eventTranslations = {
|
||||
[GameEvent.ChangeHp] = "GameEvent.ChangeHp",
|
||||
[GameEvent.Damage] = "GameEvent.Damage",
|
||||
[GameEvent.LoseHp] = "GameEvent.LoseHp",
|
||||
[GameEvent.Recover] = "GameEvent.Recover",
|
||||
[GameEvent.ChangeMaxHp] = "GameEvent.ChangeMaxHp",
|
||||
[GameEvent.Dying] = "GameEvent.Dying",
|
||||
[GameEvent.Death] = "GameEvent.Death",
|
||||
[GameEvent.MoveCards] = "GameEvent.MoveCards",
|
||||
[GameEvent.UseCard] = "GameEvent.UseCard",
|
||||
[GameEvent.RespondCard] = "GameEvent.RespondCard",
|
||||
[GameEvent.SkillEffect] = "GameEvent.SkillEffect",
|
||||
[GameEvent.Judge] = "GameEvent.Judge",
|
||||
[GameEvent.DrawInitial] = "GameEvent.DrawInitial",
|
||||
[GameEvent.Round] = "GameEvent.Round",
|
||||
[GameEvent.Turn] = "GameEvent.Turn",
|
||||
[GameEvent.Pindian] = "GameEvent.Pindian",
|
||||
}
|
||||
|
||||
function GameEvent.static:translate(id)
|
||||
return eventTranslations[id]
|
||||
end
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
---@field public room Room
|
||||
---@field public event integer
|
||||
---@field public data any
|
||||
---@field public parent GameEvent
|
||||
---@field public main_func fun(self: GameEvent)
|
||||
---@field public clear_func fun(self: GameEvent)
|
||||
---@field public extra_clear_funcs any[]
|
||||
|
@ -27,6 +28,15 @@ function GameEvent:initialize(event, ...)
|
|||
self.interrupted = false
|
||||
end
|
||||
|
||||
function GameEvent:findParent(eventType)
|
||||
local e = self.parent
|
||||
repeat
|
||||
if e.event == eventType then return e end
|
||||
e = e.parent
|
||||
until not e
|
||||
return nil
|
||||
end
|
||||
|
||||
function GameEvent:clear()
|
||||
for _, f in ipairs(self.extra_clear_funcs) do
|
||||
if type(f) == "function" then f(self) end
|
||||
|
@ -39,6 +49,7 @@ function GameEvent:exec()
|
|||
local logic = room.logic
|
||||
local ret = false -- false or nil means this event is running normally
|
||||
local extra_ret
|
||||
self.parent = logic:getCurrentEvent()
|
||||
logic.game_event_stack:push(self)
|
||||
|
||||
local co = coroutine.create(self.main_func)
|
||||
|
|
|
@ -276,10 +276,45 @@ function GameLogic:trigger(event, target, data)
|
|||
return broken
|
||||
end
|
||||
|
||||
---@return GameEvent
|
||||
function GameLogic:getCurrentEvent()
|
||||
return self.game_event_stack.t[self.game_event_stack.p]
|
||||
end
|
||||
|
||||
function GameLogic:dumpEventStack(detailed)
|
||||
local top = self:getCurrentEvent()
|
||||
local i = self.game_event_stack.p
|
||||
local inspect = p
|
||||
if not top then return end
|
||||
|
||||
print("===== Start of event stack dump =====")
|
||||
if not detailed then print("") end
|
||||
|
||||
repeat
|
||||
local printable_data
|
||||
if type(top.data) ~= "table" then
|
||||
printable_data = top.data
|
||||
else
|
||||
printable_data = table.cloneWithoutClass(top.data)
|
||||
end
|
||||
|
||||
if not detailed then
|
||||
print("Stack level #" .. i .. ": " .. GameEvent:translate(top.event))
|
||||
else
|
||||
print("\nStack level #" .. i .. ":")
|
||||
inspect{
|
||||
eventId = GameEvent:translate(top.event),
|
||||
data = printable_data or "nil",
|
||||
}
|
||||
end
|
||||
|
||||
top = top.parent
|
||||
i = i - 1
|
||||
until not top
|
||||
|
||||
print("\n===== End of event stack dump =====")
|
||||
end
|
||||
|
||||
function GameLogic:breakEvent(ret)
|
||||
coroutine.yield("__breakEvent", ret)
|
||||
end
|
||||
|
|
|
@ -419,7 +419,7 @@ local silverLion = fk.CreateArmor{
|
|||
equip_skill = silverLionSkill,
|
||||
on_uninstall = function(self, room, player)
|
||||
Armor.onUninstall(self, room, player)
|
||||
if player:isWounded() and self.equip_skill:isEffectable(player) then
|
||||
if player:isAlive() and player:isWounded() and self.equip_skill:isEffectable(player) then
|
||||
room:broadcastPlaySound("./packages/maneuvering/audio/card/silver_lion")
|
||||
room:setEmotion(player, "./packages/maneuvering/image/anim/silver_lion")
|
||||
room:recover{
|
||||
|
|
|
@ -167,6 +167,7 @@ Item {
|
|||
|
||||
DragHandler {
|
||||
enabled: draggable
|
||||
grabPermissions: PointHandler.TakeOverForbidden
|
||||
xAxis.enabled: true
|
||||
yAxis.enabled: true
|
||||
|
||||
|
|
53
qml/Pages/RoomElement/Cheat/PlayerDetail.qml
Normal file
53
qml/Pages/RoomElement/Cheat/PlayerDetail.qml
Normal file
|
@ -0,0 +1,53 @@
|
|||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
Flickable {
|
||||
id: root
|
||||
anchors.fill: parent
|
||||
property var extra_data: ({})
|
||||
|
||||
signal finish()
|
||||
|
||||
contentHeight: details.height
|
||||
ScrollBar.vertical: ScrollBar {}
|
||||
|
||||
ColumnLayout {
|
||||
id: details
|
||||
width: parent.width - 16
|
||||
|
||||
// TODO: player details
|
||||
Text {
|
||||
id: screenName
|
||||
Layout.fillWidth: true
|
||||
font.pixelSize: 18
|
||||
}
|
||||
|
||||
TextEdit {
|
||||
id: skillDesc
|
||||
|
||||
Layout.fillWidth: true
|
||||
font.pixelSize: 18
|
||||
|
||||
readOnly: true
|
||||
selectByKeyboard: true
|
||||
selectByMouse: false
|
||||
wrapMode: TextEdit.WordWrap
|
||||
textFormat: TextEdit.RichText
|
||||
}
|
||||
}
|
||||
|
||||
onExtra_dataChanged: {
|
||||
if (!extra_data.photo) return;
|
||||
screenName.text = "";
|
||||
skillDesc.text = "";
|
||||
|
||||
let id = extra_data.photo.playerid;
|
||||
if (id == 0) return;
|
||||
|
||||
let data = JSON.parse(Backend.callLuaFunction("GetPlayerSkills", [id]));
|
||||
data.forEach(t => {
|
||||
skillDesc.append("<b>" + Backend.translate(t.name) + "</b>: " + t.description)
|
||||
});
|
||||
}
|
||||
}
|
|
@ -28,6 +28,7 @@ Item {
|
|||
}
|
||||
|
||||
DragHandler {
|
||||
grabPermissions: PointHandler.TakeOverForbidden
|
||||
xAxis.enabled: true
|
||||
yAxis.enabled: true
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ Item {
|
|||
width: 175
|
||||
height: 233
|
||||
scale: 0.75
|
||||
property int playerid
|
||||
property int playerid: 0
|
||||
property string general: ""
|
||||
property string screenName: ""
|
||||
property string role: "unknown"
|
||||
|
@ -319,11 +319,22 @@ Item {
|
|||
}
|
||||
|
||||
TapHandler {
|
||||
onTapped: {
|
||||
if (parent.state != "candidate" || !parent.selectable) {
|
||||
return;
|
||||
acceptedButtons: Qt.LeftButton | Qt.RightButton | Qt.NoButton
|
||||
gesturePolicy: TapHandler.WithinBounds
|
||||
|
||||
onTapped: (p, btn) => {
|
||||
if (btn === Qt.LeftButton || btn === Qt.NoButton) {
|
||||
if (parent.state != "candidate" || !parent.selectable) {
|
||||
return;
|
||||
}
|
||||
parent.selected = !parent.selected;
|
||||
} else if (btn === Qt.RightButton) {
|
||||
parent.showDetail();
|
||||
}
|
||||
parent.selected = !parent.selected;
|
||||
}
|
||||
|
||||
onLongPressed: {
|
||||
parent.showDetail();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -538,4 +549,8 @@ Item {
|
|||
function updateLimitSkill(skill, time) {
|
||||
limitSkills.update(skill, time);
|
||||
}
|
||||
|
||||
function showDetail() {
|
||||
roomScene.startCheat("RoomElement/Cheat/PlayerDetail.qml", { photo: this });
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user