Commit 287dd26c authored by mercury233's avatar mercury233

Merge branch 'master' into patch-skip-confirm

parents b05c44a7 6b81a1af
name: Automated Test Build
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build-windows:
runs-on: windows-2022
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Download lua
id: lua
uses: mercury233/action-cache-download-file@v1.0.0
with:
url: https://www.lua.org/ftp/lua-5.4.8.tar.gz
- name: Lua
run: |
tar -xzf ${{ steps.lua.outputs.filepath }}
move lua-5.4.8 lua
- name: Download premake
id: premake
uses: mercury233/action-cache-download-file@v1.0.0
with:
url: https://github.com/premake/premake-core/releases/download/v5.0.0-beta7/premake-5.0.0-beta7-windows.zip
- name: Premake
run: |
mkdir premake-5
tar -C premake-5 -xzf ${{ steps.premake.outputs.filepath }}
copy premake\lua.lua lua\premake5.lua
copy premake\dll.lua dll.lua
.\premake-5\premake5.exe vs2022 --file=dll.lua
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v2
- name: Build x32
run: |
msbuild build\ocgcoredll.sln /t:Build /p:"Configuration=Release;Platform=Win32"
- name: Build x64
run: |
msbuild build\ocgcoredll.sln /t:Build /p:"Configuration=Release;Platform=x64"
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: ocgcore-windows
path: |
build\bin\x32\Release\ocgcore.dll
build\bin\x64\Release\ocgcore.dll
- name: GitHub Release
if: github.event_name == 'push'
uses: salix5/action-automatic-releases@node20
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "latest"
prerelease: true
title: "Development Build"
files: |
build/bin/x64/Release/ocgcore.dll
build-linux:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y gcc-multilib g++-multilib
- name: Download lua
id: lua
uses: mercury233/action-cache-download-file@v1.0.0
with:
url: https://www.lua.org/ftp/lua-5.4.8.tar.gz
- name: Lua
run: |
tar -xzf ${{ steps.lua.outputs.filepath }}
mv lua-5.4.8 lua
- name: Download premake
id: premake
uses: mercury233/action-cache-download-file@v1.0.0
with:
url: https://github.com/premake/premake-core/releases/download/v5.0.0-beta7/premake-5.0.0-beta7-linux.tar.gz
- name: Premake
run: |
mkdir premake-5
tar -C premake-5 -xzf ${{ steps.premake.outputs.filepath }}
cp premake/lua.lua lua/premake5.lua
cp premake/dll.lua dll.lua
chmod +x premake-5/premake5
./premake-5/premake5 gmake --file=dll.lua
- name: Build x32
run: |
cd build
make -j 4 config=release_x32
cd ..
- name: Build x64
run: |
cd build
make -j 4 config=release_x64
cd ..
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: ocgcore-linux
path: |
build/bin/x32/Release/libocgcore.so
build/bin/x64/Release/libocgcore.so
/.vscode/
/build/
/lua/
/temp/
/premake-5/
/premake5.exe
...@@ -4,64 +4,71 @@ ...@@ -4,64 +4,71 @@
The core logic and lua script processor of YGOPro. This library can be made external of the project and used to power server technologies. It maintains a state engine that is manipulated by Lua scripts using manipulation functions it exposes. The core logic and lua script processor of YGOPro. This library can be made external of the project and used to power server technologies. It maintains a state engine that is manipulated by Lua scripts using manipulation functions it exposes.
## Compiling ## Compiling
### 1.) Download Fluorohydride/ygopro In most cases, what you want to compile is the main program of YGOPro. You should refer to the main YGOPro project's [wiki](https://github.com/Fluorohydride/ygopro/wiki).
Start by downloading the most parent of the source code. The team developing this project are the defacto edge and experts in our community. The most upto date `ocgcore` is a compiled dll version of the `Fluorohydride/ygopro/ocgcore` folders project. If you want to compile the dynamic link library of this repository (ocgcore.dll), you can refer to [this script](https://github.com/Fluorohydride/ygopro-core/blob/master/.github/workflows/build.yml).
### 2.) Install Premake4 and Visual Studio 2010 (or later). ## Exposed Functions
Download premake4.exe, put it in `c:\windows` or a similar folder that is globally accessible via `cmd` or PowerShell. Install Visual Studio 2010, it is the system used for the guide because other parts of the project use C# and most the development team are Windows users.
### 3.) Download dependencies The 3 functions need to be provided to the core so it can get card and database information.
Dependencies are absent from the main project. There is information on how to build them but the easiest thing to do is to download the following folders from a [soarqin/ygopro](https://github.com/soarqin/ygopro) fork and simply copy them into the `Fluorohydride/ygopro` folder. - `void set_script_reader(script_reader f);`
Interface provided returns scripts based on number that corresponds to a lua file, send in a string.
* event - `void set_card_reader(card_reader f);`
* freetype Interface provided function that provides database information from the `data` table of `cards.cdb`.
* irrlicht
* lua
* sqlite3
### 4.) Create the project files - `void set_message_handler(message_handler f);`
Run the following commands from the command line in the `Fluorohydride/ygopro` folder. Interface provided function that handles error messages.
` premake4 /help ` These functions create the game itself and then manipulate it.
` premake4 vs2010 ` - `intptr_t create_duel(uint_fast32_t seed);`
Create a the instance of the duel with a PRNG seed.
If you are not using Visual Studio 2010 or higher, make the needed adjustments. In the file system open `Fluorohydride/ygopro/build` folder open the `ygo` project. - `void start_duel(intptr_t pduel, uint32_t options);`
Start the duel.
### 5.) Build the system - `void end_duel(intptr_t pduel);`
Make sure the code actually compiles. Compile them in the following order one by one: End the duel.
* lua - `void set_player_info(intptr_t pduel, int32_t playerid, int32_t lp, int32_t startcount, int32_t drawcount);`
* sqlite3 Set up the duel information.
* ocgcore
This should provide you with `ocgcore.lib` in the build output folder. `YGOCore` requires a `*.dll`; in `ocgcore` project properties change it to a dynamically linked library. Recompile, it should fail with an error indicating missing dependencies. Right click the project, add an existing file. Add `lua.lib` from the build folder to the project. It should now compile. - `void get_log_message(intptr_t pduel, char* buf);`
## Exposed Functions - `int32_t get_message(intptr_t pduel, byte* buf);`
These three function need to be provided to the core so it can get card and database information. - `int32_t process(intptr_t pduel);`
- `void set_script_reader(script_reader f);` : Interface provided returns scripts based on number that corresponds to a lua file, send in a string. Do a game tick.
- `void set_card_reader(card_reader f);` : Interface provided function that provides database information from the `data` table of `cards.cdb`. - `void new_card(intptr_t pduel, uint32_t code, uint8_t owner, uint8_t playerid, uint8_t location, uint8_t sequence, uint8_t position);`
Add a card to the duel state.
- `void set_message_handler(message_handler f);` : Interface provided function that handles errors - `void new_tag_card(intptr_t pduel, uint32_t code, uint8_t owner, uint8_t location);`
Add a new card to the tag pool.
These functions create the game itself and then manipulate it. - `int32_t query_field_card(intptr_t pduel, uint8_t playerid, uint8_t location, uint32_t query_flag, byte* buf, int32_t use_cache);`
- `ptr create_duel(uint32 seed);` : Create a the instance of the duel using a random number. Get a card in a specific location.
- `void start_duel(ptr pduel, int32 options);` : Starts the duel
- `void end_duel(ptr pduel);` : ends the duel - `int32_t query_field_count(intptr_t pduel, uint8_t playerid, uint8_t location);`
- `void set_player_info(ptr pduel, int32 playerid, int32 lp, int32 startcount, int32 drawcount);` sets the duel up Get the number of cards in a specific location.
- `void get_log_message(ptr pduel, byte* buf);`
- `int32 get_message(ptr pduel, byte* buf);` - `int32_t query_field_card(intptr_t pduel, uint8_t playerid, uint8_t location, uint32_t query_flag, byte* buf, int32_t use_cache);`
- `int32 process(ptr pduel);` : do a game tick Get all cards in some location.
- `void new_card(ptr pduel, uint32 code, uint8 owner, uint8 playerid, uint8 location, uint8 sequence, uint8 position);` : add a card to the duel state.
- `void new_tag_card(ptr pduel, uint32 code, uint8 owner, uint8 location);` : add a new card to the tag pool. - `int32_t query_field_info(intptr_t pduel, byte* buf);`
- `int32 query_card(ptr pduel, uint8 playerid, uint8 location, uint8 sequence, int32 query_flag, byte* buf, int32 use_cache);` : find out about a card in a specific spot.
- `int32 query_field_count(ptr pduel, uint8 playerid, uint8 location);` : Get the number of cards in a specific field/zone. - `void set_responsei(intptr_t pduel, int32_t value);`
- `int32 query_field_card(ptr pduel, uint8 playerid, uint8 location, int32 query_flag, byte* buf, int32 use_cache);`
- `int32 query_field_info(ptr pduel, byte* buf);` - `void set_responseb(intptr_t pduel, byte* buf);`
- `void set_responsei(ptr pduel, int32 value);`
- `void set_responseb(ptr pduel, byte* buf);` - `int32_t preload_script(intptr_t pduel, const char* script_name);`
- `int32 preload_script(ptr pduel, char* script, int32 len);`
- `byte* default_script_reader(const char* script_name, int* len);`
The default script reader using `fread`.
# Lua functions # Lua functions
`interpreter.cpp` - `libcard.cpp`
- `libdebug.cpp`
- `libduel.cpp`
- `libeffect.cpp`
- `libgroup.cpp`
#ifndef CORE_BUFFER_H
#define CORE_BUFFER_H
#include <cstdio>
#include <cstring>
#include <vector>
inline void buffer_read_block(unsigned char*& p, void* dest, size_t size) {
std::memcpy(dest, p, size);
p += size;
}
template<typename T>
inline T buffer_read(unsigned char*& p) {
T ret{};
std::memcpy(&ret, p, sizeof(T));
p += sizeof(T);
return ret;
}
inline void buffer_write_block(unsigned char*& p, const void* src, size_t size) {
std::memcpy(p, src, size);
p += size;
}
template<typename T>
inline void buffer_write(unsigned char*& p, T value) {
std::memcpy(p, &value, sizeof(T));
p += sizeof(T);
}
inline void vector_write_block(std::vector<unsigned char>& buffer, const void* src, size_t size) {
const auto len = buffer.size();
buffer.resize(len + size);
std::memcpy(&buffer[len], src, size);
}
template<typename T>
inline void vector_write(std::vector<unsigned char>& buffer, T value) {
vector_write_block(buffer, &value, sizeof(T));
}
inline void vector_fread(std::vector<unsigned char>& buffer, FILE* fp) {
unsigned char temp[4096]{};
while (size_t len = std::fread(temp, 1, sizeof temp, fp))
vector_write_block(buffer, temp, len);
std::fclose(fp);
}
#endif // !CORE_BUFFER_H
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
#include "common.h" #include "common.h"
#include "effectset.h" #include "effectset.h"
#include "card_data.h"
#include "sort.h"
#include <set> #include <set>
#include <map> #include <map>
#include <unordered_set> #include <unordered_set>
...@@ -22,120 +24,109 @@ class effect; ...@@ -22,120 +24,109 @@ class effect;
class group; class group;
struct chain; struct chain;
struct card_data { using card_set = std::set<card*, card_sort>;
uint32 code; using card_vector = std::vector<card*>;
uint32 alias; using effect_container = std::multimap<uint32_t, effect*>;
uint64 setcode; using effect_indexer = std::unordered_map<effect*, effect_container::iterator>;
uint32 type; using effect_collection = std::unordered_set<effect*>;
uint32 level;
uint32 attribute;
uint32 race;
int32 attack;
int32 defense;
uint32 lscale;
uint32 rscale;
uint32 link_marker;
void clear(); using effect_filter = bool(*)(card* self, effect* peffect);
}; using effect_filter_target = bool(*)(card* self, effect* peffect, card* target);
struct card_state { struct card_state {
card_state() uint32_t code{ 0 };
: code(0), code2(0), type(0), level(0), rank(0), link(0), lscale(0), rscale(0), attribute(0), race(0), attack(0), defense(0), base_attack(0), base_defense(0), uint32_t code2{ 0 };
controler(PLAYER_NONE), location(0), sequence(0), position(0), reason(0), pzone(false), reason_card(nullptr), reason_player(PLAYER_NONE), reason_effect(nullptr) {} std::vector<uint16_t> setcode;
uint32_t type{ 0 };
uint32_t level{ 0 };
uint32_t rank{ 0 };
uint32_t link{ 0 };
uint32_t lscale{ 0 };
uint32_t rscale{ 0 };
uint32_t attribute{ 0 };
uint32_t race{ 0 };
int32_t attack{ 0 };
int32_t defense{ 0 };
int32_t base_attack{ 0 };
int32_t base_defense{ 0 };
uint8_t controler{ PLAYER_NONE };
uint8_t location{ 0 };
uint8_t sequence{ 0 };
uint8_t position{ 0 };
uint32_t reason{ 0 };
card* reason_card{ nullptr };
effect* reason_effect{ nullptr };
uint8_t reason_player{ PLAYER_NONE };
bool pzone{ false };
uint32 code; bool is_location(uint32_t loc) const;
uint32 code2; bool is_main_mzone() const {
std::vector<uint32> setcode; return location == LOCATION_MZONE && sequence >= 0 && sequence <= 4;
uint32 type; }
uint32 level; bool is_stzone() const {
uint32 rank; return location == LOCATION_SZONE && sequence >= 0 && sequence <= 4;
uint32 link; }
uint32 lscale;
uint32 rscale;
uint32 attribute;
uint32 race;
int32 attack;
int32 defense;
int32 base_attack;
int32 base_defense;
uint8 controler;
uint8 location;
uint8 sequence;
uint8 position;
uint32 reason;
bool pzone;
card* reason_card;
uint8 reason_player;
effect* reason_effect;
bool is_location(int32 loc) const;
void init_state(); void init_state();
}; };
struct query_cache { struct query_cache {
uint32 code; uint32_t info_location{ UINT32_MAX };
uint32 alias; uint32_t current_code{ UINT32_MAX };
uint32 type; uint32_t type{ UINT32_MAX };
uint32 level; uint32_t level{ UINT32_MAX };
uint32 rank; uint32_t rank{ UINT32_MAX };
uint32 link; uint32_t link{ UINT32_MAX };
uint32 attribute; uint32_t attribute{ UINT32_MAX };
uint32 race; uint32_t race{ UINT32_MAX };
int32 attack; int32_t attack{ -1 };
int32 defense; int32_t defense{ -1 };
int32 base_attack; int32_t base_attack{ -1 };
int32 base_defense; int32_t base_defense{ -1 };
uint32 reason; uint32_t reason{ UINT32_MAX };
int32 status; uint32_t status{ UINT32_MAX };
uint32 lscale; uint32_t lscale{ UINT32_MAX };
uint32 rscale; uint32_t rscale{ UINT32_MAX };
uint32 link_marker; uint32_t link_marker{ UINT32_MAX };
void clear_cache();
}; };
struct material_info { struct material_info {
// Synchron // Synchron
card* limit_tuner; card* limit_tuner{ nullptr };
group* limit_syn; group* limit_syn{ nullptr };
int32 limit_syn_minc; int32_t limit_syn_minc{ 0 };
int32 limit_syn_maxc; int32_t limit_syn_maxc{ 0 };
// Xyz // Xyz
group* limit_xyz; group* limit_xyz{ nullptr };
int32 limit_xyz_minc; int32_t limit_xyz_minc{ 0 };
int32 limit_xyz_maxc; int32_t limit_xyz_maxc{ 0 };
// Link // Link
group* limit_link; group* limit_link{ nullptr };
card* limit_link_card; card* limit_link_card{ nullptr };
int32 limit_link_minc; int32_t limit_link_minc{ 0 };
int32 limit_link_maxc; int32_t limit_link_maxc{ 0 };
material_info()
: limit_tuner(nullptr), limit_syn(nullptr), limit_syn_minc(0), limit_syn_maxc(0), limit_xyz(nullptr), limit_xyz_minc(0), limit_xyz_maxc(0),
limit_link(nullptr), limit_link_card(nullptr), limit_link_minc(0), limit_link_maxc(0) {}
}; };
const material_info null_info; const material_info null_info;
class card { class card {
public: public:
struct effect_relation_hash { struct effect_relation_hash {
inline std::size_t operator()(const std::pair<effect*, uint16>& v) const { std::size_t operator()(const std::pair<effect*, uint16_t>& v) const {
return std::hash<uint16>()(v.second); return std::hash<uint16_t>()(v.second);
} }
}; };
using card_vector = std::vector<card*>; using effect_relation = std::unordered_set<std::pair<effect*, uint16_t>, effect_relation_hash>;
using effect_container = std::multimap<uint32, effect*>; using relation_map = std::unordered_map<card*, uint32_t>;
using card_set = std::set<card*, card_sort>; using counter_map = std::map<uint16_t, uint16_t>;
using effect_indexer = std::unordered_map<effect*, effect_container::iterator>; using effect_count = std::map<uint32_t, int32_t>;
using effect_relation = std::unordered_set<std::pair<effect*, uint16>, effect_relation_hash>; class attacker_map : public std::unordered_map<uint32_t, std::pair<card*, uint32_t>> {
using relation_map = std::unordered_map<card*, uint32>;
using counter_map = std::map<uint16, std::array<uint16, 2>>;
using effect_count = std::map<uint32, int32>;
class attacker_map : public std::unordered_map<uint16, std::pair<card*, uint32>> {
public: public:
void addcard(card* pcard); void addcard(card* pcard);
uint32 findcard(card* pcard); uint32_t findcard(card* pcard);
}; };
struct sendto_param_t { struct sendto_param_t {
void set(uint8 p, uint8 pos, uint8 loc, uint8 seq = 0) { void set(uint8_t p, uint8_t pos, uint8_t loc, uint8_t seq = 0) {
playerid = p; playerid = p;
position = pos; position = pos;
location = loc; location = loc;
...@@ -147,52 +138,55 @@ public: ...@@ -147,52 +138,55 @@ public:
location = 0; location = 0;
sequence = 0; sequence = 0;
} }
uint8 playerid; uint8_t playerid{ 0 };
uint8 position; uint8_t position{ 0 };
uint8 location; uint8_t location{ 0 };
uint8 sequence; uint8_t sequence{ 0 };
}; };
int32 ref_handle;
duel* pduel; int32_t ref_handle{};
duel* pduel{};
card_data data; card_data data;
card_state previous; card_state previous;
card_state temp; card_state temp;
card_state current; card_state current;
card_state spsummon;
query_cache q_cache; query_cache q_cache;
uint8 owner; uint8_t owner{ PLAYER_NONE };
uint8 summon_player; uint8_t summon_player{ PLAYER_NONE };
uint32 summon_info; uint32_t summon_info{};
uint32 status; uint32_t status{};
sendto_param_t sendto_param; sendto_param_t sendto_param;
uint32 release_param; uint32_t release_param{};
uint32 sum_param; uint32_t sum_param{};
uint32 position_param; uint32_t position_param{};
uint32 spsummon_param; uint32_t spsummon_param{};
uint32 to_field_param; uint32_t to_field_param{};
uint8 attack_announce_count; uint8_t attack_announce_count{};
uint8 direct_attackable; uint8_t direct_attackable{};
uint8 announce_count; uint8_t announce_count{};
uint8 attacked_count; uint8_t attacked_count{};
uint8 attack_all_target; uint8_t attack_all_target{};
uint8 attack_controler; uint8_t attack_controler{};
uint16 cardid; uint64_t cardid{};
uint32 fieldid; uint32_t fieldid{};
uint32 fieldid_r; uint32_t fieldid_r{}; //real field id, updated when moving to new location
uint16 turnid; uint32_t activate_count_id{}; //updated when moving to new location or flipping
uint16 turn_counter; uint16_t turnid{};
uint8 unique_pos[2]; uint16_t turn_counter{};
uint32 unique_fieldid; uint8_t unique_pos[2]{};
uint32 unique_code; uint32_t unique_fieldid{};
uint32 unique_location; uint32_t unique_code{};
int32 unique_function; uint32_t unique_location{};
effect* unique_effect; int32_t unique_function{};
uint32 spsummon_code; effect* unique_effect{};
uint16 spsummon_counter[2]; uint32_t spsummon_code{};
uint8 assume_type; uint16_t spsummon_counter[2]{};
uint32 assume_value; uint8_t assume_type{};
card* equiping_target; uint32_t assume_value{};
card* pre_equip_target; card* equiping_target{};
card* overlay_target; card* pre_equip_target{};
card* overlay_target{};
relation_map relations; relation_map relations;
counter_map counters; counter_map counters;
effect_count indestructable_effects; effect_count indestructable_effects;
...@@ -204,6 +198,7 @@ public: ...@@ -204,6 +198,7 @@ public:
card_set effect_target_owner; card_set effect_target_owner;
card_set effect_target_cards; card_set effect_target_cards;
card_vector xyz_materials; card_vector xyz_materials;
int32_t xyz_materials_previous_count_onfield{};
effect_container single_effect; effect_container single_effect;
effect_container field_effect; effect_container field_effect;
effect_container equip_effect; effect_container equip_effect;
...@@ -212,197 +207,230 @@ public: ...@@ -212,197 +207,230 @@ public:
effect_indexer indexer; effect_indexer indexer;
effect_relation relate_effect; effect_relation relate_effect;
effect_set_v immune_effect; effect_set_v immune_effect;
effect_collection initial_effect;
effect_collection owning_effect;
explicit card(duel* pd); explicit card(duel* pd);
~card() = default; ~card() = default;
static bool card_operation_sort(card* c1, card* c2); static bool card_operation_sort(card* c1, card* c2);
const bool is_extra_deck_monster() { return !!(data.type & (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK)); } static bool check_card_setcode(uint32_t code, uint32_t value);
bool is_extra_deck_monster() const { return !!(data.type & TYPES_EXTRA_DECK); }
uint32 get_infos(byte* buf, int32 query_flag, int32 use_cache = TRUE); int32_t get_infos(byte* buf, uint32_t query_flag, int32_t use_cache = TRUE);
uint32 get_info_location(); uint32_t get_info_location() const;
uint32 second_code(uint32 code); uint32_t get_original_code() const;
uint32 get_code(); std::tuple<uint32_t, uint32_t> get_original_code_rule() const;
uint32 get_another_code(); uint32_t get_code();
int32 is_set_card(uint32 set_code); uint32_t get_another_code();
int32 is_origin_set_card(uint32 set_code); int32_t is_set_card(uint32_t set_code);
int32 is_pre_set_card(uint32 set_code); int32_t is_origin_set_card(uint32_t set_code);
int32 is_fusion_set_card(uint32 set_code); int32_t is_pre_set_card(uint32_t set_code);
int32 is_link_set_card(uint32 set_code); int32_t is_fusion_set_card(uint32_t set_code);
uint32 get_type(); int32_t is_link_set_card(uint32_t set_code);
uint32 get_fusion_type(); int32_t is_special_summon_set_card(uint32_t set_code);
uint32 get_synchro_type(); uint32_t get_type();
uint32 get_xyz_type(); uint32_t get_fusion_type();
uint32 get_link_type(); uint32_t get_synchro_type();
std::pair<int32, int32> get_base_atk_def(); uint32_t get_xyz_type();
std::pair<int32, int32> get_atk_def(); uint32_t get_link_type();
int32 get_base_attack(); std::pair<int32_t, int32_t> get_base_atk_def();
int32 get_attack(); std::pair<int32_t, int32_t> get_atk_def();
int32 get_base_defense(); int32_t get_base_attack();
int32 get_defense(); int32_t get_attack();
int32 get_battle_attack(); int32_t get_base_defense();
int32 get_battle_defense(); int32_t get_defense();
uint32 get_level(); int32_t get_battle_attack();
uint32 get_rank(); int32_t get_battle_defense();
uint32 get_link(); uint32_t get_level();
uint32 get_synchro_level(card* pcard); uint32_t get_rank();
uint32 get_ritual_level(card* pcard); uint32_t get_link();
uint32 check_xyz_level(card* pcard, uint32 lv); uint32_t get_mat_level_from_effect(card* pcard, uint32_t effect_code);
uint32 get_attribute(); uint32_t get_mat_level(card* pcard, uint32_t level_effect_code, uint32_t allow_effect_code = 0);
uint32 get_fusion_attribute(uint8 playerid); uint32_t get_synchro_level(card* pcard);
uint32 get_link_attribute(uint8 playerid); uint32_t get_ritual_level(card* pcard);
uint32 get_grave_attribute(uint8 playerid); uint32_t check_xyz_level(card* pcard, uint32_t lv);
uint32 get_race(); uint32_t get_attribute();
uint32 get_link_race(uint8 playerid); uint32_t get_fusion_attribute(uint8_t playerid);
uint32 get_grave_race(uint8 playerid); uint32_t get_link_attribute(uint8_t playerid);
uint32 get_lscale(); uint32_t get_grave_attribute(uint8_t playerid);
uint32 get_rscale(); uint32_t get_race();
uint32 get_link_marker(); uint32_t get_link_race(uint8_t playerid);
int32 is_link_marker(uint32 dir); uint32_t get_grave_race(uint8_t playerid);
uint32 get_linked_zone(); uint32_t get_lscale();
uint32_t get_rscale();
uint32_t get_link_marker();
uint32_t is_link_marker(uint32_t dir);
uint32_t get_linked_zone();
void get_linked_cards(card_set* cset); void get_linked_cards(card_set* cset);
uint32 get_mutual_linked_zone(); uint32_t get_mutual_linked_zone();
void get_mutual_linked_cards(card_set * cset); void get_mutual_linked_cards(card_set * cset);
int32 is_link_state(); int32_t is_link_state();
int32 is_extra_link_state(); int32_t is_extra_link_state();
int32 is_position(int32 pos); int32_t is_position(uint32_t pos) const;
void set_status(uint32 status, int32 enabled); void set_status(uint32_t x, int32_t enabled);
int32 get_status(uint32 status); int32_t get_status(uint32_t x) const;
int32 is_status(uint32 status); int32_t is_status(uint32_t x) const;
uint32 get_column_zone(int32 location); uint32_t get_column_zone(int32_t location);
void get_column_cards(card_set* cset); void get_column_cards(card_set* cset);
int32 is_all_column(); int32_t is_all_column();
uint8_t get_select_sequence(uint8_t *deck_seq_pointer);
uint32_t get_select_info_location(uint8_t *deck_seq_pointer);
int32_t is_treated_as_not_on_field() const;
void equip(card *target, uint32 send_msg = TRUE); void equip(card* target, uint32_t send_msg = TRUE);
void unequip(); void unequip();
int32 get_union_count(); int32_t get_union_count();
int32 get_old_union_count(); int32_t get_old_union_count();
void xyz_overlay(card_set* materials); void xyz_overlay(const card_set& materials);
void xyz_add(card* mat); void xyz_add(card* mat);
void xyz_remove(card* mat); void xyz_remove(card* mat);
void apply_field_effect(); void apply_field_effect();
void cancel_field_effect(); void cancel_field_effect();
void enable_field_effect(bool enabled); void enable_field_effect(bool enabled);
int32 add_effect(effect* peffect); int32_t add_effect(effect* peffect);
void remove_effect(effect* peffect); effect_indexer::iterator remove_effect(effect* peffect);
void remove_effect(effect* peffect, effect_container::iterator it); int32_t copy_effect(uint32_t code, uint32_t reset, int32_t count);
int32 copy_effect(uint32 code, uint32 reset, uint32 count); int32_t replace_effect(uint32_t code, uint32_t reset, int32_t count);
int32 replace_effect(uint32 code, uint32 reset, uint32 count); void reset(uint32_t id, uint32_t reset_type);
void reset(uint32 id, uint32 reset_type);
void reset_effect_count(); void reset_effect_count();
void refresh_disable_status(); void refresh_disable_status();
std::tuple<uint8, effect*> refresh_control_status(); std::tuple<uint8_t, effect*> refresh_control_status();
void count_turn(uint16 ct); void count_turn(uint16_t ct);
void create_relation(card* target, uint32 reset); void create_relation(card* target, uint32_t reset);
int32 is_has_relation(card* target); int32_t is_has_relation(card* target);
void release_relation(card* target); void release_relation(card* target);
void create_relation(const chain& ch); void create_relation(const chain& ch);
int32 is_has_relation(const chain& ch); int32_t is_has_relation(const chain& ch);
void release_relation(const chain& ch); void release_relation(const chain& ch);
void clear_relate_effect(); void clear_relate_effect();
void create_relation(effect* peffect); void create_relation(effect* peffect);
int32 is_has_relation(effect* peffect); int32_t is_has_relation(effect* peffect);
void release_relation(effect* peffect); void release_relation(effect* peffect);
int32 leave_field_redirect(uint32 reason); int32_t leave_field_redirect(uint32_t reason);
int32 destination_redirect(uint8 destination, uint32 reason); int32_t destination_redirect(uint8_t destination, uint32_t reason);
int32 add_counter(uint8 playerid, uint16 countertype, uint16 count, uint8 singly); int32_t add_counter(uint8_t playerid, uint16_t countertype, uint16_t count, uint8_t singly);
int32 remove_counter(uint16 countertype, uint16 count); int32_t remove_counter(uint16_t countertype, uint16_t count);
int32 is_can_add_counter(uint8 playerid, uint16 countertype, uint16 count, uint8 singly, uint32 loc); int32_t is_can_add_counter(uint8_t playerid, uint16_t countertype, uint16_t count, uint8_t singly, uint32_t loc);
int32 is_can_have_counter(uint16 countertype); int32_t is_can_have_counter(uint16_t countertype);
int32 get_counter(uint16 countertype); int32_t get_counter(uint16_t countertype);
void set_material(card_set* materials); void set_material(card_set* materials);
void add_card_target(card* pcard); void add_card_target(card* pcard);
void cancel_card_target(card* pcard); void cancel_card_target(card* pcard);
void delete_card_target(uint32_t send_msg);
void clear_card_target(); void clear_card_target();
void set_special_summon_status(effect* peffect);
void filter_effect(int32 code, effect_set* eset, uint8 sort = TRUE); template<typename T>
void filter_single_continuous_effect(int32 code, effect_set* eset, uint8 sort = TRUE); void filter_effect_container(const effect_container& container, uint32_t code, effect_filter f, T& eset);
void filter_self_effect(int32 code, effect_set* eset, uint8 sort = TRUE); void filter_effect_container(const effect_container& container, uint32_t code, effect_filter f, effect_collection& eset);
void filter_effect(uint32_t code, effect_set* eset, uint8_t sort = TRUE);
void filter_single_continuous_effect(uint32_t code, effect_set* eset, uint8_t sort = TRUE);
void filter_self_effect(uint32_t code, effect_set* eset, uint8_t sort = TRUE);
void filter_immune_effect(); void filter_immune_effect();
void filter_disable_related_cards(); void filter_disable_related_cards();
int32 filter_summon_procedure(uint8 playerid, effect_set* eset, uint8 ignore_count, uint8 min_tribute, uint32 zone); int32_t filter_summon_procedure(uint8_t playerid, effect_set* eset, uint8_t ignore_count, uint8_t min_tribute, uint32_t zone);
int32 check_summon_procedure(effect* proc, uint8 playerid, uint8 ignore_count, uint8 min_tribute, uint32 zone); int32_t check_summon_procedure(effect* proc, uint8_t playerid, uint8_t ignore_count, uint8_t min_tribute, uint32_t zone);
int32 filter_set_procedure(uint8 playerid, effect_set* eset, uint8 ignore_count, uint8 min_tribute, uint32 zone); int32_t filter_set_procedure(uint8_t playerid, effect_set* eset, uint8_t ignore_count, uint8_t min_tribute, uint32_t zone);
int32 check_set_procedure(effect* proc, uint8 playerid, uint8 ignore_count, uint8 min_tribute, uint32 zone); int32_t check_set_procedure(effect* proc, uint8_t playerid, uint8_t ignore_count, uint8_t min_tribute, uint32_t zone);
void filter_spsummon_procedure(uint8 playerid, effect_set* eset, uint32 summon_type, material_info info = null_info); void filter_spsummon_procedure(uint8_t playerid, effect_set* eset, uint32_t summon_type, material_info info = null_info);
void filter_spsummon_procedure_g(uint8 playerid, effect_set* eset); void filter_spsummon_procedure_g(uint8_t playerid, effect_set* eset);
effect* is_affected_by_effect(int32 code); effect* find_effect(const effect_container& container, uint32_t code, effect_filter f);
effect* is_affected_by_effect(int32 code, card* target); effect* find_effect_with_target(const effect_container& container, uint32_t code, effect_filter_target f, card* target);
int32 fusion_check(group* fusion_m, card* cg, uint32 chkf, uint8 not_material); effect* is_affected_by_effect(uint32_t code);
void fusion_select(uint8 playerid, group* fusion_m, card* cg, uint32 chkf, uint8 not_material); effect* is_affected_by_effect(int32_t code, card* target);
int32 check_fusion_substitute(card* fcard); int32_t fusion_check(group* fusion_m, card* cg, uint32_t chkf, uint8_t not_material);
int32 is_not_tuner(card* scard); void fusion_select(uint8_t playerid, group* fusion_m, card* cg, uint32_t chkf, uint8_t not_material);
int32_t check_fusion_substitute(card* fcard);
int32_t is_not_tuner(card* scard);
int32_t is_tuner(card* scard);
int32 check_unique_code(card* pcard); int32_t check_unique_code(card* pcard);
void get_unique_target(card_set* cset, int32 controler, card* icard = 0); void get_unique_target(card_set* cset, int32_t controler, card* icard = nullptr);
int32 check_cost_condition(int32 ecode, int32 playerid); int32_t check_cost_condition(int32_t ecode, int32_t playerid);
int32 check_cost_condition(int32 ecode, int32 playerid, int32 sumtype); int32_t check_cost_condition(int32_t ecode, int32_t playerid, int32_t sumtype);
int32 is_summonable_card(); int32_t is_summonable_card() const;
int32 is_spsummonable_card(); int32_t is_spsummonable_card();
int32 is_fusion_summonable_card(uint32 summon_type); int32_t is_fusion_summonable_card(uint32_t summon_type);
int32 is_spsummonable(effect* proc, material_info info = null_info); int32_t is_spsummonable(effect* proc, material_info info = null_info);
int32 is_summonable(effect* proc, uint8 min_tribute, uint32 zone = 0x1f, uint32 releasable = 0xff00ff); int32_t is_summonable(effect* proc, uint8_t min_tribute, uint32_t zone = 0x1f, uint32_t releasable = 0xff00ff);
int32 is_can_be_summoned(uint8 playerid, uint8 ingore_count, effect* peffect, uint8 min_tribute, uint32 zone = 0x1f); int32_t is_can_be_summoned(uint8_t playerid, uint8_t ingore_count, effect* peffect, uint8_t min_tribute, uint32_t zone = 0x1f);
int32 get_summon_tribute_count(); int32_t is_summon_negatable(uint32_t sumtype, effect* reason_effect);
int32 get_set_tribute_count(); int32_t get_summon_tribute_count();
int32 is_can_be_flip_summoned(uint8 playerid); int32_t get_set_tribute_count();
int32 is_special_summonable(uint8 playerid, uint32 summon_type, material_info info = null_info); int32_t is_can_be_flip_summoned(uint8_t playerid);
int32 is_can_be_special_summoned(effect* reason_effect, uint32 sumtype, uint8 sumpos, uint8 sumplayer, uint8 toplayer, uint8 nocheck, uint8 nolimit, uint32 zone); int32_t is_special_summonable(uint8_t playerid, uint32_t summon_type, material_info info = null_info);
uint8 get_spsummonable_position(effect* reason_effect, uint32 sumtype, uint8 sumpos, uint8 sumplayer, uint8 toplayer); int32_t is_can_be_special_summoned(effect* reason_effect, uint32_t sumtype, uint8_t sumpos, uint8_t sumplayer, uint8_t toplayer, uint8_t nocheck, uint8_t nolimit, uint32_t zone);
int32 is_setable_mzone(uint8 playerid, uint8 ignore_count, effect* peffect, uint8 min_tribute, uint32 zone = 0x1f); uint8_t get_spsummonable_position(effect* reason_effect, uint32_t sumtype, uint8_t sumpos, uint8_t sumplayer, uint8_t toplayer);
int32 is_setable_szone(uint8 playerid, uint8 ignore_fd = 0); int32_t is_setable_mzone(uint8_t playerid, uint8_t ignore_count, effect* peffect, uint8_t min_tribute, uint32_t zone = 0x1f);
int32 is_affect_by_effect(effect* reason_effect); int32_t is_setable_szone(uint8_t playerid, uint8_t ignore_fd = 0);
int32 is_can_be_disabled_by_effect(effect* reason_effect); int32_t is_affect_by_effect(effect* reason_effect);
int32 is_destructable(); int32_t is_can_be_disabled_by_effect(effect* reason_effect, bool is_monster_effect);
int32 is_destructable_by_battle(card* pcard); int32_t is_destructable();
effect* check_indestructable_by_effect(effect* reason_effect, uint8 playerid); int32_t is_destructable_by_battle(card* pcard);
int32 is_destructable_by_effect(effect* reason_effect, uint8 playerid); effect* check_indestructable_by_effect(effect* reason_effect, uint8_t playerid);
int32 is_removeable(uint8 playerid, uint8 pos, uint32 reason); int32_t is_destructable_by_effect(effect* reason_effect, uint8_t playerid);
int32 is_removeable_as_cost(uint8 playerid, uint8 pos); int32_t is_removeable(uint8_t playerid, uint8_t pos, uint32_t reason);
int32 is_releasable_by_summon(uint8 playerid, card* pcard); int32_t is_removeable_as_cost(uint8_t playerid, uint8_t pos);
int32 is_releasable_by_nonsummon(uint8 playerid); int32_t is_releasable_by_summon(uint8_t playerid, card* pcard);
int32 is_releasable_by_effect(uint8 playerid, effect* reason_effect); int32_t is_releasable_by_nonsummon(uint8_t playerid, uint32_t reason);
int32 is_capable_send_to_grave(uint8 playerid); int32_t is_releasable_by_effect(uint8_t playerid, effect* reason_effect);
int32 is_capable_send_to_hand(uint8 playerid); int32_t is_capable_send_to_grave(uint8_t playerid);
int32 is_capable_send_to_deck(uint8 playerid); int32_t is_capable_send_to_hand(uint8_t playerid);
int32 is_capable_send_to_extra(uint8 playerid); int32_t is_capable_send_to_deck(uint8_t playerid, uint8_t send_activating = FALSE);
int32 is_capable_cost_to_grave(uint8 playerid); int32_t is_capable_send_to_extra(uint8_t playerid);
int32 is_capable_cost_to_hand(uint8 playerid); int32_t is_capable_cost_to_grave(uint8_t playerid);
int32 is_capable_cost_to_deck(uint8 playerid); int32_t is_capable_cost_to_hand(uint8_t playerid);
int32 is_capable_cost_to_extra(uint8 playerid); int32_t is_capable_cost_to_deck(uint8_t playerid);
int32 is_capable_attack(); int32_t is_capable_cost_to_extra(uint8_t playerid);
int32 is_capable_attack_announce(uint8 playerid); int32_t is_capable_attack();
int32 is_capable_change_position(uint8 playerid); int32_t is_capable_attack_announce(uint8_t playerid);
int32 is_capable_change_position_by_effect(uint8 playerid); int32_t is_capable_change_position(uint8_t playerid);
int32 is_capable_turn_set(uint8 playerid); int32_t is_capable_change_position_by_effect(uint8_t playerid);
int32 is_capable_change_control(); int32_t is_capable_turn_set(uint8_t playerid);
int32 is_control_can_be_changed(int32 ignore_mzone, uint32 zone); int32_t is_capable_change_control();
int32 is_capable_be_battle_target(card* pcard); int32_t is_control_can_be_changed(int32_t ignore_mzone, uint32_t zone);
int32 is_capable_be_effect_target(effect* reason_effect, uint8 playerid); int32_t is_capable_be_battle_target(card* pcard);
int32 is_capable_overlay(uint8 playerid); int32_t is_capable_be_effect_target(effect* reason_effect, uint8_t playerid);
int32 is_can_be_fusion_material(card* fcard, uint32 summon_type); int32_t is_capable_overlay(uint8_t playerid);
int32 is_can_be_synchro_material(card* scard, card* tuner = 0); int32_t is_can_be_fusion_material(card* fcard, uint32_t summon_type);
int32 is_can_be_ritual_material(card* scard); int32_t is_can_be_synchro_material(card* scard, card* tuner = nullptr);
int32 is_can_be_xyz_material(card* scard); int32_t is_can_be_ritual_material(card* scard);
int32 is_can_be_link_material(card* scard); int32_t is_can_be_xyz_material(card* scard);
int32_t is_can_be_link_material(card* scard);
int32_t is_original_effect_property(int32_t filter);
int32_t is_effect_property(int32_t filter);
}; };
//Summon Type //Summon Type in summon_info
#define SUMMON_TYPE_NORMAL 0x10000000 #define SUMMON_TYPE_NORMAL 0x10000000U
#define SUMMON_TYPE_ADVANCE 0x11000000 #define SUMMON_TYPE_ADVANCE 0x11000000U
#define SUMMON_TYPE_DUAL 0x12000000 #define SUMMON_TYPE_FLIP 0x20000000U
#define SUMMON_TYPE_FLIP 0x20000000 #define SUMMON_TYPE_SPECIAL 0x40000000U
#define SUMMON_TYPE_SPECIAL 0x40000000 #define SUMMON_TYPE_FUSION 0x43000000U
#define SUMMON_TYPE_FUSION 0x43000000 #define SUMMON_TYPE_RITUAL 0x45000000U
#define SUMMON_TYPE_RITUAL 0x45000000 #define SUMMON_TYPE_SYNCHRO 0x46000000U
#define SUMMON_TYPE_SYNCHRO 0x46000000 #define SUMMON_TYPE_XYZ 0x49000000U
#define SUMMON_TYPE_XYZ 0x49000000 #define SUMMON_TYPE_PENDULUM 0x4a000000U
#define SUMMON_TYPE_PENDULUM 0x4a000000 #define SUMMON_TYPE_LINK 0x4c000000U
#define SUMMON_TYPE_LINK 0x4c000000
//Gemini Summon
#define SUMMON_TYPE_DUAL 0x12000000U
//bitfield blocks
#define SUMMON_VALUE_MAIN_TYPE 0xf0000000U
#define SUMMON_VALUE_SUB_TYPE 0x0f000000U
#define SUMMON_VALUE_LOCATION 0x00ff0000U
#define SUMMON_VALUE_CUSTOM_TYPE 0x0000ffffU
constexpr uint32_t DEFAULT_SUMMON_TYPE = SUMMON_VALUE_MAIN_TYPE | SUMMON_VALUE_SUB_TYPE | SUMMON_VALUE_CUSTOM_TYPE;
#define SUMMON_VALUE_FUTURE_FUSION 0x18
//Counter //Counter
#define COUNTER_WITHOUT_PERMIT 0x1000 #define COUNTER_WITHOUT_PERMIT 0x1000U
//#define COUNTER_NEED_ENABLE 0x2000 //#define COUNTER_NEED_ENABLE 0x2000
//Assume
#define ASSUME_CODE 1 #define ASSUME_CODE 1
#define ASSUME_TYPE 2 #define ASSUME_TYPE 2
#define ASSUME_LEVEL 3 #define ASSUME_LEVEL 3
...@@ -412,10 +440,17 @@ public: ...@@ -412,10 +440,17 @@ public:
#define ASSUME_ATTACK 7 #define ASSUME_ATTACK 7
#define ASSUME_DEFENSE 8 #define ASSUME_DEFENSE 8
//double-name cards //Special Summon effect info
#define CARD_MARINE_DOLPHIN 78734254 #define SUMMON_INFO_CODE 0x01
#define CARD_TWINKLE_MOSS 13857930 #define SUMMON_INFO_CODE2 0x02
#define SUMMON_INFO_TYPE 0x04
#define CARD_ARTWORK_VERSIONS_OFFSET 10 #define SUMMON_INFO_LEVEL 0x08
#define SUMMON_INFO_RANK 0x10
#define SUMMON_INFO_ATTRIBUTE 0x20
#define SUMMON_INFO_RACE 0x40
#define SUMMON_INFO_ATTACK 0x80
#define SUMMON_INFO_DEFENSE 0x100
#define SUMMON_INFO_REASON_EFFECT 0x200
#define SUMMON_INFO_REASON_PLAYER 0x400
#endif /* CARD_H_ */ #endif /* CARD_H_ */
#ifndef CARD_DATA_H_
#define CARD_DATA_H_
#include <cstring>
#include <unordered_map>
#include "common.h"
constexpr int CARD_ARTWORK_VERSIONS_OFFSET = 20;
constexpr int SIZE_SETCODE = 16;
constexpr uint32_t CARD_BLACK_LUSTER_SOLDIER2 = 5405695;
//double name
constexpr uint32_t CARD_MARINE_DOLPHIN = 78734254;
constexpr uint32_t CARD_TWINKLE_MOSS = 13857930;
constexpr uint32_t CARD_TIMAEUS = 1784686;
constexpr uint32_t CARD_CRITIAS = 11082056;
constexpr uint32_t CARD_HERMOS = 46232525;
const std::unordered_map<uint32_t, uint32_t> second_code = {
{CARD_MARINE_DOLPHIN, 17955766u},
{CARD_TWINKLE_MOSS, 17732278u},
{CARD_TIMAEUS, 10000050u},
{CARD_CRITIAS, 10000060u},
{CARD_HERMOS, 10000070u},
};
struct card_data {
uint32_t code{};
uint32_t alias{};
uint16_t setcode[SIZE_SETCODE]{};
uint32_t type{};
uint32_t level{};
uint32_t attribute{};
uint32_t race{};
int32_t attack{};
int32_t defense{};
uint32_t lscale{};
uint32_t rscale{};
uint32_t link_marker{};
void clear() {
std::memset(this, 0, sizeof(card_data));
}
bool is_setcode(uint32_t value) const {
const uint16_t settype = value & 0x0fff;
const uint16_t setsubtype = value & 0xf000;
for (auto& x : setcode) {
if ((x & 0x0fff) == settype && (x & setsubtype) == setsubtype)
return true;
if (!x)
return false;
}
return false;
}
bool is_alternative() const {
if (code == CARD_BLACK_LUSTER_SOLDIER2)
return false;
return alias && (alias < code + CARD_ARTWORK_VERSIONS_OFFSET) && (code < alias + CARD_ARTWORK_VERSIONS_OFFSET);
}
void set_setcode(uint64_t value) {
int ctr = 0;
while (value) {
if (value & 0xffff) {
setcode[ctr] = value & 0xffff;
++ctr;
}
value >>= 16;
}
if (ctr < SIZE_SETCODE)
std::memset(setcode + ctr, 0, (SIZE_SETCODE - ctr) * sizeof(uint16_t));
}
uint32_t get_original_code() const {
return is_alternative() ? alias : code;
}
};
#endif /* CARD_DATA_H_ */
...@@ -9,16 +9,12 @@ ...@@ -9,16 +9,12 @@
#define COMMON_H_ #define COMMON_H_
#include <stdint.h> #include <stdint.h>
typedef unsigned long long uint64; #include <assert.h>
typedef unsigned int uint32;
typedef unsigned short uint16;
typedef unsigned char uint8;
typedef unsigned char byte; typedef unsigned char byte;
typedef long long int64;
typedef int int32; inline bool check_playerid(int32_t playerid) {
typedef short int16; return playerid >= 0 && playerid <= 1;
typedef signed char int8; }
typedef int BOOL;
#define MATCH_ALL(x,y) (((x)&(y))==(y)) #define MATCH_ALL(x,y) (((x)&(y))==(y))
#define MATCH_ANY(x,y) ((x)&(y)) #define MATCH_ANY(x,y) ((x)&(y))
...@@ -30,25 +26,35 @@ typedef int BOOL; ...@@ -30,25 +26,35 @@ typedef int BOOL;
#define OPERATION_CANCELED -1 #define OPERATION_CANCELED -1
#define TRUE 1 #define TRUE 1
#define FALSE 0 #define FALSE 0
#ifndef NULL
#define NULL 0 #define SIZE_MESSAGE_BUFFER 0x2000
#endif #define SIZE_RETURN_VALUE 512
struct card_sort { #define SIZE_AI_NAME 128
bool operator()(void* const & c1, void* const & c2) const; #define SIZE_HINT_MSG 1024
};
#define PROCESSOR_BUFFER_LEN 0x0fffffff
#define PROCESSOR_FLAG 0xf0000000
#define PROCESSOR_NONE 0
#define PROCESSOR_WAITING 0x10000000
#define PROCESSOR_END 0x20000000
#define MASTER_RULE3 3 //Master Rule 3 (2014)
#define NEW_MASTER_RULE 4 //New Master Rule (2017)
#define MASTER_RULE_2020 5 //Master Rule 2020
#define CURRENT_RULE 5
//Locations //Locations
#define LOCATION_DECK 0x01 // #define LOCATION_DECK 0x01U
#define LOCATION_HAND 0x02 // #define LOCATION_HAND 0x02U
#define LOCATION_MZONE 0x04 // #define LOCATION_MZONE 0x04U
#define LOCATION_SZONE 0x08 // #define LOCATION_SZONE 0x08U
#define LOCATION_GRAVE 0x10 // #define LOCATION_GRAVE 0x10U
#define LOCATION_REMOVED 0x20 // #define LOCATION_REMOVED 0x20U
#define LOCATION_EXTRA 0x40 // #define LOCATION_EXTRA 0x40U
#define LOCATION_OVERLAY 0x80 // #define LOCATION_OVERLAY 0x80U
#define LOCATION_ONFIELD 0x0c // #define LOCATION_ONFIELD (LOCATION_MZONE | LOCATION_SZONE)
#define LOCATION_FZONE 0x100 // #define LOCATION_FZONE 0x100U
#define LOCATION_PZONE 0x200 // #define LOCATION_PZONE 0x200U
//For redirect //For redirect
#define LOCATION_DECKBOT 0x10001 //Return to deck bottom #define LOCATION_DECKBOT 0x10001 //Return to deck bottom
#define LOCATION_DECKSHF 0x20001 //Return to deck and shuffle #define LOCATION_DECKSHF 0x20001 //Return to deck and shuffle
...@@ -69,6 +75,10 @@ struct card_sort { ...@@ -69,6 +75,10 @@ struct card_sort {
//Flip effect flags //Flip effect flags
#define NO_FLIP_EFFECT 0x10000 #define NO_FLIP_EFFECT 0x10000
//Move to field flags
#define RETURN_TEMP_REMOVE_TO_FIELD 1
#define RETURN_TRAP_MONSTER_TO_SZONE 2
//Types //Types
#define TYPE_MONSTER 0x1 // #define TYPE_MONSTER 0x1 //
#define TYPE_SPELL 0x2 // #define TYPE_SPELL 0x2 //
...@@ -96,7 +106,11 @@ struct card_sort { ...@@ -96,7 +106,11 @@ struct card_sort {
#define TYPE_SPSUMMON 0x2000000 // #define TYPE_SPSUMMON 0x2000000 //
#define TYPE_LINK 0x4000000 // #define TYPE_LINK 0x4000000 //
#define TYPES_EXTRA_DECK (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK)
//Attributes //Attributes
#define ATTRIBUTES_COUNT 7
#define ATTRIBUTE_ALL 0x7f //
#define ATTRIBUTE_EARTH 0x01 // #define ATTRIBUTE_EARTH 0x01 //
#define ATTRIBUTE_WATER 0x02 // #define ATTRIBUTE_WATER 0x02 //
#define ATTRIBUTE_FIRE 0x04 // #define ATTRIBUTE_FIRE 0x04 //
...@@ -106,6 +120,8 @@ struct card_sort { ...@@ -106,6 +120,8 @@ struct card_sort {
#define ATTRIBUTE_DEVINE 0x40 // #define ATTRIBUTE_DEVINE 0x40 //
//Races //Races
#define RACES_COUNT 26
#define RACE_ALL 0x3ffffff
#define RACE_WARRIOR 0x1 // #define RACE_WARRIOR 0x1 //
#define RACE_SPELLCASTER 0x2 // #define RACE_SPELLCASTER 0x2 //
#define RACE_FAIRY 0x4 // #define RACE_FAIRY 0x4 //
...@@ -131,6 +147,7 @@ struct card_sort { ...@@ -131,6 +147,7 @@ struct card_sort {
#define RACE_CREATORGOD 0x400000 // #define RACE_CREATORGOD 0x400000 //
#define RACE_WYRM 0x800000 // #define RACE_WYRM 0x800000 //
#define RACE_CYBERSE 0x1000000 // #define RACE_CYBERSE 0x1000000 //
#define RACE_ILLUSION 0x2000000 //
//Reason //Reason
#define REASON_DESTROY 0x1 // #define REASON_DESTROY 0x1 //
...@@ -161,29 +178,33 @@ struct card_sort { ...@@ -161,29 +178,33 @@ struct card_sort {
#define REASON_REVEAL 0x8000000 // #define REASON_REVEAL 0x8000000 //
#define REASON_LINK 0x10000000 // #define REASON_LINK 0x10000000 //
#define REASON_LOST_OVERLAY 0x20000000 // #define REASON_LOST_OVERLAY 0x20000000 //
#define REASON_MAINTENANCE 0x40000000 //
#define REASON_ACTION 0x80000000 //
#define REASONS_PROCEDURE (REASON_SYNCHRO | REASON_XYZ | REASON_LINK)
//Status //Status
#define STATUS_DISABLED 0x0001 // #define STATUS_DISABLED 0x0001
#define STATUS_TO_ENABLE 0x0002 // #define STATUS_TO_ENABLE 0x0002
#define STATUS_TO_DISABLE 0x0004 // #define STATUS_TO_DISABLE 0x0004
#define STATUS_PROC_COMPLETE 0x0008 // #define STATUS_PROC_COMPLETE 0x0008
#define STATUS_SET_TURN 0x0010 // #define STATUS_SET_TURN 0x0010
#define STATUS_NO_LEVEL 0x0020 // #define STATUS_NO_LEVEL 0x0020
#define STATUS_BATTLE_RESULT 0x0040 // #define STATUS_BATTLE_RESULT 0x0040
#define STATUS_SPSUMMON_STEP 0x0080 // #define STATUS_SPSUMMON_STEP 0x0080
#define STATUS_FORM_CHANGED 0x0100 // #define STATUS_CANNOT_CHANGE_FORM 0x0100
#define STATUS_SUMMONING 0x0200 // #define STATUS_SUMMONING 0x0200
#define STATUS_EFFECT_ENABLED 0x0400 // #define STATUS_EFFECT_ENABLED 0x0400
#define STATUS_SUMMON_TURN 0x0800 // #define STATUS_SUMMON_TURN 0x0800
#define STATUS_DESTROY_CONFIRMED 0x1000 // #define STATUS_DESTROY_CONFIRMED 0x1000
#define STATUS_LEAVE_CONFIRMED 0x2000 // #define STATUS_LEAVE_CONFIRMED 0x2000
#define STATUS_BATTLE_DESTROYED 0x4000 // #define STATUS_BATTLE_DESTROYED 0x4000
#define STATUS_COPYING_EFFECT 0x8000 // #define STATUS_COPYING_EFFECT 0x8000
#define STATUS_CHAINING 0x10000 // #define STATUS_CHAINING 0x10000
#define STATUS_SUMMON_DISABLED 0x20000 // #define STATUS_SUMMON_DISABLED 0x20000
#define STATUS_ACTIVATE_DISABLED 0x40000 // #define STATUS_ACTIVATE_DISABLED 0x40000
#define STATUS_EFFECT_REPLACED 0x80000 #define STATUS_EFFECT_REPLACED 0x80000
#define STATUS_FUTURE_FUSION 0x100000 #define STATUS_FLIP_SUMMONING 0x100000
#define STATUS_ATTACK_CANCELED 0x200000 #define STATUS_ATTACK_CANCELED 0x200000
#define STATUS_INITIALIZING 0x400000 #define STATUS_INITIALIZING 0x400000
#define STATUS_TO_HAND_WITHOUT_CONFIRM 0x800000 #define STATUS_TO_HAND_WITHOUT_CONFIRM 0x800000
...@@ -194,6 +215,7 @@ struct card_sort { ...@@ -194,6 +215,7 @@ struct card_sort {
#define STATUS_OPPO_BATTLE 0x10000000 #define STATUS_OPPO_BATTLE 0x10000000
#define STATUS_FLIP_SUMMON_TURN 0x20000000 #define STATUS_FLIP_SUMMON_TURN 0x20000000
#define STATUS_SPSUMMON_TURN 0x40000000 #define STATUS_SPSUMMON_TURN 0x40000000
#define STATUS_FLIP_SUMMON_DISABLED 0x80000000
//Query list //Query list
#define QUERY_CODE 0x1 #define QUERY_CODE 0x1
...@@ -233,12 +255,12 @@ struct card_sort { ...@@ -233,12 +255,12 @@ struct card_sort {
//Messages //Messages
#define MSG_RETRY 1 #define MSG_RETRY 1
#define MSG_HINT 2 #define MSG_HINT 2
#define MSG_WAITING 3 //#define MSG_WAITING 3
#define MSG_START 4 //#define MSG_START 4
#define MSG_WIN 5 #define MSG_WIN 5
#define MSG_UPDATE_DATA 6 //#define MSG_UPDATE_DATA 6
#define MSG_UPDATE_CARD 7 //#define MSG_UPDATE_CARD 7
#define MSG_REQUEST_DECK 8 //#define MSG_REQUEST_DECK 8
#define MSG_SELECT_BATTLECMD 10 #define MSG_SELECT_BATTLECMD 10
#define MSG_SELECT_IDLECMD 11 #define MSG_SELECT_IDLECMD 11
#define MSG_SELECT_EFFECTYN 12 #define MSG_SELECT_EFFECTYN 12
...@@ -249,7 +271,6 @@ struct card_sort { ...@@ -249,7 +271,6 @@ struct card_sort {
#define MSG_SELECT_PLACE 18 #define MSG_SELECT_PLACE 18
#define MSG_SELECT_POSITION 19 #define MSG_SELECT_POSITION 19
#define MSG_SELECT_TRIBUTE 20 #define MSG_SELECT_TRIBUTE 20
//#define MSG_SORT_CHAIN 21
#define MSG_SELECT_COUNTER 22 #define MSG_SELECT_COUNTER 22
#define MSG_SELECT_SUM 23 #define MSG_SELECT_SUM 23
#define MSG_SELECT_DISFIELD 24 #define MSG_SELECT_DISFIELD 24
...@@ -259,7 +280,7 @@ struct card_sort { ...@@ -259,7 +280,7 @@ struct card_sort {
#define MSG_CONFIRM_CARDS 31 #define MSG_CONFIRM_CARDS 31
#define MSG_SHUFFLE_DECK 32 #define MSG_SHUFFLE_DECK 32
#define MSG_SHUFFLE_HAND 33 #define MSG_SHUFFLE_HAND 33
#define MSG_REFRESH_DECK 34 //#define MSG_REFRESH_DECK 34
#define MSG_SWAP_GRAVE_DECK 35 #define MSG_SWAP_GRAVE_DECK 35
#define MSG_SHUFFLE_SET_CARD 36 #define MSG_SHUFFLE_SET_CARD 36
#define MSG_REVERSE_DECK 37 #define MSG_REVERSE_DECK 37
...@@ -286,7 +307,7 @@ struct card_sort { ...@@ -286,7 +307,7 @@ struct card_sort {
#define MSG_CHAIN_END 74 #define MSG_CHAIN_END 74
#define MSG_CHAIN_NEGATED 75 #define MSG_CHAIN_NEGATED 75
#define MSG_CHAIN_DISABLED 76 #define MSG_CHAIN_DISABLED 76
#define MSG_CARD_SELECTED 80 //#define MSG_CARD_SELECTED 80
#define MSG_RANDOM_SELECTED 81 #define MSG_RANDOM_SELECTED 81
#define MSG_BECOME_TARGET 83 #define MSG_BECOME_TARGET 83
#define MSG_DRAW 90 #define MSG_DRAW 90
...@@ -294,7 +315,7 @@ struct card_sort { ...@@ -294,7 +315,7 @@ struct card_sort {
#define MSG_RECOVER 92 #define MSG_RECOVER 92
#define MSG_EQUIP 93 #define MSG_EQUIP 93
#define MSG_LPUPDATE 94 #define MSG_LPUPDATE 94
#define MSG_UNEQUIP 95 //#define MSG_UNEQUIP 95
#define MSG_CARD_TARGET 96 #define MSG_CARD_TARGET 96
#define MSG_CANCEL_TARGET 97 #define MSG_CANCEL_TARGET 97
#define MSG_PAY_LPCOST 100 #define MSG_PAY_LPCOST 100
...@@ -306,9 +327,9 @@ struct card_sort { ...@@ -306,9 +327,9 @@ struct card_sort {
#define MSG_DAMAGE_STEP_START 113 #define MSG_DAMAGE_STEP_START 113
#define MSG_DAMAGE_STEP_END 114 #define MSG_DAMAGE_STEP_END 114
#define MSG_MISSED_EFFECT 120 #define MSG_MISSED_EFFECT 120
#define MSG_BE_CHAIN_TARGET 121 //#define MSG_BE_CHAIN_TARGET 121
#define MSG_CREATE_RELATION 122 //#define MSG_CREATE_RELATION 122
#define MSG_RELEASE_RELATION 123 //#define MSG_RELEASE_RELATION 123
#define MSG_TOSS_COIN 130 #define MSG_TOSS_COIN 130
#define MSG_TOSS_DICE 131 #define MSG_TOSS_DICE 131
#define MSG_ROCK_PAPER_SCISSORS 132 #define MSG_ROCK_PAPER_SCISSORS 132
...@@ -319,9 +340,9 @@ struct card_sort { ...@@ -319,9 +340,9 @@ struct card_sort {
#define MSG_ANNOUNCE_NUMBER 143 #define MSG_ANNOUNCE_NUMBER 143
#define MSG_CARD_HINT 160 #define MSG_CARD_HINT 160
#define MSG_TAG_SWAP 161 #define MSG_TAG_SWAP 161
#define MSG_RELOAD_FIELD 162 // Debug.ReloadFieldEnd() #define MSG_RELOAD_FIELD 162 // Debug.ReloadFieldEnd() or query_field_info()
#define MSG_AI_NAME 163 #define MSG_AI_NAME 163 // Debug.AIName()
#define MSG_SHOW_HINT 164 #define MSG_SHOW_HINT 164 // Debug.ShowHint()
#define MSG_PLAYER_HINT 165 #define MSG_PLAYER_HINT 165
#define MSG_MATCH_KILL 170 #define MSG_MATCH_KILL 170
#define MSG_CUSTOM_MSG 180 #define MSG_CUSTOM_MSG 180
...@@ -388,12 +409,13 @@ struct card_sort { ...@@ -388,12 +409,13 @@ struct card_sort {
//Options //Options
#define DUEL_TEST_MODE 0x01 #define DUEL_TEST_MODE 0x01
#define DUEL_ATTACK_FIRST_TURN 0x02 #define DUEL_ATTACK_FIRST_TURN 0x02
#define DUEL_OLD_REPLAY 0x04 //#define DUEL_OLD_REPLAY 0x04
#define DUEL_OBSOLETE_RULING 0x08 #define DUEL_OBSOLETE_RULING 0x08
#define DUEL_PSEUDO_SHUFFLE 0x10 #define DUEL_PSEUDO_SHUFFLE 0x10
#define DUEL_TAG_MODE 0x20 #define DUEL_TAG_MODE 0x20
#define DUEL_SIMPLE_AI 0x40 #define DUEL_SIMPLE_AI 0x40
#define DUEL_RETURN_DECK_TOP 0x80 #define DUEL_RETURN_DECK_TOP 0x80
#define DUEL_REVEAL_DECK_SEQ 0x100
//Activity //Activity
#define ACTIVITY_SUMMON 1 #define ACTIVITY_SUMMON 1
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* Author: Argon * Author: Argon
*/ */
#include <cstring>
#include "duel.h" #include "duel.h"
#include "interpreter.h" #include "interpreter.h"
#include "field.h" #include "field.h"
...@@ -12,12 +13,16 @@ ...@@ -12,12 +13,16 @@
#include "effect.h" #include "effect.h"
#include "group.h" #include "group.h"
#include "ocgapi.h" #include "ocgapi.h"
#include "buffer.h"
duel::duel() { duel::duel() {
lua = new interpreter(this); lua = new interpreter(this);
game_field = new field(this); game_field = new field(this);
game_field->temp_card = new_card(0); game_field->temp_card = new_card(TEMP_CARD_ID);
clear_buffer(); message_buffer.reserve(SIZE_MESSAGE_BUFFER);
#ifdef _WIN32
_set_error_mode(_OUT_TO_MSGBOX);
#endif // _WIN32
} }
duel::~duel() { duel::~duel() {
for(auto& pcard : cards) for(auto& pcard : cards)
...@@ -40,16 +45,17 @@ void duel::clear() { ...@@ -40,16 +45,17 @@ void duel::clear() {
cards.clear(); cards.clear();
groups.clear(); groups.clear();
effects.clear(); effects.clear();
assumes.clear();
sgroups.clear();
uncopy.clear();
game_field = new field(this); game_field = new field(this);
game_field->temp_card = new_card(0); game_field->temp_card = new_card(TEMP_CARD_ID);
} }
card* duel::new_card(uint32 code) { card* duel::new_card(uint32_t code) {
card* pcard = new card(this); card* pcard = new card(this);
cards.insert(pcard); cards.insert(pcard);
if(code) if (code != TEMP_CARD_ID)
::read_card(code, &(pcard->data)); ::read_card(code, &(pcard->data));
else
pcard->data.clear();
pcard->data.code = code; pcard->data.code = code;
lua->register_card(pcard); lua->register_card(pcard);
return pcard; return pcard;
...@@ -94,13 +100,15 @@ void duel::delete_effect(effect* peffect) { ...@@ -94,13 +100,15 @@ void duel::delete_effect(effect* peffect) {
effects.erase(peffect); effects.erase(peffect);
delete peffect; delete peffect;
} }
int32 duel::read_buffer(byte* buf) { int32_t duel::read_buffer(byte* buf) {
std::memcpy(buf, buffer, bufferlen); auto size = buffer_size();
return bufferlen; if (size)
std::memcpy(buf, message_buffer.data(), size);
return (int32_t)size;
} }
void duel::release_script_group() { void duel::release_script_group() {
for(auto& pgroup : sgroups) { for(auto& pgroup : sgroups) {
if(pgroup->is_readonly == 0) { if(pgroup->is_readonly == GTYPE_DEFAULT) {
lua->unregister_group(pgroup); lua->unregister_group(pgroup);
groups.erase(pgroup); groups.erase(pgroup);
delete pgroup; delete pgroup;
...@@ -113,36 +121,29 @@ void duel::restore_assumes() { ...@@ -113,36 +121,29 @@ void duel::restore_assumes() {
pcard->assume_type = 0; pcard->assume_type = 0;
assumes.clear(); assumes.clear();
} }
void duel::write_buffer32(uint32 value) { void duel::write_buffer(const void* data, int size) {
std::memcpy(bufferp, &value, sizeof(value)); vector_write_block(message_buffer, data, size);
bufferp += 4; }
bufferlen += 4; void duel::write_buffer32(uint32_t value) {
vector_write<uint32_t>(message_buffer, value);
} }
void duel::write_buffer16(uint16 value) { void duel::write_buffer16(uint16_t value) {
std::memcpy(bufferp, &value, sizeof(value)); vector_write<uint16_t>(message_buffer, value);
bufferp += 2;
bufferlen += 2;
} }
void duel::write_buffer8(uint8 value) { void duel::write_buffer8(uint8_t value) {
std::memcpy(bufferp, &value, sizeof(value)); vector_write<unsigned char>(message_buffer, value);
bufferp += 1;
bufferlen += 1;
} }
void duel::clear_buffer() { void duel::clear_buffer() {
bufferlen = 0; message_buffer.clear();
bufferp = buffer;
} }
void duel::set_responsei(uint32 resp) { void duel::set_responsei(uint32_t resp) {
game_field->returns.ivalue[0] = resp; game_field->returns.ivalue[0] = resp;
} }
void duel::set_responseb(byte* resp) { void duel::set_responseb(byte* resp) {
std::memcpy(game_field->returns.bvalue, resp, 64); std::memcpy(game_field->returns.bvalue, resp, SIZE_RETURN_VALUE);
} }
int32 duel::get_next_integer(int32 l, int32 h) { int32_t duel::get_next_integer(int32_t l, int32_t h) {
if (game_field->core.duel_options & DUEL_OLD_REPLAY) { if (rng_version == 1)
return random.get_random_integer_old(l, h); return random.get_random_integer_v1(l, h);
} return random.get_random_integer_v2(l, h);
else {
return random.get_random_integer(l, h);
}
} }
...@@ -9,9 +9,11 @@ ...@@ -9,9 +9,11 @@
#define DUEL_H_ #define DUEL_H_
#include "common.h" #include "common.h"
#include "sort.h"
#include "mtrandom.h" #include "mtrandom.h"
#include <set> #include <set>
#include <unordered_set> #include <unordered_set>
#include <vector>
class card; class card;
class group; class group;
...@@ -19,16 +21,17 @@ class effect; ...@@ -19,16 +21,17 @@ class effect;
class field; class field;
class interpreter; class interpreter;
using card_set = std::set<card*, card_sort>;
class duel { class duel {
public: public:
using card_set = std::set<card*, card_sort>; char strbuffer[256]{};
char strbuffer[256]; int32_t rng_version{ 2 };
byte buffer[0x1000];
uint32 bufferlen;
byte* bufferp;
interpreter* lua; interpreter* lua;
field* game_field; field* game_field;
mt19937 random; mtrandom random;
std::vector<byte> message_buffer;
std::unordered_set<card*> cards; std::unordered_set<card*> cards;
std::unordered_set<card*> assumes; std::unordered_set<card*> assumes;
std::unordered_set<group*> groups; std::unordered_set<group*> groups;
...@@ -40,7 +43,10 @@ public: ...@@ -40,7 +43,10 @@ public:
~duel(); ~duel();
void clear(); void clear();
card* new_card(uint32 code); uint32_t buffer_size() const {
return (uint32_t)message_buffer.size() & PROCESSOR_BUFFER_LEN;
}
card* new_card(uint32_t code);
group* new_group(); group* new_group();
group* new_group(card* pcard); group* new_group(card* pcard);
group* new_group(const card_set& cset); group* new_group(const card_set& cset);
...@@ -50,14 +56,15 @@ public: ...@@ -50,14 +56,15 @@ public:
void delete_effect(effect* peffect); void delete_effect(effect* peffect);
void release_script_group(); void release_script_group();
void restore_assumes(); void restore_assumes();
int32 read_buffer(byte* buf); int32_t read_buffer(byte* buf);
void write_buffer32(uint32 value); void write_buffer(const void* data, int size);
void write_buffer16(uint16 value); void write_buffer32(uint32_t value);
void write_buffer8(uint8 value); void write_buffer16(uint16_t value);
void write_buffer8(uint8_t value);
void clear_buffer(); void clear_buffer();
void set_responsei(uint32 resp); void set_responsei(uint32_t resp);
void set_responseb(byte* resp); void set_responseb(byte* resp);
int32 get_next_integer(int32 l, int32 h); int32_t get_next_integer(int32_t l, int32_t h);
private: private:
group* register_group(group* pgroup); group* register_group(group* pgroup);
}; };
......
...@@ -12,80 +12,47 @@ ...@@ -12,80 +12,47 @@
#include "interpreter.h" #include "interpreter.h"
bool effect_sort_id(const effect* e1, const effect* e2) { bool effect_sort_id(const effect* e1, const effect* e2) {
int32_t is_single1 = e1->is_initial_single();
int32_t is_single2 = e2->is_initial_single();
if (is_single1 != is_single2)
return is_single1 > is_single2;
return e1->id < e2->id; return e1->id < e2->id;
} }
// return: code is an event reserved for EFFECT_TYPE_CONTINUOUS or not // return: code is an event reserved for EFFECT_TYPE_CONTINUOUS or not
bool is_continuous_event(uint32 code) { bool is_continuous_event(uint32_t code) {
if (code & EVENT_CUSTOM) if (code & EVENT_CUSTOM)
return false; return false;
else if (code & 0xf0000) else if (code & 0xf0000) // EVENT_ADD_COUNTER, EVENT_REMOVE_COUNTER
return false; return false;
else if (code & 0xf000) else if (code & 0xf000) // EVENT_PHASE_START must be continuous, but other EVENT_PHASE must not be
return !!(code & EVENT_PHASE_START); return !!(code & EVENT_PHASE_START);
else else
return continuous_event.find(code) != continuous_event.end(); return continuous_event.find(code) != continuous_event.end();
} }
effect::effect(duel* pd) { effect::effect(duel* pd)
ref_handle = 0; : pduel(pd) {
pduel = pd;
owner = 0;
handler = 0;
description = 0;
effect_owner = PLAYER_NONE;
card_type = 0;
active_type = 0;
active_location = 0;
active_sequence = 0;
active_handler = 0;
id = 0;
code = 0;
type = 0;
flag[0] = 0;
flag[1] = 0;
copy_id = 0;
range = 0;
s_range = 0;
o_range = 0;
count_limit = 0;
count_limit_max = 0;
reset_count = 0;
reset_flag = 0;
count_code = 0;
category = 0;
label.reserve(4); label.reserve(4);
label_object = 0; }
hint_timing[0] = 0; int32_t effect::is_disable_related() const {
hint_timing[1] = 0;
status = 0;
condition = 0;
cost = 0;
target = 0;
value = 0;
operation = 0;
cost_checked = FALSE;
}
int32 effect::is_disable_related() {
if (code == EFFECT_IMMUNE_EFFECT || code == EFFECT_DISABLE || code == EFFECT_CANNOT_DISABLE || code == EFFECT_FORBIDDEN) if (code == EFFECT_IMMUNE_EFFECT || code == EFFECT_DISABLE || code == EFFECT_CANNOT_DISABLE || code == EFFECT_FORBIDDEN)
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
int32 effect::is_self_destroy_related() { int32_t effect::is_self_destroy_related() const {
if(code == EFFECT_UNIQUE_CHECK || code == EFFECT_SELF_DESTROY || code == EFFECT_SELF_TOGRAVE) if(code == EFFECT_UNIQUE_CHECK || code == EFFECT_SELF_DESTROY || code == EFFECT_SELF_TOGRAVE)
return TRUE; return TRUE;
return FALSE; return FALSE;
} }
int32 effect::is_can_be_forbidden() { int32_t effect::is_can_be_forbidden() const {
if (is_flag(EFFECT_FLAG_CANNOT_DISABLE) && !is_flag(EFFECT_FLAG_CANNOT_NEGATE)) if (is_flag(EFFECT_FLAG_CANNOT_DISABLE) && !is_flag(EFFECT_FLAG_CANNOT_NEGATE))
return FALSE; return FALSE;
if (code == EFFECT_CHANGE_CODE)
return FALSE;
return TRUE; return TRUE;
} }
// check if a single/field/equip effect is available // check if a single/field/equip effect is available
// check properties: range, EFFECT_FLAG_OWNER_RELATE, STATUS_BATTLE_DESTROYED, STATUS_EFFECT_ENABLED, disabled/forbidden // check properties: range, EFFECT_FLAG_OWNER_RELATE, STATUS_BATTLE_DESTROYED, STATUS_EFFECT_ENABLED, disabled/forbidden
// check fucntions: condition // check fucntions: condition
int32 effect::is_available(int32 neglect_disabled) { int32_t effect::is_available(int32_t neglect_disabled) {
if (type & EFFECT_TYPE_ACTIONS) if (type & EFFECT_TYPE_ACTIONS)
return FALSE; return FALSE;
if ((type & (EFFECT_TYPE_SINGLE | EFFECT_TYPE_XMATERIAL)) && !(type & EFFECT_TYPE_FIELD)) { if ((type & (EFFECT_TYPE_SINGLE | EFFECT_TYPE_XMATERIAL)) && !(type & EFFECT_TYPE_FIELD)) {
...@@ -136,7 +103,9 @@ int32 effect::is_available(int32 neglect_disabled) { ...@@ -136,7 +103,9 @@ int32 effect::is_available(int32 neglect_disabled) {
return FALSE; return FALSE;
if(!phandler->get_status(STATUS_EFFECT_ENABLED) && !is_flag(EFFECT_FLAG_IMMEDIATELY_APPLY)) if(!phandler->get_status(STATUS_EFFECT_ENABLED) && !is_flag(EFFECT_FLAG_IMMEDIATELY_APPLY))
return FALSE; return FALSE;
if((phandler->current.location & LOCATION_ONFIELD) && !phandler->is_position(POS_FACEUP)) if (phandler->current.is_location(LOCATION_ONFIELD) && !phandler->is_position(POS_FACEUP))
return FALSE;
if (phandler->current.is_stzone() && (phandler->data.type & (TYPE_SPELL | TYPE_TRAP)) && phandler->is_affected_by_effect(EFFECT_CHANGE_TYPE))
return FALSE; return FALSE;
if(is_flag(EFFECT_FLAG_OWNER_RELATE) && is_can_be_forbidden() && powner->is_status(STATUS_FORBIDDEN)) if(is_flag(EFFECT_FLAG_OWNER_RELATE) && is_can_be_forbidden() && powner->is_status(STATUS_FORBIDDEN))
return FALSE; return FALSE;
...@@ -153,7 +122,7 @@ int32 effect::is_available(int32 neglect_disabled) { ...@@ -153,7 +122,7 @@ int32 effect::is_available(int32 neglect_disabled) {
if (!condition) if (!condition)
return TRUE; return TRUE;
pduel->lua->add_param(this, PARAM_TYPE_EFFECT); pduel->lua->add_param(this, PARAM_TYPE_EFFECT);
int32 res = pduel->lua->check_condition(condition, 1); int32_t res = pduel->lua->check_condition(condition, 1);
if(res) { if(res) {
if(!(status & EFFECT_STATUS_AVAILABLE)) if(!(status & EFFECT_STATUS_AVAILABLE))
id = pduel->game_field->infos.field_id++; id = pduel->game_field->infos.field_id++;
...@@ -163,17 +132,16 @@ int32 effect::is_available(int32 neglect_disabled) { ...@@ -163,17 +132,16 @@ int32 effect::is_available(int32 neglect_disabled) {
return res; return res;
} }
// check if a count limit effect counter is available, which should be available even if the effect is disabled // check if a count limit effect counter is available, which should be available even if the effect is disabled
int32 effect::limit_counter_is_available() { int32_t effect::limit_counter_is_available() {
return is_available(TRUE); return is_available(TRUE);
} }
// check if a effect is EFFECT_TYPE_SINGLE and is ready // check if a effect is EFFECT_TYPE_SINGLE and is ready
// check: range, enabled, condition // check: range, enabled, condition
int32 effect::is_single_ready() { int32_t effect::is_single_ready() {
if(type & EFFECT_TYPE_ACTIONS) if(type & EFFECT_TYPE_ACTIONS)
return FALSE; return FALSE;
if((type & (EFFECT_TYPE_SINGLE | EFFECT_TYPE_XMATERIAL)) && !(type & EFFECT_TYPE_FIELD)) { if((type & (EFFECT_TYPE_SINGLE | EFFECT_TYPE_XMATERIAL)) && !(type & EFFECT_TYPE_FIELD)) {
card* phandler = get_handler(); card* phandler = get_handler();
card* powner = get_owner();
if(phandler->current.controler == PLAYER_NONE) if(phandler->current.controler == PLAYER_NONE)
return FALSE; return FALSE;
if(is_flag(EFFECT_FLAG_SINGLE_RANGE) && !in_range(phandler)) if(is_flag(EFFECT_FLAG_SINGLE_RANGE) && !in_range(phandler))
...@@ -188,21 +156,19 @@ int32 effect::is_single_ready() { ...@@ -188,21 +156,19 @@ int32 effect::is_single_ready() {
if(!condition) if(!condition)
return TRUE; return TRUE;
pduel->lua->add_param(this, PARAM_TYPE_EFFECT); pduel->lua->add_param(this, PARAM_TYPE_EFFECT);
int32 res = pduel->lua->check_condition(condition, 1); int32_t res = pduel->lua->check_condition(condition, 1);
return res; return res;
} }
// reset_count: count of effect reset int32_t effect::check_count_limit(uint8_t playerid) {
// count_limit: left count of activation
// count_limit_max: max count of activation
int32 effect::check_count_limit(uint8 playerid) {
if(is_flag(EFFECT_FLAG_COUNT_LIMIT)) { if(is_flag(EFFECT_FLAG_COUNT_LIMIT)) {
if(count_limit == 0) if(count_limit == 0)
return FALSE; return FALSE;
if(count_code) { if(count_code) {
uint32 code = count_code & 0xfffffff; uint32_t limit_code = count_code & MAX_CARD_ID;
uint32 count = count_limit_max; uint32_t limit_type = count_code & 0xf0000000U;
if(code == 1) { int32_t count = count_limit_max;
if(pduel->game_field->get_effect_code((count_code & 0xf0000000) | get_handler()->fieldid, PLAYER_NONE) >= count) if(limit_code == EFFECT_COUNT_CODE_SINGLE) {
if(pduel->game_field->get_effect_code(limit_type | get_handler()->activate_count_id, PLAYER_NONE) >= count)
return FALSE; return FALSE;
} else { } else {
if(pduel->game_field->get_effect_code(count_code, playerid) >= count) if(pduel->game_field->get_effect_code(count_code, playerid) >= count)
...@@ -212,9 +178,69 @@ int32 effect::check_count_limit(uint8 playerid) { ...@@ -212,9 +178,69 @@ int32 effect::check_count_limit(uint8 playerid) {
} }
return TRUE; return TRUE;
} }
// check activate in hand/in set turn
int32_t effect::get_required_handorset_effects(effect_set* eset, uint8_t playerid, const tevent& e, int32_t neglect_loc) {
eset->clear();
if(!(type & EFFECT_TYPE_ACTIVATE))
return 1;
int32_t ecode = 0;
if (handler->current.location == LOCATION_HAND && !neglect_loc)
{
if(handler->data.type & TYPE_TRAP)
ecode = EFFECT_TRAP_ACT_IN_HAND;
else if((handler->data.type & TYPE_SPELL) && pduel->game_field->infos.turn_player != playerid) {
if(handler->data.type & TYPE_QUICKPLAY)
ecode = EFFECT_QP_ACT_IN_NTPHAND;
else
return FALSE;
}
}
else if (handler->current.location == LOCATION_SZONE)
{
if((handler->data.type & TYPE_TRAP) && handler->get_status(STATUS_SET_TURN))
ecode = EFFECT_TRAP_ACT_IN_SET_TURN;
if((handler->data.type & TYPE_SPELL) && (handler->data.type & TYPE_QUICKPLAY) && handler->get_status(STATUS_SET_TURN))
ecode = EFFECT_QP_ACT_IN_SET_TURN;
}
if (!ecode)
return 1;
int32_t available = 0;
effect_set tmp_eset;
handler->filter_effect(ecode, &tmp_eset);
if(!tmp_eset.size())
return available;
effect* oreason = pduel->game_field->core.reason_effect;
uint8_t op = pduel->game_field->core.reason_player;
pduel->game_field->core.reason_player = playerid;
pduel->game_field->save_lp_cost();
for(effect_set::size_type i = 0; i < tmp_eset.size(); ++i) {
auto peffect = tmp_eset[i];
if(peffect->check_count_limit(playerid)) {
pduel->game_field->core.reason_effect = peffect;
pduel->lua->add_param(peffect, PARAM_TYPE_EFFECT);
pduel->lua->add_param(playerid, PARAM_TYPE_INT);
pduel->lua->add_param(e.event_cards , PARAM_TYPE_GROUP);
pduel->lua->add_param(e.event_player, PARAM_TYPE_INT);
pduel->lua->add_param(e.event_value, PARAM_TYPE_INT);
pduel->lua->add_param(e.reason_effect , PARAM_TYPE_EFFECT);
pduel->lua->add_param(e.reason, PARAM_TYPE_INT);
pduel->lua->add_param(e.reason_player, PARAM_TYPE_INT);
pduel->lua->add_param(0, PARAM_TYPE_INT);
pduel->lua->add_param(this, PARAM_TYPE_EFFECT);
if(pduel->lua->check_condition(peffect->cost, 10)) {
available = 2;
eset->push_back(peffect);
}
}
}
pduel->game_field->core.reason_effect = oreason;
pduel->game_field->core.reason_player = op;
pduel->game_field->restore_lp_cost();
return available;
}
// check if an EFFECT_TYPE_ACTIONS effect can be activated // check if an EFFECT_TYPE_ACTIONS effect can be activated
// for triggering effects, it checks EFFECT_FLAG_DAMAGE_STEP, EFFECT_FLAG_SET_AVAILABLE // for triggering effects, it checks EFFECT_FLAG_DAMAGE_STEP, EFFECT_FLAG_SET_AVAILABLE
int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_cond, int32 neglect_cost, int32 neglect_target, int32 neglect_loc, int32 neglect_faceup) { int32_t effect::is_activateable(uint8_t playerid, const tevent& e, int32_t neglect_cond, int32_t neglect_cost, int32_t neglect_target, int32_t neglect_loc, int32_t neglect_faceup) {
if(!(type & EFFECT_TYPE_ACTIONS)) if(!(type & EFFECT_TYPE_ACTIONS))
return FALSE; return FALSE;
if(!check_count_limit(playerid)) if(!check_count_limit(playerid))
...@@ -233,7 +259,7 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con ...@@ -233,7 +259,7 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
&& !pduel->game_field->get_cteffect(this, playerid, FALSE)) && !pduel->game_field->get_cteffect(this, playerid, FALSE))
return FALSE; return FALSE;
} }
uint32 zone = 0xff; uint32_t zone = 0xff;
if(!(handler->data.type & (TYPE_FIELD | TYPE_PENDULUM)) && is_flag(EFFECT_FLAG_LIMIT_ZONE)) { if(!(handler->data.type & (TYPE_FIELD | TYPE_PENDULUM)) && is_flag(EFFECT_FLAG_LIMIT_ZONE)) {
pduel->lua->add_param(playerid, PARAM_TYPE_INT); pduel->lua->add_param(playerid, PARAM_TYPE_INT);
pduel->lua->add_param(e.event_cards , PARAM_TYPE_GROUP); pduel->lua->add_param(e.event_cards , PARAM_TYPE_GROUP);
...@@ -265,44 +291,16 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con ...@@ -265,44 +291,16 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
return FALSE; return FALSE;
} }
// check activate in hand/in set turn // check activate in hand/in set turn
int32 ecode = 0;
if(handler->current.location == LOCATION_HAND && !neglect_loc) {
if(handler->data.type & TYPE_TRAP)
ecode = EFFECT_TRAP_ACT_IN_HAND;
else if((handler->data.type & TYPE_SPELL) && pduel->game_field->infos.turn_player != playerid) {
if(handler->data.type & TYPE_QUICKPLAY)
ecode = EFFECT_QP_ACT_IN_NTPHAND;
else
return FALSE;
}
} else if(handler->current.location == LOCATION_SZONE) {
if((handler->data.type & TYPE_TRAP) && handler->get_status(STATUS_SET_TURN))
ecode = EFFECT_TRAP_ACT_IN_SET_TURN;
if((handler->data.type & TYPE_SPELL) && (handler->data.type & TYPE_QUICKPLAY) && handler->get_status(STATUS_SET_TURN))
ecode = EFFECT_QP_ACT_IN_SET_TURN;
}
if(ecode) {
bool available = false;
effect_set eset; effect_set eset;
handler->filter_effect(ecode, &eset); if(!get_required_handorset_effects(&eset, playerid, e, neglect_loc))
for(int32 i = 0; i < eset.size(); ++i) {
if(eset[i]->check_count_limit(playerid)) {
available = true;
break;
}
}
if(!available)
return FALSE; return FALSE;
}
if(handler->is_status(STATUS_FORBIDDEN)) if(handler->is_status(STATUS_FORBIDDEN))
return FALSE; return FALSE;
if(handler->is_affected_by_effect(EFFECT_CANNOT_TRIGGER)) if(handler->is_affected_by_effect(EFFECT_CANNOT_TRIGGER))
return FALSE; return FALSE;
} else if(!(type & EFFECT_TYPE_CONTINUOUS)) { } else if(!(type & EFFECT_TYPE_CONTINUOUS)) {
card* phandler = get_handler(); card* phandler = get_handler();
if(!(phandler->get_type() & TYPE_MONSTER) && (get_active_type() & TYPE_MONSTER)) if(!(phandler->get_type() & TYPE_MONSTER) && (get_active_type(FALSE) & TYPE_MONSTER))
return FALSE;
if((phandler->get_type() & TYPE_CONTINUOUS) && (phandler->get_type() & TYPE_EQUIP))
return FALSE; return FALSE;
if((type & EFFECT_TYPE_QUICK_O) && is_flag(EFFECT_FLAG_DELAY) && !in_range(phandler)) if((type & EFFECT_TYPE_QUICK_O) && is_flag(EFFECT_FLAG_DELAY) && !in_range(phandler))
return FALSE; return FALSE;
...@@ -321,12 +319,14 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con ...@@ -321,12 +319,14 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
if(phandler->current.location == LOCATION_OVERLAY) if(phandler->current.location == LOCATION_OVERLAY)
return FALSE; return FALSE;
if(phandler->current.location == LOCATION_DECK if(phandler->current.location == LOCATION_DECK
|| pduel->game_field->core.duel_rule >= 5 && phandler->current.location == LOCATION_EXTRA && (phandler->current.position & POS_FACEDOWN)) { || pduel->game_field->core.duel_rule >= MASTER_RULE_2020 && phandler->current.location == LOCATION_EXTRA && (phandler->current.position & POS_FACEDOWN)) {
if((type & EFFECT_TYPE_SINGLE) && code != EVENT_TO_DECK) if((type & EFFECT_TYPE_SINGLE) && code != EVENT_TO_DECK)
return FALSE; return FALSE;
if((type & EFFECT_TYPE_FIELD) && !(range & (LOCATION_DECK | LOCATION_EXTRA))) if((type & EFFECT_TYPE_FIELD) && !(range & (LOCATION_DECK | LOCATION_EXTRA)))
return FALSE; return FALSE;
} }
if (phandler->current.is_stzone() && (phandler->data.type & (TYPE_SPELL|TYPE_TRAP)) && phandler->is_affected_by_effect(EFFECT_CHANGE_TYPE))
return FALSE;
if((type & EFFECT_TYPE_FIELD) && (phandler->current.controler != playerid) && !is_flag(EFFECT_FLAG_BOTH_SIDE | EFFECT_FLAG_EVENT_PLAYER)) if((type & EFFECT_TYPE_FIELD) && (phandler->current.controler != playerid) && !is_flag(EFFECT_FLAG_BOTH_SIDE | EFFECT_FLAG_EVENT_PLAYER))
return FALSE; return FALSE;
if(phandler->is_status(STATUS_FORBIDDEN)) if(phandler->is_status(STATUS_FORBIDDEN))
...@@ -337,7 +337,8 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con ...@@ -337,7 +337,8 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
card* phandler = get_handler(); card* phandler = get_handler();
if((type & EFFECT_TYPE_FIELD) && phandler->is_status(STATUS_BATTLE_DESTROYED)) if((type & EFFECT_TYPE_FIELD) && phandler->is_status(STATUS_BATTLE_DESTROYED))
return FALSE; return FALSE;
if(((type & EFFECT_TYPE_FIELD) || ((type & EFFECT_TYPE_SINGLE) && is_flag(EFFECT_FLAG_SINGLE_RANGE))) && (phandler->current.location & LOCATION_ONFIELD) if(((type & EFFECT_TYPE_FIELD) || ((type & EFFECT_TYPE_SINGLE) && is_flag(EFFECT_FLAG_SINGLE_RANGE)))
&& (phandler->current.location & LOCATION_ONFIELD)
&& (!phandler->is_position(POS_FACEUP) || !phandler->is_status(STATUS_EFFECT_ENABLED))) && (!phandler->is_position(POS_FACEUP) || !phandler->is_status(STATUS_EFFECT_ENABLED)))
return FALSE; return FALSE;
if((type & EFFECT_TYPE_SINGLE) && is_flag(EFFECT_FLAG_SINGLE_RANGE) && !in_range(phandler)) if((type & EFFECT_TYPE_SINGLE) && is_flag(EFFECT_FLAG_SINGLE_RANGE) && !in_range(phandler))
...@@ -357,10 +358,10 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con ...@@ -357,10 +358,10 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
} }
pduel->game_field->save_lp_cost(); pduel->game_field->save_lp_cost();
effect* oreason = pduel->game_field->core.reason_effect; effect* oreason = pduel->game_field->core.reason_effect;
uint8 op = pduel->game_field->core.reason_player; uint8_t op = pduel->game_field->core.reason_player;
pduel->game_field->core.reason_effect = this; pduel->game_field->core.reason_effect = this;
pduel->game_field->core.reason_player = playerid; pduel->game_field->core.reason_player = playerid;
int32 result = TRUE; int32_t result = TRUE;
if(!(type & EFFECT_TYPE_CONTINUOUS)) if(!(type & EFFECT_TYPE_CONTINUOUS))
result = is_action_check(playerid); result = is_action_check(playerid);
if(result) if(result)
...@@ -371,10 +372,10 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con ...@@ -371,10 +372,10 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
return result; return result;
} }
// check functions: value of EFFECT_CANNOT_ACTIVATE, target, cost of EFFECT_ACTIVATE_COST // check functions: value of EFFECT_CANNOT_ACTIVATE, target, cost of EFFECT_ACTIVATE_COST
int32 effect::is_action_check(uint8 playerid) { int32_t effect::is_action_check(uint8_t playerid) {
effect_set eset; effect_set eset;
pduel->game_field->filter_player_effect(playerid, EFFECT_CANNOT_ACTIVATE, &eset); pduel->game_field->filter_player_effect(playerid, EFFECT_CANNOT_ACTIVATE, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(effect_set::size_type i = 0; i < eset.size(); ++i) {
pduel->lua->add_param(this, PARAM_TYPE_EFFECT); pduel->lua->add_param(this, PARAM_TYPE_EFFECT);
pduel->lua->add_param(playerid, PARAM_TYPE_INT); pduel->lua->add_param(playerid, PARAM_TYPE_INT);
if(eset[i]->check_value_condition(2)) if(eset[i]->check_value_condition(2))
...@@ -382,7 +383,7 @@ int32 effect::is_action_check(uint8 playerid) { ...@@ -382,7 +383,7 @@ int32 effect::is_action_check(uint8 playerid) {
} }
eset.clear(); eset.clear();
pduel->game_field->filter_player_effect(playerid, EFFECT_ACTIVATE_COST, &eset); pduel->game_field->filter_player_effect(playerid, EFFECT_ACTIVATE_COST, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(effect_set::size_type i = 0; i < eset.size(); ++i) {
pduel->lua->add_param(eset[i], PARAM_TYPE_EFFECT); pduel->lua->add_param(eset[i], PARAM_TYPE_EFFECT);
pduel->lua->add_param(this, PARAM_TYPE_EFFECT); pduel->lua->add_param(this, PARAM_TYPE_EFFECT);
pduel->lua->add_param(playerid, PARAM_TYPE_INT); pduel->lua->add_param(playerid, PARAM_TYPE_INT);
...@@ -397,7 +398,7 @@ int32 effect::is_action_check(uint8 playerid) { ...@@ -397,7 +398,7 @@ int32 effect::is_action_check(uint8 playerid) {
return TRUE; return TRUE;
} }
// check functions: condition, cost(chk=0), target(chk=0) // check functions: condition, cost(chk=0), target(chk=0)
int32 effect::is_activate_ready(effect* reason_effect, uint8 playerid, const tevent& e, int32 neglect_cond, int32 neglect_cost, int32 neglect_target) { int32_t effect::is_activate_ready(effect* reason_effect, uint8_t playerid, const tevent& e, int32_t neglect_cond, int32_t neglect_cost, int32_t neglect_target) {
if(!neglect_cond && condition) { if(!neglect_cond && condition) {
pduel->lua->add_param(reason_effect, PARAM_TYPE_EFFECT); pduel->lua->add_param(reason_effect, PARAM_TYPE_EFFECT);
pduel->lua->add_param(playerid, PARAM_TYPE_INT); pduel->lua->add_param(playerid, PARAM_TYPE_INT);
...@@ -449,18 +450,18 @@ int32 effect::is_activate_ready(effect* reason_effect, uint8 playerid, const tev ...@@ -449,18 +450,18 @@ int32 effect::is_activate_ready(effect* reason_effect, uint8 playerid, const tev
reason_effect->cost_checked = FALSE; reason_effect->cost_checked = FALSE;
return TRUE; return TRUE;
} }
int32 effect::is_activate_ready(uint8 playerid, const tevent& e, int32 neglect_cond, int32 neglect_cost, int32 neglect_target) { int32_t effect::is_activate_ready(uint8_t playerid, const tevent& e, int32_t neglect_cond, int32_t neglect_cost, int32_t neglect_target) {
return is_activate_ready(this, playerid, e, neglect_cond, neglect_cost, neglect_target); return is_activate_ready(this, playerid, e, neglect_cond, neglect_cost, neglect_target);
} }
// check functions: condition // check functions: condition
int32 effect::is_condition_check(uint8 playerid, const tevent& e) { int32_t effect::is_condition_check(uint8_t playerid, const tevent& e) {
card* phandler = get_handler(); card* phandler = get_handler();
if(!(type & EFFECT_TYPE_ACTIVATE) && (phandler->current.location & (LOCATION_ONFIELD | LOCATION_REMOVED)) && !phandler->is_position(POS_FACEUP)) if(!(type & EFFECT_TYPE_ACTIVATE) && (phandler->current.location & (LOCATION_ONFIELD | LOCATION_REMOVED)) && !phandler->is_position(POS_FACEUP))
return FALSE; return FALSE;
if(!condition) if(!condition)
return TRUE; return TRUE;
effect* oreason = pduel->game_field->core.reason_effect; effect* oreason = pduel->game_field->core.reason_effect;
uint8 op = pduel->game_field->core.reason_player; uint8_t op = pduel->game_field->core.reason_player;
pduel->game_field->core.reason_effect = this; pduel->game_field->core.reason_effect = this;
pduel->game_field->core.reason_player = playerid; pduel->game_field->core.reason_player = playerid;
pduel->game_field->save_lp_cost(); pduel->game_field->save_lp_cost();
...@@ -483,19 +484,19 @@ int32 effect::is_condition_check(uint8 playerid, const tevent& e) { ...@@ -483,19 +484,19 @@ int32 effect::is_condition_check(uint8 playerid, const tevent& e) {
pduel->game_field->core.reason_player = op; pduel->game_field->core.reason_player = op;
return TRUE; return TRUE;
} }
int32 effect::is_activate_check(uint8 playerid, const tevent& e, int32 neglect_cond, int32 neglect_cost, int32 neglect_target) { int32_t effect::is_activate_check(uint8_t playerid, const tevent& e, int32_t neglect_cond, int32_t neglect_cost, int32_t neglect_target) {
pduel->game_field->save_lp_cost(); pduel->game_field->save_lp_cost();
effect* oreason = pduel->game_field->core.reason_effect; effect* oreason = pduel->game_field->core.reason_effect;
uint8 op = pduel->game_field->core.reason_player; uint8_t op = pduel->game_field->core.reason_player;
pduel->game_field->core.reason_effect = this; pduel->game_field->core.reason_effect = this;
pduel->game_field->core.reason_player = playerid; pduel->game_field->core.reason_player = playerid;
int32 result = is_activate_ready(playerid, e, neglect_cond, neglect_cost, neglect_target); int32_t result = is_activate_ready(playerid, e, neglect_cond, neglect_cost, neglect_target);
pduel->game_field->core.reason_effect = oreason; pduel->game_field->core.reason_effect = oreason;
pduel->game_field->core.reason_player = op; pduel->game_field->core.reason_player = op;
pduel->game_field->restore_lp_cost(); pduel->game_field->restore_lp_cost();
return result; return result;
} }
int32 effect::is_target(card* pcard) { int32_t effect::is_target(card* pcard) {
if(type & EFFECT_TYPE_ACTIONS) if(type & EFFECT_TYPE_ACTIONS)
return FALSE; return FALSE;
if(type & (EFFECT_TYPE_SINGLE | EFFECT_TYPE_EQUIP | EFFECT_TYPE_XMATERIAL) && !(type & EFFECT_TYPE_FIELD)) if(type & (EFFECT_TYPE_SINGLE | EFFECT_TYPE_EQUIP | EFFECT_TYPE_XMATERIAL) && !(type & EFFECT_TYPE_FIELD))
...@@ -507,7 +508,7 @@ int32 effect::is_target(card* pcard) { ...@@ -507,7 +508,7 @@ int32 effect::is_target(card* pcard) {
&& !pcard->is_position(POS_FACEUP)) && !pcard->is_position(POS_FACEUP))
return FALSE; return FALSE;
if(!is_flag(EFFECT_FLAG_IGNORE_RANGE)) { if(!is_flag(EFFECT_FLAG_IGNORE_RANGE)) {
if(pcard->get_status(STATUS_SUMMONING | STATUS_SUMMON_DISABLED | STATUS_ACTIVATE_DISABLED | STATUS_SPSUMMON_STEP)) if(pcard->is_treated_as_not_on_field())
return FALSE; return FALSE;
if(is_flag(EFFECT_FLAG_SPSUM_PARAM)) if(is_flag(EFFECT_FLAG_SPSUM_PARAM))
return FALSE; return FALSE;
...@@ -531,7 +532,7 @@ int32 effect::is_target(card* pcard) { ...@@ -531,7 +532,7 @@ int32 effect::is_target(card* pcard) {
} }
return is_fit_target_function(pcard); return is_fit_target_function(pcard);
} }
int32 effect::is_fit_target_function(card* pcard) { int32_t effect::is_fit_target_function(card* pcard) {
if(target) { if(target) {
pduel->lua->add_param(this, PARAM_TYPE_EFFECT); pduel->lua->add_param(this, PARAM_TYPE_EFFECT);
pduel->lua->add_param(pcard, PARAM_TYPE_CARD); pduel->lua->add_param(pcard, PARAM_TYPE_CARD);
...@@ -541,10 +542,10 @@ int32 effect::is_fit_target_function(card* pcard) { ...@@ -541,10 +542,10 @@ int32 effect::is_fit_target_function(card* pcard) {
} }
return TRUE; return TRUE;
} }
int32 effect::is_target_player(uint8 playerid) { int32_t effect::is_target_player(uint8_t playerid) {
if(!is_flag(EFFECT_FLAG_PLAYER_TARGET)) if(!is_flag(EFFECT_FLAG_PLAYER_TARGET))
return FALSE; return FALSE;
uint8 self = get_handler_player(); uint8_t self = get_handler_player();
if(is_flag(EFFECT_FLAG_ABSOLUTE_TARGET)) { if(is_flag(EFFECT_FLAG_ABSOLUTE_TARGET)) {
if(s_range && playerid == 0) if(s_range && playerid == 0)
return TRUE; return TRUE;
...@@ -558,7 +559,7 @@ int32 effect::is_target_player(uint8 playerid) { ...@@ -558,7 +559,7 @@ int32 effect::is_target_player(uint8 playerid) {
} }
return FALSE; return FALSE;
} }
int32 effect::is_player_effect_target(card* pcard) { int32_t effect::is_player_effect_target(card* pcard) {
if(target) { if(target) {
handler->pduel->lua->add_param(this, PARAM_TYPE_EFFECT); handler->pduel->lua->add_param(this, PARAM_TYPE_EFFECT);
handler->pduel->lua->add_param(pcard, PARAM_TYPE_CARD); handler->pduel->lua->add_param(pcard, PARAM_TYPE_CARD);
...@@ -568,9 +569,9 @@ int32 effect::is_player_effect_target(card* pcard) { ...@@ -568,9 +569,9 @@ int32 effect::is_player_effect_target(card* pcard) {
} }
return TRUE; return TRUE;
} }
int32 effect::is_immuned(card* pcard) { int32_t effect::is_immuned(card* pcard) {
const effect_set_v& effects = pcard->immune_effect; const effect_set_v& effects = pcard->immune_effect;
for (int32 i = 0; i < effects.size(); ++i) { for (effect_set::size_type i = 0; i < effects.size(); ++i) {
effect* peffect = effects[i]; effect* peffect = effects[i];
if(peffect->is_available() && peffect->value) { if(peffect->is_available() && peffect->value) {
pduel->lua->add_param(this, PARAM_TYPE_EFFECT); pduel->lua->add_param(this, PARAM_TYPE_EFFECT);
...@@ -581,10 +582,10 @@ int32 effect::is_immuned(card* pcard) { ...@@ -581,10 +582,10 @@ int32 effect::is_immuned(card* pcard) {
} }
return FALSE; return FALSE;
} }
int32 effect::is_chainable(uint8 tp) { int32_t effect::is_chainable(uint8_t tp) {
if(!(type & EFFECT_TYPE_ACTIONS)) if(!(type & EFFECT_TYPE_ACTIONS))
return FALSE; return FALSE;
int32 sp = get_speed(); int32_t sp = get_speed();
// Curse of Field is the exception // Curse of Field is the exception
if((type & EFFECT_TYPE_ACTIVATE) && (sp <= 1) && !is_flag(EFFECT_FLAG2_COF)) if((type & EFFECT_TYPE_ACTIVATE) && (sp <= 1) && !is_flag(EFFECT_FLAG2_COF))
return FALSE; return FALSE;
...@@ -612,12 +613,20 @@ int32 effect::is_chainable(uint8 tp) { ...@@ -612,12 +613,20 @@ int32 effect::is_chainable(uint8 tp) {
} }
return TRUE; return TRUE;
} }
int32 effect::is_hand_trigger() { int32_t effect::is_hand_trigger() const {
return (range & LOCATION_HAND) && (type & EFFECT_TYPE_TRIGGER_O) && get_code_type() != CODE_PHASE; return (range & LOCATION_HAND) && (type & EFFECT_TYPE_TRIGGER_O) && get_code_type() != CODE_PHASE;
} }
int32_t effect::is_initial_single() const {
return (type & EFFECT_TYPE_SINGLE) && is_flag(EFFECT_FLAG_SINGLE_RANGE) && is_flag(EFFECT_FLAG_INITIAL);
}
int32_t effect::is_monster_effect() const {
if (range & (LOCATION_SZONE | LOCATION_FZONE | LOCATION_PZONE))
return FALSE;
return TRUE;
}
//return: this can be reset by reset_level or not //return: this can be reset by reset_level or not
//RESET_DISABLE is valid only when owner == handler //RESET_DISABLE is valid only when owner == handler
int32 effect::reset(uint32 reset_level, uint32 reset_type) { int32_t effect::reset(uint32_t reset_level, uint32_t reset_type) {
switch (reset_type) { switch (reset_type) {
case RESET_EVENT: { case RESET_EVENT: {
if(!(reset_flag & RESET_EVENT)) if(!(reset_flag & RESET_EVENT))
...@@ -636,11 +645,11 @@ int32 effect::reset(uint32 reset_level, uint32 reset_type) { ...@@ -636,11 +645,11 @@ int32 effect::reset(uint32 reset_level, uint32 reset_type) {
case RESET_PHASE: { case RESET_PHASE: {
if(!(reset_flag & RESET_PHASE)) if(!(reset_flag & RESET_PHASE))
return FALSE; return FALSE;
uint8 pid = get_owner_player(); uint8_t pid = get_owner_player();
uint8 tp = handler->pduel->game_field->infos.turn_player; uint8_t tp = handler->pduel->game_field->infos.turn_player;
if((((reset_flag & RESET_SELF_TURN) && pid == tp) || ((reset_flag & RESET_OPPO_TURN) && pid != tp)) if((((reset_flag & RESET_SELF_TURN) && pid == tp) || ((reset_flag & RESET_OPPO_TURN) && pid != tp))
&& (reset_level & 0x3ff & reset_flag)) && (reset_level & 0x3ff & reset_flag))
reset_count--; --reset_count;
if(reset_count == 0) if(reset_count == 0)
return TRUE; return TRUE;
return FALSE; return FALSE;
...@@ -657,7 +666,7 @@ int32 effect::reset(uint32 reset_level, uint32 reset_type) { ...@@ -657,7 +666,7 @@ int32 effect::reset(uint32 reset_level, uint32 reset_type) {
} }
return FALSE; return FALSE;
} }
void effect::dec_count(uint32 playerid) { void effect::dec_count(uint8_t playerid) {
if(!is_flag(EFFECT_FLAG_COUNT_LIMIT)) if(!is_flag(EFFECT_FLAG_COUNT_LIMIT))
return; return;
if(count_limit == 0) if(count_limit == 0)
...@@ -665,9 +674,10 @@ void effect::dec_count(uint32 playerid) { ...@@ -665,9 +674,10 @@ void effect::dec_count(uint32 playerid) {
if(count_code == 0 || is_flag(EFFECT_FLAG_NO_TURN_RESET)) if(count_code == 0 || is_flag(EFFECT_FLAG_NO_TURN_RESET))
count_limit -= 1; count_limit -= 1;
if(count_code) { if(count_code) {
uint32 code = count_code & 0xfffffff; uint32_t limit_code = count_code & MAX_CARD_ID;
if(code == 1) uint32_t limit_type = count_code & 0xf0000000;
pduel->game_field->add_effect_code((count_code & 0xf0000000) | get_handler()->fieldid, PLAYER_NONE); if(limit_code == EFFECT_COUNT_CODE_SINGLE)
pduel->game_field->add_effect_code(limit_type | get_handler()->activate_count_id, PLAYER_NONE);
else else
pduel->game_field->add_effect_code(count_code, playerid); pduel->game_field->add_effect_code(count_code, playerid);
} }
...@@ -677,81 +687,84 @@ void effect::recharge() { ...@@ -677,81 +687,84 @@ void effect::recharge() {
count_limit = count_limit_max; count_limit = count_limit_max;
} }
} }
int32 effect::get_value(uint32 extraargs) { int32_t effect::get_value(uint32_t extraargs) {
if(is_flag(EFFECT_FLAG_FUNC_VALUE)) { if(is_flag(EFFECT_FLAG_FUNC_VALUE)) {
pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE); pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE);
int32 res = pduel->lua->get_function_value(value, 1 + extraargs); int32_t res = pduel->lua->get_function_value(value, 1 + extraargs);
return res; return res;
} else { } else {
pduel->lua->params.clear(); pduel->lua->params.clear();
return (int32)value; return value;
} }
} }
int32 effect::get_value(card* pcard, uint32 extraargs) { int32_t effect::get_value(card* pcard, uint32_t extraargs) {
if(is_flag(EFFECT_FLAG_FUNC_VALUE)) { if(is_flag(EFFECT_FLAG_FUNC_VALUE)) {
pduel->lua->add_param(pcard, PARAM_TYPE_CARD, TRUE); pduel->lua->add_param(pcard, PARAM_TYPE_CARD, TRUE);
pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE); pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE);
int32 res = pduel->lua->get_function_value(value, 2 + extraargs); int32_t res = pduel->lua->get_function_value(value, 2 + extraargs);
return res; return res;
} else { } else {
pduel->lua->params.clear(); pduel->lua->params.clear();
return (int32)value; return value;
} }
} }
int32 effect::get_value(effect* peffect, uint32 extraargs) { int32_t effect::get_value(effect* peffect, uint32_t extraargs) {
if(is_flag(EFFECT_FLAG_FUNC_VALUE)) { if(is_flag(EFFECT_FLAG_FUNC_VALUE)) {
pduel->lua->add_param(peffect, PARAM_TYPE_EFFECT, TRUE); pduel->lua->add_param(peffect, PARAM_TYPE_EFFECT, TRUE);
pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE); pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE);
int32 res = pduel->lua->get_function_value(value, 2 + extraargs); int32_t res = pduel->lua->get_function_value(value, 2 + extraargs);
return res; return res;
} else { } else {
pduel->lua->params.clear(); pduel->lua->params.clear();
return (int32)value; return value;
} }
} }
void effect::get_value(uint32 extraargs, std::vector<int32>* result) { void effect::get_value(uint32_t extraargs, std::vector<lua_Integer>& result) {
if(is_flag(EFFECT_FLAG_FUNC_VALUE)) { if(is_flag(EFFECT_FLAG_FUNC_VALUE)) {
pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE); pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE);
pduel->lua->get_function_value(value, 1 + extraargs, result); pduel->lua->get_function_value(value, 1 + extraargs, result);
} else { } else {
pduel->lua->params.clear(); pduel->lua->params.clear();
result->push_back((int32)value); result.push_back(value);
} }
} }
void effect::get_value(card* pcard, uint32 extraargs, std::vector<int32>* result) { void effect::get_value(card* pcard, uint32_t extraargs, std::vector<lua_Integer>& result) {
if(is_flag(EFFECT_FLAG_FUNC_VALUE)) { if(is_flag(EFFECT_FLAG_FUNC_VALUE)) {
pduel->lua->add_param(pcard, PARAM_TYPE_CARD, TRUE); pduel->lua->add_param(pcard, PARAM_TYPE_CARD, TRUE);
pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE); pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE);
pduel->lua->get_function_value(value, 2 + extraargs, result); pduel->lua->get_function_value(value, 2 + extraargs, result);
} else { } else {
pduel->lua->params.clear(); pduel->lua->params.clear();
result->push_back((int32)value); result.push_back(value);
} }
} }
void effect::get_value(effect* peffect, uint32 extraargs, std::vector<int32>* result) { void effect::get_value(effect* peffect, uint32_t extraargs, std::vector<lua_Integer>& result) {
if(is_flag(EFFECT_FLAG_FUNC_VALUE)) { if(is_flag(EFFECT_FLAG_FUNC_VALUE)) {
pduel->lua->add_param(peffect, PARAM_TYPE_EFFECT, TRUE); pduel->lua->add_param(peffect, PARAM_TYPE_EFFECT, TRUE);
pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE); pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE);
pduel->lua->get_function_value(value, 2 + extraargs, result); pduel->lua->get_function_value(value, 2 + extraargs, result);
} else { } else {
pduel->lua->params.clear(); pduel->lua->params.clear();
result->push_back((int32)value); result.push_back(value);
} }
} }
int32 effect::check_value_condition(uint32 extraargs) { int32_t effect::get_integer_value() {
return is_flag(EFFECT_FLAG_FUNC_VALUE) ? 0 : value;
}
int32_t effect::check_value_condition(uint32_t extraargs) {
if(is_flag(EFFECT_FLAG_FUNC_VALUE)) { if(is_flag(EFFECT_FLAG_FUNC_VALUE)) {
pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE); pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE);
int32 res = pduel->lua->check_condition(value, 1 + extraargs); int32_t res = pduel->lua->check_condition(value, 1 + extraargs);
return res; return res;
} else { } else {
pduel->lua->params.clear(); pduel->lua->params.clear();
return (int32)value; return value;
} }
} }
void* effect::get_label_object() { void* effect::get_label_object() {
return pduel->lua->get_ref_object(label_object); return pduel->lua->get_ref_object(label_object);
} }
int32 effect::get_speed() { int32_t effect::get_speed() {
if(!(type & EFFECT_TYPE_ACTIONS)) if(!(type & EFFECT_TYPE_ACTIONS))
return 0; return 0;
if(type & (EFFECT_TYPE_TRIGGER_O | EFFECT_TYPE_TRIGGER_F | EFFECT_TYPE_IGNITION)) if(type & (EFFECT_TYPE_TRIGGER_O | EFFECT_TYPE_TRIGGER_F | EFFECT_TYPE_IGNITION))
...@@ -775,7 +788,7 @@ int32 effect::get_speed() { ...@@ -775,7 +788,7 @@ int32 effect::get_speed() {
} }
effect* effect::clone() { effect* effect::clone() {
effect* ceffect = pduel->new_effect(); effect* ceffect = pduel->new_effect();
int32 ref = ceffect->ref_handle; int32_t ref = ceffect->ref_handle;
*ceffect = *this; *ceffect = *this;
ceffect->ref_handle = ref; ceffect->ref_handle = ref;
ceffect->handler = 0; ceffect->handler = 0;
...@@ -798,7 +811,7 @@ card* effect::get_owner() const { ...@@ -798,7 +811,7 @@ card* effect::get_owner() const {
return handler->overlay_target; return handler->overlay_target;
return owner; return owner;
} }
uint8 effect::get_owner_player() { uint8_t effect::get_owner_player() const {
if(effect_owner != PLAYER_NONE) if(effect_owner != PLAYER_NONE)
return effect_owner; return effect_owner;
return get_owner()->current.controler; return get_owner()->current.controler;
...@@ -810,17 +823,17 @@ card* effect::get_handler() const { ...@@ -810,17 +823,17 @@ card* effect::get_handler() const {
return handler->overlay_target; return handler->overlay_target;
return handler; return handler;
} }
uint8 effect::get_handler_player() { uint8_t effect::get_handler_player() const {
if(is_flag(EFFECT_FLAG_FIELD_ONLY)) if(is_flag(EFFECT_FLAG_FIELD_ONLY))
return effect_owner; return effect_owner;
return get_handler()->current.controler; return get_handler()->current.controler;
} }
int32 effect::in_range(card* pcard) { int32_t effect::in_range(card* pcard) const {
if(type & EFFECT_TYPE_XMATERIAL) if(type & EFFECT_TYPE_XMATERIAL)
return handler->overlay_target ? TRUE : FALSE; return handler->overlay_target ? TRUE : FALSE;
return pcard->current.is_location(range); return pcard->current.is_location(range);
} }
int32 effect::in_range(const chain& ch) { int32_t effect::in_range(const chain& ch) const {
if(type & EFFECT_TYPE_XMATERIAL) if(type & EFFECT_TYPE_XMATERIAL)
return handler->overlay_target ? TRUE : FALSE; return handler->overlay_target ? TRUE : FALSE;
return range & ch.triggering_location; return range & ch.triggering_location;
...@@ -836,9 +849,9 @@ void effect::set_active_type() { ...@@ -836,9 +849,9 @@ void effect::set_active_type() {
if(active_type & TYPE_TRAPMONSTER) if(active_type & TYPE_TRAPMONSTER)
active_type &= ~TYPE_TRAP; active_type &= ~TYPE_TRAP;
} }
uint32 effect::get_active_type() { uint32_t effect::get_active_type(uint8_t uselast) {
if(type & 0x7f0) { if(type & EFFECT_TYPES_CHAIN_LINK) {
if(active_type) if(active_type && uselast)
return active_type; return active_type;
else if((type & EFFECT_TYPE_ACTIVATE) && (get_handler()->data.type & TYPE_PENDULUM)) else if((type & EFFECT_TYPE_ACTIVATE) && (get_handler()->data.type & TYPE_PENDULUM))
return TYPE_PENDULUM + TYPE_SPELL; return TYPE_PENDULUM + TYPE_SPELL;
...@@ -847,9 +860,9 @@ uint32 effect::get_active_type() { ...@@ -847,9 +860,9 @@ uint32 effect::get_active_type() {
} else } else
return owner->get_type(); return owner->get_type();
} }
int32 effect::get_code_type() { code_type effect::get_code_type() const {
// start from the highest bit // start from the highest bit
if (code & EVENT_CUSTOM) if (code & 0xf0000000)
return CODE_CUSTOM; return CODE_CUSTOM;
else if (code & 0xf0000) else if (code & 0xf0000)
return CODE_COUNTER; return CODE_COUNTER;
......
...@@ -11,110 +11,116 @@ ...@@ -11,110 +11,116 @@
#include "common.h" #include "common.h"
#include "field.h" #include "field.h"
#include "effectset.h" #include "effectset.h"
#include <stdlib.h>
#include <vector> #include <vector>
#include <map>
class card; class card;
class duel; class duel;
class group; class group;
class effect; class effect;
struct tevent; struct tevent;
struct effect_set; enum effect_flag : uint64_t;
struct effect_set_v; enum effect_flag2 : uint64_t;
enum effect_flag : uint32; enum effect_category :uint64_t;
enum effect_flag2 : uint32; enum code_type : int32_t;
bool is_continuous_event(uint32_t code);
class effect { class effect {
public: public:
int32 ref_handle; int32_t ref_handle{ 0 };
duel* pduel; duel* pduel{ nullptr };
card* owner; card* owner{ nullptr };
card* handler; card* handler{ nullptr };
uint8 effect_owner; uint8_t effect_owner{ PLAYER_NONE };
uint32 description; uint32_t description{ 0 };
uint32 code; uint32_t code{ 0 };
uint32 flag[2]; uint32_t id{ 0 };
uint32 id; uint32_t type{ 0 };
uint16 type; uint16_t copy_id{ 0 };
uint16 copy_id; uint16_t range{ 0 };
uint16 range; uint16_t s_range{ 0 };
uint16 s_range; uint16_t o_range{ 0 };
uint16 o_range; uint8_t count_limit{ 0 }; //left count of activation
uint8 count_limit; uint8_t count_limit_max{ 0 }; //max count of activation
uint8 count_limit_max; uint16_t status{ 0 };
uint16 reset_count; int32_t reset_count{ 0 };
uint32 reset_flag; uint32_t reset_flag{ 0 };
uint32 count_code; uint32_t count_code{ 0 };
uint32 category; uint64_t category{ 0 };
uint32 hint_timing[2]; uint64_t flag[2]{};
uint32 card_type; uint32_t hint_timing[2]{};
uint32 active_type; uint32_t card_type{ 0 };
uint16 active_location; uint32_t active_type{ 0 };
uint16 active_sequence; uint16_t active_location{ 0 };
card* active_handler; uint16_t active_sequence{ 0 };
uint16 status; card* active_handler{ nullptr };
std::vector<uint32> label; std::vector<lua_Integer> label;
int32 label_object; int32_t label_object{ 0 };
int32 condition; int32_t condition{ 0 };
int32 cost; int32_t cost{ 0 };
int32 target; int32_t target{ 0 };
int32 value; int32_t value{ 0 };
int32 operation; int32_t operation{ 0 };
uint8 cost_checked; uint8_t cost_checked{ FALSE };
effect_set required_handorset_effects;
LuaParamType object_type{ PARAM_TYPE_INT };
explicit effect(duel* pd); explicit effect(duel* pd);
~effect() = default; ~effect() = default;
int32 is_disable_related(); int32_t is_disable_related() const;
int32 is_self_destroy_related(); int32_t is_self_destroy_related() const;
int32 is_can_be_forbidden(); int32_t is_can_be_forbidden() const;
int32 is_available(int32 neglect_disabled = FALSE); int32_t is_available(int32_t neglect_disabled = FALSE);
int32 limit_counter_is_available(); int32_t limit_counter_is_available();
int32 is_single_ready(); int32_t is_single_ready();
int32 check_count_limit(uint8 playerid); int32_t check_count_limit(uint8_t playerid);
int32 is_activateable(uint8 playerid, const tevent& e, int32 neglect_cond = FALSE, int32 neglect_cost = FALSE, int32 neglect_target = FALSE, int32 neglect_loc = FALSE, int32 neglect_faceup = FALSE); int32_t get_required_handorset_effects(effect_set* eset, uint8_t playerid, const tevent& e, int32_t neglect_loc = FALSE);
int32 is_action_check(uint8 playerid); int32_t is_activateable(uint8_t playerid, const tevent &e, int32_t neglect_cond = FALSE, int32_t neglect_cost = FALSE, int32_t neglect_target = FALSE, int32_t neglect_loc = FALSE, int32_t neglect_faceup = FALSE);
int32 is_activate_ready(effect* reason_effect, uint8 playerid, const tevent& e, int32 neglect_cond = FALSE, int32 neglect_cost = FALSE, int32 neglect_target = FALSE); int32_t is_action_check(uint8_t playerid);
int32 is_activate_ready(uint8 playerid, const tevent& e, int32 neglect_cond = FALSE, int32 neglect_cost = FALSE, int32 neglect_target = FALSE); int32_t is_activate_ready(effect* reason_effect, uint8_t playerid, const tevent& e, int32_t neglect_cond = FALSE, int32_t neglect_cost = FALSE, int32_t neglect_target = FALSE);
int32 is_condition_check(uint8 playerid, const tevent& e); int32_t is_activate_ready(uint8_t playerid, const tevent& e, int32_t neglect_cond = FALSE, int32_t neglect_cost = FALSE, int32_t neglect_target = FALSE);
int32 is_activate_check(uint8 playerid, const tevent& e, int32 neglect_cond = FALSE, int32 neglect_cost = FALSE, int32 neglect_target = FALSE); int32_t is_condition_check(uint8_t playerid, const tevent& e);
int32 is_target(card* pcard); int32_t is_activate_check(uint8_t playerid, const tevent& e, int32_t neglect_cond = FALSE, int32_t neglect_cost = FALSE, int32_t neglect_target = FALSE);
int32 is_fit_target_function(card* pcard); int32_t is_target(card* pcard);
int32 is_target_player(uint8 playerid); int32_t is_fit_target_function(card* pcard);
int32 is_player_effect_target(card* pcard); int32_t is_target_player(uint8_t playerid);
int32 is_immuned(card* pcard); int32_t is_player_effect_target(card* pcard);
int32 is_chainable(uint8 tp); int32_t is_immuned(card* pcard);
int32 is_hand_trigger(); int32_t is_chainable(uint8_t tp);
int32 reset(uint32 reset_level, uint32 reset_type); int32_t is_hand_trigger() const;
void dec_count(uint32 playerid = 2); int32_t is_initial_single() const;
int32_t is_monster_effect() const;
int32_t reset(uint32_t reset_level, uint32_t reset_type);
void dec_count(uint8_t playerid = PLAYER_NONE);
void recharge(); void recharge();
int32 get_value(uint32 extraargs = 0); int32_t get_value(uint32_t extraargs = 0);
int32 get_value(card* pcard, uint32 extraargs = 0); int32_t get_value(card* pcard, uint32_t extraargs = 0);
int32 get_value(effect* peffect, uint32 extraargs = 0); int32_t get_value(effect* peffect, uint32_t extraargs = 0);
void get_value(uint32 extraargs, std::vector<int32>* result); void get_value(uint32_t extraargs, std::vector<lua_Integer>& result);
void get_value(card* pcard, uint32 extraargs, std::vector<int32>* result); void get_value(card* pcard, uint32_t extraargs, std::vector<lua_Integer>& result);
void get_value(effect* peffect, uint32 extraargs, std::vector<int32>* result); void get_value(effect* peffect, uint32_t extraargs, std::vector<lua_Integer>& result);
int32 check_value_condition(uint32 extraargs = 0); int32_t get_integer_value();
int32_t check_value_condition(uint32_t extraargs = 0);
void* get_label_object(); void* get_label_object();
int32 get_speed(); int32_t get_speed();
effect* clone(); effect* clone();
card* get_owner() const; card* get_owner() const;
uint8 get_owner_player(); uint8_t get_owner_player() const;
card* get_handler() const; card* get_handler() const;
uint8 get_handler_player(); uint8_t get_handler_player() const;
int32 in_range(card* pcard); int32_t in_range(card* pcard) const;
int32 in_range(const chain& ch); int32_t in_range(const chain& ch) const;
void set_activate_location(); void set_activate_location();
void set_active_type(); void set_active_type();
uint32 get_active_type(); uint32_t get_active_type(uint8_t uselast = TRUE);
int32 get_code_type(); code_type get_code_type() const;
bool is_flag(effect_flag flag) const { bool is_flag(effect_flag x) const {
return !!(this->flag[0] & flag); return !!(flag[0] & x);
} }
bool is_flag(effect_flag2 flag) const { bool is_flag(effect_flag2 x) const {
return !!(this->flag[1] & flag); return !!(flag[1] & x);
} }
}; };
...@@ -123,8 +129,10 @@ public: ...@@ -123,8 +129,10 @@ public:
//#define EFFECT_STATUS_ACTIVATED 0x0002 //#define EFFECT_STATUS_ACTIVATED 0x0002
#define EFFECT_STATUS_SPSELF 0x0004 #define EFFECT_STATUS_SPSELF 0x0004
#define EFFECT_COUNT_CODE_OATH 0x10000000 #define EFFECT_COUNT_CODE_OATH 0x10000000U
#define EFFECT_COUNT_CODE_DUEL 0x20000000 #define EFFECT_COUNT_CODE_DUEL 0x20000000U
#define EFFECT_COUNT_CODE_CHAIN 0x40000000U
#define EFFECT_COUNT_CODE_SINGLE 0x1U
//========== Reset ========== //========== Reset ==========
#define RESET_SELF_TURN 0x10000000 #define RESET_SELF_TURN 0x10000000
...@@ -149,6 +157,8 @@ public: ...@@ -149,6 +157,8 @@ public:
#define RESET_OVERLAY 0x04000000 #define RESET_OVERLAY 0x04000000
#define RESET_MSCHANGE 0x08000000 #define RESET_MSCHANGE 0x08000000
constexpr uint32_t RESETS_STANDARD = RESET_TOFIELD | RESET_LEAVE | RESET_TODECK | RESET_TOHAND | RESET_TEMP_REMOVE | RESET_REMOVE | RESET_TOGRAVE | RESET_TURN_SET;
//========== Types ========== //========== Types ==========
#define EFFECT_TYPE_SINGLE 0x0001 // #define EFFECT_TYPE_SINGLE 0x0001 //
#define EFFECT_TYPE_FIELD 0x0002 // #define EFFECT_TYPE_FIELD 0x0002 //
...@@ -166,10 +176,11 @@ public: ...@@ -166,10 +176,11 @@ public:
#define EFFECT_TYPE_GRANT 0x2000 // #define EFFECT_TYPE_GRANT 0x2000 //
#define EFFECT_TYPE_TARGET 0x4000 // #define EFFECT_TYPE_TARGET 0x4000 //
#define EFFECT_TYPES_TRIGGER_LIKE (EFFECT_TYPE_ACTIVATE | EFFECT_TYPE_TRIGGER_O | EFFECT_TYPE_TRIGGER_F | EFFECT_TYPE_QUICK_O | EFFECT_TYPE_QUICK_F) constexpr uint32_t EFFECT_TYPES_TRIGGER_LIKE = EFFECT_TYPE_ACTIVATE | EFFECT_TYPE_TRIGGER_O | EFFECT_TYPE_TRIGGER_F | EFFECT_TYPE_QUICK_O | EFFECT_TYPE_QUICK_F;
constexpr uint32_t EFFECT_TYPES_CHAIN_LINK = EFFECT_TYPES_TRIGGER_LIKE | EFFECT_TYPE_FLIP | EFFECT_TYPE_IGNITION;
//========== Flags ========== //========== Flags ==========
enum effect_flag : uint32 { enum effect_flag : uint64_t {
EFFECT_FLAG_INITIAL = 0x0001, EFFECT_FLAG_INITIAL = 0x0001,
EFFECT_FLAG_FUNC_VALUE = 0x0002, EFFECT_FLAG_FUNC_VALUE = 0x0002,
EFFECT_FLAG_COUNT_LIMIT = 0x0004, EFFECT_FLAG_COUNT_LIMIT = 0x0004,
...@@ -183,7 +194,7 @@ enum effect_flag : uint32 { ...@@ -183,7 +194,7 @@ enum effect_flag : uint32 {
EFFECT_FLAG_CANNOT_DISABLE = 0x0400, EFFECT_FLAG_CANNOT_DISABLE = 0x0400,
EFFECT_FLAG_PLAYER_TARGET = 0x0800, EFFECT_FLAG_PLAYER_TARGET = 0x0800,
EFFECT_FLAG_BOTH_SIDE = 0x1000, EFFECT_FLAG_BOTH_SIDE = 0x1000,
EFFECT_FLAG_COPY_INHERIT = 0x2000, EFFECT_FLAG_COPY = 0x2000,
EFFECT_FLAG_DAMAGE_STEP = 0x4000, EFFECT_FLAG_DAMAGE_STEP = 0x4000,
EFFECT_FLAG_DAMAGE_CAL = 0x8000, EFFECT_FLAG_DAMAGE_CAL = 0x8000,
EFFECT_FLAG_DELAY = 0x10000, EFFECT_FLAG_DELAY = 0x10000,
...@@ -199,20 +210,66 @@ enum effect_flag : uint32 { ...@@ -199,20 +210,66 @@ enum effect_flag : uint32 {
EFFECT_FLAG_CLIENT_HINT = 0x4000000, EFFECT_FLAG_CLIENT_HINT = 0x4000000,
EFFECT_FLAG_CONTINUOUS_TARGET = 0x8000000, EFFECT_FLAG_CONTINUOUS_TARGET = 0x8000000,
EFFECT_FLAG_LIMIT_ZONE = 0x10000000, EFFECT_FLAG_LIMIT_ZONE = 0x10000000,
// EFFECT_FLAG_COF = 0x20000000, EFFECT_FLAG_ACTIVATE_CONDITION = 0x20000000,
// EFFECT_FLAG_CVAL_CHECK = 0x40000000, // EFFECT_FLAG_CVAL_CHECK = 0x40000000,
EFFECT_FLAG_IMMEDIATELY_APPLY = 0x80000000, EFFECT_FLAG_IMMEDIATELY_APPLY = 0x80000000,
EFFECT_FLAG_COIN = 0x100000000,
EFFECT_FLAG_DICE = 0x200000000,
EFFECT_FLAG_FUSION_SUMMON = 0x400000000,
}; };
enum effect_flag2 : uint32 { enum effect_flag2 : uint64_t {
// EFFECT_FLAG2_MILLENNIUM_RESTRICT = 0x0001, EFFECT_FLAG2_REPEAT_UPDATE = 0x0001,
EFFECT_FLAG2_COF = 0x0002, EFFECT_FLAG2_COF = 0x0002,
EFFECT_FLAG2_WICKED = 0x0004, EFFECT_FLAG2_WICKED = 0x0004,
EFFECT_FLAG2_OPTION = 0x0008, EFFECT_FLAG2_OPTION = 0x0008,
}; };
inline effect_flag operator|(effect_flag flag1, effect_flag flag2) constexpr effect_flag operator|(effect_flag flag1, effect_flag flag2) {
{ return static_cast<effect_flag>(static_cast<uint64_t>(flag1) | static_cast<uint64_t>(flag2));
return static_cast<effect_flag>(static_cast<uint32>(flag1) | static_cast<uint32>(flag2));
} }
constexpr uint64_t INTERNAL_FLAGS = EFFECT_FLAG_INITIAL | EFFECT_FLAG_COPY | EFFECT_FLAG_FUNC_VALUE | EFFECT_FLAG_COUNT_LIMIT | EFFECT_FLAG_FIELD_ONLY | EFFECT_FLAG_ABSOLUTE_TARGET;
//Category
enum effect_category : uint64_t {
CATEGORY_DESTROY = 0x1,
CATEGORY_RELEASE = 0x2,
CATEGORY_REMOVE = 0x4,
CATEGORY_TOHAND = 0x8,
CATEGORY_TODECK = 0x10,
CATEGORY_TOGRAVE = 0x20,
CATEGORY_DECKDES = 0x40,
CATEGORY_HANDES = 0x80,
CATEGORY_SUMMON = 0x100,
CATEGORY_SPECIAL_SUMMON = 0x200,
CATEGORY_TOKEN = 0x400,
CATEGORY_GRAVE_ACTION = 0x800,
CATEGORY_POSITION = 0x1000,
CATEGORY_CONTROL = 0x2000,
CATEGORY_DISABLE = 0x4000,
CATEGORY_DISABLE_SUMMON = 0x8000,
CATEGORY_DRAW = 0x10000,
CATEGORY_SEARCH = 0x20000,
CATEGORY_EQUIP = 0x40000,
CATEGORY_DAMAGE = 0x80000,
CATEGORY_RECOVER = 0x100000,
CATEGORY_ATKCHANGE = 0x200000,
CATEGORY_DEFCHANGE = 0x400000,
CATEGORY_COUNTER = 0x800000,
CATEGORY_COIN = 0x1000000,
CATEGORY_DICE = 0x2000000,
CATEGORY_LEAVE_GRAVE = 0x4000000,
CATEGORY_GRAVE_SPSUMMON = 0x8000000,
CATEGORY_NEGATE = 0x10000000,
CATEGORY_ANNOUNCE = 0x20000000,
CATEGORY_FUSION_SUMMON = 0x40000000,
CATEGORY_TOEXTRA = 0x80000000,
};
const std::map<uint64_t, uint64_t> category_checklist{
{CATEGORY_COIN, EFFECT_FLAG_COIN},
{CATEGORY_DICE, EFFECT_FLAG_DICE},
{CATEGORY_FUSION_SUMMON, EFFECT_FLAG_FUSION_SUMMON},
};
//========== Codes ========== //========== Codes ==========
#define EFFECT_IMMUNE_EFFECT 1 // #define EFFECT_IMMUNE_EFFECT 1 //
#define EFFECT_DISABLE 2 // #define EFFECT_DISABLE 2 //
...@@ -383,7 +440,7 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2) ...@@ -383,7 +440,7 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
#define EFFECT_TOSS_DICE_REPLACE 221 #define EFFECT_TOSS_DICE_REPLACE 221
#define EFFECT_FUSION_MATERIAL 230 #define EFFECT_FUSION_MATERIAL 230
#define EFFECT_CHAIN_MATERIAL 231 #define EFFECT_CHAIN_MATERIAL 231
#define EFFECT_SYNCHRO_MATERIAL 232 #define EFFECT_EXTRA_SYNCHRO_MATERIAL 232
#define EFFECT_XYZ_MATERIAL 233 #define EFFECT_XYZ_MATERIAL 233
#define EFFECT_FUSION_SUBSTITUTE 234 #define EFFECT_FUSION_SUBSTITUTE 234
#define EFFECT_CANNOT_BE_FUSION_MATERIAL 235 #define EFFECT_CANNOT_BE_FUSION_MATERIAL 235
...@@ -467,6 +524,12 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2) ...@@ -467,6 +524,12 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
#define EFFECT_CHANGE_GRAVE_RACE 366 #define EFFECT_CHANGE_GRAVE_RACE 366
#define EFFECT_ACTIVATION_COUNT_LIMIT 367 #define EFFECT_ACTIVATION_COUNT_LIMIT 367
#define EFFECT_LIMIT_SPECIAL_SUMMON_POSITION 368 #define EFFECT_LIMIT_SPECIAL_SUMMON_POSITION 368
#define EFFECT_TUNER 369
#define EFFECT_KAISER_COLOSSEUM 370
#define EFFECT_REPLACE_DAMAGE 371
#define EFFECT_XYZ_MIN_COUNT 372
#define EFFECT_SYNCHRO_LEVEL_EX 373
#define EFFECT_RITUAL_LEVEL_EX 374
//#define EVENT_STARTUP 1000 //#define EVENT_STARTUP 1000
#define EVENT_FLIP 1001 #define EVENT_FLIP 1001
...@@ -493,6 +556,7 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2) ...@@ -493,6 +556,7 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
#define EVENT_DESTROYED 1029 #define EVENT_DESTROYED 1029
#define EVENT_MOVE 1030 #define EVENT_MOVE 1030
#define EVENT_LEAVE_GRAVE 1031 #define EVENT_LEAVE_GRAVE 1031
#define EVENT_LEAVE_DECK 1032
#define EVENT_ADJUST 1040 #define EVENT_ADJUST 1040
#define EVENT_BREAK_EFFECT 1050 #define EVENT_BREAK_EFFECT 1050
#define EVENT_SUMMON_SUCCESS 1100 #define EVENT_SUMMON_SUCCESS 1100
...@@ -512,6 +576,7 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2) ...@@ -512,6 +576,7 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
#define EVENT_SUMMON_NEGATED 1114 #define EVENT_SUMMON_NEGATED 1114
#define EVENT_FLIP_SUMMON_NEGATED 1115 #define EVENT_FLIP_SUMMON_NEGATED 1115
#define EVENT_SPSUMMON_NEGATED 1116 #define EVENT_SPSUMMON_NEGATED 1116
#define EVENT_SPSUMMON_SUCCESS_G_P 1117
#define EVENT_CONTROL_CHANGED 1120 #define EVENT_CONTROL_CHANGED 1120
#define EVENT_EQUIP 1121 #define EVENT_EQUIP 1121
#define EVENT_ATTACK_ANNOUNCE 1130 #define EVENT_ATTACK_ANNOUNCE 1130
...@@ -542,16 +607,36 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2) ...@@ -542,16 +607,36 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
#define EVENT_REMOVE_COUNTER 0x20000 #define EVENT_REMOVE_COUNTER 0x20000
#define EVENT_CUSTOM 0x10000000 #define EVENT_CUSTOM 0x10000000
#define DOUBLE_DAMAGE 0x80000000 constexpr int32_t DOUBLE_DAMAGE = INT32_MIN;
#define HALF_DAMAGE 0x80000001 constexpr int32_t HALF_DAMAGE = INT32_MIN + 1;
// The type of event in code constexpr uint32_t MAX_PARAMETER = 0xffffU;
#define CODE_CUSTOM 1 // header + id (28 bits) constexpr uint32_t MAX_XYZ_LEVEL = 0x0fffU;
#define CODE_COUNTER 2 // header + counter_id (16 bits)
#define CODE_PHASE 3 // header + phase_id (12 bits)
#define CODE_VALUE 4 // numeric value, max = 4095
const std::unordered_set<uint32> continuous_event({ EVENT_ADJUST, EVENT_BREAK_EFFECT, EVENT_TURN_END }); // flag effect
bool is_continuous_event(uint32 code); #define EFFECT_FLAG_EFFECT 0x20000000U
#define MAX_CARD_ID 0x0fffffffU
// The type of effect code
enum code_type : int32_t {
CODE_CUSTOM = 1, // header + id (28 bits)
CODE_COUNTER, // header + counter_id (16 bits)
CODE_PHASE, // header + phase_id (12 bits)
CODE_VALUE, // numeric value, max = 4095
};
const std::unordered_set<uint32_t> continuous_event{
EVENT_ADJUST,
EVENT_BREAK_EFFECT,
EVENT_TURN_END,
EVENT_PRE_BATTLE_DAMAGE,
EVENT_SPSUMMON_SUCCESS_G_P,
};
const std::unordered_set<uint32_t> affect_summoning_effect{
EFFECT_CANNOT_DISABLE_SUMMON,
EFFECT_CANNOT_DISABLE_SPSUMMON,
EVENT_BE_PRE_MATERIAL,
};
#endif /* EFFECT_H_ */ #endif /* EFFECT_H_ */
...@@ -8,8 +8,6 @@ ...@@ -8,8 +8,6 @@
#ifndef EFFECTSET_H_ #ifndef EFFECTSET_H_
#define EFFECTSET_H_ #define EFFECTSET_H_
#include <stdlib.h>
#include <array>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
...@@ -17,100 +15,7 @@ class effect; ...@@ -17,100 +15,7 @@ class effect;
bool effect_sort_id(const effect* e1, const effect* e2); bool effect_sort_id(const effect* e1, const effect* e2);
struct effect_set { using effect_set = std::vector<effect*>;
effect_set() using effect_set_v = effect_set;
: count(0), container{ nullptr } {}
void add_item(effect* peffect) {
if(count >= 64) return;
container[count++] = peffect;
}
void remove_item(int index) {
if(index >= count)
return;
if(index == count - 1) {
count--;
return;
}
for(int i = index; i < count - 1; ++i)
container[i] = container[i + 1];
count--;
}
void clear() {
count = 0;
}
int size() const {
return count;
}
void sort() {
if(count < 2)
return;
std::sort(container.begin(), container.begin() + count, effect_sort_id);
}
effect* const& get_last() const {
return container[count - 1];
}
effect*& get_last() {
return container[count - 1];
}
effect* const& operator[] (int index) const {
return container[index];
}
effect*& operator[] (int index) {
return container[index];
}
effect* const& at(int index) const {
return container[index];
}
effect*& at(int index) {
return container[index];
}
private:
std::array<effect*, 64> container;
int count;
};
struct effect_set_v {
effect_set_v() {}
void add_item(effect* peffect) {
container.push_back(peffect);
}
void remove_item(int index) {
if(index >= (int)container.size())
return;
container.erase(container.begin() + index);
}
void clear() {
container.clear();
}
int size() const {
return (int)container.size();
}
void sort() {
int count = (int)container.size();
if(count < 2)
return;
std::sort(container.begin(), container.begin() + count, effect_sort_id);
}
effect* const& get_last() const {
return container.back();
}
effect*& get_last() {
return container.back();
}
effect* const& operator[] (int index) const {
return container[index];
}
effect*& operator[] (int index) {
return container[index];
}
effect* const& at(int index) const {
return container[index];
}
effect*& at(int index) {
return container[index];
}
private:
std::vector<effect*> container;
};
#endif //EFFECTSET_H_ #endif //EFFECTSET_H_
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -11,82 +11,81 @@ ...@@ -11,82 +11,81 @@
#include "common.h" #include "common.h"
#include "card.h" #include "card.h"
#include "effectset.h" #include "effectset.h"
#include "interpreter.h"
#include <vector> #include <vector>
#include <set> #include <set>
#include <map> #include <map>
#include <list> #include <list>
#include <array>
#include <functional>
#include <unordered_map> #include <unordered_map>
#include <unordered_set> #include <unordered_set>
#define MAX_COIN_COUNT 20
//summon action type
#define SUMMON_IN_IDLE 0
#define SUMMON_IN_CHAIN 1
class card; class card;
struct card_data; struct card_data;
class duel; class duel;
class group; class group;
class effect; class effect;
using effect_vector = std::vector<effect*>;
struct tevent { struct tevent {
card* trigger_card; card* trigger_card{ nullptr };
group* event_cards; group* event_cards{ nullptr };
effect* reason_effect; effect* reason_effect{ nullptr };
uint32 event_code; uint32_t event_code{ 0 };
uint32 event_value; uint32_t event_value{ 0 };
uint32 reason; uint32_t reason{ 0 };
uint8 event_player; uint8_t event_player{ PLAYER_NONE };
uint8 reason_player; uint8_t reason_player{ PLAYER_NONE };
tevent()
: trigger_card(nullptr), event_cards(nullptr), reason_effect(nullptr), event_code(0), event_value(0), reason(0), event_player(PLAYER_NONE), reason_player(PLAYER_NONE) {}
bool operator< (const tevent& v) const; bool operator< (const tevent& v) const;
}; };
struct optarget { struct optarget {
group* op_cards; group* op_cards{ nullptr };
uint8 op_count; uint8_t op_count{ 0 };
uint8 op_player; uint8_t op_player{ PLAYER_NONE };
int32 op_param; int32_t op_param{ 0 };
optarget()
: op_cards(nullptr), op_count(0), op_player(PLAYER_NONE), op_param(0) {}
}; };
struct chain { struct chain {
using opmap = std::unordered_map<uint32, optarget>; using opmap = std::unordered_map<uint32_t, optarget>;
uint16 chain_id; uint16_t chain_id{ 0 };
uint8 chain_count; uint8_t chain_count{ 0 };
uint8 triggering_player; uint8_t triggering_player{ PLAYER_NONE };
uint8 triggering_controler; uint8_t triggering_controler{ PLAYER_NONE };
uint16 triggering_location; uint16_t triggering_location{ 0 };
uint8 triggering_sequence; uint8_t triggering_sequence{ 0 };
uint8 triggering_position; uint8_t triggering_position{ 0 };
card_state triggering_state; card_state triggering_state;
effect* triggering_effect; effect* triggering_effect{ nullptr };
group* target_cards; group* target_cards{ nullptr };
int32 replace_op; int32_t replace_op{ 0 };
uint8 target_player; uint8_t target_player{ PLAYER_NONE };
int32 target_param; int32_t target_param{ 0 };
effect* disable_reason; effect* disable_reason{ nullptr };
uint8 disable_player; uint8_t disable_player{ PLAYER_NONE };
tevent evt; tevent evt;
opmap opinfos; opmap opinfos;
uint32 flag; uint32_t flag{ 0 };
effect_set required_handorset_effects;
chain()
: chain_id(0), chain_count(0), triggering_player(PLAYER_NONE), triggering_controler(PLAYER_NONE), triggering_location(0), triggering_sequence(0), triggering_position(0),
triggering_state(), triggering_effect(nullptr), target_cards(nullptr), replace_op(0), target_player(PLAYER_NONE), target_param(0), disable_reason(nullptr), disable_player(PLAYER_NONE),
evt(), flag(0) {}
static bool chain_operation_sort(const chain& c1, const chain& c2); static bool chain_operation_sort(const chain& c1, const chain& c2);
void set_triggering_state(card* pcard); void set_triggering_state(card* pcard);
}; };
struct player_info { struct player_info {
using card_vector = std::vector<card*>; int32_t lp{ 8000 };
int32 lp; int32_t start_count{ 5 };
int32 start_count; int32_t draw_count{ 1 };
int32 draw_count; uint32_t used_location{ 0 };
uint32 used_location; uint32_t disabled_location{ 0 };
uint32 disabled_location; uint32_t extra_p_count{ 0 };
uint32 extra_p_count; uint32_t tag_extra_p_count{ 0 };
uint32 tag_extra_p_count; int32_t szone_size{ 6 };
card_vector list_mzone; card_vector list_mzone;
card_vector list_szone; card_vector list_szone;
card_vector list_main; card_vector list_main;
...@@ -97,15 +96,9 @@ struct player_info { ...@@ -97,15 +96,9 @@ struct player_info {
card_vector tag_list_main; card_vector tag_list_main;
card_vector tag_list_hand; card_vector tag_list_hand;
card_vector tag_list_extra; card_vector tag_list_extra;
player_info()
: lp(0), start_count(0), draw_count(0), used_location(0), disabled_location(0), extra_p_count(0), tag_extra_p_count(0) {}
}; };
struct field_effect { struct field_effect {
using effect_container = std::multimap<uint32, effect*>;
using effect_indexer = std::unordered_map<effect*, effect_container::iterator>;
using oath_effects = std::unordered_map<effect*, effect*>; using oath_effects = std::unordered_map<effect*, effect*>;
using effect_collection = std::unordered_set<effect*>;
using gain_effects = std::unordered_map<card*, effect*>; using gain_effects = std::unordered_map<card*, effect*>;
using grant_effect_container = std::unordered_map<effect*, gain_effects>; using grant_effect_container = std::unordered_map<effect*, gain_effects>;
...@@ -130,70 +123,70 @@ struct field_effect { ...@@ -130,70 +123,70 @@ struct field_effect {
grant_effect_container grant_effect; grant_effect_container grant_effect;
}; };
struct field_info { struct field_info {
int32 field_id; uint64_t card_id{ 1 };
int16 copy_id; int32_t field_id{ 1 };
int16 turn_id; uint16_t copy_id{ 1 };
int16 turn_id_by_player[2]; uint16_t turn_id{};
int16 card_id; uint16_t turn_id_by_player[2]{};
uint16 phase; uint16_t phase{};
uint8 turn_player; uint8_t turn_player{};
uint8 priorities[2]; uint8_t priorities[2]{};
uint8 can_shuffle; uint8_t can_shuffle{ TRUE };
field_info()
: field_id(0), copy_id(0), turn_id(0), turn_id_by_player{ 0 }, card_id(0), phase(0), turn_player(0), priorities{ 0 }, can_shuffle(TRUE) {}
}; };
struct lpcost { struct lpcost {
int32 count; int32_t count{};
int32 amount; int32_t amount{};
int32 lpstack[8]; int32_t lpstack[8]{};
lpcost()
: count(0), amount(0), lpstack{ 0 } {}
}; };
struct processor_unit { struct processor_unit {
uint16 type; uint16_t type{ 0 };
uint16 step; uint16_t step{ 0 };
effect* peffect; effect* peffect{ nullptr };
group* ptarget; group* ptarget{ nullptr };
int32 arg1; uint32_t arg1{ 0 };
int32 arg2; uint32_t arg2{ 0 };
int32 arg3; uint32_t arg3{ 0 };
int32 arg4; uint32_t arg4{ 0 };
void* ptr1; int32_t value1{ 0 };
void* ptr2; int32_t value2{ 0 };
int32_t value3{ 0 };
processor_unit() int32_t value4{ 0 };
: type(0), step(0), peffect(nullptr), ptarget(nullptr), arg1(0), arg2(0), arg3(0), arg4(0), ptr1(nullptr), ptr2(nullptr) {} void* ptr1{ nullptr };
void* ptr2{ nullptr };
void* ptr3{ nullptr };
void* ptr4{ nullptr };
}; };
constexpr int SIZE_SVALUE = SIZE_RETURN_VALUE / 2;
constexpr int SIZE_IVALUE = SIZE_RETURN_VALUE / 4;
constexpr int SIZE_LVALUE = SIZE_RETURN_VALUE / 8;
union return_value { union return_value {
int8 bvalue[64]; uint8_t bvalue[SIZE_RETURN_VALUE];
int16 svalue[32]; uint16_t svalue[SIZE_SVALUE];
int32 ivalue[16]; int32_t ivalue[SIZE_IVALUE];
int64 lvalue[8]; int64_t lvalue[SIZE_LVALUE];
}; };
using option_vector = std::vector<uint32_t>;
using card_list = std::list<card*>;
using event_list = std::list<tevent>;
using chain_list = std::list<chain>;
using instant_f_list = std::map<effect*, chain>;
using chain_array = std::vector<chain>;
using processor_list = std::list<processor_unit>;
using delayed_effect_collection = std::set<std::pair<effect*, tevent>>;
using activity_map = std::unordered_map<int32_t, std::pair<int32_t, uint32_t>>; // (counter_id, (counter_filter, count[1]|count[0]))
struct processor { struct processor {
using effect_vector = std::vector<effect*>;
using card_vector = std::vector<card*>;
using option_vector = std::vector<uint32>;
using card_list = std::list<card*>;
using event_list = std::list<tevent>;
using chain_list = std::list<chain>;
using instant_f_list = std::map<effect*, chain>;
using chain_array = std::vector<chain>;
using processor_list = std::list<processor_unit>;
using card_set = std::set<card*, card_sort>;
using delayed_effect_collection = std::set<std::pair<effect*, tevent>>;
struct chain_limit_t { struct chain_limit_t {
chain_limit_t(int32 f, int32 p): function(f), player(p) {} chain_limit_t(int32_t f, int32_t p): function(f), player(p) {}
int32 function; int32_t function{ 0 };
int32 player; int32_t player{ PLAYER_NONE };
}; };
using chain_limit_list = std::vector<chain_limit_t>; using chain_limit_list = std::vector<chain_limit_t>;
processor_list units; processor_list units;
processor_list subunits; processor_list subunits;
processor_unit reserved; processor_unit damage_step_reserved;
processor_unit summon_reserved;
card_vector select_cards; card_vector select_cards;
card_vector unselect_cards; card_vector unselect_cards;
card_vector summonable_cards; card_vector summonable_cards;
...@@ -252,6 +245,7 @@ struct processor { ...@@ -252,6 +245,7 @@ struct processor {
card_set operated_set; card_set operated_set;
card_set discarded_set; card_set discarded_set;
card_set destroy_canceled; card_set destroy_canceled;
card_set indestructable_count_set;
card_set delayed_enable_set; card_set delayed_enable_set;
card_set set_group_pre_set; card_set set_group_pre_set;
card_set set_group_set; card_set set_group_set;
...@@ -259,393 +253,394 @@ struct processor { ...@@ -259,393 +253,394 @@ struct processor {
effect_set_v extra_mzone_effects; effect_set_v extra_mzone_effects;
effect_set_v extra_szone_effects; effect_set_v extra_szone_effects;
std::set<effect*> reseted_effects; std::set<effect*> reseted_effects;
std::unordered_map<card*, uint32> readjust_map; std::unordered_map<card*, uint32_t> readjust_map;
std::unordered_set<card*> unique_cards[2]; std::unordered_set<card*> unique_cards[2];
std::unordered_map<uint32, uint32> effect_count_code; std::unordered_map<uint32_t, int32_t> effect_count_code[3];
std::unordered_map<uint32, uint32> effect_count_code_duel; std::unordered_map<uint32_t, int32_t> effect_count_code_duel[3];
std::unordered_map<uint32, uint32> spsummon_once_map[2]; std::unordered_map<uint32_t, int32_t> effect_count_code_chain[3];
std::multimap<int32, card*, std::greater<int32>> xmaterial_lst; std::unordered_map<uint32_t, uint32_t> spsummon_once_map[2];
std::multimap<int32_t, card*, std::greater<int32_t>> xmaterial_lst;
int32 temp_var[4];
uint32 global_flag; int32_t temp_var[4]{};
uint16 pre_field[2]; uint32_t global_flag{ 0 };
std::set<uint16> opp_mzone; uint16_t pre_field[2]{};
std::set<uint16_t> opp_mzone;
chain_limit_list chain_limit; chain_limit_list chain_limit;
chain_limit_list chain_limit_p; chain_limit_list chain_limit_p;
uint8 chain_solving; uint8_t chain_solving{ FALSE };
uint8 conti_solving; uint8_t conti_solving{ FALSE };
uint8 win_player; uint8_t win_player{ 5 };
uint8 win_reason; uint8_t win_reason{ 0 };
uint8 re_adjust; uint8_t re_adjust{ FALSE };
effect* reason_effect; effect* reason_effect{ nullptr };
uint8 reason_player; uint8_t reason_player{ PLAYER_NONE };
card* summoning_card; card* summoning_card{ nullptr };
uint8 summon_depth; uint8_t summon_depth{ 0 };
uint8 summon_cancelable; uint8_t summon_cancelable{ FALSE };
card* attacker; card* attacker{ nullptr };
card* attack_target; card* attack_target{ nullptr };
uint32 limit_extra_summon_zone; uint8_t attacker_player{ PLAYER_NONE };
uint32 limit_extra_summon_releasable; uint8_t attack_target_player{ PLAYER_NONE };
card* limit_tuner; uint32_t limit_extra_summon_zone{ 0 };
group* limit_syn; uint32_t limit_extra_summon_releasable{ 0 };
int32 limit_syn_minc; card* limit_tuner{ nullptr };
int32 limit_syn_maxc; group* limit_syn{ nullptr };
group* limit_xyz; int32_t limit_syn_minc{ 0 };
int32 limit_xyz_minc; int32_t limit_syn_maxc{ 0 };
int32 limit_xyz_maxc; group* limit_xyz{ nullptr };
group* limit_link; int32_t limit_xyz_minc{ 0 };
card* limit_link_card; int32_t limit_xyz_maxc{ 0 };
int32 limit_link_minc; group* limit_link{ nullptr };
int32 limit_link_maxc; card* limit_link_card{ nullptr };
uint8 not_material; int32_t limit_link_minc{ 0 };
uint8 attack_cancelable; int32_t limit_link_maxc{ 0 };
uint8 attack_rollback; uint8_t not_material{ FALSE };
uint8 effect_damage_step; uint8_t attack_cancelable{ FALSE };
int32 battle_damage[2]; uint8_t attack_rollback{ FALSE };
int32 summon_count[2]; uint8_t effect_damage_step{ 0 };
uint8 extra_summon[2]; int32_t battle_damage[2]{};
int32 spe_effect[2]; int32_t summon_count[2]{};
int32 duel_options; uint8_t extra_summon[2]{};
int32 duel_rule; //current rule: 5, Master Rule 2020 int32_t spe_effect[2]{};
uint32 copy_reset; int32_t last_select_hint[2]{ 0 };
uint8 copy_reset_count; uint32_t duel_options{ 0 };
uint32 last_control_changed_id; int32_t duel_rule{ CURRENT_RULE };
uint32 set_group_used_zones; uint32_t copy_reset{ 0 };
uint8 set_group_seq[7]; int32_t copy_reset_count{ 0 };
uint8 dice_result[5]; uint32_t last_control_changed_id{ 0 };
uint8 coin_result[5]; uint32_t set_group_used_zones{ 0 };
uint8 to_bp; uint8_t set_group_seq[7]{};
uint8 to_m2; uint8_t dice_result[5]{};
uint8 to_ep; uint8_t coin_result[MAX_COIN_COUNT]{};
uint8 skip_m2; int32_t coin_count{ 0 };
uint8 chain_attack; bool is_target_ready{ false };
uint32 chain_attacker_id; bool is_gemini_summoning{ false };
card* chain_attack_target; bool is_summon_negated{ false };
uint8 attack_player;
uint8 selfdes_disabled; uint8_t to_bp{ FALSE };
uint8 overdraw[2]; uint8_t to_m2{ FALSE };
int32 check_level; uint8_t to_ep{ FALSE };
uint8 shuffle_check_disabled; uint8_t skip_m2{ FALSE };
uint8 shuffle_hand_check[2]; uint8_t chain_attack{ FALSE };
uint8 shuffle_deck_check[2]; uint32_t chain_attacker_id{ 0 };
uint8 deck_reversed; card* chain_attack_target{ nullptr };
uint8 remove_brainwashing; uint8_t attack_player{ PLAYER_NONE };
uint8 flip_delayed; uint8_t selfdes_disabled{ FALSE };
uint8 damage_calculated; uint8_t overdraw[2]{};
uint8 hand_adjusted; int32_t check_level{ 0 };
uint8 summon_state_count[2]; uint8_t shuffle_check_disabled{ FALSE };
uint8 normalsummon_state_count[2]; uint8_t shuffle_hand_check[2]{};
uint8 flipsummon_state_count[2]; uint8_t shuffle_deck_check[2]{};
uint8 spsummon_state_count[2]; uint8_t deck_reversed{ FALSE };
uint8 attack_state_count[2]; uint8_t remove_brainwashing{ FALSE };
uint8 battle_phase_count[2]; uint8_t flip_delayed{ FALSE };
uint8 battled_count[2]; uint8_t damage_calculated{ FALSE };
uint8 phase_action; uint8_t hand_adjusted{ FALSE };
uint32 hint_timing[2]; uint8_t summon_state_count[2]{};
uint8 current_player; uint8_t normalsummon_state_count[2]{};
uint8 conti_player; uint8_t flipsummon_state_count[2]{};
std::unordered_map<uint32, std::pair<uint32, uint32>> summon_counter; uint8_t spsummon_state_count[2]{};
std::unordered_map<uint32, std::pair<uint32, uint32>> normalsummon_counter; uint8_t attack_state_count[2]{};
std::unordered_map<uint32, std::pair<uint32, uint32>> spsummon_counter; uint8_t battle_phase_count[2]{};
std::unordered_map<uint32, std::pair<uint32, uint32>> flipsummon_counter; uint8_t battled_count[2]{};
std::unordered_map<uint32, std::pair<uint32, uint32>> attack_counter; uint8_t phase_action{ FALSE };
std::unordered_map<uint32, std::pair<uint32, uint32>> chain_counter; uint32_t hint_timing[2]{};
uint8_t current_player{ PLAYER_NONE };
uint8_t conti_player{ PLAYER_NONE };
uint8_t select_deck_sequence_revealed{ FALSE };
uint8_t selecting_player{ 0 };
activity_map summon_counter;
activity_map normalsummon_counter;
activity_map spsummon_counter;
activity_map flipsummon_counter;
activity_map attack_counter;
activity_map chain_counter;
processor_list recover_damage_reserve; processor_list recover_damage_reserve;
effect_vector dec_count_reserve; effect_vector dec_count_reserve;
processor()
: temp_var{ 0 }, global_flag(0), pre_field{ 0 }, chain_solving(FALSE), conti_solving(FALSE), win_player(5), win_reason(0), re_adjust(FALSE), reason_effect(nullptr), reason_player(PLAYER_NONE),
summoning_card(nullptr), summon_depth(0), summon_cancelable(FALSE), attacker(nullptr), attack_target(nullptr), limit_extra_summon_zone(0), limit_extra_summon_releasable(0),
limit_tuner(nullptr), limit_syn(nullptr), limit_syn_minc(0), limit_syn_maxc(0), limit_xyz(nullptr), limit_xyz_minc(0), limit_xyz_maxc(0), limit_link(nullptr), limit_link_card(nullptr),
limit_link_minc(0), limit_link_maxc(0), not_material(FALSE), attack_cancelable(FALSE), attack_rollback(FALSE), effect_damage_step(0), battle_damage{ 0 }, summon_count{ 0 }, extra_summon{ FALSE },
spe_effect{ 0 }, duel_options(0), duel_rule(0), copy_reset(0), copy_reset_count(0), last_control_changed_id(0), set_group_used_zones(0), set_group_seq{ 0 }, dice_result{ 0 }, coin_result{ 0 },
to_bp(FALSE), to_m2(FALSE), to_ep(FALSE), skip_m2(FALSE), chain_attack(FALSE), chain_attacker_id(0), chain_attack_target(nullptr), attack_player(PLAYER_NONE), selfdes_disabled(FALSE),
overdraw{ FALSE }, check_level(0), shuffle_check_disabled(FALSE), shuffle_hand_check{ FALSE }, shuffle_deck_check{ FALSE }, deck_reversed(FALSE), remove_brainwashing(FALSE), flip_delayed(FALSE),
damage_calculated(FALSE), hand_adjusted(FALSE), summon_state_count{ 0 }, normalsummon_state_count{ 0 }, flipsummon_state_count{ 0 }, spsummon_state_count{ 0 }, attack_state_count{ 0 },
battle_phase_count{ 0 }, battled_count{ 0 }, phase_action(FALSE), hint_timing{ 0 }, current_player(PLAYER_NONE), conti_player(PLAYER_NONE) {}
}; };
class field { class field {
public: public:
using effect_container = std::multimap<uint32, effect*>; duel* pduel{};
using card_set = std::set<card*, card_sort>;
using effect_vector = std::vector<effect*>;
using card_vector = std::vector<card*>;
using card_list = std::list<card*>;
using event_list = std::list<tevent>;
using chain_list = std::list<chain>;
using instant_f_list = std::map<effect*, chain>;
using chain_array = std::vector<chain>;
using processor_list = std::list<processor_unit>;
duel* pduel;
player_info player[2]; player_info player[2];
card* temp_card; card* temp_card{};
field_info infos; field_info infos;
//lpcost cost[2]; //lpcost cost[2];
field_effect effects; field_effect effects;
processor core; processor core;
return_value returns; return_value returns{};
tevent nil_event; tevent nil_event;
static int32 field_used_count[32]; static int32_t field_used_count[32];
explicit field(duel* pduel); explicit field(duel* pd);
~field() = default; ~field() = default;
void reload_field_info(); void reload_field_info();
void add_card(uint8 playerid, card* pcard, uint8 location, uint8 sequence, uint8 pzone = FALSE); void add_card(uint8_t playerid, card* pcard, uint8_t location, uint8_t sequence, uint8_t pzone = FALSE);
void remove_card(card* pcard); void remove_card(card* pcard);
void move_card(uint8 playerid, card* pcard, uint8 location, uint8 sequence, uint8 pzone = FALSE); void move_card(uint8_t playerid, card* pcard, uint8_t location, uint8_t sequence, uint8_t pzone = FALSE);
void swap_card(card* pcard1, card* pcard2, uint8 new_sequence1, uint8 new_sequence2); void swap_card(card* pcard1, card* pcard2, uint8_t new_sequence1, uint8_t new_sequence2);
void swap_card(card* pcard1, card* pcard2); void swap_card(card* pcard1, card* pcard2);
void set_control(card* pcard, uint8 playerid, uint16 reset_phase, uint8 reset_count); void set_control(card* pcard, uint8_t playerid, uint16_t reset_phase, uint8_t reset_count);
card* get_field_card(uint32 playerid, uint32 location, uint32 sequence);
int32 is_location_useable(uint32 playerid, uint32 location, uint32 sequence); int32_t get_pzone_sequence(uint8_t pseq) const;
int32 get_useable_count(card* pcard, uint8 playerid, uint8 location, uint8 uplayer, uint32 reason, uint32 zone = 0xff, uint32* list = 0); card* get_field_card(uint8_t playerid, uint32_t general_location, uint8_t sequence) const;
int32 get_useable_count_fromex(card* pcard, uint8 playerid, uint8 uplayer, uint32 zone = 0xff, uint32* list = 0); int32_t is_location_useable(uint8_t playerid, uint32_t general_location, uint8_t sequence) const;
int32 get_spsummonable_count(card* pcard, uint8 playerid, uint32 zone = 0xff, uint32* list = 0); int32_t get_useable_count(card* pcard, uint8_t playerid, uint8_t location, uint8_t uplayer, uint32_t reason, uint32_t zone = 0xff, uint32_t* list = nullptr);
int32 get_spsummonable_count_fromex(card* pcard, uint8 playerid, uint8 uplayer, uint32 zone = 0xff, uint32* list = 0); int32_t get_useable_count_fromex(card* pcard, uint8_t playerid, uint8_t uplayer, uint32_t zone = 0xff, uint32_t* list = nullptr);
int32 get_useable_count_other(card* pcard, uint8 playerid, uint8 location, uint8 uplayer, uint32 reason, uint32 zone = 0xff, uint32* list = 0); int32_t get_spsummonable_count(card* pcard, uint8_t playerid, uint32_t zone = 0xff, uint32_t* list = nullptr);
int32 get_tofield_count(card* pcard, uint8 playerid, uint8 location, uint32 uplayer, uint32 reason, uint32 zone = 0xff, uint32* list = 0); int32_t get_spsummonable_count_fromex(card* pcard, uint8_t playerid, uint8_t uplayer, uint32_t zone = 0xff, uint32_t* list = nullptr);
int32 get_useable_count_fromex_rule4(card* pcard, uint8 playerid, uint8 uplayer, uint32 zone = 0xff, uint32* list = 0); int32_t get_useable_count_other(card* pcard, uint8_t playerid, uint8_t location, uint8_t uplayer, uint32_t reason, uint32_t zone = 0xff, uint32_t* list = nullptr);
int32 get_spsummonable_count_fromex_rule4(card* pcard, uint8 playerid, uint8 uplayer, uint32 zone = 0xff, uint32* list = 0); int32_t get_tofield_count(card* pcard, uint8_t playerid, uint8_t location, uint32_t uplayer, uint32_t reason, uint32_t zone = 0xff, uint32_t* list = nullptr);
int32 get_mzone_limit(uint8 playerid, uint8 uplayer, uint32 reason); int32_t get_useable_count_fromex_rule4(card* pcard, uint8_t playerid, uint8_t uplayer, uint32_t zone = 0xff, uint32_t* list = nullptr);
int32 get_szone_limit(uint8 playerid, uint8 uplayer, uint32 reason); int32_t get_spsummonable_count_fromex_rule4(card* pcard, uint8_t playerid, uint8_t uplayer, uint32_t zone = 0xff, uint32_t* list = nullptr);
uint32 get_linked_zone(int32 playerid); int32_t get_mzone_limit(uint8_t playerid, uint8_t uplayer, uint32_t reason);
uint32 get_rule_zone_fromex(int32 playerid, card* pcard); int32_t get_szone_limit(uint8_t playerid, uint8_t uplayer, uint32_t reason);
void filter_must_use_mzone(uint8 playerid, uint8 uplayer, uint32 reason, card* pcard, uint32* flag); uint32_t get_linked_zone(int32_t playerid);
void get_linked_cards(uint8 self, uint8 s, uint8 o, card_set* cset); uint32_t get_rule_zone_fromex(int32_t playerid, card* pcard);
int32 check_extra_link(int32 playerid); void filter_must_use_mzone(uint8_t playerid, uint8_t uplayer, uint32_t reason, card* pcard, uint32_t* flag);
int32 check_extra_link(int32 playerid, card* pcard, int32 sequence); void get_linked_cards(uint8_t self, uint8_t s, uint8_t o, card_set* cset);
void get_cards_in_zone(card_set* cset, uint32 zone, int32 playerid, int32 location); int32_t check_extra_link(int32_t playerid);
void shuffle(uint8 playerid, uint8 location); int32_t check_extra_link(int32_t playerid, card* pcard, int32_t sequence);
void reset_sequence(uint8 playerid, uint8 location); void get_cards_in_zone(card_set* cset, uint32_t zone, int32_t playerid, int32_t location);
void swap_deck_and_grave(uint8 playerid); void shuffle(uint8_t playerid, uint8_t location);
void reverse_deck(uint8 playerid); void reset_sequence(uint8_t playerid, uint8_t location);
void tag_swap(uint8 playerid); void swap_deck_and_grave(uint8_t playerid);
void reverse_deck(uint8_t playerid);
void add_effect(effect* peffect, uint8 owner_player = 2); void refresh_player_info(uint8_t playerid);
void tag_swap(uint8_t playerid);
void add_effect(effect* peffect, uint8_t owner_player = PLAYER_NONE);
void remove_effect(effect* peffect); void remove_effect(effect* peffect);
void remove_oath_effect(effect* reason_effect); void remove_oath_effect(effect* reason_effect);
void release_oath_relation(effect* reason_effect); void release_oath_relation(effect* reason_effect);
void reset_phase(uint32 phase); void reset_phase(uint32_t phase);
void reset_chain(); void reset_chain();
void add_effect_code(uint32 code, uint32 playerid); void add_effect_code(uint32_t code, int32_t playerid);
uint32 get_effect_code(uint32 code, uint32 playerid); int32_t get_effect_code(uint32_t code, int32_t playerid);
void dec_effect_code(uint32 code, uint32 playerid); void dec_effect_code(uint32_t code, int32_t playerid);
void filter_field_effect(uint32 code, effect_set* eset, uint8 sort = TRUE); void filter_field_effect(uint32_t code, effect_set* eset, uint8_t sort = TRUE);
void filter_affected_cards(effect* peffect, card_set* cset); void filter_affected_cards(effect* peffect, card_set* cset);
void filter_inrange_cards(effect* peffect, card_set* cset); void filter_inrange_cards(effect* peffect, card_set* cset);
void filter_player_effect(uint8 playerid, uint32 code, effect_set* eset, uint8 sort = TRUE); void filter_player_effect(uint8_t playerid, uint32_t code, effect_set* eset, uint8_t sort = TRUE);
int32 filter_matching_card(int32 findex, uint8 self, uint32 location1, uint32 location2, group* pgroup, card* pexception, group* pexgroup, uint32 extraargs, card** pret = 0, int32 fcount = 0, int32 is_target = FALSE); int32_t filter_matching_card(lua_State* L, int32_t findex, uint8_t self, uint32_t location1, uint32_t location2, group* pgroup, card* pexception, group* pexgroup, uint32_t extraargs, card** pret = nullptr, int32_t fcount = 0, int32_t is_target = FALSE);
int32 filter_field_card(uint8 self, uint32 location, uint32 location2, group* pgroup); int32_t filter_field_card(uint8_t self, uint32_t location, uint32_t location2, group* pgroup);
effect* is_player_affected_by_effect(uint8 playerid, uint32 code); effect* is_player_affected_by_effect(uint8_t playerid, uint32_t code);
int32 get_release_list(uint8 playerid, card_set* release_list, card_set* ex_list, card_set* ex_list_oneof, int32 use_con, int32 use_hand, int32 fun, int32 exarg, card* exc, group* exg); int32_t get_release_list(lua_State* L, uint8_t playerid, card_set* release_list, card_set* ex_list, card_set* ex_list_oneof, int32_t use_con, int32_t use_hand, int32_t fun, int32_t exarg, card* exc, group* exg, uint32_t reason);
int32 check_release_list(uint8 playerid, int32 count, int32 use_con, int32 use_hand, int32 fun, int32 exarg, card* exc, group* exg); int32_t check_release_list(lua_State* L, uint8_t playerid, int32_t count, int32_t use_con, int32_t use_hand, int32_t fun, int32_t exarg, card* exc, group* exg, uint32_t reason);
int32 get_summon_release_list(card* target, card_set* release_list, card_set* ex_list, card_set* ex_list_oneof, group* mg = NULL, uint32 ex = 0, uint32 releasable = 0xff00ff, uint32 pos = 0x1); int32_t get_summon_release_list(card* target, card_set* release_list, card_set* ex_list, card_set* ex_list_oneof, group* mg = nullptr, uint32_t ex = 0, uint32_t releasable = 0xff00ff, uint32_t pos = 0x1);
int32 get_summon_count_limit(uint8 playerid); int32_t get_summon_count_limit(uint8_t playerid);
int32 get_draw_count(uint8 playerid); int32_t get_draw_count(uint8_t playerid);
void get_ritual_material(uint8 playerid, effect* peffect, card_set* material, uint8 no_level = FALSE); void get_ritual_material(uint8_t playerid, effect* peffect, card_set* material, uint8_t no_level = FALSE);
void get_fusion_material(uint8 playerid, card_set* material_all, card_set* material_base, uint32 location); void get_fusion_material(uint8_t playerid, card_set* material_all, card_set* material_base, uint32_t location);
void ritual_release(card_set* material); void ritual_release(const card_set& material);
void get_xyz_material(card* scard, int32 findex, uint32 lv, int32 maxc, group* mg); void get_xyz_material(lua_State* L, card* scard, int32_t findex, uint32_t lv, int32_t maxc, group* mg);
void get_overlay_group(uint8 self, uint8 s, uint8 o, card_set* pset); void get_overlay_group(uint8_t self, uint8_t s, uint8_t o, card_set* pset);
int32 get_overlay_count(uint8 self, uint8 s, uint8 o); int32_t get_overlay_count(uint8_t self, uint8_t s, uint8_t o);
void update_disable_check_list(effect* peffect); void update_disable_check_list(effect* peffect);
void add_to_disable_check_list(card* pcard); void add_to_disable_check_list(card* pcard);
void adjust_disable_check_list(); void adjust_disable_check_list();
void adjust_self_destroy_set(); void adjust_self_destroy_set();
void erase_grant_effect(effect* peffect); void erase_grant_effect(effect* peffect);
int32 adjust_grant_effect(); int32_t adjust_grant_effect();
void add_unique_card(card* pcard); void add_unique_card(card* pcard);
void remove_unique_card(card* pcard); void remove_unique_card(card* pcard);
effect* check_unique_onfield(card* pcard, uint8 controler, uint8 location, card* icard = 0); effect* check_unique_onfield(card* pcard, uint8_t controler, uint8_t location, card* icard = nullptr);
int32 check_spsummon_once(card* pcard, uint8 playerid); int32_t check_spsummon_once(card* pcard, uint8_t playerid);
void check_card_counter(card* pcard, int32 counter_type, int32 playerid); void check_card_counter(card* pcard, int32_t counter_type, int32_t playerid);
void check_card_counter(group* pgroup, int32 counter_type, int32 playerid); void check_card_counter(group* pgroup, int32_t counter_type, int32_t playerid);
void check_chain_counter(effect* peffect, int32 playerid, int32 chainid, bool cancel = false); void check_chain_counter(effect* peffect, int32_t playerid, int32_t chainid, bool cancel = false);
void set_spsummon_counter(uint8 playerid); void set_spsummon_counter(uint8_t playerid);
int32 check_spsummon_counter(uint8 playerid, uint8 ct = 1); int32_t check_spsummon_counter(uint8_t playerid, uint8_t ct = 1);
bool is_select_hide_deck_sequence(uint8_t playerid);
int32 check_lp_cost(uint8 playerid, uint32 cost, uint32 must_pay);
int32_t check_lp_cost(uint8_t playerid, int32_t cost, uint32_t must_pay);
void save_lp_cost() {} void save_lp_cost() {}
void restore_lp_cost() {} void restore_lp_cost() {}
int32 pay_lp_cost(uint32 step, uint8 playerid, uint32 cost, uint32 must_pay); int32_t pay_lp_cost(uint32_t step, uint8_t playerid, uint32_t cost, uint32_t must_pay);
uint32 get_field_counter(uint8 self, uint8 s, uint8 o, uint16 countertype); uint32_t get_field_counter(uint8_t self, uint8_t s, uint8_t o, uint16_t countertype);
int32 effect_replace_check(uint32 code, const tevent& e); int32_t effect_replace_check(uint32_t code, const tevent& e);
int32 get_attack_target(card* pcard, card_vector* v, uint8 chain_attack = FALSE, bool select_target = true); int32_t get_attack_target(card* pcard, card_vector* v, uint8_t chain_attack = FALSE, bool select_target = true);
bool confirm_attack_target(); bool confirm_attack_target();
void attack_all_target_check(); void attack_all_target_check();
int32 check_synchro_material(card* pcard, int32 findex1, int32 findex2, int32 min, int32 max, card* smat, group* mg); int32_t get_must_material_list(uint8_t playerid, uint32_t limit, card_set* must_list);
int32 check_tuner_material(card* pcard, card* tuner, int32 findex1, int32 findex2, int32 min, int32 max, card* smat, group* mg); int32_t check_must_material(group* mg, uint8_t playerid, uint32_t limit);
int32 check_other_synchro_material(const card_vector& nsyn, int32 lv, int32 min, int32 max, int32 mcount); void get_synchro_material(uint8_t playerid, card_set* material, effect* tuner_limit = nullptr);
int32 check_tribute(card* pcard, int32 min, int32 max, group* mg, uint8 toplayer, uint32 zone = 0x1f, uint32 releasable = 0xff00ff, uint32 pos = 0x1);
static int32 check_with_sum_limit(const card_vector& mats, int32 acc, int32 index, int32 count, int32 min, int32 max, int32 opmin); //check material
static int32 check_with_sum_limit_m(const card_vector& mats, int32 acc, int32 index, int32 min, int32 max, int32 opmin, int32 must_count); int32_t check_synchro_material(lua_State* L, card* pcard, int32_t findex1, int32_t findex2, int32_t min, int32_t max, card* smat, group* mg);
static int32 check_with_sum_greater_limit(const card_vector& mats, int32 acc, int32 index, int32 opmin); int32_t check_tuner_material(lua_State* L, card* pcard, card* tuner, int32_t findex1, int32_t findex2, int32_t min, int32_t max, card* smat, group* mg);
static int32 check_with_sum_greater_limit_m(const card_vector& mats, int32 acc, int32 index, int32 opmin, int32 must_count); int32_t check_other_synchro_material(const card_vector& nsyn, int32_t lv, int32_t min, int32_t max, int32_t mcount);
int32 check_xyz_material(card* pcard, int32 findex, int32 lv, int32 min, int32 max, group* mg); int32_t check_tribute(card* pcard, int32_t min, int32_t max, group* mg, uint8_t toplayer, uint32_t zone = 0x1f, uint32_t releasable = 0xff00ff, uint32_t pos = 0x1);
static int32_t check_with_sum_limit(const card_vector& mats, int32_t acc, int32_t index, int32_t count, int32_t min, int32_t max, int32_t opmin);
int32 is_player_can_draw(uint8 playerid); static int32_t check_with_sum_limit_m(const card_vector& mats, int32_t acc, int32_t index, int32_t min, int32_t max, int32_t opmin, int32_t must_count);
int32 is_player_can_discard_deck(uint8 playerid, int32 count); static int32_t check_with_sum_greater_limit(const card_vector& mats, int32_t acc, int32_t index, int32_t opmin);
int32 is_player_can_discard_deck_as_cost(uint8 playerid, int32 count); static int32_t check_with_sum_greater_limit_m(const card_vector& mats, int32_t acc, int32_t index, int32_t opmin, int32_t must_count);
int32 is_player_can_discard_hand(uint8 playerid, card* pcard, effect* reason_effect, uint32 reason); int32_t check_xyz_material(lua_State* L, card* pcard, int32_t findex, int32_t lv, int32_t min, int32_t max, group* mg);
int32 is_player_can_action(uint8 playerid, uint32 actionlimit);
int32 is_player_can_summon(uint32 sumtype, uint8 playerid, card* pcard, uint8 toplayer); int32_t is_player_can_draw(uint8_t playerid);
int32 is_player_can_mset(uint32 sumtype, uint8 playerid, card* pcard, uint8 toplayer); int32_t is_player_can_discard_deck(uint8_t playerid, int32_t count);
int32 is_player_can_sset(uint8 playerid, card* pcard); int32_t is_player_can_discard_deck_as_cost(uint8_t playerid, int32_t count);
int32 is_player_can_spsummon(uint8 playerid); int32_t is_player_can_discard_hand(uint8_t playerid, card* pcard, effect* reason_effect, uint32_t reason);
int32 is_player_can_spsummon(effect* reason_effect, uint32 sumtype, uint8 sumpos, uint8 playerid, uint8 toplayer, card* pcard); int32_t is_player_can_action(uint8_t playerid, uint32_t actionlimit);
int32 is_player_can_flipsummon(uint8 playerid, card* pcard); int32_t is_player_can_summon(uint32_t sumtype, uint8_t playerid, card* pcard, uint8_t toplayer);
int32 is_player_can_spsummon_monster(uint8 playerid, uint8 toplayer, uint8 sumpos, uint32 sumtype, card_data* pdata); int32_t is_player_can_mset(uint32_t sumtype, uint8_t playerid, card* pcard, uint8_t toplayer);
int32 is_player_can_spsummon_count(uint8 playerid, uint32 count); int32_t is_player_can_sset(uint8_t playerid, card* pcard);
int32 is_player_can_release(uint8 playerid, card* pcard); int32_t is_player_can_spsummon(uint8_t playerid);
int32 is_player_can_place_counter(uint8 playerid, card* pcard, uint16 countertype, uint16 count); int32_t is_player_can_spsummon(effect* reason_effect, uint32_t sumtype, uint8_t sumpos, uint8_t playerid, uint8_t toplayer, card* pcard);
int32 is_player_can_remove_counter(uint8 playerid, card* pcard, uint8 s, uint8 o, uint16 countertype, uint16 count, uint32 reason); int32_t is_player_can_flipsummon(uint8_t playerid, card* pcard);
int32 is_player_can_remove_overlay_card(uint8 playerid, card* pcard, uint8 s, uint8 o, uint16 count, uint32 reason); int32_t is_player_can_spsummon_monster(uint8_t playerid, uint8_t toplayer, uint8_t sumpos, uint32_t sumtype, card_data* pdata);
int32 is_player_can_send_to_grave(uint8 playerid, card* pcard); int32_t is_player_can_spsummon_count(uint8_t playerid, uint32_t count);
int32 is_player_can_send_to_hand(uint8 playerid, card* pcard); int32_t is_player_can_release(uint8_t playerid, card* pcard, uint32_t reason);
int32 is_player_can_send_to_deck(uint8 playerid, card* pcard); int32_t is_player_can_place_counter(uint8_t playerid, card* pcard, uint16_t countertype, uint16_t count);
int32 is_player_can_remove(uint8 playerid, card* pcard, uint32 reason); int32_t is_player_can_remove_counter(uint8_t playerid, card* pcard, uint8_t s, uint8_t o, uint16_t countertype, uint16_t count, uint32_t reason);
int32 is_chain_negatable(uint8 chaincount); int32_t is_player_can_remove_overlay_card(uint8_t playerid, card* pcard, uint8_t s, uint8_t o, uint16_t count, uint32_t reason);
int32 is_chain_disablable(uint8 chaincount); int32_t is_player_can_send_to_grave(uint8_t playerid, card* pcard);
int32 is_chain_disabled(uint8 chaincount); int32_t is_player_can_send_to_hand(uint8_t playerid, card* pcard);
int32 check_chain_target(uint8 chaincount, card* pcard); int32_t is_player_can_send_to_deck(uint8_t playerid, card* pcard);
chain* get_chain(uint32 chaincount); int32_t is_player_can_remove(uint8_t playerid, card* pcard, uint32_t reason);
int32 get_cteffect(effect* peffect, int32 playerid, int32 store); int32_t is_chain_negatable(uint8_t chaincount);
int32 get_cteffect_evt(effect* feffect, int32 playerid, const tevent& e, int32 store); int32_t is_chain_disablable(uint8_t chaincount);
int32 check_cteffect_hint(effect* peffect, uint8 playerid); int32_t is_chain_disabled(uint8_t chaincount);
int32 check_nonpublic_trigger(chain& ch); int32_t check_chain_target(uint8_t chaincount, card* pcard);
int32 check_trigger_effect(const chain& ch) const; chain* get_chain(uint32_t chaincount);
int32 check_spself_from_hand_trigger(const chain& ch) const; int32_t get_cteffect(effect* peffect, int32_t playerid, int32_t store);
int32 is_able_to_enter_bp(); int32_t get_cteffect_evt(effect* feffect, int32_t playerid, const tevent& e, int32_t store);
int32_t check_cteffect_hint(effect* peffect, uint8_t playerid);
void add_process(uint16 type, uint16 step, effect* peffect, group* target, int32 arg1, int32 arg2, int32 arg3 = 0, int32 arg4 = 0, void* ptr1 = nullptr, void* ptr2 = nullptr); int32_t check_nonpublic_trigger(chain& ch);
int32 process(); int32_t check_trigger_effect(const chain& ch) const;
int32 execute_cost(uint16 step, effect* peffect, uint8 triggering_player); int32_t check_spself_from_hand_trigger(const chain& ch) const;
int32 execute_operation(uint16 step, effect* peffect, uint8 triggering_player); int32_t is_able_to_enter_bp();
int32 execute_target(uint16 step, effect* peffect, uint8 triggering_player);
void raise_event(card* event_card, uint32 event_code, effect* reason_effect, uint32 reason, uint8 reason_player, uint8 event_player, uint32 event_value); void add_process(uint16_t type, uint16_t step, effect* peffect, group* target, int32_t arg1, int32_t arg2, int32_t arg3 = 0, int32_t arg4 = 0, void* ptr1 = nullptr, void* ptr2 = nullptr);
void raise_event(card_set* event_cards, uint32 event_code, effect* reason_effect, uint32 reason, uint8 reason_player, uint8 event_player, uint32 event_value); uint32_t process();
void raise_single_event(card* trigger_card, card_set* event_cards, uint32 event_code, effect* reason_effect, uint32 reason, uint8 reason_player, uint8 event_player, uint32 event_value); int32_t execute_cost(uint16_t step, effect* peffect, uint8_t triggering_player);
int32 check_event(uint32 code, tevent* pe = 0); int32_t execute_operation(uint16_t step, effect* peffect, uint8_t triggering_player);
int32 check_event_c(effect* peffect, uint8 playerid, int32 neglect_con, int32 neglect_cost, int32 copy_info, tevent* pe = 0); int32_t execute_target(uint16_t step, effect* peffect, uint8_t triggering_player);
int32 check_hint_timing(effect* peffect); void raise_event(card* event_card, uint32_t event_code, effect* reason_effect, uint32_t reason, uint8_t reason_player, uint8_t event_player, uint32_t event_value);
int32 process_phase_event(int16 step, int32 phase_event); void raise_event(const card_set& event_cards, uint32_t event_code, effect* reason_effect, uint32_t reason, uint8_t reason_player, uint8_t event_player, uint32_t event_value);
int32 process_point_event(int16 step, int32 skip_trigger, int32 skip_freechain, int32 skip_new); void raise_single_event(card* trigger_card, card_set* event_cards, uint32_t event_code, effect* reason_effect, uint32_t reason, uint8_t reason_player, uint8_t event_player, uint32_t event_value);
int32 process_quick_effect(int16 step, int32 skip_freechain, uint8 priority); int32_t check_event(uint32_t code, tevent* pe = nullptr);
int32 process_instant_event(); int32_t check_event_c(effect* peffect, uint8_t playerid, int32_t neglect_con, int32_t neglect_cost, int32_t copy_info, tevent* pe = nullptr);
int32 process_single_event(); int32_t check_hint_timing(effect* peffect);
int32 process_single_event(effect* peffect, const tevent& e, chain_list& tp, chain_list& ntp); int32_t process_phase_event(int16_t step, int32_t phase_event);
int32 process_idle_command(uint16 step); int32_t process_point_event(int16_t step, int32_t skip_trigger, int32_t skip_freechain, int32_t skip_new);
int32 process_battle_command(uint16 step); int32_t process_quick_effect(int16_t step, int32_t skip_freechain, uint8_t priority);
int32 process_damage_step(uint16 step, uint32 new_attack); int32_t process_instant_event();
void calculate_battle_damage(effect** pdamchange, card** preason_card, uint8* battle_destroyed); int32_t process_single_event();
int32 process_turn(uint16 step, uint8 turn_player); int32_t process_single_event(effect* peffect, const tevent& e, chain_list& tp, chain_list& ntp);
int32_t process_idle_command(uint16_t step);
int32 add_chain(uint16 step); int32_t process_battle_command(uint16_t step);
void solve_continuous(uint8 playerid, effect* peffect, const tevent& e); int32_t process_damage_step(uint16_t step, uint32_t new_attack);
int32 solve_continuous(uint16 step); void calculate_battle_damage(effect** pdamchange, card** preason_card, uint8_t* battle_destroyed);
int32 solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2); int32_t process_turn(uint16_t step, uint8_t turn_player);
int32 break_effect();
int32_t add_chain(uint16_t step);
void solve_continuous(uint8_t playerid, effect* peffect, const tevent& e);
int32_t solve_continuous(uint16_t step);
int32_t solve_chain(uint16_t step, uint32_t chainend_arg1, uint32_t chainend_arg2);
int32_t break_effect();
void adjust_instant(); void adjust_instant();
void adjust_all(); void adjust_all();
void refresh_location_info_instant(); void refresh_location_info_instant();
int32 refresh_location_info(uint16 step); int32_t refresh_location_info(uint16_t step);
int32 adjust_step(uint16 step); int32_t adjust_step(uint16_t step);
//operations //operations
int32 negate_chain(uint8 chaincount); int32_t negate_chain(uint8_t chaincount);
int32 disable_chain(uint8 chaincount, uint8 forced); int32_t disable_chain(uint8_t chaincount, uint8_t forced);
void change_chain_effect(uint8 chaincount, int32 replace_op); void change_chain_effect(uint8_t chaincount, int32_t replace_op);
void change_target(uint8 chaincount, group* targets); void change_target(uint8_t chaincount, group* targets);
void change_target_player(uint8 chaincount, uint8 playerid); void change_target_player(uint8_t chaincount, uint8_t playerid);
void change_target_param(uint8 chaincount, int32 param); void change_target_param(uint8_t chaincount, int32_t param);
void remove_counter(uint32 reason, card* pcard, uint32 rplayer, uint32 s, uint32 o, uint32 countertype, uint32 count); void remove_counter(uint32_t reason, card* pcard, uint32_t rplayer, uint32_t s, uint32_t o, uint32_t countertype, uint32_t count);
void remove_overlay_card(uint32 reason, card* pcard, uint32 rplayer, uint32 s, uint32 o, uint16 min, uint16 max); void remove_overlay_card(uint32_t reason, card* pcard, uint32_t rplayer, uint32_t s, uint32_t o, uint16_t min, uint16_t max);
void get_control(card_set* targets, effect* reason_effect, uint32 reason_player, uint32 playerid, uint32 reset_phase, uint32 reset_count, uint32 zone); void get_control(const card_set& targets, effect* reason_effect, uint32_t reason_player, uint32_t playerid, uint32_t reset_phase, uint32_t reset_count, uint32_t zone);
void get_control(card* target, effect* reason_effect, uint32 reason_player, uint32 playerid, uint32 reset_phase, uint32 reset_count, uint32 zone); void get_control(card* target, effect* reason_effect, uint32_t reason_player, uint32_t playerid, uint32_t reset_phase, uint32_t reset_count, uint32_t zone);
void swap_control(effect* reason_effect, uint32 reason_player, card_set* targets1, card_set* targets2, uint32 reset_phase, uint32 reset_count); void swap_control(effect* reason_effect, uint32_t reason_player, const card_set& targets1, const card_set& targets2, uint32_t reset_phase, uint32_t reset_count);
void swap_control(effect* reason_effect, uint32 reason_player, card* pcard1, card* pcard2, uint32 reset_phase, uint32 reset_count); void swap_control(effect* reason_effect, uint32_t reason_player, card* pcard1, card* pcard2, uint32_t reset_phase, uint32_t reset_count);
void equip(uint32 equip_player, card* equip_card, card* target, uint32 up, uint32 is_step); void equip(uint32_t equip_player, card* equip_card, card* target, uint32_t up, uint32_t is_step);
void draw(effect* reason_effect, uint32 reason, uint32 reason_player, uint32 playerid, uint32 count); void draw(effect* reason_effect, uint32_t reason, uint32_t reason_player, uint32_t playerid, int32_t count);
void damage(effect* reason_effect, uint32 reason, uint32 reason_player, card* reason_card, uint32 playerid, uint32 amount, uint32 is_step = FALSE); void damage(effect* reason_effect, uint32_t reason, uint32_t reason_player, card* reason_card, uint32_t playerid, int32_t amount, uint32_t is_step = FALSE);
void recover(effect* reason_effect, uint32 reason, uint32 reason_player, uint32 playerid, uint32 amount, uint32 is_step = FALSE); void recover(effect* reason_effect, uint32_t reason, uint32_t reason_player, uint32_t playerid, int32_t amount, uint32_t is_step = FALSE);
void summon(uint32 sumplayer, card* target, effect* proc, uint32 ignore_count, uint32 min_tribute, uint32 zone = 0x1f); void summon(uint32_t sumplayer, card* target, effect* proc, uint32_t ignore_count, uint32_t min_tribute, uint32_t zone = 0x1f, uint32_t action_type = SUMMON_IN_IDLE);
void mset(uint32 setplayer, card* target, effect* proc, uint32 ignore_count, uint32 min_tribute, uint32 zone = 0x1f); void mset(uint32_t setplayer, card* target, effect* proc, uint32_t ignore_count, uint32_t min_tribute, uint32_t zone = 0x1f, uint32_t action_type = SUMMON_IN_IDLE);
void special_summon_rule(uint32 sumplayer, card* target, uint32 summon_type); void special_summon_rule(uint32_t sumplayer, card* target, uint32_t summon_type, uint32_t action_type = SUMMON_IN_IDLE);
void special_summon(card_set* target, uint32 sumtype, uint32 sumplayer, uint32 playerid, uint32 nocheck, uint32 nolimit, uint32 positions, uint32 zone); void special_summon(const card_set& target, uint32_t sumtype, uint32_t sumplayer, uint32_t playerid, uint32_t nocheck, uint32_t nolimit, uint32_t positions, uint32_t zone);
void special_summon_step(card* target, uint32 sumtype, uint32 sumplayer, uint32 playerid, uint32 nocheck, uint32 nolimit, uint32 positions, uint32 zone); void special_summon_step(card* target, uint32_t sumtype, uint32_t sumplayer, uint32_t playerid, uint32_t nocheck, uint32_t nolimit, uint32_t positions, uint32_t zone);
void special_summon_complete(effect* reason_effect, uint8 reason_player); void special_summon_complete(effect* reason_effect, uint8_t reason_player);
void destroy(card_set* targets, effect* reason_effect, uint32 reason, uint32 reason_player, uint32 playerid = 2, uint32 destination = 0, uint32 sequence = 0); void destroy(card_set& targets, effect* reason_effect, uint32_t reason, uint32_t reason_player, uint32_t playerid = 2, uint32_t destination = 0, uint32_t sequence = 0);
void destroy(card* target, effect* reason_effect, uint32 reason, uint32 reason_player, uint32 playerid = 2, uint32 destination = 0, uint32 sequence = 0); void destroy(card* target, effect* reason_effect, uint32_t reason, uint32_t reason_player, uint32_t playerid = 2, uint32_t destination = 0, uint32_t sequence = 0);
void release(card_set* targets, effect* reason_effect, uint32 reason, uint32 reason_player); void release(const card_set& targets, effect* reason_effect, uint32_t reason, uint32_t reason_player);
void release(card* target, effect* reason_effect, uint32 reason, uint32 reason_player); void release(card* target, effect* reason_effect, uint32_t reason, uint32_t reason_player);
void send_to(card_set* targets, effect* reason_effect, uint32 reason, uint32 reason_player, uint32 playerid, uint32 destination, uint32 sequence, uint32 position); void send_to(const card_set& targets, effect* reason_effect, uint32_t reason, uint32_t reason_player, uint32_t playerid, uint32_t destination, uint32_t sequence, uint32_t position, uint8_t send_activating = FALSE);
void send_to(card* target, effect* reason_effect, uint32 reason, uint32 reason_player, uint32 playerid, uint32 destination, uint32 sequence, uint32 position); void send_to(card* target, effect* reason_effect, uint32_t reason, uint32_t reason_player, uint32_t playerid, uint32_t destination, uint32_t sequence, uint32_t position, uint8_t send_activating = FALSE);
void move_to_field(card* target, uint32 move_player, uint32 playerid, uint32 destination, uint32 positions, uint32 enable = FALSE, uint32 ret = 0, uint32 pzone = FALSE, uint32 zone = 0xff); void move_to_field(card* target, uint32_t move_player, uint32_t playerid, uint32_t destination, uint32_t positions, uint32_t enable = FALSE, uint32_t ret = 0, uint32_t pzone = FALSE, uint32_t zone = 0xff);
void change_position(card_set* targets, effect* reason_effect, uint32 reason_player, uint32 au, uint32 ad, uint32 du, uint32 dd, uint32 flag, uint32 enable = FALSE); void change_position(const card_set& targets, effect* reason_effect, uint32_t reason_player, uint32_t au, uint32_t ad, uint32_t du, uint32_t dd, uint32_t flag, uint32_t enable = FALSE);
void change_position(card* target, effect* reason_effect, uint32 reason_player, uint32 npos, uint32 flag, uint32 enable = FALSE); void change_position(card* target, effect* reason_effect, uint32_t reason_player, uint32_t npos, uint32_t flag, uint32_t enable = FALSE);
void operation_replace(int32 type, int32 step, group* targets); void operation_replace(int32_t type, int32_t step, group* targets);
void select_tribute_cards(card* target, uint8 playerid, uint8 cancelable, int32 min, int32 max, uint8 toplayer, uint32 zone); void select_tribute_cards(card* target, uint8_t playerid, uint8_t cancelable, int32_t min, int32_t max, uint8_t toplayer, uint32_t zone);
int32 remove_counter(uint16 step, uint32 reason, card* pcard, uint8 rplayer, uint8 s, uint8 o, uint16 countertype, uint16 count); // summon
int32 remove_overlay_card(uint16 step, uint32 reason, card* pcard, uint8 rplayer, uint8 s, uint8 o, uint16 min, uint16 max); int32_t summon(uint16_t step, uint8_t sumplayer, card* target, effect* proc, uint8_t ignore_count, uint8_t min_tribute, uint32_t zone, uint32_t action_type);
int32 get_control(uint16 step, effect* reason_effect, uint8 reason_player, group* targets, uint8 playerid, uint16 reset_phase, uint8 reset_count, uint32 zone); int32_t mset(uint16_t step, uint8_t setplayer, card* ptarget, effect* proc, uint8_t ignore_count, uint8_t min_tribute, uint32_t zone, uint32_t action_type);
int32 swap_control(uint16 step, effect* reason_effect, uint8 reason_player, group* targets1, group* targets2, uint16 reset_phase, uint8 reset_count); int32_t flip_summon(uint16_t step, uint8_t sumplayer, card* target, uint32_t action_type);
int32 self_destroy(uint16 step, card* ucard, int32 p); int32_t special_summon_rule(uint16_t step, uint8_t sumplayer, card* target, uint32_t summon_type, uint32_t action_type);
int32 trap_monster_adjust(uint16 step);
int32 equip(uint16 step, uint8 equip_player, card* equip_card, card* target, uint32 up, uint32 is_step); int32_t remove_counter(uint16_t step, uint32_t reason, card* pcard, uint8_t rplayer, uint8_t s, uint8_t o, uint16_t countertype, uint16_t count);
int32 draw(uint16 step, effect* reason_effect, uint32 reason, uint8 reason_player, uint8 playerid, uint32 count); int32_t remove_overlay_card(uint16_t step, uint32_t reason, card* pcard, uint8_t rplayer, uint8_t s, uint8_t o, uint16_t min, uint16_t max);
int32 damage(uint16 step, effect* reason_effect, uint32 reason, uint8 reason_player, card* reason_card, uint8 playerid, uint32 amount, uint32 is_step); int32_t get_control(uint16_t step, effect* reason_effect, uint8_t reason_player, group* targets, uint8_t playerid, uint16_t reset_phase, uint8_t reset_count, uint32_t zone);
int32 recover(uint16 step, effect* reason_effect, uint32 reason, uint8 reason_player, uint8 playerid, uint32 amount, uint32 is_step); int32_t swap_control(uint16_t step, effect* reason_effect, uint8_t reason_player, group* targets1, group* targets2, uint16_t reset_phase, uint8_t reset_count);
int32 summon(uint16 step, uint8 sumplayer, card* target, effect* proc, uint8 ignore_count, uint8 min_tribute, uint32 zone); int32_t self_destroy(uint16_t step, card* ucard, int32_t p);
int32 flip_summon(uint16 step, uint8 sumplayer, card* target); int32_t trap_monster_adjust(uint16_t step);
int32 mset(uint16 step, uint8 setplayer, card* ptarget, effect* proc, uint8 ignore_count, uint8 min_tribute, uint32 zone); int32_t equip(uint16_t step, uint8_t equip_player, card* equip_card, card* target, uint32_t up, uint32_t is_step);
int32 sset(uint16 step, uint8 setplayer, uint8 toplayer, card* ptarget, effect* reason_effect); int32_t draw(uint16_t step, effect* reason_effect, uint32_t reason, uint8_t reason_player, uint8_t playerid, int32_t count);
int32 sset_g(uint16 step, uint8 setplayer, uint8 toplayer, group* ptarget, uint8 confirm, effect* reason_effect); int32_t damage(uint16_t step, effect* reason_effect, uint32_t reason, uint8_t reason_player, card* reason_card, uint8_t playerid, int32_t amount, uint32_t is_step);
int32 special_summon_rule(uint16 step, uint8 sumplayer, card* target, uint32 summon_type); int32_t recover(uint16_t step, effect* reason_effect, uint32_t reason, uint8_t reason_player, uint8_t playerid, int32_t amount, uint32_t is_step);
int32 special_summon_step(uint16 step, group* targets, card* target, uint32 zone); int32_t sset(uint16_t step, uint8_t setplayer, uint8_t toplayer, card* ptarget, effect* reason_effect);
int32 special_summon(uint16 step, effect* reason_effect, uint8 reason_player, group* targets, uint32 zone); int32_t sset_g(uint16_t step, uint8_t setplayer, uint8_t toplayer, group* ptarget, uint8_t confirm, effect* reason_effect);
int32 destroy_replace(uint16 step, group* targets, card* target, uint8 battle); int32_t special_summon_step(uint16_t step, group* targets, card* target, uint32_t zone);
int32 destroy(uint16 step, group* targets, effect* reason_effect, uint32 reason, uint8 reason_player); int32_t special_summon(uint16_t step, effect* reason_effect, uint8_t reason_player, group* targets, uint32_t zone);
int32 release_replace(uint16 step, group* targets, card* target); int32_t destroy_replace(uint16_t step, group* targets, card* target, uint8_t battle);
int32 release(uint16 step, group* targets, effect* reason_effect, uint32 reason, uint8 reason_player); int32_t destroy(uint16_t step, group* targets, effect* reason_effect, uint32_t reason, uint8_t reason_player);
int32 send_replace(uint16 step, group* targets, card* target); int32_t release_replace(uint16_t step, group* targets, card* target);
int32 send_to(uint16 step, group* targets, effect* reason_effect, uint32 reason, uint8 reason_player); int32_t release(uint16_t step, group* targets, effect* reason_effect, uint32_t reason, uint8_t reason_player);
int32 discard_deck(uint16 step, uint8 playerid, uint8 count, uint32 reason); int32_t send_replace(uint16_t step, group* targets, card* target);
int32 move_to_field(uint16 step, card* target, uint32 enable, uint32 ret, uint32 pzone, uint32 zone); int32_t send_to(uint16_t step, group* targets, effect* reason_effect, uint32_t reason, uint8_t reason_player, uint8_t send_activating);
int32 change_position(uint16 step, group* targets, effect* reason_effect, uint8 reason_player, uint32 enable); int32_t discard_deck(uint16_t step, uint8_t playerid, uint8_t count, uint32_t reason);
int32 operation_replace(uint16 step, effect* replace_effect, group* targets, card* target, int32 is_destroy); int32_t move_to_field(uint16_t step, card* target, uint32_t enable, uint32_t ret, uint32_t pzone, uint32_t zone);
int32 activate_effect(uint16 step, effect* peffect); int32_t change_position(uint16_t step, group* targets, effect* reason_effect, uint8_t reason_player, uint32_t enable);
int32 select_synchro_material(int16 step, uint8 playerid, card* pcard, int32 min, int32 max, card* smat, group* mg); int32_t operation_replace(uint16_t step, effect* replace_effect, group* targets, card* target, int32_t is_destroy);
int32 select_xyz_material(int16 step, uint8 playerid, uint32 lv, card* pcard, int32 min, int32 max); int32_t activate_effect(uint16_t step, effect* peffect);
int32 select_release_cards(int16 step, uint8 playerid, uint8 cancelable, int32 min, int32 max); int32_t select_synchro_material(int16_t step, uint8_t playerid, card* pcard, int32_t min, int32_t max, card* smat, group* mg, int32_t filter1, int32_t filter2);
int32 select_tribute_cards(int16 step, card* target, uint8 playerid, uint8 cancelable, int32 min, int32 max, uint8 toplayer, uint32 zone); int32_t select_xyz_material(int16_t step, uint8_t playerid, uint32_t lv, card* pcard, int32_t min, int32_t max);
int32 toss_coin(uint16 step, effect* reason_effect, uint8 reason_player, uint8 playerid, uint8 count); int32_t select_release_cards(int16_t step, uint8_t playerid, uint8_t cancelable, int32_t min, int32_t max);
int32 toss_dice(uint16 step, effect* reason_effect, uint8 reason_player, uint8 playerid, uint8 count1, uint8 count2); int32_t select_tribute_cards(int16_t step, card* target, uint8_t playerid, uint8_t cancelable, int32_t min, int32_t max, uint8_t toplayer, uint32_t zone);
int32 rock_paper_scissors(uint16 step, uint8 repeat); int32_t toss_coin(uint16_t step, effect* reason_effect, uint8_t reason_player, uint8_t playerid, int32_t count);
int32_t toss_dice(uint16_t step, effect* reason_effect, uint8_t reason_player, uint8_t playerid, uint8_t count1, uint8_t count2);
int32 select_battle_command(uint16 step, uint8 playerid); int32_t rock_paper_scissors(uint16_t step, uint8_t repeat);
int32 select_idle_command(uint16 step, uint8 playerid);
int32 select_effect_yes_no(uint16 step, uint8 playerid, uint32 description, card* pcard); bool check_response(size_t vector_size, int32_t min_len, int32_t max_len) const;
int32 select_yes_no(uint16 step, uint8 playerid, uint32 description); int32_t select_battle_command(uint16_t step, uint8_t playerid);
int32 select_option(uint16 step, uint8 playerid); int32_t select_idle_command(uint16_t step, uint8_t playerid);
int32 select_card(uint16 step, uint8 playerid, uint8 cancelable, uint8 min, uint8 max); int32_t select_effect_yes_no(uint16_t step, uint8_t playerid, uint32_t description, card* pcard);
int32 select_unselect_card(uint16 step, uint8 playerid, uint8 cancelable, uint8 min, uint8 max, uint8 finishable); int32_t select_yes_no(uint16_t step, uint8_t playerid, uint32_t description);
int32 select_chain(uint16 step, uint8 playerid, uint8 spe_count, uint8 forced); int32_t select_option(uint16_t step, uint8_t playerid);
int32 select_place(uint16 step, uint8 playerid, uint32 flag, uint8 count); int32_t select_card(uint16_t step, uint8_t playerid, uint8_t cancelable, uint8_t min, uint8_t max);
int32 select_position(uint16 step, uint8 playerid, uint32 code, uint8 positions); int32_t select_unselect_card(uint16_t step, uint8_t playerid, uint8_t cancelable, uint8_t min, uint8_t max, uint8_t finishable);
int32 select_tribute(uint16 step, uint8 playerid, uint8 cancelable, uint8 min, uint8 max); int32_t select_chain(uint16_t step, uint8_t playerid, uint8_t spe_count, uint8_t forced);
int32 select_counter(uint16 step, uint8 playerid, uint16 countertype, uint16 count, uint8 s, uint8 o); int32_t select_place(uint16_t step, uint8_t playerid, uint32_t flag, uint8_t count);
int32 select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32 min, int32 max); int32_t select_position(uint16_t step, uint8_t playerid, uint32_t code, uint8_t positions);
int32 sort_card(int16 step, uint8 playerid); int32_t select_tribute(uint16_t step, uint8_t playerid, uint8_t cancelable, uint8_t min, uint8_t max);
int32 announce_race(int16 step, uint8 playerid, int32 count, int32 available); int32_t select_counter(uint16_t step, uint8_t playerid, uint16_t countertype, uint16_t count, uint8_t s, uint8_t o);
int32 announce_attribute(int16 step, uint8 playerid, int32 count, int32 available); int32_t select_with_sum_limit(int16_t step, uint8_t playerid, int32_t acc, int32_t min, int32_t max);
int32 announce_card(int16 step, uint8 playerid); int32_t sort_card(int16_t step, uint8_t playerid);
int32 announce_number(int16 step, uint8 playerid); int32_t announce_race(int16_t step, uint8_t playerid, int32_t count, int32_t available);
int32_t announce_attribute(int16_t step, uint8_t playerid, int32_t count, int32_t available);
int32_t announce_card(int16_t step, uint8_t playerid);
int32_t announce_number(int16_t step, uint8_t playerid);
}; };
//Location Use Reason //Location Use Reason
...@@ -718,7 +713,7 @@ public: ...@@ -718,7 +713,7 @@ public:
#define GLOBALFLAG_SCRAP_CHIMERA 0x4 #define GLOBALFLAG_SCRAP_CHIMERA 0x4
//#define GLOBALFLAG_DELAYED_QUICKEFFECT 0x8 //#define GLOBALFLAG_DELAYED_QUICKEFFECT 0x8
#define GLOBALFLAG_DETACH_EVENT 0x10 #define GLOBALFLAG_DETACH_EVENT 0x10
#define GLOBALFLAG_MUST_BE_SMATERIAL 0x20 //#define GLOBALFLAG_MUST_BE_SMATERIAL 0x20
#define GLOBALFLAG_SPSUMMON_COUNT 0x40 #define GLOBALFLAG_SPSUMMON_COUNT 0x40
#define GLOBALFLAG_XMAT_COUNT_LIMIT 0x80 #define GLOBALFLAG_XMAT_COUNT_LIMIT 0x80
#define GLOBALFLAG_SELF_TOGRAVE 0x100 #define GLOBALFLAG_SELF_TOGRAVE 0x100
...@@ -726,9 +721,6 @@ public: ...@@ -726,9 +721,6 @@ public:
#define GLOBALFLAG_TUNE_MAGICIAN 0x400 #define GLOBALFLAG_TUNE_MAGICIAN 0x400
#define GLOBALFLAG_ACTIVATION_COUNT 0x800 #define GLOBALFLAG_ACTIVATION_COUNT 0x800
// //
#define PROCESSOR_NONE 0
#define PROCESSOR_WAITING 0x10000
#define PROCESSOR_END 0x20000
#define PROCESSOR_ADJUST 1 #define PROCESSOR_ADJUST 1
#define PROCESSOR_HINT 2 #define PROCESSOR_HINT 2
......
...@@ -10,21 +10,15 @@ ...@@ -10,21 +10,15 @@
#include "duel.h" #include "duel.h"
group::group(duel* pd) { group::group(duel* pd) {
ref_handle = 0;
pduel = pd; pduel = pd;
is_readonly = FALSE;
it = container.begin(); it = container.begin();
} }
group::group(duel* pd, card* pcard) { group::group(duel* pd, card* pcard) {
container.insert(pcard); container.insert(pcard);
ref_handle = 0;
pduel = pd; pduel = pd;
is_readonly = FALSE;
it = container.begin(); it = container.begin();
} }
group::group(duel* pd, const card_set& cset): container(cset) { group::group(duel* pd, const card_set& cset): container(cset) {
ref_handle = 0;
pduel = pd; pduel = pd;
is_readonly = FALSE;
it = container.begin(); it = container.begin();
} }
...@@ -9,22 +9,29 @@ ...@@ -9,22 +9,29 @@
#define GROUP_H_ #define GROUP_H_
#include "common.h" #include "common.h"
#include "sort.h"
#include <set> #include <set>
#include <list> #include <list>
class card; class card;
class duel; class duel;
class group { using card_set = std::set<card*, card_sort>;
constexpr uint32_t GTYPE_DEFAULT = 0;
constexpr uint32_t GTYPE_READ_ONLY = 1;
constexpr uint32_t GTYPE_KEEP_ALIVE = 2;
class alignas(8) group {
public: public:
using card_set = std::set<card*, card_sort>; int32_t ref_handle{ 0 };
int32 ref_handle; uint32_t is_readonly{ GTYPE_DEFAULT };
duel* pduel; duel* pduel;
card_set container; card_set container;
card_set::iterator it; card_set::iterator it;
uint32 is_readonly; bool is_iterator_dirty{ true };
inline bool has_card(card* c) { bool has_card(card* c) {
return container.find(c) != container.end(); return container.find(c) != container.end();
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
* Author: Argon * Author: Argon
*/ */
#include <cstring>
#include "duel.h" #include "duel.h"
#include "group.h" #include "group.h"
#include "card.h" #include "card.h"
...@@ -17,33 +18,29 @@ interpreter::interpreter(duel* pd): coroutines(256) { ...@@ -17,33 +18,29 @@ interpreter::interpreter(duel* pd): coroutines(256) {
lua_state = luaL_newstate(); lua_state = luaL_newstate();
current_state = lua_state; current_state = lua_state;
pduel = pd; pduel = pd;
memcpy(lua_getextraspace(lua_state), &pd, LUA_EXTRASPACE); //set_duel_info std::memcpy(lua_getextraspace(lua_state), &pd, LUA_EXTRASPACE); //set_duel_info
no_action = 0; no_action = 0;
call_depth = 0; call_depth = 0;
//Initial //Initial
luaL_openlibs(lua_state); luaL_requiref(lua_state, "base", luaopen_base, 0);
lua_pushnil(lua_state); lua_pop(lua_state, 1);
lua_setglobal(lua_state, "io"); luaL_requiref(lua_state, "string", luaopen_string, 1);
lua_pushnil(lua_state); lua_pop(lua_state, 1);
lua_setglobal(lua_state, "os"); luaL_requiref(lua_state, "utf8", luaopen_utf8, 1);
lua_pushnil(lua_state);
lua_setglobal(lua_state, "package");
lua_pushnil(lua_state);
lua_setglobal(lua_state, "debug");
lua_pushnil(lua_state);
lua_setglobal(lua_state, "coroutine");
luaL_getsubtable(lua_state, LUA_REGISTRYINDEX, "_LOADED");
lua_pushnil(lua_state);
lua_setfield(lua_state, -2, "io");
lua_pushnil(lua_state);
lua_setfield(lua_state, -2, "os");
lua_pushnil(lua_state);
lua_setfield(lua_state, -2, "package");
lua_pushnil(lua_state);
lua_setfield(lua_state, -2, "debug");
lua_pushnil(lua_state);
lua_setfield(lua_state, -2, "coroutine");
lua_pop(lua_state, 1); lua_pop(lua_state, 1);
luaL_requiref(lua_state, "table", luaopen_table, 1);
lua_pop(lua_state, 1);
luaL_requiref(lua_state, "math", luaopen_math, 1);
lua_pop(lua_state, 1);
auto nil_out = [&](const char* name) {
lua_pushnil(lua_state);
lua_setglobal(lua_state, name);
};
nil_out("collectgarbage");
#ifndef ENABLE_UNSAFE_LIBRARIES
nil_out("dofile");
nil_out("loadfile");
#endif // ENABLE_UNSAFE_LIBRARIES
//open all libs //open all libs
scriptlib::open_cardlib(lua_state); scriptlib::open_cardlib(lua_state);
scriptlib::open_effectlib(lua_state); scriptlib::open_effectlib(lua_state);
...@@ -53,42 +50,41 @@ interpreter::interpreter(duel* pd): coroutines(256) { ...@@ -53,42 +50,41 @@ interpreter::interpreter(duel* pd): coroutines(256) {
//extra scripts //extra scripts
load_script("./script/constant.lua"); load_script("./script/constant.lua");
load_script("./script/utility.lua"); load_script("./script/utility.lua");
load_script("./script/procedure.lua");
} }
interpreter::~interpreter() { interpreter::~interpreter() {
lua_close(lua_state); lua_close(lua_state);
} }
int32 interpreter::register_card(card *pcard) { void interpreter::register_card(card *pcard) {
if (!pcard)
return;
//create a card in by userdata //create a card in by userdata
luaL_checkstack(lua_state, 1, NULL); luaL_checkstack(lua_state, 1, nullptr);
luaL_checkstack(current_state, 1, NULL); card ** ppcard = (card**) lua_newuserdata(lua_state, sizeof(card*)); //+1 userdata
card ** ppcard = (card**) lua_newuserdata(lua_state, sizeof(card*));
*ppcard = pcard; *ppcard = pcard;
pcard->ref_handle = luaL_ref(lua_state, LUA_REGISTRYINDEX); pcard->ref_handle = luaL_ref(lua_state, LUA_REGISTRYINDEX); //-1
//some userdata may be created in script like token so use current_state //some userdata may be created in script like token so use current_state
lua_rawgeti(current_state, LUA_REGISTRYINDEX, pcard->ref_handle); luaL_checkstack(current_state, 1, nullptr);
//load script lua_rawgeti(current_state, LUA_REGISTRYINDEX, pcard->ref_handle); //+1 userdata
if(pcard->data.alias && (pcard->data.alias < pcard->data.code + CARD_ARTWORK_VERSIONS_OFFSET) && (pcard->data.code < pcard->data.alias + CARD_ARTWORK_VERSIONS_OFFSET)) load_card_script(pcard->data.get_original_code());
load_card_script(pcard->data.alias); //stack: table cxxx, userdata
else
load_card_script(pcard->data.code);
//set metatable of pointer to base script //set metatable of pointer to base script
lua_setmetatable(current_state, -2); lua_setmetatable(current_state, -2); //-1
lua_pop(current_state, 1); lua_pop(current_state, 1); //-1
//Initial //Initial
if(pcard->data.code && (!(pcard->data.type & TYPE_NORMAL) || (pcard->data.type & TYPE_PENDULUM))) { if(is_load_script(pcard->data)) {
pcard->set_status(STATUS_INITIALIZING, TRUE); pcard->set_status(STATUS_INITIALIZING, TRUE);
add_param(pcard, PARAM_TYPE_CARD); add_param(pcard, PARAM_TYPE_CARD);
call_card_function(pcard, "initial_effect", 1, 0); call_card_function(pcard, "initial_effect", 1, 0);
pcard->set_status(STATUS_INITIALIZING, FALSE); pcard->set_status(STATUS_INITIALIZING, FALSE);
} }
pcard->cardid = pduel->game_field->infos.card_id++; pcard->cardid = pduel->game_field->infos.card_id++;
return OPERATION_SUCCESS;
} }
void interpreter::register_effect(effect *peffect) { void interpreter::register_effect(effect *peffect) {
if (!peffect) if (!peffect)
return; return;
//create a effect in by userdata //create a effect in userdata
luaL_checkstack(lua_state, 3, NULL); luaL_checkstack(lua_state, 3, nullptr);
effect ** ppeffect = (effect**) lua_newuserdata(lua_state, sizeof(effect*)); effect ** ppeffect = (effect**) lua_newuserdata(lua_state, sizeof(effect*));
*ppeffect = peffect; *ppeffect = peffect;
peffect->ref_handle = luaL_ref(lua_state, LUA_REGISTRYINDEX); peffect->ref_handle = luaL_ref(lua_state, LUA_REGISTRYINDEX);
...@@ -118,7 +114,7 @@ void interpreter::register_group(group *pgroup) { ...@@ -118,7 +114,7 @@ void interpreter::register_group(group *pgroup) {
if (!pgroup) if (!pgroup)
return; return;
//create a group in by userdata //create a group in by userdata
luaL_checkstack(lua_state, 3, NULL); luaL_checkstack(lua_state, 3, nullptr);
group ** ppgroup = (group**) lua_newuserdata(lua_state, sizeof(group*)); group ** ppgroup = (group**) lua_newuserdata(lua_state, sizeof(group*));
*ppgroup = pgroup; *ppgroup = pgroup;
pgroup->ref_handle = luaL_ref(lua_state, LUA_REGISTRYINDEX); pgroup->ref_handle = luaL_ref(lua_state, LUA_REGISTRYINDEX);
...@@ -134,120 +130,128 @@ void interpreter::unregister_group(group *pgroup) { ...@@ -134,120 +130,128 @@ void interpreter::unregister_group(group *pgroup) {
luaL_unref(lua_state, LUA_REGISTRYINDEX, pgroup->ref_handle); luaL_unref(lua_state, LUA_REGISTRYINDEX, pgroup->ref_handle);
pgroup->ref_handle = 0; pgroup->ref_handle = 0;
} }
int32 interpreter::load_script(const char* script_name) { int32_t interpreter::load_script(const char* script_name) {
int32 len = 0; int len = 0;
byte* buffer = read_script(script_name, &len); byte* buffer = ::read_script(script_name, &len);
if (!buffer) if (!buffer)
return OPERATION_FAIL; return OPERATION_FAIL;
no_action++; ++no_action;
int32 error = luaL_loadbuffer(current_state, (char*)buffer, len, script_name) || lua_pcall(current_state, 0, 0, 0); luaL_checkstack(current_state, 2, nullptr);
int32_t error = luaL_loadbuffer(current_state, (const char*)buffer, len, script_name) || lua_pcall(current_state, 0, 0, 0);
if (error) { if (error) {
sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1)); interpreter::sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1));
handle_message(pduel, 1); handle_message(pduel, 1);
lua_pop(current_state, 1); lua_pop(current_state, 1);
no_action--; --no_action;
return OPERATION_FAIL; return OPERATION_FAIL;
} }
no_action--; --no_action;
return OPERATION_SUCCESS; return OPERATION_SUCCESS;
} }
int32 interpreter::load_card_script(uint32 code) { //push table cxxx onto the stack of current_state
int32_t interpreter::load_card_script(uint32_t code) {
char class_name[20]; char class_name[20];
sprintf(class_name, "c%d", code); interpreter::sprintf(class_name, "c%d", code);
luaL_checkstack(current_state, 1, NULL); luaL_checkstack(current_state, 1, nullptr);
lua_getglobal(current_state, class_name); lua_getglobal(current_state, class_name); //+1 table cxxx
//if script is not loaded, create and load it
if (lua_isnil(current_state, -1)) { if (lua_isnil(current_state, -1)) {
luaL_checkstack(current_state, 5, NULL); luaL_checkstack(current_state, 5, nullptr);
lua_pop(current_state, 1); lua_pop(current_state, 1); //-1
//create a table & set metatable //create a table & set metatable
lua_createtable(current_state, 0, 0); lua_createtable(current_state, 0, 0); //+1, {}
lua_setglobal(current_state, class_name); lua_setglobal(current_state, class_name); //-1
lua_getglobal(current_state, class_name); lua_getglobal(current_state, class_name); //+1 table cxxx
lua_getglobal(current_state, "Card"); lua_getglobal(current_state, "Card"); //+1 Card, table cxxx
lua_setmetatable(current_state, -2); lua_setmetatable(current_state, -2); //-1 table cxxx
lua_pushstring(current_state, "__index"); lua_pushstring(current_state, "__index"); //+1 "__index", table cxxx
lua_pushvalue(current_state, -2); lua_pushvalue(current_state, -2); //+1 table cxxx, "__index", table cxxx
lua_rawset(current_state, -3); lua_rawset(current_state, -3); //-2 table cxxx
lua_getglobal(current_state, class_name); card_data cdata;
lua_setglobal(current_state, "self_table"); int32_t res = OPERATION_SUCCESS;
lua_pushinteger(current_state, code); ::read_card(code, &cdata);
lua_setglobal(current_state, "self_code"); if (is_load_script(cdata)) {
lua_getglobal(current_state, class_name); //+1
lua_setglobal(current_state, "self_table"); //-1
lua_pushinteger(current_state, code); //+1
lua_setglobal(current_state, "self_code"); //-1
char script_name[64]; char script_name[64];
sprintf(script_name, "./script/c%d.lua", code); interpreter::sprintf(script_name, "./script/c%d.lua", code);
int32 res = load_script(script_name); res = load_script(script_name);
lua_pushnil(current_state); lua_pushnil(current_state); //+1
lua_setglobal(current_state, "self_table"); lua_setglobal(current_state, "self_table"); //-1
lua_pushnil(current_state); lua_pushnil(current_state); //+1
lua_setglobal(current_state, "self_code"); lua_setglobal(current_state, "self_code"); //-1 table cxxx {__index: cxxx }
}
if(!res) { if(!res) {
return OPERATION_FAIL; return OPERATION_FAIL;
} }
} }
return OPERATION_SUCCESS; return OPERATION_SUCCESS;
} }
void interpreter::add_param(void *param, int32 type, bool front) { void interpreter::add_param(void* param, LuaParamType type, bool front) {
lua_param p;
p.ptr = param;
if(front) if(front)
params.emplace_front(param, type); params.emplace_front(p, type);
else else
params.emplace_back(param, type); params.emplace_back(p, type);
} }
void interpreter::add_param(int32 param, int32 type, bool front) { void interpreter::add_param(int32_t param, LuaParamType type, bool front) {
lua_param p;
p.integer = param;
if(front) if(front)
params.emplace_front((void*)(intptr_t)param, type); params.emplace_front(p, type);
else else
params.emplace_back((void*)(intptr_t)param, type); params.emplace_back(p, type);
} }
void interpreter::push_param(lua_State* L, bool is_coroutine) { void interpreter::push_param(lua_State* L, bool is_coroutine) {
int32 pushed = 0; int32_t pushed = 0;
for (const auto& it : params) { for (const auto& it : params) {
luaL_checkstack(L, 1, NULL); luaL_checkstack(L, 1, nullptr);
uint32 type = it.second; auto type = it.second;
switch(type) { switch(type) {
case PARAM_TYPE_INT: case PARAM_TYPE_INT:
lua_pushinteger(L, (lua_Integer)it.first); lua_pushinteger(L, it.first.integer);
break; break;
case PARAM_TYPE_STRING: case PARAM_TYPE_STRING:
lua_pushstring(L, (const char *)it.first); lua_pushstring(L, (const char*)it.first.ptr);
break; break;
case PARAM_TYPE_BOOLEAN: case PARAM_TYPE_BOOLEAN:
lua_pushboolean(L, (int32)(intptr_t)it.first); lua_pushboolean(L, it.first.integer);
break; break;
case PARAM_TYPE_CARD: { case PARAM_TYPE_CARD: {
if (it.first) if (it.first.ptr)
lua_rawgeti(L, LUA_REGISTRYINDEX, ((card*)it.first)->ref_handle); lua_rawgeti(L, LUA_REGISTRYINDEX, ((card*)it.first.ptr)->ref_handle);
else else
lua_pushnil(L); lua_pushnil(L);
break; break;
} }
case PARAM_TYPE_EFFECT: { case PARAM_TYPE_EFFECT: {
if (it.first) if (it.first.ptr)
lua_rawgeti(L, LUA_REGISTRYINDEX, ((effect*)it.first)->ref_handle); lua_rawgeti(L, LUA_REGISTRYINDEX, ((effect*)it.first.ptr)->ref_handle);
else else
lua_pushnil(L); lua_pushnil(L);
break; break;
} }
case PARAM_TYPE_GROUP: { case PARAM_TYPE_GROUP: {
if (it.first) if (it.first.ptr)
lua_rawgeti(L, LUA_REGISTRYINDEX, ((group*)it.first)->ref_handle); lua_rawgeti(L, LUA_REGISTRYINDEX, ((group*)it.first.ptr)->ref_handle);
else else
lua_pushnil(L); lua_pushnil(L);
break; break;
} }
case PARAM_TYPE_FUNCTION: { case PARAM_TYPE_FUNCTION: {
function2value(L, (int32)(intptr_t)it.first); function2value(L, it.first.integer);
break; break;
} }
case PARAM_TYPE_INDEX: { case PARAM_TYPE_INDEX: {
int32 index = (int32)(intptr_t)it.first; int32_t index = it.first.integer;
if(index > 0) if(index > 0)
lua_pushvalue(L, index); lua_pushvalue(L, index);
else if(is_coroutine) { else if(is_coroutine) {
//copy value from current_state to new stack //copy value from current_state to new stack
lua_pushvalue(current_state, index); lua_pushvalue(current_state, index);
int32 ref = luaL_ref(current_state, LUA_REGISTRYINDEX); lua_xmove(current_state, L, 1);
lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
luaL_unref(current_state, LUA_REGISTRYINDEX, ref);
} else { } else {
//the calling function is pushed before the params, so the actual index is: index - pushed -1 //the calling function is pushed before the params, so the actual index is: index - pushed -1
lua_pushvalue(L, index - pushed - 1); lua_pushvalue(L, index - pushed - 1);
...@@ -255,300 +259,300 @@ void interpreter::push_param(lua_State* L, bool is_coroutine) { ...@@ -255,300 +259,300 @@ void interpreter::push_param(lua_State* L, bool is_coroutine) {
break; break;
} }
} }
pushed++; ++pushed;
} }
params.clear(); params.clear();
} }
int32 interpreter::call_function(int32 f, uint32 param_count, int32 ret_count) { int32_t interpreter::call_function(int32_t f, uint32_t param_count, int32_t ret_count) {
if (!f) { if (!f) {
sprintf(pduel->strbuffer, "\"CallFunction\": attempt to call a null function."); interpreter::sprintf(pduel->strbuffer, "%s", "\"CallFunction\": attempt to call a null function.");
handle_message(pduel, 1); handle_message(pduel, 1);
params.clear(); params.clear();
return OPERATION_FAIL; return OPERATION_FAIL;
} }
if (param_count != params.size()) { if (param_count != params.size()) {
sprintf(pduel->strbuffer, "\"CallFunction\": incorrect parameter count (%d expected, %zu pushed)", param_count, params.size()); interpreter::sprintf(pduel->strbuffer, "\"CallFunction\": incorrect parameter count (%d expected, %zu pushed)", param_count, params.size());
handle_message(pduel, 1); handle_message(pduel, 1);
params.clear(); params.clear();
return OPERATION_FAIL; return OPERATION_FAIL;
} }
function2value(current_state, f); function2value(current_state, f);
if (!lua_isfunction(current_state, -1)) { if (!lua_isfunction(current_state, -1)) {
sprintf(pduel->strbuffer, "\"CallFunction\": attempt to call an error function"); interpreter::sprintf(pduel->strbuffer, "%s", "\"CallFunction\": attempt to call an error function");
handle_message(pduel, 1); handle_message(pduel, 1);
lua_pop(current_state, 1); lua_pop(current_state, 1);
params.clear(); params.clear();
return OPERATION_FAIL; return OPERATION_FAIL;
} }
no_action++; ++no_action;
call_depth++; ++call_depth;
push_param(current_state); push_param(current_state);
if (lua_pcall(current_state, param_count, ret_count, 0)) { if (lua_pcall(current_state, param_count, ret_count, 0)) {
sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1)); interpreter::sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1));
handle_message(pduel, 1); handle_message(pduel, 1);
lua_pop(current_state, 1); lua_pop(current_state, 1);
no_action--; --no_action;
call_depth--; --call_depth;
if(call_depth == 0) { if(call_depth == 0) {
pduel->release_script_group(); pduel->release_script_group();
pduel->restore_assumes(); pduel->restore_assumes();
} }
return OPERATION_FAIL; return OPERATION_FAIL;
} }
no_action--; --no_action;
call_depth--; --call_depth;
if(call_depth == 0) { if(call_depth == 0) {
pduel->release_script_group(); pduel->release_script_group();
pduel->restore_assumes(); pduel->restore_assumes();
} }
return OPERATION_SUCCESS; return OPERATION_SUCCESS;
} }
int32 interpreter::call_card_function(card* pcard, const char* f, uint32 param_count, int32 ret_count) { int32_t interpreter::call_card_function(card* pcard, const char* f, uint32_t param_count, int32_t ret_count) {
if (param_count != params.size()) { if (param_count != params.size()) {
sprintf(pduel->strbuffer, "\"CallCardFunction\"(c%d.%s): incorrect parameter count", pcard->data.code, f); interpreter::sprintf(pduel->strbuffer, "\"CallCardFunction\"(c%d.%s): incorrect parameter count", pcard->data.get_original_code(), f);
handle_message(pduel, 1); handle_message(pduel, 1);
params.clear(); params.clear();
return OPERATION_FAIL; return OPERATION_FAIL;
} }
card2value(current_state, pcard); card2value(current_state, pcard);
luaL_checkstack(current_state, 1, NULL); luaL_checkstack(current_state, 1, nullptr);
lua_getfield(current_state, -1, f); lua_getfield(current_state, -1, f);
if (!lua_isfunction(current_state, -1)) { if (!lua_isfunction(current_state, -1)) {
sprintf(pduel->strbuffer, "\"CallCardFunction\"(c%d.%s): attempt to call an error function", pcard->data.code, f); interpreter::sprintf(pduel->strbuffer, "\"CallCardFunction\"(c%d.%s): attempt to call an error function", pcard->data.get_original_code(), f);
handle_message(pduel, 1); handle_message(pduel, 1);
lua_pop(current_state, 2); lua_pop(current_state, 2);
params.clear(); params.clear();
return OPERATION_FAIL; return OPERATION_FAIL;
} }
no_action++; ++no_action;
call_depth++; ++call_depth;
lua_remove(current_state, -2); lua_remove(current_state, -2);
push_param(current_state); push_param(current_state);
if (lua_pcall(current_state, param_count, ret_count, 0)) { if (lua_pcall(current_state, param_count, ret_count, 0)) {
sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1)); interpreter::sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1));
handle_message(pduel, 1); handle_message(pduel, 1);
lua_pop(current_state, 1); lua_pop(current_state, 1);
no_action--; --no_action;
call_depth--; --call_depth;
if(call_depth == 0) { if(call_depth == 0) {
pduel->release_script_group(); pduel->release_script_group();
pduel->restore_assumes(); pduel->restore_assumes();
} }
return OPERATION_FAIL; return OPERATION_FAIL;
} }
no_action--; --no_action;
call_depth--; --call_depth;
if(call_depth == 0) { if(call_depth == 0) {
pduel->release_script_group(); pduel->release_script_group();
pduel->restore_assumes(); pduel->restore_assumes();
} }
return OPERATION_SUCCESS; return OPERATION_SUCCESS;
} }
int32 interpreter::call_code_function(uint32 code, const char* f, uint32 param_count, int32 ret_count) { int32_t interpreter::call_code_function(uint32_t code, const char* f, uint32_t param_count, int32_t ret_count) {
if (param_count != params.size()) { if (param_count != params.size()) {
sprintf(pduel->strbuffer, "\"CallCodeFunction\": incorrect parameter count"); interpreter::sprintf(pduel->strbuffer, "%s", "\"CallCodeFunction\": incorrect parameter count");
handle_message(pduel, 1); handle_message(pduel, 1);
params.clear(); params.clear();
return OPERATION_FAIL; return OPERATION_FAIL;
} }
load_card_script(code); load_card_script(code);
luaL_checkstack(current_state, 1, NULL); luaL_checkstack(current_state, 1, nullptr);
lua_getfield(current_state, -1, f); lua_getfield(current_state, -1, f);
if (!lua_isfunction(current_state, -1)) { if (!lua_isfunction(current_state, -1)) {
sprintf(pduel->strbuffer, "\"CallCodeFunction\": attempt to call an error function"); interpreter::sprintf(pduel->strbuffer, "%s", "\"CallCodeFunction\": attempt to call an error function");
handle_message(pduel, 1); handle_message(pduel, 1);
lua_pop(current_state, 2); lua_pop(current_state, 2);
params.clear(); params.clear();
return OPERATION_FAIL; return OPERATION_FAIL;
} }
lua_remove(current_state, -2); lua_remove(current_state, -2);
no_action++; ++no_action;
call_depth++; ++call_depth;
push_param(current_state); push_param(current_state);
if (lua_pcall(current_state, param_count, ret_count, 0)) { if (lua_pcall(current_state, param_count, ret_count, 0)) {
sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1)); interpreter::sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1));
handle_message(pduel, 1); handle_message(pduel, 1);
lua_pop(current_state, 1); lua_pop(current_state, 1);
no_action--; --no_action;
call_depth--; --call_depth;
if(call_depth == 0) { if(call_depth == 0) {
pduel->release_script_group(); pduel->release_script_group();
pduel->restore_assumes(); pduel->restore_assumes();
} }
return OPERATION_FAIL; return OPERATION_FAIL;
} }
no_action--; --no_action;
call_depth--; --call_depth;
if(call_depth == 0) { if(call_depth == 0) {
pduel->release_script_group(); pduel->release_script_group();
pduel->restore_assumes(); pduel->restore_assumes();
} }
return OPERATION_SUCCESS; return OPERATION_SUCCESS;
} }
int32 interpreter::check_condition(int32 f, uint32 param_count) { int32_t interpreter::check_condition(int32_t f, uint32_t param_count) {
if(!f) { if(!f) {
params.clear(); params.clear();
return TRUE; return TRUE;
} }
no_action++; ++no_action;
call_depth++; ++call_depth;
if (call_function(f, param_count, 1)) { if (call_function(f, param_count, 1)) {
int32 result = lua_toboolean(current_state, -1); int32_t result = lua_toboolean(current_state, -1);
lua_pop(current_state, 1); lua_pop(current_state, 1);
no_action--; --no_action;
call_depth--; --call_depth;
if(call_depth == 0) { if(call_depth == 0) {
pduel->release_script_group(); pduel->release_script_group();
pduel->restore_assumes(); pduel->restore_assumes();
} }
return result; return result;
} }
no_action--; --no_action;
call_depth--; --call_depth;
if(call_depth == 0) { if(call_depth == 0) {
pduel->release_script_group(); pduel->release_script_group();
pduel->restore_assumes(); pduel->restore_assumes();
} }
return OPERATION_FAIL; return OPERATION_FAIL;
} }
int32 interpreter::check_matching(card* pcard, int32 findex, int32 extraargs) { int32_t interpreter::check_filter(lua_State* L, card* pcard, int32_t findex, int32_t extraargs) {
if(!findex || lua_isnil(current_state, findex)) if (!findex || lua_isnil(L, findex))
return TRUE; return TRUE;
no_action++; ++no_action;
call_depth++; ++call_depth;
luaL_checkstack(current_state, 1 + extraargs, NULL); luaL_checkstack(L, 1 + extraargs, nullptr);
lua_pushvalue(current_state, findex); lua_pushvalue(L, findex);
interpreter::card2value(current_state, pcard); card2value(L, pcard);
for(int32 i = 0; i < extraargs; ++i) for (int32_t i = 0; i < extraargs; ++i)
lua_pushvalue(current_state, (int32)(-extraargs - 2)); lua_pushvalue(L, (int32_t)(-extraargs - 2));
if (lua_pcall(current_state, 1 + extraargs, 1, 0)) { if (lua_pcall(L, 1 + extraargs, 1, 0)) {
sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1)); interpreter::sprintf(pduel->strbuffer, "%s", lua_tostring(L, -1));
handle_message(pduel, 1); handle_message(pduel, 1);
lua_pop(current_state, 1); lua_pop(L, 1);
no_action--; --no_action;
call_depth--; --call_depth;
if(call_depth == 0) { if (call_depth == 0) {
pduel->release_script_group(); pduel->release_script_group();
pduel->restore_assumes(); pduel->restore_assumes();
} }
return OPERATION_FAIL; return OPERATION_FAIL;
} }
int32 result = lua_toboolean(current_state, -1); int32_t result = lua_toboolean(L, -1);
lua_pop(current_state, 1); lua_pop(L, 1);
no_action--; --no_action;
call_depth--; --call_depth;
if(call_depth == 0) { if (call_depth == 0) {
pduel->release_script_group(); pduel->release_script_group();
pduel->restore_assumes(); pduel->restore_assumes();
} }
return result; return result;
} }
int32 interpreter::get_operation_value(card* pcard, int32 findex, int32 extraargs) { int32_t interpreter::get_operation_value(card* pcard, int32_t findex, int32_t extraargs) {
if(!findex || lua_isnil(current_state, findex)) if(!findex || lua_isnil(current_state, findex))
return 0; return 0;
no_action++; ++no_action;
call_depth++; ++call_depth;
luaL_checkstack(current_state, 1 + extraargs, NULL); luaL_checkstack(current_state, 1 + extraargs, nullptr);
lua_pushvalue(current_state, findex); lua_pushvalue(current_state, findex);
interpreter::card2value(current_state, pcard); interpreter::card2value(current_state, pcard);
for(int32 i = 0; i < extraargs; ++i) for(int32_t i = 0; i < extraargs; ++i)
lua_pushvalue(current_state, (int32)(-extraargs - 2)); lua_pushvalue(current_state, (int32_t)(-extraargs - 2));
if (lua_pcall(current_state, 1 + extraargs, 1, 0)) { if (lua_pcall(current_state, 1 + extraargs, 1, 0)) {
sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1)); interpreter::sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1));
handle_message(pduel, 1); handle_message(pduel, 1);
lua_pop(current_state, 1); lua_pop(current_state, 1);
no_action--; --no_action;
call_depth--; --call_depth;
if(call_depth == 0) { if(call_depth == 0) {
pduel->release_script_group(); pduel->release_script_group();
pduel->restore_assumes(); pduel->restore_assumes();
} }
return OPERATION_FAIL; return OPERATION_FAIL;
} }
int32 result = lua_isinteger(current_state, -1) ? (int32)lua_tointeger(current_state, -1) : (int32)lua_tonumber(current_state, -1); int32_t result = lua_isinteger(current_state, -1) ? (int32_t)lua_tointeger(current_state, -1) : (int32_t)lua_tonumber(current_state, -1);
lua_pop(current_state, 1); lua_pop(current_state, 1);
no_action--; --no_action;
call_depth--; --call_depth;
if(call_depth == 0) { if(call_depth == 0) {
pduel->release_script_group(); pduel->release_script_group();
pduel->restore_assumes(); pduel->restore_assumes();
} }
return result; return result;
} }
int32 interpreter::get_function_value(int32 f, uint32 param_count) { int32_t interpreter::get_function_value(int32_t f, uint32_t param_count) {
if(!f) { if(!f) {
params.clear(); params.clear();
return 0; return 0;
} }
no_action++; ++no_action;
call_depth++; ++call_depth;
if (call_function(f, param_count, 1)) { if (call_function(f, param_count, 1)) {
int32 result = 0; int32_t result = 0;
if(lua_isboolean(current_state, -1)) if(lua_isboolean(current_state, -1))
result = lua_toboolean(current_state, -1); result = lua_toboolean(current_state, -1);
else if(lua_isinteger(current_state, -1)) else if(lua_isinteger(current_state, -1))
result = (int32)lua_tointeger(current_state, -1); result = (int32_t)lua_tointeger(current_state, -1);
else else
result = (int32)lua_tonumber(current_state, -1); result = (int32_t)lua_tonumber(current_state, -1);
lua_pop(current_state, 1); lua_pop(current_state, 1);
no_action--; --no_action;
call_depth--; --call_depth;
if(call_depth == 0) { if(call_depth == 0) {
pduel->release_script_group(); pduel->release_script_group();
pduel->restore_assumes(); pduel->restore_assumes();
} }
return result; return result;
} }
no_action--; --no_action;
call_depth--; --call_depth;
if(call_depth == 0) { if(call_depth == 0) {
pduel->release_script_group(); pduel->release_script_group();
pduel->restore_assumes(); pduel->restore_assumes();
} }
return OPERATION_FAIL; return OPERATION_FAIL;
} }
int32 interpreter::get_function_value(int32 f, uint32 param_count, std::vector<int32>* result) { int32_t interpreter::get_function_value(int32_t f, uint32_t param_count, std::vector<lua_Integer>& result) {
int32 is_success = OPERATION_FAIL; int32_t is_success = OPERATION_FAIL;
if(!f) { if(!f) {
params.clear(); params.clear();
return is_success; return is_success;
} }
int32 stack_top = lua_gettop(current_state); int32_t stack_top = lua_gettop(current_state);
no_action++; ++no_action;
call_depth++; ++call_depth;
if (call_function(f, param_count, LUA_MULTRET)) { if (call_function(f, param_count, LUA_MULTRET)) {
int32 stack_newtop = lua_gettop(current_state); int32_t stack_newtop = lua_gettop(current_state);
for (int32 index = stack_top + 1; index <= stack_newtop; ++index) { for (int32_t index = stack_top + 1; index <= stack_newtop; ++index) {
int32 return_value = 0; lua_Integer return_value = 0;
if(lua_isboolean(current_state, index)) if(lua_isboolean(current_state, index))
return_value = lua_toboolean(current_state, index); return_value = lua_toboolean(current_state, index);
else if(lua_isinteger(current_state, index)) else if(lua_isinteger(current_state, index))
return_value = (int32)lua_tointeger(current_state, index); return_value = lua_tointeger(current_state, index);
else else
return_value = (int32)lua_tonumber(current_state, index); return_value = static_cast<lua_Integer>(lua_tonumber(current_state, index));
result->push_back(return_value); result.push_back(return_value);
} }
lua_settop(current_state, stack_top); lua_settop(current_state, stack_top);
is_success = OPERATION_SUCCESS; is_success = OPERATION_SUCCESS;
} }
no_action--; --no_action;
call_depth--; --call_depth;
if(call_depth == 0) { if(call_depth == 0) {
pduel->release_script_group(); pduel->release_script_group();
pduel->restore_assumes(); pduel->restore_assumes();
} }
return is_success; return is_success;
} }
int32 interpreter::call_coroutine(int32 f, uint32 param_count, uint32 * yield_value, uint16 step) { int32_t interpreter::call_coroutine(int32_t f, uint32_t param_count, int32_t* yield_value, uint16_t step) {
*yield_value = 0; *yield_value = 0;
if (!f) { if (!f) {
sprintf(pduel->strbuffer, "\"CallCoroutine\": attempt to call a null function"); interpreter::sprintf(pduel->strbuffer, "%s", "\"CallCoroutine\": attempt to call a null function");
handle_message(pduel, 1); handle_message(pduel, 1);
params.clear(); params.clear();
return OPERATION_FAIL; return OPERATION_FAIL;
} }
if (param_count != params.size()) { if (param_count != params.size()) {
sprintf(pduel->strbuffer, "\"CallCoroutine\": incorrect parameter count"); interpreter::sprintf(pduel->strbuffer, "%s", "\"CallCoroutine\": incorrect parameter count");
handle_message(pduel, 1); handle_message(pduel, 1);
params.clear(); params.clear();
return OPERATION_FAIL; return OPERATION_FAIL;
...@@ -557,124 +561,130 @@ int32 interpreter::call_coroutine(int32 f, uint32 param_count, uint32 * yield_va ...@@ -557,124 +561,130 @@ int32 interpreter::call_coroutine(int32 f, uint32 param_count, uint32 * yield_va
lua_State* rthread; lua_State* rthread;
if (it == coroutines.end()) { if (it == coroutines.end()) {
rthread = lua_newthread(lua_state); rthread = lua_newthread(lua_state);
const auto threadref = luaL_ref(lua_state, LUA_REGISTRYINDEX);
function2value(rthread, f); function2value(rthread, f);
if(!lua_isfunction(rthread, -1)) { if(!lua_isfunction(rthread, -1)) {
sprintf(pduel->strbuffer, "\"CallCoroutine\": attempt to call an error function"); luaL_unref(lua_state, LUA_REGISTRYINDEX, threadref);
interpreter::sprintf(pduel->strbuffer, "%s", "\"CallCoroutine\": attempt to call an error function");
handle_message(pduel, 1); handle_message(pduel, 1);
params.clear(); params.clear();
return OPERATION_FAIL; return OPERATION_FAIL;
} }
call_depth++; ++call_depth;
coroutines.emplace(f, rthread); auto ret = coroutines.emplace(f, coroutine_map::mapped_type(rthread, threadref));
it = ret.first;
} else { } else {
rthread = it->second;
if(step == 0) { if(step == 0) {
sprintf(pduel->strbuffer, "recursive event trigger detected."); auto threadref = it->second.second;
coroutines.erase(it);
luaL_unref(lua_state, LUA_REGISTRYINDEX, threadref);
interpreter::sprintf(pduel->strbuffer, "%s", "recursive event trigger detected");
handle_message(pduel, 1); handle_message(pduel, 1);
params.clear(); params.clear();
call_depth--; --call_depth;
if(call_depth == 0) { if(call_depth == 0) {
pduel->release_script_group(); pduel->release_script_group();
pduel->restore_assumes(); pduel->restore_assumes();
} }
return OPERATION_FAIL; return OPERATION_FAIL;
} }
rthread = it->second.first;
} }
push_param(rthread, true); push_param(rthread, true);
lua_State* prev_state = current_state; int32_t result = 0, nresults = 0;
{
auto prev_state = current_state;
current_state = rthread; current_state = rthread;
#if (LUA_VERSION_NUM >= 504) #if (LUA_VERSION_NUM >= 504)
int32 nresults; result = lua_resume(rthread, prev_state, param_count, &nresults);
int32 result = lua_resume(rthread, prev_state, param_count, &nresults);
#else #else
int32 result = lua_resume(rthread, 0, param_count); result = lua_resume(rthread, prev_state, param_count);
int32 nresults = lua_gettop(rthread); nresults = lua_gettop(rthread);
#endif #endif
if (result == 0) { current_state = prev_state;
coroutines.erase(f);
if(yield_value) {
if(nresults == 0)
*yield_value = 0;
else if(lua_isboolean(rthread, -1))
*yield_value = lua_toboolean(rthread, -1);
else
*yield_value = (uint32)lua_tointeger(rthread, -1);
} }
current_state = lua_state; if (result == LUA_YIELD)
call_depth--;
if(call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
return COROUTINE_FINISH;
} else if (result == LUA_YIELD) {
return COROUTINE_YIELD; return COROUTINE_YIELD;
} else { if (result != LUA_OK) {
coroutines.erase(f); interpreter::sprintf(pduel->strbuffer, "%s", lua_tostring(rthread, -1));
sprintf(pduel->strbuffer, "%s", lua_tostring(rthread, -1));
handle_message(pduel, 1); handle_message(pduel, 1);
lua_pop(rthread, 1); lua_pop(rthread, 1);
current_state = lua_state; }
call_depth--; else if (yield_value) {
if(call_depth == 0) { if (nresults == 0)
*yield_value = 0;
else if (lua_isboolean(rthread, -1))
*yield_value = lua_toboolean(rthread, -1);
else
*yield_value = (int32_t)lua_tointeger(rthread, -1);
}
auto threadref = it->second.second;
coroutines.erase(it);
luaL_unref(lua_state, LUA_REGISTRYINDEX, threadref);
--call_depth;
if (call_depth == 0) {
pduel->release_script_group(); pduel->release_script_group();
pduel->restore_assumes(); pduel->restore_assumes();
} }
return COROUTINE_ERROR; return (result == LUA_OK) ? COROUTINE_FINISH : COROUTINE_ERROR;
}
} }
int32 interpreter::clone_function_ref(int32 func_ref) { int32_t interpreter::clone_function_ref(int32_t func_ref) {
luaL_checkstack(current_state, 1, NULL); luaL_checkstack(current_state, 1, nullptr);
lua_rawgeti(current_state, LUA_REGISTRYINDEX, func_ref); lua_rawgeti(current_state, LUA_REGISTRYINDEX, func_ref);
int32 ref = luaL_ref(current_state, LUA_REGISTRYINDEX); int32_t ref = luaL_ref(current_state, LUA_REGISTRYINDEX);
return ref; return ref;
} }
void* interpreter::get_ref_object(int32 ref_handler) { void* interpreter::get_ref_object(int32_t ref_handler) {
if(ref_handler == 0) if(ref_handler == 0)
return nullptr; return nullptr;
luaL_checkstack(current_state, 1, NULL); luaL_checkstack(current_state, 1, nullptr);
lua_rawgeti(current_state, LUA_REGISTRYINDEX, ref_handler); lua_rawgeti(current_state, LUA_REGISTRYINDEX, ref_handler);
void* p = *(void**)lua_touserdata(current_state, -1); void* p = *(void**)lua_touserdata(current_state, -1);
lua_pop(current_state, 1); lua_pop(current_state, 1);
return p; return p;
} }
//Convert a pointer to a lua value, +1 -0 //push the object onto the stack of L, +1
void interpreter::card2value(lua_State* L, card* pcard) { void interpreter::card2value(lua_State* L, card* pcard) {
luaL_checkstack(L, 1, NULL); luaL_checkstack(L, 1, nullptr);
if (!pcard || pcard->ref_handle == 0) if (!pcard || pcard->ref_handle == 0)
lua_pushnil(L); lua_pushnil(L);
else else
lua_rawgeti(L, LUA_REGISTRYINDEX, pcard->ref_handle); lua_rawgeti(L, LUA_REGISTRYINDEX, pcard->ref_handle);
} }
void interpreter::group2value(lua_State* L, group* pgroup) { void interpreter::group2value(lua_State* L, group* pgroup) {
luaL_checkstack(L, 1, NULL); luaL_checkstack(L, 1, nullptr);
if (!pgroup || pgroup->ref_handle == 0) if (!pgroup || pgroup->ref_handle == 0)
lua_pushnil(L); lua_pushnil(L);
else else
lua_rawgeti(L, LUA_REGISTRYINDEX, pgroup->ref_handle); lua_rawgeti(L, LUA_REGISTRYINDEX, pgroup->ref_handle);
} }
void interpreter::effect2value(lua_State* L, effect* peffect) { void interpreter::effect2value(lua_State* L, effect* peffect) {
luaL_checkstack(L, 1, NULL); luaL_checkstack(L, 1, nullptr);
if (!peffect || peffect->ref_handle == 0) if (!peffect || peffect->ref_handle == 0)
lua_pushnil(L); lua_pushnil(L);
else else
lua_rawgeti(L, LUA_REGISTRYINDEX, peffect->ref_handle); lua_rawgeti(L, LUA_REGISTRYINDEX, peffect->ref_handle);
} }
void interpreter::function2value(lua_State* L, int32 func_ref) { void interpreter::function2value(lua_State* L, int32_t func_ref) {
luaL_checkstack(L, 1, NULL); luaL_checkstack(L, 1, nullptr);
if (!func_ref) if (!func_ref)
lua_pushnil(L); lua_pushnil(L);
else else
lua_rawgeti(L, LUA_REGISTRYINDEX, func_ref); lua_rawgeti(L, LUA_REGISTRYINDEX, func_ref);
} }
int32 interpreter::get_function_handle(lua_State* L, int32 index) { int32_t interpreter::get_function_handle(lua_State* L, int32_t index) {
luaL_checkstack(L, 1, NULL); luaL_checkstack(L, 1, nullptr);
lua_pushvalue(L, index); lua_pushvalue(L, index);
int32 ref = luaL_ref(L, LUA_REGISTRYINDEX); int32_t ref = luaL_ref(L, LUA_REGISTRYINDEX);
return ref; return ref;
} }
duel* interpreter::get_duel_info(lua_State * L) { duel* interpreter::get_duel_info(lua_State* L) {
duel* pduel; duel* pduel;
memcpy(&pduel, lua_getextraspace(L), LUA_EXTRASPACE); std::memcpy(&pduel, lua_getextraspace(L), LUA_EXTRASPACE);
return pduel; return pduel;
} }
bool interpreter::is_load_script(const card_data& data) {
if(data.code == TEMP_CARD_ID)
return false;
return !(data.type & TYPE_NORMAL) || (data.type & TYPE_PENDULUM);
}
...@@ -8,25 +8,40 @@ ...@@ -8,25 +8,40 @@
#ifndef INTERPRETER_H_ #ifndef INTERPRETER_H_
#define INTERPRETER_H_ #define INTERPRETER_H_
#include "lua.h" #include <lua.h>
#include "lauxlib.h" #include <lauxlib.h>
#include "lualib.h" #include <lualib.h>
#include "common.h" #include "common.h"
#include <unordered_map> #include <unordered_map>
#include <list> #include <list>
#include <vector> #include <vector>
#include <cstdio> #include <cstdio>
#include <cstring>
class card; class card;
struct card_data;
class effect; class effect;
class group; class group;
class duel; class duel;
enum LuaParamType : int32_t {
PARAM_TYPE_INT = 0x01,
PARAM_TYPE_STRING = 0x02,
PARAM_TYPE_CARD = 0x04,
PARAM_TYPE_GROUP = 0x08,
PARAM_TYPE_EFFECT = 0x10,
PARAM_TYPE_FUNCTION = 0x20,
PARAM_TYPE_BOOLEAN = 0x40,
PARAM_TYPE_INDEX = 0x80,
};
class interpreter { class interpreter {
public: public:
using coroutine_map = std::unordered_map<int32, lua_State*>; union lua_param {
using param_list = std::list<std::pair<void*, uint32>>; void* ptr;
int32_t integer;
};
using coroutine_map = std::unordered_map<int32_t, std::pair<lua_State*, int32_t>>;
using param_list = std::list<std::pair<lua_param, LuaParamType>>;
duel* pduel; duel* pduel;
char msgbuf[64]; char msgbuf[64];
...@@ -35,41 +50,42 @@ public: ...@@ -35,41 +50,42 @@ public:
param_list params; param_list params;
param_list resumes; param_list resumes;
coroutine_map coroutines; coroutine_map coroutines;
int32 no_action; int32_t no_action;
int32 call_depth; int32_t call_depth;
explicit interpreter(duel* pd); explicit interpreter(duel* pd);
~interpreter(); ~interpreter();
int32 register_card(card* pcard); void register_card(card* pcard);
void register_effect(effect* peffect); void register_effect(effect* peffect);
void unregister_effect(effect* peffect); void unregister_effect(effect* peffect);
void register_group(group* pgroup); void register_group(group* pgroup);
void unregister_group(group* pgroup); void unregister_group(group* pgroup);
int32 load_script(const char* script_name); int32_t load_script(const char* script_name);
int32 load_card_script(uint32 code); int32_t load_card_script(uint32_t code);
void add_param(void* param, int32 type, bool front = false); void add_param(void* param, LuaParamType type, bool front = false);
void add_param(int32 param, int32 type, bool front = false); void add_param(int32_t param, LuaParamType type, bool front = false);
void push_param(lua_State* L, bool is_coroutine = false); void push_param(lua_State* L, bool is_coroutine = false);
int32 call_function(int32 f, uint32 param_count, int32 ret_count); int32_t call_function(int32_t f, uint32_t param_count, int32_t ret_count);
int32 call_card_function(card* pcard, const char* f, uint32 param_count, int32 ret_count); int32_t call_card_function(card* pcard, const char* f, uint32_t param_count, int32_t ret_count);
int32 call_code_function(uint32 code, const char* f, uint32 param_count, int32 ret_count); int32_t call_code_function(uint32_t code, const char* f, uint32_t param_count, int32_t ret_count);
int32 check_condition(int32 f, uint32 param_count); int32_t check_condition(int32_t f, uint32_t param_count);
int32 check_matching(card* pcard, int32 findex, int32 extraargs); int32_t check_filter(lua_State* L, card* pcard, int32_t findex, int32_t extraargs);
int32 get_operation_value(card* pcard, int32 findex, int32 extraargs); int32_t get_operation_value(card* pcard, int32_t findex, int32_t extraargs);
int32 get_function_value(int32 f, uint32 param_count); int32_t get_function_value(int32_t f, uint32_t param_count);
int32 get_function_value(int32 f, uint32 param_count, std::vector<int32>* result); int32_t get_function_value(int32_t f, uint32_t param_count, std::vector<lua_Integer>& result);
int32 call_coroutine(int32 f, uint32 param_count, uint32* yield_value, uint16 step); int32_t call_coroutine(int32_t f, uint32_t param_count, int32_t* yield_value, uint16_t step);
int32 clone_function_ref(int32 func_ref); int32_t clone_function_ref(int32_t func_ref);
void* get_ref_object(int32 ref_handler); void* get_ref_object(int32_t ref_handler);
static void card2value(lua_State* L, card* pcard); static void card2value(lua_State* L, card* pcard);
static void group2value(lua_State* L, group* pgroup); static void group2value(lua_State* L, group* pgroup);
static void effect2value(lua_State* L, effect* peffect); static void effect2value(lua_State* L, effect* peffect);
static void function2value(lua_State* L, int32 pointer); static void function2value(lua_State* L, int32_t func_ref);
static int32 get_function_handle(lua_State* L, int32 index); static int32_t get_function_handle(lua_State* L, int32_t index);
static duel* get_duel_info(lua_State* L); static duel* get_duel_info(lua_State* L);
static bool is_load_script(const card_data& data);
template <size_t N, typename... TR> template <size_t N, typename... TR>
static int sprintf(char (&buffer)[N], const char* format, TR... args) { static int sprintf(char (&buffer)[N], const char* format, TR... args) {
...@@ -77,15 +93,6 @@ public: ...@@ -77,15 +93,6 @@ public:
} }
}; };
#define PARAM_TYPE_INT 0x01
#define PARAM_TYPE_STRING 0x02
#define PARAM_TYPE_CARD 0x04
#define PARAM_TYPE_GROUP 0x08
#define PARAM_TYPE_EFFECT 0x10
#define PARAM_TYPE_FUNCTION 0x20
#define PARAM_TYPE_BOOLEAN 0x40
#define PARAM_TYPE_INDEX 0x80
#define COROUTINE_FINISH 1 #define COROUTINE_FINISH 1
#define COROUTINE_YIELD 2 #define COROUTINE_YIELD 2
#define COROUTINE_ERROR 3 #define COROUTINE_ERROR 3
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* Author: Argon * Author: Argon
*/ */
#include <string.h> #include <cstring>
#include "scriptlib.h" #include "scriptlib.h"
#include "duel.h" #include "duel.h"
#include "field.h" #include "field.h"
...@@ -13,7 +13,8 @@ ...@@ -13,7 +13,8 @@
#include "effect.h" #include "effect.h"
#include "ocgapi.h" #include "ocgapi.h"
int32 scriptlib::debug_message(lua_State *L) { int32_t scriptlib::debug_message(lua_State *L) {
check_param_count(L, 1);
duel* pduel = interpreter::get_duel_info(L); duel* pduel = interpreter::get_duel_info(L);
lua_getglobal(L, "tostring"); lua_getglobal(L, "tostring");
lua_pushvalue(L, -2); lua_pushvalue(L, -2);
...@@ -22,19 +23,19 @@ int32 scriptlib::debug_message(lua_State *L) { ...@@ -22,19 +23,19 @@ int32 scriptlib::debug_message(lua_State *L) {
handle_message(pduel, 2); handle_message(pduel, 2);
return 0; return 0;
} }
int32 scriptlib::debug_add_card(lua_State *L) { int32_t scriptlib::debug_add_card(lua_State *L) {
check_param_count(L, 6); check_param_count(L, 6);
duel* pduel = interpreter::get_duel_info(L); duel* pduel = interpreter::get_duel_info(L);
int32 code = (int32)lua_tointeger(L, 1); int32_t code = (int32_t)lua_tointeger(L, 1);
int32 owner = (int32)lua_tointeger(L, 2); int32_t owner = (int32_t)lua_tointeger(L, 2);
int32 playerid = (int32)lua_tointeger(L, 3); int32_t playerid = (int32_t)lua_tointeger(L, 3);
int32 location = (int32)lua_tointeger(L, 4); int32_t location = (int32_t)lua_tointeger(L, 4);
int32 sequence = (int32)lua_tointeger(L, 5); int32_t sequence = (int32_t)lua_tointeger(L, 5);
int32 position = (int32)lua_tointeger(L, 6); int32_t position = (int32_t)lua_tointeger(L, 6);
int32 proc = lua_toboolean(L, 7); int32_t proc = lua_toboolean(L, 7);
if(owner != 0 && owner != 1) if (!check_playerid(owner))
return 0; return 0;
if(playerid != 0 && playerid != 1) if (!check_playerid(playerid))
return 0; return 0;
if(pduel->game_field->is_location_useable(playerid, location, sequence)) { if(pduel->game_field->is_location_useable(playerid, location, sequence)) {
card* pcard = pduel->new_card(code); card* pcard = pduel->new_card(code);
...@@ -43,7 +44,7 @@ int32 scriptlib::debug_add_card(lua_State *L) { ...@@ -43,7 +44,7 @@ int32 scriptlib::debug_add_card(lua_State *L) {
position = POS_FACEDOWN_DEFENSE; position = POS_FACEDOWN_DEFENSE;
pcard->sendto_param.position = position; pcard->sendto_param.position = position;
if(location == LOCATION_PZONE) { if(location == LOCATION_PZONE) {
int32 seq = pduel->game_field->core.duel_rule >= 4 ? sequence * 4 : sequence + 6; int32_t seq = pduel->game_field->get_pzone_sequence(sequence);
pduel->game_field->add_card(playerid, pcard, LOCATION_SZONE, seq, TRUE); pduel->game_field->add_card(playerid, pcard, LOCATION_SZONE, seq, TRUE);
} else { } else {
pduel->game_field->add_card(playerid, pcard, location, sequence); pduel->game_field->add_card(playerid, pcard, location, sequence);
...@@ -58,9 +59,11 @@ int32 scriptlib::debug_add_card(lua_State *L) { ...@@ -58,9 +59,11 @@ int32 scriptlib::debug_add_card(lua_State *L) {
interpreter::card2value(L, pcard); interpreter::card2value(L, pcard);
return 1; return 1;
} else if(location == LOCATION_MZONE) { } else if(location == LOCATION_MZONE) {
card* fcard = pduel->game_field->get_field_card(playerid, location, sequence);
if (!fcard || !(fcard->data.type & TYPE_XYZ))
return 0;
card* pcard = pduel->new_card(code); card* pcard = pduel->new_card(code);
pcard->owner = owner; pcard->owner = owner;
card* fcard = pduel->game_field->get_field_card(playerid, location, sequence);
fcard->xyz_add(pcard); fcard->xyz_add(pcard);
if(proc) if(proc)
pcard->set_status(STATUS_PROC_COMPLETE, TRUE); pcard->set_status(STATUS_PROC_COMPLETE, TRUE);
...@@ -69,13 +72,13 @@ int32 scriptlib::debug_add_card(lua_State *L) { ...@@ -69,13 +72,13 @@ int32 scriptlib::debug_add_card(lua_State *L) {
} }
return 0; return 0;
} }
int32 scriptlib::debug_set_player_info(lua_State *L) { int32_t scriptlib::debug_set_player_info(lua_State *L) {
check_param_count(L, 4); check_param_count(L, 4);
duel* pduel = interpreter::get_duel_info(L); duel* pduel = interpreter::get_duel_info(L);
uint32 playerid = (uint32)lua_tointeger(L, 1); int32_t playerid = (int32_t)lua_tointeger(L, 1);
uint32 lp = (uint32)lua_tointeger(L, 2); int32_t lp = (int32_t)lua_tointeger(L, 2);
uint32 startcount = (uint32)lua_tointeger(L, 3); int32_t startcount = (int32_t)lua_tointeger(L, 3);
uint32 drawcount = (uint32)lua_tointeger(L, 4); int32_t drawcount = (int32_t)lua_tointeger(L, 4);
if(playerid != 0 && playerid != 1) if(playerid != 0 && playerid != 1)
return 0; return 0;
pduel->game_field->player[playerid].lp = lp; pduel->game_field->player[playerid].lp = lp;
...@@ -83,18 +86,18 @@ int32 scriptlib::debug_set_player_info(lua_State *L) { ...@@ -83,18 +86,18 @@ int32 scriptlib::debug_set_player_info(lua_State *L) {
pduel->game_field->player[playerid].draw_count = drawcount; pduel->game_field->player[playerid].draw_count = drawcount;
return 0; return 0;
} }
int32 scriptlib::debug_pre_summon(lua_State *L) { int32_t scriptlib::debug_pre_summon(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1); check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1); card* pcard = *(card**) lua_touserdata(L, 1);
uint32 summon_type = (uint32)lua_tointeger(L, 2); uint32_t summon_type = (uint32_t)lua_tointeger(L, 2);
uint8 summon_location = 0; uint8_t summon_location = 0;
if(lua_gettop(L) > 2) if(lua_gettop(L) > 2)
summon_location = (uint8)lua_tointeger(L, 3); summon_location = (uint8_t)lua_tointeger(L, 3);
pcard->summon_info = summon_type | (summon_location << 16); pcard->summon_info = summon_type | (summon_location << 16);
return 0; return 0;
} }
int32 scriptlib::debug_pre_equip(lua_State *L) { int32_t scriptlib::debug_pre_equip(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1); check_param(L, PARAM_TYPE_CARD, 1);
check_param(L, PARAM_TYPE_CARD, 2); check_param(L, PARAM_TYPE_CARD, 2);
...@@ -112,7 +115,7 @@ int32 scriptlib::debug_pre_equip(lua_State *L) { ...@@ -112,7 +115,7 @@ int32 scriptlib::debug_pre_equip(lua_State *L) {
} }
return 1; return 1;
} }
int32 scriptlib::debug_pre_set_target(lua_State *L) { int32_t scriptlib::debug_pre_set_target(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1); check_param(L, PARAM_TYPE_CARD, 1);
check_param(L, PARAM_TYPE_CARD, 2); check_param(L, PARAM_TYPE_CARD, 2);
...@@ -121,30 +124,23 @@ int32 scriptlib::debug_pre_set_target(lua_State *L) { ...@@ -121,30 +124,23 @@ int32 scriptlib::debug_pre_set_target(lua_State *L) {
t_card->add_card_target(target); t_card->add_card_target(target);
return 0; return 0;
} }
int32 scriptlib::debug_pre_add_counter(lua_State *L) { int32_t scriptlib::debug_pre_add_counter(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1); check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1); card* pcard = *(card**) lua_touserdata(L, 1);
uint32 countertype = (uint32)lua_tointeger(L, 2); uint32_t countertype = (uint32_t)lua_tointeger(L, 2);
uint32 count = (uint32)lua_tointeger(L, 3); uint16_t count = (uint16_t)lua_tointeger(L, 3);
uint16 cttype = countertype; uint16_t cttype = countertype;
auto pr = pcard->counters.emplace(cttype, card::counter_map::mapped_type()); auto pr = pcard->counters.emplace(cttype, 0);
auto cmit = pr.first; auto cmit = pr.first;
if(pr.second) { cmit->second += count;
cmit->second[0] = 0;
cmit->second[1] = 0;
}
if(countertype & COUNTER_WITHOUT_PERMIT)
cmit->second[0] += count;
else
cmit->second[1] += count;
return 0; return 0;
} }
int32 scriptlib::debug_reload_field_begin(lua_State *L) { int32_t scriptlib::debug_reload_field_begin(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
duel* pduel = interpreter::get_duel_info(L); duel* pduel = interpreter::get_duel_info(L);
uint32 flag = (uint32)lua_tointeger(L, 1); uint32_t flag = (uint32_t)lua_tointeger(L, 1);
int32 rule = (int32)lua_tointeger(L, 2); int32_t rule = (int32_t)lua_tointeger(L, 2);
pduel->clear(); pduel->clear();
pduel->game_field->core.duel_options |= flag; pduel->game_field->core.duel_options |= flag;
if (rule) if (rule)
...@@ -152,10 +148,10 @@ int32 scriptlib::debug_reload_field_begin(lua_State *L) { ...@@ -152,10 +148,10 @@ int32 scriptlib::debug_reload_field_begin(lua_State *L) {
else if (flag & DUEL_OBSOLETE_RULING) else if (flag & DUEL_OBSOLETE_RULING)
pduel->game_field->core.duel_rule = 1; pduel->game_field->core.duel_rule = 1;
else else
pduel->game_field->core.duel_rule = 5; pduel->game_field->core.duel_rule = CURRENT_RULE;
return 0; return 0;
} }
int32 scriptlib::debug_reload_field_end(lua_State *L) { int32_t scriptlib::debug_reload_field_end(lua_State *L) {
duel* pduel = interpreter::get_duel_info(L); duel* pduel = interpreter::get_duel_info(L);
pduel->game_field->core.shuffle_hand_check[0] = FALSE; pduel->game_field->core.shuffle_hand_check[0] = FALSE;
pduel->game_field->core.shuffle_hand_check[1] = FALSE; pduel->game_field->core.shuffle_hand_check[1] = FALSE;
...@@ -164,35 +160,31 @@ int32 scriptlib::debug_reload_field_end(lua_State *L) { ...@@ -164,35 +160,31 @@ int32 scriptlib::debug_reload_field_end(lua_State *L) {
pduel->game_field->reload_field_info(); pduel->game_field->reload_field_info();
return 0; return 0;
} }
int32 scriptlib::debug_set_ai_name(lua_State *L) { int32_t scriptlib::debug_set_ai_name(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_STRING, 1); check_param(L, PARAM_TYPE_STRING, 1);
duel* pduel = interpreter::get_duel_info(L); duel* pduel = interpreter::get_duel_info(L);
pduel->write_buffer8(MSG_AI_NAME); pduel->write_buffer8(MSG_AI_NAME);
const char* pstr = lua_tostring(L, 1); const char* pstr = lua_tostring(L, 1);
int len = (int)strlen(pstr); int len = (int)std::strlen(pstr);
if(len > 100) if(len > SIZE_AI_NAME -1)
len = 100; len = SIZE_AI_NAME - 1;
pduel->write_buffer16(len); pduel->write_buffer16(len);
memcpy(pduel->bufferp, pstr, len); pduel->write_buffer(pstr, len);
pduel->bufferp += len;
pduel->bufferlen += len;
pduel->write_buffer8(0); pduel->write_buffer8(0);
return 0; return 0;
} }
int32 scriptlib::debug_show_hint(lua_State *L) { int32_t scriptlib::debug_show_hint(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_STRING, 1); check_param(L, PARAM_TYPE_STRING, 1);
duel* pduel = interpreter::get_duel_info(L); duel* pduel = interpreter::get_duel_info(L);
pduel->write_buffer8(MSG_SHOW_HINT); pduel->write_buffer8(MSG_SHOW_HINT);
const char* pstr = lua_tostring(L, 1); const char* pstr = lua_tostring(L, 1);
int len = (int)strlen(pstr); int len = (int)std::strlen(pstr);
if(len > 1024) if (len > SIZE_HINT_MSG - 1)
len = 1024; len = SIZE_HINT_MSG - 1;
pduel->write_buffer16(len); pduel->write_buffer16(len);
memcpy(pduel->bufferp, pstr, len); pduel->write_buffer(pstr, len);
pduel->bufferp += len;
pduel->bufferlen += len;
pduel->write_buffer8(0); pduel->write_buffer8(0);
return 0; return 0;
} }
...@@ -209,7 +201,7 @@ static const struct luaL_Reg debuglib[] = { ...@@ -209,7 +201,7 @@ static const struct luaL_Reg debuglib[] = {
{ "ReloadFieldEnd", scriptlib::debug_reload_field_end }, { "ReloadFieldEnd", scriptlib::debug_reload_field_end },
{ "SetAIName", scriptlib::debug_set_ai_name }, { "SetAIName", scriptlib::debug_set_ai_name },
{ "ShowHint", scriptlib::debug_show_hint }, { "ShowHint", scriptlib::debug_show_hint },
{ NULL, NULL } { nullptr, nullptr }
}; };
void scriptlib::open_debuglib(lua_State *L) { void scriptlib::open_debuglib(lua_State *L) {
luaL_newlib(L, debuglib); luaL_newlib(L, debuglib);
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -12,7 +12,62 @@ ...@@ -12,7 +12,62 @@
#include "effect.h" #include "effect.h"
#include "group.h" #include "group.h"
int32 scriptlib::effect_new(lua_State *L) { int32_t scriptlib::get_effect_property(lua_State* L, effect_member type) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**)lua_touserdata(L, 1);
lua_Integer value{};
if (peffect) {
switch (type) {
case MEMBER_CATEGORY:
value = peffect->category;
break;
case MEMBER_CODE:
value = peffect->code;
break;
case MEMBER_DESCRIPTION:
value = peffect->description;
break;
case MEMBER_ID:
value = peffect->id;
break;
case MEMBER_RANGE:
value = peffect->range;
break;
case MEMBER_TYPE:
value = peffect->type;
break;
}
}
lua_pushinteger(L, value);
return 1;
}
int32_t scriptlib::is_effect_has_property(lua_State* L, effect_member type) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**)lua_touserdata(L, 1);
uint64_t value{};
if (peffect) {
switch (type) {
case MEMBER_CATEGORY:
value = peffect->category;
break;
case MEMBER_RANGE:
value = peffect->range;
break;
case MEMBER_TYPE:
value = peffect->type;
break;
}
}
uint64_t x = lua_tointeger(L, 2);
if (value & x)
lua_pushboolean(L, 1);
else
lua_pushboolean(L, 0);
return 1;
}
int32_t scriptlib::effect_new(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1); check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1); card* pcard = *(card**) lua_touserdata(L, 1);
...@@ -23,7 +78,7 @@ int32 scriptlib::effect_new(lua_State *L) { ...@@ -23,7 +78,7 @@ int32 scriptlib::effect_new(lua_State *L) {
interpreter::effect2value(L, peffect); interpreter::effect2value(L, peffect);
return 1; return 1;
} }
int32 scriptlib::effect_newex(lua_State *L) { int32_t scriptlib::effect_newex(lua_State *L) {
duel* pduel = interpreter::get_duel_info(L); duel* pduel = interpreter::get_duel_info(L);
effect* peffect = pduel->new_effect(); effect* peffect = pduel->new_effect();
peffect->effect_owner = 0; peffect->effect_owner = 0;
...@@ -31,7 +86,7 @@ int32 scriptlib::effect_newex(lua_State *L) { ...@@ -31,7 +86,7 @@ int32 scriptlib::effect_newex(lua_State *L) {
interpreter::effect2value(L, peffect); interpreter::effect2value(L, peffect);
return 1; return 1;
} }
int32 scriptlib::effect_clone(lua_State *L) { int32_t scriptlib::effect_clone(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
...@@ -39,7 +94,7 @@ int32 scriptlib::effect_clone(lua_State *L) { ...@@ -39,7 +94,7 @@ int32 scriptlib::effect_clone(lua_State *L) {
interpreter::effect2value(L, ceffect); interpreter::effect2value(L, ceffect);
return 1; return 1;
} }
int32 scriptlib::effect_reset(lua_State *L) { int32_t scriptlib::effect_reset(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
...@@ -51,55 +106,51 @@ int32 scriptlib::effect_reset(lua_State *L) { ...@@ -51,55 +106,51 @@ int32 scriptlib::effect_reset(lua_State *L) {
peffect->handler->remove_effect(peffect); peffect->handler->remove_effect(peffect);
return 0; return 0;
} }
int32 scriptlib::effect_get_field_id(lua_State *L) { int32_t scriptlib::effect_get_field_id(lua_State *L) {
check_param_count(L, 1); return get_effect_property(L, MEMBER_ID);
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
lua_pushinteger(L, peffect->id);
return 1;
} }
int32 scriptlib::effect_set_description(lua_State *L) { int32_t scriptlib::effect_set_description(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 v = (uint32)lua_tointeger(L, 2); uint32_t v = (uint32_t)lua_tointeger(L, 2);
peffect->description = v; peffect->description = v;
return 0; return 0;
} }
int32 scriptlib::effect_set_code(lua_State *L) { int32_t scriptlib::effect_set_code(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 v = (uint32)lua_tointeger(L, 2); uint32_t v = (uint32_t)lua_tointeger(L, 2);
peffect->code = v; peffect->code = v;
return 0; return 0;
} }
int32 scriptlib::effect_set_range(lua_State *L) { int32_t scriptlib::effect_set_range(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 v = (uint32)lua_tointeger(L, 2); uint32_t v = (uint32_t)lua_tointeger(L, 2);
peffect->range = v; peffect->range = v;
return 0; return 0;
} }
int32 scriptlib::effect_set_target_range(lua_State *L) { int32_t scriptlib::effect_set_target_range(lua_State *L) {
check_param_count(L, 3); check_param_count(L, 3);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 s = (uint32)lua_tointeger(L, 2); uint32_t s = (uint32_t)lua_tointeger(L, 2);
uint32 o = (uint32)lua_tointeger(L, 3); uint32_t o = (uint32_t)lua_tointeger(L, 3);
peffect->s_range = s; peffect->s_range = s;
peffect->o_range = o; peffect->o_range = o;
peffect->flag[0] &= ~EFFECT_FLAG_ABSOLUTE_TARGET; peffect->flag[0] &= ~EFFECT_FLAG_ABSOLUTE_TARGET;
return 0; return 0;
} }
int32 scriptlib::effect_set_absolute_range(lua_State *L) { int32_t scriptlib::effect_set_absolute_range(lua_State *L) {
check_param_count(L, 4); check_param_count(L, 4);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 playerid = (uint32)lua_tointeger(L, 2); int32_t playerid = (int32_t)lua_tointeger(L, 2);
uint32 s = (uint32)lua_tointeger(L, 3); uint32_t s = (uint32_t)lua_tointeger(L, 3);
uint32 o = (uint32)lua_tointeger(L, 4); uint32_t o = (uint32_t)lua_tointeger(L, 4);
if(playerid == 0) { if(playerid == 0) {
peffect->s_range = s; peffect->s_range = s;
peffect->o_range = o; peffect->o_range = o;
...@@ -110,28 +161,30 @@ int32 scriptlib::effect_set_absolute_range(lua_State *L) { ...@@ -110,28 +161,30 @@ int32 scriptlib::effect_set_absolute_range(lua_State *L) {
peffect->flag[0] |= EFFECT_FLAG_ABSOLUTE_TARGET; peffect->flag[0] |= EFFECT_FLAG_ABSOLUTE_TARGET;
return 0; return 0;
} }
int32 scriptlib::effect_set_count_limit(lua_State *L) { int32_t scriptlib::effect_set_count_limit(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 v = (uint32)lua_tointeger(L, 2); uint32_t v = (uint32_t)lua_tointeger(L, 2);
uint32 code = 0; uint32_t code = 0;
if(lua_gettop(L) >= 3) if(lua_gettop(L) >= 3)
code = (uint32)lua_tointeger(L, 3); code = (uint32_t)lua_tointeger(L, 3);
if(v == 0) if(v == 0)
v = 1; v = 1;
if(code == EFFECT_COUNT_CODE_CHAIN)
code = EFFECT_COUNT_CODE_CHAIN | EFFECT_COUNT_CODE_SINGLE;
peffect->flag[0] |= EFFECT_FLAG_COUNT_LIMIT; peffect->flag[0] |= EFFECT_FLAG_COUNT_LIMIT;
peffect->count_limit = v; peffect->count_limit = v;
peffect->count_limit_max = v; peffect->count_limit_max = v;
peffect->count_code = code; peffect->count_code = code;
return 0; return 0;
} }
int32 scriptlib::effect_set_reset(lua_State *L) { int32_t scriptlib::effect_set_reset(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 v = (uint32)lua_tointeger(L, 2); uint32_t v = (uint32_t)lua_tointeger(L, 2);
uint32 c = (uint32)lua_tointeger(L, 3); int32_t c = (int32_t)lua_tointeger(L, 3);
if(c == 0) if(c == 0)
c = 1; c = 1;
if(v & (RESET_PHASE) && !(v & (RESET_SELF_TURN | RESET_OPPO_TURN))) if(v & (RESET_PHASE) && !(v & (RESET_SELF_TURN | RESET_OPPO_TURN)))
...@@ -140,90 +193,101 @@ int32 scriptlib::effect_set_reset(lua_State *L) { ...@@ -140,90 +193,101 @@ int32 scriptlib::effect_set_reset(lua_State *L) {
peffect->reset_count = c; peffect->reset_count = c;
return 0; return 0;
} }
int32 scriptlib::effect_set_type(lua_State *L) { int32_t scriptlib::effect_set_type(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 v = (uint32)lua_tointeger(L, 2); uint32_t v = (uint32_t)lua_tointeger(L, 2);
if (v & 0x0ff0) if (v & EFFECT_TYPE_ACTIVATE) {
v |= EFFECT_TYPE_ACTIONS; v = EFFECT_TYPE_FIELD | EFFECT_TYPE_ACTIVATE;
else
v &= ~EFFECT_TYPE_ACTIONS;
if(v & (EFFECT_TYPE_ACTIVATE | EFFECT_TYPE_IGNITION | EFFECT_TYPE_QUICK_O | EFFECT_TYPE_QUICK_F))
v |= EFFECT_TYPE_FIELD;
if(v & EFFECT_TYPE_ACTIVATE)
peffect->range = LOCATION_SZONE + LOCATION_FZONE + LOCATION_HAND; peffect->range = LOCATION_SZONE + LOCATION_FZONE + LOCATION_HAND;
if(v & EFFECT_TYPE_FLIP) { }
else if(v & EFFECT_TYPE_FLIP) {
peffect->code = EVENT_FLIP; peffect->code = EVENT_FLIP;
if(!(v & EFFECT_TYPE_TRIGGER_O)) if (v & EFFECT_TYPE_TRIGGER_O) {
v |= EFFECT_TYPE_TRIGGER_F; v = EFFECT_TYPE_SINGLE | EFFECT_TYPE_FLIP | EFFECT_TYPE_TRIGGER_O;
peffect->flag[0] |= EFFECT_FLAG_DELAY;
}
else {
v = EFFECT_TYPE_SINGLE | EFFECT_TYPE_FLIP | EFFECT_TYPE_TRIGGER_F;
} }
}
else if (v & (EFFECT_TYPE_IGNITION | EFFECT_TYPE_QUICK_O | EFFECT_TYPE_QUICK_F)) {
v |= EFFECT_TYPE_FIELD;
}
if (v & (EFFECT_TYPES_CHAIN_LINK | EFFECT_TYPE_CONTINUOUS))
v |= EFFECT_TYPE_ACTIONS;
else
v &= ~EFFECT_TYPE_ACTIONS;
peffect->type = v; peffect->type = v;
return 0; return 0;
} }
int32 scriptlib::effect_set_property(lua_State *L) { int32_t scriptlib::effect_set_property(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 v1 = (uint32)lua_tointeger(L, 2); uint64_t v1 = lua_tointeger(L, 2);
uint32 v2 = (uint32)lua_tointeger(L, 3); uint64_t v2 = lua_tointeger(L, 3);
peffect->flag[0] = (peffect->flag[0] & 0x4f) | (v1 & ~0x4f); peffect->flag[0] = (peffect->flag[0] & INTERNAL_FLAGS) | (v1 & ~INTERNAL_FLAGS);
peffect->flag[1] = v2; peffect->flag[1] = v2;
return 0; return 0;
} }
int32 scriptlib::effect_set_label(lua_State *L) { int32_t scriptlib::effect_set_label(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
peffect->label.clear(); peffect->label.clear();
for(int32 i = 2; i <= lua_gettop(L); ++i) { for(int32_t i = 2; i <= lua_gettop(L); ++i) {
uint32 v = (uint32)lua_tointeger(L, i); peffect->label.push_back(lua_tointeger(L, i));
peffect->label.push_back(v);
} }
return 0; return 0;
} }
int32 scriptlib::effect_set_label_object(lua_State *L) { int32_t scriptlib::effect_set_label_object(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
if(lua_isnil(L, 2)) { if(lua_isnil(L, 2)) {
peffect->label_object = 0; peffect->label_object = 0;
peffect->object_type = PARAM_TYPE_INT;
return 0; return 0;
} }
if(check_param(L, PARAM_TYPE_CARD, 2, TRUE)) { if(check_param(L, PARAM_TYPE_CARD, 2, TRUE)) {
card* p = *(card**)lua_touserdata(L, 2); card* p = *(card**)lua_touserdata(L, 2);
peffect->label_object = p->ref_handle; peffect->label_object = p->ref_handle;
peffect->object_type = PARAM_TYPE_CARD;
} else if(check_param(L, PARAM_TYPE_EFFECT, 2, TRUE)) { } else if(check_param(L, PARAM_TYPE_EFFECT, 2, TRUE)) {
effect* p = *(effect**)lua_touserdata(L, 2); effect* p = *(effect**)lua_touserdata(L, 2);
peffect->label_object = p->ref_handle; peffect->label_object = p->ref_handle;
peffect->object_type = PARAM_TYPE_EFFECT;
} else if(check_param(L, PARAM_TYPE_GROUP, 2, TRUE)) { } else if(check_param(L, PARAM_TYPE_GROUP, 2, TRUE)) {
group* p = *(group**)lua_touserdata(L, 2); group* p = *(group**)lua_touserdata(L, 2);
peffect->label_object = p->ref_handle; peffect->label_object = p->ref_handle;
peffect->object_type = PARAM_TYPE_GROUP;
} else } else
return luaL_error(L, "Parameter 2 should be \"Card\" or \"Effect\" or \"Group\"."); return luaL_error(L, "Parameter 2 should be \"Card\" or \"Effect\" or \"Group\".");
return 0; return 0;
} }
int32 scriptlib::effect_set_category(lua_State *L) { int32_t scriptlib::effect_set_category(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 v = (uint32)lua_tointeger(L, 2); uint32_t v = (uint32_t)lua_tointeger(L, 2);
peffect->category = v; peffect->category = v;
return 0; return 0;
} }
int32 scriptlib::effect_set_hint_timing(lua_State *L) { int32_t scriptlib::effect_set_hint_timing(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 vs = (uint32)lua_tointeger(L, 2); uint32_t vs = (uint32_t)lua_tointeger(L, 2);
uint32 vo = vs; uint32_t vo = vs;
if(lua_gettop(L) >= 3) if(lua_gettop(L) >= 3)
vo = (uint32)lua_tointeger(L, 3); vo = (uint32_t)lua_tointeger(L, 3);
peffect->hint_timing[0] = vs; peffect->hint_timing[0] = vs;
peffect->hint_timing[1] = vo; peffect->hint_timing[1] = vo;
return 0; return 0;
} }
int32 scriptlib::effect_set_condition(lua_State *L) { int32_t scriptlib::effect_set_condition(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2); check_param(L, PARAM_TYPE_FUNCTION, 2);
...@@ -233,7 +297,7 @@ int32 scriptlib::effect_set_condition(lua_State *L) { ...@@ -233,7 +297,7 @@ int32 scriptlib::effect_set_condition(lua_State *L) {
peffect->condition = interpreter::get_function_handle(L, 2); peffect->condition = interpreter::get_function_handle(L, 2);
return 0; return 0;
} }
int32 scriptlib::effect_set_target(lua_State *L) { int32_t scriptlib::effect_set_target(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2); check_param(L, PARAM_TYPE_FUNCTION, 2);
...@@ -243,7 +307,7 @@ int32 scriptlib::effect_set_target(lua_State *L) { ...@@ -243,7 +307,7 @@ int32 scriptlib::effect_set_target(lua_State *L) {
peffect->target = interpreter::get_function_handle(L, 2); peffect->target = interpreter::get_function_handle(L, 2);
return 0; return 0;
} }
int32 scriptlib::effect_set_cost(lua_State *L) { int32_t scriptlib::effect_set_cost(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2); check_param(L, PARAM_TYPE_FUNCTION, 2);
...@@ -253,7 +317,7 @@ int32 scriptlib::effect_set_cost(lua_State *L) { ...@@ -253,7 +317,7 @@ int32 scriptlib::effect_set_cost(lua_State *L) {
peffect->cost = interpreter::get_function_handle(L, 2); peffect->cost = interpreter::get_function_handle(L, 2);
return 0; return 0;
} }
int32 scriptlib::effect_set_value(lua_State *L) { int32_t scriptlib::effect_set_value(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
...@@ -267,13 +331,13 @@ int32 scriptlib::effect_set_value(lua_State *L) { ...@@ -267,13 +331,13 @@ int32 scriptlib::effect_set_value(lua_State *L) {
if(lua_isboolean(L, 2)) if(lua_isboolean(L, 2))
peffect->value = lua_toboolean(L, 2); peffect->value = lua_toboolean(L, 2);
else if(lua_isinteger(L, 2)) else if(lua_isinteger(L, 2))
peffect->value = (int32)lua_tointeger(L, 2); peffect->value = (int32_t)lua_tointeger(L, 2);
else else
peffect->value = (int32)lua_tonumber(L, 2); peffect->value = (int32_t)lua_tonumber(L, 2);
} }
return 0; return 0;
} }
int32 scriptlib::effect_set_operation(lua_State *L) { int32_t scriptlib::effect_set_operation(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
...@@ -286,47 +350,26 @@ int32 scriptlib::effect_set_operation(lua_State *L) { ...@@ -286,47 +350,26 @@ int32 scriptlib::effect_set_operation(lua_State *L) {
peffect->operation = 0; peffect->operation = 0;
return 0; return 0;
} }
int32 scriptlib::effect_set_owner_player(lua_State *L) { int32_t scriptlib::effect_set_owner_player(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 p = (uint32)lua_tointeger(L, 2); int32_t p = (int32_t)lua_tointeger(L, 2);
if(p != 0 && p != 1) if(p != 0 && p != 1)
return 0; return 0;
peffect->effect_owner = p; peffect->effect_owner = p;
return 0; return 0;
} }
int32 scriptlib::effect_get_description(lua_State *L) { int32_t scriptlib::effect_get_description(lua_State *L) {
check_param_count(L, 1); return get_effect_property(L, MEMBER_DESCRIPTION);
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
if (peffect) {
lua_pushinteger(L, peffect->description);
return 1;
}
return 0;
} }
int32 scriptlib::effect_get_code(lua_State *L) { int32_t scriptlib::effect_get_code(lua_State *L) {
check_param_count(L, 1); return get_effect_property(L, MEMBER_CODE);
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
if (peffect) {
lua_pushinteger(L, peffect->code);
return 1;
}
return 0;
} }
int32 scriptlib::effect_get_type(lua_State *L) { int32_t scriptlib::effect_get_type(lua_State *L) {
check_param_count(L, 1); return get_effect_property(L, MEMBER_TYPE);
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
if (peffect) {
lua_pushinteger(L, peffect->type);
return 1;
}
return 0;
} }
int32 scriptlib::effect_get_property(lua_State *L) { int32_t scriptlib::effect_get_property(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
...@@ -337,7 +380,7 @@ int32 scriptlib::effect_get_property(lua_State *L) { ...@@ -337,7 +380,7 @@ int32 scriptlib::effect_get_property(lua_State *L) {
} }
return 0; return 0;
} }
int32 scriptlib::effect_get_label(lua_State *L) { int32_t scriptlib::effect_get_label(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
...@@ -348,11 +391,11 @@ int32 scriptlib::effect_get_label(lua_State *L) { ...@@ -348,11 +391,11 @@ int32 scriptlib::effect_get_label(lua_State *L) {
} }
for(const auto& lab : peffect->label) for(const auto& lab : peffect->label)
lua_pushinteger(L, lab); lua_pushinteger(L, lab);
return (int32)peffect->label.size(); return (int32_t)peffect->label.size();
} }
return 0; return 0;
} }
int32 scriptlib::effect_get_label_object(lua_State *L) { int32_t scriptlib::effect_get_label_object(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
...@@ -369,141 +412,124 @@ int32 scriptlib::effect_get_label_object(lua_State *L) { ...@@ -369,141 +412,124 @@ int32 scriptlib::effect_get_label_object(lua_State *L) {
return 1; return 1;
} }
} }
int32 scriptlib::effect_get_category(lua_State *L) { int32_t scriptlib::effect_get_category(lua_State *L) {
check_param_count(L, 1); return get_effect_property(L, MEMBER_CATEGORY);
check_param(L, PARAM_TYPE_EFFECT, 1); }
effect* peffect = *(effect**) lua_touserdata(L, 1); int32_t scriptlib::effect_get_range(lua_State* L) {
if (peffect) { return get_effect_property(L, MEMBER_RANGE);
lua_pushinteger(L, peffect->category);
return 1;
}
return 0;
} }
int32 scriptlib::effect_get_owner(lua_State *L) { int32_t scriptlib::effect_get_owner(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
interpreter::card2value(L, peffect->get_owner()); interpreter::card2value(L, peffect->get_owner());
return 1; return 1;
} }
int32 scriptlib::effect_get_handler(lua_State *L) { int32_t scriptlib::effect_get_handler(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
interpreter::card2value(L, peffect->get_handler()); interpreter::card2value(L, peffect->get_handler());
return 1; return 1;
} }
int32 scriptlib::effect_get_owner_player(lua_State *L) { int32_t scriptlib::effect_get_owner_player(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
lua_pushinteger(L, peffect->get_owner_player()); lua_pushinteger(L, peffect->get_owner_player());
return 1; return 1;
} }
int32 scriptlib::effect_get_handler_player(lua_State *L) { int32_t scriptlib::effect_get_handler_player(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
lua_pushinteger(L, peffect->get_handler_player()); lua_pushinteger(L, peffect->get_handler_player());
return 1; return 1;
} }
int32 scriptlib::effect_get_condition(lua_State *L) { int32_t scriptlib::effect_get_condition(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
interpreter::function2value(L, peffect->condition); interpreter::function2value(L, peffect->condition);
return 1; return 1;
} }
int32 scriptlib::effect_get_target(lua_State *L) { int32_t scriptlib::effect_get_target(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
interpreter::function2value(L, peffect->target); interpreter::function2value(L, peffect->target);
return 1; return 1;
} }
int32 scriptlib::effect_get_cost(lua_State *L) { int32_t scriptlib::effect_get_cost(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
interpreter::function2value(L, peffect->cost); interpreter::function2value(L, peffect->cost);
return 1; return 1;
} }
int32 scriptlib::effect_get_value(lua_State *L) { int32_t scriptlib::effect_get_value(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
if(peffect->is_flag(EFFECT_FLAG_FUNC_VALUE)) if(peffect->is_flag(EFFECT_FLAG_FUNC_VALUE))
interpreter::function2value(L, peffect->value); interpreter::function2value(L, peffect->value);
else else
lua_pushinteger(L, (int32)peffect->value); lua_pushinteger(L, (int32_t)peffect->value);
return 1; return 1;
} }
int32 scriptlib::effect_get_operation(lua_State *L) { int32_t scriptlib::effect_get_operation(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
interpreter::function2value(L, peffect->operation); interpreter::function2value(L, peffect->operation);
return 1; return 1;
} }
int32 scriptlib::effect_get_active_type(lua_State *L) { int32_t scriptlib::effect_get_active_type(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
lua_pushinteger(L, peffect->get_active_type()); lua_pushinteger(L, peffect->get_active_type());
return 1; return 1;
} }
int32 scriptlib::effect_is_active_type(lua_State *L) { int32_t scriptlib::effect_is_active_type(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 type = (uint32)lua_tointeger(L, 2); uint32_t type = (uint32_t)lua_tointeger(L, 2);
if(peffect->get_active_type() & type) if(peffect->get_active_type() & type)
lua_pushboolean(L, 1); lua_pushboolean(L, 1);
else else
lua_pushboolean(L, 0); lua_pushboolean(L, 0);
return 1; return 1;
} }
int32 scriptlib::effect_is_has_property(lua_State *L) { int32_t scriptlib::effect_is_has_property(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 tflag1 = (uint32)lua_tointeger(L, 2); uint64_t tflag1 = lua_tointeger(L, 2);
uint32 tflag2 = (uint32)lua_tointeger(L, 3); uint64_t tflag2 = lua_tointeger(L, 3);
if (peffect && (!tflag1 || (peffect->flag[0] & tflag1)) && (!tflag2 || (peffect->flag[1] & tflag2))) if (peffect && (!tflag1 || (peffect->flag[0] & tflag1)) && (!tflag2 || (peffect->flag[1] & tflag2)))
lua_pushboolean(L, 1); lua_pushboolean(L, 1);
else else
lua_pushboolean(L, 0); lua_pushboolean(L, 0);
return 1; return 1;
} }
int32 scriptlib::effect_is_has_category(lua_State *L) { int32_t scriptlib::effect_is_has_category(lua_State *L) {
check_param_count(L, 2); return is_effect_has_property(L, MEMBER_CATEGORY);
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 tcate = (uint32)lua_tointeger(L, 2);
if (peffect && (peffect->category & tcate))
lua_pushboolean(L, 1);
else
lua_pushboolean(L, 0);
return 1;
} }
int32 scriptlib::effect_is_has_type(lua_State *L) { int32_t scriptlib::effect_is_has_type(lua_State *L) {
check_param_count(L, 2); return is_effect_has_property(L, MEMBER_TYPE);
check_param(L, PARAM_TYPE_EFFECT, 1); }
effect* peffect = *(effect**) lua_touserdata(L, 1); int32_t scriptlib::effect_is_has_range(lua_State* L) {
uint32 ttype = (uint32)lua_tointeger(L, 2); return is_effect_has_property(L, MEMBER_RANGE);
if (peffect && (peffect->type & ttype))
lua_pushboolean(L, 1);
else
lua_pushboolean(L, 0);
return 1;
} }
int32 scriptlib::effect_is_activatable(lua_State *L) { int32_t scriptlib::effect_is_activatable(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
uint32 playerid = (uint32)lua_tointeger(L, 2); int32_t playerid = (int32_t)lua_tointeger(L, 2);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 neglect_loc = 0; uint32_t neglect_loc = 0;
uint32 neglect_target = 0; uint32_t neglect_target = 0;
if(lua_gettop(L) > 2) { if(lua_gettop(L) > 2) {
neglect_loc = lua_toboolean(L, 3); neglect_loc = lua_toboolean(L, 3);
if (lua_gettop(L) > 3) if (lua_gettop(L) > 3)
...@@ -512,67 +538,67 @@ int32 scriptlib::effect_is_activatable(lua_State *L) { ...@@ -512,67 +538,67 @@ int32 scriptlib::effect_is_activatable(lua_State *L) {
lua_pushboolean(L, peffect->is_activateable(playerid, peffect->pduel->game_field->nil_event, 0, 0, neglect_target, neglect_loc)); lua_pushboolean(L, peffect->is_activateable(playerid, peffect->pduel->game_field->nil_event, 0, 0, neglect_target, neglect_loc));
return 1; return 1;
} }
int32 scriptlib::effect_is_activated(lua_State *L) { int32_t scriptlib::effect_is_activated(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
lua_pushboolean(L, (peffect->type & 0x7f0)); lua_pushboolean(L, (peffect->type & EFFECT_TYPES_CHAIN_LINK));
return 1; return 1;
} }
int32 scriptlib::effect_is_cost_checked(lua_State *L) { int32_t scriptlib::effect_is_cost_checked(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**)lua_touserdata(L, 1); effect* peffect = *(effect**)lua_touserdata(L, 1);
lua_pushboolean(L, peffect->cost_checked); lua_pushboolean(L, peffect->cost_checked);
return 1; return 1;
} }
int32 scriptlib::effect_set_cost_check(lua_State *L) { int32_t scriptlib::effect_set_cost_check(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint8 cost_check = lua_toboolean(L, 2); uint8_t cost_check = lua_toboolean(L, 2);
peffect->cost_checked = cost_check; peffect->cost_checked = cost_check;
return 0; return 0;
} }
int32 scriptlib::effect_get_activate_location(lua_State *L) { int32_t scriptlib::effect_get_activate_location(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
lua_pushinteger(L, peffect->active_location); lua_pushinteger(L, peffect->active_location);
return 1; return 1;
} }
int32 scriptlib::effect_get_activate_sequence(lua_State *L) { int32_t scriptlib::effect_get_activate_sequence(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
lua_pushinteger(L, peffect->active_sequence); lua_pushinteger(L, peffect->active_sequence);
return 1; return 1;
} }
int32 scriptlib::effect_check_count_limit(lua_State *L) { int32_t scriptlib::effect_check_count_limit(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 p = (uint32)lua_tointeger(L, 2); int32_t p = (int32_t)lua_tointeger(L, 2);
lua_pushboolean(L, peffect->check_count_limit(p)); lua_pushboolean(L, peffect->check_count_limit(p));
return 1; return 1;
} }
int32 scriptlib::effect_use_count_limit(lua_State *L) { int32_t scriptlib::effect_use_count_limit(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 p = (uint32)lua_tointeger(L, 2); int32_t p = (int32_t)lua_tointeger(L, 2);
uint32 count = 1; int32_t count = 1;
uint32 oath_only = 0; int32_t oath_only = 0;
uint32 code = peffect->count_code; uint32_t code = peffect->count_code;
if(lua_gettop(L) > 2) { if(lua_gettop(L) > 2) {
count = (uint32)lua_tointeger(L, 3); count = (int32_t)lua_tointeger(L, 3);
if (lua_gettop(L) > 3) if (lua_gettop(L) > 3)
oath_only = lua_toboolean(L, 4); oath_only = lua_toboolean(L, 4);
} }
if (!oath_only || code & EFFECT_COUNT_CODE_OATH) if (!oath_only || code & EFFECT_COUNT_CODE_OATH)
while(count) { while(count) {
peffect->dec_count(p); peffect->dec_count(p);
count--; --count;
} }
return 0; return 0;
} }
...@@ -609,6 +635,7 @@ static const struct luaL_Reg effectlib[] = { ...@@ -609,6 +635,7 @@ static const struct luaL_Reg effectlib[] = {
{ "GetLabel", scriptlib::effect_get_label }, { "GetLabel", scriptlib::effect_get_label },
{ "GetLabelObject", scriptlib::effect_get_label_object }, { "GetLabelObject", scriptlib::effect_get_label_object },
{ "GetCategory", scriptlib::effect_get_category }, { "GetCategory", scriptlib::effect_get_category },
{ "GetRange", scriptlib::effect_get_range },
{ "GetOwner", scriptlib::effect_get_owner }, { "GetOwner", scriptlib::effect_get_owner },
{ "GetHandler", scriptlib::effect_get_handler }, { "GetHandler", scriptlib::effect_get_handler },
{ "GetCondition", scriptlib::effect_get_condition }, { "GetCondition", scriptlib::effect_get_condition },
...@@ -623,6 +650,7 @@ static const struct luaL_Reg effectlib[] = { ...@@ -623,6 +650,7 @@ static const struct luaL_Reg effectlib[] = {
{ "IsHasProperty", scriptlib::effect_is_has_property }, { "IsHasProperty", scriptlib::effect_is_has_property },
{ "IsHasCategory", scriptlib::effect_is_has_category }, { "IsHasCategory", scriptlib::effect_is_has_category },
{ "IsHasType", scriptlib::effect_is_has_type }, { "IsHasType", scriptlib::effect_is_has_type },
{ "IsHasRange", scriptlib::effect_is_has_range },
{ "IsActivatable", scriptlib::effect_is_activatable }, { "IsActivatable", scriptlib::effect_is_activatable },
{ "IsActivated", scriptlib::effect_is_activated }, { "IsActivated", scriptlib::effect_is_activated },
{ "IsCostChecked", scriptlib::effect_is_cost_checked }, { "IsCostChecked", scriptlib::effect_is_cost_checked },
...@@ -631,7 +659,7 @@ static const struct luaL_Reg effectlib[] = { ...@@ -631,7 +659,7 @@ static const struct luaL_Reg effectlib[] = {
{ "GetActivateSequence", scriptlib::effect_get_activate_sequence }, { "GetActivateSequence", scriptlib::effect_get_activate_sequence },
{ "CheckCountLimit", scriptlib::effect_check_count_limit }, { "CheckCountLimit", scriptlib::effect_check_count_limit },
{ "UseCountLimit", scriptlib::effect_use_count_limit }, { "UseCountLimit", scriptlib::effect_use_count_limit },
{ NULL, NULL } { nullptr, nullptr }
}; };
void scriptlib::open_effectlib(lua_State *L) { void scriptlib::open_effectlib(lua_State *L) {
luaL_newlib(L, effectlib); luaL_newlib(L, effectlib);
......
...@@ -11,13 +11,13 @@ ...@@ -11,13 +11,13 @@
#include "effect.h" #include "effect.h"
#include "duel.h" #include "duel.h"
int32 scriptlib::group_new(lua_State *L) { int32_t scriptlib::group_new(lua_State *L) {
duel* pduel = interpreter::get_duel_info(L); duel* pduel = interpreter::get_duel_info(L);
group* pgroup = pduel->new_group(); group* pgroup = pduel->new_group();
interpreter::group2value(L, pgroup); interpreter::group2value(L, pgroup);
return 1; return 1;
} }
int32 scriptlib::group_clone(lua_State *L) { int32_t scriptlib::group_clone(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
...@@ -26,10 +26,10 @@ int32 scriptlib::group_clone(lua_State *L) { ...@@ -26,10 +26,10 @@ int32 scriptlib::group_clone(lua_State *L) {
interpreter::group2value(L, newgroup); interpreter::group2value(L, newgroup);
return 1; return 1;
} }
int32 scriptlib::group_from_cards(lua_State *L) { int32_t scriptlib::group_from_cards(lua_State *L) {
duel* pduel = interpreter::get_duel_info(L); duel* pduel = interpreter::get_duel_info(L);
group* pgroup = pduel->new_group(); group* pgroup = pduel->new_group();
for(int32 i = 0; i < lua_gettop(L); ++i) { for(int32_t i = 0; i < lua_gettop(L); ++i) {
if(!lua_isnil(L, i + 1)) { if(!lua_isnil(L, i + 1)) {
check_param(L, PARAM_TYPE_CARD, i + 1); check_param(L, PARAM_TYPE_CARD, i + 1);
card* pcard = *(card**) lua_touserdata(L, i + 1); card* pcard = *(card**) lua_touserdata(L, i + 1);
...@@ -39,63 +39,70 @@ int32 scriptlib::group_from_cards(lua_State *L) { ...@@ -39,63 +39,70 @@ int32 scriptlib::group_from_cards(lua_State *L) {
interpreter::group2value(L, pgroup); interpreter::group2value(L, pgroup);
return 1; return 1;
} }
int32 scriptlib::group_delete(lua_State *L) { int32_t scriptlib::group_delete(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
duel* pduel = interpreter::get_duel_info(L); duel* pduel = interpreter::get_duel_info(L);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
if(pgroup->is_readonly != 2) if(pgroup->is_readonly != GTYPE_KEEP_ALIVE)
return 0; return 0;
pgroup->is_readonly = 0; pgroup->is_iterator_dirty = true;
pgroup->is_readonly = GTYPE_DEFAULT;
pduel->sgroups.insert(pgroup); pduel->sgroups.insert(pgroup);
return 0; return 0;
} }
int32 scriptlib::group_keep_alive(lua_State *L) { int32_t scriptlib::group_keep_alive(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
duel* pduel = interpreter::get_duel_info(L); duel* pduel = interpreter::get_duel_info(L);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
if(pgroup->is_readonly == 1) if(pgroup->is_readonly == GTYPE_READ_ONLY)
return 0; return 0;
pgroup->is_readonly = 2; pgroup->is_readonly = GTYPE_KEEP_ALIVE;
pduel->sgroups.erase(pgroup); pduel->sgroups.erase(pgroup);
return 0; return 0;
} }
int32 scriptlib::group_clear(lua_State *L) { int32_t scriptlib::group_clear(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
if (pgroup->is_readonly != 1) { if (pgroup->is_readonly != GTYPE_READ_ONLY) {
pgroup->is_iterator_dirty = true;
pgroup->container.clear(); pgroup->container.clear();
} }
return 0; return 0;
} }
int32 scriptlib::group_add_card(lua_State *L) { int32_t scriptlib::group_add_card(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_CARD, 2); check_param(L, PARAM_TYPE_CARD, 2);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
card* pcard = *(card**) lua_touserdata(L, 2); card* pcard = *(card**) lua_touserdata(L, 2);
if (pgroup->is_readonly != 1) { if (pgroup->is_readonly != GTYPE_READ_ONLY) {
pgroup->is_iterator_dirty = true;
pgroup->container.insert(pcard); pgroup->container.insert(pcard);
} }
return 0; return 0;
} }
int32 scriptlib::group_remove_card(lua_State *L) { int32_t scriptlib::group_remove_card(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_CARD, 2); check_param(L, PARAM_TYPE_CARD, 2);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
card* pcard = *(card**) lua_touserdata(L, 2); card* pcard = *(card**) lua_touserdata(L, 2);
if (pgroup->is_readonly != 1) { if (pgroup->is_readonly != GTYPE_READ_ONLY) {
pgroup->is_iterator_dirty = true;
pgroup->container.erase(pcard); pgroup->container.erase(pcard);
} }
return 0; return 0;
} }
int32 scriptlib::group_get_next(lua_State *L) { int32_t scriptlib::group_get_next(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
if (pgroup->is_iterator_dirty) {
return luaL_error(L, "Called Group.GetNext without calling Group.GetFirst first.");
}
if(pgroup->it == pgroup->container.end()) if(pgroup->it == pgroup->container.end())
lua_pushnil(L); lua_pushnil(L);
else { else {
...@@ -107,10 +114,11 @@ int32 scriptlib::group_get_next(lua_State *L) { ...@@ -107,10 +114,11 @@ int32 scriptlib::group_get_next(lua_State *L) {
} }
return 1; return 1;
} }
int32 scriptlib::group_get_first(lua_State *L) { int32_t scriptlib::group_get_first(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
pgroup->is_iterator_dirty = false;
if (pgroup->container.size()) { if (pgroup->container.size()) {
pgroup->it = pgroup->container.begin(); pgroup->it = pgroup->container.begin();
interpreter::card2value(L, (*(pgroup->it))); interpreter::card2value(L, (*(pgroup->it)));
...@@ -118,35 +126,19 @@ int32 scriptlib::group_get_first(lua_State *L) { ...@@ -118,35 +126,19 @@ int32 scriptlib::group_get_first(lua_State *L) {
lua_pushnil(L); lua_pushnil(L);
return 1; return 1;
} }
int32 scriptlib::group_get_count(lua_State *L) { int32_t scriptlib::group_get_count(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
lua_pushinteger(L, pgroup->container.size()); lua_pushinteger(L, pgroup->container.size());
return 1; return 1;
} }
int32 scriptlib::group_for_each(lua_State *L) { int32_t scriptlib::group_filter(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
duel* pduel = interpreter::get_duel_info(L);
group* pgroup = *(group**) lua_touserdata(L, 1);
int32 f = interpreter::get_function_handle(L, 2);
int32 extraargs = lua_gettop(L) - 2;
for (auto& pcard : pgroup->container) {
pduel->lua->add_param(pcard, PARAM_TYPE_CARD);
for(int32 i = 0; i < extraargs; ++i)
pduel->lua->add_param(-extraargs + i, PARAM_TYPE_INDEX);
pduel->lua->call_function(f, 1 + extraargs, 0);
}
return 0;
}
int32 scriptlib::group_filter(lua_State *L) {
check_param_count(L, 3); check_param_count(L, 3);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2); check_param(L, PARAM_TYPE_FUNCTION, 2);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
field::card_set cset(pgroup->container); card_set cset(pgroup->container);
if(check_param(L, PARAM_TYPE_CARD, 3, TRUE)) { if(check_param(L, PARAM_TYPE_CARD, 3, TRUE)) {
card* pexception = *(card**) lua_touserdata(L, 3); card* pexception = *(card**) lua_touserdata(L, 3);
cset.erase(pexception); cset.erase(pexception);
...@@ -157,21 +149,21 @@ int32 scriptlib::group_filter(lua_State *L) { ...@@ -157,21 +149,21 @@ int32 scriptlib::group_filter(lua_State *L) {
} }
duel* pduel = pgroup->pduel; duel* pduel = pgroup->pduel;
group* new_group = pduel->new_group(); group* new_group = pduel->new_group();
uint32 extraargs = lua_gettop(L) - 3; uint32_t extraargs = lua_gettop(L) - 3;
for(auto& pcard : cset) { for(auto& pcard : cset) {
if(pduel->lua->check_matching(pcard, 2, extraargs)) { if(pduel->lua->check_filter(L, pcard, 2, extraargs)) {
new_group->container.insert(pcard); new_group->container.insert(pcard);
} }
} }
interpreter::group2value(L, new_group); interpreter::group2value(L, new_group);
return 1; return 1;
} }
int32 scriptlib::group_filter_count(lua_State *L) { int32_t scriptlib::group_filter_count(lua_State *L) {
check_param_count(L, 3); check_param_count(L, 3);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2); check_param(L, PARAM_TYPE_FUNCTION, 2);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
field::card_set cset(pgroup->container); card_set cset(pgroup->container);
if(check_param(L, PARAM_TYPE_CARD, 3, TRUE)) { if(check_param(L, PARAM_TYPE_CARD, 3, TRUE)) {
card* pexception = *(card**) lua_touserdata(L, 3); card* pexception = *(card**) lua_touserdata(L, 3);
cset.erase(pexception); cset.erase(pexception);
...@@ -181,22 +173,22 @@ int32 scriptlib::group_filter_count(lua_State *L) { ...@@ -181,22 +173,22 @@ int32 scriptlib::group_filter_count(lua_State *L) {
cset.erase(pcard); cset.erase(pcard);
} }
duel* pduel = pgroup->pduel; duel* pduel = pgroup->pduel;
uint32 extraargs = lua_gettop(L) - 3; uint32_t extraargs = lua_gettop(L) - 3;
uint32 count = 0; uint32_t count = 0;
for (auto& pcard : cset) { for (auto& pcard : cset) {
if(pduel->lua->check_matching(pcard, 2, extraargs)) if(pduel->lua->check_filter(L, pcard, 2, extraargs))
count++; ++count;
} }
lua_pushinteger(L, count); lua_pushinteger(L, count);
return 1; return 1;
} }
int32 scriptlib::group_filter_select(lua_State *L) { int32_t scriptlib::group_filter_select(lua_State *L) {
check_action_permission(L); check_action_permission(L);
check_param_count(L, 6); check_param_count(L, 6);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 3); check_param(L, PARAM_TYPE_FUNCTION, 3);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
field::card_set cset(pgroup->container); card_set cset(pgroup->container);
if(check_param(L, PARAM_TYPE_CARD, 6, TRUE)) { if(check_param(L, PARAM_TYPE_CARD, 6, TRUE)) {
card* pexception = *(card**) lua_touserdata(L, 6); card* pexception = *(card**) lua_touserdata(L, 6);
cset.erase(pexception); cset.erase(pexception);
...@@ -206,22 +198,22 @@ int32 scriptlib::group_filter_select(lua_State *L) { ...@@ -206,22 +198,22 @@ int32 scriptlib::group_filter_select(lua_State *L) {
cset.erase(pcard); cset.erase(pcard);
} }
duel* pduel = pgroup->pduel; duel* pduel = pgroup->pduel;
uint32 playerid = (uint32)lua_tointeger(L, 2); int32_t playerid = (int32_t)lua_tointeger(L, 2);
if(playerid != 0 && playerid != 1) if(playerid != 0 && playerid != 1)
return 0; return 0;
uint32 min = (uint32)lua_tointeger(L, 4); uint32_t min = (uint32_t)lua_tointeger(L, 4);
uint32 max = (uint32)lua_tointeger(L, 5); uint32_t max = (uint32_t)lua_tointeger(L, 5);
uint32 extraargs = lua_gettop(L) - 6; uint32_t extraargs = lua_gettop(L) - 6;
pduel->game_field->core.select_cards.clear(); pduel->game_field->core.select_cards.clear();
for (auto& pcard : cset) { for (auto& pcard : cset) {
if(pduel->lua->check_matching(pcard, 3, extraargs)) if(pduel->lua->check_filter(L, pcard, 3, extraargs))
pduel->game_field->core.select_cards.push_back(pcard); pduel->game_field->core.select_cards.push_back(pcard);
} }
pduel->game_field->add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, playerid, min + (max << 16)); pduel->game_field->add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, playerid, min + (max << 16));
return lua_yieldk(L, 0, (lua_KContext)pduel, [](lua_State *L, int32 status, lua_KContext ctx) { return lua_yieldk(L, 0, (lua_KContext)pduel, [](lua_State *L, int32_t status, lua_KContext ctx) {
duel* pduel = (duel*)ctx; duel* pduel = (duel*)ctx;
group* pgroup = pduel->new_group(); group* pgroup = pduel->new_group();
for(int32 i = 0; i < pduel->game_field->returns.bvalue[0]; ++i) { for(int32_t i = 0; i < pduel->game_field->returns.bvalue[0]; ++i) {
card* pcard = pduel->game_field->core.select_cards[pduel->game_field->returns.bvalue[i + 1]]; card* pcard = pduel->game_field->core.select_cards[pduel->game_field->returns.bvalue[i + 1]];
pgroup->container.insert(pcard); pgroup->container.insert(pcard);
} }
...@@ -229,12 +221,12 @@ int32 scriptlib::group_filter_select(lua_State *L) { ...@@ -229,12 +221,12 @@ int32 scriptlib::group_filter_select(lua_State *L) {
return 1; return 1;
}); });
} }
int32 scriptlib::group_select(lua_State *L) { int32_t scriptlib::group_select(lua_State *L) {
check_action_permission(L); check_action_permission(L);
check_param_count(L, 5); check_param_count(L, 5);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
field::card_set cset(pgroup->container); card_set cset(pgroup->container);
if(check_param(L, PARAM_TYPE_CARD, 5, TRUE)) { if(check_param(L, PARAM_TYPE_CARD, 5, TRUE)) {
card* pexception = *(card**) lua_touserdata(L, 5); card* pexception = *(card**) lua_touserdata(L, 5);
cset.erase(pexception); cset.erase(pexception);
...@@ -244,20 +236,20 @@ int32 scriptlib::group_select(lua_State *L) { ...@@ -244,20 +236,20 @@ int32 scriptlib::group_select(lua_State *L) {
cset.erase(pcard); cset.erase(pcard);
} }
duel* pduel = pgroup->pduel; duel* pduel = pgroup->pduel;
uint32 playerid = (uint32)lua_tointeger(L, 2); int32_t playerid = (int32_t)lua_tointeger(L, 2);
if(playerid != 0 && playerid != 1) if(playerid != 0 && playerid != 1)
return 0; return 0;
uint32 min = (uint32)lua_tointeger(L, 3); uint32_t min = (uint32_t)lua_tointeger(L, 3);
uint32 max = (uint32)lua_tointeger(L, 4); uint32_t max = (uint32_t)lua_tointeger(L, 4);
pduel->game_field->core.select_cards.clear(); pduel->game_field->core.select_cards.clear();
for (auto& pcard : cset) { for (auto& pcard : cset) {
pduel->game_field->core.select_cards.push_back(pcard); pduel->game_field->core.select_cards.push_back(pcard);
} }
pduel->game_field->add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, playerid, min + (max << 16)); pduel->game_field->add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, playerid, min + (max << 16));
return lua_yieldk(L, 0, (lua_KContext)pduel, [](lua_State *L, int32 status, lua_KContext ctx) { return lua_yieldk(L, 0, (lua_KContext)pduel, [](lua_State *L, int32_t status, lua_KContext ctx) {
duel* pduel = (duel*)ctx; duel* pduel = (duel*)ctx;
group* pgroup = pduel->new_group(); group* pgroup = pduel->new_group();
for(int32 i = 0; i < pduel->game_field->returns.bvalue[0]; ++i) { for(int32_t i = 0; i < pduel->game_field->returns.bvalue[0]; ++i) {
card* pcard = pduel->game_field->core.select_cards[pduel->game_field->returns.bvalue[i + 1]]; card* pcard = pduel->game_field->core.select_cards[pduel->game_field->returns.bvalue[i + 1]];
pgroup->container.insert(pcard); pgroup->container.insert(pcard);
} }
...@@ -265,16 +257,16 @@ int32 scriptlib::group_select(lua_State *L) { ...@@ -265,16 +257,16 @@ int32 scriptlib::group_select(lua_State *L) {
return 1; return 1;
}); });
} }
int32 scriptlib::group_select_unselect(lua_State *L) { int32_t scriptlib::group_select_unselect(lua_State *L) {
check_action_permission(L); check_action_permission(L);
check_param_count(L, 3); check_param_count(L, 3);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
group* select_group = *(group**)lua_touserdata(L, 1); group* select_group = *(group**)lua_touserdata(L, 1);
group* unselect_group = 0; group* unselect_group = nullptr;
if(check_param(L, PARAM_TYPE_GROUP, 2, TRUE)) if(check_param(L, PARAM_TYPE_GROUP, 2, TRUE))
unselect_group = *(group**)lua_touserdata(L, 2); unselect_group = *(group**)lua_touserdata(L, 2);
duel* pduel = select_group->pduel; duel* pduel = select_group->pduel;
uint32 playerid = (uint32)lua_tointeger(L, 3); int32_t playerid = (int32_t)lua_tointeger(L, 3);
if(playerid != 0 && playerid != 1) if(playerid != 0 && playerid != 1)
return 0; return 0;
if(select_group->container.size() == 0 && (!unselect_group || unselect_group->container.size() == 0)) if(select_group->container.size() == 0 && (!unselect_group || unselect_group->container.size() == 0))
...@@ -289,21 +281,21 @@ int32 scriptlib::group_select_unselect(lua_State *L) { ...@@ -289,21 +281,21 @@ int32 scriptlib::group_select_unselect(lua_State *L) {
} }
} }
} }
uint32 finishable = FALSE; uint32_t finishable = FALSE;
if(lua_gettop(L) > 3) { if(lua_gettop(L) > 3) {
finishable = lua_toboolean(L, 4); finishable = lua_toboolean(L, 4);
} }
uint32 cancelable = FALSE; uint32_t cancelable = FALSE;
if(lua_gettop(L) > 4) { if(lua_gettop(L) > 4) {
cancelable = lua_toboolean(L, 5); cancelable = lua_toboolean(L, 5);
} }
uint32 min = 1; uint32_t min = 1;
if(lua_gettop(L) > 5) { if(lua_gettop(L) > 5) {
min = (uint32)lua_tointeger(L, 6); min = (uint32_t)lua_tointeger(L, 6);
} }
uint32 max = 1; uint32_t max = 1;
if(lua_gettop(L) > 6) { if(lua_gettop(L) > 6) {
max = (uint32)lua_tointeger(L, 7); max = (uint32_t)lua_tointeger(L, 7);
} }
if(min > max) if(min > max)
min = max; min = max;
...@@ -318,31 +310,32 @@ int32 scriptlib::group_select_unselect(lua_State *L) { ...@@ -318,31 +310,32 @@ int32 scriptlib::group_select_unselect(lua_State *L) {
} }
} }
pduel->game_field->add_process(PROCESSOR_SELECT_UNSELECT_CARD, 0, 0, 0, playerid + (cancelable << 16), min + (max << 16), finishable); pduel->game_field->add_process(PROCESSOR_SELECT_UNSELECT_CARD, 0, 0, 0, playerid + (cancelable << 16), min + (max << 16), finishable);
return lua_yieldk(L, 0, (lua_KContext)pduel, [](lua_State *L, int32 status, lua_KContext ctx) { return lua_yieldk(L, 0, (lua_KContext)pduel, [](lua_State *L, int32_t status, lua_KContext ctx) {
duel* pduel = (duel*)ctx; duel* pduel = (duel*)ctx;
if(pduel->game_field->returns.bvalue[0] == -1) { if(pduel->game_field->returns.ivalue[0] == -1) {
lua_pushnil(L); lua_pushnil(L);
} else { } else {
card* pcard; card* pcard;
if((size_t)pduel->game_field->returns.bvalue[1] < pduel->game_field->core.select_cards.size()) const int32_t index = pduel->game_field->returns.bvalue[1];
pcard = pduel->game_field->core.select_cards[pduel->game_field->returns.bvalue[1]]; if(index < (int32_t)pduel->game_field->core.select_cards.size())
pcard = pduel->game_field->core.select_cards[index];
else else
pcard = pduel->game_field->core.unselect_cards[pduel->game_field->returns.bvalue[1] - pduel->game_field->core.select_cards.size()]; pcard = pduel->game_field->core.unselect_cards[index - pduel->game_field->core.select_cards.size()];
interpreter::card2value(L, pcard); interpreter::card2value(L, pcard);
} }
return 1; return 1;
}); });
} }
int32 scriptlib::group_random_select(lua_State *L) { int32_t scriptlib::group_random_select(lua_State *L) {
check_param_count(L, 3); check_param_count(L, 3);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
int32 playerid = (int32)lua_tointeger(L, 2); int32_t playerid = (int32_t)lua_tointeger(L, 2);
uint32 count = (uint32)lua_tointeger(L, 3); uint32_t count = (uint32_t)lua_tointeger(L, 3);
duel* pduel = pgroup->pduel; duel* pduel = pgroup->pduel;
group* newgroup = pduel->new_group(); group* newgroup = pduel->new_group();
if(count > pgroup->container.size()) if(count > pgroup->container.size())
count = (uint32)pgroup->container.size(); count = (uint32_t)pgroup->container.size();
if(count == 0) { if(count == 0) {
interpreter::group2value(L, newgroup); interpreter::group2value(L, newgroup);
return 1; return 1;
...@@ -351,7 +344,7 @@ int32 scriptlib::group_random_select(lua_State *L) { ...@@ -351,7 +344,7 @@ int32 scriptlib::group_random_select(lua_State *L) {
newgroup->container = pgroup->container; newgroup->container = pgroup->container;
else { else {
while(newgroup->container.size() < count) { while(newgroup->container.size() < count) {
int32 i = pduel->get_next_integer(0, (int32)pgroup->container.size() - 1); int32_t i = pduel->get_next_integer(0, (int32_t)pgroup->container.size() - 1);
auto cit = pgroup->container.begin(); auto cit = pgroup->container.begin();
std::advance(cit, i); std::advance(cit, i);
newgroup->container.insert(*cit); newgroup->container.insert(*cit);
...@@ -366,12 +359,52 @@ int32 scriptlib::group_random_select(lua_State *L) { ...@@ -366,12 +359,52 @@ int32 scriptlib::group_random_select(lua_State *L) {
interpreter::group2value(L, newgroup); interpreter::group2value(L, newgroup);
return 1; return 1;
} }
int32 scriptlib::group_is_exists(lua_State *L) { int32_t scriptlib::group_cancelable_select(lua_State *L) {
check_action_permission(L);
check_param_count(L, 5);
check_param(L, PARAM_TYPE_GROUP, 1);
group* pgroup = *(group**) lua_touserdata(L, 1);
card_set cset(pgroup->container);
if(check_param(L, PARAM_TYPE_CARD, 5, TRUE)) {
card* pexception = *(card**) lua_touserdata(L, 5);
cset.erase(pexception);
} else if(check_param(L, PARAM_TYPE_GROUP, 5, TRUE)) {
group* pexgroup = *(group**) lua_touserdata(L, 5);
for(auto& pcard : pexgroup->container)
cset.erase(pcard);
}
duel* pduel = pgroup->pduel;
int32_t playerid = (int32_t)lua_tointeger(L, 2);
if(playerid != 0 && playerid != 1)
return 0;
uint32_t min = (uint32_t)lua_tointeger(L, 3);
uint32_t max = (uint32_t)lua_tointeger(L, 4);
pduel->game_field->core.select_cards.clear();
for (auto& pcard : cset) {
pduel->game_field->core.select_cards.push_back(pcard);
}
pduel->game_field->add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, playerid + 0x10000, min + (max << 16));
return lua_yieldk(L, 0, (lua_KContext)pduel, [](lua_State *L, int32_t status, lua_KContext ctx) {
duel* pduel = (duel*)ctx;
if(pduel->game_field->returns.ivalue[0] == -1) {
lua_pushnil(L);
} else {
group* pgroup = pduel->new_group();
for(int32_t i = 0; i < pduel->game_field->returns.bvalue[0]; ++i) {
card* pcard = pduel->game_field->core.select_cards[pduel->game_field->returns.bvalue[i + 1]];
pgroup->container.insert(pcard);
}
interpreter::group2value(L, pgroup);
}
return 1;
});
}
int32_t scriptlib::group_is_exists(lua_State *L) {
check_param_count(L, 4); check_param_count(L, 4);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2); check_param(L, PARAM_TYPE_FUNCTION, 2);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
field::card_set cset(pgroup->container); card_set cset(pgroup->container);
if(check_param(L, PARAM_TYPE_CARD, 4, TRUE)) { if(check_param(L, PARAM_TYPE_CARD, 4, TRUE)) {
card* pexception = *(card**) lua_touserdata(L, 4); card* pexception = *(card**) lua_touserdata(L, 4);
cset.erase(pexception); cset.erase(pexception);
...@@ -381,13 +414,17 @@ int32 scriptlib::group_is_exists(lua_State *L) { ...@@ -381,13 +414,17 @@ int32 scriptlib::group_is_exists(lua_State *L) {
cset.erase(pcard); cset.erase(pcard);
} }
duel* pduel = pgroup->pduel; duel* pduel = pgroup->pduel;
uint32 count = (uint32)lua_tointeger(L, 3); uint32_t count = (uint32_t)lua_tointeger(L, 3);
uint32 extraargs = lua_gettop(L) - 4; uint32_t extraargs = lua_gettop(L) - 4;
uint32 fcount = 0; uint32_t fcount = 0;
uint32 result = FALSE; uint32_t result = FALSE;
if (count > pgroup->container.size()) {
lua_pushboolean(L, 0);
return 1;
}
for (auto& pcard : cset) { for (auto& pcard : cset) {
if(pduel->lua->check_matching(pcard, 2, extraargs)) { if(pduel->lua->check_filter(L, pcard, 2, extraargs)) {
fcount++; ++fcount;
if(fcount >= count) { if(fcount >= count) {
result = TRUE; result = TRUE;
break; break;
...@@ -397,22 +434,22 @@ int32 scriptlib::group_is_exists(lua_State *L) { ...@@ -397,22 +434,22 @@ int32 scriptlib::group_is_exists(lua_State *L) {
lua_pushboolean(L, result); lua_pushboolean(L, result);
return 1; return 1;
} }
int32 scriptlib::group_check_with_sum_equal(lua_State *L) { int32_t scriptlib::group_check_with_sum_equal(lua_State *L) {
check_param_count(L, 5); check_param_count(L, 5);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2); check_param(L, PARAM_TYPE_FUNCTION, 2);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel; duel* pduel = pgroup->pduel;
int32 acc = (int32)lua_tointeger(L, 3); int32_t acc = (int32_t)lua_tointeger(L, 3);
int32 min = (int32)lua_tointeger(L, 4); int32_t min = (int32_t)lua_tointeger(L, 4);
int32 max = (int32)lua_tointeger(L, 5); int32_t max = (int32_t)lua_tointeger(L, 5);
if(min < 0) if(min < 0)
min = 0; min = 0;
if(max < min) if(max < min)
max = min; max = min;
int32 extraargs = lua_gettop(L) - 5; int32_t extraargs = lua_gettop(L) - 5;
field::card_vector cv(pduel->game_field->core.must_select_cards); card_vector cv(pduel->game_field->core.must_select_cards);
int32 mcount = (int32)cv.size(); int32_t mcount = (int32_t)cv.size();
for(auto& pcard : pgroup->container) { for(auto& pcard : pgroup->container) {
auto it = std::find(pduel->game_field->core.must_select_cards.begin(), pduel->game_field->core.must_select_cards.end(), pcard); auto it = std::find(pduel->game_field->core.must_select_cards.begin(), pduel->game_field->core.must_select_cards.end(), pcard);
if(it == pduel->game_field->core.must_select_cards.end()) if(it == pduel->game_field->core.must_select_cards.end())
...@@ -424,33 +461,33 @@ int32 scriptlib::group_check_with_sum_equal(lua_State *L) { ...@@ -424,33 +461,33 @@ int32 scriptlib::group_check_with_sum_equal(lua_State *L) {
lua_pushboolean(L, field::check_with_sum_limit_m(cv, acc, 0, min, max, 0xffff, mcount)); lua_pushboolean(L, field::check_with_sum_limit_m(cv, acc, 0, min, max, 0xffff, mcount));
return 1; return 1;
} }
int32 scriptlib::group_select_with_sum_equal(lua_State *L) { int32_t scriptlib::group_select_with_sum_equal(lua_State *L) {
check_action_permission(L); check_action_permission(L);
check_param_count(L, 6); check_param_count(L, 6);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 3); check_param(L, PARAM_TYPE_FUNCTION, 3);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel; duel* pduel = pgroup->pduel;
int32 playerid = (int32)lua_tointeger(L, 2); int32_t playerid = (int32_t)lua_tointeger(L, 2);
if(playerid != 0 && playerid != 1) if(playerid != 0 && playerid != 1)
return 0; return 0;
int32 acc = (int32)lua_tointeger(L, 4); int32_t acc = (int32_t)lua_tointeger(L, 4);
int32 min = (int32)lua_tointeger(L, 5); int32_t min = (int32_t)lua_tointeger(L, 5);
int32 max = (int32)lua_tointeger(L, 6); int32_t max = (int32_t)lua_tointeger(L, 6);
if(min < 0) if(min < 0)
min = 0; min = 0;
if(max < min) if(max < min)
max = min; max = min;
if(max > 127) if(max > UINT8_MAX)
return luaL_error(L, "Parameter \"max\" exceeded 127."); return luaL_error(L, "Parameter \"max\" exceeded 255.");
int32 extraargs = lua_gettop(L) - 6; int32_t extraargs = lua_gettop(L) - 6;
pduel->game_field->core.select_cards.assign(pgroup->container.begin(), pgroup->container.end()); pduel->game_field->core.select_cards.assign(pgroup->container.begin(), pgroup->container.end());
for(auto& pcard : pduel->game_field->core.must_select_cards) { 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); auto it = std::remove(pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end(), pcard);
pduel->game_field->core.select_cards.erase(it, pduel->game_field->core.select_cards.end()); pduel->game_field->core.select_cards.erase(it, pduel->game_field->core.select_cards.end());
} }
field::card_vector cv(pduel->game_field->core.must_select_cards); card_vector cv(pduel->game_field->core.must_select_cards);
int32 mcount = (int32)cv.size(); int32_t mcount = (int32_t)cv.size();
cv.insert(cv.end(), pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end()); cv.insert(cv.end(), pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end());
for(auto& pcard : cv) for(auto& pcard : cv)
pcard->sum_param = pduel->lua->get_operation_value(pcard, 3, extraargs); pcard->sum_param = pduel->lua->get_operation_value(pcard, 3, extraargs);
...@@ -460,12 +497,12 @@ int32 scriptlib::group_select_with_sum_equal(lua_State *L) { ...@@ -460,12 +497,12 @@ int32 scriptlib::group_select_with_sum_equal(lua_State *L) {
interpreter::group2value(L, empty_group); interpreter::group2value(L, empty_group);
return 1; return 1;
} }
pduel->game_field->add_process(PROCESSOR_SELECT_SUM, 0, 0, 0, acc, playerid + (min << 16) + (max << 24)); pduel->game_field->add_process(PROCESSOR_SELECT_SUM, 0, 0, 0, acc, playerid, min, max);
return lua_yieldk(L, 0, (lua_KContext)pduel, [](lua_State *L, int32 status, lua_KContext ctx) { return lua_yieldk(L, 0, (lua_KContext)pduel, [](lua_State *L, int32_t status, lua_KContext ctx) {
duel* pduel = (duel*)ctx; duel* pduel = (duel*)ctx;
group* pgroup = pduel->new_group(); group* pgroup = pduel->new_group();
int32 mcount = (int32)pduel->game_field->core.must_select_cards.size(); int32_t mcount = (int32_t)pduel->game_field->core.must_select_cards.size();
for(int32 i = mcount; i < pduel->game_field->returns.bvalue[0]; ++i) { for(int32_t i = mcount; i < pduel->game_field->returns.bvalue[0]; ++i) {
card* pcard = pduel->game_field->core.select_cards[pduel->game_field->returns.bvalue[i + 1]]; card* pcard = pduel->game_field->core.select_cards[pduel->game_field->returns.bvalue[i + 1]];
pgroup->container.insert(pcard); pgroup->container.insert(pcard);
} }
...@@ -474,16 +511,16 @@ int32 scriptlib::group_select_with_sum_equal(lua_State *L) { ...@@ -474,16 +511,16 @@ int32 scriptlib::group_select_with_sum_equal(lua_State *L) {
return 1; return 1;
}); });
} }
int32 scriptlib::group_check_with_sum_greater(lua_State *L) { int32_t scriptlib::group_check_with_sum_greater(lua_State *L) {
check_param_count(L, 3); check_param_count(L, 3);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2); check_param(L, PARAM_TYPE_FUNCTION, 2);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel; duel* pduel = pgroup->pduel;
int32 acc = (int32)lua_tointeger(L, 3); int32_t acc = (int32_t)lua_tointeger(L, 3);
int32 extraargs = lua_gettop(L) - 3; int32_t extraargs = lua_gettop(L) - 3;
field::card_vector cv(pduel->game_field->core.must_select_cards); card_vector cv(pduel->game_field->core.must_select_cards);
int32 mcount = (int32)cv.size(); int32_t mcount = (int32_t)cv.size();
for(auto& pcard : pgroup->container) { for(auto& pcard : pgroup->container) {
auto it = std::find(pduel->game_field->core.must_select_cards.begin(), pduel->game_field->core.must_select_cards.end(), pcard); auto it = std::find(pduel->game_field->core.must_select_cards.begin(), pduel->game_field->core.must_select_cards.end(), pcard);
if(it == pduel->game_field->core.must_select_cards.end()) if(it == pduel->game_field->core.must_select_cards.end())
...@@ -495,25 +532,25 @@ int32 scriptlib::group_check_with_sum_greater(lua_State *L) { ...@@ -495,25 +532,25 @@ int32 scriptlib::group_check_with_sum_greater(lua_State *L) {
lua_pushboolean(L, field::check_with_sum_greater_limit_m(cv, acc, 0, 0xffff, mcount)); lua_pushboolean(L, field::check_with_sum_greater_limit_m(cv, acc, 0, 0xffff, mcount));
return 1; return 1;
} }
int32 scriptlib::group_select_with_sum_greater(lua_State *L) { int32_t scriptlib::group_select_with_sum_greater(lua_State *L) {
check_action_permission(L); check_action_permission(L);
check_param_count(L, 4); check_param_count(L, 4);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 3); check_param(L, PARAM_TYPE_FUNCTION, 3);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel; duel* pduel = pgroup->pduel;
int32 playerid = (int32)lua_tointeger(L, 2); int32_t playerid = (int32_t)lua_tointeger(L, 2);
if(playerid != 0 && playerid != 1) if(playerid != 0 && playerid != 1)
return 0; return 0;
int32 acc = (int32)lua_tointeger(L, 4); int32_t acc = (int32_t)lua_tointeger(L, 4);
int32 extraargs = lua_gettop(L) - 4; int32_t extraargs = lua_gettop(L) - 4;
pduel->game_field->core.select_cards.assign(pgroup->container.begin(), pgroup->container.end()); pduel->game_field->core.select_cards.assign(pgroup->container.begin(), pgroup->container.end());
for(auto& pcard : pduel->game_field->core.must_select_cards) { 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); auto it = std::remove(pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end(), pcard);
pduel->game_field->core.select_cards.erase(it, pduel->game_field->core.select_cards.end()); pduel->game_field->core.select_cards.erase(it, pduel->game_field->core.select_cards.end());
} }
field::card_vector cv(pduel->game_field->core.must_select_cards); card_vector cv(pduel->game_field->core.must_select_cards);
int32 mcount = (int32)cv.size(); int32_t mcount = (int32_t)cv.size();
cv.insert(cv.end(), pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end()); cv.insert(cv.end(), pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end());
for(auto& pcard : cv) for(auto& pcard : cv)
pcard->sum_param = pduel->lua->get_operation_value(pcard, 3, extraargs); pcard->sum_param = pduel->lua->get_operation_value(pcard, 3, extraargs);
...@@ -524,11 +561,11 @@ int32 scriptlib::group_select_with_sum_greater(lua_State *L) { ...@@ -524,11 +561,11 @@ int32 scriptlib::group_select_with_sum_greater(lua_State *L) {
return 1; return 1;
} }
pduel->game_field->add_process(PROCESSOR_SELECT_SUM, 0, 0, 0, acc, playerid); pduel->game_field->add_process(PROCESSOR_SELECT_SUM, 0, 0, 0, acc, playerid);
return lua_yieldk(L, 0, (lua_KContext)pduel, [](lua_State *L, int32 status, lua_KContext ctx) { return lua_yieldk(L, 0, (lua_KContext)pduel, [](lua_State *L, int32_t status, lua_KContext ctx) {
duel* pduel = (duel*)ctx; duel* pduel = (duel*)ctx;
group* pgroup = pduel->new_group(); group* pgroup = pduel->new_group();
int32 mcount = (int32)pduel->game_field->core.must_select_cards.size(); int32_t mcount = (int32_t)pduel->game_field->core.must_select_cards.size();
for(int32 i = mcount; i < pduel->game_field->returns.bvalue[0]; ++i) { for(int32_t i = mcount; i < pduel->game_field->returns.bvalue[0]; ++i) {
card* pcard = pduel->game_field->core.select_cards[pduel->game_field->returns.bvalue[i + 1]]; card* pcard = pduel->game_field->core.select_cards[pduel->game_field->returns.bvalue[i + 1]];
pgroup->container.insert(pcard); pgroup->container.insert(pcard);
} }
...@@ -537,7 +574,7 @@ int32 scriptlib::group_select_with_sum_greater(lua_State *L) { ...@@ -537,7 +574,7 @@ int32 scriptlib::group_select_with_sum_greater(lua_State *L) {
return 1; return 1;
}); });
} }
int32 scriptlib::group_get_min_group(lua_State *L) { int32_t scriptlib::group_get_min_group(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2); check_param(L, PARAM_TYPE_FUNCTION, 2);
...@@ -546,8 +583,8 @@ int32 scriptlib::group_get_min_group(lua_State *L) { ...@@ -546,8 +583,8 @@ int32 scriptlib::group_get_min_group(lua_State *L) {
if(pgroup->container.size() == 0) if(pgroup->container.size() == 0)
return 0; return 0;
group* newgroup = pduel->new_group(); group* newgroup = pduel->new_group();
int32 min, op; int32_t min, op;
int32 extraargs = lua_gettop(L) - 2; int32_t extraargs = lua_gettop(L) - 2;
auto cit = pgroup->container.begin(); auto cit = pgroup->container.begin();
min = pduel->lua->get_operation_value(*cit, 2, extraargs); min = pduel->lua->get_operation_value(*cit, 2, extraargs);
newgroup->container.insert(*cit); newgroup->container.insert(*cit);
...@@ -566,7 +603,7 @@ int32 scriptlib::group_get_min_group(lua_State *L) { ...@@ -566,7 +603,7 @@ int32 scriptlib::group_get_min_group(lua_State *L) {
lua_pushinteger(L, min); lua_pushinteger(L, min);
return 2; return 2;
} }
int32 scriptlib::group_get_max_group(lua_State *L) { int32_t scriptlib::group_get_max_group(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2); check_param(L, PARAM_TYPE_FUNCTION, 2);
...@@ -575,8 +612,8 @@ int32 scriptlib::group_get_max_group(lua_State *L) { ...@@ -575,8 +612,8 @@ int32 scriptlib::group_get_max_group(lua_State *L) {
if(pgroup->container.size() == 0) if(pgroup->container.size() == 0)
return 0; return 0;
group* newgroup = pduel->new_group(); group* newgroup = pduel->new_group();
int32 max, op; int32_t max, op;
int32 extraargs = lua_gettop(L) - 2; int32_t extraargs = lua_gettop(L) - 2;
auto cit = pgroup->container.begin(); auto cit = pgroup->container.begin();
max = pduel->lua->get_operation_value(*cit, 2, extraargs); max = pduel->lua->get_operation_value(*cit, 2, extraargs);
newgroup->container.insert(*cit); newgroup->container.insert(*cit);
...@@ -595,81 +632,85 @@ int32 scriptlib::group_get_max_group(lua_State *L) { ...@@ -595,81 +632,85 @@ int32 scriptlib::group_get_max_group(lua_State *L) {
lua_pushinteger(L, max); lua_pushinteger(L, max);
return 2; return 2;
} }
int32 scriptlib::group_get_sum(lua_State *L) { int32_t scriptlib::group_get_sum(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2); check_param(L, PARAM_TYPE_FUNCTION, 2);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel; duel* pduel = pgroup->pduel;
int32 extraargs = lua_gettop(L) - 2; int32_t extraargs = lua_gettop(L) - 2;
int32 sum = 0; int32_t sum = 0;
for(auto& pcard : pgroup->container) { for(auto& pcard : pgroup->container) {
sum += pduel->lua->get_operation_value(pcard, 2, extraargs); sum += pduel->lua->get_operation_value(pcard, 2, extraargs);
} }
lua_pushinteger(L, sum); lua_pushinteger(L, sum);
return 1; return 1;
} }
int32 scriptlib::group_get_class_count(lua_State *L) { int32_t scriptlib::group_get_class_count(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2); check_param(L, PARAM_TYPE_FUNCTION, 2);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel; duel* pduel = pgroup->pduel;
int32 extraargs = lua_gettop(L) - 2; int32_t extraargs = lua_gettop(L) - 2;
std::set<uint32> er; std::set<uint32_t> er;
for(auto& pcard : pgroup->container) { for(auto& pcard : pgroup->container) {
er.insert(pduel->lua->get_operation_value(pcard, 2, extraargs)); er.insert(pduel->lua->get_operation_value(pcard, 2, extraargs));
} }
lua_pushinteger(L, er.size()); lua_pushinteger(L, er.size());
return 1; return 1;
} }
int32 scriptlib::group_remove(lua_State *L) { int32_t scriptlib::group_remove(lua_State *L) {
check_param_count(L, 3); check_param_count(L, 3);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2); check_param(L, PARAM_TYPE_FUNCTION, 2);
card* pexception = 0; card* pexception = nullptr;
if(!lua_isnil(L, 3)) { if(!lua_isnil(L, 3)) {
check_param(L, PARAM_TYPE_CARD, 3); check_param(L, PARAM_TYPE_CARD, 3);
pexception = *(card**) lua_touserdata(L, 3); pexception = *(card**) lua_touserdata(L, 3);
} }
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel; duel* pduel = pgroup->pduel;
uint32 extraargs = lua_gettop(L) - 3; uint32_t extraargs = lua_gettop(L) - 3;
if(pgroup->is_readonly == 1) if(pgroup->is_readonly == GTYPE_READ_ONLY)
return 0; return 0;
pgroup->is_iterator_dirty = true;
for (auto cit = pgroup->container.begin(); cit != pgroup->container.end();) { for (auto cit = pgroup->container.begin(); cit != pgroup->container.end();) {
auto rm = cit++; if((*cit) != pexception && pduel->lua->check_filter(L, *cit, 2, extraargs)) {
if((*rm) != pexception && pduel->lua->check_matching(*rm, 2, extraargs)) { cit = pgroup->container.erase(cit);
pgroup->container.erase(rm);
} }
else
++cit;
} }
return 0; return 0;
} }
int32 scriptlib::group_merge(lua_State *L) { int32_t scriptlib::group_merge(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_GROUP, 2); check_param(L, PARAM_TYPE_GROUP, 2);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
group* mgroup = *(group**) lua_touserdata(L, 2); group* mgroup = *(group**) lua_touserdata(L, 2);
if(pgroup->is_readonly == 1) if(pgroup->is_readonly == GTYPE_READ_ONLY)
return 0; return 0;
pgroup->is_iterator_dirty = true;
pgroup->container.insert(mgroup->container.begin(), mgroup->container.end()); pgroup->container.insert(mgroup->container.begin(), mgroup->container.end());
return 0; return 0;
} }
int32 scriptlib::group_sub(lua_State *L) { int32_t scriptlib::group_sub(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_GROUP, 2); check_param(L, PARAM_TYPE_GROUP, 2);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
group* sgroup = *(group**) lua_touserdata(L, 2); group* sgroup = *(group**) lua_touserdata(L, 2);
if(pgroup->is_readonly == 1) if(pgroup->is_readonly == GTYPE_READ_ONLY)
return 0; return 0;
pgroup->is_iterator_dirty = true;
for (auto& pcard : sgroup->container) { for (auto& pcard : sgroup->container) {
pgroup->container.erase(pcard); pgroup->container.erase(pcard);
} }
return 0; return 0;
} }
int32 scriptlib::group_equal(lua_State *L) { int32_t scriptlib::group_equal(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_GROUP, 2); check_param(L, PARAM_TYPE_GROUP, 2);
...@@ -690,7 +731,7 @@ int32 scriptlib::group_equal(lua_State *L) { ...@@ -690,7 +731,7 @@ int32 scriptlib::group_equal(lua_State *L) {
lua_pushboolean(L, 1); lua_pushboolean(L, 1);
return 1; return 1;
} }
int32 scriptlib::group_is_contains(lua_State *L) { int32_t scriptlib::group_is_contains(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_CARD, 2); check_param(L, PARAM_TYPE_CARD, 2);
...@@ -702,40 +743,41 @@ int32 scriptlib::group_is_contains(lua_State *L) { ...@@ -702,40 +743,41 @@ int32 scriptlib::group_is_contains(lua_State *L) {
lua_pushboolean(L, 0); lua_pushboolean(L, 0);
return 1; return 1;
} }
int32 scriptlib::group_search_card(lua_State *L) { int32_t scriptlib::group_search_card(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2); check_param(L, PARAM_TYPE_FUNCTION, 2);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel; duel* pduel = pgroup->pduel;
uint32 extraargs = lua_gettop(L) - 2; uint32_t extraargs = lua_gettop(L) - 2;
for(auto& pcard : pgroup->container) for (auto& pcard : pgroup->container) {
if(pduel->lua->check_matching(pcard, 2, extraargs)) { if (pduel->lua->check_filter(L, pcard, 2, extraargs)) {
interpreter::card2value(L, pcard); interpreter::card2value(L, pcard);
return 1; return 1;
} }
}
return 0; return 0;
} }
int32 scriptlib::group_get_bin_class_count(lua_State *L) { int32_t scriptlib::group_get_bin_class_count(lua_State *L) {
check_param_count(L, 2); check_param_count(L, 2);
check_param(L, PARAM_TYPE_GROUP, 1); check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2); check_param(L, PARAM_TYPE_FUNCTION, 2);
group* pgroup = *(group**) lua_touserdata(L, 1); group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel; duel* pduel = pgroup->pduel;
int32 extraargs = lua_gettop(L) - 2; int32_t extraargs = lua_gettop(L) - 2;
int32 er = 0; int32_t er = 0;
for(auto& pcard : pgroup->container) { for(auto& pcard : pgroup->container) {
er |= pduel->lua->get_operation_value(pcard, 2, extraargs); er |= pduel->lua->get_operation_value(pcard, 2, extraargs);
} }
int32 ans = 0; int32_t ans = 0;
while(er) { while(er) {
er &= er - 1; er &= er - 1;
ans++; ++ans;
} }
lua_pushinteger(L, ans); lua_pushinteger(L, ans);
return 1; return 1;
} }
int32 scriptlib::group_meta_add(lua_State* L) { int32_t scriptlib::group_meta_add(lua_State* L) {
check_param_count(L, 2); check_param_count(L, 2);
if(!check_param(L, PARAM_TYPE_CARD, 1, TRUE) && !check_param(L, PARAM_TYPE_GROUP, 1, TRUE)) if(!check_param(L, PARAM_TYPE_CARD, 1, TRUE) && !check_param(L, PARAM_TYPE_GROUP, 1, TRUE))
return luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 1); return luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 1);
...@@ -762,7 +804,7 @@ int32 scriptlib::group_meta_add(lua_State* L) { ...@@ -762,7 +804,7 @@ int32 scriptlib::group_meta_add(lua_State* L) {
interpreter::group2value(L, pgroup); interpreter::group2value(L, pgroup);
return 1; return 1;
} }
int32 scriptlib::group_meta_sub(lua_State* L) { int32_t scriptlib::group_meta_sub(lua_State* L) {
check_param_count(L, 2); check_param_count(L, 2);
if(!check_param(L, PARAM_TYPE_CARD, 1, TRUE) && !check_param(L, PARAM_TYPE_GROUP, 1, TRUE)) if(!check_param(L, PARAM_TYPE_CARD, 1, TRUE) && !check_param(L, PARAM_TYPE_GROUP, 1, TRUE))
return luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 1); return luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 1);
...@@ -789,7 +831,7 @@ int32 scriptlib::group_meta_sub(lua_State* L) { ...@@ -789,7 +831,7 @@ int32 scriptlib::group_meta_sub(lua_State* L) {
interpreter::group2value(L, pgroup); interpreter::group2value(L, pgroup);
return 1; return 1;
} }
int32 scriptlib::group_meta_band(lua_State* L) { int32_t scriptlib::group_meta_band(lua_State* L) {
check_param_count(L, 2); check_param_count(L, 2);
if(!check_param(L, PARAM_TYPE_CARD, 1, TRUE) && !check_param(L, PARAM_TYPE_GROUP, 1, TRUE)) if(!check_param(L, PARAM_TYPE_CARD, 1, TRUE) && !check_param(L, PARAM_TYPE_GROUP, 1, TRUE))
return luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 1); return luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 1);
...@@ -797,7 +839,7 @@ int32 scriptlib::group_meta_band(lua_State* L) { ...@@ -797,7 +839,7 @@ int32 scriptlib::group_meta_band(lua_State* L) {
return luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 2); return luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 2);
duel* pduel = interpreter::get_duel_info(L); duel* pduel = interpreter::get_duel_info(L);
group* pgroup = pduel->new_group(); group* pgroup = pduel->new_group();
field::card_set check_set; card_set check_set;
if(check_param(L, PARAM_TYPE_CARD, 1, TRUE)) { if(check_param(L, PARAM_TYPE_CARD, 1, TRUE)) {
card* ccard = *(card**) lua_touserdata(L, 1); card* ccard = *(card**) lua_touserdata(L, 1);
check_set.insert(ccard); check_set.insert(ccard);
...@@ -818,7 +860,7 @@ int32 scriptlib::group_meta_band(lua_State* L) { ...@@ -818,7 +860,7 @@ int32 scriptlib::group_meta_band(lua_State* L) {
interpreter::group2value(L, pgroup); interpreter::group2value(L, pgroup);
return 1; return 1;
} }
int32 scriptlib::group_meta_bxor(lua_State* L) { int32_t scriptlib::group_meta_bxor(lua_State* L) {
check_param_count(L, 2); check_param_count(L, 2);
if(!check_param(L, PARAM_TYPE_CARD, 1, TRUE) && !check_param(L, PARAM_TYPE_GROUP, 1, TRUE)) if(!check_param(L, PARAM_TYPE_CARD, 1, TRUE) && !check_param(L, PARAM_TYPE_GROUP, 1, TRUE))
return luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 1); return luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 1);
...@@ -866,13 +908,13 @@ static const struct luaL_Reg grouplib[] = { ...@@ -866,13 +908,13 @@ static const struct luaL_Reg grouplib[] = {
{ "GetFirst", scriptlib::group_get_first }, { "GetFirst", scriptlib::group_get_first },
{ "GetCount", scriptlib::group_get_count }, { "GetCount", scriptlib::group_get_count },
{ "__len", scriptlib::group_get_count }, { "__len", scriptlib::group_get_count },
{ "ForEach", scriptlib::group_for_each },
{ "Filter", scriptlib::group_filter }, { "Filter", scriptlib::group_filter },
{ "FilterCount", scriptlib::group_filter_count }, { "FilterCount", scriptlib::group_filter_count },
{ "FilterSelect", scriptlib::group_filter_select }, { "FilterSelect", scriptlib::group_filter_select },
{ "Select", scriptlib::group_select }, { "Select", scriptlib::group_select },
{ "SelectUnselect", scriptlib::group_select_unselect }, { "SelectUnselect", scriptlib::group_select_unselect },
{ "RandomSelect", scriptlib::group_random_select }, { "RandomSelect", scriptlib::group_random_select },
{ "CancelableSelect", scriptlib::group_cancelable_select },
{ "IsExists", scriptlib::group_is_exists }, { "IsExists", scriptlib::group_is_exists },
{ "CheckWithSumEqual", scriptlib::group_check_with_sum_equal }, { "CheckWithSumEqual", scriptlib::group_check_with_sum_equal },
{ "SelectWithSumEqual", scriptlib::group_select_with_sum_equal }, { "SelectWithSumEqual", scriptlib::group_select_with_sum_equal },
...@@ -894,7 +936,7 @@ static const struct luaL_Reg grouplib[] = { ...@@ -894,7 +936,7 @@ static const struct luaL_Reg grouplib[] = {
{ "__sub", scriptlib::group_meta_sub }, { "__sub", scriptlib::group_meta_sub },
{ "__band", scriptlib::group_meta_band }, { "__band", scriptlib::group_meta_band },
{ "__bxor", scriptlib::group_meta_bxor }, { "__bxor", scriptlib::group_meta_bxor },
{ NULL, NULL } { nullptr, nullptr }
}; };
void scriptlib::open_grouplib(lua_State *L) { void scriptlib::open_grouplib(lua_State *L) {
luaL_newlib(L, grouplib); luaL_newlib(L, grouplib);
......
...@@ -9,61 +9,77 @@ ...@@ -9,61 +9,77 @@
#define MTRANDOM_H_ #define MTRANDOM_H_
#include <random> #include <random>
#include <vector>
#include <utility>
class mt19937 { class mtrandom {
public: public:
const unsigned int rand_max; const unsigned int rand_max{ std::mt19937::max() };
mt19937() : mtrandom() :
rng(), rand_max((rng.max)()) {} rng() {}
explicit mt19937(unsigned int seed) : mtrandom(uint32_t seq[], size_t len) {
rng(seed), rand_max((rng.max)()) {} std::seed_seq q(seq, seq + len);
rng.seed(q);
}
explicit mtrandom(uint_fast32_t value) :
rng(value) {}
mtrandom(std::seed_seq& q) :
rng(q) {}
mtrandom(const mtrandom& other) = delete;
void operator=(const mtrandom& other) = delete;
// mersenne_twister_engine // mersenne_twister_engine
void reset(unsigned int seed) { void seed(uint32_t seq[], size_t len) {
rng.seed(seed); std::seed_seq q(seq, seq + len);
rng.seed(q);
}
void seed(uint_fast32_t value) {
rng.seed(value);
} }
unsigned int rand() { void seed(std::seed_seq& q) {
rng.seed(q);
}
uint_fast32_t rand() {
return rng(); return rng();
} }
void discard(unsigned long long z) {
rng.discard(z);
}
// uniform_int_distribution // old vesion, discard too many numbers
int get_random_integer(int l, int h) { int get_random_integer_v1(int l, int h) {
unsigned int range = (unsigned int)(h - l + 1); uint32_t range = (h - l + 1);
unsigned int secureMax = rand_max - rand_max % range; uint32_t secureMax = rand_max - rand_max % range;
unsigned int x; uint_fast32_t x;
do { do {
x = rng(); x = rng();
} while (x >= secureMax); } while (x >= secureMax);
return (int)(l + x % range); return l + (int)(x % range);
}
int get_random_integer_old(int l, int h) {
int result = (int)((double)rng() / rand_max * ((double)h - l + 1)) + l;
if (result > h)
result = h;
return result;
} }
// Fisher-Yates shuffle v[a]~v[b] // N % k == (N - k) % k, discard the leftmost numbers
template<typename T> int get_random_integer_v2(int l, int h) {
void shuffle_vector(std::vector<T>& v, int a = -1, int b = -1) { uint32_t range = (h - l + 1);
if (a < 0) uint32_t bound = -range % range;
a = 0; auto x = rng();
if (b < 0) while (x < bound) {
b = (int)v.size() - 1; x = rng();
for (int i = a; i < b; ++i) {
int r = get_random_integer(i, b);
std::swap(v[i], v[r]);
} }
return l + (int)(x % range);
} }
// Fisher-Yates shuffle [first, last)
template<typename T> template<typename T>
void shuffle_vector_old(std::vector<T>& v, int a = -1, int b = -1) { void shuffle_vector(std::vector<T>& v, int first = 0, int last = INT32_MAX, int version = 2) {
if (a < 0) if ((size_t)last > v.size())
a = 0; last = v.size();
if (b < 0) auto distribution = &mtrandom::get_random_integer_v2;
b = (int)v.size() - 1; if (version == 1)
for (int i = a; i < b; ++i) { distribution = &mtrandom::get_random_integer_v1;
int r = get_random_integer_old(i, b); for (int i = first; i < last - 1; ++i) {
int r = (this->*distribution)(i, last - 1);
std::swap(v[i], v[r]); std::swap(v[i], v[r]);
} }
} }
......
...@@ -4,8 +4,9 @@ ...@@ -4,8 +4,9 @@
* Created on: 2010-5-2 * Created on: 2010-5-2
* Author: Argon * Author: Argon
*/ */
#include <stdio.h> #include <cstdio>
#include <string.h> #include <cstring>
#include <set>
#include "ocgapi.h" #include "ocgapi.h"
#include "duel.h" #include "duel.h"
#include "card.h" #include "card.h"
...@@ -13,66 +14,83 @@ ...@@ -13,66 +14,83 @@
#include "effect.h" #include "effect.h"
#include "field.h" #include "field.h"
#include "interpreter.h" #include "interpreter.h"
#include <set> #include "buffer.h"
static uint32_t default_card_reader(uint32_t code, card_data* data) {
return 0;
}
static uint32_t default_message_handler(intptr_t pduel, uint32_t message_type) {
return 0;
}
static script_reader sreader = default_script_reader; static script_reader sreader = default_script_reader;
static card_reader creader = default_card_reader; static card_reader creader = default_card_reader;
static message_handler mhandler = default_message_handler; static message_handler mhandler = default_message_handler;
static byte buffer[0x20000]; static byte buffer[0x100000];
static std::set<duel*> duel_set; static std::set<duel*> duel_set;
extern "C" DECL_DLLEXPORT void set_script_reader(script_reader f) { OCGCORE_API void set_script_reader(script_reader f) {
sreader = f; sreader = f;
} }
extern "C" DECL_DLLEXPORT void set_card_reader(card_reader f) { OCGCORE_API void set_card_reader(card_reader f) {
creader = f; creader = f;
} }
extern "C" DECL_DLLEXPORT void set_message_handler(message_handler f) { OCGCORE_API void set_message_handler(message_handler f) {
mhandler = f; mhandler = f;
} }
byte* read_script(const char* script_name, int* len) { byte* read_script(const char* script_name, int* len) {
return sreader(script_name, len); return sreader(script_name, len);
} }
uint32 read_card(uint32 code, card_data* data) { uint32_t read_card(uint32_t code, card_data* data) {
if (code == TEMP_CARD_ID) {
data->clear();
return 0;
}
return creader(code, data); return creader(code, data);
} }
uint32 handle_message(void* pduel, uint32 msg_type) { uint32_t handle_message(void* pduel, uint32_t message_type) {
return mhandler(pduel, msg_type); return mhandler((intptr_t)pduel, message_type);
} }
byte* default_script_reader(const char* script_name, int* slen) { OCGCORE_API byte* default_script_reader(const char* script_name, int* slen) {
FILE *fp; FILE *fp;
fp = fopen(script_name, "rb"); fp = std::fopen(script_name, "rb");
if (!fp) if (!fp)
return 0; return nullptr;
int len = (int)fread(buffer, 1, sizeof(buffer), fp); size_t len = std::fread(buffer, 1, sizeof buffer, fp);
fclose(fp); std::fclose(fp);
if(len >= sizeof(buffer)) if (len >= sizeof buffer)
return 0; return nullptr;
*slen = len; *slen = (int)len;
return buffer; return buffer;
} }
uint32 default_card_reader(uint32 code, card_data* data) { OCGCORE_API intptr_t create_duel(uint_fast32_t seed) {
return 0; duel* pduel = new duel();
} duel_set.insert(pduel);
uint32 default_message_handler(void* pduel, uint32 message_type) { pduel->random.seed(seed);
return 0; pduel->rng_version = 1;
return (intptr_t)pduel;
} }
extern "C" DECL_DLLEXPORT intptr_t create_duel(uint32 seed) { OCGCORE_API intptr_t create_duel_v2(uint32_t seed_sequence[]) {
duel* pduel = new duel(); duel* pduel = new duel();
duel_set.insert(pduel); duel_set.insert(pduel);
pduel->random.reset(seed); pduel->random.seed(seed_sequence, SEED_COUNT);
pduel->rng_version = 2;
return (intptr_t)pduel; return (intptr_t)pduel;
} }
extern "C" DECL_DLLEXPORT void start_duel(intptr_t pduel, int32 options) { OCGCORE_API void start_duel(intptr_t pduel, uint32_t options) {
duel* pd = (duel*)pduel; duel* pd = (duel*)pduel;
pd->game_field->core.duel_options |= options & 0xffff; uint16_t duel_rule = options >> 16;
int32 duel_rule = options >> 16; uint16_t duel_options = options & 0xffff;
if(duel_rule) pd->game_field->core.duel_options |= duel_options;
if (duel_rule >= 1 && duel_rule <= CURRENT_RULE)
pd->game_field->core.duel_rule = duel_rule; pd->game_field->core.duel_rule = duel_rule;
else if(options & DUEL_OBSOLETE_RULING) //provide backward compatibility with replay else if(options & DUEL_OBSOLETE_RULING) //provide backward compatibility with replay
pd->game_field->core.duel_rule = 1; pd->game_field->core.duel_rule = 1;
else if(!pd->game_field->core.duel_rule) if (pd->game_field->core.duel_rule < 1 || pd->game_field->core.duel_rule > CURRENT_RULE)
pd->game_field->core.duel_rule = 5; pd->game_field->core.duel_rule = CURRENT_RULE;
if (pd->game_field->core.duel_rule == MASTER_RULE3) {
pd->game_field->player[0].szone_size = 8;
pd->game_field->player[1].szone_size = 8;
}
pd->game_field->core.shuffle_hand_check[0] = FALSE; pd->game_field->core.shuffle_hand_check[0] = FALSE;
pd->game_field->core.shuffle_hand_check[1] = FALSE; pd->game_field->core.shuffle_hand_check[1] = FALSE;
pd->game_field->core.shuffle_deck_check[0] = FALSE; pd->game_field->core.shuffle_deck_check[0] = FALSE;
...@@ -88,7 +106,7 @@ extern "C" DECL_DLLEXPORT void start_duel(intptr_t pduel, int32 options) { ...@@ -88,7 +106,7 @@ extern "C" DECL_DLLEXPORT void start_duel(intptr_t pduel, int32 options) {
pd->game_field->player[0].tag_list_hand.push_back(pcard); pd->game_field->player[0].tag_list_hand.push_back(pcard);
pcard->current.controler = 0; pcard->current.controler = 0;
pcard->current.location = LOCATION_HAND; pcard->current.location = LOCATION_HAND;
pcard->current.sequence = (uint8)pd->game_field->player[0].tag_list_hand.size() - 1; pcard->current.sequence = (uint8_t)pd->game_field->player[0].tag_list_hand.size() - 1;
pcard->current.position = POS_FACEDOWN; pcard->current.position = POS_FACEDOWN;
} }
for(int i = 0; i < pd->game_field->player[1].start_count && pd->game_field->player[1].tag_list_main.size(); ++i) { for(int i = 0; i < pd->game_field->player[1].start_count && pd->game_field->player[1].tag_list_main.size(); ++i) {
...@@ -97,20 +115,22 @@ extern "C" DECL_DLLEXPORT void start_duel(intptr_t pduel, int32 options) { ...@@ -97,20 +115,22 @@ extern "C" DECL_DLLEXPORT void start_duel(intptr_t pduel, int32 options) {
pd->game_field->player[1].tag_list_hand.push_back(pcard); pd->game_field->player[1].tag_list_hand.push_back(pcard);
pcard->current.controler = 1; pcard->current.controler = 1;
pcard->current.location = LOCATION_HAND; pcard->current.location = LOCATION_HAND;
pcard->current.sequence = (uint8)pd->game_field->player[1].tag_list_hand.size() - 1; pcard->current.sequence = (uint8_t)pd->game_field->player[1].tag_list_hand.size() - 1;
pcard->current.position = POS_FACEDOWN; pcard->current.position = POS_FACEDOWN;
} }
} }
pd->game_field->add_process(PROCESSOR_TURN, 0, 0, 0, 0, 0); pd->game_field->add_process(PROCESSOR_TURN, 0, 0, 0, 0, 0);
} }
extern "C" DECL_DLLEXPORT void end_duel(intptr_t pduel) { OCGCORE_API void end_duel(intptr_t pduel) {
duel* pd = (duel*)pduel; duel* pd = (duel*)pduel;
if(duel_set.count(pd)) { if(duel_set.count(pd)) {
duel_set.erase(pd); duel_set.erase(pd);
delete pd; delete pd;
} }
} }
extern "C" DECL_DLLEXPORT void set_player_info(intptr_t pduel, int32 playerid, int32 lp, int32 startcount, int32 drawcount) { OCGCORE_API void set_player_info(intptr_t pduel, int32_t playerid, int32_t lp, int32_t startcount, int32_t drawcount) {
if (!check_playerid(playerid))
return;
duel* pd = (duel*)pduel; duel* pd = (duel*)pduel;
if(lp > 0) if(lp > 0)
pd->game_field->player[playerid].lp = lp; pd->game_field->player[playerid].lp = lp;
...@@ -119,22 +139,27 @@ extern "C" DECL_DLLEXPORT void set_player_info(intptr_t pduel, int32 playerid, i ...@@ -119,22 +139,27 @@ extern "C" DECL_DLLEXPORT void set_player_info(intptr_t pduel, int32 playerid, i
if(drawcount >= 0) if(drawcount >= 0)
pd->game_field->player[playerid].draw_count = drawcount; pd->game_field->player[playerid].draw_count = drawcount;
} }
extern "C" DECL_DLLEXPORT void get_log_message(intptr_t pduel, byte* buf) { OCGCORE_API void get_log_message(intptr_t pduel, char* buf) {
strcpy((char*)buf, ((duel*)pduel)->strbuffer); duel* pd = (duel*)pduel;
std::strncpy(buf, pd->strbuffer, sizeof pd->strbuffer - 1);
buf[sizeof pd->strbuffer - 1] = 0;
} }
extern "C" DECL_DLLEXPORT int32 get_message(intptr_t pduel, byte* buf) { OCGCORE_API int32_t get_message(intptr_t pduel, byte* buf) {
int32 len = ((duel*)pduel)->read_buffer(buf); int32_t len = ((duel*)pduel)->read_buffer(buf);
((duel*)pduel)->clear_buffer(); ((duel*)pduel)->clear_buffer();
return len; return len;
} }
extern "C" DECL_DLLEXPORT int32 process(intptr_t pduel) { OCGCORE_API uint32_t process(intptr_t pduel) {
duel* pd = (duel*)pduel; duel* pd = (duel*)pduel;
int result = pd->game_field->process(); uint32_t result = 0;
while((result & 0xffff) == 0 && (result & 0xf0000) == 0) do {
result = pd->game_field->process(); result = pd->game_field->process();
} while ((result & PROCESSOR_BUFFER_LEN) == 0 && (result & PROCESSOR_FLAG) == 0);
return result; return result;
} }
extern "C" DECL_DLLEXPORT void new_card(intptr_t pduel, uint32 code, uint8 owner, uint8 playerid, uint8 location, uint8 sequence, uint8 position) { OCGCORE_API void new_card(intptr_t pduel, uint32_t code, uint8_t owner, uint8_t playerid, uint8_t location, uint8_t sequence, uint8_t position) {
if (!check_playerid(owner) || !check_playerid(playerid))
return;
duel* ptduel = (duel*)pduel; duel* ptduel = (duel*)pduel;
if(ptduel->game_field->is_location_useable(playerid, location, sequence)) { if(ptduel->game_field->is_location_useable(playerid, location, sequence)) {
card* pcard = ptduel->new_card(code); card* pcard = ptduel->new_card(code);
...@@ -150,7 +175,7 @@ extern "C" DECL_DLLEXPORT void new_card(intptr_t pduel, uint32 code, uint8 owner ...@@ -150,7 +175,7 @@ extern "C" DECL_DLLEXPORT void new_card(intptr_t pduel, uint32 code, uint8 owner
} }
} }
} }
extern "C" DECL_DLLEXPORT void new_tag_card(intptr_t pduel, uint32 code, uint8 owner, uint8 location) { OCGCORE_API void new_tag_card(intptr_t pduel, uint32_t code, uint8_t owner, uint8_t location) {
duel* ptduel = (duel*)pduel; duel* ptduel = (duel*)pduel;
if(owner > 1 || !(location & (LOCATION_DECK | LOCATION_EXTRA))) if(owner > 1 || !(location & (LOCATION_DECK | LOCATION_EXTRA)))
return; return;
...@@ -161,7 +186,7 @@ extern "C" DECL_DLLEXPORT void new_tag_card(intptr_t pduel, uint32 code, uint8 o ...@@ -161,7 +186,7 @@ extern "C" DECL_DLLEXPORT void new_tag_card(intptr_t pduel, uint32 code, uint8 o
pcard->owner = owner; pcard->owner = owner;
pcard->current.controler = owner; pcard->current.controler = owner;
pcard->current.location = LOCATION_DECK; pcard->current.location = LOCATION_DECK;
pcard->current.sequence = (uint8)ptduel->game_field->player[owner].tag_list_main.size() - 1; pcard->current.sequence = (uint8_t)ptduel->game_field->player[owner].tag_list_main.size() - 1;
pcard->current.position = POS_FACEDOWN_DEFENSE; pcard->current.position = POS_FACEDOWN_DEFENSE;
break; break;
case LOCATION_EXTRA: case LOCATION_EXTRA:
...@@ -169,103 +194,109 @@ extern "C" DECL_DLLEXPORT void new_tag_card(intptr_t pduel, uint32 code, uint8 o ...@@ -169,103 +194,109 @@ extern "C" DECL_DLLEXPORT void new_tag_card(intptr_t pduel, uint32 code, uint8 o
pcard->owner = owner; pcard->owner = owner;
pcard->current.controler = owner; pcard->current.controler = owner;
pcard->current.location = LOCATION_EXTRA; pcard->current.location = LOCATION_EXTRA;
pcard->current.sequence = (uint8)ptduel->game_field->player[owner].tag_list_extra.size() - 1; pcard->current.sequence = (uint8_t)ptduel->game_field->player[owner].tag_list_extra.size() - 1;
pcard->current.position = POS_FACEDOWN_DEFENSE; pcard->current.position = POS_FACEDOWN_DEFENSE;
break; break;
} }
} }
extern "C" DECL_DLLEXPORT int32 query_card(intptr_t pduel, uint8 playerid, uint8 location, uint8 sequence, int32 query_flag, byte* buf, int32 use_cache) { /**
if(playerid != 0 && playerid != 1) * @brief Get card information.
return 0; * @param buf int32_t array
* @return buffer length in bytes
*/
OCGCORE_API int32_t query_card(intptr_t pduel, uint8_t playerid, uint8_t location, uint8_t sequence, int32_t query_flag, byte* buf, int32_t use_cache) {
if (!check_playerid(playerid))
return LEN_FAIL;
duel* ptduel = (duel*)pduel; duel* ptduel = (duel*)pduel;
card* pcard = 0; card* pcard = nullptr;
location &= 0x7f; location &= 0x7f;
if(location & LOCATION_ONFIELD) if (location == LOCATION_MZONE || location == LOCATION_SZONE)
pcard = ptduel->game_field->get_field_card(playerid, location, sequence); pcard = ptduel->game_field->get_field_card(playerid, location, sequence);
else { else {
field::card_vector* lst = 0; card_vector* lst = nullptr;
if(location == LOCATION_HAND) if (location == LOCATION_HAND)
lst = &ptduel->game_field->player[playerid].list_hand; lst = &ptduel->game_field->player[playerid].list_hand;
else if(location == LOCATION_GRAVE) else if (location == LOCATION_GRAVE)
lst = &ptduel->game_field->player[playerid].list_grave; lst = &ptduel->game_field->player[playerid].list_grave;
else if(location == LOCATION_REMOVED) else if (location == LOCATION_REMOVED)
lst = &ptduel->game_field->player[playerid].list_remove; lst = &ptduel->game_field->player[playerid].list_remove;
else if(location == LOCATION_EXTRA) else if (location == LOCATION_EXTRA)
lst = &ptduel->game_field->player[playerid].list_extra; lst = &ptduel->game_field->player[playerid].list_extra;
else if(location == LOCATION_DECK) else if (location == LOCATION_DECK)
lst = &ptduel->game_field->player[playerid].list_main; lst = &ptduel->game_field->player[playerid].list_main;
if(!lst || sequence >= lst->size())
pcard = 0;
else else
return LEN_FAIL;
if (sequence >= (int32_t)lst->size())
return LEN_FAIL;
pcard = (*lst)[sequence]; pcard = (*lst)[sequence];
} }
if (pcard) { if (pcard) {
return pcard->get_infos(buf, query_flag, use_cache); return pcard->get_infos(buf, query_flag, use_cache);
} }
else { else {
*((int32*)buf) = 4; buffer_write<int32_t>(buf, LEN_EMPTY);
return 4; return LEN_EMPTY;
} }
} }
extern "C" DECL_DLLEXPORT int32 query_field_count(intptr_t pduel, uint8 playerid, uint8 location) { OCGCORE_API int32_t query_field_count(intptr_t pduel, uint8_t playerid, uint8_t location) {
duel* ptduel = (duel*)pduel; duel* ptduel = (duel*)pduel;
if(playerid != 0 && playerid != 1) if (!check_playerid(playerid))
return 0; return 0;
auto& player = ptduel->game_field->player[playerid]; auto& player = ptduel->game_field->player[playerid];
if(location == LOCATION_HAND) if(location == LOCATION_HAND)
return (int32)player.list_hand.size(); return (int32_t)player.list_hand.size();
if(location == LOCATION_GRAVE) if(location == LOCATION_GRAVE)
return (int32)player.list_grave.size(); return (int32_t)player.list_grave.size();
if(location == LOCATION_REMOVED) if(location == LOCATION_REMOVED)
return (int32)player.list_remove.size(); return (int32_t)player.list_remove.size();
if(location == LOCATION_EXTRA) if(location == LOCATION_EXTRA)
return (int32)player.list_extra.size(); return (int32_t)player.list_extra.size();
if(location == LOCATION_DECK) if(location == LOCATION_DECK)
return (int32)player.list_main.size(); return (int32_t)player.list_main.size();
if(location == LOCATION_MZONE) { if(location == LOCATION_MZONE) {
uint32 count = 0; int32_t count = 0;
for(auto& pcard : player.list_mzone) for(auto& pcard : player.list_mzone)
if(pcard) count++; if(pcard)
++count;
return count; return count;
} }
if(location == LOCATION_SZONE) { if(location == LOCATION_SZONE) {
uint32 count = 0; int32_t count = 0;
for(auto& pcard : player.list_szone) for(auto& pcard : player.list_szone)
if(pcard) count++; if(pcard)
++count;
return count; return count;
} }
return 0; return 0;
} }
extern "C" DECL_DLLEXPORT int32 query_field_card(intptr_t pduel, uint8 playerid, uint8 location, int32 query_flag, byte* buf, int32 use_cache) { OCGCORE_API int32_t query_field_card(intptr_t pduel, uint8_t playerid, uint8_t location, uint32_t query_flag, byte* buf, int32_t use_cache) {
if(playerid != 0 && playerid != 1) if (!check_playerid(playerid))
return 0; return LEN_FAIL;
duel* ptduel = (duel*)pduel; duel* ptduel = (duel*)pduel;
auto& player = ptduel->game_field->player[playerid]; auto& player = ptduel->game_field->player[playerid];
byte* p = buf; byte* p = buf;
if(location == LOCATION_MZONE) { if(location == LOCATION_MZONE) {
for(auto& pcard : player.list_mzone) { for(auto& pcard : player.list_mzone) {
if(pcard) { if(pcard) {
uint32 clen = pcard->get_infos(p, query_flag, use_cache); int32_t clen = pcard->get_infos(p, query_flag, use_cache);
p += clen; p += clen;
} else { } else {
*((int32*)p) = 4; buffer_write<int32_t>(p, LEN_EMPTY);
p += 4;
} }
} }
} }
else if(location == LOCATION_SZONE) { else if(location == LOCATION_SZONE) {
for(auto& pcard : player.list_szone) { for(auto& pcard : player.list_szone) {
if(pcard) { if(pcard) {
uint32 clen = pcard->get_infos(p, query_flag, use_cache); int32_t clen = pcard->get_infos(p, query_flag, use_cache);
p += clen; p += clen;
} else { } else {
*((int32*)p) = 4; buffer_write<int32_t>(p, LEN_EMPTY);
p += 4;
} }
} }
} }
else { else {
field::card_vector* lst = nullptr; card_vector* lst = nullptr;
if(location == LOCATION_HAND) if(location == LOCATION_HAND)
lst = &player.list_hand; lst = &player.list_hand;
else if(location == LOCATION_GRAVE) else if(location == LOCATION_GRAVE)
...@@ -277,28 +308,27 @@ extern "C" DECL_DLLEXPORT int32 query_field_card(intptr_t pduel, uint8 playerid, ...@@ -277,28 +308,27 @@ extern "C" DECL_DLLEXPORT int32 query_field_card(intptr_t pduel, uint8 playerid,
else if(location == LOCATION_DECK) else if(location == LOCATION_DECK)
lst = &player.list_main; lst = &player.list_main;
else else
return 0; return LEN_FAIL;
for(auto& pcard : *lst) { for(auto& pcard : *lst) {
uint32 clen = pcard->get_infos(p, query_flag, use_cache); int32_t clen = pcard->get_infos(p, query_flag, use_cache);
p += clen; p += clen;
} }
} }
return (int32)(p - buf); return (int32_t)(p - buf);
} }
extern "C" DECL_DLLEXPORT int32 query_field_info(intptr_t pduel, byte* buf) { OCGCORE_API int32_t query_field_info(intptr_t pduel, byte* buf) {
duel* ptduel = (duel*)pduel; duel* ptduel = (duel*)pduel;
byte* p = buf; byte* p = buf;
*p++ = MSG_RELOAD_FIELD; *p++ = MSG_RELOAD_FIELD;
*p++ = ptduel->game_field->core.duel_rule; *p++ = (uint8_t)ptduel->game_field->core.duel_rule;
for(int playerid = 0; playerid < 2; ++playerid) { for(int playerid = 0; playerid < 2; ++playerid) {
auto& player = ptduel->game_field->player[playerid]; auto& player = ptduel->game_field->player[playerid];
*((int*)p) = player.lp; buffer_write<int32_t>(p, player.lp);
p += 4;
for(auto& pcard : player.list_mzone) { for(auto& pcard : player.list_mzone) {
if(pcard) { if(pcard) {
*p++ = 1; *p++ = 1;
*p++ = pcard->current.position; *p++ = pcard->current.position;
*p++ = (uint8)pcard->xyz_materials.size(); *p++ = (uint8_t)pcard->xyz_materials.size();
} else { } else {
*p++ = 0; *p++ = 0;
} }
...@@ -311,34 +341,31 @@ extern "C" DECL_DLLEXPORT int32 query_field_info(intptr_t pduel, byte* buf) { ...@@ -311,34 +341,31 @@ extern "C" DECL_DLLEXPORT int32 query_field_info(intptr_t pduel, byte* buf) {
*p++ = 0; *p++ = 0;
} }
} }
*p++ = (uint8)player.list_main.size(); *p++ = (uint8_t)player.list_main.size();
*p++ = (uint8)player.list_hand.size(); *p++ = (uint8_t)player.list_hand.size();
*p++ = (uint8)player.list_grave.size(); *p++ = (uint8_t)player.list_grave.size();
*p++ = (uint8)player.list_remove.size(); *p++ = (uint8_t)player.list_remove.size();
*p++ = (uint8)player.list_extra.size(); *p++ = (uint8_t)player.list_extra.size();
*p++ = (uint8)player.extra_p_count; *p++ = (uint8_t)player.extra_p_count;
} }
*p++ = (uint8)ptduel->game_field->core.current_chain.size(); *p++ = (uint8_t)ptduel->game_field->core.current_chain.size();
for(const auto& ch : ptduel->game_field->core.current_chain) { for(const auto& ch : ptduel->game_field->core.current_chain) {
effect* peffect = ch.triggering_effect; effect* peffect = ch.triggering_effect;
*((int*)p) = peffect->get_handler()->data.code; buffer_write<uint32_t>(p, peffect->get_handler()->data.code);
p += 4; buffer_write<uint32_t>(p, peffect->get_handler()->get_info_location());
*((int*)p) = peffect->get_handler()->get_info_location();
p += 4;
*p++ = ch.triggering_controler; *p++ = ch.triggering_controler;
*p++ = (uint8)ch.triggering_location; *p++ = (uint8_t)ch.triggering_location;
*p++ = ch.triggering_sequence; *p++ = ch.triggering_sequence;
*((int*)p) = peffect->description; buffer_write<uint32_t>(p, peffect->description);
p += 4;
} }
return (int32)(p - buf); return (int32_t)(p - buf);
} }
extern "C" DECL_DLLEXPORT void set_responsei(intptr_t pduel, int32 value) { OCGCORE_API void set_responsei(intptr_t pduel, int32_t value) {
((duel*)pduel)->set_responsei(value); ((duel*)pduel)->set_responsei(value);
} }
extern "C" DECL_DLLEXPORT void set_responseb(intptr_t pduel, byte* buf) { OCGCORE_API void set_responseb(intptr_t pduel, byte* buf) {
((duel*)pduel)->set_responseb(buf); ((duel*)pduel)->set_responseb(buf);
} }
extern "C" DECL_DLLEXPORT int32 preload_script(intptr_t pduel, const char* script, int32 len) { OCGCORE_API int32_t preload_script(intptr_t pduel, const char* script_name) {
return ((duel*)pduel)->lua->load_script(script); return ((duel*)pduel)->lua->load_script(script_name);
} }
...@@ -10,49 +10,56 @@ ...@@ -10,49 +10,56 @@
#include "common.h" #include "common.h"
#ifdef WIN32 #ifdef __cplusplus
#define DECL_DLLEXPORT __declspec(dllexport) #define EXTERN_C extern "C"
#else #else
#define DECL_DLLEXPORT #define EXTERN_C
#endif #endif
class card; #ifdef _WIN32
#define OCGCORE_API EXTERN_C __declspec(dllexport)
#else
#define OCGCORE_API EXTERN_C __attribute__ ((visibility ("default")))
#endif
#define SEED_COUNT 8
#define LEN_FAIL 0
#define LEN_EMPTY 4
#define LEN_HEADER 8
#define TEMP_CARD_ID 0
struct card_data; struct card_data;
struct card_info;
class group;
class effect;
class interpreter;
typedef byte* (*script_reader)(const char*, int*); typedef byte* (*script_reader)(const char* script_name, int* len);
typedef uint32 (*card_reader)(uint32, card_data*); typedef uint32_t (*card_reader)(uint32_t code, card_data* data);
typedef uint32 (*message_handler)(void*, uint32); typedef uint32_t (*message_handler)(intptr_t pduel, uint32_t msg_type);
extern "C" DECL_DLLEXPORT void set_script_reader(script_reader f); OCGCORE_API void set_script_reader(script_reader f);
extern "C" DECL_DLLEXPORT void set_card_reader(card_reader f); OCGCORE_API void set_card_reader(card_reader f);
extern "C" DECL_DLLEXPORT void set_message_handler(message_handler f); OCGCORE_API void set_message_handler(message_handler f);
byte* read_script(const char* script_name, int* len); byte* read_script(const char* script_name, int* len);
uint32 read_card(uint32 code, card_data* data); uint32_t read_card(uint32_t code, card_data* data);
uint32 handle_message(void* pduel, uint32 message_type); uint32_t handle_message(void* pduel, uint32_t message_type);
extern "C" DECL_DLLEXPORT intptr_t create_duel(uint32 seed); OCGCORE_API intptr_t create_duel(uint_fast32_t seed);
extern "C" DECL_DLLEXPORT void start_duel(intptr_t pduel, int32 options); OCGCORE_API intptr_t create_duel_v2(uint32_t seed_sequence[]);
extern "C" DECL_DLLEXPORT void end_duel(intptr_t pduel); OCGCORE_API void start_duel(intptr_t pduel, uint32_t options);
extern "C" DECL_DLLEXPORT void set_player_info(intptr_t pduel, int32 playerid, int32 lp, int32 startcount, int32 drawcount); OCGCORE_API void end_duel(intptr_t pduel);
extern "C" DECL_DLLEXPORT void get_log_message(intptr_t pduel, byte* buf); OCGCORE_API void set_player_info(intptr_t pduel, int32_t playerid, int32_t lp, int32_t startcount, int32_t drawcount);
extern "C" DECL_DLLEXPORT int32 get_message(intptr_t pduel, byte* buf); OCGCORE_API void get_log_message(intptr_t pduel, char* buf);
extern "C" DECL_DLLEXPORT int32 process(intptr_t pduel); OCGCORE_API int32_t get_message(intptr_t pduel, byte* buf);
extern "C" DECL_DLLEXPORT void new_card(intptr_t pduel, uint32 code, uint8 owner, uint8 playerid, uint8 location, uint8 sequence, uint8 position); OCGCORE_API uint32_t process(intptr_t pduel);
extern "C" DECL_DLLEXPORT void new_tag_card(intptr_t pduel, uint32 code, uint8 owner, uint8 location); OCGCORE_API void new_card(intptr_t pduel, uint32_t code, uint8_t owner, uint8_t playerid, uint8_t location, uint8_t sequence, uint8_t position);
extern "C" DECL_DLLEXPORT int32 query_card(intptr_t pduel, uint8 playerid, uint8 location, uint8 sequence, int32 query_flag, byte* buf, int32 use_cache); OCGCORE_API void new_tag_card(intptr_t pduel, uint32_t code, uint8_t owner, uint8_t location);
extern "C" DECL_DLLEXPORT int32 query_field_count(intptr_t pduel, uint8 playerid, uint8 location); OCGCORE_API int32_t query_card(intptr_t pduel, uint8_t playerid, uint8_t location, uint8_t sequence, int32_t query_flag, byte* buf, int32_t use_cache);
extern "C" DECL_DLLEXPORT int32 query_field_card(intptr_t pduel, uint8 playerid, uint8 location, int32 query_flag, byte* buf, int32 use_cache); OCGCORE_API int32_t query_field_count(intptr_t pduel, uint8_t playerid, uint8_t location);
extern "C" DECL_DLLEXPORT int32 query_field_info(intptr_t pduel, byte* buf); OCGCORE_API int32_t query_field_card(intptr_t pduel, uint8_t playerid, uint8_t location, uint32_t query_flag, byte* buf, int32_t use_cache);
extern "C" DECL_DLLEXPORT void set_responsei(intptr_t pduel, int32 value); OCGCORE_API int32_t query_field_info(intptr_t pduel, byte* buf);
extern "C" DECL_DLLEXPORT void set_responseb(intptr_t pduel, byte* buf); OCGCORE_API void set_responsei(intptr_t pduel, int32_t value);
extern "C" DECL_DLLEXPORT int32 preload_script(intptr_t pduel, const char* script, int32 len); OCGCORE_API void set_responseb(intptr_t pduel, byte* buf);
byte* default_script_reader(const char* script_name, int* len); OCGCORE_API int32_t preload_script(intptr_t pduel, const char* script_name);
uint32 default_card_reader(uint32 code, card_data* data); OCGCORE_API byte* default_script_reader(const char* script_name, int* len);
uint32 default_message_handler(void* pduel, uint32 msg_type);
#endif /* OCGAPI_H_ */ #endif /* OCGAPI_H_ */
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -14,12 +14,26 @@ ...@@ -14,12 +14,26 @@
#include <algorithm> #include <algorithm>
#include <stack> #include <stack>
int32 field::select_battle_command(uint16 step, uint8 playerid) { bool field::check_response(size_t vector_size, int32_t min_len, int32_t max_len) const {
const int32_t len = returns.bvalue[0];
if (len < min_len || len > max_len)
return false;
std::set<uint8_t> index_set;
for (int32_t i = 0; i < len; ++i) {
uint8_t index = returns.bvalue[1 + i];
if (index >= (int32_t)vector_size || index_set.count(index)) {
return false;
}
index_set.insert(index);
}
return true;
}
int32_t field::select_battle_command(uint16_t step, uint8_t playerid) {
if(step == 0) { if(step == 0) {
pduel->write_buffer8(MSG_SELECT_BATTLECMD); pduel->write_buffer8(MSG_SELECT_BATTLECMD);
pduel->write_buffer8(playerid); pduel->write_buffer8(playerid);
//Activatable //Activatable
pduel->write_buffer8((uint8)core.select_chains.size()); pduel->write_buffer8((uint8_t)core.select_chains.size());
std::sort(core.select_chains.begin(), core.select_chains.end(), chain::chain_operation_sort); std::sort(core.select_chains.begin(), core.select_chains.end(), chain::chain_operation_sort);
for(const auto& ch : core.select_chains) { for(const auto& ch : core.select_chains) {
effect* peffect = ch.triggering_effect; effect* peffect = ch.triggering_effect;
...@@ -34,7 +48,7 @@ int32 field::select_battle_command(uint16 step, uint8 playerid) { ...@@ -34,7 +48,7 @@ int32 field::select_battle_command(uint16 step, uint8 playerid) {
pduel->write_buffer32(peffect->description); pduel->write_buffer32(peffect->description);
} }
//Attackable //Attackable
pduel->write_buffer8((uint8)core.attackable_cards.size()); pduel->write_buffer8((uint8_t)core.attackable_cards.size());
for(auto& pcard : core.attackable_cards) { for(auto& pcard : core.attackable_cards) {
pduel->write_buffer32(pcard->data.code); pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler); pduel->write_buffer8(pcard->current.controler);
...@@ -53,11 +67,11 @@ int32 field::select_battle_command(uint16 step, uint8 playerid) { ...@@ -53,11 +67,11 @@ int32 field::select_battle_command(uint16 step, uint8 playerid) {
pduel->write_buffer8(0); pduel->write_buffer8(0);
return FALSE; return FALSE;
} else { } else {
uint32 t = returns.ivalue[0] & 0xffff; int32_t t = (uint32_t)returns.ivalue[0] & 0xffff;
uint32 s = returns.ivalue[0] >> 16; int32_t s = (uint32_t)returns.ivalue[0] >> 16;
if(t < 0 || t > 3 || s < 0 if(t < 0 || t > 3 || s < 0
|| (t == 0 && s >= core.select_chains.size()) || (t == 0 && s >= (int32_t)core.select_chains.size())
|| (t == 1 && s >= core.attackable_cards.size()) || (t == 1 && s >= (int32_t)core.attackable_cards.size())
|| (t == 2 && !core.to_m2) || (t == 2 && !core.to_m2)
|| (t == 3 && !core.to_ep)) { || (t == 3 && !core.to_ep)) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
...@@ -66,12 +80,12 @@ int32 field::select_battle_command(uint16 step, uint8 playerid) { ...@@ -66,12 +80,12 @@ int32 field::select_battle_command(uint16 step, uint8 playerid) {
return TRUE; return TRUE;
} }
} }
int32 field::select_idle_command(uint16 step, uint8 playerid) { int32_t field::select_idle_command(uint16_t step, uint8_t playerid) {
if(step == 0) { if(step == 0) {
pduel->write_buffer8(MSG_SELECT_IDLECMD); pduel->write_buffer8(MSG_SELECT_IDLECMD);
pduel->write_buffer8(playerid); pduel->write_buffer8(playerid);
//idle summon //idle summon
pduel->write_buffer8((uint8)core.summonable_cards.size()); pduel->write_buffer8((uint8_t)core.summonable_cards.size());
for(auto& pcard : core.summonable_cards) { for(auto& pcard : core.summonable_cards) {
pduel->write_buffer32(pcard->data.code); pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler); pduel->write_buffer8(pcard->current.controler);
...@@ -79,7 +93,7 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) { ...@@ -79,7 +93,7 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) {
pduel->write_buffer8(pcard->current.sequence); pduel->write_buffer8(pcard->current.sequence);
} }
//idle spsummon //idle spsummon
pduel->write_buffer8((uint8)core.spsummonable_cards.size()); pduel->write_buffer8((uint8_t)core.spsummonable_cards.size());
for(auto& pcard : core.spsummonable_cards) { for(auto& pcard : core.spsummonable_cards) {
pduel->write_buffer32(pcard->data.code); pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler); pduel->write_buffer8(pcard->current.controler);
...@@ -87,7 +101,7 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) { ...@@ -87,7 +101,7 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) {
pduel->write_buffer8(pcard->current.sequence); pduel->write_buffer8(pcard->current.sequence);
} }
//idle pos change //idle pos change
pduel->write_buffer8((uint8)core.repositionable_cards.size()); pduel->write_buffer8((uint8_t)core.repositionable_cards.size());
for(auto& pcard : core.repositionable_cards) { for(auto& pcard : core.repositionable_cards) {
pduel->write_buffer32(pcard->data.code); pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler); pduel->write_buffer8(pcard->current.controler);
...@@ -95,7 +109,7 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) { ...@@ -95,7 +109,7 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) {
pduel->write_buffer8(pcard->current.sequence); pduel->write_buffer8(pcard->current.sequence);
} }
//idle mset //idle mset
pduel->write_buffer8((uint8)core.msetable_cards.size()); pduel->write_buffer8((uint8_t)core.msetable_cards.size());
for(auto& pcard : core.msetable_cards) { for(auto& pcard : core.msetable_cards) {
pduel->write_buffer32(pcard->data.code); pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler); pduel->write_buffer8(pcard->current.controler);
...@@ -103,7 +117,7 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) { ...@@ -103,7 +117,7 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) {
pduel->write_buffer8(pcard->current.sequence); pduel->write_buffer8(pcard->current.sequence);
} }
//idle sset //idle sset
pduel->write_buffer8((uint8)core.ssetable_cards.size()); pduel->write_buffer8((uint8_t)core.ssetable_cards.size());
for(auto& pcard : core.ssetable_cards) { for(auto& pcard : core.ssetable_cards) {
pduel->write_buffer32(pcard->data.code); pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler); pduel->write_buffer8(pcard->current.controler);
...@@ -111,7 +125,7 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) { ...@@ -111,7 +125,7 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) {
pduel->write_buffer8(pcard->current.sequence); pduel->write_buffer8(pcard->current.sequence);
} }
//idle activate //idle activate
pduel->write_buffer8((uint8)core.select_chains.size()); pduel->write_buffer8((uint8_t)core.select_chains.size());
std::sort(core.select_chains.begin(), core.select_chains.end(), chain::chain_operation_sort); std::sort(core.select_chains.begin(), core.select_chains.end(), chain::chain_operation_sort);
for(const auto& ch : core.select_chains) { for(const auto& ch : core.select_chains) {
effect* peffect = ch.triggering_effect; effect* peffect = ch.triggering_effect;
...@@ -140,25 +154,25 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) { ...@@ -140,25 +154,25 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) {
pduel->write_buffer8(0); pduel->write_buffer8(0);
return FALSE; return FALSE;
} else { } else {
uint32 t = returns.ivalue[0] & 0xffff; int32_t t = (uint32_t)returns.ivalue[0] & 0xffff;
uint32 s = returns.ivalue[0] >> 16; int32_t s = (uint32_t)returns.ivalue[0] >> 16;
if(t < 0 || t > 8 || s < 0 if(t < 0 || t > 8 || s < 0
|| (t == 0 && s >= core.summonable_cards.size()) || (t == 0 && s >= (int32_t)core.summonable_cards.size())
|| (t == 1 && s >= core.spsummonable_cards.size()) || (t == 1 && s >= (int32_t)core.spsummonable_cards.size())
|| (t == 2 && s >= core.repositionable_cards.size()) || (t == 2 && s >= (int32_t)core.repositionable_cards.size())
|| (t == 3 && s >= core.msetable_cards.size()) || (t == 3 && s >= (int32_t)core.msetable_cards.size())
|| (t == 4 && s >= core.ssetable_cards.size()) || (t == 4 && s >= (int32_t)core.ssetable_cards.size())
|| (t == 5 && s >= core.select_chains.size()) || (t == 5 && s >= (int32_t)core.select_chains.size())
|| (t == 6 && (infos.phase != PHASE_MAIN1 || !core.to_bp)) || (t == 6 && (infos.phase != PHASE_MAIN1 || !core.to_bp))
|| (t == 7 && !core.to_ep) || (t == 7 && !core.to_ep)
|| (t == 8 && !(infos.can_shuffle && player[playerid].list_hand.size() > 1))) { || (t == 8 && !(infos.can_shuffle && (int32_t)player[playerid].list_hand.size() > 1))) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
} }
int32 field::select_effect_yes_no(uint16 step, uint8 playerid, uint32 description, card* pcard) { int32_t field::select_effect_yes_no(uint16_t step, uint8_t playerid, uint32_t description, card* pcard) {
if(step == 0) { if(step == 0) {
if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) { if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) {
returns.ivalue[0] = 1; returns.ivalue[0] = 1;
...@@ -179,7 +193,7 @@ int32 field::select_effect_yes_no(uint16 step, uint8 playerid, uint32 descriptio ...@@ -179,7 +193,7 @@ int32 field::select_effect_yes_no(uint16 step, uint8 playerid, uint32 descriptio
return TRUE; return TRUE;
} }
} }
int32 field::select_yes_no(uint16 step, uint8 playerid, uint32 description) { int32_t field::select_yes_no(uint16_t step, uint8_t playerid, uint32_t description) {
if(step == 0) { if(step == 0) {
if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) { if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) {
returns.ivalue[0] = 1; returns.ivalue[0] = 1;
...@@ -198,7 +212,7 @@ int32 field::select_yes_no(uint16 step, uint8 playerid, uint32 description) { ...@@ -198,7 +212,7 @@ int32 field::select_yes_no(uint16 step, uint8 playerid, uint32 description) {
return TRUE; return TRUE;
} }
} }
int32 field::select_option(uint16 step, uint8 playerid) { int32_t field::select_option(uint16_t step, uint8_t playerid) {
if(step == 0) { if(step == 0) {
returns.ivalue[0] = -1; returns.ivalue[0] = -1;
if(core.select_options.size() == 0) if(core.select_options.size() == 0)
...@@ -209,95 +223,97 @@ int32 field::select_option(uint16 step, uint8 playerid) { ...@@ -209,95 +223,97 @@ int32 field::select_option(uint16 step, uint8 playerid) {
} }
pduel->write_buffer8(MSG_SELECT_OPTION); pduel->write_buffer8(MSG_SELECT_OPTION);
pduel->write_buffer8(playerid); pduel->write_buffer8(playerid);
pduel->write_buffer8((uint8)core.select_options.size()); pduel->write_buffer8((uint8_t)core.select_options.size());
for(auto& option : core.select_options) for(auto& option : core.select_options)
pduel->write_buffer32(option); pduel->write_buffer32(option);
return FALSE; return FALSE;
} else { } else {
if(returns.ivalue[0] < 0 || returns.ivalue[0] >= (int32)core.select_options.size()) { if(returns.ivalue[0] < 0 || returns.ivalue[0] >= (int32_t)core.select_options.size()) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
} }
int32 field::select_card(uint16 step, uint8 playerid, uint8 cancelable, uint8 min, uint8 max) { int32_t field::select_card(uint16_t step, uint8_t playerid, uint8_t cancelable, uint8_t min, uint8_t max) {
if(step == 0) { if(step == 0) {
returns.bvalue[0] = 0; returns.bvalue[0] = 0;
if(max == 0 || core.select_cards.empty()) if(max == 0 || core.select_cards.empty())
return TRUE; return TRUE;
if(max > 127) core.selecting_player = playerid;
max = 127; std::sort(core.select_cards.begin(), core.select_cards.end(), card::card_operation_sort);
if (core.select_cards.size() > UINT8_MAX)
core.select_cards.resize(UINT8_MAX);
if(max > core.select_cards.size()) if(max > core.select_cards.size())
max = (uint8)core.select_cards.size(); max = (uint8_t)core.select_cards.size();
if(min > max) if(min > max)
min = max; min = max;
if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) { if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) {
returns.bvalue[0] = min; returns.bvalue[0] = min;
for(uint8 i = 0; i < min; ++i) for(uint8_t i = 0; i < min; ++i)
returns.bvalue[i + 1] = i; returns.bvalue[i + 1] = i;
return TRUE; return TRUE;
} }
core.units.begin()->arg2 = ((uint32)min) + (((uint32)max) << 16); core.units.begin()->arg2 = ((uint32_t)min) + (((uint32_t)max) << 16);
pduel->write_buffer8(MSG_SELECT_CARD); pduel->write_buffer8(MSG_SELECT_CARD);
pduel->write_buffer8(playerid); pduel->write_buffer8(playerid);
pduel->write_buffer8(cancelable); pduel->write_buffer8(cancelable);
pduel->write_buffer8(min); pduel->write_buffer8(min);
pduel->write_buffer8(max); pduel->write_buffer8(max);
pduel->write_buffer8((uint8)core.select_cards.size()); pduel->write_buffer8((uint8_t)core.select_cards.size());
std::sort(core.select_cards.begin(), core.select_cards.end(), card::card_operation_sort); uint8_t deck_seq = 0;
for(auto& pcard : core.select_cards) { for(auto& pcard : core.select_cards) {
pduel->write_buffer32(pcard->data.code); pduel->write_buffer32(pcard->data.code);
pduel->write_buffer32(pcard->get_info_location()); pduel->write_buffer32(pcard->get_select_info_location(&deck_seq));
} }
return FALSE; return FALSE;
} else { } else {
if(cancelable && returns.ivalue[0] == -1) if (returns.ivalue[0] == -1) {
if (cancelable)
return TRUE; return TRUE;
if(returns.bvalue[0] < min || returns.bvalue[0] > max) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
std::set<int8> c; if (!check_response(core.select_cards.size(), min, max)) {
uint8 m = (uint8)core.select_cards.size();
for(int32 i = 0; i < returns.bvalue[0]; ++i) {
int8 v = returns.bvalue[i + 1];
if(v < 0 || v >= m || c.count(v)) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
c.insert(v);
}
return TRUE; return TRUE;
} }
} }
int32 field::select_unselect_card(uint16 step, uint8 playerid, uint8 cancelable, uint8 min, uint8 max, uint8 finishable) { int32_t field::select_unselect_card(uint16_t step, uint8_t playerid, uint8_t cancelable, uint8_t min, uint8_t max, uint8_t finishable) {
if(step == 0) { if(step == 0) {
returns.bvalue[0] = 0; returns.bvalue[0] = 0;
if(core.select_cards.empty() && core.unselect_cards.empty()) if(core.select_cards.empty() && core.unselect_cards.empty())
return TRUE; return TRUE;
if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) { if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) {
returns.bvalue[0] = 1; returns.bvalue[0] = 1;
for(uint8 i = 0; i < 1; ++i) for(uint8_t i = 0; i < 1; ++i)
returns.bvalue[i + 1] = i; returns.bvalue[i + 1] = i;
return TRUE; return TRUE;
} }
core.selecting_player = playerid;
std::sort(core.select_cards.begin(), core.select_cards.end(), card::card_operation_sort);
if (core.select_cards.size() > UINT8_MAX)
core.select_cards.resize(UINT8_MAX);
if (core.unselect_cards.size() > UINT8_MAX)
core.unselect_cards.resize(UINT8_MAX);
pduel->write_buffer8(MSG_SELECT_UNSELECT_CARD); pduel->write_buffer8(MSG_SELECT_UNSELECT_CARD);
pduel->write_buffer8(playerid); pduel->write_buffer8(playerid);
pduel->write_buffer8(finishable); pduel->write_buffer8(finishable);
pduel->write_buffer8(cancelable); pduel->write_buffer8(cancelable);
pduel->write_buffer8(min); pduel->write_buffer8(min);
pduel->write_buffer8(max); pduel->write_buffer8(max);
pduel->write_buffer8((uint8)core.select_cards.size()); pduel->write_buffer8((uint8_t)core.select_cards.size());
std::sort(core.select_cards.begin(), core.select_cards.end(), card::card_operation_sort); uint8_t deck_seq = 0;
for(auto& pcard : core.select_cards) { for(auto& pcard : core.select_cards) {
pduel->write_buffer32(pcard->data.code); pduel->write_buffer32(pcard->data.code);
pduel->write_buffer32(pcard->get_info_location()); pduel->write_buffer32(pcard->get_select_info_location(&deck_seq));
} }
pduel->write_buffer8((uint8)core.unselect_cards.size()); pduel->write_buffer8((uint8_t)core.unselect_cards.size());
for(auto& pcard : core.unselect_cards) { for(auto& pcard : core.unselect_cards) {
pduel->write_buffer32(pcard->data.code); pduel->write_buffer32(pcard->data.code);
pduel->write_buffer32(pcard->get_info_location()); pduel->write_buffer32(pcard->get_select_info_location(&deck_seq));
} }
return FALSE; return FALSE;
} else { } else {
...@@ -307,20 +323,14 @@ int32 field::select_unselect_card(uint16 step, uint8 playerid, uint8 cancelable, ...@@ -307,20 +323,14 @@ int32 field::select_unselect_card(uint16 step, uint8 playerid, uint8 cancelable,
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
if(returns.bvalue[0] == 0 || returns.bvalue[0] > 1) { if (!check_response(core.select_cards.size() + core.unselect_cards.size(), 1, 1)) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
uint8 m = (uint8)core.select_cards.size() + (uint8)core.unselect_cards.size();
uint8 v = returns.bvalue[1];
if(v < 0 || v >= m) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
} }
int32 field::select_chain(uint16 step, uint8 playerid, uint8 spe_count, uint8 forced) { int32_t field::select_chain(uint16_t step, uint8_t playerid, uint8_t spe_count, uint8_t forced) {
if(step == 0) { if(step == 0) {
returns.ivalue[0] = -1; returns.ivalue[0] = -1;
if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) { if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) {
...@@ -342,7 +352,7 @@ int32 field::select_chain(uint16 step, uint8 playerid, uint8 spe_count, uint8 fo ...@@ -342,7 +352,7 @@ int32 field::select_chain(uint16 step, uint8 playerid, uint8 spe_count, uint8 fo
} }
pduel->write_buffer8(MSG_SELECT_CHAIN); pduel->write_buffer8(MSG_SELECT_CHAIN);
pduel->write_buffer8(playerid); pduel->write_buffer8(playerid);
pduel->write_buffer8((uint8)core.select_chains.size()); pduel->write_buffer8((uint8_t)core.select_chains.size());
pduel->write_buffer8(spe_count); pduel->write_buffer8(spe_count);
pduel->write_buffer8(forced); pduel->write_buffer8(forced);
pduel->write_buffer32(pduel->game_field->core.hint_timing[playerid]); pduel->write_buffer32(pduel->game_field->core.hint_timing[playerid]);
...@@ -363,21 +373,25 @@ int32 field::select_chain(uint16 step, uint8 playerid, uint8 spe_count, uint8 fo ...@@ -363,21 +373,25 @@ int32 field::select_chain(uint16 step, uint8 playerid, uint8 spe_count, uint8 fo
} }
return FALSE; return FALSE;
} else { } else {
if(!forced && returns.ivalue[0] == -1) if (returns.ivalue[0] == -1) {
if (!forced)
return TRUE; return TRUE;
if(returns.ivalue[0] < 0 || returns.ivalue[0] >= (int32)core.select_chains.size()) { pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
if(returns.ivalue[0] < 0 || returns.ivalue[0] >= (int32_t)core.select_chains.size()) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
} }
int32 field::select_place(uint16 step, uint8 playerid, uint32 flag, uint8 count) { int32_t field::select_place(uint16_t step, uint8_t playerid, uint32_t flag, uint8_t count) {
if(step == 0) { if(step == 0) {
if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) { if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) {
flag = ~flag; flag = ~flag;
int32 filter; uint32_t filter;
int32 pzone = 0; int32_t pzone = 0;
if(flag & 0x7f) { if(flag & 0x7f) {
returns.bvalue[0] = 1; returns.bvalue[0] = 1;
returns.bvalue[1] = LOCATION_MZONE; returns.bvalue[1] = LOCATION_MZONE;
...@@ -429,13 +443,14 @@ int32 field::select_place(uint16 step, uint8 playerid, uint32 flag, uint8 count) ...@@ -429,13 +443,14 @@ int32 field::select_place(uint16 step, uint8 playerid, uint32 flag, uint8 count)
returns.bvalue[0] = 0; returns.bvalue[0] = 0;
return FALSE; return FALSE;
} else { } else {
uint8 pt = 0; uint8_t pt = 0;
uint32 selected = 0; uint32_t selected = 0;
for(int8 i = 0; i < 1 || i < count; ++i) { int32_t len = std::max(1, (int32_t)count);
uint8 p = returns.bvalue[pt]; for (int32_t i = 0; i < len; ++i) {
uint8 l = returns.bvalue[pt + 1]; uint8_t p = returns.bvalue[pt];
uint8 s = returns.bvalue[pt + 2]; uint8_t l = returns.bvalue[pt + 1];
uint32 sel = 0x1u << (s + (p == playerid ? 0 : 16) + (l == LOCATION_MZONE ? 0 : 8)); uint8_t s = returns.bvalue[pt + 2];
uint32_t sel = 0x1u << (s + (p == playerid ? 0 : 16) + (l == LOCATION_MZONE ? 0 : 8));
if(!(count == 0 && i == 0 && l == 0) if(!(count == 0 && i == 0 && l == 0)
&& ((p != 0 && p != 1) && ((p != 0 && p != 1)
|| ((l != LOCATION_MZONE) && (l != LOCATION_SZONE)) || ((l != LOCATION_MZONE) && (l != LOCATION_SZONE))
...@@ -443,17 +458,17 @@ int32 field::select_place(uint16 step, uint8 playerid, uint32 flag, uint8 count) ...@@ -443,17 +458,17 @@ int32 field::select_place(uint16 step, uint8 playerid, uint32 flag, uint8 count)
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
if(sel & (0x1 << 5)) if(sel & (0x1u << 5))
sel |= 0x1 << (16 + 6); sel |= 0x1u << (16 + 6);
if(sel & (0x1 << 6)) if(sel & (0x1u << 6))
sel |= 0x1 << (16 + 5); sel |= 0x1u << (16 + 5);
selected |= sel; selected |= sel;
pt += 3; pt += 3;
} }
return TRUE; return TRUE;
} }
} }
int32 field::select_position(uint16 step, uint8 playerid, uint32 code, uint8 positions) { int32_t field::select_position(uint16_t step, uint8_t playerid, uint32_t code, uint8_t positions) {
if(step == 0) { if(step == 0) {
if(positions == 0) { if(positions == 0) {
returns.ivalue[0] = POS_FACEUP_ATTACK; returns.ivalue[0] = POS_FACEUP_ATTACK;
...@@ -465,11 +480,11 @@ int32 field::select_position(uint16 step, uint8 playerid, uint32 code, uint8 pos ...@@ -465,11 +480,11 @@ int32 field::select_position(uint16 step, uint8 playerid, uint32 code, uint8 pos
return TRUE; return TRUE;
} }
if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) { if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) {
if(positions & 0x4) if((uint32_t)positions & 0x4)
returns.ivalue[0] = 0x4; returns.ivalue[0] = 0x4;
else if(positions & 0x1) else if((uint32_t)positions & 0x1)
returns.ivalue[0] = 0x1; returns.ivalue[0] = 0x1;
else if(positions & 0x8) else if((uint32_t)positions & 0x8)
returns.ivalue[0] = 0x8; returns.ivalue[0] = 0x8;
else else
returns.ivalue[0] = 0x2; returns.ivalue[0] = 0x2;
...@@ -482,7 +497,7 @@ int32 field::select_position(uint16 step, uint8 playerid, uint32 code, uint8 pos ...@@ -482,7 +497,7 @@ int32 field::select_position(uint16 step, uint8 playerid, uint32 code, uint8 pos
returns.ivalue[0] = 0; returns.ivalue[0] = 0;
return FALSE; return FALSE;
} else { } else {
uint32 pos = returns.ivalue[0]; uint32_t pos = returns.ivalue[0];
if(pos != 0x1 && pos != 0x2 && pos != 0x4 && pos != 0x8 || !(pos & positions)) { if(pos != 0x1 && pos != 0x2 && pos != 0x4 && pos != 0x8 || !(pos & positions)) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
...@@ -490,12 +505,16 @@ int32 field::select_position(uint16 step, uint8 playerid, uint32 code, uint8 pos ...@@ -490,12 +505,16 @@ int32 field::select_position(uint16 step, uint8 playerid, uint32 code, uint8 pos
return TRUE; return TRUE;
} }
} }
int32 field::select_tribute(uint16 step, uint8 playerid, uint8 cancelable, uint8 min, uint8 max) { int32_t field::select_tribute(uint16_t step, uint8_t playerid, uint8_t cancelable, uint8_t min, uint8_t max) {
if(step == 0) { if(step == 0) {
returns.bvalue[0] = 0; returns.bvalue[0] = 0;
if(max == 0 || core.select_cards.empty()) if(max == 0 || core.select_cards.empty())
return TRUE; return TRUE;
uint8 tm = 0; core.selecting_player = playerid;
std::sort(core.select_cards.begin(), core.select_cards.end(), card::card_operation_sort);
if (core.select_cards.size() > UINT8_MAX)
core.select_cards.resize(UINT8_MAX);
uint8_t tm = 0;
for(auto& pcard : core.select_cards) for(auto& pcard : core.select_cards)
tm += pcard->release_param; tm += pcard->release_param;
if(max > 5) if(max > 5)
...@@ -504,34 +523,38 @@ int32 field::select_tribute(uint16 step, uint8 playerid, uint8 cancelable, uint8 ...@@ -504,34 +523,38 @@ int32 field::select_tribute(uint16 step, uint8 playerid, uint8 cancelable, uint8
max = tm; max = tm;
if(min > max) if(min > max)
min = max; min = max;
core.units.begin()->arg2 = ((uint32)min) + (((uint32)max) << 16); core.units.begin()->arg2 = ((uint32_t)min) + (((uint32_t)max) << 16);
pduel->write_buffer8(MSG_SELECT_TRIBUTE); pduel->write_buffer8(MSG_SELECT_TRIBUTE);
pduel->write_buffer8(playerid); pduel->write_buffer8(playerid);
pduel->write_buffer8(cancelable); pduel->write_buffer8(cancelable);
pduel->write_buffer8(min); pduel->write_buffer8(min);
pduel->write_buffer8(max); pduel->write_buffer8(max);
pduel->write_buffer8((uint8)core.select_cards.size()); pduel->write_buffer8((uint8_t)core.select_cards.size());
std::sort(core.select_cards.begin(), core.select_cards.end(), card::card_operation_sort); uint8_t deck_seq = 0;
for(auto& pcard : core.select_cards) { for(auto& pcard : core.select_cards) {
pduel->write_buffer32(pcard->data.code); pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler); pduel->write_buffer8(pcard->current.controler);
pduel->write_buffer8(pcard->current.location); pduel->write_buffer8(pcard->current.location);
pduel->write_buffer8(pcard->current.sequence); pduel->write_buffer8(pcard->get_select_sequence(&deck_seq));
pduel->write_buffer8(pcard->release_param); pduel->write_buffer8(pcard->release_param);
} }
return FALSE; return FALSE;
} else { } else {
if(cancelable && returns.ivalue[0] == -1) if (returns.ivalue[0] == -1) {
if (cancelable)
return TRUE; return TRUE;
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
if(returns.bvalue[0] > max) { if(returns.bvalue[0] > max) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
std::set<int8> c; std::set<uint8_t> c;
uint8 m = (uint8)core.select_cards.size(), tt = 0; int32_t m = (int32_t)core.select_cards.size(), tt = 0;
for(int32 i = 0; i < returns.bvalue[0]; ++i) { for(int32_t i = 0; i < returns.bvalue[0]; ++i) {
int8 v = returns.bvalue[i + 1]; uint8_t v = returns.bvalue[i + 1];
if(v < 0 || v >= m || c.count(v)) { if(v >= m || c.count(v)) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
...@@ -545,13 +568,13 @@ int32 field::select_tribute(uint16 step, uint8 playerid, uint8 cancelable, uint8 ...@@ -545,13 +568,13 @@ int32 field::select_tribute(uint16 step, uint8 playerid, uint8 cancelable, uint8
return TRUE; return TRUE;
} }
} }
int32 field::select_counter(uint16 step, uint8 playerid, uint16 countertype, uint16 count, uint8 s, uint8 o) { int32_t field::select_counter(uint16_t step, uint8_t playerid, uint16_t countertype, uint16_t count, uint8_t s, uint8_t o) {
if(step == 0) { if(step == 0) {
if(count == 0) if(count == 0)
return TRUE; return TRUE;
uint8 avail = s; uint8_t avail = s;
uint8 fp = playerid; uint8_t fp = playerid;
uint32 total = 0; uint32_t total = 0;
core.select_cards.clear(); core.select_cards.clear();
for(int p = 0; p < 2; ++p) { for(int p = 0; p < 2; ++p) {
if(avail) { if(avail) {
...@@ -579,19 +602,21 @@ int32 field::select_counter(uint16 step, uint8 playerid, uint16 countertype, uin ...@@ -579,19 +602,21 @@ int32 field::select_counter(uint16 step, uint8 playerid, uint16 countertype, uin
pduel->write_buffer8(playerid); pduel->write_buffer8(playerid);
pduel->write_buffer16(countertype); pduel->write_buffer16(countertype);
pduel->write_buffer16(count); pduel->write_buffer16(count);
pduel->write_buffer8((uint8)core.select_cards.size()); pduel->write_buffer8((uint8_t)core.select_cards.size());
core.selecting_player = playerid;
std::sort(core.select_cards.begin(), core.select_cards.end(), card::card_operation_sort); std::sort(core.select_cards.begin(), core.select_cards.end(), card::card_operation_sort);
uint8_t deck_seq = 0;
for(auto& pcard : core.select_cards) { for(auto& pcard : core.select_cards) {
pduel->write_buffer32(pcard->data.code); pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler); pduel->write_buffer8(pcard->current.controler);
pduel->write_buffer8(pcard->current.location); pduel->write_buffer8(pcard->current.location);
pduel->write_buffer8(pcard->current.sequence); pduel->write_buffer8(pcard->get_select_sequence(&deck_seq));
pduel->write_buffer16(pcard->get_counter(countertype)); pduel->write_buffer16(pcard->get_counter(countertype));
} }
return FALSE; return FALSE;
} else { } else {
uint16 ct = 0; int32_t ct = 0;
for(uint32 i = 0; i < core.select_cards.size(); ++i) { for(int32_t i = 0; i < (int32_t)core.select_cards.size(); ++i) {
if(core.select_cards[i]->get_counter(countertype) < returns.svalue[i]) { if(core.select_cards[i]->get_counter(countertype) < returns.svalue[i]) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
...@@ -605,21 +630,27 @@ int32 field::select_counter(uint16 step, uint8 playerid, uint16 countertype, uin ...@@ -605,21 +630,27 @@ int32 field::select_counter(uint16 step, uint8 playerid, uint16 countertype, uin
} }
return TRUE; return TRUE;
} }
static int32 select_sum_check1(const int32* oparam, int32 size, int32 index, int32 acc, int32 opmin) { static int32_t select_sum_check1(const uint32_t* oparam, int32_t size, int32_t index, int32_t acc, int32_t opmin) {
if(acc == 0 || index == size) if(acc == 0 || index == size)
return FALSE; return FALSE;
int32 o1 = oparam[index] & 0xffff; int32_t o1 = oparam[index] & 0xffff;
int32 o2 = oparam[index] >> 16; int32_t o2 = oparam[index] >> 16;
if(index == size - 1) if(index == size - 1)
return (acc == o1 && acc + opmin > o1) || (o2 && acc == o2 && acc + opmin > o2); return (acc == o1 && acc + opmin > o1) || (o2 && acc == o2 && acc + opmin > o2);
return (acc > o1 && select_sum_check1(oparam, size, index + 1, acc - o1, std::min(o1, opmin))) return (acc > o1 && select_sum_check1(oparam, size, index + 1, acc - o1, std::min(o1, opmin)))
|| (o2 > 0 && acc > o2 && select_sum_check1(oparam, size, index + 1, acc - o2, std::min(o2, opmin))); || (o2 > 0 && acc > o2 && select_sum_check1(oparam, size, index + 1, acc - o2, std::min(o2, opmin)));
} }
int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32 min, int32 max) { int32_t field::select_with_sum_limit(int16_t step, uint8_t playerid, int32_t acc, int32_t min, int32_t max) {
if(step == 0) { if(step == 0) {
returns.bvalue[0] = 0; returns.bvalue[0] = 0;
if(core.select_cards.empty()) if(core.select_cards.empty())
return TRUE; return TRUE;
core.selecting_player = playerid;
std::sort(core.select_cards.begin(), core.select_cards.end(), card::card_operation_sort);
if (core.select_cards.size() > UINT8_MAX)
core.select_cards.resize(UINT8_MAX);
if (core.must_select_cards.size() > UINT8_MAX)
core.must_select_cards.resize(UINT8_MAX);
pduel->write_buffer8(MSG_SELECT_SUM); pduel->write_buffer8(MSG_SELECT_SUM);
if(max) if(max)
pduel->write_buffer8(0); pduel->write_buffer8(0);
...@@ -628,41 +659,43 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32 ...@@ -628,41 +659,43 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32
if(max < min) if(max < min)
max = min; max = min;
pduel->write_buffer8(playerid); pduel->write_buffer8(playerid);
pduel->write_buffer32(acc & 0xffff); pduel->write_buffer32((uint32_t)acc & 0xffff);
pduel->write_buffer8(min); pduel->write_buffer8(min);
pduel->write_buffer8(max); pduel->write_buffer8(max);
pduel->write_buffer8((uint8)core.must_select_cards.size()); pduel->write_buffer8((uint8_t)core.must_select_cards.size());
uint8_t deck_seq = 0;
for(auto& pcard : core.must_select_cards) { for(auto& pcard : core.must_select_cards) {
pduel->write_buffer32(pcard->data.code); pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler); pduel->write_buffer8(pcard->current.controler);
pduel->write_buffer8(pcard->current.location); pduel->write_buffer8(pcard->current.location);
pduel->write_buffer8(pcard->current.sequence); pduel->write_buffer8(pcard->get_select_sequence(&deck_seq));
pduel->write_buffer32(pcard->sum_param); pduel->write_buffer32(pcard->sum_param);
} }
pduel->write_buffer8((uint8)core.select_cards.size()); pduel->write_buffer8((uint8_t)core.select_cards.size());
std::sort(core.select_cards.begin(), core.select_cards.end(), card::card_operation_sort);
for(auto& pcard : core.select_cards) { for(auto& pcard : core.select_cards) {
pduel->write_buffer32(pcard->data.code); pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler); pduel->write_buffer8(pcard->current.controler);
pduel->write_buffer8(pcard->current.location); pduel->write_buffer8(pcard->current.location);
pduel->write_buffer8(pcard->current.sequence); pduel->write_buffer8(pcard->get_select_sequence(&deck_seq));
pduel->write_buffer32(pcard->sum_param); pduel->write_buffer32(pcard->sum_param);
} }
return FALSE; return FALSE;
} else { } else {
std::set<int32> c; std::set<int32_t> c;
int32_t mcount = (int32_t)core.must_select_cards.size();
if (mcount > UINT8_MAX)
mcount = UINT8_MAX;
if(max) { if(max) {
int32 oparam[16]; uint32_t oparam[512]{};
int32 mcount = (int32)core.must_select_cards.size();
if(returns.bvalue[0] < min + mcount || returns.bvalue[0] > max + mcount) { if(returns.bvalue[0] < min + mcount || returns.bvalue[0] > max + mcount) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
for(int32 i = 0; i < mcount; ++i) for(int32_t i = 0; i < mcount; ++i)
oparam[i] = core.must_select_cards[i]->sum_param; oparam[i] = core.must_select_cards[i]->sum_param;
int32 m = (int32)core.select_cards.size(); int32_t m = (int32_t)core.select_cards.size();
for(int32 i = mcount; i < returns.bvalue[0]; ++i) { for(int32_t i = mcount; i < returns.bvalue[0]; ++i) {
int32 v = returns.bvalue[i + 1]; int32_t v = returns.bvalue[i + 1];
if(v < 0 || v >= m || c.count(v)) { if(v < 0 || v >= m || c.count(v)) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
...@@ -676,32 +709,31 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32 ...@@ -676,32 +709,31 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32
} }
return TRUE; return TRUE;
} else { } else {
int32 mcount = (int32)core.must_select_cards.size(); int32_t sum = 0, mx = 0, mn = 0x7fffffff;
int32 sum = 0, mx = 0, mn = 0x7fffffff; for(int32_t i = 0; i < mcount; ++i) {
for(int32 i = 0; i < mcount; ++i) { uint32_t op = core.must_select_cards[i]->sum_param;
int32 op = core.must_select_cards[i]->sum_param; int32_t o1 = op & 0xffff;
int32 o1 = op & 0xffff; int32_t o2 = op >> 16;
int32 o2 = op >> 16; int32_t ms = (o2 && o2 < o1) ? o2 : o1;
int32 ms = (o2 && o2 < o1) ? o2 : o1;
sum += ms; sum += ms;
mx += (o2 > o1) ? o2 : o1; mx += std::max(o1, o2);
if(ms < mn) if(ms < mn)
mn = ms; mn = ms;
} }
int32 m = (int32)core.select_cards.size(); int32_t m = (int32_t)core.select_cards.size();
for(int32 i = mcount; i < returns.bvalue[0]; ++i) { for(int32_t i = mcount; i < returns.bvalue[0]; ++i) {
int32 v = returns.bvalue[i + 1]; int32_t v = returns.bvalue[i + 1];
if(v < 0 || v >= m || c.count(v)) { if(v < 0 || v >= m || c.count(v)) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
c.insert(v); c.insert(v);
int32 op = core.select_cards[v]->sum_param; uint32_t op = core.select_cards[v]->sum_param;
int32 o1 = op & 0xffff; int32_t o1 = op & 0xffff;
int32 o2 = op >> 16; int32_t o2 = op >> 16;
int32 ms = (o2 && o2 < o1) ? o2 : o1; int32_t ms = (o2 && o2 < o1) ? o2 : o1;
sum += ms; sum += ms;
mx += (o2 > o1) ? o2 : o1; mx += std::max(o1, o2);
if(ms < mn) if(ms < mn)
mn = ms; mn = ms;
} }
...@@ -714,18 +746,20 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32 ...@@ -714,18 +746,20 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32
} }
return TRUE; return TRUE;
} }
int32 field::sort_card(int16 step, uint8 playerid) { int32_t field::sort_card(int16_t step, uint8_t playerid) {
if(step == 0) { if(step == 0) {
returns.bvalue[0] = 0; returns.bvalue[0] = 0;
if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) { if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) {
returns.bvalue[0] = -1; returns.bvalue[0] = 0xff;
return TRUE; return TRUE;
} }
if(core.select_cards.empty()) if(core.select_cards.empty())
return TRUE; return TRUE;
if (core.select_cards.size() > UINT8_MAX)
core.select_cards.resize(UINT8_MAX);
pduel->write_buffer8(MSG_SORT_CARD); pduel->write_buffer8(MSG_SORT_CARD);
pduel->write_buffer8(playerid); pduel->write_buffer8(playerid);
pduel->write_buffer8((uint8)core.select_cards.size()); pduel->write_buffer8((uint8_t)core.select_cards.size());
for(auto& pcard : core.select_cards) { for(auto& pcard : core.select_cards) {
pduel->write_buffer32(pcard->data.code); pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler); pduel->write_buffer8(pcard->current.controler);
...@@ -734,13 +768,13 @@ int32 field::sort_card(int16 step, uint8 playerid) { ...@@ -734,13 +768,13 @@ int32 field::sort_card(int16 step, uint8 playerid) {
} }
return FALSE; return FALSE;
} else { } else {
if(returns.bvalue[0] == -1) if(returns.bvalue[0] == 0xff)
return TRUE; return TRUE;
std::set<int8> c; std::set<uint8_t> c;
uint8 m = (uint8)core.select_cards.size(); int32_t m = (int32_t)core.select_cards.size();
for(uint8 i = 0; i < m; ++i) { for(int32_t i = 0; i < m; ++i) {
int8 v = returns.bvalue[i]; uint8_t v = returns.bvalue[i];
if(v < 0 || v >= m || c.count(v)) { if(v >= m || c.count(v)) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
...@@ -750,12 +784,12 @@ int32 field::sort_card(int16 step, uint8 playerid) { ...@@ -750,12 +784,12 @@ int32 field::sort_card(int16 step, uint8 playerid) {
} }
return TRUE; return TRUE;
} }
int32 field::announce_race(int16 step, uint8 playerid, int32 count, int32 available) { int32_t field::announce_race(int16_t step, uint8_t playerid, int32_t count, int32_t available) {
if(step == 0) { if(step == 0) {
int32 scount = 0; int32_t scount = 0;
for(int32 ft = 0x1; ft != 0x2000000; ft <<= 1) { for(uint32_t ft = 0x1; ft < (0x1U << RACES_COUNT); ft <<= 1) {
if(ft & available) if(ft & available)
scount++; ++scount;
} }
if(scount <= count) { if(scount <= count) {
count = scount; count = scount;
...@@ -767,15 +801,16 @@ int32 field::announce_race(int16 step, uint8 playerid, int32 count, int32 availa ...@@ -767,15 +801,16 @@ int32 field::announce_race(int16 step, uint8 playerid, int32 count, int32 availa
pduel->write_buffer32(available); pduel->write_buffer32(available);
return FALSE; return FALSE;
} else { } else {
int32 rc = returns.ivalue[0]; int32_t rc = returns.ivalue[0];
int32 sel = 0; int32_t sel = 0;
for(int32 ft = 0x1; ft != 0x2000000; ft <<= 1) { for(uint32_t ft = 0x1; ft < (0x1U << RACES_COUNT); ft <<= 1) {
if(!(ft & rc)) continue; if(!(ft & rc))
continue;
if(!(ft & available)) { if(!(ft & available)) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
sel++; ++sel;
} }
if(sel != count) { if(sel != count) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
...@@ -789,12 +824,12 @@ int32 field::announce_race(int16 step, uint8 playerid, int32 count, int32 availa ...@@ -789,12 +824,12 @@ int32 field::announce_race(int16 step, uint8 playerid, int32 count, int32 availa
} }
return TRUE; return TRUE;
} }
int32 field::announce_attribute(int16 step, uint8 playerid, int32 count, int32 available) { int32_t field::announce_attribute(int16_t step, uint8_t playerid, int32_t count, int32_t available) {
if(step == 0) { if(step == 0) {
int32 scount = 0; int32_t scount = 0;
for(int32 ft = 0x1; ft != 0x80; ft <<= 1) { for(int32_t ft = 0x1; ft != 0x80; ft <<= 1) {
if(ft & available) if(ft & available)
scount++; ++scount;
} }
if(scount <= count) { if(scount <= count) {
count = scount; count = scount;
...@@ -806,15 +841,15 @@ int32 field::announce_attribute(int16 step, uint8 playerid, int32 count, int32 a ...@@ -806,15 +841,15 @@ int32 field::announce_attribute(int16 step, uint8 playerid, int32 count, int32 a
pduel->write_buffer32(available); pduel->write_buffer32(available);
return FALSE; return FALSE;
} else { } else {
int32 rc = returns.ivalue[0]; int32_t rc = returns.ivalue[0];
int32 sel = 0; int32_t sel = 0;
for(int32 ft = 0x1; ft != 0x80; ft <<= 1) { for(int32_t ft = 0x1; ft != 0x80; ft <<= 1) {
if(!(ft & rc)) continue; if(!(ft & rc)) continue;
if(!(ft & available)) { if(!(ft & available)) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
sel++; ++sel;
} }
if(sel != count) { if(sel != count) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
...@@ -828,15 +863,15 @@ int32 field::announce_attribute(int16 step, uint8 playerid, int32 count, int32 a ...@@ -828,15 +863,15 @@ int32 field::announce_attribute(int16 step, uint8 playerid, int32 count, int32 a
} }
return TRUE; return TRUE;
} }
static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcode) { static int32_t is_declarable(card_data const& cd, const std::vector<uint32_t>& opcode) {
std::stack<int32> stack; std::stack<int32_t> stack;
for(auto& it : opcode) { for(auto& it : opcode) {
switch(it) { switch(it) {
case OPCODE_ADD: { case OPCODE_ADD: {
if(stack.size() >= 2) { if(stack.size() >= 2) {
int32 rhs = stack.top(); int32_t rhs = stack.top();
stack.pop(); stack.pop();
int32 lhs = stack.top(); int32_t lhs = stack.top();
stack.pop(); stack.pop();
stack.push(lhs + rhs); stack.push(lhs + rhs);
} }
...@@ -844,9 +879,9 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod ...@@ -844,9 +879,9 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
} }
case OPCODE_SUB: { case OPCODE_SUB: {
if(stack.size() >= 2) { if(stack.size() >= 2) {
int32 rhs = stack.top(); int32_t rhs = stack.top();
stack.pop(); stack.pop();
int32 lhs = stack.top(); int32_t lhs = stack.top();
stack.pop(); stack.pop();
stack.push(lhs - rhs); stack.push(lhs - rhs);
} }
...@@ -854,9 +889,9 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod ...@@ -854,9 +889,9 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
} }
case OPCODE_MUL: { case OPCODE_MUL: {
if(stack.size() >= 2) { if(stack.size() >= 2) {
int32 rhs = stack.top(); int32_t rhs = stack.top();
stack.pop(); stack.pop();
int32 lhs = stack.top(); int32_t lhs = stack.top();
stack.pop(); stack.pop();
stack.push(lhs * rhs); stack.push(lhs * rhs);
} }
...@@ -864,9 +899,9 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod ...@@ -864,9 +899,9 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
} }
case OPCODE_DIV: { case OPCODE_DIV: {
if(stack.size() >= 2) { if(stack.size() >= 2) {
int32 rhs = stack.top(); int32_t rhs = stack.top();
stack.pop(); stack.pop();
int32 lhs = stack.top(); int32_t lhs = stack.top();
stack.pop(); stack.pop();
stack.push(lhs / rhs); stack.push(lhs / rhs);
} }
...@@ -874,27 +909,27 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod ...@@ -874,27 +909,27 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
} }
case OPCODE_AND: { case OPCODE_AND: {
if(stack.size() >= 2) { if(stack.size() >= 2) {
int32 rhs = stack.top(); int32_t rhs = stack.top();
stack.pop(); stack.pop();
int32 lhs = stack.top(); int32_t lhs = stack.top();
stack.pop(); stack.pop();
stack.push(lhs && rhs); stack.push(static_cast<int32_t>(lhs && rhs));
} }
break; break;
} }
case OPCODE_OR: { case OPCODE_OR: {
if(stack.size() >= 2) { if(stack.size() >= 2) {
int32 rhs = stack.top(); int32_t rhs = stack.top();
stack.pop(); stack.pop();
int32 lhs = stack.top(); int32_t lhs = stack.top();
stack.pop(); stack.pop();
stack.push(lhs || rhs); stack.push(static_cast<int32_t>(lhs || rhs));
} }
break; break;
} }
case OPCODE_NEG: { case OPCODE_NEG: {
if(stack.size() >= 1) { if(stack.size() >= 1) {
int32 val = stack.top(); int32_t val = stack.top();
stack.pop(); stack.pop();
stack.push(-val); stack.push(-val);
} }
...@@ -902,15 +937,15 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod ...@@ -902,15 +937,15 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
} }
case OPCODE_NOT: { case OPCODE_NOT: {
if(stack.size() >= 1) { if(stack.size() >= 1) {
int32 val = stack.top(); int32_t val = stack.top();
stack.pop(); stack.pop();
stack.push(!val); stack.push(static_cast<int32_t>(!val));
} }
break; break;
} }
case OPCODE_ISCODE: { case OPCODE_ISCODE: {
if(stack.size() >= 1) { if(stack.size() >= 1) {
int32 code = stack.top(); int32_t code = stack.top();
stack.pop(); stack.pop();
stack.push(cd.code == code); stack.push(cd.code == code);
} }
...@@ -918,24 +953,16 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod ...@@ -918,24 +953,16 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
} }
case OPCODE_ISSETCARD: { case OPCODE_ISSETCARD: {
if(stack.size() >= 1) { if(stack.size() >= 1) {
int32 set_code = stack.top(); int32_t set_code = stack.top();
stack.pop(); stack.pop();
uint64 sc = cd.setcode; bool res = cd.is_setcode(set_code);
bool res = false;
uint32 settype = set_code & 0xfff;
uint32 setsubtype = set_code & 0xf000;
while(sc) {
if((sc & 0xfff) == settype && (sc & 0xf000 & setsubtype) == setsubtype)
res = true;
sc = sc >> 16;
}
stack.push(res); stack.push(res);
} }
break; break;
} }
case OPCODE_ISTYPE: { case OPCODE_ISTYPE: {
if(stack.size() >= 1) { if(stack.size() >= 1) {
int32 val = stack.top(); int32_t val = stack.top();
stack.pop(); stack.pop();
stack.push(cd.type & val); stack.push(cd.type & val);
} }
...@@ -943,7 +970,7 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod ...@@ -943,7 +970,7 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
} }
case OPCODE_ISRACE: { case OPCODE_ISRACE: {
if(stack.size() >= 1) { if(stack.size() >= 1) {
int32 race = stack.top(); int32_t race = stack.top();
stack.pop(); stack.pop();
stack.push(cd.race & race); stack.push(cd.race & race);
} }
...@@ -951,7 +978,7 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod ...@@ -951,7 +978,7 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
} }
case OPCODE_ISATTRIBUTE: { case OPCODE_ISATTRIBUTE: {
if(stack.size() >= 1) { if(stack.size() >= 1) {
int32 attribute = stack.top(); int32_t attribute = stack.top();
stack.pop(); stack.pop();
stack.push(cd.attribute & attribute); stack.push(cd.attribute & attribute);
} }
...@@ -966,20 +993,20 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod ...@@ -966,20 +993,20 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
if(stack.size() != 1 || stack.top() == 0) if(stack.size() != 1 || stack.top() == 0)
return FALSE; return FALSE;
return cd.code == CARD_MARINE_DOLPHIN || cd.code == CARD_TWINKLE_MOSS return cd.code == CARD_MARINE_DOLPHIN || cd.code == CARD_TWINKLE_MOSS
|| (!cd.alias && (cd.type & (TYPE_MONSTER + TYPE_TOKEN)) != (TYPE_MONSTER + TYPE_TOKEN)); || (!cd.alias && (cd.type & (TYPE_MONSTER | TYPE_TOKEN)) != (TYPE_MONSTER | TYPE_TOKEN));
} }
int32 field::announce_card(int16 step, uint8 playerid) { int32_t field::announce_card(int16_t step, uint8_t playerid) {
if(step == 0) { if(step == 0) {
pduel->write_buffer8(MSG_ANNOUNCE_CARD); pduel->write_buffer8(MSG_ANNOUNCE_CARD);
pduel->write_buffer8(playerid); pduel->write_buffer8(playerid);
pduel->write_buffer8((uint8)core.select_options.size()); pduel->write_buffer8((uint8_t)core.select_options.size());
for(auto& option : core.select_options) for(auto& option : core.select_options)
pduel->write_buffer32(option); pduel->write_buffer32(option);
return FALSE; return FALSE;
} else { } else {
int32 code = returns.ivalue[0]; int32_t code = returns.ivalue[0];
card_data data; card_data data;
read_card(code, &data); ::read_card(code, &data);
if(!data.code) { if(!data.code) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
...@@ -997,17 +1024,19 @@ int32 field::announce_card(int16 step, uint8 playerid) { ...@@ -997,17 +1024,19 @@ int32 field::announce_card(int16 step, uint8 playerid) {
} }
return TRUE; return TRUE;
} }
int32 field::announce_number(int16 step, uint8 playerid) { int32_t field::announce_number(int16_t step, uint8_t playerid) {
if(step == 0) { if(step == 0) {
if (core.select_options.size() > UINT8_MAX)
core.select_options.resize(UINT8_MAX);
pduel->write_buffer8(MSG_ANNOUNCE_NUMBER); pduel->write_buffer8(MSG_ANNOUNCE_NUMBER);
pduel->write_buffer8(playerid); pduel->write_buffer8(playerid);
pduel->write_buffer8((uint8)core.select_options.size()); pduel->write_buffer8((uint8_t)core.select_options.size());
for(auto& option : core.select_options) for(auto& option : core.select_options)
pduel->write_buffer32(option); pduel->write_buffer32(option);
return FALSE; return FALSE;
} else { } else {
int32 ret = returns.ivalue[0]; int32_t ret = returns.ivalue[0];
if(ret < 0 || ret >= (int32)core.select_options.size()) { if(ret < 0 || ret >= (int32_t)core.select_options.size()) {
pduel->write_buffer8(MSG_RETRY); pduel->write_buffer8(MSG_RETRY);
return FALSE; return FALSE;
} }
......
newoption { trigger = "lua-dir", description = "", value = "PATH", default = "./lua" }
function GetParam(param)
return _OPTIONS[param] or os.getenv(string.upper(string.gsub(param,"-","_")))
end
LUA_DIR=GetParam("lua-dir")
if not os.isdir(LUA_DIR) then
LUA_DIR="../lua"
end
workspace "ocgcoredll"
location "build"
language "C++"
cppdialect "C++14"
configurations { "Release", "Debug" }
platforms { "x32", "x64" }
filter "platforms:x32"
architecture "x32"
filter "platforms:x64"
architecture "x64"
filter "configurations:Release"
optimize "Speed"
filter "configurations:Debug"
symbols "On"
defines "_DEBUG"
filter "system:windows"
systemversion "latest"
startproject "ocgcore"
filter { "configurations:Release", "action:vs*" }
linktimeoptimization "On"
staticruntime "On"
disablewarnings { "4146", "4334" }
filter "action:vs*"
cdialect "C11"
conformancemode "On"
buildoptions { "/utf-8" }
defines { "_CRT_SECURE_NO_WARNINGS" }
filter "system:bsd"
defines { "LUA_USE_POSIX" }
filter "system:macosx"
defines { "LUA_USE_MACOSX" }
filter "system:linux"
defines { "LUA_USE_LINUX" }
pic "On"
filter {}
include(LUA_DIR)
project "ocgcore"
kind "SharedLib"
cppdialect "C++14"
files { "*.cpp", "*.h" }
links { "lua" }
includedirs { LUA_DIR .. "/src" }
project "lua"
kind "StaticLib"
compileas "C++"
files { "src/*.c", "src/*.h" }
removefiles { "src/lua.c", "src/luac.c", "src/linit.c", "src/onelua.c" }
filter "configurations:Debug"
defines { "LUA_USE_APICHECK" }
filter "system:bsd"
defines { "LUA_USE_POSIX" }
filter "system:macosx"
defines { "LUA_USE_MACOSX" }
filter "system:linux"
defines { "LUA_USE_LINUX" }
project "ocgcore" project "ocgcore"
kind "StaticLib" kind "StaticLib"
cppdialect "C++14"
files { "*.cpp", "*.h" } files { "*.cpp", "*.h" }
links { LUA_LIB_NAME }
if BUILD_LUA then if BUILD_LUA then
includedirs { "../lua/src" } includedirs { "../lua/src" }
else else
includedirs { LUA_INCLUDE_DIR } includedirs { LUA_INCLUDE_DIR }
libdirs { LUA_LIB_DIR }
end end
filter "not action:vs*"
buildoptions { "-std=c++14" }
filter "system:bsd" filter "system:bsd"
defines { "LUA_USE_POSIX" } defines { "LUA_USE_POSIX" }
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -7,8 +7,9 @@ ...@@ -7,8 +7,9 @@
#include "scriptlib.h" #include "scriptlib.h"
#include "duel.h" #include "duel.h"
static int32 check_data_type(lua_State* L, int32 index, const char* tname) { static int32_t check_data_type(lua_State* L, int32_t index, const char* tname) {
int32 result = FALSE; luaL_checkstack(L, 2, nullptr);
int32_t result = FALSE;
if(lua_getmetatable(L, index)) { if(lua_getmetatable(L, index)) {
lua_getglobal(L, tname); lua_getglobal(L, tname);
if(lua_rawequal(L, -1, -2)) if(lua_rawequal(L, -1, -2))
...@@ -17,10 +18,11 @@ static int32 check_data_type(lua_State* L, int32 index, const char* tname) { ...@@ -17,10 +18,11 @@ static int32 check_data_type(lua_State* L, int32 index, const char* tname) {
} }
return result; return result;
} }
int32 scriptlib::check_param(lua_State* L, int32 param_type, int32 index, int32 retfalse) { int32_t scriptlib::check_param(lua_State* L, int32_t param_type, int32_t index, int32_t retfalse) {
switch (param_type) { switch (param_type) {
case PARAM_TYPE_CARD: { case PARAM_TYPE_CARD: {
int32 result = FALSE; luaL_checkstack(L, 1, nullptr);
int32_t result = FALSE;
if(lua_isuserdata(L, index) && lua_getmetatable(L, index)) { if(lua_isuserdata(L, index) && lua_getmetatable(L, index)) {
result = check_data_type(L, -1, "Card"); result = check_data_type(L, -1, "Card");
lua_pop(L, 1); lua_pop(L, 1);
...@@ -68,12 +70,12 @@ int32 scriptlib::check_param(lua_State* L, int32 param_type, int32 index, int32 ...@@ -68,12 +70,12 @@ int32 scriptlib::check_param(lua_State* L, int32 param_type, int32 index, int32
return FALSE; return FALSE;
} }
int32 scriptlib::check_param_count(lua_State* L, int32 count) { int32_t scriptlib::check_param_count(lua_State* L, int32_t count) {
if (lua_gettop(L) < count) if (lua_gettop(L) < count)
return luaL_error(L, "%d Parameters are needed.", count); return luaL_error(L, "%d Parameters are needed.", count);
return TRUE; return TRUE;
} }
int32 scriptlib::check_action_permission(lua_State* L) { int32_t scriptlib::check_action_permission(lua_State* L) {
duel* pduel = interpreter::get_duel_info(L); duel* pduel = interpreter::get_duel_info(L);
if(pduel->lua->no_action) if(pduel->lua->no_action)
return luaL_error(L, "Action is not allowed here."); return luaL_error(L, "Action is not allowed here.");
......
...@@ -11,618 +11,658 @@ ...@@ -11,618 +11,658 @@
#include "common.h" #include "common.h"
#include "interpreter.h" #include "interpreter.h"
constexpr bool match_all(uint32_t x, uint32_t y) {
return (x & y) == y;
}
class scriptlib { class scriptlib {
public: public:
static int32 check_param(lua_State* L, int32 param_type, int32 index, BOOL retfalse = FALSE); enum effect_member : int32_t {
static int32 check_param_count(lua_State* L, int32 count); MEMBER_CATEGORY,
static int32 check_action_permission(lua_State* L); MEMBER_CODE,
MEMBER_DESCRIPTION,
MEMBER_ID,
MEMBER_RANGE,
MEMBER_TYPE,
};
static int32_t check_param(lua_State* L, int32_t param_type, int32_t index, int32_t retfalse = FALSE);
static int32_t check_param_count(lua_State* L, int32_t count);
static int32_t check_action_permission(lua_State* L);
//card lib //card lib
static int32 card_get_code(lua_State *L); static int32_t card_get_code(lua_State *L);
static int32 card_get_origin_code(lua_State *L); static int32_t card_get_origin_code(lua_State *L);
static int32 card_get_origin_code_rule(lua_State *L); static int32_t card_get_origin_code_rule(lua_State *L);
static int32 card_get_fusion_code(lua_State *L); static int32_t card_get_fusion_code(lua_State *L);
static int32 card_get_link_code(lua_State *L); static int32_t card_get_link_code(lua_State *L);
static int32 card_is_fusion_code(lua_State *L); static int32_t card_is_fusion_code(lua_State *L);
static int32 card_is_link_code(lua_State *L); static int32_t card_is_link_code(lua_State *L);
static int32 card_is_set_card(lua_State *L); static int32_t card_is_set_card(lua_State *L);
static int32 card_is_origin_set_card(lua_State *L); static int32_t card_is_origin_set_card(lua_State *L);
static int32 card_is_pre_set_card(lua_State *L); static int32_t card_is_pre_set_card(lua_State *L);
static int32 card_is_fusion_set_card(lua_State *L); static int32_t card_is_fusion_set_card(lua_State *L);
static int32 card_is_link_set_card(lua_State *L); static int32_t card_is_link_set_card(lua_State *L);
static int32 card_get_type(lua_State *L); static int32_t card_is_special_summon_set_card(lua_State *L);
static int32 card_get_origin_type(lua_State *L); static int32_t card_get_type(lua_State *L);
static int32 card_get_fusion_type(lua_State *L); static int32_t card_get_origin_type(lua_State *L);
static int32 card_get_synchro_type(lua_State *L); static int32_t card_get_fusion_type(lua_State *L);
static int32 card_get_xyz_type(lua_State *L); static int32_t card_get_synchro_type(lua_State *L);
static int32 card_get_link_type(lua_State *L); static int32_t card_get_xyz_type(lua_State *L);
static int32 card_get_level(lua_State *L); static int32_t card_get_link_type(lua_State *L);
static int32 card_get_rank(lua_State *L); static int32_t card_get_level(lua_State *L);
static int32 card_get_link(lua_State *L); static int32_t card_get_rank(lua_State *L);
static int32 card_get_synchro_level(lua_State *L); static int32_t card_get_link(lua_State *L);
static int32 card_get_ritual_level(lua_State *L); static int32_t card_get_synchro_level(lua_State *L);
static int32 card_get_origin_level(lua_State *L); static int32_t card_get_ritual_level(lua_State *L);
static int32 card_get_origin_rank(lua_State *L); static int32_t card_get_origin_level(lua_State *L);
static int32 card_is_xyz_level(lua_State *L); static int32_t card_get_origin_rank(lua_State *L);
static int32 card_get_lscale(lua_State *L); static int32_t card_is_xyz_level(lua_State *L);
static int32 card_get_origin_lscale(lua_State *L); static int32_t card_get_lscale(lua_State *L);
static int32 card_get_rscale(lua_State *L); static int32_t card_get_origin_lscale(lua_State *L);
static int32 card_get_origin_rscale(lua_State *L); static int32_t card_get_rscale(lua_State *L);
static int32 card_get_current_scale(lua_State *L); static int32_t card_get_origin_rscale(lua_State *L);
static int32 card_is_link_marker(lua_State *L); static int32_t card_get_current_scale(lua_State *L);
static int32 card_get_linked_group(lua_State *L); static int32_t card_is_link_marker(lua_State *L);
static int32 card_get_linked_group_count(lua_State *L); static int32_t card_get_linked_group(lua_State *L);
static int32 card_get_linked_zone(lua_State *L); static int32_t card_get_linked_group_count(lua_State *L);
static int32 card_get_mutual_linked_group(lua_State *L); static int32_t card_get_linked_zone(lua_State *L);
static int32 card_get_mutual_linked_group_count(lua_State *L); static int32_t card_get_mutual_linked_group(lua_State *L);
static int32 card_get_mutual_linked_zone(lua_State *L); static int32_t card_get_mutual_linked_group_count(lua_State *L);
static int32 card_is_link_state(lua_State *L); static int32_t card_get_mutual_linked_zone(lua_State *L);
static int32 card_is_extra_link_state(lua_State *L); static int32_t card_is_link_state(lua_State *L);
static int32 card_get_column_group(lua_State *L); static int32_t card_is_extra_link_state(lua_State *L);
static int32 card_get_column_group_count(lua_State *L); static int32_t card_get_column_group(lua_State *L);
static int32 card_get_column_zone(lua_State *L); static int32_t card_get_column_group_count(lua_State *L);
static int32 card_is_all_column(lua_State *L); static int32_t card_get_column_zone(lua_State *L);
static int32 card_get_attribute(lua_State *L); static int32_t card_is_all_column(lua_State *L);
static int32 card_get_origin_attribute(lua_State *L); static int32_t card_get_attribute(lua_State *L);
static int32 card_get_fusion_attribute(lua_State *L); static int32_t card_get_origin_attribute(lua_State *L);
static int32 card_get_link_attribute(lua_State *L); static int32_t card_get_fusion_attribute(lua_State *L);
static int32 card_get_attribute_in_grave(lua_State *L); static int32_t card_get_link_attribute(lua_State *L);
static int32 card_get_race(lua_State *L); static int32_t card_get_attribute_in_grave(lua_State *L);
static int32 card_get_origin_race(lua_State *L); static int32_t card_get_race(lua_State *L);
static int32 card_get_link_race(lua_State *L); static int32_t card_get_origin_race(lua_State *L);
static int32 card_get_race_in_grave(lua_State *L); static int32_t card_get_link_race(lua_State *L);
static int32 card_get_attack(lua_State *L); static int32_t card_get_race_in_grave(lua_State *L);
static int32 card_get_origin_attack(lua_State *L); static int32_t card_get_attack(lua_State *L);
static int32 card_get_text_attack(lua_State *L); static int32_t card_get_origin_attack(lua_State *L);
static int32 card_get_defense(lua_State *L); static int32_t card_get_text_attack(lua_State *L);
static int32 card_get_origin_defense(lua_State *L); static int32_t card_get_defense(lua_State *L);
static int32 card_get_text_defense(lua_State *L); static int32_t card_get_origin_defense(lua_State *L);
static int32 card_get_previous_code_onfield(lua_State *L); static int32_t card_get_text_defense(lua_State *L);
static int32 card_get_previous_type_onfield(lua_State *L); static int32_t card_get_previous_code_onfield(lua_State *L);
static int32 card_get_previous_level_onfield(lua_State *L); static int32_t card_get_previous_type_onfield(lua_State *L);
static int32 card_get_previous_rank_onfield(lua_State *L); static int32_t card_get_previous_level_onfield(lua_State *L);
static int32 card_get_previous_attribute_onfield(lua_State *L); static int32_t card_get_previous_rank_onfield(lua_State *L);
static int32 card_get_previous_race_onfield(lua_State *L); static int32_t card_get_previous_attribute_onfield(lua_State *L);
static int32 card_get_previous_attack_onfield(lua_State *L); static int32_t card_get_previous_race_onfield(lua_State *L);
static int32 card_get_previous_defense_onfield(lua_State *L); static int32_t card_get_previous_attack_onfield(lua_State *L);
static int32 card_get_owner(lua_State *L); static int32_t card_get_previous_defense_onfield(lua_State *L);
static int32 card_get_controler(lua_State *L); static int32_t card_get_previous_overlay_count_onfield(lua_State *L);
static int32 card_get_previous_controler(lua_State *L); static int32_t card_get_owner(lua_State *L);
static int32 card_set_reason(lua_State *L); static int32_t card_get_controler(lua_State *L);
static int32 card_get_reason(lua_State *L); static int32_t card_get_previous_controler(lua_State *L);
static int32 card_get_reason_card(lua_State *L); static int32_t card_set_reason(lua_State *L);
static int32 card_get_reason_player(lua_State *L); static int32_t card_get_reason(lua_State *L);
static int32 card_get_reason_effect(lua_State *L); static int32_t card_get_reason_card(lua_State *L);
static int32 card_get_position(lua_State *L); static int32_t card_get_reason_player(lua_State *L);
static int32 card_get_previous_position(lua_State *L); static int32_t card_get_reason_effect(lua_State *L);
static int32 card_get_battle_position(lua_State *L); static int32_t card_get_position(lua_State *L);
static int32 card_get_location(lua_State *L); static int32_t card_get_previous_position(lua_State *L);
static int32 card_get_previous_location(lua_State *L); static int32_t card_get_battle_position(lua_State *L);
static int32 card_get_sequence(lua_State *L); static int32_t card_get_location(lua_State *L);
static int32 card_get_previous_sequence(lua_State *L); static int32_t card_get_previous_location(lua_State *L);
static int32 card_get_summon_type(lua_State *L); static int32_t card_get_sequence(lua_State *L);
static int32 card_get_summon_location(lua_State *L); static int32_t card_get_previous_sequence(lua_State *L);
static int32 card_get_summon_player(lua_State *L); static int32_t card_get_summon_type(lua_State *L);
static int32 card_get_destination(lua_State *L); static int32_t card_get_summon_location(lua_State *L);
static int32 card_get_leave_field_dest(lua_State *L); static int32_t card_get_summon_player(lua_State *L);
static int32 card_get_turnid(lua_State *L); static int32_t card_get_destination(lua_State *L);
static int32 card_get_fieldid(lua_State *L); static int32_t card_get_leave_field_dest(lua_State *L);
static int32 card_get_fieldidr(lua_State *L); static int32_t card_get_turnid(lua_State *L);
static int32 card_is_origin_code_rule(lua_State *L); static int32_t card_get_fieldid(lua_State *L);
static int32 card_is_code(lua_State *L); static int32_t card_get_fieldidr(lua_State *L);
static int32 card_is_type(lua_State *L); static int32_t card_is_origin_code_rule(lua_State *L);
static int32 card_is_fusion_type(lua_State *L); static int32_t card_is_code(lua_State *L);
static int32 card_is_synchro_type(lua_State *L); static int32_t card_is_type(lua_State *L);
static int32 card_is_xyz_type(lua_State *L); static int32_t card_is_all_types(lua_State *L);
static int32 card_is_link_type(lua_State *L); static int32_t card_is_fusion_type(lua_State *L);
static int32 card_is_level(lua_State *L); static int32_t card_is_synchro_type(lua_State *L);
static int32 card_is_rank(lua_State *L); static int32_t card_is_xyz_type(lua_State *L);
static int32 card_is_link(lua_State *L); static int32_t card_is_link_type(lua_State *L);
static int32 card_is_attack(lua_State *L); static int32_t card_is_level(lua_State *L);
static int32 card_is_defense(lua_State *L); static int32_t card_is_rank(lua_State *L);
static int32 card_is_race(lua_State *L); static int32_t card_is_link(lua_State *L);
static int32 card_is_link_race(lua_State *L); static int32_t card_is_attack(lua_State *L);
static int32 card_is_attribute(lua_State *L); static int32_t card_is_defense(lua_State *L);
static int32 card_is_fusion_attribute(lua_State *L); static int32_t card_is_race(lua_State *L);
static int32 card_is_link_attribute(lua_State *L); static int32_t card_is_link_race(lua_State *L);
static int32 card_is_extra_deck_monster(lua_State *L); static int32_t card_is_attribute(lua_State *L);
static int32 card_is_reason(lua_State *L); static int32_t card_is_fusion_attribute(lua_State *L);
static int32 card_is_summon_type(lua_State *L); static int32_t card_is_link_attribute(lua_State *L);
static int32 card_is_summon_location(lua_State *L); static int32_t card_is_non_attribute(lua_State *L);
static int32 card_is_summon_player(lua_State *L); static int32_t card_is_extra_deck_monster(lua_State *L);
static int32 card_is_status(lua_State *L); static int32_t card_is_reason(lua_State *L);
static int32 card_is_not_tuner(lua_State *L); static int32_t card_is_all_reasons(lua_State *L);
static int32 card_set_status(lua_State *L); static int32_t card_is_summon_type(lua_State *L);
static int32 card_is_dual_state(lua_State *L); static int32_t card_is_summon_location(lua_State *L);
static int32 card_enable_dual_state(lua_State *L); static int32_t card_is_summon_player(lua_State *L);
static int32 card_set_turn_counter(lua_State *L); static int32_t card_get_special_summon_info(lua_State *L);
static int32 card_get_turn_counter(lua_State *L); static int32_t card_is_status(lua_State *L);
static int32 card_set_material(lua_State *L); static int32_t card_is_not_tuner(lua_State *L);
static int32 card_get_material(lua_State *L); static int32_t card_is_tuner(lua_State* L);
static int32 card_get_material_count(lua_State *L); static int32_t card_is_original_effect_property(lua_State* L);
static int32 card_get_equip_group(lua_State *L); static int32_t card_is_effect_property(lua_State* L);
static int32 card_get_equip_count(lua_State *L); static int32_t card_set_status(lua_State *L);
static int32 card_get_equip_target(lua_State *L); static int32_t card_is_dual_state(lua_State *L);
static int32 card_get_pre_equip_target(lua_State *L); static int32_t card_enable_dual_state(lua_State *L);
static int32 card_check_equip_target(lua_State *L); static int32_t card_set_turn_counter(lua_State *L);
static int32 card_check_union_target(lua_State *L); static int32_t card_get_turn_counter(lua_State *L);
static int32 card_get_union_count(lua_State *L); static int32_t card_set_material(lua_State *L);
static int32 card_get_overlay_group(lua_State *L); static int32_t card_get_material(lua_State *L);
static int32 card_get_overlay_count(lua_State *L); static int32_t card_get_material_count(lua_State *L);
static int32 card_get_overlay_target(lua_State *L); static int32_t card_get_equip_group(lua_State *L);
static int32 card_check_remove_overlay_card(lua_State *L); static int32_t card_get_equip_count(lua_State *L);
static int32 card_remove_overlay_card(lua_State *L); static int32_t card_get_equip_target(lua_State *L);
static int32 card_get_attacked_group(lua_State *L); static int32_t card_get_pre_equip_target(lua_State *L);
static int32 card_get_attacked_group_count(lua_State *L); static int32_t card_check_equip_target(lua_State *L);
static int32 card_get_attacked_count(lua_State *L); static int32_t card_check_union_target(lua_State *L);
static int32 card_get_battled_group(lua_State *L); static int32_t card_get_union_count(lua_State *L);
static int32 card_get_battled_group_count(lua_State *L); static int32_t card_get_overlay_group(lua_State *L);
static int32 card_get_attack_announced_count(lua_State *L); static int32_t card_get_overlay_count(lua_State *L);
static int32 card_is_direct_attacked(lua_State *L); static int32_t card_get_overlay_target(lua_State *L);
static int32 card_set_card_target(lua_State *L); static int32_t card_check_remove_overlay_card(lua_State *L);
static int32 card_get_card_target(lua_State *L); static int32_t card_remove_overlay_card(lua_State *L);
static int32 card_get_first_card_target(lua_State *L); static int32_t card_get_attacked_group(lua_State *L);
static int32 card_get_card_target_count(lua_State *L); static int32_t card_get_attacked_group_count(lua_State *L);
static int32 card_is_has_card_target(lua_State *L); static int32_t card_get_attacked_count(lua_State *L);
static int32 card_cancel_card_target(lua_State *L); static int32_t card_get_battled_group(lua_State *L);
static int32 card_get_owner_target(lua_State *L); static int32_t card_get_battled_group_count(lua_State *L);
static int32 card_get_owner_target_count(lua_State *L); static int32_t card_get_attack_announced_count(lua_State *L);
static int32 card_get_activate_effect(lua_State *L); static int32_t card_is_direct_attacked(lua_State *L);
static int32 card_check_activate_effect(lua_State *L); static int32_t card_set_card_target(lua_State *L);
static int32 card_get_tuner_limit(lua_State * L); static int32_t card_get_card_target(lua_State *L);
static int32 card_get_hand_synchro(lua_State * L); static int32_t card_get_first_card_target(lua_State *L);
static int32 card_register_effect(lua_State *L); static int32_t card_get_card_target_count(lua_State *L);
static int32 card_is_has_effect(lua_State *L); static int32_t card_is_has_card_target(lua_State *L);
static int32 card_reset_effect(lua_State *L); static int32_t card_cancel_card_target(lua_State *L);
static int32 card_get_effect_count(lua_State *L); static int32_t card_get_owner_target(lua_State *L);
static int32 card_register_flag_effect(lua_State *L); static int32_t card_get_owner_target_count(lua_State *L);
static int32 card_get_flag_effect(lua_State *L); static int32_t card_get_activate_effect(lua_State *L);
static int32 card_reset_flag_effect(lua_State *L); static int32_t card_check_activate_effect(lua_State *L);
static int32 card_set_flag_effect_label(lua_State *L); static int32_t card_get_tuner_limit(lua_State * L);
static int32 card_get_flag_effect_label(lua_State *L); static int32_t card_get_hand_synchro(lua_State * L);
static int32 card_create_relation(lua_State *L); static int32_t card_register_effect(lua_State *L);
static int32 card_release_relation(lua_State *L); static int32_t card_is_has_effect(lua_State *L);
static int32 card_create_effect_relation(lua_State *L); static int32_t card_reset_effect(lua_State *L);
static int32 card_release_effect_relation(lua_State *L); static int32_t card_get_effect_count(lua_State *L);
static int32 card_clear_effect_relation(lua_State *L); static int32_t card_register_flag_effect(lua_State *L);
static int32 card_is_relate_to_effect(lua_State *L); static int32_t card_get_flag_effect(lua_State *L);
static int32 card_is_relate_to_chain(lua_State *L); static int32_t card_reset_flag_effect(lua_State *L);
static int32 card_is_relate_to_card(lua_State *L); static int32_t card_set_flag_effect_label(lua_State *L);
static int32 card_is_relate_to_battle(lua_State *L); static int32_t card_get_flag_effect_label(lua_State *L);
static int32 card_copy_effect(lua_State *L); static int32_t card_create_relation(lua_State *L);
static int32 card_replace_effect(lua_State *L); static int32_t card_release_relation(lua_State *L);
static int32 card_enable_revive_limit(lua_State *L); static int32_t card_create_effect_relation(lua_State *L);
static int32 card_complete_procedure(lua_State *L); static int32_t card_release_effect_relation(lua_State *L);
static int32 card_is_disabled(lua_State *L); static int32_t card_clear_effect_relation(lua_State *L);
static int32 card_is_destructable(lua_State *L); static int32_t card_is_relate_to_effect(lua_State *L);
static int32 card_is_summonable(lua_State *L); static int32_t card_is_relate_to_chain(lua_State *L);
static int32 card_is_special_summonable_card(lua_State *L); static int32_t card_is_relate_to_card(lua_State *L);
static int32 card_is_fusion_summonable_card(lua_State *L); static int32_t card_is_relate_to_battle(lua_State *L);
static int32 card_is_msetable(lua_State *L); static int32_t card_copy_effect(lua_State *L);
static int32 card_is_ssetable(lua_State *L); static int32_t card_replace_effect(lua_State *L);
static int32 card_is_special_summonable(lua_State *L); static int32_t card_enable_revive_limit(lua_State *L);
static int32 card_is_synchro_summonable(lua_State *L); static int32_t card_complete_procedure(lua_State *L);
static int32 card_is_xyz_summonable(lua_State *L); static int32_t card_is_disabled(lua_State *L);
static int32 card_is_link_summonable(lua_State *L); static int32_t card_is_destructable(lua_State *L);
static int32 card_is_can_be_summoned(lua_State *L); static int32_t card_is_summonable(lua_State *L);
static int32 card_is_can_be_special_summoned(lua_State *L); static int32_t card_is_special_summonable_card(lua_State *L);
static int32 card_is_able_to_hand(lua_State *L); static int32_t card_is_fusion_summonable_card(lua_State *L);
static int32 card_is_able_to_grave(lua_State *L); static int32_t card_is_msetable(lua_State *L);
static int32 card_is_able_to_deck(lua_State *L); static int32_t card_is_ssetable(lua_State *L);
static int32 card_is_able_to_extra(lua_State *L); static int32_t card_is_special_summonable(lua_State *L);
static int32 card_is_able_to_remove(lua_State *L); static int32_t card_is_synchro_summonable(lua_State *L);
static int32 card_is_able_to_hand_as_cost(lua_State *L); static int32_t card_is_xyz_summonable(lua_State *L);
static int32 card_is_able_to_grave_as_cost(lua_State *L); static int32_t card_is_link_summonable(lua_State *L);
static int32 card_is_able_to_deck_as_cost(lua_State *L); static int32_t card_is_can_be_summoned(lua_State *L);
static int32 card_is_able_to_extra_as_cost(lua_State *L); static int32_t card_is_can_be_special_summoned(lua_State *L);
static int32 card_is_able_to_deck_or_extra_as_cost(lua_State *L); static int32_t card_is_can_be_placed_on_field(lua_State *L);
static int32 card_is_able_to_remove_as_cost(lua_State *L); static int32_t card_is_able_to_hand(lua_State *L);
static int32 card_is_releasable(lua_State *L); static int32_t card_is_able_to_grave(lua_State *L);
static int32 card_is_releasable_by_effect(lua_State *L); static int32_t card_is_able_to_deck(lua_State *L);
static int32 card_is_discardable(lua_State *L); static int32_t card_is_able_to_extra(lua_State *L);
static int32 card_is_attackable(lua_State *L); static int32_t card_is_able_to_remove(lua_State *L);
static int32 card_is_chain_attackable(lua_State *L); static int32_t card_is_able_to_hand_as_cost(lua_State *L);
static int32 card_is_faceup(lua_State *L); static int32_t card_is_able_to_grave_as_cost(lua_State *L);
static int32 card_is_faceup_ex(lua_State *L); static int32_t card_is_able_to_deck_as_cost(lua_State *L);
static int32 card_is_attack_pos(lua_State *L); static int32_t card_is_able_to_extra_as_cost(lua_State *L);
static int32 card_is_facedown(lua_State *L); static int32_t card_is_able_to_deck_or_extra_as_cost(lua_State *L);
static int32 card_is_defense_pos(lua_State *L); static int32_t card_is_able_to_remove_as_cost(lua_State *L);
static int32 card_is_position(lua_State *L); static int32_t card_is_releasable(lua_State *L);
static int32 card_is_pre_position(lua_State *L); static int32_t card_is_releasable_by_effect(lua_State *L);
static int32 card_is_controler(lua_State *L); static int32_t card_is_discardable(lua_State *L);
static int32 card_is_pre_controler(lua_State *L); static int32_t card_is_attackable(lua_State *L);
static int32 card_is_onfield(lua_State *L); static int32_t card_is_chain_attackable(lua_State *L);
static int32 card_is_location(lua_State *L); static int32_t card_is_faceup(lua_State *L);
static int32 card_is_pre_location(lua_State *L); static int32_t card_is_faceup_ex(lua_State *L);
static int32 card_is_level_below(lua_State *L); static int32_t card_is_attack_pos(lua_State *L);
static int32 card_is_level_above(lua_State *L); static int32_t card_is_facedown(lua_State *L);
static int32 card_is_rank_below(lua_State *L); static int32_t card_is_defense_pos(lua_State *L);
static int32 card_is_rank_above(lua_State *L); static int32_t card_is_position(lua_State *L);
static int32 card_is_link_below(lua_State *L); static int32_t card_is_pre_position(lua_State *L);
static int32 card_is_link_above(lua_State *L); static int32_t card_is_controler(lua_State *L);
static int32 card_is_attack_below(lua_State *L); static int32_t card_is_pre_controler(lua_State *L);
static int32 card_is_attack_above(lua_State *L); static int32_t card_is_onfield(lua_State *L);
static int32 card_is_defense_below(lua_State *L); static int32_t card_is_location(lua_State *L);
static int32 card_is_defense_above(lua_State *L); static int32_t card_is_pre_location(lua_State *L);
static int32 card_is_public(lua_State *L); static int32_t card_is_level_below(lua_State *L);
static int32 card_is_forbidden(lua_State *L); static int32_t card_is_level_above(lua_State *L);
static int32 card_is_able_to_change_controler(lua_State *L); static int32_t card_is_rank_below(lua_State *L);
static int32 card_is_controler_can_be_changed(lua_State *L); static int32_t card_is_rank_above(lua_State *L);
static int32 card_add_counter(lua_State *L); static int32_t card_is_link_below(lua_State *L);
static int32 card_remove_counter(lua_State *L); static int32_t card_is_link_above(lua_State *L);
static int32 card_get_counter(lua_State *L); static int32_t card_is_attack_below(lua_State *L);
static int32 card_enable_counter_permit(lua_State *L); static int32_t card_is_attack_above(lua_State *L);
static int32 card_set_counter_limit(lua_State *L); static int32_t card_is_defense_below(lua_State *L);
static int32 card_is_can_change_position(lua_State *L); static int32_t card_is_defense_above(lua_State *L);
static int32 card_is_can_turn_set(lua_State *L); static int32_t card_is_has_level(lua_State *L);
static int32 card_is_can_add_counter(lua_State *L); static int32_t card_is_has_defense(lua_State *L);
static int32 card_is_can_remove_counter(lua_State *L); static int32_t card_is_public(lua_State *L);
static int32 card_is_can_have_counter(lua_State* L); static int32_t card_is_forbidden(lua_State *L);
static int32 card_is_can_overlay(lua_State *L); static int32_t card_is_able_to_change_controler(lua_State *L);
static int32 card_is_can_be_fusion_material(lua_State *L); static int32_t card_is_controler_can_be_changed(lua_State *L);
static int32 card_is_can_be_synchro_material(lua_State *L); static int32_t card_add_counter(lua_State *L);
static int32 card_is_can_be_ritual_material(lua_State *L); static int32_t card_remove_counter(lua_State *L);
static int32 card_is_can_be_xyz_material(lua_State *L); static int32_t card_get_counter(lua_State *L);
static int32 card_is_can_be_link_material(lua_State *L); static int32_t card_enable_counter_permit(lua_State *L);
static int32 card_check_fusion_material(lua_State *L); static int32_t card_set_counter_limit(lua_State *L);
static int32 card_check_fusion_substitute(lua_State *L); static int32_t card_is_can_change_position(lua_State *L);
static int32 card_is_immune_to_effect(lua_State *L); static int32_t card_is_can_turn_set(lua_State *L);
static int32 card_is_can_be_disabled_by_effect(lua_State* L); static int32_t card_is_can_add_counter(lua_State *L);
static int32 card_is_can_be_effect_target(lua_State *L); static int32_t card_is_can_remove_counter(lua_State *L);
static int32 card_is_can_be_battle_target(lua_State *L); static int32_t card_is_can_have_counter(lua_State* L);
static int32 card_add_monster_attribute(lua_State *L); static int32_t card_is_can_overlay(lua_State *L);
static int32 card_cancel_to_grave(lua_State *L); static int32_t card_is_can_be_fusion_material(lua_State *L);
static int32 card_get_tribute_requirement(lua_State *L); static int32_t card_is_can_be_synchro_material(lua_State *L);
static int32 card_get_battle_target(lua_State *L); static int32_t card_is_can_be_ritual_material(lua_State *L);
static int32 card_get_attackable_target(lua_State *L); static int32_t card_is_can_be_xyz_material(lua_State *L);
static int32 card_set_hint(lua_State *L); static int32_t card_is_can_be_link_material(lua_State *L);
static int32 card_reverse_in_deck(lua_State *L); static int32_t card_check_fusion_material(lua_State *L);
static int32 card_set_unique_onfield(lua_State *L); static int32_t card_check_fusion_substitute(lua_State *L);
static int32 card_check_unique_onfield(lua_State *L); static int32_t card_is_immune_to_effect(lua_State *L);
static int32 card_reset_negate_effect(lua_State *L); static int32_t card_is_can_be_disabled_by_effect(lua_State* L);
static int32 card_assume_prop(lua_State *L); static int32_t card_is_can_be_effect_target(lua_State *L);
static int32 card_set_spsummon_once(lua_State *L); static int32_t card_is_can_be_battle_target(lua_State *L);
static int32_t card_add_monster_attribute(lua_State *L);
static int32_t card_cancel_to_grave(lua_State *L);
static int32_t card_get_tribute_requirement(lua_State *L);
static int32_t card_get_battle_target(lua_State *L);
static int32_t card_get_attackable_target(lua_State *L);
static int32_t card_set_hint(lua_State *L);
static int32_t card_reverse_in_deck(lua_State *L);
static int32_t card_set_unique_onfield(lua_State *L);
static int32_t card_check_unique_onfield(lua_State *L);
static int32_t card_reset_negate_effect(lua_State *L);
static int32_t card_assume_prop(lua_State *L);
static int32_t card_set_spsummon_once(lua_State *L);
static void open_cardlib(lua_State *L); static void open_cardlib(lua_State *L);
//Effect functions //Effect functions
static int32 effect_new(lua_State *L); static int32_t get_effect_property(lua_State* L, effect_member type);
static int32 effect_newex(lua_State *L); static int32_t is_effect_has_property(lua_State* L, effect_member type);
static int32 effect_clone(lua_State *L); static int32_t effect_new(lua_State *L);
static int32 effect_reset(lua_State *L); static int32_t effect_newex(lua_State *L);
static int32 effect_get_field_id(lua_State *L); static int32_t effect_clone(lua_State *L);
static int32 effect_set_description(lua_State *L); static int32_t effect_reset(lua_State *L);
static int32 effect_set_code(lua_State *L); static int32_t effect_get_field_id(lua_State *L);
static int32 effect_set_range(lua_State *L); static int32_t effect_set_description(lua_State *L);
static int32 effect_set_target_range(lua_State *L); static int32_t effect_set_code(lua_State *L);
static int32 effect_set_absolute_range(lua_State *L); static int32_t effect_set_range(lua_State *L);
static int32 effect_set_count_limit(lua_State *L); static int32_t effect_set_target_range(lua_State *L);
static int32 effect_set_reset(lua_State *L); static int32_t effect_set_absolute_range(lua_State *L);
static int32 effect_set_type(lua_State *L); static int32_t effect_set_count_limit(lua_State *L);
static int32 effect_set_property(lua_State *L); static int32_t effect_set_reset(lua_State *L);
static int32 effect_set_label(lua_State *L); static int32_t effect_set_type(lua_State *L);
static int32 effect_set_label_object(lua_State *L); static int32_t effect_set_property(lua_State *L);
static int32 effect_set_category(lua_State *L); static int32_t effect_set_label(lua_State *L);
static int32 effect_set_hint_timing(lua_State *L); static int32_t effect_set_label_object(lua_State *L);
static int32 effect_set_condition(lua_State *L); static int32_t effect_set_category(lua_State *L);
static int32 effect_set_target(lua_State *L); static int32_t effect_set_hint_timing(lua_State *L);
static int32 effect_set_cost(lua_State *L); static int32_t effect_set_condition(lua_State *L);
static int32 effect_set_value(lua_State *L); static int32_t effect_set_target(lua_State *L);
static int32 effect_set_operation(lua_State *L); static int32_t effect_set_cost(lua_State *L);
static int32 effect_set_owner_player(lua_State *L); static int32_t effect_set_value(lua_State *L);
static int32 effect_get_description(lua_State *L); static int32_t effect_set_operation(lua_State *L);
static int32 effect_get_code(lua_State *L); static int32_t effect_set_owner_player(lua_State *L);
static int32 effect_get_type(lua_State *L); static int32_t effect_get_description(lua_State *L);
static int32 effect_get_property(lua_State *L); static int32_t effect_get_code(lua_State *L);
static int32 effect_get_label(lua_State *L); static int32_t effect_get_type(lua_State *L);
static int32 effect_get_label_object(lua_State *L); static int32_t effect_get_property(lua_State *L);
static int32 effect_get_category(lua_State *L); static int32_t effect_get_label(lua_State *L);
static int32 effect_get_owner(lua_State *L); static int32_t effect_get_label_object(lua_State *L);
static int32 effect_get_handler(lua_State *L); static int32_t effect_get_category(lua_State *L);
static int32 effect_get_owner_player(lua_State *L); static int32_t effect_get_range(lua_State* L);
static int32 effect_get_handler_player(lua_State *L); static int32_t effect_get_owner(lua_State *L);
static int32 effect_get_condition(lua_State *L); static int32_t effect_get_handler(lua_State *L);
static int32 effect_get_target(lua_State *L); static int32_t effect_get_owner_player(lua_State *L);
static int32 effect_get_cost(lua_State *L); static int32_t effect_get_handler_player(lua_State *L);
static int32 effect_get_value(lua_State *L); static int32_t effect_get_condition(lua_State *L);
static int32 effect_get_operation(lua_State *L); static int32_t effect_get_target(lua_State *L);
static int32 effect_get_active_type(lua_State *L); static int32_t effect_get_cost(lua_State *L);
static int32 effect_is_active_type(lua_State *L); static int32_t effect_get_value(lua_State *L);
static int32 effect_is_has_property(lua_State *L); static int32_t effect_get_operation(lua_State *L);
static int32 effect_is_has_category(lua_State *L); static int32_t effect_get_active_type(lua_State *L);
static int32 effect_is_has_type(lua_State *L); static int32_t effect_is_active_type(lua_State *L);
static int32 effect_is_activatable(lua_State *L); static int32_t effect_is_has_property(lua_State *L);
static int32 effect_is_activated(lua_State *L); static int32_t effect_is_has_category(lua_State *L);
static int32 effect_is_cost_checked(lua_State *L); static int32_t effect_is_has_range(lua_State* L);
static int32 effect_set_cost_check(lua_State *L); static int32_t effect_is_has_type(lua_State *L);
static int32 effect_get_activate_location(lua_State *L); static int32_t effect_is_activatable(lua_State *L);
static int32 effect_get_activate_sequence(lua_State *L); static int32_t effect_is_activated(lua_State *L);
static int32 effect_check_count_limit(lua_State *L); static int32_t effect_is_cost_checked(lua_State *L);
static int32 effect_use_count_limit(lua_State *L); static int32_t effect_set_cost_check(lua_State *L);
static int32_t effect_get_activate_location(lua_State *L);
static int32_t effect_get_activate_sequence(lua_State *L);
static int32_t effect_check_count_limit(lua_State *L);
static int32_t effect_use_count_limit(lua_State *L);
static void open_effectlib(lua_State *L); static void open_effectlib(lua_State *L);
//Group functions //Group functions
static int32 group_new(lua_State *L); static int32_t group_new(lua_State *L);
static int32 group_clone(lua_State *L); static int32_t group_clone(lua_State *L);
static int32 group_from_cards(lua_State *L); static int32_t group_from_cards(lua_State *L);
static int32 group_delete(lua_State *L); static int32_t group_delete(lua_State *L);
static int32 group_keep_alive(lua_State *L); static int32_t group_keep_alive(lua_State *L);
static int32 group_clear(lua_State *L); static int32_t group_clear(lua_State *L);
static int32 group_add_card(lua_State *L); static int32_t group_add_card(lua_State *L);
static int32 group_remove_card(lua_State *L); static int32_t group_remove_card(lua_State *L);
static int32 group_get_next(lua_State *L); static int32_t group_get_next(lua_State *L);
static int32 group_get_first(lua_State *L); static int32_t group_get_first(lua_State *L);
static int32 group_get_count(lua_State *L); static int32_t group_get_count(lua_State *L);
static int32 group_for_each(lua_State *L); static int32_t group_filter(lua_State *L);
static int32 group_filter(lua_State *L); static int32_t group_filter_count(lua_State *L);
static int32 group_filter_count(lua_State *L); static int32_t group_filter_select(lua_State *L);
static int32 group_filter_select(lua_State *L); static int32_t group_select(lua_State *L);
static int32 group_select(lua_State *L); static int32_t group_select_unselect(lua_State *L);
static int32 group_select_unselect(lua_State *L); static int32_t group_random_select(lua_State *L);
static int32 group_random_select(lua_State *L); static int32_t group_cancelable_select(lua_State *L);
static int32 group_is_exists(lua_State *L); static int32_t group_is_exists(lua_State *L);
static int32 group_check_with_sum_equal(lua_State *L); static int32_t group_check_with_sum_equal(lua_State *L);
static int32 group_select_with_sum_equal(lua_State *L); static int32_t group_select_with_sum_equal(lua_State *L);
static int32 group_check_with_sum_greater(lua_State *L); static int32_t group_check_with_sum_greater(lua_State *L);
static int32 group_select_with_sum_greater(lua_State *L); static int32_t group_select_with_sum_greater(lua_State *L);
static int32 group_get_min_group(lua_State *L); static int32_t group_get_min_group(lua_State *L);
static int32 group_get_max_group(lua_State *L); static int32_t group_get_max_group(lua_State *L);
static int32 group_get_sum(lua_State *L); static int32_t group_get_sum(lua_State *L);
static int32 group_get_class_count(lua_State *L); static int32_t group_get_class_count(lua_State *L);
static int32 group_remove(lua_State *L); static int32_t group_remove(lua_State *L);
static int32 group_merge(lua_State *L); static int32_t group_merge(lua_State *L);
static int32 group_sub(lua_State *L); static int32_t group_sub(lua_State *L);
static int32 group_equal(lua_State *L); static int32_t group_equal(lua_State *L);
static int32 group_is_contains(lua_State *L); static int32_t group_is_contains(lua_State *L);
static int32 group_search_card(lua_State *L); static int32_t group_search_card(lua_State *L);
static int32 group_get_bin_class_count(lua_State *L); static int32_t group_get_bin_class_count(lua_State *L);
static void open_grouplib(lua_State *L); static void open_grouplib(lua_State *L);
//Duel functions //Duel functions
static int32 duel_enable_global_flag(lua_State *L); static int32_t duel_enable_global_flag(lua_State *L);
static int32 duel_get_lp(lua_State *L); static int32_t duel_get_lp(lua_State *L);
static int32 duel_set_lp(lua_State *L); static int32_t duel_set_lp(lua_State *L);
static int32 duel_get_turn_player(lua_State *L); static int32_t duel_is_turn_player(lua_State *L);
static int32 duel_get_turn_count(lua_State *L); static int32_t duel_get_turn_player(lua_State *L);
static int32 duel_get_draw_count(lua_State *L); static int32_t duel_get_turn_count(lua_State *L);
static int32 duel_register_effect(lua_State *L); static int32_t duel_get_draw_count(lua_State *L);
static int32 duel_register_flag_effect(lua_State *L); static int32_t duel_register_effect(lua_State *L);
static int32 duel_get_flag_effect(lua_State *L); static int32_t duel_register_flag_effect(lua_State *L);
static int32 duel_reset_flag_effect(lua_State *L); static int32_t duel_get_flag_effect(lua_State *L);
static int32 duel_set_flag_effect_label(lua_State *L); static int32_t duel_reset_flag_effect(lua_State *L);
static int32 duel_get_flag_effect_label(lua_State *L); static int32_t duel_set_flag_effect_label(lua_State *L);
static int32 duel_destroy(lua_State *L); static int32_t duel_get_flag_effect_label(lua_State *L);
static int32 duel_remove(lua_State *L); static int32_t duel_destroy(lua_State *L);
static int32 duel_sendto_grave(lua_State *L); static int32_t duel_remove(lua_State *L);
static int32 duel_summon(lua_State *L); static int32_t duel_sendto_grave(lua_State *L);
static int32 duel_special_summon_rule(lua_State *L); static int32_t duel_summon(lua_State *L);
static int32 duel_synchro_summon(lua_State *L); static int32_t duel_special_summon_rule(lua_State *L);
static int32 duel_xyz_summon(lua_State *L); static int32_t duel_synchro_summon(lua_State *L);
static int32 duel_link_summon(lua_State *L); static int32_t duel_xyz_summon(lua_State *L);
static int32 duel_setm(lua_State *L); static int32_t duel_link_summon(lua_State *L);
static int32 duel_sets(lua_State *L); static int32_t duel_setm(lua_State *L);
static int32 duel_create_token(lua_State *L); static int32_t duel_sets(lua_State *L);
static int32 duel_special_summon(lua_State *L); static int32_t duel_create_token(lua_State *L);
static int32 duel_special_summon_step(lua_State *L); static int32_t duel_special_summon(lua_State *L);
static int32 duel_special_summon_complete(lua_State *L); static int32_t duel_special_summon_step(lua_State *L);
static int32 duel_sendto_hand(lua_State *L); static int32_t duel_special_summon_complete(lua_State *L);
static int32 duel_sendto_deck(lua_State *L); static int32_t duel_sendto_hand(lua_State *L);
static int32 duel_sendto_extra(lua_State *L); static int32_t duel_sendto_deck(lua_State *L);
static int32 duel_get_operated_group(lua_State *L); static int32_t duel_sendto_extra(lua_State *L);
static int32 duel_is_can_add_counter(lua_State *L); static int32_t duel_get_operated_group(lua_State *L);
static int32 duel_remove_counter(lua_State *L); static int32_t duel_is_can_add_counter(lua_State *L);
static int32 duel_is_can_remove_counter(lua_State *L); static int32_t duel_remove_counter(lua_State *L);
static int32 duel_get_counter(lua_State *L); static int32_t duel_is_can_remove_counter(lua_State *L);
static int32 duel_change_form(lua_State *L); static int32_t duel_get_counter(lua_State *L);
static int32 duel_release(lua_State *L); static int32_t duel_change_form(lua_State *L);
static int32 duel_move_to_field(lua_State *L); static int32_t duel_release(lua_State *L);
static int32 duel_return_to_field(lua_State *L); static int32_t duel_move_to_field(lua_State *L);
static int32 duel_move_sequence(lua_State *L); static int32_t duel_return_to_field(lua_State *L);
static int32 duel_swap_sequence(lua_State *L); static int32_t duel_move_sequence(lua_State *L);
static int32 duel_activate_effect(lua_State *L); static int32_t duel_swap_sequence(lua_State *L);
static int32 duel_set_chain_limit(lua_State *L); static int32_t duel_activate_effect(lua_State *L);
static int32 duel_set_chain_limit_p(lua_State *L); static int32_t duel_set_chain_limit(lua_State *L);
static int32 duel_get_chain_material(lua_State *L); static int32_t duel_set_chain_limit_p(lua_State *L);
static int32 duel_confirm_decktop(lua_State *L); static int32_t duel_get_chain_material(lua_State *L);
static int32 duel_confirm_extratop(lua_State *L); static int32_t duel_confirm_decktop(lua_State *L);
static int32 duel_confirm_cards(lua_State *L); static int32_t duel_confirm_extratop(lua_State *L);
static int32 duel_sort_decktop(lua_State *L); static int32_t duel_confirm_cards(lua_State *L);
static int32 duel_check_event(lua_State *L); static int32_t duel_sort_decktop(lua_State *L);
static int32 duel_raise_event(lua_State *L); static int32_t duel_check_event(lua_State *L);
static int32 duel_raise_single_event(lua_State *L); static int32_t duel_raise_event(lua_State *L);
static int32 duel_check_timing(lua_State *L); static int32_t duel_raise_single_event(lua_State *L);
static int32 duel_is_environment(lua_State *L); static int32_t duel_check_timing(lua_State *L);
static int32_t duel_is_environment(lua_State *L);
static int32 duel_win(lua_State *L); static int32_t duel_win(lua_State *L);
static int32 duel_draw(lua_State *L); static int32_t duel_draw(lua_State *L);
static int32 duel_damage(lua_State *L); static int32_t duel_damage(lua_State *L);
static int32 duel_recover(lua_State *L); static int32_t duel_recover(lua_State *L);
static int32 duel_rd_complete(lua_State *L); static int32_t duel_rd_complete(lua_State *L);
static int32 duel_equip(lua_State *L); static int32_t duel_equip(lua_State *L);
static int32 duel_equip_complete(lua_State *L); static int32_t duel_equip_complete(lua_State *L);
static int32 duel_get_control(lua_State *L); static int32_t duel_get_control(lua_State *L);
static int32 duel_swap_control(lua_State *L); static int32_t duel_swap_control(lua_State *L);
static int32 duel_check_lp_cost(lua_State *L); static int32_t duel_check_lp_cost(lua_State *L);
static int32 duel_pay_lp_cost(lua_State *L); static int32_t duel_pay_lp_cost(lua_State *L);
static int32 duel_discard_deck(lua_State *L); static int32_t duel_discard_deck(lua_State *L);
static int32 duel_discard_hand(lua_State *L); static int32_t duel_discard_hand(lua_State *L);
static int32 duel_disable_shuffle_check(lua_State *L); static int32_t duel_disable_shuffle_check(lua_State *L);
static int32 duel_disable_self_destroy_check(lua_State *L); static int32_t duel_disable_self_destroy_check(lua_State *L);
static int32 duel_shuffle_deck(lua_State *L); static int32_t duel_reveal_select_deck_sequence(lua_State *L);
static int32 duel_shuffle_extra(lua_State *L); static int32_t duel_shuffle_deck(lua_State *L);
static int32 duel_shuffle_hand(lua_State *L); static int32_t duel_shuffle_extra(lua_State *L);
static int32 duel_shuffle_setcard(lua_State *L); static int32_t duel_shuffle_hand(lua_State *L);
static int32 duel_change_attacker(lua_State *L); static int32_t duel_shuffle_setcard(lua_State *L);
static int32 duel_change_attack_target(lua_State *L); static int32_t duel_change_attacker(lua_State *L);
static int32 duel_calculate_damage(lua_State *L); static int32_t duel_change_attack_target(lua_State *L);
static int32 duel_get_battle_damage(lua_State *L); static int32_t duel_calculate_damage(lua_State *L);
static int32 duel_change_battle_damage(lua_State *L); static int32_t duel_get_battle_damage(lua_State *L);
static int32 duel_change_target(lua_State *L); static int32_t duel_change_battle_damage(lua_State *L);
static int32 duel_change_target_player(lua_State *L); static int32_t duel_change_target(lua_State *L);
static int32 duel_change_target_param(lua_State *L); static int32_t duel_change_target_player(lua_State *L);
static int32 duel_break_effect(lua_State *L); static int32_t duel_change_target_param(lua_State *L);
static int32 duel_change_effect(lua_State *L); static int32_t duel_break_effect(lua_State *L);
static int32 duel_negate_activate(lua_State *L); static int32_t duel_change_effect(lua_State *L);
static int32 duel_negate_effect(lua_State *L); static int32_t duel_negate_activate(lua_State *L);
static int32 duel_negate_related_chain(lua_State *L); static int32_t duel_negate_effect(lua_State *L);
static int32 duel_disable_summon(lua_State *L); static int32_t duel_negate_related_chain(lua_State *L);
static int32 duel_increase_summon_count(lua_State *L); static int32_t duel_disable_summon(lua_State *L);
static int32 duel_check_summon_count(lua_State *L); static int32_t duel_increase_summon_count(lua_State *L);
static int32 duel_get_location_count(lua_State *L); static int32_t duel_check_summon_count(lua_State *L);
static int32 duel_get_mzone_count(lua_State *L); static int32_t duel_get_location_count(lua_State *L);
static int32 duel_get_location_count_fromex(lua_State *L); static int32_t duel_get_mzone_count(lua_State *L);
static int32 duel_get_usable_mzone_count(lua_State *L); static int32_t duel_get_szone_count(lua_State *L);
static int32 duel_get_linked_group(lua_State *L); static int32_t duel_get_location_count_fromex(lua_State *L);
static int32 duel_get_linked_group_count(lua_State *L); static int32_t duel_get_usable_mzone_count(lua_State *L);
static int32 duel_get_linked_zone(lua_State *L); static int32_t duel_get_linked_group(lua_State *L);
static int32 duel_get_field_card(lua_State *L); static int32_t duel_get_linked_group_count(lua_State *L);
static int32 duel_check_location(lua_State *L); static int32_t duel_get_linked_zone(lua_State *L);
static int32 duel_get_current_chain(lua_State *L); static int32_t duel_get_field_card(lua_State *L);
static int32 duel_get_chain_info(lua_State *L); static int32_t duel_check_location(lua_State *L);
static int32 duel_get_chain_event(lua_State *L); static int32_t duel_get_current_chain(lua_State *L);
static int32 duel_get_first_target(lua_State *L); static int32_t duel_get_ready_chain(lua_State* L);
static int32 duel_get_targets_relate_to_chain(lua_State *L); static int32_t duel_get_chain_info(lua_State *L);
static int32 duel_get_current_phase(lua_State *L); static int32_t duel_get_chain_event(lua_State *L);
static int32 duel_skip_phase(lua_State *L); static int32_t duel_get_first_target(lua_State *L);
static int32 duel_is_damage_calculated(lua_State *L); static int32_t duel_get_targets_relate_to_chain(lua_State *L);
static int32 duel_get_attacker(lua_State *L); static int32_t duel_is_phase(lua_State *L);
static int32 duel_get_attack_target(lua_State* L); static int32_t duel_is_main_phase(lua_State *L);
static int32 duel_get_battle_monster(lua_State* L); static int32_t duel_is_battle_phase(lua_State *L);
static int32 duel_disable_attack(lua_State *L); static int32_t duel_get_current_phase(lua_State *L);
static int32 duel_chain_attack(lua_State *L); static int32_t duel_skip_phase(lua_State *L);
static int32 duel_readjust(lua_State *L); static int32_t duel_is_damage_calculated(lua_State *L);
static int32 duel_adjust_instantly(lua_State *L); static int32_t duel_get_attacker(lua_State *L);
static int32 duel_adjust_all(lua_State *L); static int32_t duel_get_attack_target(lua_State* L);
static int32_t duel_get_battle_monster(lua_State* L);
static int32_t duel_disable_attack(lua_State *L);
static int32_t duel_chain_attack(lua_State *L);
static int32_t duel_readjust(lua_State *L);
static int32_t duel_adjust_instantly(lua_State *L);
static int32_t duel_adjust_all(lua_State *L);
static int32 duel_get_field_group(lua_State *L); static int32_t duel_get_field_group(lua_State *L);
static int32 duel_get_field_group_count(lua_State *L); static int32_t duel_get_field_group_count(lua_State *L);
static int32 duel_get_decktop_group(lua_State *L); static int32_t duel_get_decktop_group(lua_State *L);
static int32 duel_get_extratop_group(lua_State *L); static int32_t duel_get_extratop_group(lua_State *L);
static int32 duel_get_matching_group(lua_State *L); static int32_t duel_get_matching_group(lua_State *L);
static int32 duel_get_matching_count(lua_State *L); static int32_t duel_get_matching_count(lua_State *L);
static int32 duel_get_first_matching_card(lua_State *L); static int32_t duel_get_first_matching_card(lua_State *L);
static int32 duel_is_existing_matching_card(lua_State *L); static int32_t duel_is_existing_matching_card(lua_State *L);
static int32 duel_select_matching_cards(lua_State *L); static int32_t duel_select_matching_cards(lua_State *L);
static int32 duel_get_release_group(lua_State *L); static int32_t duel_get_release_group(lua_State *L);
static int32 duel_get_release_group_count(lua_State *L); static int32_t duel_get_release_group_count(lua_State *L);
static int32 duel_check_release_group(lua_State *L); static int32_t duel_check_release_group(lua_State *L);
static int32 duel_select_release_group(lua_State *L); static int32_t duel_select_release_group(lua_State *L);
static int32 duel_check_release_group_ex(lua_State *L); static int32_t duel_check_release_group_ex(lua_State *L);
static int32 duel_select_release_group_ex(lua_State *L); static int32_t duel_select_release_group_ex(lua_State *L);
static int32 duel_get_tribute_group(lua_State *L); static int32_t duel_get_tribute_group(lua_State *L);
static int32 duel_get_tribute_count(lua_State *L); static int32_t duel_get_tribute_count(lua_State *L);
static int32 duel_check_tribute(lua_State *L); static int32_t duel_check_tribute(lua_State *L);
static int32 duel_select_tribute(lua_State *L); static int32_t duel_select_tribute(lua_State *L);
static int32 duel_get_target_count(lua_State *L); static int32_t duel_get_target_count(lua_State *L);
static int32 duel_is_existing_target(lua_State *L); static int32_t duel_is_existing_target(lua_State *L);
static int32 duel_select_target(lua_State *L); static int32_t duel_select_target(lua_State *L);
static int32 duel_select_fusion_material(lua_State *L); static int32_t duel_get_must_material(lua_State *L);
static int32 duel_set_fusion_material(lua_State *L); static int32_t duel_check_must_material(lua_State *L);
static int32 duel_set_synchro_material(lua_State *L); static int32_t duel_select_fusion_material(lua_State *L);
static int32 duel_select_synchro_material(lua_State *L); static int32_t duel_set_fusion_material(lua_State *L);
static int32 duel_check_synchro_material(lua_State *L); static int32_t duel_set_synchro_material(lua_State *L);
static int32 duel_select_tuner_material(lua_State *L); static int32_t duel_get_synchro_material(lua_State *L);
static int32 duel_check_tuner_material(lua_State *L); static int32_t duel_select_synchro_material(lua_State *L);
static int32 duel_get_ritual_material(lua_State *L); static int32_t duel_check_synchro_material(lua_State *L);
static int32 duel_get_ritual_material_ex(lua_State *L); static int32_t duel_select_tuner_material(lua_State *L);
static int32 duel_release_ritual_material(lua_State *L); static int32_t duel_check_tuner_material(lua_State *L);
static int32 duel_get_fusion_material(lua_State *L); static int32_t duel_get_ritual_material(lua_State *L);
static int32 duel_is_summon_cancelable(lua_State *L); static int32_t duel_get_ritual_material_ex(lua_State *L);
static int32 duel_set_must_select_cards(lua_State *L); static int32_t duel_release_ritual_material(lua_State *L);
static int32 duel_grab_must_select_cards(lua_State *L); static int32_t duel_get_fusion_material(lua_State *L);
static int32 duel_set_target_card(lua_State *L); static int32_t duel_is_summon_cancelable(lua_State *L);
static int32 duel_clear_target_card(lua_State *L); static int32_t duel_set_must_select_cards(lua_State *L);
static int32 duel_set_target_player(lua_State *L); static int32_t duel_grab_must_select_cards(lua_State *L);
static int32 duel_set_target_param(lua_State *L); static int32_t duel_set_target_card(lua_State *L);
static int32 duel_set_operation_info(lua_State *L); static int32_t duel_clear_target_card(lua_State *L);
static int32 duel_get_operation_info(lua_State *L); static int32_t duel_set_target_player(lua_State *L);
static int32 duel_get_operation_count(lua_State *L); static int32_t duel_set_target_param(lua_State *L);
static int32 duel_clear_operation_info(lua_State *L); static int32_t duel_set_operation_info(lua_State *L);
static int32 duel_check_xyz_material(lua_State *L); static int32_t duel_get_operation_info(lua_State *L);
static int32 duel_select_xyz_material(lua_State *L); static int32_t duel_get_operation_count(lua_State *L);
static int32 duel_overlay(lua_State *L); static int32_t duel_clear_operation_info(lua_State *L);
static int32 duel_get_overlay_group(lua_State *L); static int32_t duel_check_xyz_material(lua_State *L);
static int32 duel_get_overlay_count(lua_State *L); static int32_t duel_select_xyz_material(lua_State *L);
static int32 duel_check_remove_overlay_card(lua_State *L); static int32_t duel_overlay(lua_State *L);
static int32 duel_remove_overlay_card(lua_State *L); static int32_t duel_get_overlay_group(lua_State *L);
static int32_t duel_get_overlay_count(lua_State *L);
static int32_t duel_check_remove_overlay_card(lua_State *L);
static int32_t duel_remove_overlay_card(lua_State *L);
static int32 duel_hint(lua_State *L); static int32_t duel_hint(lua_State *L);
static int32 duel_hint_selection(lua_State *L); static int32_t duel_get_last_select_hint(lua_State *L);
static int32 duel_select_effect_yesno(lua_State *L); static int32_t duel_hint_selection(lua_State *L);
static int32 duel_select_yesno(lua_State *L); static int32_t duel_select_effect_yesno(lua_State *L);
static int32 duel_select_option(lua_State *L); static int32_t duel_select_yesno(lua_State *L);
static int32 duel_select_sequence(lua_State *L); static int32_t duel_select_option(lua_State *L);
static int32 duel_select_position(lua_State *L); static int32_t duel_select_sequence(lua_State *L);
static int32 duel_select_disable_field(lua_State *L); static int32_t duel_select_position(lua_State *L);
static int32 duel_select_field(lua_State *L); static int32_t duel_select_disable_field(lua_State *L);
static int32 duel_announce_race(lua_State *L); static int32_t duel_select_field(lua_State *L);
static int32 duel_announce_attribute(lua_State *L); static int32_t duel_announce_race(lua_State *L);
static int32 duel_announce_level(lua_State *L); static int32_t duel_announce_attribute(lua_State *L);
static int32 duel_announce_card(lua_State *L); static int32_t duel_announce_level(lua_State *L);
static int32 duel_announce_type(lua_State *L); static int32_t duel_announce_card(lua_State *L);
static int32 duel_announce_number(lua_State *L); static int32_t duel_announce_type(lua_State *L);
static int32 duel_announce_coin(lua_State *L); static int32_t duel_announce_number(lua_State *L);
static int32 duel_toss_coin(lua_State *L); static int32_t duel_announce_coin(lua_State *L);
static int32 duel_toss_dice(lua_State *L); static int32_t duel_toss_coin(lua_State *L);
static int32 duel_rock_paper_scissors(lua_State *L); static int32_t duel_toss_dice(lua_State *L);
static int32 duel_get_coin_result(lua_State *L); static int32_t duel_rock_paper_scissors(lua_State *L);
static int32 duel_get_dice_result(lua_State *L); static int32_t duel_get_coin_result(lua_State *L);
static int32 duel_set_coin_result(lua_State *L); static int32_t duel_get_dice_result(lua_State *L);
static int32 duel_set_dice_result(lua_State *L); static int32_t duel_set_coin_result(lua_State *L);
static int32_t duel_set_dice_result(lua_State *L);
static int32 duel_is_player_affected_by_effect(lua_State *L); static int32_t duel_is_player_affected_by_effect(lua_State *L);
static int32 duel_is_player_can_draw(lua_State *L); static int32_t duel_is_player_can_draw(lua_State *L);
static int32 duel_is_player_can_discard_deck(lua_State *L); static int32_t duel_is_player_can_discard_deck(lua_State *L);
static int32 duel_is_player_can_discard_deck_as_cost(lua_State *L); static int32_t duel_is_player_can_discard_deck_as_cost(lua_State *L);
static int32 duel_is_player_can_summon(lua_State *L); static int32_t duel_is_player_can_summon(lua_State *L);
static int32 duel_is_player_can_mset(lua_State *L); static int32_t duel_is_player_can_mset(lua_State *L);
static int32 duel_is_player_can_sset(lua_State *L); static int32_t duel_is_player_can_sset(lua_State *L);
static int32 duel_is_player_can_spsummon(lua_State *L); static int32_t duel_is_player_can_spsummon(lua_State *L);
static int32 duel_is_player_can_flipsummon(lua_State *L); static int32_t duel_is_player_can_flipsummon(lua_State *L);
static int32 duel_is_player_can_spsummon_monster(lua_State *L); static int32_t duel_is_player_can_spsummon_monster(lua_State *L);
static int32 duel_is_player_can_spsummon_count(lua_State *L); static int32_t duel_is_player_can_spsummon_count(lua_State *L);
static int32 duel_is_player_can_release(lua_State *L); static int32_t duel_is_player_can_release(lua_State *L);
static int32 duel_is_player_can_remove(lua_State *L); static int32_t duel_is_player_can_remove(lua_State *L);
static int32 duel_is_player_can_send_to_hand(lua_State *L); static int32_t duel_is_player_can_send_to_hand(lua_State *L);
static int32 duel_is_player_can_send_to_grave(lua_State *L); static int32_t duel_is_player_can_send_to_grave(lua_State *L);
static int32 duel_is_player_can_send_to_deck(lua_State *L); static int32_t duel_is_player_can_send_to_deck(lua_State *L);
static int32 duel_is_player_can_additional_summon(lua_State *L); static int32_t duel_is_player_can_additional_summon(lua_State *L);
static int32 duel_is_chain_negatable(lua_State *L); static int32_t duel_is_chain_solving(lua_State *L);
static int32 duel_is_chain_disablable(lua_State *L); static int32_t duel_is_chain_negatable(lua_State *L);
static int32 duel_is_chain_disabled(lua_State *L); static int32_t duel_is_chain_disablable(lua_State *L);
static int32 duel_check_chain_target(lua_State *L); static int32_t duel_is_chain_disabled(lua_State *L);
static int32 duel_check_chain_uniqueness(lua_State *L); static int32_t duel_check_chain_target(lua_State *L);
static int32 duel_get_activity_count(lua_State *L); static int32_t duel_check_chain_uniqueness(lua_State *L);
static int32 duel_check_phase_activity(lua_State *L); static int32_t duel_get_activity_count(lua_State *L);
static int32 duel_add_custom_activity_counter(lua_State *L); static int32_t duel_check_phase_activity(lua_State *L);
static int32 duel_get_custom_activity_count(lua_State *L); static int32_t duel_add_custom_activity_counter(lua_State *L);
static int32 duel_is_able_to_enter_bp(lua_State *L); static int32_t duel_get_custom_activity_count(lua_State *L);
static int32 duel_get_battled_count(lua_State *L); static int32_t duel_is_able_to_enter_bp(lua_State *L);
static int32_t duel_get_battled_count(lua_State *L);
//specific card functions //specific card functions
static int32 duel_swap_deck_and_grave(lua_State *L); static int32_t duel_swap_deck_and_grave(lua_State *L);
static int32 duel_majestic_copy(lua_State *L); static int32_t duel_majestic_copy(lua_State *L);
static void open_duellib(lua_State *L); static void open_duellib(lua_State *L);
//group metamethods //group metamethods
//__len is in the group lib, which is same as group_get_count //__len is in the group lib, which is same as group_get_count
static int32 group_meta_add(lua_State *L); static int32_t group_meta_add(lua_State *L);
static int32 group_meta_sub(lua_State *L); static int32_t group_meta_sub(lua_State *L);
static int32 group_meta_band(lua_State *L); static int32_t group_meta_band(lua_State *L);
static int32 group_meta_bxor(lua_State *L); static int32_t group_meta_bxor(lua_State *L);
//preload //preload
static int32 debug_message(lua_State *L); static int32_t debug_message(lua_State *L);
static int32 debug_add_card(lua_State *L); static int32_t debug_add_card(lua_State *L);
static int32 debug_set_player_info(lua_State *L); static int32_t debug_set_player_info(lua_State *L);
static int32 debug_pre_summon(lua_State *L); static int32_t debug_pre_summon(lua_State *L);
static int32 debug_pre_equip(lua_State *L); static int32_t debug_pre_equip(lua_State *L);
static int32 debug_pre_set_target(lua_State *L); static int32_t debug_pre_set_target(lua_State *L);
static int32 debug_pre_add_counter(lua_State *L); static int32_t debug_pre_add_counter(lua_State *L);
static int32 debug_reload_field_begin(lua_State *L); static int32_t debug_reload_field_begin(lua_State *L);
static int32 debug_reload_field_end(lua_State *L); static int32_t debug_reload_field_end(lua_State *L);
static int32 debug_set_ai_name(lua_State *L); static int32_t debug_set_ai_name(lua_State *L);
static int32 debug_show_hint(lua_State *L); static int32_t debug_show_hint(lua_State *L);
static void open_debuglib(lua_State *L); static void open_debuglib(lua_State *L);
}; };
......
#ifndef SORT_H_
#define SORT_H_
class card;
struct card_sort {
bool operator()(card* const& c1, card* const& c2) const;
};
#endif /* SORT_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment