2015-09-25 21:07:16 +08:00
|
|
|
/*
|
2024-01-03 01:21:08 +01:00
|
|
|
* Copyright (c) 2010-2015, Argon Sun (Fluorohydride)
|
2025-04-25 11:00:10 +02:00
|
|
|
* Copyright (c) 2017-2025, Edoardo Lolletti (edo9300) <edoardo762@gmail.com>
|
2015-09-25 21:07:16 +08:00
|
|
|
*
|
2024-01-03 01:21:08 +01:00
|
|
|
* SPDX-License-Identifier: AGPL-3.0-or-later
|
2015-09-25 21:07:16 +08:00
|
|
|
*/
|
2024-01-05 12:17:47 +01:00
|
|
|
#include <algorithm> //std::find, std::remove, std::includes, std::set_intersection
|
|
|
|
|
#include <iterator> //std::advance, std::inserter
|
|
|
|
|
#include <set>
|
|
|
|
|
#include <tuple>
|
|
|
|
|
#include <utility> //std::move, std::swap
|
|
|
|
|
#include "bit.h"
|
2015-09-25 21:07:16 +08:00
|
|
|
#include "card.h"
|
|
|
|
|
#include "duel.h"
|
2024-01-05 12:17:47 +01:00
|
|
|
#include "field.h"
|
|
|
|
|
#include "group.h"
|
|
|
|
|
#include "scriptlib.h"
|
2015-09-25 21:07:16 +08:00
|
|
|
|
2022-05-14 19:55:59 +02:00
|
|
|
#define LUA_MODULE Group
|
2023-11-21 11:56:23 +01:00
|
|
|
using LUA_CLASS = group;
|
2022-05-14 19:55:59 +02:00
|
|
|
#include "function_array_helper.h"
|
|
|
|
|
|
2021-10-13 17:29:29 +02:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
using namespace scriptlib;
|
|
|
|
|
|
|
|
|
|
void assert_readonly_group(lua_State* L, group* pgroup) {
|
2025-05-03 18:08:41 +02:00
|
|
|
if(!pgroup->is_readonly)
|
2021-09-04 20:29:09 +02:00
|
|
|
return;
|
2022-06-23 11:47:00 +02:00
|
|
|
lua_error(L, "attempt to modify a read only group");
|
2021-08-11 14:24:03 +02:00
|
|
|
}
|
|
|
|
|
|
2023-11-21 11:56:23 +01:00
|
|
|
LUA_STATIC_FUNCTION(CreateGroup) {
|
2025-05-03 12:54:01 +02:00
|
|
|
auto pgroup = pduel->new_group();
|
2022-10-27 12:49:36 +02:00
|
|
|
lua_iterate_table_or_stack(L, 1, lua_gettop(L), [L, &container = pgroup->container] {
|
2022-10-26 18:13:11 +02:00
|
|
|
if(!lua_isnil(L, -1)) {
|
|
|
|
|
auto pcard = lua_get<card*, true>(L, -1);
|
|
|
|
|
container.insert(pcard);
|
|
|
|
|
}
|
|
|
|
|
});
|
2020-07-20 22:05:04 +02:00
|
|
|
interpreter::pushobject(L, pgroup);
|
2015-09-25 21:07:16 +08:00
|
|
|
return 1;
|
|
|
|
|
}
|
2022-10-19 15:07:05 +02:00
|
|
|
LUA_FUNCTION_ALIAS(FromCards);
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(Clone) {
|
2025-05-03 12:54:01 +02:00
|
|
|
auto newgroup = pduel->new_group(self);
|
2020-07-20 22:05:04 +02:00
|
|
|
interpreter::pushobject(L, newgroup);
|
2015-09-25 21:07:16 +08:00
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(DeleteGroup) {
|
2015-09-25 21:07:16 +08:00
|
|
|
return 0;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(KeepAlive) {
|
2023-11-21 11:56:23 +01:00
|
|
|
interpreter::pushobject(L, self);
|
2023-02-05 11:23:31 +01:00
|
|
|
return 1;
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(Clear) {
|
2023-11-21 11:56:23 +01:00
|
|
|
assert_readonly_group(L, self);
|
|
|
|
|
self->is_iterator_dirty = true;
|
|
|
|
|
self->container.clear();
|
|
|
|
|
interpreter::pushobject(L, self);
|
2023-02-05 11:23:31 +01:00
|
|
|
return 1;
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(AddCard) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_param_count(L, 2);
|
2023-11-21 11:56:23 +01:00
|
|
|
assert_readonly_group(L, self);
|
|
|
|
|
self->is_iterator_dirty = true;
|
2023-12-03 11:34:38 +01:00
|
|
|
if(auto [pcard, pgroup] = lua_get_card_or_group(L, 2); pcard)
|
2023-11-21 11:56:23 +01:00
|
|
|
self->container.insert(pcard);
|
2021-08-11 14:24:03 +02:00
|
|
|
else
|
2023-11-26 15:11:50 +01:00
|
|
|
self->container.insert(pgroup->container.begin(), pgroup->container.end());
|
2023-11-21 11:56:23 +01:00
|
|
|
interpreter::pushobject(L, self);
|
2021-08-11 14:24:03 +02:00
|
|
|
return 1;
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION_ALIAS(Merge);
|
|
|
|
|
LUA_FUNCTION(RemoveCard) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_param_count(L, 2);
|
2023-11-21 11:56:23 +01:00
|
|
|
assert_readonly_group(L, self);
|
|
|
|
|
self->is_iterator_dirty = true;
|
2023-12-03 11:34:38 +01:00
|
|
|
if(auto [pcard, pgroup] = lua_get_card_or_group(L, 2); pcard)
|
2023-11-21 11:56:23 +01:00
|
|
|
self->container.erase(pcard);
|
2021-08-11 14:24:03 +02:00
|
|
|
else {
|
2023-11-26 15:11:50 +01:00
|
|
|
if(self == pgroup)
|
2022-08-10 16:05:20 +02:00
|
|
|
lua_error(L, "Attempting to remove a group from itself");
|
2023-11-26 15:11:50 +01:00
|
|
|
for(auto& _pcard : pgroup->container)
|
2023-11-21 11:56:23 +01:00
|
|
|
self->container.erase(_pcard);
|
2021-08-11 14:24:03 +02:00
|
|
|
}
|
2023-11-21 11:56:23 +01:00
|
|
|
interpreter::pushobject(L, self);
|
2021-08-05 16:53:23 +02:00
|
|
|
return 1;
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION_ALIAS(Sub);
|
|
|
|
|
LUA_FUNCTION(GetNext) {
|
2023-11-21 11:56:23 +01:00
|
|
|
if(self->is_iterator_dirty)
|
2022-06-23 11:47:00 +02:00
|
|
|
lua_error(L, "Called Group.GetNext without first calling Group.GetFirst");
|
2023-12-02 12:04:35 +01:00
|
|
|
if(self->it == self->container.end() || (++self->it) == self->container.end())
|
2015-09-25 21:07:16 +08:00
|
|
|
lua_pushnil(L);
|
2023-12-02 12:04:35 +01:00
|
|
|
else
|
|
|
|
|
interpreter::pushobject(L, *self->it);
|
2015-09-25 21:07:16 +08:00
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(GetFirst) {
|
2023-11-21 11:56:23 +01:00
|
|
|
self->is_iterator_dirty = false;
|
2023-12-02 12:04:35 +01:00
|
|
|
if(self->it = self->container.begin(); self->it != self->container.end())
|
|
|
|
|
interpreter::pushobject(L, *self->it);
|
2020-07-20 19:44:59 +02:00
|
|
|
else
|
2015-09-25 21:07:16 +08:00
|
|
|
lua_pushnil(L);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(TakeatPos) {
|
2017-09-23 19:29:58 +02:00
|
|
|
check_param_count(L, 2);
|
2020-07-20 19:44:59 +02:00
|
|
|
auto pos = lua_get<size_t>(L, 2);
|
2023-11-21 11:56:23 +01:00
|
|
|
if(pos >= self->container.size())
|
2017-09-23 19:29:58 +02:00
|
|
|
lua_pushnil(L);
|
|
|
|
|
else {
|
2023-11-21 11:56:23 +01:00
|
|
|
auto cit = self->container.begin();
|
2017-09-23 19:29:58 +02:00
|
|
|
std::advance(cit, pos);
|
2020-07-20 22:05:04 +02:00
|
|
|
interpreter::pushobject(L, *cit);
|
2017-09-23 19:29:58 +02:00
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(GetCount) {
|
2023-11-21 11:56:23 +01:00
|
|
|
lua_pushinteger(L, self->container.size());
|
2015-09-25 21:07:16 +08:00
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(Filter) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_param_count(L, 3);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 2);
|
2023-11-21 11:56:23 +01:00
|
|
|
card_set cset(self->container);
|
2023-12-03 11:34:38 +01:00
|
|
|
if(auto [pexception, pexgroup] = lua_get_card_or_group<true>(L, 3); pexception) {
|
2017-02-08 21:16:32 +09:00
|
|
|
cset.erase(pexception);
|
2023-12-03 10:27:47 +01:00
|
|
|
} else if(pexgroup) {
|
2018-09-03 16:36:45 +08:00
|
|
|
for(auto& pcard : pexgroup->container)
|
|
|
|
|
cset.erase(pcard);
|
2017-02-08 21:16:32 +09:00
|
|
|
}
|
2025-05-03 12:54:01 +02:00
|
|
|
auto new_group = pduel->new_group();
|
2021-09-04 22:04:14 +02:00
|
|
|
uint32_t extraargs = lua_gettop(L) - 3;
|
2018-09-03 16:36:45 +08:00
|
|
|
for(auto& pcard : cset) {
|
2022-06-11 12:59:38 +02:00
|
|
|
if(pduel->lua->check_matching(pcard, findex, extraargs)) {
|
2018-09-03 16:36:45 +08:00
|
|
|
new_group->container.insert(pcard);
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
|
|
|
|
}
|
2020-07-20 22:05:04 +02:00
|
|
|
interpreter::pushobject(L, new_group);
|
2015-09-25 21:07:16 +08:00
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(Match) {
|
2021-08-14 23:38:25 +02:00
|
|
|
check_param_count(L, 3);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 2);
|
2023-11-21 11:56:23 +01:00
|
|
|
assert_readonly_group(L, self);
|
|
|
|
|
self->is_iterator_dirty = true;
|
2021-09-04 22:04:14 +02:00
|
|
|
uint32_t extraargs = lua_gettop(L) - 3;
|
2023-11-21 11:56:23 +01:00
|
|
|
auto& cset = self->container;
|
2023-12-03 11:34:38 +01:00
|
|
|
if(auto [pexception, pexgroup] = lua_get_card_or_group<true>(L, 3); pexception) {
|
2022-05-15 16:48:51 +02:00
|
|
|
for(auto cit = cset.begin(), cend = cset.end(); cit != cend; ) {
|
|
|
|
|
auto rm = cit++;
|
|
|
|
|
auto* pcard = *rm;
|
2022-06-11 12:59:38 +02:00
|
|
|
if(pcard == pexception || !pduel->lua->check_matching(pcard, findex, extraargs))
|
2022-05-15 16:48:51 +02:00
|
|
|
cset.erase(rm);
|
|
|
|
|
}
|
|
|
|
|
} else if(pexgroup) {
|
2023-12-03 10:27:47 +01:00
|
|
|
auto should_remove = [pexbegin = pexgroup->container.cbegin(), pexend = pexgroup->container.cend()](card* pcard) mutable {
|
2022-05-15 16:48:51 +02:00
|
|
|
if(pexbegin == pexend)
|
|
|
|
|
return false;
|
|
|
|
|
if(*pexbegin == pcard) {
|
|
|
|
|
++pexbegin;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
for(auto cit = cset.begin(), cend = cset.end(); cit != cend; ) {
|
|
|
|
|
auto rm = cit++;
|
|
|
|
|
auto* pcard = *rm;
|
2022-06-11 12:59:38 +02:00
|
|
|
if(should_remove(pcard) || !pduel->lua->check_matching(pcard, findex, extraargs))
|
2022-05-15 16:48:51 +02:00
|
|
|
cset.erase(rm);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
for(auto cit = cset.begin(), cend = cset.end(); cit != cend; ) {
|
|
|
|
|
auto rm = cit++;
|
|
|
|
|
auto* pcard = *rm;
|
2022-06-11 12:59:38 +02:00
|
|
|
if(!pduel->lua->check_matching(pcard, findex, extraargs))
|
2022-05-15 16:48:51 +02:00
|
|
|
cset.erase(rm);
|
|
|
|
|
}
|
2021-08-14 23:38:25 +02:00
|
|
|
}
|
2023-11-21 11:56:23 +01:00
|
|
|
interpreter::pushobject(L, self);
|
2021-08-14 23:38:25 +02:00
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(FilterCount) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_param_count(L, 3);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 2);
|
2023-11-21 11:56:23 +01:00
|
|
|
card_set cset(self->container);
|
2023-12-03 11:34:38 +01:00
|
|
|
if(auto [pexception, pexgroup] = lua_get_card_or_group<true>(L, 3); pexception) {
|
2022-09-29 19:46:15 +02:00
|
|
|
cset.erase(pexception);
|
2023-12-03 10:27:47 +01:00
|
|
|
} else if(pexgroup) {
|
2022-09-29 19:46:15 +02:00
|
|
|
for(auto& pcard : pexgroup->container)
|
|
|
|
|
cset.erase(pcard);
|
|
|
|
|
}
|
2021-09-04 22:04:14 +02:00
|
|
|
uint32_t extraargs = lua_gettop(L) - 3;
|
|
|
|
|
uint32_t count = 0;
|
2022-09-29 19:46:15 +02:00
|
|
|
for (auto& pcard : cset) {
|
|
|
|
|
if(pduel->lua->check_matching(pcard, findex, extraargs))
|
|
|
|
|
++count;
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
|
|
|
|
lua_pushinteger(L, count);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(FilterSelect) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_action_permission(L);
|
|
|
|
|
check_param_count(L, 6);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 3);
|
2023-11-21 11:56:23 +01:00
|
|
|
card_set cset(self->container);
|
2020-07-23 23:50:09 +02:00
|
|
|
bool cancelable = false;
|
2020-03-14 18:40:09 +01:00
|
|
|
uint8_t lastarg = 6;
|
2020-07-24 00:16:34 +02:00
|
|
|
if(lua_isboolean(L, lastarg)) {
|
2020-07-23 23:50:09 +02:00
|
|
|
cancelable = lua_get<bool, false>(L, lastarg);
|
2022-03-05 13:56:43 +01:00
|
|
|
++lastarg;
|
2020-03-14 18:40:09 +01:00
|
|
|
}
|
2023-12-03 11:34:38 +01:00
|
|
|
if(auto [pexception, pexgroup] = lua_get_card_or_group<true>(L, lastarg); pexception) {
|
2017-02-08 21:16:32 +09:00
|
|
|
cset.erase(pexception);
|
2023-12-03 10:27:47 +01:00
|
|
|
} else if(pexgroup) {
|
2018-09-03 16:36:45 +08:00
|
|
|
for(auto& pcard : pexgroup->container)
|
|
|
|
|
cset.erase(pcard);
|
2017-02-08 21:16:32 +09:00
|
|
|
}
|
2021-09-04 22:04:14 +02:00
|
|
|
auto playerid = lua_get<uint8_t>(L, 2);
|
2015-09-25 21:07:16 +08:00
|
|
|
if(playerid != 0 && playerid != 1)
|
|
|
|
|
return 0;
|
2021-09-04 22:04:14 +02:00
|
|
|
auto min = lua_get<uint16_t>(L, 4);
|
|
|
|
|
auto max = lua_get<uint16_t>(L, 5);
|
|
|
|
|
uint32_t extraargs = lua_gettop(L) - lastarg;
|
2015-09-25 21:07:16 +08:00
|
|
|
pduel->game_field->core.select_cards.clear();
|
2021-10-13 17:29:29 +02:00
|
|
|
for(auto& pcard : cset) {
|
2022-06-11 12:59:38 +02:00
|
|
|
if(pduel->lua->check_matching(pcard, findex, extraargs))
|
2018-09-03 16:36:45 +08:00
|
|
|
pduel->game_field->core.select_cards.push_back(pcard);
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
2024-01-08 20:46:41 +01:00
|
|
|
pduel->game_field->emplace_process<Processors::SelectCard>(playerid, cancelable, min, max);
|
2023-11-25 11:15:21 +01:00
|
|
|
return push_return_cards(L, cancelable);
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(Select) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_action_permission(L);
|
|
|
|
|
check_param_count(L, 5);
|
2023-11-21 11:56:23 +01:00
|
|
|
card_set cset(self->container);
|
2020-07-23 23:50:09 +02:00
|
|
|
bool cancelable = false;
|
2020-03-14 18:40:09 +01:00
|
|
|
uint8_t lastarg = 5;
|
2020-07-24 00:16:34 +02:00
|
|
|
if(lua_isboolean(L, lastarg)) {
|
2020-07-23 23:50:09 +02:00
|
|
|
cancelable = lua_get<bool, false>(L, lastarg);
|
2022-03-05 13:56:43 +01:00
|
|
|
++lastarg;
|
2020-03-14 18:40:09 +01:00
|
|
|
}
|
2023-12-03 11:34:38 +01:00
|
|
|
if(auto [pexception, pexgroup] = lua_get_card_or_group<true>(L, lastarg); pexception) {
|
2017-02-08 21:16:32 +09:00
|
|
|
cset.erase(pexception);
|
2023-12-03 10:27:47 +01:00
|
|
|
} else if(pexgroup) {
|
2018-09-03 16:36:45 +08:00
|
|
|
for(auto& pcard : pexgroup->container)
|
|
|
|
|
cset.erase(pcard);
|
2017-02-08 21:16:32 +09:00
|
|
|
}
|
2021-09-04 22:04:14 +02:00
|
|
|
auto playerid = lua_get<uint8_t>(L, 2);
|
2015-09-25 21:07:16 +08:00
|
|
|
if(playerid != 0 && playerid != 1)
|
|
|
|
|
return 0;
|
2021-09-04 22:04:14 +02:00
|
|
|
auto min = lua_get<uint16_t>(L, 3);
|
|
|
|
|
auto max = lua_get<uint16_t>(L, 4);
|
2020-07-20 19:44:59 +02:00
|
|
|
pduel->game_field->core.select_cards.assign(cset.begin(), cset.end());
|
2024-01-08 20:46:41 +01:00
|
|
|
pduel->game_field->emplace_process<Processors::SelectCard>(playerid, cancelable, min, max);
|
2023-11-25 11:15:21 +01:00
|
|
|
return push_return_cards(L, cancelable);
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(SelectUnselect) {
|
2017-02-06 23:16:54 +01:00
|
|
|
check_action_permission(L);
|
|
|
|
|
check_param_count(L, 3);
|
2022-05-15 17:05:45 +02:00
|
|
|
auto pgroup2 = lua_get<group*>(L, 2);
|
2021-09-04 22:04:14 +02:00
|
|
|
auto playerid = lua_get<uint8_t>(L, 3);
|
2017-02-06 23:16:54 +01:00
|
|
|
if(playerid != 0 && playerid != 1)
|
|
|
|
|
return 0;
|
2022-05-15 17:05:45 +02:00
|
|
|
if(pgroup2) {
|
2023-11-21 11:56:23 +01:00
|
|
|
auto first1 = self->container.begin();
|
|
|
|
|
auto last1 = self->container.end();
|
2022-05-15 16:47:13 +02:00
|
|
|
auto first2 = pgroup2->container.begin();
|
|
|
|
|
auto last2 = pgroup2->container.end();
|
|
|
|
|
while(first1 != last1 && first2 != last2) {
|
|
|
|
|
if((*first1)->cardid < (*first2)->cardid) {
|
|
|
|
|
++first1;
|
|
|
|
|
} else {
|
|
|
|
|
if(!((*first2)->cardid < (*first1)->cardid)) {
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
++first2;
|
|
|
|
|
}
|
2017-02-06 23:16:54 +01:00
|
|
|
}
|
|
|
|
|
}
|
2020-07-23 23:50:09 +02:00
|
|
|
bool finishable = lua_get<bool, false>(L, 4);
|
|
|
|
|
bool cancelable = lua_get<bool, false>(L, 5);
|
2022-05-15 17:05:45 +02:00
|
|
|
uint16_t min = lua_get<uint16_t, 1>(L, 6);
|
|
|
|
|
uint16_t max = lua_get<uint16_t, 1>(L, 7);
|
2018-04-05 14:41:14 +02:00
|
|
|
if(min > max)
|
2017-02-06 23:16:54 +01:00
|
|
|
min = max;
|
2023-11-21 11:56:23 +01:00
|
|
|
pduel->game_field->core.select_cards.assign(self->container.begin(), self->container.end());
|
2022-05-15 17:05:45 +02:00
|
|
|
if(pgroup2)
|
|
|
|
|
pduel->game_field->core.unselect_cards.assign(pgroup2->container.begin(), pgroup2->container.end());
|
|
|
|
|
else
|
|
|
|
|
pduel->game_field->core.unselect_cards.clear();
|
2024-01-08 20:46:41 +01:00
|
|
|
pduel->game_field->emplace_process<Processors::SelectUnselectCard>(playerid, cancelable, min, max, finishable);
|
2023-11-25 11:15:21 +01:00
|
|
|
return yieldk({
|
2021-04-19 12:24:48 +02:00
|
|
|
if(pduel->game_field->return_cards.canceled)
|
|
|
|
|
lua_pushnil(L);
|
|
|
|
|
else
|
|
|
|
|
interpreter::pushobject(L, pduel->game_field->return_cards.list[0]);
|
|
|
|
|
return 1;
|
|
|
|
|
});
|
2017-02-06 23:16:54 +01:00
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(RandomSelect) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_param_count(L, 3);
|
2021-09-04 22:04:14 +02:00
|
|
|
auto playerid = lua_get<uint8_t>(L, 2);
|
|
|
|
|
size_t count = lua_get<uint32_t>(L, 3);
|
2025-05-03 12:54:01 +02:00
|
|
|
auto newgroup = pduel->new_group();
|
2023-11-21 11:56:23 +01:00
|
|
|
if(count > self->container.size())
|
|
|
|
|
count = self->container.size();
|
2019-06-23 14:15:19 +08:00
|
|
|
if(count == 0) {
|
2020-07-20 22:05:04 +02:00
|
|
|
interpreter::pushobject(L, newgroup);
|
2019-06-23 14:15:19 +08:00
|
|
|
return 1;
|
|
|
|
|
}
|
2023-11-21 11:56:23 +01:00
|
|
|
if(count == self->container.size())
|
|
|
|
|
newgroup->container = self->container;
|
2019-06-23 14:15:19 +08:00
|
|
|
else {
|
2020-10-03 18:07:30 +02:00
|
|
|
while(newgroup->container.size() < count) {
|
2023-11-21 11:56:23 +01:00
|
|
|
int32_t i = pduel->get_next_integer(0, (int32_t)self->container.size() - 1);
|
|
|
|
|
auto cit = self->container.begin();
|
2020-10-03 18:07:30 +02:00
|
|
|
std::advance(cit, i);
|
2019-06-23 14:15:19 +08:00
|
|
|
newgroup->container.insert(*cit);
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-07-16 00:57:53 +02:00
|
|
|
auto message = pduel->new_message(MSG_RANDOM_SELECTED);
|
2021-09-04 22:04:14 +02:00
|
|
|
message->write<uint8_t>(playerid);
|
|
|
|
|
message->write<uint32_t>(count);
|
2019-06-23 14:15:19 +08:00
|
|
|
for(auto& pcard : newgroup->container) {
|
2019-07-16 00:57:53 +02:00
|
|
|
message->write(pcard->get_info_location());
|
2019-06-23 14:15:19 +08:00
|
|
|
}
|
2020-07-20 22:05:04 +02:00
|
|
|
interpreter::pushobject(L, newgroup);
|
2019-06-23 14:15:19 +08:00
|
|
|
return 1;
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(IsExists) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_param_count(L, 4);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 2);
|
2023-11-21 11:56:23 +01:00
|
|
|
card_set cset(self->container);
|
2023-12-03 11:34:38 +01:00
|
|
|
if(auto [pexception, pexgroup] = lua_get_card_or_group<true>(L, 4); pexception) {
|
2017-02-08 21:16:32 +09:00
|
|
|
cset.erase(pexception);
|
2023-12-03 10:27:47 +01:00
|
|
|
} else if(pexgroup) {
|
2018-09-03 16:36:45 +08:00
|
|
|
for(auto& pcard : pexgroup->container)
|
|
|
|
|
cset.erase(pcard);
|
2017-02-08 21:16:32 +09:00
|
|
|
}
|
2021-09-04 22:04:14 +02:00
|
|
|
auto count = lua_get<uint16_t>(L, 3);
|
|
|
|
|
uint32_t extraargs = lua_gettop(L) - 4;
|
|
|
|
|
uint32_t fcount = 0;
|
2021-10-13 17:29:29 +02:00
|
|
|
for(auto& pcard : cset) {
|
2022-06-11 12:59:38 +02:00
|
|
|
if(pduel->lua->check_matching(pcard, findex, extraargs)) {
|
2022-03-05 13:56:43 +01:00
|
|
|
++fcount;
|
2020-07-20 19:44:59 +02:00
|
|
|
if(fcount >= count)
|
2015-09-25 21:07:16 +08:00
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-07-20 19:44:59 +02:00
|
|
|
lua_pushboolean(L, fcount >= count);
|
2015-09-25 21:07:16 +08:00
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(CheckWithSumEqual) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_param_count(L, 5);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 2);
|
2021-09-04 22:04:14 +02:00
|
|
|
auto acc = lua_get<uint32_t>(L, 3);
|
|
|
|
|
auto min = lua_get<int32_t>(L, 4);
|
|
|
|
|
auto max = lua_get<int32_t>(L, 5);
|
2016-03-18 00:48:52 +09:00
|
|
|
if(min < 0)
|
|
|
|
|
min = 0;
|
2015-09-25 21:07:16 +08:00
|
|
|
if(max < min)
|
|
|
|
|
max = min;
|
2021-09-04 22:04:14 +02:00
|
|
|
int32_t extraargs = lua_gettop(L) - 5;
|
2021-09-04 20:46:43 +02:00
|
|
|
card_vector cv(pduel->game_field->core.must_select_cards);
|
2023-02-07 16:43:27 +01:00
|
|
|
int32_t mcount = static_cast<int32_t>(cv.size());
|
2021-12-04 15:51:42 +01:00
|
|
|
const auto beginit = pduel->game_field->core.must_select_cards.begin();
|
|
|
|
|
const auto endit = pduel->game_field->core.must_select_cards.end();
|
2023-11-21 11:56:23 +01:00
|
|
|
for(auto& pcard : self->container) {
|
2021-12-04 15:51:42 +01:00
|
|
|
if(std::find(beginit, endit, pcard) == endit)
|
2018-09-03 16:36:45 +08:00
|
|
|
cv.push_back(pcard);
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
2016-03-18 00:48:52 +09:00
|
|
|
pduel->game_field->core.must_select_cards.clear();
|
2025-04-25 11:00:10 +02:00
|
|
|
for(auto& pcard : cv) {
|
|
|
|
|
if(pcard->sum_param = pduel->lua->get_operation_value(pcard, findex, extraargs); pcard->sum_param == 0) {
|
|
|
|
|
lua_error(L, "Group contains a card for which the value function returned 0.");
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-09-04 22:04:14 +02:00
|
|
|
int32_t should_continue = TRUE;
|
2019-12-10 19:04:45 +01:00
|
|
|
lua_pushboolean(L, field::check_with_sum_limit_m(cv, acc, 0, min, max, mcount, &should_continue));
|
|
|
|
|
lua_pushboolean(L, should_continue);
|
|
|
|
|
return 2;
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(SelectWithSumEqual) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_action_permission(L);
|
|
|
|
|
check_param_count(L, 6);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 3);
|
2021-09-04 22:04:14 +02:00
|
|
|
auto playerid = lua_get<uint8_t>(L, 2);
|
2015-09-25 21:07:16 +08:00
|
|
|
if(playerid != 0 && playerid != 1)
|
|
|
|
|
return 0;
|
2021-09-04 22:04:14 +02:00
|
|
|
auto acc = lua_get<uint32_t>(L, 4);
|
|
|
|
|
auto min = lua_get<int32_t>(L, 5);
|
|
|
|
|
auto max = lua_get<int32_t>(L, 6);
|
2016-03-18 00:48:52 +09:00
|
|
|
if(min < 0)
|
|
|
|
|
min = 0;
|
2015-09-25 21:07:16 +08:00
|
|
|
if(max < min)
|
|
|
|
|
max = min;
|
2021-09-04 22:04:14 +02:00
|
|
|
int32_t extraargs = lua_gettop(L) - 6;
|
2023-11-21 11:56:23 +01:00
|
|
|
pduel->game_field->core.select_cards.assign(self->container.begin(), self->container.end());
|
2018-09-03 16:36:45 +08:00
|
|
|
for(auto& pcard : pduel->game_field->core.must_select_cards) {
|
|
|
|
|
auto it = std::remove(pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end(), pcard);
|
2015-12-19 09:56:22 +09:00
|
|
|
pduel->game_field->core.select_cards.erase(it, pduel->game_field->core.select_cards.end());
|
|
|
|
|
}
|
2021-09-04 20:46:43 +02:00
|
|
|
card_vector cv(pduel->game_field->core.must_select_cards);
|
2023-02-07 16:43:27 +01:00
|
|
|
int32_t mcount = static_cast<int32_t>(cv.size());
|
2015-12-19 09:56:22 +09:00
|
|
|
cv.insert(cv.end(), pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end());
|
2025-04-25 11:00:10 +02:00
|
|
|
for(auto& pcard : cv) {
|
|
|
|
|
if(pcard->sum_param = pduel->lua->get_operation_value(pcard, findex, extraargs); pcard->sum_param == 0) {
|
|
|
|
|
lua_error(L, "Group contains a card for which the value function returned 0.");
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-12-10 19:04:45 +01:00
|
|
|
if(!field::check_with_sum_limit_m(cv, acc, 0, min, max, mcount, nullptr)) {
|
2016-03-18 00:48:52 +09:00
|
|
|
pduel->game_field->core.must_select_cards.clear();
|
2025-05-03 12:54:01 +02:00
|
|
|
auto empty_group = pduel->new_group();
|
2020-07-20 22:05:04 +02:00
|
|
|
interpreter::pushobject(L, empty_group);
|
2016-12-06 19:07:43 +08:00
|
|
|
return 1;
|
2016-03-18 00:48:52 +09:00
|
|
|
}
|
2024-01-08 20:46:41 +01:00
|
|
|
pduel->game_field->emplace_process<Processors::SelectSum>(playerid, acc, min, max);
|
2023-11-25 11:15:21 +01:00
|
|
|
return yieldk({
|
2025-05-03 12:54:01 +02:00
|
|
|
auto pgroup = pduel->new_group(pduel->game_field->return_cards.list);
|
2019-06-23 14:15:19 +08:00
|
|
|
pduel->game_field->core.must_select_cards.clear();
|
2020-07-20 22:05:04 +02:00
|
|
|
interpreter::pushobject(L, pgroup);
|
2019-06-23 14:15:19 +08:00
|
|
|
return 1;
|
2021-12-04 15:51:42 +01:00
|
|
|
});
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(CheckWithSumGreater) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_param_count(L, 3);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 2);
|
2021-09-04 22:04:14 +02:00
|
|
|
auto acc = lua_get<uint32_t>(L, 3);
|
|
|
|
|
int32_t extraargs = lua_gettop(L) - 3;
|
2021-09-04 20:46:43 +02:00
|
|
|
card_vector cv(pduel->game_field->core.must_select_cards);
|
2023-02-07 16:43:27 +01:00
|
|
|
int32_t mcount = static_cast<int32_t>(cv.size());
|
2021-12-04 15:51:42 +01:00
|
|
|
const auto beginit = pduel->game_field->core.must_select_cards.begin();
|
|
|
|
|
const auto endit = pduel->game_field->core.must_select_cards.end();
|
2023-11-21 11:56:23 +01:00
|
|
|
for(auto& pcard : self->container) {
|
2021-12-04 15:51:42 +01:00
|
|
|
if(std::find(beginit, endit, pcard) == endit)
|
2018-09-03 16:36:45 +08:00
|
|
|
cv.push_back(pcard);
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
2016-03-18 00:48:52 +09:00
|
|
|
pduel->game_field->core.must_select_cards.clear();
|
2025-04-25 11:00:10 +02:00
|
|
|
for(auto& pcard : cv) {
|
|
|
|
|
if(pcard->sum_param = pduel->lua->get_operation_value(pcard, findex, extraargs); pcard->sum_param == 0) {
|
|
|
|
|
lua_error(L, "Group contains a card for which the value function returned 0.");
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-09-04 22:04:14 +02:00
|
|
|
int32_t should_continue = TRUE;
|
2019-12-10 19:04:45 +01:00
|
|
|
lua_pushboolean(L, field::check_with_sum_greater_limit_m(cv, acc, 0, 0xffff, mcount, &should_continue));
|
|
|
|
|
lua_pushboolean(L, should_continue);
|
|
|
|
|
return 2;
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(SelectWithSumGreater) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_action_permission(L);
|
|
|
|
|
check_param_count(L, 4);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 3);
|
2021-09-04 22:04:14 +02:00
|
|
|
auto playerid = lua_get<uint8_t>(L, 2);
|
2015-09-25 21:07:16 +08:00
|
|
|
if(playerid != 0 && playerid != 1)
|
|
|
|
|
return 0;
|
2021-09-04 22:04:14 +02:00
|
|
|
auto acc = lua_get<uint32_t>(L, 4);
|
|
|
|
|
int32_t extraargs = lua_gettop(L) - 4;
|
2023-11-21 11:56:23 +01:00
|
|
|
pduel->game_field->core.select_cards.assign(self->container.begin(), self->container.end());
|
2018-09-03 16:36:45 +08:00
|
|
|
for(auto& pcard : pduel->game_field->core.must_select_cards) {
|
|
|
|
|
auto it = std::remove(pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end(), pcard);
|
2016-03-18 00:48:52 +09:00
|
|
|
pduel->game_field->core.select_cards.erase(it, pduel->game_field->core.select_cards.end());
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
2021-09-04 20:46:43 +02:00
|
|
|
card_vector cv(pduel->game_field->core.must_select_cards);
|
2023-02-07 16:43:27 +01:00
|
|
|
int32_t mcount = static_cast<int32_t>(cv.size());
|
2016-03-18 00:48:52 +09:00
|
|
|
cv.insert(cv.end(), pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end());
|
2025-04-25 11:00:10 +02:00
|
|
|
for(auto& pcard : cv) {
|
|
|
|
|
if(pcard->sum_param = pduel->lua->get_operation_value(pcard, findex, extraargs); pcard->sum_param == 0) {
|
|
|
|
|
lua_error(L, "Group contains a card for which the value function returned 0.");
|
|
|
|
|
}
|
|
|
|
|
}
|
2019-12-10 19:04:45 +01:00
|
|
|
if(!field::check_with_sum_greater_limit_m(cv, acc, 0, 0xffff, mcount, nullptr)) {
|
2016-03-18 00:48:52 +09:00
|
|
|
pduel->game_field->core.must_select_cards.clear();
|
2025-05-03 12:54:01 +02:00
|
|
|
auto empty_group = pduel->new_group();
|
2020-07-20 22:05:04 +02:00
|
|
|
interpreter::pushobject(L, empty_group);
|
2016-12-06 19:07:43 +08:00
|
|
|
return 1;
|
2016-03-18 00:48:52 +09:00
|
|
|
}
|
2024-01-08 20:46:41 +01:00
|
|
|
pduel->game_field->emplace_process<Processors::SelectSum>(playerid, acc, 0, 0);
|
2023-11-25 11:15:21 +01:00
|
|
|
return yieldk({
|
2025-05-03 12:54:01 +02:00
|
|
|
auto pgroup = pduel->new_group(pduel->game_field->return_cards.list);
|
2019-06-23 14:15:19 +08:00
|
|
|
pduel->game_field->core.must_select_cards.clear();
|
2020-07-20 22:05:04 +02:00
|
|
|
interpreter::pushobject(L, pgroup);
|
2019-06-23 14:15:19 +08:00
|
|
|
return 1;
|
2022-05-14 19:55:59 +02:00
|
|
|
});
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(GetMinGroup) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_param_count(L, 2);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 2);
|
2023-11-21 11:56:23 +01:00
|
|
|
if(self->container.size() == 0)
|
2015-09-25 21:07:16 +08:00
|
|
|
return 0;
|
2025-05-03 12:54:01 +02:00
|
|
|
auto newgroup = pduel->new_group();
|
2022-08-27 16:59:47 +02:00
|
|
|
int64_t min, op;
|
2021-09-04 22:04:14 +02:00
|
|
|
int32_t extraargs = lua_gettop(L) - 2;
|
2023-11-21 11:56:23 +01:00
|
|
|
auto cit = self->container.begin();
|
2022-06-11 12:59:38 +02:00
|
|
|
min = pduel->lua->get_operation_value(*cit, findex, extraargs);
|
2015-09-25 21:07:16 +08:00
|
|
|
newgroup->container.insert(*cit);
|
|
|
|
|
++cit;
|
2023-11-21 11:56:23 +01:00
|
|
|
for(; cit != self->container.end(); ++cit) {
|
2022-06-11 12:59:38 +02:00
|
|
|
op = pduel->lua->get_operation_value(*cit, findex, extraargs);
|
2015-09-25 21:07:16 +08:00
|
|
|
if(op == min)
|
|
|
|
|
newgroup->container.insert(*cit);
|
|
|
|
|
else if(op < min) {
|
|
|
|
|
newgroup->container.clear();
|
|
|
|
|
newgroup->container.insert(*cit);
|
|
|
|
|
min = op;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-07-20 22:05:04 +02:00
|
|
|
interpreter::pushobject(L, newgroup);
|
2015-09-25 21:07:16 +08:00
|
|
|
lua_pushinteger(L, min);
|
|
|
|
|
return 2;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(GetMaxGroup) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_param_count(L, 2);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 2);
|
2023-11-21 11:56:23 +01:00
|
|
|
if(self->container.size() == 0)
|
2015-09-25 21:07:16 +08:00
|
|
|
return 0;
|
2025-05-03 12:54:01 +02:00
|
|
|
auto newgroup = pduel->new_group();
|
2022-08-27 16:59:47 +02:00
|
|
|
int64_t max, op;
|
2021-09-04 22:04:14 +02:00
|
|
|
int32_t extraargs = lua_gettop(L) - 2;
|
2023-11-21 11:56:23 +01:00
|
|
|
auto cit = self->container.begin();
|
2022-06-11 12:59:38 +02:00
|
|
|
max = pduel->lua->get_operation_value(*cit, findex, extraargs);
|
2015-09-25 21:07:16 +08:00
|
|
|
newgroup->container.insert(*cit);
|
|
|
|
|
++cit;
|
2023-11-21 11:56:23 +01:00
|
|
|
for(; cit != self->container.end(); ++cit) {
|
2022-06-11 12:59:38 +02:00
|
|
|
op = pduel->lua->get_operation_value(*cit, findex, extraargs);
|
2015-09-25 21:07:16 +08:00
|
|
|
if(op == max)
|
|
|
|
|
newgroup->container.insert(*cit);
|
|
|
|
|
else if(op > max) {
|
|
|
|
|
newgroup->container.clear();
|
|
|
|
|
newgroup->container.insert(*cit);
|
|
|
|
|
max = op;
|
|
|
|
|
}
|
|
|
|
|
}
|
2020-07-20 22:05:04 +02:00
|
|
|
interpreter::pushobject(L, newgroup);
|
2015-09-25 21:07:16 +08:00
|
|
|
lua_pushinteger(L, max);
|
|
|
|
|
return 2;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(GetSum) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_param_count(L, 2);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 2);
|
2021-09-04 22:04:14 +02:00
|
|
|
int32_t extraargs = lua_gettop(L) - 2;
|
2022-08-27 16:59:47 +02:00
|
|
|
int64_t sum = 0;
|
2023-11-21 11:56:23 +01:00
|
|
|
for(auto& pcard : self->container) {
|
2022-06-11 12:59:38 +02:00
|
|
|
sum += pduel->lua->get_operation_value(pcard, findex, extraargs);
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
|
|
|
|
lua_pushinteger(L, sum);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-15 16:08:07 +02:00
|
|
|
LUA_FUNCTION(GetBitwiseAnd) {
|
|
|
|
|
check_param_count(L, 2);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 2);
|
2022-05-15 16:08:07 +02:00
|
|
|
int32_t extraargs = lua_gettop(L) - 2;
|
|
|
|
|
uint64_t total = 0;
|
2023-11-21 11:56:23 +01:00
|
|
|
for(auto& pcard : self->container) {
|
2022-06-11 12:59:38 +02:00
|
|
|
total &= static_cast<uint64_t>(pduel->lua->get_operation_value(pcard, findex, extraargs));
|
2022-05-15 16:08:07 +02:00
|
|
|
}
|
|
|
|
|
lua_pushinteger(L, total);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
LUA_FUNCTION(GetBitwiseOr) {
|
|
|
|
|
check_param_count(L, 2);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 2);
|
2022-05-15 16:08:07 +02:00
|
|
|
int32_t extraargs = lua_gettop(L) - 2;
|
|
|
|
|
uint64_t total = 0;
|
2023-11-21 11:56:23 +01:00
|
|
|
for(auto& pcard : self->container) {
|
2022-06-11 12:59:38 +02:00
|
|
|
total |= static_cast<uint64_t>(pduel->lua->get_operation_value(pcard, findex, extraargs));
|
2022-05-15 16:08:07 +02:00
|
|
|
}
|
|
|
|
|
lua_pushinteger(L, total);
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(GetClass) {
|
2020-02-12 19:41:43 +01:00
|
|
|
check_param_count(L, 2);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 2);
|
2021-09-04 22:04:14 +02:00
|
|
|
int32_t extraargs = lua_gettop(L) - 2;
|
2022-08-27 16:59:47 +02:00
|
|
|
std::set<int64_t> er;
|
2023-11-21 11:56:23 +01:00
|
|
|
for(auto& pcard : self->container) {
|
2022-06-11 12:59:38 +02:00
|
|
|
er.insert(pduel->lua->get_operation_value(pcard, findex, extraargs));
|
2020-02-12 19:41:43 +01:00
|
|
|
}
|
2024-04-15 22:39:25 +02:00
|
|
|
lua_createtable(L, static_cast<int>(er.size()), 0);
|
2020-02-12 19:41:43 +01:00
|
|
|
int i = 1;
|
|
|
|
|
for(auto& val : er) {
|
2020-07-23 23:50:09 +02:00
|
|
|
lua_pushinteger(L, i++);
|
2020-02-12 19:41:43 +01:00
|
|
|
lua_pushinteger(L, val);
|
|
|
|
|
lua_settable(L, -3);
|
|
|
|
|
}
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(GetClassCount) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_param_count(L, 2);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 2);
|
2021-09-04 22:04:14 +02:00
|
|
|
int32_t extraargs = lua_gettop(L) - 2;
|
2022-08-27 16:59:47 +02:00
|
|
|
std::set<int64_t> er;
|
2023-11-21 11:56:23 +01:00
|
|
|
for(auto& pcard : self->container) {
|
2022-06-11 12:59:38 +02:00
|
|
|
er.insert(pduel->lua->get_operation_value(pcard, findex, extraargs));
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
|
|
|
|
lua_pushinteger(L, er.size());
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(Remove) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_param_count(L, 3);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 2);
|
2023-11-21 11:56:23 +01:00
|
|
|
assert_readonly_group(L, self);
|
|
|
|
|
self->is_iterator_dirty = true;
|
2021-09-04 22:04:14 +02:00
|
|
|
uint32_t extraargs = lua_gettop(L) - 3;
|
2023-12-03 10:26:44 +01:00
|
|
|
auto& cset = self->container;
|
2023-12-03 11:34:38 +01:00
|
|
|
if(auto [pexception, pexgroup] = lua_get_card_or_group<true>(L, 3); pexception) {
|
2023-12-03 10:26:44 +01:00
|
|
|
for(auto cit = cset.begin(), cend = cset.end(); cit != cend; ) {
|
|
|
|
|
auto rm = cit++;
|
|
|
|
|
auto* pcard = *rm;
|
|
|
|
|
if(pcard != pexception && pduel->lua->check_matching(pcard, findex, extraargs))
|
|
|
|
|
cset.erase(rm);
|
|
|
|
|
}
|
|
|
|
|
} else if(pexgroup) {
|
|
|
|
|
auto should_keep = [pexbegin = pexgroup->container.cbegin(), pexend = pexgroup->container.cend()](card* pcard) mutable {
|
|
|
|
|
if(pexbegin == pexend)
|
|
|
|
|
return false;
|
|
|
|
|
if(*pexbegin == pcard) {
|
|
|
|
|
++pexbegin;
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
return false;
|
|
|
|
|
};
|
|
|
|
|
for(auto cit = cset.begin(), cend = cset.end(); cit != cend; ) {
|
|
|
|
|
auto rm = cit++;
|
|
|
|
|
auto* pcard = *rm;
|
|
|
|
|
if(!should_keep(pcard) && pduel->lua->check_matching(pcard, findex, extraargs))
|
|
|
|
|
cset.erase(rm);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
for(auto cit = cset.begin(), cend = cset.end(); cit != cend; ) {
|
|
|
|
|
auto rm = cit++;
|
|
|
|
|
auto* pcard = *rm;
|
|
|
|
|
if(pduel->lua->check_matching(pcard, findex, extraargs))
|
|
|
|
|
cset.erase(rm);
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
|
|
|
|
}
|
2023-11-21 11:56:23 +01:00
|
|
|
interpreter::pushobject(L, self);
|
2021-08-10 16:05:36 +02:00
|
|
|
return 1;
|
2015-09-25 21:07:16 +08:00
|
|
|
}
|
2023-12-03 11:19:22 +01:00
|
|
|
std::tuple<group*, group*, card*> get_binary_op_group_card_parameters(lua_State* L) {
|
2020-07-21 15:03:03 +02:00
|
|
|
auto obj1 = lua_get<lua_obj*>(L, 1);
|
2020-07-31 22:55:46 +02:00
|
|
|
auto obj2 = lua_get<lua_obj*>(L, 2);
|
2023-12-03 11:19:22 +01:00
|
|
|
if(!obj1 || !obj2)
|
2022-06-23 11:47:00 +02:00
|
|
|
lua_error(L, "At least 1 parameter should be \"Group\".");
|
2023-12-08 19:53:35 +01:00
|
|
|
if(obj1->lua_type != LuaParam::GROUP)
|
2023-12-03 11:19:22 +01:00
|
|
|
std::swap(obj1, obj2);
|
2023-12-08 19:53:35 +01:00
|
|
|
if(obj1->lua_type != LuaParam::GROUP)
|
2023-12-03 11:19:22 +01:00
|
|
|
lua_error(L, "At least 1 parameter should be \"Group\".");
|
|
|
|
|
|
|
|
|
|
switch(obj2->lua_type) {
|
2023-12-08 19:53:35 +01:00
|
|
|
case LuaParam::GROUP:
|
2023-12-03 11:19:22 +01:00
|
|
|
return { static_cast<group*>(obj1), static_cast<group*>(obj2), nullptr};
|
2023-12-08 19:53:35 +01:00
|
|
|
case LuaParam::CARD:
|
2023-12-03 11:19:22 +01:00
|
|
|
return { static_cast<group*>(obj1), nullptr, static_cast<card*>(obj2) };
|
|
|
|
|
default:
|
2022-06-23 11:47:00 +02:00
|
|
|
lua_error(L, "A parameter isn't \"Group\" nor \"Card\".");
|
2020-07-21 15:03:03 +02:00
|
|
|
}
|
|
|
|
|
}
|
2023-11-21 11:56:23 +01:00
|
|
|
LUA_STATIC_FUNCTION(__band) {
|
2020-02-12 00:21:50 +01:00
|
|
|
check_param_count(L, 2);
|
2025-05-03 12:54:01 +02:00
|
|
|
auto [pgroup1, pgroup2, pcard] = get_binary_op_group_card_parameters(L);
|
2021-09-04 20:46:43 +02:00
|
|
|
card_set cset;
|
2025-05-03 12:54:01 +02:00
|
|
|
if(pcard) {
|
2020-10-30 17:05:28 +01:00
|
|
|
if(pgroup1->has_card(pcard)) {
|
2020-02-12 00:21:50 +01:00
|
|
|
cset.insert(pcard);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
2020-10-31 02:06:44 +01:00
|
|
|
std::set_intersection(pgroup1->container.cbegin(), pgroup1->container.cend(), pgroup2->container.cbegin(), pgroup2->container.cend(),
|
|
|
|
|
std::inserter(cset, cset.begin()), card_sort());
|
2020-02-12 00:21:50 +01:00
|
|
|
}
|
2021-09-04 20:46:43 +02:00
|
|
|
interpreter::pushobject(L, pduel->new_group(std::move(cset)));
|
2020-02-12 00:21:50 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
2023-11-21 11:56:23 +01:00
|
|
|
LUA_STATIC_FUNCTION(__add) {
|
2020-02-12 00:21:50 +01:00
|
|
|
check_param_count(L, 2);
|
2023-12-03 11:19:22 +01:00
|
|
|
auto [pgroup1, pgroup2, pcard] = get_binary_op_group_card_parameters(L);
|
2025-05-03 12:54:01 +02:00
|
|
|
auto newgroup = pduel->new_group(pgroup1);
|
2020-02-12 00:21:50 +01:00
|
|
|
if(pcard) {
|
|
|
|
|
newgroup->container.insert(pcard);
|
|
|
|
|
} else {
|
|
|
|
|
newgroup->container.insert(pgroup2->container.begin(), pgroup2->container.end());
|
|
|
|
|
}
|
2020-07-20 22:05:04 +02:00
|
|
|
interpreter::pushobject(L, newgroup);
|
2020-02-12 00:21:50 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(__sub) {
|
2020-02-12 00:21:50 +01:00
|
|
|
check_param_count(L, 2);
|
2023-12-03 11:34:38 +01:00
|
|
|
auto [pcard, pgroup] = lua_get_card_or_group(L, 2);
|
2025-05-03 12:54:01 +02:00
|
|
|
auto newgroup = pduel->new_group(self);
|
2023-11-26 15:11:50 +01:00
|
|
|
if(pgroup) {
|
|
|
|
|
for(auto& _pcard : pgroup->container)
|
2020-09-16 17:12:50 +02:00
|
|
|
newgroup->container.erase(_pcard);
|
2021-08-11 14:24:03 +02:00
|
|
|
} else
|
2020-02-12 00:21:50 +01:00
|
|
|
newgroup->container.erase(pcard);
|
2020-07-20 22:05:04 +02:00
|
|
|
interpreter::pushobject(L, newgroup);
|
2020-02-12 00:21:50 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(__len) {
|
2023-11-21 11:56:23 +01:00
|
|
|
lua_pushinteger(L, self->container.size());
|
2020-02-12 00:21:50 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(__eq) {
|
2020-02-12 00:21:50 +01:00
|
|
|
check_param_count(L, 2);
|
2020-07-21 01:21:25 +02:00
|
|
|
auto sgroup = lua_get<group*, true>(L, 2);
|
2023-11-21 11:56:23 +01:00
|
|
|
lua_pushboolean(L, self->container.size() == sgroup->container.size());
|
2020-02-12 00:21:50 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(Equal) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_param_count(L, 2);
|
2020-07-21 01:21:25 +02:00
|
|
|
auto sgroup = lua_get<group*, true>(L, 2);
|
2023-11-21 11:56:23 +01:00
|
|
|
lua_pushboolean(L, self->container == sgroup->container);
|
2015-09-25 21:07:16 +08:00
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(__lt) {
|
2020-02-12 00:21:50 +01:00
|
|
|
check_param_count(L, 2);
|
2020-07-21 01:21:25 +02:00
|
|
|
auto sgroup = lua_get<group*, true>(L, 2);
|
2023-11-21 11:56:23 +01:00
|
|
|
lua_pushboolean(L, self->container.size() < sgroup->container.size());
|
2020-02-12 00:21:50 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(__le) {
|
2020-02-12 00:21:50 +01:00
|
|
|
check_param_count(L, 2);
|
2020-07-21 01:21:25 +02:00
|
|
|
auto sgroup = lua_get<group*, true>(L, 2);
|
2023-11-21 11:56:23 +01:00
|
|
|
lua_pushboolean(L, self->container.size() <= sgroup->container.size());
|
2020-02-12 00:21:50 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
2025-05-03 12:54:01 +02:00
|
|
|
LUA_FUNCTION(__gc) {
|
2025-05-09 19:11:14 +02:00
|
|
|
pduel->delete_group(self);
|
2025-05-03 12:54:01 +02:00
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(IsContains) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_param_count(L, 2);
|
2020-07-21 01:21:25 +02:00
|
|
|
auto pcard = lua_get<card*, true>(L, 2);
|
2023-11-21 11:56:23 +01:00
|
|
|
lua_pushboolean(L, self->has_card(pcard));
|
2015-09-25 21:07:16 +08:00
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(SearchCard) {
|
2015-09-25 21:07:16 +08:00
|
|
|
check_param_count(L, 2);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 2);
|
2021-09-04 22:04:14 +02:00
|
|
|
uint32_t extraargs = lua_gettop(L) - 2;
|
2023-11-21 11:56:23 +01:00
|
|
|
for(auto& pcard : self->container)
|
2022-06-11 12:59:38 +02:00
|
|
|
if(pduel->lua->check_matching(pcard, findex, extraargs)) {
|
2020-07-20 22:05:04 +02:00
|
|
|
interpreter::pushobject(L, pcard);
|
2015-09-25 21:07:16 +08:00
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(Split) {
|
2020-02-12 00:21:50 +01:00
|
|
|
check_param_count(L, 3);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 2);
|
2023-11-21 11:56:23 +01:00
|
|
|
card_set cset(self->container);
|
2021-09-04 20:46:43 +02:00
|
|
|
card_set notmatching;
|
2023-12-03 11:34:38 +01:00
|
|
|
if(auto [pexception, pexgroup] = lua_get_card_or_group<true>(L, 3); pexception) {
|
2020-02-12 00:21:50 +01:00
|
|
|
cset.erase(pexception);
|
|
|
|
|
notmatching.insert(pexception);
|
2023-12-03 10:27:47 +01:00
|
|
|
} else if(pexgroup) {
|
2020-02-12 00:21:50 +01:00
|
|
|
for(auto& pcard : pexgroup->container) {
|
|
|
|
|
cset.erase(pcard);
|
|
|
|
|
notmatching.insert(pcard);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-09-04 22:04:14 +02:00
|
|
|
uint32_t extraargs = lua_gettop(L) - 3;
|
2022-10-25 15:40:48 +02:00
|
|
|
for(auto it = cset.begin(); it != cset.end();) {
|
|
|
|
|
auto pcard = *it;
|
2022-06-11 12:59:38 +02:00
|
|
|
if(pduel->lua->check_matching(pcard, findex, extraargs)) {
|
2022-10-25 15:40:48 +02:00
|
|
|
++it;
|
2020-02-12 00:21:50 +01:00
|
|
|
} else {
|
|
|
|
|
notmatching.insert(pcard);
|
2022-10-25 15:40:48 +02:00
|
|
|
it = cset.erase(it);
|
2020-02-12 00:21:50 +01:00
|
|
|
}
|
|
|
|
|
}
|
2022-10-25 15:40:48 +02:00
|
|
|
interpreter::pushobject(L, pduel->new_group(std::move(cset)));
|
2021-09-04 20:46:43 +02:00
|
|
|
interpreter::pushobject(L, pduel->new_group(std::move(notmatching)));
|
2020-02-12 00:21:50 +01:00
|
|
|
return 2;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(Includes) {
|
2020-02-12 00:21:50 +01:00
|
|
|
check_param_count(L, 2);
|
2020-07-21 01:21:25 +02:00
|
|
|
auto pgroup2 = lua_get<group*, true>(L, 2);
|
2020-10-31 01:58:04 +01:00
|
|
|
int res = TRUE;
|
2023-11-21 11:56:23 +01:00
|
|
|
if(self->container.size() < pgroup2->container.size())
|
2020-10-31 01:58:04 +01:00
|
|
|
res = FALSE;
|
2021-10-13 17:29:29 +02:00
|
|
|
else if(!pgroup2->container.empty())
|
2023-11-21 11:56:23 +01:00
|
|
|
res = std::includes(self->container.cbegin(), self->container.cend(), pgroup2->container.cbegin(), pgroup2->container.cend(), card_sort());
|
2020-10-31 01:58:04 +01:00
|
|
|
lua_pushboolean(L, res);
|
2020-02-12 00:21:50 +01:00
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION(GetBinClassCount) {
|
2018-04-27 21:17:45 +08:00
|
|
|
check_param_count(L, 2);
|
2022-06-11 12:59:38 +02:00
|
|
|
const auto findex = lua_get<function, true>(L, 2);
|
2021-09-04 22:04:14 +02:00
|
|
|
int32_t extraargs = lua_gettop(L) - 2;
|
2022-08-27 16:49:51 +02:00
|
|
|
uint64_t er = 0;
|
2023-11-21 11:56:23 +01:00
|
|
|
for(auto& pcard : self->container)
|
2022-08-27 16:49:51 +02:00
|
|
|
er |= static_cast<uint64_t>(pduel->lua->get_operation_value(pcard, findex, extraargs));
|
2023-04-23 21:34:36 +02:00
|
|
|
lua_pushinteger(L, bit::popcnt(er));
|
2018-04-27 21:17:45 +08:00
|
|
|
return 1;
|
|
|
|
|
}
|
2022-05-14 19:55:59 +02:00
|
|
|
LUA_FUNCTION_EXISTING(GetLuaRef, get_lua_ref<group>);
|
|
|
|
|
LUA_FUNCTION_EXISTING(FromLuaRef, from_lua_ref<group>);
|
|
|
|
|
LUA_FUNCTION_EXISTING(IsDeleted, is_deleted_object);
|
2021-10-13 17:29:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void scriptlib::push_group_lib(lua_State* L) {
|
2022-05-14 19:55:59 +02:00
|
|
|
static constexpr auto grouplib = GET_LUA_FUNCTIONS_ARRAY();
|
2023-11-26 14:47:09 +01:00
|
|
|
static_assert(grouplib.back().name == nullptr);
|
2023-02-07 16:43:27 +01:00
|
|
|
lua_createtable(L, 0, static_cast<int>(grouplib.size() - 1));
|
2024-04-13 10:34:09 +02:00
|
|
|
ensure_luaL_stack(luaL_setfuncs, L, grouplib.data(), 0);
|
2021-10-13 17:29:29 +02:00
|
|
|
lua_pushstring(L, "__index");
|
|
|
|
|
lua_pushvalue(L, -2);
|
|
|
|
|
lua_rawset(L, -3);
|
|
|
|
|
lua_setglobal(L, "Group");
|
2023-02-07 16:43:27 +01:00
|
|
|
}
|