From 3dc95ebc49cd29ce5d8955c6bd4475026ba1147e Mon Sep 17 00:00:00 2001 From: Notify-ctrl <70358032+Notify-ctrl@users.noreply.github.com> Date: Fri, 25 Mar 2022 12:28:07 +0800 Subject: [PATCH] Gamecore (#3) * create some class * create some base classes * fixup Co-authored-by: Ho-spair --- lua/client/clientplayer.lua | 1 + lua/core/card.lua | 71 +++++++++++++++---------------------- lua/core/engine.lua | 65 +++++++++++++++++++++++++++++++++ lua/core/general.lua | 19 ++++++++++ lua/core/player.lua | 27 ++++++++++++++ lua/core/skill.lua | 32 +++++++++++++++++ lua/freekill.lua | 14 ++++++-- lua/server/event.lua | 16 +++++++++ lua/server/gamelogic.lua | 23 ++++++++++++ lua/server/room.lua | 18 ++++++++++ lua/server/server.lua | 10 +++++- lua/server/serverplayer.lua | 1 + lua/util.lua | 26 ++++++++++++++ 13 files changed, 276 insertions(+), 47 deletions(-) create mode 100644 lua/client/clientplayer.lua create mode 100644 lua/core/engine.lua create mode 100644 lua/core/general.lua create mode 100644 lua/core/player.lua create mode 100644 lua/core/skill.lua create mode 100644 lua/server/event.lua create mode 100644 lua/server/gamelogic.lua create mode 100644 lua/server/room.lua create mode 100644 lua/server/serverplayer.lua create mode 100644 lua/util.lua diff --git a/lua/client/clientplayer.lua b/lua/client/clientplayer.lua new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/lua/client/clientplayer.lua @@ -0,0 +1 @@ + diff --git a/lua/core/card.lua b/lua/core/card.lua index 31e9bc11..408829b0 100644 --- a/lua/core/card.lua +++ b/lua/core/card.lua @@ -1,52 +1,37 @@ --- class Card : public Object -local Card = class('Card') - --- public: - --- enum Suit -Card.Suit = { - Spade = 0, - Club = 1, - Heart = 2, - Diamond = 3, - NoSuitBlack = 4, - NoSuitRed = 5, - NoSuit = 6, - SuitToBeDecided = -1, +local SUITS = { + "Spade", + "Club", + "Diamond", + "Heart", + "NonSuit", } --- enum Color -Card.Color = { - Red = 0, - Black = 1, - Colorless = 2, +CardSuit = Util:createEnum(SUITS) + +local COLOR = { + "Red", + "Black", + "NonColor", } --- enum HandlingMethod -Card.HandlingMethod = { - MethodNone = 0, - MethodUse = 1, - MethodResponse = 2, - MethodDiscard = 3, - MethodRecast = 4, - MethodPindian = 5, -} -function Card:initialize(suit, number) +CardColor = Util:createEnum(COLOR) +local Card = class("Card") + +function Card:initialize(name, suit, cardNumber) + self.name = name + self.suit = suit + self.cardNumber = cardNumber end --- private: -local subcards = {} -- array of cards -local target_fixed -local mute -local will_throw -local has_preact -local can_recast -local m_suit -local m_number -local id -local skill_name -local handling_method -local flags = {} +function Card:getColor() + if self.suit == CardSuit.Spade or self.suit == CardSuit.Club then + return CardColor.Red + elseif self.suit == CardSuit.Diamond or self.suit == CardSuit.Heart then + return CardColor.Black + else + return CardColor.NonColor + end +end return Card diff --git a/lua/core/engine.lua b/lua/core/engine.lua new file mode 100644 index 00000000..86ecb09a --- /dev/null +++ b/lua/core/engine.lua @@ -0,0 +1,65 @@ +local Sanguosha = class("Engine") + +function Sanguosha:initialize() + self.skills = {} + self.generals = {} + self.cards = {} +end + +function Sanguosha:addSkill(skill) + table.insert(self.skills, skill) +end + +function Sanguosha:addGeneral(general) + table.insert(self.generals, general) +end + +function Sanguosha:addCard(card) + table.insert(self.cards, cards) +end + +function Sanguosha:getGeneralsRandomly(num, generalPool, except, filter) + if filter then + assert(type(filter) == "function") + end + + generalPool = generalPool or self.generals + except = except or {} + + local availableGenerals = {} + for _, general in ipairs(generalPool) do + if not table.contains(except, general) and not (filter and filter(general)) then + table.insert(availableGenerals, general) + end + end + + if #availableGenerals == 0 then + return {} + end + + local result = {} + while num > 0 do + local randomGeneral = math.random(1, #availableGenerals) + table.insert(result, randomGeneral) + table.remove(availableGenerals, randomGeneral) + + if #availableGenerals == 0 then + break + end + end + + return result +end + +function Sanguosha:getAllGenerals(except) + local result = {} + for _, general in ipairs(self.generals) do + if not (except and table.contains(except, general)) then + table.insert(result, general) + end + end + + return result +end + +return Sanguosha diff --git a/lua/core/general.lua b/lua/core/general.lua new file mode 100644 index 00000000..070bece8 --- /dev/null +++ b/lua/core/general.lua @@ -0,0 +1,19 @@ +General = class("General") + +function General:initialize(package, name, kingdom, hp, maxHp, gender, initialHp) + self.package = package + self.name = name + self.kingdom = kingdom + self.hp = hp + self.maxHp = maxHp + self.gender = gender + self.initialHp = initialHp or maxHp + + self.skills = {} +end + +function General:addSkill(skill) + table.insert(self.skills, skill) +end + +return General diff --git a/lua/core/player.lua b/lua/core/player.lua new file mode 100644 index 00000000..fdf2380c --- /dev/null +++ b/lua/core/player.lua @@ -0,0 +1,27 @@ +local Player = class("Skill") + +function Player:initialize() + self.hp = nil + self.maxHp = nil + self.general = nil + self.dying = false + self.dead = false + self.playerSkills = {} +end + +function Player:setGeneral(general, setHp, addSkills) + self.general = general + if setHp then + self.maxHp = general.maxHp + self.hp = general.initialHp + end + + if addSkills then + table.insertTable(self.playerSkills, general.skills) + end +end + +function Player:setHp(maxHp, initialHp) + self.maxHp = maxHp + self.hp = initialHp or maxHp +end diff --git a/lua/core/skill.lua b/lua/core/skill.lua new file mode 100644 index 00000000..0f393a20 --- /dev/null +++ b/lua/core/skill.lua @@ -0,0 +1,32 @@ +local SKILL_TYPE = { + "Common", + "Frequent", + "Compulsory", + "Awaken", + "Limit", + "Lord", +} + +SkillType = Util:createEnum(SKILL_TYPE) + +local Skill = class("Skill") + +function Skill:initialize(name, skillType) + self.name = name + self.description = ":" .. name + self.skillType = skillType +end + +local TriggerSkill = class("TriggerSkill", Skill) + +function TriggerSkill:initialize(spec) + Skill.initialize(self, spec.name, spec.skillType) + self.isRefreshAt = spec.isRefreshAt + self.isTriggerable = spec.isTriggerable + self.targetFilter = spec.targetFilter + self.cardFilter = spec.cardFilter + self.beforeTrigger = spec.beforeTrigger + self.onTrigger = spec.onTrigger +end + +return Skill diff --git a/lua/freekill.lua b/lua/freekill.lua index b63b2588..a262b832 100644 --- a/lua/freekill.lua +++ b/lua/freekill.lua @@ -1,11 +1,13 @@ -- Fundemental script for FreeKill -- Load mods, init the engine, etc. -package.path = package.path .. ';./lua/lib/?.lua' +package.path = package.path .. ";./lua/lib/?.lua" + .. ";./lua/core/?.lua" -- load libraries -class = require 'middleclass' -json = require 'json' +class = require "middleclass" +json = require "json" +Util = require "util" DebugMode = true @@ -16,3 +18,9 @@ function pt(t) end -- load core classes +Sanguosha = require "engine" +General = require "general" +Card = require "card" +Skill = require "skill" + +-- load packages diff --git a/lua/server/event.lua b/lua/server/event.lua new file mode 100644 index 00000000..23e6e73e --- /dev/null +++ b/lua/server/event.lua @@ -0,0 +1,16 @@ +local EVENTS = { + "GameStart", + + "PhaseChanging", + "PhaseStart", + "PhaseProceeding", + "PhaseEnd", + + "PreCardUse", + "AfterCardUseDeclared", + "AfterCardTargetDeclared", + "CardUsing", + "CardUseFinished", +} + +GameEvent = Util:createEnum(EVENTS) diff --git a/lua/server/gamelogic.lua b/lua/server/gamelogic.lua new file mode 100644 index 00000000..9b4345c9 --- /dev/null +++ b/lua/server/gamelogic.lua @@ -0,0 +1,23 @@ +function logic() + chooseGeneral() + initSkillList() + actionNormal() +end + +function chooseGeneral() + for _, p in ipairs(room:getPlayers()) do + local g = p:askForGeneral() + room:changeHero(p, g) + end +end + +function actionNormal() + local p = room:getLord() + while true do + room:setCurrent(p) + act(room:getCurrent) + p = p:getNextAlive() + end +end + +function trigger() end diff --git a/lua/server/room.lua b/lua/server/room.lua new file mode 100644 index 00000000..186e38e8 --- /dev/null +++ b/lua/server/room.lua @@ -0,0 +1,18 @@ +Room = class("Room") + +-- Just same as "static int roomId" in cpp +-- However id 0 is for lobby, so we start at 1 +local roomId = 1 + +function Room:initialize() + self.id = roomId + roomId = roomId + 1 + self.room = ServerInstace:findRoom(self.id) +end + +function Room:getCProperties() + self.name = self.room:getName() + self.capacity = self.room:getCapacity() +end + +return Room diff --git a/lua/server/server.lua b/lua/server/server.lua index e2c8e6e8..9b0da680 100644 --- a/lua/server/server.lua +++ b/lua/server/server.lua @@ -1,4 +1,4 @@ -local Server = class('Server') +local Server = class("Server") freekill.server_callback = {} @@ -12,6 +12,13 @@ function Server:initialize() print("Server error: Unknown command " .. command); end end + + self.rooms = {} -- hashtable: uid --> room + self.players = {} -- hashtable: uid --> splayer +end + +function Server:createRoom(owner, roomName, capacity) + end freekill.server_callback["CreateRoom"] = function(jsonData) @@ -21,6 +28,7 @@ freekill.server_callback["CreateRoom"] = function(jsonData) local roomName = data[2] local capacity = data[3] freekill.ServerInstance:createRoom(owner, roomName, capacity) + ServerInstance:createRoom() end freekill.server_callback["EnterRoom"] = function(jsonData) diff --git a/lua/server/serverplayer.lua b/lua/server/serverplayer.lua new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/lua/server/serverplayer.lua @@ -0,0 +1 @@ + diff --git a/lua/util.lua b/lua/util.lua new file mode 100644 index 00000000..10342124 --- /dev/null +++ b/lua/util.lua @@ -0,0 +1,26 @@ +function table:contains(element) + if #self == 0 or type(self[1]) ~= type(element) then return false end + for _, e in ipairs(self) do + if e == element then return true end + end +end + +function table:insertTable(list) + for _, e in ipairs(list) do + table.insert(self, e) + end +end + +local Util = class("Util") + +function Util.static:createEnum(tbl, index) + assert(type(tbl) == "table") + local enumtbl = {} + local enumindex = index or 0 + for i, v in ipairs(tbl) do + enumtbl[v] = enumindex + i + end + return enumtbl +end + +return Util