jxg;
This commit is contained in:
commit
c99e200301
|
@ -747,6 +747,26 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
// manualBox: same as popupBox, but must be closed manually
|
||||
Loader {
|
||||
id: manualBox
|
||||
z: 999
|
||||
onSourceChanged: {
|
||||
if (item === null)
|
||||
return;
|
||||
item.finished.connect(() => sourceComponent = undefined);
|
||||
item.widthChanged.connect(() => manualBox.moveToCenter());
|
||||
item.heightChanged.connect(() => manualBox.moveToCenter());
|
||||
moveToCenter();
|
||||
}
|
||||
onSourceComponentChanged: sourceChanged();
|
||||
|
||||
function moveToCenter() {
|
||||
item.x = Math.round((roomArea.width - item.width) / 2);
|
||||
item.y = Math.round(roomArea.height * 0.67 - item.height / 2);
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: popupBox
|
||||
z: 999
|
||||
|
@ -772,27 +792,6 @@ Item {
|
|||
}
|
||||
}
|
||||
|
||||
// manualBox: same as popupBox, but must be closed manually
|
||||
Loader {
|
||||
id: manualBox
|
||||
z: 999
|
||||
onSourceChanged: {
|
||||
if (item === null)
|
||||
return;
|
||||
item.finished.connect(() => sourceComponent = undefined);
|
||||
item.widthChanged.connect(() => manualBox.moveToCenter());
|
||||
item.heightChanged.connect(() => manualBox.moveToCenter());
|
||||
moveToCenter();
|
||||
}
|
||||
onSourceComponentChanged: sourceChanged();
|
||||
|
||||
function moveToCenter()
|
||||
{
|
||||
item.x = Math.round((roomArea.width - item.width) / 2);
|
||||
item.y = Math.round(roomArea.height * 0.67 - item.height / 2);
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: bigAnim
|
||||
anchors.fill: parent
|
||||
|
|
|
@ -324,7 +324,7 @@ function CanUseCardToTarget(card, to_select, selected)
|
|||
local selected_cards
|
||||
if type(card) == "number" then
|
||||
c = Fk:getCardById(card)
|
||||
selected_cards = {card}
|
||||
selected_cards = { card }
|
||||
else
|
||||
local t = json.decode(card)
|
||||
return ActiveTargetFilter(t.skill, to_select, selected, t.subcards)
|
||||
|
@ -343,7 +343,7 @@ function CanSelectCardForSkill(card, to_select, selected_targets)
|
|||
local selected_cards
|
||||
if type(card) == "number" then
|
||||
c = Fk:getCardById(card)
|
||||
selected_cards = {card}
|
||||
selected_cards = { card }
|
||||
else
|
||||
error()
|
||||
end
|
||||
|
@ -359,7 +359,7 @@ function CardFeasible(card, selected_targets)
|
|||
local selected_cards
|
||||
if type(card) == "number" then
|
||||
c = Fk:getCardById(card)
|
||||
selected_cards = {card}
|
||||
selected_cards = { card }
|
||||
else
|
||||
local t = json.decode(card)
|
||||
return ActiveFeasible(t.skill, selected_targets, t.subcards)
|
||||
|
@ -637,8 +637,8 @@ function ResetClientLua()
|
|||
local data = ClientInstance.room_settings
|
||||
Self = ClientPlayer:new(fk.Self)
|
||||
ClientInstance = Client:new() -- clear old client data
|
||||
ClientInstance.players = {Self}
|
||||
ClientInstance.alive_players = {Self}
|
||||
ClientInstance.players = { Self }
|
||||
ClientInstance.alive_players = { Self }
|
||||
ClientInstance.discard_pile = {}
|
||||
|
||||
ClientInstance.enter_room_data = _data;
|
||||
|
@ -695,4 +695,54 @@ function SaveRecord()
|
|||
c.client:saveRecord(json.encode(c.record), c.record[2])
|
||||
end
|
||||
|
||||
function GetCardProhibitReason(cid, method, pattern)
|
||||
local card = Fk:getCardById(cid)
|
||||
if not card then return "" end
|
||||
if method == "play" and not card.skill:canUse(Self, card) then return "" end
|
||||
if method ~= "play" and not card:matchPattern(pattern) then return "" end
|
||||
if method == "play" then method = "use" end
|
||||
|
||||
local status_skills = Fk:currentRoom().status_skills[ProhibitSkill] or Util.DummyTable
|
||||
local s
|
||||
for _, skill in ipairs(status_skills) do
|
||||
local fn = method == "use" and skill.prohibitUse or skill.prohibitResponse
|
||||
if fn(skill, Self, card) then
|
||||
s = skill
|
||||
break
|
||||
end
|
||||
end
|
||||
if not s then return "" end
|
||||
|
||||
-- try to return a translated string
|
||||
local skillName = s.name
|
||||
local ret = Fk:translate(skillName)
|
||||
if ret ~= skillName then
|
||||
-- TODO: translate
|
||||
return ret .. "禁" .. (method == "use" and "使用" or "打出")
|
||||
elseif skillName:endsWith("_prohibit") and skillName:startsWith("#") then
|
||||
return Fk:translate(skillName:sub(2, -10)) .. "禁" .. (method == "use" and "使用" or "打出")
|
||||
else
|
||||
return ret
|
||||
end
|
||||
end
|
||||
|
||||
function PoxiPrompt(poxi_type, data)
|
||||
local poxi = Fk.poxi_methods[poxi_type]
|
||||
if not poxi or not poxi.prompt then return "" end
|
||||
if type(poxi.prompt) == "string" then return Fk:translate(poxi.prompt) end
|
||||
return poxi.prompt(data)
|
||||
end
|
||||
|
||||
function PoxiFilter(poxi_type, to_select, selected, data)
|
||||
local poxi = Fk.poxi_methods[poxi_type]
|
||||
if not poxi then return "false" end
|
||||
return json.encode(poxi.card_filter(to_select, selected, data))
|
||||
end
|
||||
|
||||
function PoxiFeasible(poxi_type, selected, data)
|
||||
local poxi = Fk.poxi_methods[poxi_type]
|
||||
if not poxi then return "false" end
|
||||
return json.encode(poxi.feasible(selected, data))
|
||||
end
|
||||
|
||||
dofile "lua/client/i18n/init.lua"
|
||||
|
|
|
@ -43,7 +43,7 @@ local function useActiveSkill(self, skill, card)
|
|||
avail_targets = table.map(avail_targets, function(p)
|
||||
return p.id
|
||||
end)
|
||||
local avail_cards = table.filter(player:getCardIds{Player.Hand, Player.Equip}, function(id)
|
||||
local avail_cards = table.filter(player:getCardIds { Player.Hand, Player.Equip }, function(id)
|
||||
return filter_func(skill, id, selected_cards, selected_targets)
|
||||
end)
|
||||
|
||||
|
@ -110,7 +110,7 @@ local function useVSSkill(self, skill, pattern, cancelable, extra_data)
|
|||
local max_try_time = 100
|
||||
|
||||
for _ = 0, max_try_time do
|
||||
local avail_cards = table.filter(player:getCardIds{Player.Hand, Player.Equip}, function(id)
|
||||
local avail_cards = table.filter(player:getCardIds { Player.Hand, Player.Equip }, function(id)
|
||||
return skill:cardFilter(id, selected_cards)
|
||||
end)
|
||||
if #avail_cards == 0 then
|
||||
|
@ -144,7 +144,7 @@ random_cb.AskForUseActiveSkill = function(self, jsonData)
|
|||
end
|
||||
|
||||
random_cb.AskForSkillInvoke = function(self, jsonData)
|
||||
return table.random {"1", ""}
|
||||
return table.random { "1", "" }
|
||||
end
|
||||
|
||||
random_cb.AskForUseCard = function(self, jsonData)
|
||||
|
@ -174,11 +174,11 @@ random_cb.AskForUseCard = function(self, jsonData)
|
|||
local min_card = skill:getMinCardNum()
|
||||
local max_card = skill:getMaxCardNum()
|
||||
for _ = 0, max_try_times do
|
||||
if skill:feasible(selected_targets, {card.id}, self.player, card) then
|
||||
if skill:feasible(selected_targets, { card.id }, self.player, card) then
|
||||
break
|
||||
end
|
||||
local avail_targets = table.filter(self.room:getAlivePlayers(), function(p)
|
||||
local ret = skill:targetFilter(p.id, selected_targets, {card}, card or Fk:cloneCard 'zixing')
|
||||
local ret = skill:targetFilter(p.id, selected_targets, { card }, card or Fk:cloneCard 'zixing')
|
||||
return ret
|
||||
end)
|
||||
avail_targets = table.map(avail_targets, function(p)
|
||||
|
@ -190,7 +190,7 @@ random_cb.AskForUseCard = function(self, jsonData)
|
|||
end
|
||||
table.insertIfNeed(selected_targets, table.random(avail_targets))
|
||||
end
|
||||
if skill:feasible(selected_targets, {card.id}, self.player, card) then
|
||||
if skill:feasible(selected_targets, { card.id }, self.player, card) then
|
||||
return json.encode {
|
||||
card = table.random(avail_cards),
|
||||
targets = selected_targets
|
||||
|
@ -207,7 +207,7 @@ random_cb.AskForResponseCard = function(self, jsonData)
|
|||
local pattern = data[2]
|
||||
local cancelable = true
|
||||
local exp = Exppattern:Parse(pattern)
|
||||
local avail_cards = table.filter(self.player:getCardIds{Player.Hand, Player.Equip}, function(id)
|
||||
local avail_cards = table.filter(self.player:getCardIds { Player.Hand, Player.Equip }, function(id)
|
||||
return exp:match(Fk:getCardById(id))
|
||||
end)
|
||||
if #avail_cards > 0 then
|
||||
|
|
|
@ -8,328 +8,6 @@ local trust_cb = {}
|
|||
function TrustAI:initialize(player)
|
||||
AI.initialize(self, player)
|
||||
self.cb_table = trust_cb
|
||||
<<<<<<< HEAD
|
||||
=======
|
||||
self.player = player
|
||||
self.room = RoomInstance or ClientInstance
|
||||
|
||||
fk.ai_role[player.id] = "neutral"
|
||||
fk.roleValue[player.id] = {
|
||||
lord = 0,
|
||||
loyalist = 0,
|
||||
rebel = 0,
|
||||
renegade = 0
|
||||
}
|
||||
self:updatePlayers()
|
||||
end
|
||||
|
||||
function TrustAI:isRolePredictable()
|
||||
return self.room.settings.gameMode ~= "aaa_role_mode"
|
||||
end
|
||||
|
||||
local function aliveRoles(room)
|
||||
fk.alive_roles = {
|
||||
lord = 0,
|
||||
loyalist = 0,
|
||||
rebel = 0,
|
||||
renegade = 0
|
||||
}
|
||||
for _, ap in ipairs(room:getAllPlayers(false)) do
|
||||
fk.alive_roles[ap.role] = 0
|
||||
end
|
||||
for _, ap in ipairs(room:getAlivePlayers(false)) do
|
||||
fk.alive_roles[ap.role] = fk.alive_roles[ap.role] + 1
|
||||
end
|
||||
return fk.alive_roles
|
||||
end
|
||||
|
||||
function TrustAI:objectiveLevel(to)
|
||||
if self.player.id == to.id then
|
||||
return -2
|
||||
elseif #self.room:getAlivePlayers(false) < 3 then
|
||||
return 5
|
||||
end
|
||||
local ars = aliveRoles(self.room)
|
||||
if self:isRolePredictable() then
|
||||
fk.ai_role[self.player.id] = self.role
|
||||
fk.roleValue[self.player.id][self.role] = 666
|
||||
if self.role == "renegade" then
|
||||
fk.explicit_renegade = true
|
||||
end
|
||||
for _, p in ipairs(self.room:getAlivePlayers()) do
|
||||
if
|
||||
p.role == self.role or p.role == "lord" and self.role == "loyalist" or
|
||||
p.role == "loyalist" and self.role == "lord"
|
||||
then
|
||||
table.insert(self.friends, p)
|
||||
if p.id ~= self.player.id then
|
||||
table.insert(self.friends_noself, p)
|
||||
end
|
||||
else
|
||||
table.insert(self.enemies, p)
|
||||
end
|
||||
end
|
||||
elseif self.role == "renegade" then
|
||||
if to.role == "lord" then
|
||||
return -1
|
||||
elseif ars.rebel < 1 then
|
||||
return 4
|
||||
elseif fk.ai_role[to.id] == "loyalist" then
|
||||
return ars.lord + ars.loyalist - ars.rebel
|
||||
elseif fk.ai_role[to.id] == "rebel" then
|
||||
local r = ars.rebel - ars.lord + ars.loyalist
|
||||
if r >= 0 then
|
||||
return 3
|
||||
else
|
||||
return r
|
||||
end
|
||||
end
|
||||
elseif self.role == "lord" or self.role == "loyalist" then
|
||||
if fk.ai_role[to.id] == "rebel" then
|
||||
return 5
|
||||
elseif to.role == "lord" then
|
||||
return -2
|
||||
elseif ars.rebel < 1 then
|
||||
if self.role == "lord" then
|
||||
return fk.explicit_renegade and fk.ai_role[to.id] == "renegade" and 4 or to.hp > 1 and 2 or 0
|
||||
elseif fk.explicit_renegade then
|
||||
return fk.ai_role[to.id] == "renegade" and 4 or -1
|
||||
else
|
||||
return 3
|
||||
end
|
||||
elseif fk.ai_role[to.id] == "loyalist" then
|
||||
return -2
|
||||
elseif fk.ai_role[to.id] == "renegade" then
|
||||
local r = ars.lord + ars.loyalist - ars.rebel
|
||||
if r <= 0 then
|
||||
return r
|
||||
else
|
||||
return 3
|
||||
end
|
||||
end
|
||||
elseif self.role == "rebel" then
|
||||
if to.role == "lord" then
|
||||
return 5
|
||||
elseif fk.ai_role[to.id] == "loyalist" then
|
||||
return 4
|
||||
elseif fk.ai_role[to.id] == "rebel" then
|
||||
return -2
|
||||
elseif fk.ai_role[to.id] == "renegade" then
|
||||
local r = ars.rebel - ars.lord + ars.loyalist
|
||||
if r > 0 then
|
||||
return 1
|
||||
else
|
||||
return r
|
||||
end
|
||||
end
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function TrustAI:updatePlayers(update)
|
||||
self.role = self.player.role
|
||||
local neutrality = {}
|
||||
self.enemies = {}
|
||||
self.friends = {}
|
||||
self.friends_noself = {}
|
||||
|
||||
local aps = self.room:getAlivePlayers()
|
||||
local function compare_func(a, b)
|
||||
local v1 = fk.roleValue[a.id].rebel
|
||||
local v2 = fk.roleValue[b.id].rebel
|
||||
if v1 == v2 then
|
||||
v1 = fk.roleValue[a.id].renegade
|
||||
v2 = fk.roleValue[b.id].renegade
|
||||
end
|
||||
return v1 > v2
|
||||
end
|
||||
table.sort(aps, compare_func)
|
||||
fk.explicit_renegade = false
|
||||
local ars = aliveRoles(self.room)
|
||||
local rebel, renegade, loyalist = 0, 0, 0
|
||||
for _, ap in ipairs(aps) do
|
||||
if ap.role == "lord" then
|
||||
fk.ai_role[ap.id] = "loyalist"
|
||||
elseif fk.roleValue[ap.id].rebel > 50 and ars.rebel > rebel then
|
||||
rebel = rebel + 1
|
||||
fk.ai_role[ap.id] = "rebel"
|
||||
elseif fk.roleValue[ap.id].renegade > 50 and ars.renegade > renegade then
|
||||
renegade = renegade + 1
|
||||
fk.ai_role[ap.id] = "renegade"
|
||||
fk.explicit_renegade = fk.roleValue[ap.id].renegade > 100
|
||||
elseif fk.roleValue[ap.id].rebel < -50 and ars.loyalist > loyalist then
|
||||
loyalist = loyalist + 1
|
||||
fk.ai_role[ap.id] = "loyalist"
|
||||
else
|
||||
fk.ai_role[ap.id] = "neutral"
|
||||
end
|
||||
end
|
||||
|
||||
for n, p in ipairs(self.room:getAlivePlayers(false)) do
|
||||
n = self:objectiveLevel(p)
|
||||
if n < 0 then
|
||||
table.insert(self.friends, p)
|
||||
if p.id ~= self.player.id then
|
||||
table.insert(self.friends_noself, p)
|
||||
end
|
||||
elseif n > 0 then
|
||||
table.insert(self.enemies, p)
|
||||
else
|
||||
table.insert(neutrality, p)
|
||||
end
|
||||
end
|
||||
self:assignValue()
|
||||
--[[
|
||||
if self.enemies<1 and #neutrality>0
|
||||
and#self.toUse<3 and self:getOverflow()>0
|
||||
then
|
||||
function compare_func(a,b)
|
||||
return sgs.getDefense(a)<sgs.getDefense(b)
|
||||
end
|
||||
table.sort(neutrality,compare_func)
|
||||
table.insert(self.enemies,neutrality[1])
|
||||
end-]]
|
||||
end
|
||||
|
||||
local function updateIntention(player, to, intention)
|
||||
if player.id == to.id then
|
||||
return
|
||||
elseif player.role == "lord" then
|
||||
fk.roleValue[to.id].rebel = fk.roleValue[to.id].rebel + intention * (200 - fk.roleValue[to.id].rebel) / 200
|
||||
else
|
||||
if to.role == "lord" or fk.ai_role[to.id] == "loyalist" then
|
||||
fk.roleValue[player.id].rebel = fk.roleValue[player.id].rebel +
|
||||
intention * (200 - fk.roleValue[player.id].rebel) / 200
|
||||
elseif fk.ai_role[to.id] == "rebel" then
|
||||
fk.roleValue[player.id].rebel = fk.roleValue[player.id].rebel -
|
||||
intention * (fk.roleValue[player.id].rebel + 200) / 200
|
||||
end
|
||||
if fk.roleValue[player.id].rebel < 0 and intention > 0 or fk.roleValue[player.id].rebel > 0 and intention < 0 then
|
||||
fk.roleValue[player.id].renegade = fk.roleValue[player.id].renegade +
|
||||
intention * (100 - fk.roleValue[player.id].renegade) / 200
|
||||
end
|
||||
local aps = player.room:getAlivePlayers()
|
||||
local function compare_func(a, b)
|
||||
local v1 = fk.roleValue[a.id].rebel
|
||||
local v2 = fk.roleValue[b.id].rebel
|
||||
if v1 == v2 then
|
||||
v1 = fk.roleValue[a.id].renegade
|
||||
v2 = fk.roleValue[b.id].renegade
|
||||
end
|
||||
return v1 > v2
|
||||
end
|
||||
table.sort(aps, compare_func)
|
||||
fk.explicit_renegade = false
|
||||
local ars = aliveRoles(player.room)
|
||||
local rebel, renegade, loyalist = 0, 0, 0
|
||||
for _, ap in ipairs(aps) do
|
||||
if ap.role == "lord" then
|
||||
fk.ai_role[ap.id] = "loyalist"
|
||||
elseif fk.roleValue[ap.id].rebel > 50 and ars.rebel > rebel then
|
||||
rebel = rebel + 1
|
||||
fk.ai_role[ap.id] = "rebel"
|
||||
elseif fk.roleValue[ap.id].renegade > 50 and ars.renegade > renegade then
|
||||
renegade = renegade + 1
|
||||
fk.ai_role[ap.id] = "renegade"
|
||||
fk.explicit_renegade = fk.roleValue[ap.id].renegade > 100
|
||||
elseif fk.roleValue[ap.id].rebel < -50 and ars.loyalist > loyalist then
|
||||
loyalist = loyalist + 1
|
||||
fk.ai_role[ap.id] = "loyalist"
|
||||
else
|
||||
fk.ai_role[ap.id] = "neutral"
|
||||
end
|
||||
end
|
||||
fk.qWarning(
|
||||
player.general ..
|
||||
" " ..
|
||||
intention ..
|
||||
" " ..
|
||||
fk.ai_role[player.id] ..
|
||||
" rebelValue:" .. fk.roleValue[player.id].rebel .. " renegadeValue:" .. fk.roleValue[player.id].renegade
|
||||
) --]]
|
||||
end
|
||||
end
|
||||
|
||||
function TrustAI:filterEvent(event, player, data)
|
||||
if event == fk.TargetSpecified then
|
||||
local callback = fk.ai_card[data.card.name]
|
||||
callback = callback and callback.intention
|
||||
if type(callback) == "function" then
|
||||
for _, p in ipairs(TargetGroup:getRealTargets(data.tos)) do
|
||||
p = self.room:getPlayerById(p)
|
||||
local intention = callback(p.ai, data.card, self.room:getPlayerById(data.from))
|
||||
if type(intention) == "number" then
|
||||
updateIntention(self.room:getPlayerById(data.from), p, intention)
|
||||
end
|
||||
end
|
||||
elseif type(callback) == "number" then
|
||||
for _, p in ipairs(TargetGroup:getRealTargets(data.tos)) do
|
||||
p = self.room:getPlayerById(p)
|
||||
updateIntention(self.room:getPlayerById(data.from), p, callback)
|
||||
end
|
||||
end
|
||||
elseif event == fk.StartJudge then
|
||||
fk.trick_judge[data.reason] = data.pattern
|
||||
elseif event == fk.AfterCardsMove then
|
||||
end
|
||||
end
|
||||
|
||||
function TrustAI:isWeak(player, getAP)
|
||||
player = player or self.player
|
||||
if type(player) == "number" then
|
||||
player = self.room:getPlayerById(player)
|
||||
end
|
||||
return player.hp < 2 or player.hp <= 2 and #player:getCardIds("&h") <= 2
|
||||
end
|
||||
|
||||
function TrustAI:isFriend(pid, tid)
|
||||
if tid then
|
||||
local bt = self:isFriend(pid)
|
||||
return bt ~= nil and bt == self:isFriend(tid)
|
||||
end
|
||||
if type(pid) == "number" then
|
||||
pid = self.room:getPlayerById(pid)
|
||||
end
|
||||
local ve = self:objectiveLevel(pid)
|
||||
if ve < 0 then
|
||||
return true
|
||||
elseif ve > 0 then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function TrustAI:isEnemie(pid, tid)
|
||||
if tid then
|
||||
local bt = self:isFriend(pid)
|
||||
return bt ~= nil and bt ~= self:isFriend(tid)
|
||||
end
|
||||
if type(pid) == "number" then
|
||||
pid = self.room:getPlayerById(pid)
|
||||
end
|
||||
local ve = self:objectiveLevel(pid)
|
||||
if ve > 0 then
|
||||
return true
|
||||
elseif ve < 0 then
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
function TrustAI:eventData(game_event)
|
||||
local event = self.room.logic:getCurrentEvent():findParent(GameEvent[game_event], true)
|
||||
return event and event.data[1]
|
||||
end
|
||||
|
||||
for _, n in ipairs(FileIO.ls("packages")) do
|
||||
if FileIO.isDir("packages/" .. n) and FileIO.exists("packages/" .. n .. "/" .. n .. "_ai.lua") then
|
||||
dofile("packages/" .. n .. "/" .. n .. "_ai.lua")
|
||||
end
|
||||
end
|
||||
-- 加载两次拓展是为了能够引用,例如属性杀的使用直接套入普通杀的使用
|
||||
for _, n in ipairs(FileIO.ls("packages")) do
|
||||
if FileIO.isDir("packages/" .. n) and FileIO.exists("packages/" .. n .. "/" .. n .. "_ai.lua") then
|
||||
dofile("packages/" .. n .. "/" .. n .. "_ai.lua")
|
||||
end
|
||||
>>>>>>> 79d3213cc0aa996c9072ae5696e387a9bda210d8
|
||||
end
|
||||
|
||||
return TrustAI
|
||||
|
|
|
@ -129,3 +129,121 @@ fk.GeneralRevealed = 89
|
|||
fk.GeneralHidden = 90
|
||||
|
||||
fk.NumOfEvents = 91
|
||||
|
||||
local events = {
|
||||
"NonTrigger",
|
||||
"GamePrepared",
|
||||
"GameStart",
|
||||
"BeforeTurnStart",
|
||||
"TurnStart",
|
||||
"TurnEnd",
|
||||
"AfterTurnEnd",
|
||||
"EventPhaseStart",
|
||||
"EventPhaseProceeding",
|
||||
"EventPhaseEnd",
|
||||
"AfterPhaseEnd",
|
||||
"EventPhaseChanging",
|
||||
"EventPhaseSkipping",
|
||||
|
||||
"BeforeCardsMove",
|
||||
"AfterCardsMove",
|
||||
|
||||
"DrawNCards",
|
||||
"AfterDrawNCards",
|
||||
"DrawInitialCards",
|
||||
"AfterDrawInitialCards",
|
||||
|
||||
"PreHpRecover",
|
||||
"HpRecover",
|
||||
"PreHpLost",
|
||||
"HpLost",
|
||||
"BeforeHpChanged",
|
||||
"HpChanged",
|
||||
"MaxHpChanged",
|
||||
|
||||
"EventLoseSkill",
|
||||
"EventAcquireSkill",
|
||||
|
||||
"StartJudge",
|
||||
"AskForRetrial",
|
||||
"FinishRetrial",
|
||||
"FinishJudge",
|
||||
|
||||
"RoundStart",
|
||||
"RoundEnd",
|
||||
"BeforeTurnOver",
|
||||
"TurnedOver",
|
||||
"BeforeChainStateChange",
|
||||
"ChainStateChanged",
|
||||
|
||||
"PreDamage",
|
||||
"DamageCaused",
|
||||
"DamageInflicted",
|
||||
"Damage",
|
||||
"Damaged",
|
||||
"DamageFinished",
|
||||
|
||||
"EnterDying",
|
||||
"Dying",
|
||||
"AfterDying",
|
||||
|
||||
"PreCardUse",
|
||||
"AfterCardUseDeclared",
|
||||
"AfterCardTargetDeclared",
|
||||
"CardUsing",
|
||||
"BeforeCardUseEffect",
|
||||
"TargetSpecifying",
|
||||
"TargetConfirming",
|
||||
"TargetSpecified",
|
||||
"TargetConfirmed",
|
||||
"CardUseFinished",
|
||||
|
||||
"PreCardRespond",
|
||||
"CardResponding",
|
||||
"CardRespondFinished",
|
||||
|
||||
"PreCardEffect",
|
||||
"BeforeCardEffect",
|
||||
"CardEffecting",
|
||||
"CardEffectFinished",
|
||||
"CardEffectCancelledOut",
|
||||
|
||||
"AskForPeaches",
|
||||
"AskForPeachesDone",
|
||||
"Death",
|
||||
"BuryVictim",
|
||||
"Deathed",
|
||||
"BeforeGameOverJudge",
|
||||
"GameOverJudge",
|
||||
"GameFinished",
|
||||
|
||||
"AskForCardUse",
|
||||
"AskForCardResponse",
|
||||
|
||||
"StartPindian",
|
||||
"PindianCardsDisplayed",
|
||||
"PindianResultConfirmed",
|
||||
"PindianFinished",
|
||||
|
||||
"AfterDrawPileShuffle",
|
||||
|
||||
"BeforeTriggerSkillUse",
|
||||
|
||||
"BeforeDrawCard",
|
||||
|
||||
"CardShown",
|
||||
|
||||
"SkillEffect",
|
||||
"AfterSkillEffect",
|
||||
|
||||
"AreaAborted",
|
||||
"AreaResumed",
|
||||
|
||||
"GeneralRevealed",
|
||||
"GeneralHidden",
|
||||
|
||||
"NumOfEvents"
|
||||
}
|
||||
for i, event in ipairs(events) do
|
||||
fk[event] = i
|
||||
end --]]
|
||||
|
|
|
@ -194,16 +194,15 @@ end
|
|||
GameEvent.functions[GameEvent.UseCard] = function(self)
|
||||
local cardUseEvent = table.unpack(self.data)
|
||||
local room = self.room
|
||||
local logic = room.logic
|
||||
|
||||
if cardUseEvent.card.skill then
|
||||
cardUseEvent.card.skill:onUse(room, cardUseEvent)
|
||||
end
|
||||
|
||||
if logic:trigger(fk.PreCardUse, room:getPlayerById(cardUseEvent.from), cardUseEvent) then
|
||||
if room.logic:trigger(fk.PreCardUse, room:getPlayerById(cardUseEvent.from), cardUseEvent) then
|
||||
cardUseEvent.breakEvent = true
|
||||
self.data = { cardUseEvent }
|
||||
logic:breakEvent()
|
||||
room.logic:breakEvent()
|
||||
end
|
||||
|
||||
room:moveCardTo(cardUseEvent.card, Card.Processing, nil, fk.ReasonUse)
|
||||
|
@ -223,7 +222,7 @@ GameEvent.functions[GameEvent.UseCard] = function(self)
|
|||
break
|
||||
end
|
||||
|
||||
logic:trigger(event, room:getPlayerById(cardUseEvent.from), cardUseEvent)
|
||||
room.logic:trigger(event, room:getPlayerById(cardUseEvent.from), cardUseEvent)
|
||||
if event == fk.CardUsing then
|
||||
room:doCardUseEffect(cardUseEvent)
|
||||
end
|
||||
|
@ -232,13 +231,12 @@ end
|
|||
|
||||
GameEvent.cleaners[GameEvent.UseCard] = function(self)
|
||||
local cardUseEvent = table.unpack(self.data)
|
||||
local room = self.room
|
||||
|
||||
room.logic:trigger(fk.CardUseFinished, room:getPlayerById(cardUseEvent.from), cardUseEvent)
|
||||
self.room.logic:trigger(fk.CardUseFinished, self.room:getPlayerById(cardUseEvent.from), cardUseEvent)
|
||||
|
||||
local leftRealCardIds = room:getSubcardsByRule(cardUseEvent.card, { Card.Processing })
|
||||
local leftRealCardIds = self.room:getSubcardsByRule(cardUseEvent.card, { Card.Processing })
|
||||
if #leftRealCardIds > 0 then
|
||||
room:moveCards({
|
||||
self.room:moveCards({
|
||||
ids = leftRealCardIds,
|
||||
toArea = Card.DiscardPile,
|
||||
moveReason = fk.ReasonUse
|
||||
|
@ -249,12 +247,11 @@ end
|
|||
GameEvent.functions[GameEvent.RespondCard] = function(self)
|
||||
local cardResponseEvent = table.unpack(self.data)
|
||||
local room = self.room
|
||||
local logic = room.logic
|
||||
|
||||
if logic:trigger(fk.PreCardRespond, room:getPlayerById(cardResponseEvent.from), cardResponseEvent) then
|
||||
if room.logic:trigger(fk.PreCardRespond, room:getPlayerById(cardResponseEvent.from), cardResponseEvent) then
|
||||
cardResponseEvent.breakEvent = true
|
||||
self.data = { cardResponseEvent }
|
||||
logic:breakEvent()
|
||||
room.logic:breakEvent()
|
||||
end
|
||||
|
||||
local from = cardResponseEvent.customFrom or cardResponseEvent.from
|
||||
|
@ -296,19 +293,18 @@ GameEvent.functions[GameEvent.RespondCard] = function(self)
|
|||
if cardResponseEvent.retrial ~= true then
|
||||
playCardEmotionAndSound(room, room:getPlayerById(from), card)
|
||||
end
|
||||
logic:trigger(fk.CardResponding, room:getPlayerById(cardResponseEvent.from), cardResponseEvent)
|
||||
room.logic:trigger(fk.CardResponding, room:getPlayerById(cardResponseEvent.from), cardResponseEvent)
|
||||
self.data = { cardResponseEvent }
|
||||
end
|
||||
|
||||
GameEvent.cleaners[GameEvent.RespondCard] = function(self)
|
||||
local cardResponseEvent = table.unpack(self.data)
|
||||
local room = self.room
|
||||
|
||||
room.logic:trigger(fk.CardRespondFinished, room:getPlayerById(cardResponseEvent.from), cardResponseEvent)
|
||||
self.room.logic:trigger(fk.CardRespondFinished, self.room:getPlayerById(cardResponseEvent.from), cardResponseEvent)
|
||||
|
||||
local realCardIds = room:getSubcardsByRule(cardResponseEvent.card, { Card.Processing })
|
||||
local realCardIds = self.room:getSubcardsByRule(cardResponseEvent.card, { Card.Processing })
|
||||
if #realCardIds > 0 and not cardResponseEvent.skipDrop then
|
||||
room:moveCards({
|
||||
self.room:moveCards({
|
||||
ids = realCardIds,
|
||||
toArea = Card.DiscardPile,
|
||||
moveReason = fk.ReasonResonpse
|
||||
|
@ -319,34 +315,33 @@ end
|
|||
GameEvent.functions[GameEvent.CardEffect] = function(self)
|
||||
local cardEffectEvent = table.unpack(self.data)
|
||||
local room = self.room
|
||||
local logic = room.logic
|
||||
|
||||
for _, event in ipairs({ fk.PreCardEffect, fk.BeforeCardEffect, fk.CardEffecting, fk.CardEffectFinished }) do
|
||||
local user = cardEffectEvent.from and room:getPlayerById(cardEffectEvent.from) or nil
|
||||
if cardEffectEvent.isCancellOut then
|
||||
if logic:trigger(fk.CardEffectCancelledOut, user, cardEffectEvent) then
|
||||
if room.logic:trigger(fk.CardEffectCancelledOut, user, cardEffectEvent) then
|
||||
cardEffectEvent.isCancellOut = false
|
||||
else
|
||||
logic:breakEvent()
|
||||
room.logic:breakEvent()
|
||||
end
|
||||
end
|
||||
|
||||
if not cardEffectEvent.toCard and
|
||||
(not (room:getPlayerById(cardEffectEvent.to):isAlive() and cardEffectEvent.to) or
|
||||
#room:deadPlayerFilter(TargetGroup:getRealTargets(cardEffectEvent.tos)) == 0) then
|
||||
logic:breakEvent()
|
||||
room.logic:breakEvent()
|
||||
end
|
||||
|
||||
if table.contains((cardEffectEvent.nullifiedTargets or Util.DummyTable), cardEffectEvent.to) then
|
||||
logic:breakEvent()
|
||||
room.logic:breakEvent()
|
||||
end
|
||||
|
||||
if event == fk.PreCardEffect then
|
||||
if cardEffectEvent.from and logic:trigger(event, room:getPlayerById(cardEffectEvent.from), cardEffectEvent) then
|
||||
logic:breakEvent()
|
||||
if cardEffectEvent.from and room.logic:trigger(event, room:getPlayerById(cardEffectEvent.from), cardEffectEvent) then
|
||||
room.logic:breakEvent()
|
||||
end
|
||||
elseif cardEffectEvent.to and logic:trigger(event, room:getPlayerById(cardEffectEvent.to), cardEffectEvent) then
|
||||
logic:breakEvent()
|
||||
elseif cardEffectEvent.to and room.logic:trigger(event, room:getPlayerById(cardEffectEvent.to), cardEffectEvent) then
|
||||
room.logic:breakEvent()
|
||||
end
|
||||
|
||||
room:handleCardEffect(event, cardEffectEvent)
|
||||
|
|
|
@ -23,11 +23,11 @@ function GameLogic:initialize(room)
|
|||
self.event_recorder = {}
|
||||
self.current_event_id = 0
|
||||
|
||||
self.role_table = {{"lord"}, {"lord", "rebel"}, {"lord", "rebel", "renegade"},
|
||||
{"lord", "loyalist", "rebel", "renegade"}, {"lord", "loyalist", "rebel", "rebel", "renegade"},
|
||||
{"lord", "loyalist", "rebel", "rebel", "rebel", "renegade"},
|
||||
{"lord", "loyalist", "loyalist", "rebel", "rebel", "rebel", "renegade"},
|
||||
{"lord", "loyalist", "loyalist", "rebel", "rebel", "rebel", "rebel", "renegade"}}
|
||||
self.role_table = { { "lord" }, { "lord", "rebel" }, { "lord", "rebel", "renegade" },
|
||||
{ "lord", "loyalist", "rebel", "renegade" }, { "lord", "loyalist", "rebel", "rebel", "renegade" },
|
||||
{ "lord", "loyalist", "rebel", "rebel", "rebel", "renegade" },
|
||||
{ "lord", "loyalist", "loyalist", "rebel", "rebel", "rebel", "renegade" },
|
||||
{ "lord", "loyalist", "loyalist", "rebel", "rebel", "rebel", "rebel", "renegade" } }
|
||||
end
|
||||
|
||||
function GameLogic:run()
|
||||
|
@ -117,11 +117,11 @@ function GameLogic:chooseGenerals()
|
|||
lord_general = lord_generals[1]
|
||||
else
|
||||
lord_general = lord_generals
|
||||
lord_generals = {lord_general}
|
||||
lord_generals = { lord_general }
|
||||
end
|
||||
|
||||
room:setPlayerGeneral(lord, lord_general, true)
|
||||
room:askForChooseKingdom({lord})
|
||||
room:askForChooseKingdom({ lord })
|
||||
room:broadcastProperty(lord, "general")
|
||||
room:broadcastProperty(lord, "kingdom")
|
||||
room:setDeputyGeneral(lord, deputy)
|
||||
|
@ -136,7 +136,7 @@ function GameLogic:chooseGenerals()
|
|||
for i = 1, generalNum do
|
||||
table.insert(arg, table.remove(generals, 1).name)
|
||||
end
|
||||
p.request_data = json.encode {arg, n}
|
||||
p.request_data = json.encode { arg, n }
|
||||
p.default_reply = table.random(arg, n)
|
||||
end
|
||||
|
||||
|
@ -163,7 +163,7 @@ end
|
|||
function GameLogic:buildPlayerCircle()
|
||||
local room = self.room
|
||||
local players = room.players
|
||||
room.alive_players = {table.unpack(players)}
|
||||
room.alive_players = { table.unpack(players) }
|
||||
for i = 1, #players - 1 do
|
||||
players[i].next = players[i + 1]
|
||||
end
|
||||
|
@ -264,7 +264,7 @@ function GameLogic:prepareForStart()
|
|||
self:addTriggerSkill(trig)
|
||||
end
|
||||
|
||||
self.room:sendLog{
|
||||
self.room:sendLog {
|
||||
type = "$GameStart"
|
||||
}
|
||||
end
|
||||
|
@ -324,7 +324,6 @@ function GameLogic:addTriggerSkill(skill)
|
|||
end
|
||||
|
||||
if not table.contains(self.skill_priority_table[event], skill.priority_table[event]) then
|
||||
|
||||
table.insert(self.skill_priority_table[event], skill.priority_table[event])
|
||||
end
|
||||
end
|
||||
|
@ -498,7 +497,6 @@ function GameLogic:dumpAllEvents(from, to)
|
|||
from = from or 1
|
||||
to = to or #self.all_game_events
|
||||
assert(from <= to)
|
||||
|
||||
local indent = 0
|
||||
local tab = " "
|
||||
for i = from, to, 1 do
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
dir=FreeKill-${FK_VER}
|
||||
mkdir $dir
|
||||
echo Copying
|
||||
cp -r ./Freekill/.git $dir
|
||||
cp -r ./FreeKill/.git $dir
|
||||
|
||||
cd $dir
|
||||
git restore .
|
||||
|
|
|
@ -8,10 +8,10 @@
|
|||
给FreeKill的GitHub仓库点一个star吧!
|
||||
你可以在武将一览界面禁将,在你创建的房间中禁用武将不会出现在选将框。
|
||||
如果你遇到了bug,请截图并反馈给开发者
|
||||
如果你想要制作FK的mod,需要先学习Lua语言
|
||||
如果你想要制作新月杀的mod,需要先学习Lua语言
|
||||
目光所及短寸吾才之间满腹狭目之阿瞒有我见袁本良计初只能窥取冀州便是底竟不从易成略在胸如反掌之良计速出吾才满目光所及腹袁本初竟短寸之间不从之
|
||||
吔!
|
||||
想要参与到FK的开发工作中?那么就从制作自己的Mod开始吧!
|
||||
想要参与到新月杀的开发工作中?那么就从制作自己的Mod开始吧!
|
||||
在游戏的一些地方,长按可以显示该元素的详情。如果你用的是电脑版的话可以用鼠标右键代替长按。
|
||||
注意:官方不支持任何形式的账号交易行为,请妥善保管好您的账号密码。请勿与他人共享账号。因账号交易、共享引起的账号争议官方均不受理。
|
||||
如果牌不好的话,就请辱骂GK的发牌员吧
|
||||
|
@ -19,8 +19,9 @@
|
|||
神曰:“MBKS”
|
||||
正在匹配势均力敌的对手…… 匹配到界徐盛
|
||||
先喝酒还是先上刀,这是个值得考虑的问题
|
||||
在抱怨FK只有标准包?那么去试着参与联机吧
|
||||
在抱怨新月杀只有标准包?那么去试着参与联机吧
|
||||
如果在牌局内想查看技能,可以长按想要看技能的角色
|
||||
FK的开服很简单,只要单机启动就可以当做服务器使用了
|
||||
用Linux也能搭建FK服务器,起始页推荐的联机IP就是跑在Linux服务器上的
|
||||
新月杀的开服很简单,只要单机启动就可以当做服务器使用了
|
||||
用Linux也能搭建新月杀服务器,起始页推荐的联机IP就是跑在Linux服务器上的
|
||||
我们的游戏正在蒸蒸日上哦~
|
||||
请素质游戏!不要做出烧条之类的举动哦~
|
||||
|
|
Loading…
Reference in New Issue