Distance skill (#37)

* global distance skill

* normal distance skill

* remove addGeneral from init.lua

* fixed distance
This commit is contained in:
notify 2023-01-04 14:21:29 +08:00 committed by GitHub
parent 9de041e969
commit 509cf29175
14 changed files with 131 additions and 46 deletions

View File

@ -4,6 +4,7 @@
---@field alive_players ClientPlayer[]
---@field current ClientPlayer
---@field discard_pile integer[]
---@field status_skills Skill[]
Client = class('Client')
-- load client classes
@ -28,6 +29,10 @@ function Client:initialize()
self.players = {} -- ClientPlayer[]
self.alive_players = {}
self.discard_pile = {}
self.status_skills = {}
for class, skills in pairs(Fk.global_status_skill) do
self.status_skills[class] = {table.unpack(skills)}
end
end
---@param id integer

View File

@ -12,19 +12,4 @@ function ClientPlayer:initialize(cp)
self.global_known_cards = {} -- card that visible to all players
end
---@param skill Skill
function ClientPlayer:hasSkill(skill)
return table.contains(self.player_skills, skill)
end
---@param skill Skill
function ClientPlayer:addSkill(skill)
table.insert(self.player_skills, skill)
end
---@param skill Skill
function ClientPlayer:loseSkill(skill)
table.removeOne(self.player_skills, skill)
end
return ClientPlayer

View File

@ -4,6 +4,7 @@
---@field skills table<string, Skill>
---@field related_skills table<string, Skill[]>
---@field global_trigger TriggerSkill[]
---@field global_status_skill table<class, Skill[]>
---@field generals table<string, General>
---@field lords string[]
---@field cards Card[]
@ -24,6 +25,7 @@ function Engine:initialize()
self.skills = {} -- name --> Skill
self.related_skills = {} -- skillName --> relatedSkill[]
self.global_trigger = {}
self.global_status_skill = {}
self.generals = {} -- name --> General
self.lords = {} -- lordName[]
self.cards = {} -- Card[]
@ -97,6 +99,16 @@ function Engine:addSkill(skill)
error(string.format("Duplicate skill %s detected", skill.name))
end
self.skills[skill.name] = skill
if skill.global then
if skill:isInstanceOf(TriggerSkill) then
table.insert(self.global_trigger, skill)
else
local t = self.global_status_skill
t[skill.class] = t[skill.class] or {}
table.insert(t[skill.class], skill)
end
end
end
---@param skills Skill[]

View File

@ -24,6 +24,8 @@ function General:initialize(package, name, kingdom, hp, maxHp, gender)
self.skills = {} -- skills first added to this general
self.other_skills = {} -- skill belongs other general, e.g. "mashu" of pangde
package:addGeneral(self)
end
---@param skill Skill

View File

@ -41,7 +41,7 @@ end
---@param general General
function Package:addGeneral(general)
assert(general.class and general:isInstanceOf(General))
table.insert(self.generals, general)
table.insertIfNeed(self.generals, general)
end
---@param card Card

View File

@ -22,6 +22,7 @@
---@field player_cards table<integer, integer[]>
---@field special_cards table<string, integer[]>
---@field cardUsedHistory table<string, integer>
---@field fixedDistance table<Player, integer>
local Player = class("Player")
---@alias Phase integer
@ -72,6 +73,7 @@ function Player:initialize()
self.special_cards = {}
self.cardUsedHistory = {}
self.fixedDistance = {}
end
---@param general General
@ -226,6 +228,17 @@ function Player:getAttackRange()
return math.max(baseAttackRange, 0)
end
---@param other Player
---@param num integer
function Player:setFixedDistance(other, num)
self.fixedDistance[other] = num
end
---@param other Player
function Player:removeFixedDistance(other)
self.fixedDistance[other] = nil
end
---@param other Player
function Player:distanceTo(other)
assert(other:isInstanceOf(Player))
@ -239,7 +252,17 @@ function Player:distanceTo(other)
end
local left = #Fk:currentRoom().alive_players - right
local ret = math.min(left, right)
-- TODO: corrent distance here using skills
local status_skills = Fk:currentRoom().status_skills[DistanceSkill] or {}
for _, skill in ipairs(status_skills) do
local correct = skill:getCorrect(self, other)
ret = ret + correct
end
if self.fixedDistance[other] then
ret = self.fixedDistance[other]
end
return math.max(ret, 1)
end
@ -334,12 +357,21 @@ end
function Player:addSkill(skill, source_skill)
skill = getActualSkill(skill)
local toget = table.clone(skill.related_skills)
local toget = {table.unpack(skill.related_skills)}
table.insert(toget, skill)
local room = Fk:currentRoom()
local ret = {}
for _, s in ipairs(toget) do
if not self:hasSkill(s) then
table.insert(ret, s)
if skill:isInstanceOf(TriggerSkill) and RoomInstance then
room.logic:addTriggerSkill(skill)
end
if table.contains(StatusSkills, skill.class) then
room.status_skills[skill.class] = room.status_skills[skill.class] or {}
table.insertIfNeed(room.status_skills[skill.class], skill)
end
end
end

View File

@ -0,0 +1,18 @@
---@class DistanceSkill : Skill
---@field global boolean
local DistanceSkill = Skill:subclass("DistanceSkill")
function DistanceSkill:initialize(name)
Skill.initialize(self, name, Skill.NotFrequent)
self.global = false
end
---@param from Player
---@param to Player
---@return integer
function DistanceSkill:getCorrect(from, to)
return 0
end
return DistanceSkill

View File

@ -10,7 +10,7 @@ function fk.qlist(list)
end
function table:contains(element)
if #self == 0 or type(self[1]) ~= type(element) then return false end
if #self == 0 then return false end
for _, e in ipairs(self) do
if e == element then return true end
end

View File

@ -4,6 +4,10 @@ dofile "lua/server/event.lua"
dofile "lua/server/system_enum.lua"
TriggerSkill = require "core.skill_type.trigger"
ActiveSkill = require "core.skill_type.active_skill"
DistanceSkill = require "core.skill_type.distance"
StatusSkills = {
DistanceSkill,
}
BasicCard = require "core.card_type.basic"
local Trick = require "core.card_type.trick"
@ -107,6 +111,25 @@ function fk.CreateActiveSkill(spec)
return skill
end
---@class DistanceSpec: SkillSpec
---@field correct_func fun(self: DistanceSkill, from: Player, to: Player)
---@field global boolean
---@param spec DistanceSpec
---@return DistanceSkill
function fk.CreateDistanceSkill(spec)
assert(type(spec.name) == "string")
assert(type(spec.correct_func) == "function")
local skill = DistanceSkill:new(spec.name)
skill.getCorrect = spec.correct_func
if spec.global then
skill.global = spec.global
end
return skill
end
---@class CardSpec: Card
---@field skill Skill

View File

@ -135,7 +135,7 @@ function GameLogic:prepareForStart()
end
for _, p in ipairs(room.alive_players) do
room:handleAddLoseSkills(p, "zhiheng", nil, false)
room:handleAddLoseSkills(p, "zhiheng|mashu", nil, false)
end
self:addTriggerSkill(GameRule)

View File

@ -12,6 +12,7 @@
---@field void integer[]
---@field card_place table<integer, CardArea>
---@field owner_map table<integer, integer>
---@field status_skills Skill[]
local Room = class("Room")
-- load classes used by the game
@ -71,6 +72,10 @@ function Room:initialize(_room)
self.void = {}
self.card_place = {}
self.owner_map = {}
self.status_skills = {}
for class, skills in pairs(Fk.global_status_skill) do
self.status_skills[class] = {table.unpack(skills)}
end
end
-- When this function returns, the Room(C++) thread stopped.

View File

@ -12,85 +12,81 @@ Fk:loadTranslationTable{
}
local caocao = General:new(extension, "caocao", "wei", 4)
extension:addGeneral(caocao)
Fk:loadTranslationTable{
["caocao"] = "曹操",
}
local simayi = General:new(extension, "simayi", "wei", 3)
extension:addGeneral(simayi)
Fk:loadTranslationTable{
["simayi"] = "司马懿",
}
local xiahoudun = General:new(extension, "xiahoudun", "wei", 4)
extension:addGeneral(xiahoudun)
Fk:loadTranslationTable{
["xiahoudun"] = "夏侯惇",
}
local zhangliao = General:new(extension, "zhangliao", "wei", 4)
extension:addGeneral(zhangliao)
Fk:loadTranslationTable{
["zhangliao"] = "张辽",
}
local xuchu = General:new(extension, "xuchu", "wei", 4)
extension:addGeneral(xuchu)
Fk:loadTranslationTable{
["xuchu"] = "许褚",
}
local guojia = General:new(extension, "guojia", "wei", 3)
extension:addGeneral(guojia)
Fk:loadTranslationTable{
["guojia"] = "郭嘉",
}
local zhenji = General:new(extension, "zhenji", "wei", 3)
extension:addGeneral(zhenji)
Fk:loadTranslationTable{
["zhenji"] = "甄姬",
}
local liubei = General:new(extension, "liubei", "shu", 4)
extension:addGeneral(liubei)
Fk:loadTranslationTable{
["liubei"] = "刘备",
}
local guanyu = General:new(extension, "guanyu", "shu", 4)
extension:addGeneral(guanyu)
Fk:loadTranslationTable{
["guanyu"] = "关羽",
}
local zhangfei = General:new(extension, "zhangfei", "shu", 4)
extension:addGeneral(zhangfei)
Fk:loadTranslationTable{
["zhangfei"] = "张飞",
}
local zhugeliang = General:new(extension, "zhugeliang", "shu", 3)
extension:addGeneral(zhugeliang)
Fk:loadTranslationTable{
["zhugeliang"] = "诸葛亮",
}
local zhaoyun = General:new(extension, "zhaoyun", "shu", 4)
extension:addGeneral(zhaoyun)
Fk:loadTranslationTable{
["zhaoyun"] = "赵云",
}
local mashu = fk.CreateDistanceSkill{
name = "mashu",
correct_func = function(self, from, to)
if from:hasSkill(self.name) then
return -1
end
end,
}
local machao = General:new(extension, "machao", "shu", 4)
extension:addGeneral(machao)
machao:addSkill(mashu)
Fk:loadTranslationTable{
["machao"] = "马超",
["mashu"] = "马术",
}
local huangyueying = General:new(extension, "huangyueying", "shu", 3)
extension:addGeneral(huangyueying)
Fk:loadTranslationTable{
["huangyueying"] = "黄月英",
}
@ -108,68 +104,57 @@ local zhiheng = fk.CreateActiveSkill{
}
local sunquan = General:new(extension, "sunquan", "wu", 4)
sunquan:addSkill(zhiheng)
extension:addGeneral(sunquan)
Fk:loadTranslationTable{
["sunquan"] = "孙权",
["zhiheng"] = "制衡",
}
local ganning = General:new(extension, "ganning", "wu", 4)
extension:addGeneral(ganning)
Fk:loadTranslationTable{
["ganning"] = "甘宁",
}
local lvmeng = General:new(extension, "lvmeng", "wu", 4)
extension:addGeneral(lvmeng)
Fk:loadTranslationTable{
["lvmeng"] = "吕蒙",
}
local huanggai = General:new(extension, "huanggai", "wu", 4)
extension:addGeneral(huanggai)
Fk:loadTranslationTable{
["huanggai"] = "黄盖",
}
local zhouyu = General:new(extension, "zhouyu", "wu", 3)
extension:addGeneral(zhouyu)
Fk:loadTranslationTable{
["zhouyu"] = "周瑜",
}
local daqiao = General:new(extension, "daqiao", "wu", 3)
extension:addGeneral(daqiao)
Fk:loadTranslationTable{
["daqiao"] = "大乔",
}
local luxun = General:new(extension, "luxun", "wu", 3)
extension:addGeneral(luxun)
Fk:loadTranslationTable{
["luxun"] = "陆逊",
}
local sunshangxiang = General:new(extension, "sunshangxiang", "wu", 3)
extension:addGeneral(sunshangxiang)
Fk:loadTranslationTable{
["sunshangxiang"] = "孙尚香",
}
local huatuo = General:new(extension, "huatuo", "qun", 3)
extension:addGeneral(huatuo)
Fk:loadTranslationTable{
["huatuo"] = "华佗",
}
local lvbu = General:new(extension, "lvbu", "qun", 4)
extension:addGeneral(lvbu)
Fk:loadTranslationTable{
["lvbu"] = "吕布",
}
local diaochan = General:new(extension, "diaochan", "qun", 3)
extension:addGeneral(diaochan)
Fk:loadTranslationTable{
["diaochan"] = "貂蝉",
}

View File

@ -862,6 +862,24 @@ extension:addCards({
niohShield,
})
local horseSkill = fk.CreateDistanceSkill{
name = "horse_skill",
global = true,
correct_func = function(self, from, to)
local ret = 0
if from:getEquipment(Card.SubtypeOffensiveRide) then
ret = ret - 1
end
if to:getEquipment(Card.SubtypeDefensiveRide) then
ret = ret + 1
end
return ret
end,
}
if not Fk.skills["horse_skill"] then
Fk:addSkill(horseSkill)
end
local diLu = fk.CreateDefensiveRide{
name = "dilu",
suit = Card.Club,

View File

@ -71,7 +71,7 @@ Flickable {
"GetSkillData",
[skill_name]
));
if (data.freq = "active") {
if (data.freq === "active") {
active_skills.append(data);
} else {
not_active_skills.append(data);