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 @@
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
### 1.) Download Fluorohydride/ygopro
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.
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).
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).
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.
## Exposed Functions
### 3.) Download dependencies
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.
The 3 functions need to be provided to the core so it can get card and database information.
- `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
* freetype
* irrlicht
* lua
* sqlite3
- `void set_card_reader(card_reader f);`
Interface provided function that provides database information from the `data` table of `cards.cdb`.
### 4.) Create the project files
Run the following commands from the command line in the `Fluorohydride/ygopro` folder.
- `void set_message_handler(message_handler f);`
Interface provided function that handles error messages.
` premake4 /help `
` premake4 vs2010 `
These functions create the game itself and then manipulate it.
- `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
Make sure the code actually compiles. Compile them in the following order one by one:
- `void end_duel(intptr_t pduel);`
End the duel.
* lua
* sqlite3
* ocgcore
- `void set_player_info(intptr_t pduel, int32_t playerid, int32_t lp, int32_t startcount, int32_t drawcount);`
Set up the duel information.
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.
- `void set_script_reader(script_reader f);` : Interface provided returns scripts based on number that corresponds to a lua file, send in a string.
- `int32_t process(intptr_t pduel);`
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.
- `ptr create_duel(uint32 seed);` : Create a the instance of the duel using a random number.
- `void start_duel(ptr pduel, int32 options);` : Starts the duel
- `void end_duel(ptr pduel);` : ends the duel
- `void set_player_info(ptr pduel, int32 playerid, int32 lp, int32 startcount, int32 drawcount);` sets the duel up
- `void get_log_message(ptr pduel, byte* buf);`
- `int32 get_message(ptr pduel, byte* buf);`
- `int32 process(ptr pduel);` : do a game tick
- `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 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.
- `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_responsei(ptr pduel, int32 value);`
- `void set_responseb(ptr pduel, byte* buf);`
- `int32 preload_script(ptr pduel, char* script, int32 len);`
- `int32_t query_field_card(intptr_t pduel, uint8_t playerid, uint8_t location, uint32_t query_flag, byte* buf, int32_t use_cache);`
Get a card in a specific location.
- `int32_t query_field_count(intptr_t pduel, uint8_t playerid, uint8_t location);`
Get the number of cards in a specific location.
- `int32_t query_field_card(intptr_t pduel, uint8_t playerid, uint8_t location, uint32_t query_flag, byte* buf, int32_t use_cache);`
Get all cards in some location.
- `int32_t query_field_info(intptr_t pduel, byte* buf);`
- `void set_responsei(intptr_t pduel, int32_t value);`
- `void set_responseb(intptr_t pduel, byte* buf);`
- `int32_t preload_script(intptr_t pduel, const char* script_name);`
- `byte* default_script_reader(const char* script_name, int* len);`
The default script reader using `fread`.
# 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 @@
#include "common.h"
#include "effectset.h"
#include "card_data.h"
#include "sort.h"
#include <set>
#include <map>
#include <unordered_set>
......@@ -22,120 +24,109 @@ class effect;
class group;
struct chain;
struct card_data {
uint32 code;
uint32 alias;
uint64 setcode;
uint32 type;
uint32 level;
uint32 attribute;
uint32 race;
int32 attack;
int32 defense;
uint32 lscale;
uint32 rscale;
uint32 link_marker;
using card_set = std::set<card*, card_sort>;
using card_vector = std::vector<card*>;
using effect_container = std::multimap<uint32_t, effect*>;
using effect_indexer = std::unordered_map<effect*, effect_container::iterator>;
using effect_collection = std::unordered_set<effect*>;
void clear();
};
using effect_filter = bool(*)(card* self, effect* peffect);
using effect_filter_target = bool(*)(card* self, effect* peffect, card* target);
struct card_state {
card_state()
: 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),
controler(PLAYER_NONE), location(0), sequence(0), position(0), reason(0), pzone(false), reason_card(nullptr), reason_player(PLAYER_NONE), reason_effect(nullptr) {}
uint32_t code{ 0 };
uint32_t code2{ 0 };
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;
uint32 code2;
std::vector<uint32> setcode;
uint32 type;
uint32 level;
uint32 rank;
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;
bool is_location(uint32_t loc) const;
bool is_main_mzone() const {
return location == LOCATION_MZONE && sequence >= 0 && sequence <= 4;
}
bool is_stzone() const {
return location == LOCATION_SZONE && sequence >= 0 && sequence <= 4;
}
void init_state();
};
struct query_cache {
uint32 code;
uint32 alias;
uint32 type;
uint32 level;
uint32 rank;
uint32 link;
uint32 attribute;
uint32 race;
int32 attack;
int32 defense;
int32 base_attack;
int32 base_defense;
uint32 reason;
int32 status;
uint32 lscale;
uint32 rscale;
uint32 link_marker;
uint32_t info_location{ UINT32_MAX };
uint32_t current_code{ UINT32_MAX };
uint32_t type{ UINT32_MAX };
uint32_t level{ UINT32_MAX };
uint32_t rank{ UINT32_MAX };
uint32_t link{ UINT32_MAX };
uint32_t attribute{ UINT32_MAX };
uint32_t race{ UINT32_MAX };
int32_t attack{ -1 };
int32_t defense{ -1 };
int32_t base_attack{ -1 };
int32_t base_defense{ -1 };
uint32_t reason{ UINT32_MAX };
uint32_t status{ UINT32_MAX };
uint32_t lscale{ UINT32_MAX };
uint32_t rscale{ UINT32_MAX };
uint32_t link_marker{ UINT32_MAX };
void clear_cache();
};
struct material_info {
// Synchron
card* limit_tuner;
group* limit_syn;
int32 limit_syn_minc;
int32 limit_syn_maxc;
card* limit_tuner{ nullptr };
group* limit_syn{ nullptr };
int32_t limit_syn_minc{ 0 };
int32_t limit_syn_maxc{ 0 };
// Xyz
group* limit_xyz;
int32 limit_xyz_minc;
int32 limit_xyz_maxc;
group* limit_xyz{ nullptr };
int32_t limit_xyz_minc{ 0 };
int32_t limit_xyz_maxc{ 0 };
// Link
group* limit_link;
card* limit_link_card;
int32 limit_link_minc;
int32 limit_link_maxc;
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) {}
group* limit_link{ nullptr };
card* limit_link_card{ nullptr };
int32_t limit_link_minc{ 0 };
int32_t limit_link_maxc{ 0 };
};
const material_info null_info;
class card {
public:
struct effect_relation_hash {
inline std::size_t operator()(const std::pair<effect*, uint16>& v) const {
return std::hash<uint16>()(v.second);
std::size_t operator()(const std::pair<effect*, uint16_t>& v) const {
return std::hash<uint16_t>()(v.second);
}
};
using card_vector = std::vector<card*>;
using effect_container = std::multimap<uint32, effect*>;
using card_set = std::set<card*, card_sort>;
using effect_indexer = std::unordered_map<effect*, effect_container::iterator>;
using effect_relation = std::unordered_set<std::pair<effect*, uint16>, effect_relation_hash>;
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>> {
using effect_relation = std::unordered_set<std::pair<effect*, uint16_t>, effect_relation_hash>;
using relation_map = std::unordered_map<card*, uint32_t>;
using counter_map = std::map<uint16_t, uint16_t>;
using effect_count = std::map<uint32_t, int32_t>;
class attacker_map : public std::unordered_map<uint32_t, std::pair<card*, uint32_t>> {
public:
void addcard(card* pcard);
uint32 findcard(card* pcard);
uint32_t findcard(card* pcard);
};
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;
position = pos;
location = loc;
......@@ -147,52 +138,55 @@ public:
location = 0;
sequence = 0;
}
uint8 playerid;
uint8 position;
uint8 location;
uint8 sequence;
uint8_t playerid{ 0 };
uint8_t position{ 0 };
uint8_t location{ 0 };
uint8_t sequence{ 0 };
};
int32 ref_handle;
duel* pduel;
int32_t ref_handle{};
duel* pduel{};
card_data data;
card_state previous;
card_state temp;
card_state current;
card_state spsummon;
query_cache q_cache;
uint8 owner;
uint8 summon_player;
uint32 summon_info;
uint32 status;
uint8_t owner{ PLAYER_NONE };
uint8_t summon_player{ PLAYER_NONE };
uint32_t summon_info{};
uint32_t status{};
sendto_param_t sendto_param;
uint32 release_param;
uint32 sum_param;
uint32 position_param;
uint32 spsummon_param;
uint32 to_field_param;
uint8 attack_announce_count;
uint8 direct_attackable;
uint8 announce_count;
uint8 attacked_count;
uint8 attack_all_target;
uint8 attack_controler;
uint16 cardid;
uint32 fieldid;
uint32 fieldid_r;
uint16 turnid;
uint16 turn_counter;
uint8 unique_pos[2];
uint32 unique_fieldid;
uint32 unique_code;
uint32 unique_location;
int32 unique_function;
effect* unique_effect;
uint32 spsummon_code;
uint16 spsummon_counter[2];
uint8 assume_type;
uint32 assume_value;
card* equiping_target;
card* pre_equip_target;
card* overlay_target;
uint32_t release_param{};
uint32_t sum_param{};
uint32_t position_param{};
uint32_t spsummon_param{};
uint32_t to_field_param{};
uint8_t attack_announce_count{};
uint8_t direct_attackable{};
uint8_t announce_count{};
uint8_t attacked_count{};
uint8_t attack_all_target{};
uint8_t attack_controler{};
uint64_t cardid{};
uint32_t fieldid{};
uint32_t fieldid_r{}; //real field id, updated when moving to new location
uint32_t activate_count_id{}; //updated when moving to new location or flipping
uint16_t turnid{};
uint16_t turn_counter{};
uint8_t unique_pos[2]{};
uint32_t unique_fieldid{};
uint32_t unique_code{};
uint32_t unique_location{};
int32_t unique_function{};
effect* unique_effect{};
uint32_t spsummon_code{};
uint16_t spsummon_counter[2]{};
uint8_t assume_type{};
uint32_t assume_value{};
card* equiping_target{};
card* pre_equip_target{};
card* overlay_target{};
relation_map relations;
counter_map counters;
effect_count indestructable_effects;
......@@ -204,6 +198,7 @@ public:
card_set effect_target_owner;
card_set effect_target_cards;
card_vector xyz_materials;
int32_t xyz_materials_previous_count_onfield{};
effect_container single_effect;
effect_container field_effect;
effect_container equip_effect;
......@@ -212,197 +207,230 @@ public:
effect_indexer indexer;
effect_relation relate_effect;
effect_set_v immune_effect;
effect_collection initial_effect;
effect_collection owning_effect;
explicit card(duel* pd);
~card() = default;
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);
uint32 get_info_location();
uint32 second_code(uint32 code);
uint32 get_code();
uint32 get_another_code();
int32 is_set_card(uint32 set_code);
int32 is_origin_set_card(uint32 set_code);
int32 is_pre_set_card(uint32 set_code);
int32 is_fusion_set_card(uint32 set_code);
int32 is_link_set_card(uint32 set_code);
uint32 get_type();
uint32 get_fusion_type();
uint32 get_synchro_type();
uint32 get_xyz_type();
uint32 get_link_type();
std::pair<int32, int32> get_base_atk_def();
std::pair<int32, int32> get_atk_def();
int32 get_base_attack();
int32 get_attack();
int32 get_base_defense();
int32 get_defense();
int32 get_battle_attack();
int32 get_battle_defense();
uint32 get_level();
uint32 get_rank();
uint32 get_link();
uint32 get_synchro_level(card* pcard);
uint32 get_ritual_level(card* pcard);
uint32 check_xyz_level(card* pcard, uint32 lv);
uint32 get_attribute();
uint32 get_fusion_attribute(uint8 playerid);
uint32 get_link_attribute(uint8 playerid);
uint32 get_grave_attribute(uint8 playerid);
uint32 get_race();
uint32 get_link_race(uint8 playerid);
uint32 get_grave_race(uint8 playerid);
uint32 get_lscale();
uint32 get_rscale();
uint32 get_link_marker();
int32 is_link_marker(uint32 dir);
uint32 get_linked_zone();
int32_t get_infos(byte* buf, uint32_t query_flag, int32_t use_cache = TRUE);
uint32_t get_info_location() const;
uint32_t get_original_code() const;
std::tuple<uint32_t, uint32_t> get_original_code_rule() const;
uint32_t get_code();
uint32_t get_another_code();
int32_t is_set_card(uint32_t set_code);
int32_t is_origin_set_card(uint32_t set_code);
int32_t is_pre_set_card(uint32_t set_code);
int32_t is_fusion_set_card(uint32_t set_code);
int32_t is_link_set_card(uint32_t set_code);
int32_t is_special_summon_set_card(uint32_t set_code);
uint32_t get_type();
uint32_t get_fusion_type();
uint32_t get_synchro_type();
uint32_t get_xyz_type();
uint32_t get_link_type();
std::pair<int32_t, int32_t> get_base_atk_def();
std::pair<int32_t, int32_t> get_atk_def();
int32_t get_base_attack();
int32_t get_attack();
int32_t get_base_defense();
int32_t get_defense();
int32_t get_battle_attack();
int32_t get_battle_defense();
uint32_t get_level();
uint32_t get_rank();
uint32_t get_link();
uint32_t get_mat_level_from_effect(card* pcard, uint32_t effect_code);
uint32_t get_mat_level(card* pcard, uint32_t level_effect_code, uint32_t allow_effect_code = 0);
uint32_t get_synchro_level(card* pcard);
uint32_t get_ritual_level(card* pcard);
uint32_t check_xyz_level(card* pcard, uint32_t lv);
uint32_t get_attribute();
uint32_t get_fusion_attribute(uint8_t playerid);
uint32_t get_link_attribute(uint8_t playerid);
uint32_t get_grave_attribute(uint8_t playerid);
uint32_t get_race();
uint32_t get_link_race(uint8_t playerid);
uint32_t get_grave_race(uint8_t playerid);
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);
uint32 get_mutual_linked_zone();
uint32_t get_mutual_linked_zone();
void get_mutual_linked_cards(card_set * cset);
int32 is_link_state();
int32 is_extra_link_state();
int32 is_position(int32 pos);
void set_status(uint32 status, int32 enabled);
int32 get_status(uint32 status);
int32 is_status(uint32 status);
uint32 get_column_zone(int32 location);
int32_t is_link_state();
int32_t is_extra_link_state();
int32_t is_position(uint32_t pos) const;
void set_status(uint32_t x, int32_t enabled);
int32_t get_status(uint32_t x) const;
int32_t is_status(uint32_t x) const;
uint32_t get_column_zone(int32_t location);
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();
int32 get_union_count();
int32 get_old_union_count();
void xyz_overlay(card_set* materials);
int32_t get_union_count();
int32_t get_old_union_count();
void xyz_overlay(const card_set& materials);
void xyz_add(card* mat);
void xyz_remove(card* mat);
void apply_field_effect();
void cancel_field_effect();
void enable_field_effect(bool enabled);
int32 add_effect(effect* peffect);
void remove_effect(effect* peffect);
void remove_effect(effect* peffect, effect_container::iterator it);
int32 copy_effect(uint32 code, uint32 reset, uint32 count);
int32 replace_effect(uint32 code, uint32 reset, uint32 count);
void reset(uint32 id, uint32 reset_type);
int32_t add_effect(effect* peffect);
effect_indexer::iterator remove_effect(effect* peffect);
int32_t copy_effect(uint32_t code, uint32_t reset, int32_t count);
int32_t replace_effect(uint32_t code, uint32_t reset, int32_t count);
void reset(uint32_t id, uint32_t reset_type);
void reset_effect_count();
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 create_relation(card* target, uint32 reset);
int32 is_has_relation(card* target);
void count_turn(uint16_t ct);
void create_relation(card* target, uint32_t reset);
int32_t is_has_relation(card* target);
void release_relation(card* target);
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 clear_relate_effect();
void create_relation(effect* peffect);
int32 is_has_relation(effect* peffect);
int32_t is_has_relation(effect* peffect);
void release_relation(effect* peffect);
int32 leave_field_redirect(uint32 reason);
int32 destination_redirect(uint8 destination, uint32 reason);
int32 add_counter(uint8 playerid, uint16 countertype, uint16 count, uint8 singly);
int32 remove_counter(uint16 countertype, uint16 count);
int32 is_can_add_counter(uint8 playerid, uint16 countertype, uint16 count, uint8 singly, uint32 loc);
int32 is_can_have_counter(uint16 countertype);
int32 get_counter(uint16 countertype);
int32_t leave_field_redirect(uint32_t reason);
int32_t destination_redirect(uint8_t destination, uint32_t reason);
int32_t add_counter(uint8_t playerid, uint16_t countertype, uint16_t count, uint8_t singly);
int32_t remove_counter(uint16_t countertype, uint16_t count);
int32_t is_can_add_counter(uint8_t playerid, uint16_t countertype, uint16_t count, uint8_t singly, uint32_t loc);
int32_t is_can_have_counter(uint16_t countertype);
int32_t get_counter(uint16_t countertype);
void set_material(card_set* materials);
void add_card_target(card* pcard);
void cancel_card_target(card* pcard);
void delete_card_target(uint32_t send_msg);
void clear_card_target();
void set_special_summon_status(effect* peffect);
void filter_effect(int32 code, effect_set* eset, uint8 sort = TRUE);
void filter_single_continuous_effect(int32 code, effect_set* eset, uint8 sort = TRUE);
void filter_self_effect(int32 code, effect_set* eset, uint8 sort = TRUE);
template<typename T>
void filter_effect_container(const effect_container& container, uint32_t code, effect_filter f, T& eset);
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_disable_related_cards();
int32 filter_summon_procedure(uint8 playerid, effect_set* eset, uint8 ignore_count, uint8 min_tribute, uint32 zone);
int32 check_summon_procedure(effect* proc, uint8 playerid, uint8 ignore_count, uint8 min_tribute, uint32 zone);
int32 filter_set_procedure(uint8 playerid, effect_set* eset, uint8 ignore_count, uint8 min_tribute, uint32 zone);
int32 check_set_procedure(effect* proc, uint8 playerid, uint8 ignore_count, uint8 min_tribute, uint32 zone);
void filter_spsummon_procedure(uint8 playerid, effect_set* eset, uint32 summon_type, material_info info = null_info);
void filter_spsummon_procedure_g(uint8 playerid, effect_set* eset);
effect* is_affected_by_effect(int32 code);
effect* is_affected_by_effect(int32 code, card* target);
int32 fusion_check(group* fusion_m, card* cg, uint32 chkf, uint8 not_material);
void fusion_select(uint8 playerid, group* fusion_m, card* cg, uint32 chkf, uint8 not_material);
int32 check_fusion_substitute(card* fcard);
int32 is_not_tuner(card* scard);
int32_t filter_summon_procedure(uint8_t playerid, effect_set* eset, uint8_t ignore_count, uint8_t min_tribute, uint32_t zone);
int32_t check_summon_procedure(effect* proc, uint8_t playerid, uint8_t ignore_count, uint8_t min_tribute, uint32_t zone);
int32_t filter_set_procedure(uint8_t playerid, effect_set* eset, uint8_t ignore_count, uint8_t min_tribute, uint32_t 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_t playerid, effect_set* eset, uint32_t summon_type, material_info info = null_info);
void filter_spsummon_procedure_g(uint8_t playerid, effect_set* eset);
effect* find_effect(const effect_container& container, uint32_t code, effect_filter f);
effect* find_effect_with_target(const effect_container& container, uint32_t code, effect_filter_target f, card* target);
effect* is_affected_by_effect(uint32_t code);
effect* is_affected_by_effect(int32_t code, card* target);
int32_t fusion_check(group* fusion_m, card* cg, uint32_t chkf, uint8_t not_material);
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);
void get_unique_target(card_set* cset, int32 controler, card* icard = 0);
int32 check_cost_condition(int32 ecode, int32 playerid);
int32 check_cost_condition(int32 ecode, int32 playerid, int32 sumtype);
int32 is_summonable_card();
int32 is_spsummonable_card();
int32 is_fusion_summonable_card(uint32 summon_type);
int32 is_spsummonable(effect* proc, material_info info = null_info);
int32 is_summonable(effect* proc, uint8 min_tribute, uint32 zone = 0x1f, uint32 releasable = 0xff00ff);
int32 is_can_be_summoned(uint8 playerid, uint8 ingore_count, effect* peffect, uint8 min_tribute, uint32 zone = 0x1f);
int32 get_summon_tribute_count();
int32 get_set_tribute_count();
int32 is_can_be_flip_summoned(uint8 playerid);
int32 is_special_summonable(uint8 playerid, uint32 summon_type, material_info info = null_info);
int32 is_can_be_special_summoned(effect* reason_effect, uint32 sumtype, uint8 sumpos, uint8 sumplayer, uint8 toplayer, uint8 nocheck, uint8 nolimit, uint32 zone);
uint8 get_spsummonable_position(effect* reason_effect, uint32 sumtype, uint8 sumpos, uint8 sumplayer, uint8 toplayer);
int32 is_setable_mzone(uint8 playerid, uint8 ignore_count, effect* peffect, uint8 min_tribute, uint32 zone = 0x1f);
int32 is_setable_szone(uint8 playerid, uint8 ignore_fd = 0);
int32 is_affect_by_effect(effect* reason_effect);
int32 is_can_be_disabled_by_effect(effect* reason_effect);
int32 is_destructable();
int32 is_destructable_by_battle(card* pcard);
effect* check_indestructable_by_effect(effect* reason_effect, uint8 playerid);
int32 is_destructable_by_effect(effect* reason_effect, uint8 playerid);
int32 is_removeable(uint8 playerid, uint8 pos, uint32 reason);
int32 is_removeable_as_cost(uint8 playerid, uint8 pos);
int32 is_releasable_by_summon(uint8 playerid, card* pcard);
int32 is_releasable_by_nonsummon(uint8 playerid);
int32 is_releasable_by_effect(uint8 playerid, effect* reason_effect);
int32 is_capable_send_to_grave(uint8 playerid);
int32 is_capable_send_to_hand(uint8 playerid);
int32 is_capable_send_to_deck(uint8 playerid);
int32 is_capable_send_to_extra(uint8 playerid);
int32 is_capable_cost_to_grave(uint8 playerid);
int32 is_capable_cost_to_hand(uint8 playerid);
int32 is_capable_cost_to_deck(uint8 playerid);
int32 is_capable_cost_to_extra(uint8 playerid);
int32 is_capable_attack();
int32 is_capable_attack_announce(uint8 playerid);
int32 is_capable_change_position(uint8 playerid);
int32 is_capable_change_position_by_effect(uint8 playerid);
int32 is_capable_turn_set(uint8 playerid);
int32 is_capable_change_control();
int32 is_control_can_be_changed(int32 ignore_mzone, uint32 zone);
int32 is_capable_be_battle_target(card* pcard);
int32 is_capable_be_effect_target(effect* reason_effect, uint8 playerid);
int32 is_capable_overlay(uint8 playerid);
int32 is_can_be_fusion_material(card* fcard, uint32 summon_type);
int32 is_can_be_synchro_material(card* scard, card* tuner = 0);
int32 is_can_be_ritual_material(card* scard);
int32 is_can_be_xyz_material(card* scard);
int32 is_can_be_link_material(card* scard);
int32_t check_unique_code(card* pcard);
void get_unique_target(card_set* cset, int32_t controler, card* icard = nullptr);
int32_t check_cost_condition(int32_t ecode, int32_t playerid);
int32_t check_cost_condition(int32_t ecode, int32_t playerid, int32_t sumtype);
int32_t is_summonable_card() const;
int32_t is_spsummonable_card();
int32_t is_fusion_summonable_card(uint32_t summon_type);
int32_t is_spsummonable(effect* proc, material_info info = null_info);
int32_t is_summonable(effect* proc, uint8_t min_tribute, uint32_t zone = 0x1f, uint32_t releasable = 0xff00ff);
int32_t is_can_be_summoned(uint8_t playerid, uint8_t ingore_count, effect* peffect, uint8_t min_tribute, uint32_t zone = 0x1f);
int32_t is_summon_negatable(uint32_t sumtype, effect* reason_effect);
int32_t get_summon_tribute_count();
int32_t get_set_tribute_count();
int32_t is_can_be_flip_summoned(uint8_t playerid);
int32_t is_special_summonable(uint8_t playerid, uint32_t summon_type, material_info info = null_info);
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);
uint8_t get_spsummonable_position(effect* reason_effect, uint32_t sumtype, uint8_t sumpos, uint8_t sumplayer, uint8_t toplayer);
int32_t is_setable_mzone(uint8_t playerid, uint8_t ignore_count, effect* peffect, uint8_t min_tribute, uint32_t zone = 0x1f);
int32_t is_setable_szone(uint8_t playerid, uint8_t ignore_fd = 0);
int32_t is_affect_by_effect(effect* reason_effect);
int32_t is_can_be_disabled_by_effect(effect* reason_effect, bool is_monster_effect);
int32_t is_destructable();
int32_t is_destructable_by_battle(card* pcard);
effect* check_indestructable_by_effect(effect* reason_effect, uint8_t playerid);
int32_t is_destructable_by_effect(effect* reason_effect, uint8_t playerid);
int32_t is_removeable(uint8_t playerid, uint8_t pos, uint32_t reason);
int32_t is_removeable_as_cost(uint8_t playerid, uint8_t pos);
int32_t is_releasable_by_summon(uint8_t playerid, card* pcard);
int32_t is_releasable_by_nonsummon(uint8_t playerid, uint32_t reason);
int32_t is_releasable_by_effect(uint8_t playerid, effect* reason_effect);
int32_t is_capable_send_to_grave(uint8_t playerid);
int32_t is_capable_send_to_hand(uint8_t playerid);
int32_t is_capable_send_to_deck(uint8_t playerid, uint8_t send_activating = FALSE);
int32_t is_capable_send_to_extra(uint8_t playerid);
int32_t is_capable_cost_to_grave(uint8_t playerid);
int32_t is_capable_cost_to_hand(uint8_t playerid);
int32_t is_capable_cost_to_deck(uint8_t playerid);
int32_t is_capable_cost_to_extra(uint8_t playerid);
int32_t is_capable_attack();
int32_t is_capable_attack_announce(uint8_t playerid);
int32_t is_capable_change_position(uint8_t playerid);
int32_t is_capable_change_position_by_effect(uint8_t playerid);
int32_t is_capable_turn_set(uint8_t playerid);
int32_t is_capable_change_control();
int32_t is_control_can_be_changed(int32_t ignore_mzone, uint32_t zone);
int32_t is_capable_be_battle_target(card* pcard);
int32_t is_capable_be_effect_target(effect* reason_effect, uint8_t playerid);
int32_t is_capable_overlay(uint8_t playerid);
int32_t is_can_be_fusion_material(card* fcard, uint32_t summon_type);
int32_t is_can_be_synchro_material(card* scard, card* tuner = nullptr);
int32_t is_can_be_ritual_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
#define SUMMON_TYPE_NORMAL 0x10000000
#define SUMMON_TYPE_ADVANCE 0x11000000
#define SUMMON_TYPE_DUAL 0x12000000
#define SUMMON_TYPE_FLIP 0x20000000
#define SUMMON_TYPE_SPECIAL 0x40000000
#define SUMMON_TYPE_FUSION 0x43000000
#define SUMMON_TYPE_RITUAL 0x45000000
#define SUMMON_TYPE_SYNCHRO 0x46000000
#define SUMMON_TYPE_XYZ 0x49000000
#define SUMMON_TYPE_PENDULUM 0x4a000000
#define SUMMON_TYPE_LINK 0x4c000000
//Summon Type in summon_info
#define SUMMON_TYPE_NORMAL 0x10000000U
#define SUMMON_TYPE_ADVANCE 0x11000000U
#define SUMMON_TYPE_FLIP 0x20000000U
#define SUMMON_TYPE_SPECIAL 0x40000000U
#define SUMMON_TYPE_FUSION 0x43000000U
#define SUMMON_TYPE_RITUAL 0x45000000U
#define SUMMON_TYPE_SYNCHRO 0x46000000U
#define SUMMON_TYPE_XYZ 0x49000000U
#define SUMMON_TYPE_PENDULUM 0x4a000000U
#define SUMMON_TYPE_LINK 0x4c000000U
//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
#define COUNTER_WITHOUT_PERMIT 0x1000
#define COUNTER_WITHOUT_PERMIT 0x1000U
//#define COUNTER_NEED_ENABLE 0x2000
//Assume
#define ASSUME_CODE 1
#define ASSUME_TYPE 2
#define ASSUME_LEVEL 3
......@@ -412,10 +440,17 @@ public:
#define ASSUME_ATTACK 7
#define ASSUME_DEFENSE 8
//double-name cards
#define CARD_MARINE_DOLPHIN 78734254
#define CARD_TWINKLE_MOSS 13857930
#define CARD_ARTWORK_VERSIONS_OFFSET 10
//Special Summon effect info
#define SUMMON_INFO_CODE 0x01
#define SUMMON_INFO_CODE2 0x02
#define SUMMON_INFO_TYPE 0x04
#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_ */
#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 @@
#define COMMON_H_
#include <stdint.h>
typedef unsigned long long uint64;
typedef unsigned int uint32;
typedef unsigned short uint16;
typedef unsigned char uint8;
#include <assert.h>
typedef unsigned char byte;
typedef long long int64;
typedef int int32;
typedef short int16;
typedef signed char int8;
typedef int BOOL;
inline bool check_playerid(int32_t playerid) {
return playerid >= 0 && playerid <= 1;
}
#define MATCH_ALL(x,y) (((x)&(y))==(y))
#define MATCH_ANY(x,y) ((x)&(y))
......@@ -30,25 +26,35 @@ typedef int BOOL;
#define OPERATION_CANCELED -1
#define TRUE 1
#define FALSE 0
#ifndef NULL
#define NULL 0
#endif
struct card_sort {
bool operator()(void* const & c1, void* const & c2) const;
};
#define SIZE_MESSAGE_BUFFER 0x2000
#define SIZE_RETURN_VALUE 512
#define SIZE_AI_NAME 128
#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
#define LOCATION_DECK 0x01 //
#define LOCATION_HAND 0x02 //
#define LOCATION_MZONE 0x04 //
#define LOCATION_SZONE 0x08 //
#define LOCATION_GRAVE 0x10 //
#define LOCATION_REMOVED 0x20 //
#define LOCATION_EXTRA 0x40 //
#define LOCATION_OVERLAY 0x80 //
#define LOCATION_ONFIELD 0x0c //
#define LOCATION_FZONE 0x100 //
#define LOCATION_PZONE 0x200 //
#define LOCATION_DECK 0x01U
#define LOCATION_HAND 0x02U
#define LOCATION_MZONE 0x04U
#define LOCATION_SZONE 0x08U
#define LOCATION_GRAVE 0x10U
#define LOCATION_REMOVED 0x20U
#define LOCATION_EXTRA 0x40U
#define LOCATION_OVERLAY 0x80U
#define LOCATION_ONFIELD (LOCATION_MZONE | LOCATION_SZONE)
#define LOCATION_FZONE 0x100U
#define LOCATION_PZONE 0x200U
//For redirect
#define LOCATION_DECKBOT 0x10001 //Return to deck bottom
#define LOCATION_DECKSHF 0x20001 //Return to deck and shuffle
......@@ -69,6 +75,10 @@ struct card_sort {
//Flip effect flags
#define NO_FLIP_EFFECT 0x10000
//Move to field flags
#define RETURN_TEMP_REMOVE_TO_FIELD 1
#define RETURN_TRAP_MONSTER_TO_SZONE 2
//Types
#define TYPE_MONSTER 0x1 //
#define TYPE_SPELL 0x2 //
......@@ -96,7 +106,11 @@ struct card_sort {
#define TYPE_SPSUMMON 0x2000000 //
#define TYPE_LINK 0x4000000 //
#define TYPES_EXTRA_DECK (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK)
//Attributes
#define ATTRIBUTES_COUNT 7
#define ATTRIBUTE_ALL 0x7f //
#define ATTRIBUTE_EARTH 0x01 //
#define ATTRIBUTE_WATER 0x02 //
#define ATTRIBUTE_FIRE 0x04 //
......@@ -106,6 +120,8 @@ struct card_sort {
#define ATTRIBUTE_DEVINE 0x40 //
//Races
#define RACES_COUNT 26
#define RACE_ALL 0x3ffffff
#define RACE_WARRIOR 0x1 //
#define RACE_SPELLCASTER 0x2 //
#define RACE_FAIRY 0x4 //
......@@ -131,6 +147,7 @@ struct card_sort {
#define RACE_CREATORGOD 0x400000 //
#define RACE_WYRM 0x800000 //
#define RACE_CYBERSE 0x1000000 //
#define RACE_ILLUSION 0x2000000 //
//Reason
#define REASON_DESTROY 0x1 //
......@@ -161,29 +178,33 @@ struct card_sort {
#define REASON_REVEAL 0x8000000 //
#define REASON_LINK 0x10000000 //
#define REASON_LOST_OVERLAY 0x20000000 //
#define REASON_MAINTENANCE 0x40000000 //
#define REASON_ACTION 0x80000000 //
#define REASONS_PROCEDURE (REASON_SYNCHRO | REASON_XYZ | REASON_LINK)
//Status
#define STATUS_DISABLED 0x0001 //
#define STATUS_TO_ENABLE 0x0002 //
#define STATUS_TO_DISABLE 0x0004 //
#define STATUS_PROC_COMPLETE 0x0008 //
#define STATUS_SET_TURN 0x0010 //
#define STATUS_NO_LEVEL 0x0020 //
#define STATUS_BATTLE_RESULT 0x0040 //
#define STATUS_SPSUMMON_STEP 0x0080 //
#define STATUS_FORM_CHANGED 0x0100 //
#define STATUS_SUMMONING 0x0200 //
#define STATUS_EFFECT_ENABLED 0x0400 //
#define STATUS_SUMMON_TURN 0x0800 //
#define STATUS_DESTROY_CONFIRMED 0x1000 //
#define STATUS_LEAVE_CONFIRMED 0x2000 //
#define STATUS_BATTLE_DESTROYED 0x4000 //
#define STATUS_COPYING_EFFECT 0x8000 //
#define STATUS_CHAINING 0x10000 //
#define STATUS_SUMMON_DISABLED 0x20000 //
#define STATUS_ACTIVATE_DISABLED 0x40000 //
#define STATUS_DISABLED 0x0001
#define STATUS_TO_ENABLE 0x0002
#define STATUS_TO_DISABLE 0x0004
#define STATUS_PROC_COMPLETE 0x0008
#define STATUS_SET_TURN 0x0010
#define STATUS_NO_LEVEL 0x0020
#define STATUS_BATTLE_RESULT 0x0040
#define STATUS_SPSUMMON_STEP 0x0080
#define STATUS_CANNOT_CHANGE_FORM 0x0100
#define STATUS_SUMMONING 0x0200
#define STATUS_EFFECT_ENABLED 0x0400
#define STATUS_SUMMON_TURN 0x0800
#define STATUS_DESTROY_CONFIRMED 0x1000
#define STATUS_LEAVE_CONFIRMED 0x2000
#define STATUS_BATTLE_DESTROYED 0x4000
#define STATUS_COPYING_EFFECT 0x8000
#define STATUS_CHAINING 0x10000
#define STATUS_SUMMON_DISABLED 0x20000
#define STATUS_ACTIVATE_DISABLED 0x40000
#define STATUS_EFFECT_REPLACED 0x80000
#define STATUS_FUTURE_FUSION 0x100000
#define STATUS_FLIP_SUMMONING 0x100000
#define STATUS_ATTACK_CANCELED 0x200000
#define STATUS_INITIALIZING 0x400000
#define STATUS_TO_HAND_WITHOUT_CONFIRM 0x800000
......@@ -194,6 +215,7 @@ struct card_sort {
#define STATUS_OPPO_BATTLE 0x10000000
#define STATUS_FLIP_SUMMON_TURN 0x20000000
#define STATUS_SPSUMMON_TURN 0x40000000
#define STATUS_FLIP_SUMMON_DISABLED 0x80000000
//Query list
#define QUERY_CODE 0x1
......@@ -233,12 +255,12 @@ struct card_sort {
//Messages
#define MSG_RETRY 1
#define MSG_HINT 2
#define MSG_WAITING 3
#define MSG_START 4
//#define MSG_WAITING 3
//#define MSG_START 4
#define MSG_WIN 5
#define MSG_UPDATE_DATA 6
#define MSG_UPDATE_CARD 7
#define MSG_REQUEST_DECK 8
//#define MSG_UPDATE_DATA 6
//#define MSG_UPDATE_CARD 7
//#define MSG_REQUEST_DECK 8
#define MSG_SELECT_BATTLECMD 10
#define MSG_SELECT_IDLECMD 11
#define MSG_SELECT_EFFECTYN 12
......@@ -249,7 +271,6 @@ struct card_sort {
#define MSG_SELECT_PLACE 18
#define MSG_SELECT_POSITION 19
#define MSG_SELECT_TRIBUTE 20
//#define MSG_SORT_CHAIN 21
#define MSG_SELECT_COUNTER 22
#define MSG_SELECT_SUM 23
#define MSG_SELECT_DISFIELD 24
......@@ -259,7 +280,7 @@ struct card_sort {
#define MSG_CONFIRM_CARDS 31
#define MSG_SHUFFLE_DECK 32
#define MSG_SHUFFLE_HAND 33
#define MSG_REFRESH_DECK 34
//#define MSG_REFRESH_DECK 34
#define MSG_SWAP_GRAVE_DECK 35
#define MSG_SHUFFLE_SET_CARD 36
#define MSG_REVERSE_DECK 37
......@@ -286,7 +307,7 @@ struct card_sort {
#define MSG_CHAIN_END 74
#define MSG_CHAIN_NEGATED 75
#define MSG_CHAIN_DISABLED 76
#define MSG_CARD_SELECTED 80
//#define MSG_CARD_SELECTED 80
#define MSG_RANDOM_SELECTED 81
#define MSG_BECOME_TARGET 83
#define MSG_DRAW 90
......@@ -294,7 +315,7 @@ struct card_sort {
#define MSG_RECOVER 92
#define MSG_EQUIP 93
#define MSG_LPUPDATE 94
#define MSG_UNEQUIP 95
//#define MSG_UNEQUIP 95
#define MSG_CARD_TARGET 96
#define MSG_CANCEL_TARGET 97
#define MSG_PAY_LPCOST 100
......@@ -306,9 +327,9 @@ struct card_sort {
#define MSG_DAMAGE_STEP_START 113
#define MSG_DAMAGE_STEP_END 114
#define MSG_MISSED_EFFECT 120
#define MSG_BE_CHAIN_TARGET 121
#define MSG_CREATE_RELATION 122
#define MSG_RELEASE_RELATION 123
//#define MSG_BE_CHAIN_TARGET 121
//#define MSG_CREATE_RELATION 122
//#define MSG_RELEASE_RELATION 123
#define MSG_TOSS_COIN 130
#define MSG_TOSS_DICE 131
#define MSG_ROCK_PAPER_SCISSORS 132
......@@ -319,9 +340,9 @@ struct card_sort {
#define MSG_ANNOUNCE_NUMBER 143
#define MSG_CARD_HINT 160
#define MSG_TAG_SWAP 161
#define MSG_RELOAD_FIELD 162 // Debug.ReloadFieldEnd()
#define MSG_AI_NAME 163
#define MSG_SHOW_HINT 164
#define MSG_RELOAD_FIELD 162 // Debug.ReloadFieldEnd() or query_field_info()
#define MSG_AI_NAME 163 // Debug.AIName()
#define MSG_SHOW_HINT 164 // Debug.ShowHint()
#define MSG_PLAYER_HINT 165
#define MSG_MATCH_KILL 170
#define MSG_CUSTOM_MSG 180
......@@ -388,12 +409,13 @@ struct card_sort {
//Options
#define DUEL_TEST_MODE 0x01
#define DUEL_ATTACK_FIRST_TURN 0x02
#define DUEL_OLD_REPLAY 0x04
//#define DUEL_OLD_REPLAY 0x04
#define DUEL_OBSOLETE_RULING 0x08
#define DUEL_PSEUDO_SHUFFLE 0x10
#define DUEL_TAG_MODE 0x20
#define DUEL_SIMPLE_AI 0x40
#define DUEL_RETURN_DECK_TOP 0x80
#define DUEL_REVEAL_DECK_SEQ 0x100
//Activity
#define ACTIVITY_SUMMON 1
......
......@@ -5,6 +5,7 @@
* Author: Argon
*/
#include <cstring>
#include "duel.h"
#include "interpreter.h"
#include "field.h"
......@@ -12,12 +13,16 @@
#include "effect.h"
#include "group.h"
#include "ocgapi.h"
#include "buffer.h"
duel::duel() {
lua = new interpreter(this);
game_field = new field(this);
game_field->temp_card = new_card(0);
clear_buffer();
game_field->temp_card = new_card(TEMP_CARD_ID);
message_buffer.reserve(SIZE_MESSAGE_BUFFER);
#ifdef _WIN32
_set_error_mode(_OUT_TO_MSGBOX);
#endif // _WIN32
}
duel::~duel() {
for(auto& pcard : cards)
......@@ -40,16 +45,17 @@ void duel::clear() {
cards.clear();
groups.clear();
effects.clear();
assumes.clear();
sgroups.clear();
uncopy.clear();
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);
cards.insert(pcard);
if(code)
if (code != TEMP_CARD_ID)
::read_card(code, &(pcard->data));
else
pcard->data.clear();
pcard->data.code = code;
lua->register_card(pcard);
return pcard;
......@@ -94,13 +100,15 @@ void duel::delete_effect(effect* peffect) {
effects.erase(peffect);
delete peffect;
}
int32 duel::read_buffer(byte* buf) {
std::memcpy(buf, buffer, bufferlen);
return bufferlen;
int32_t duel::read_buffer(byte* buf) {
auto size = buffer_size();
if (size)
std::memcpy(buf, message_buffer.data(), size);
return (int32_t)size;
}
void duel::release_script_group() {
for(auto& pgroup : sgroups) {
if(pgroup->is_readonly == 0) {
if(pgroup->is_readonly == GTYPE_DEFAULT) {
lua->unregister_group(pgroup);
groups.erase(pgroup);
delete pgroup;
......@@ -113,36 +121,29 @@ void duel::restore_assumes() {
pcard->assume_type = 0;
assumes.clear();
}
void duel::write_buffer32(uint32 value) {
std::memcpy(bufferp, &value, sizeof(value));
bufferp += 4;
bufferlen += 4;
void duel::write_buffer(const void* data, int size) {
vector_write_block(message_buffer, data, size);
}
void duel::write_buffer32(uint32_t value) {
vector_write<uint32_t>(message_buffer, value);
}
void duel::write_buffer16(uint16 value) {
std::memcpy(bufferp, &value, sizeof(value));
bufferp += 2;
bufferlen += 2;
void duel::write_buffer16(uint16_t value) {
vector_write<uint16_t>(message_buffer, value);
}
void duel::write_buffer8(uint8 value) {
std::memcpy(bufferp, &value, sizeof(value));
bufferp += 1;
bufferlen += 1;
void duel::write_buffer8(uint8_t value) {
vector_write<unsigned char>(message_buffer, value);
}
void duel::clear_buffer() {
bufferlen = 0;
bufferp = buffer;
message_buffer.clear();
}
void duel::set_responsei(uint32 resp) {
void duel::set_responsei(uint32_t resp) {
game_field->returns.ivalue[0] = 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) {
if (game_field->core.duel_options & DUEL_OLD_REPLAY) {
return random.get_random_integer_old(l, h);
}
else {
return random.get_random_integer(l, h);
}
int32_t duel::get_next_integer(int32_t l, int32_t h) {
if (rng_version == 1)
return random.get_random_integer_v1(l, h);
return random.get_random_integer_v2(l, h);
}
......@@ -9,9 +9,11 @@
#define DUEL_H_
#include "common.h"
#include "sort.h"
#include "mtrandom.h"
#include <set>
#include <unordered_set>
#include <vector>
class card;
class group;
......@@ -19,16 +21,17 @@ class effect;
class field;
class interpreter;
using card_set = std::set<card*, card_sort>;
class duel {
public:
using card_set = std::set<card*, card_sort>;
char strbuffer[256];
byte buffer[0x1000];
uint32 bufferlen;
byte* bufferp;
char strbuffer[256]{};
int32_t rng_version{ 2 };
interpreter* lua;
field* game_field;
mt19937 random;
mtrandom random;
std::vector<byte> message_buffer;
std::unordered_set<card*> cards;
std::unordered_set<card*> assumes;
std::unordered_set<group*> groups;
......@@ -40,7 +43,10 @@ public:
~duel();
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(card* pcard);
group* new_group(const card_set& cset);
......@@ -50,14 +56,15 @@ public:
void delete_effect(effect* peffect);
void release_script_group();
void restore_assumes();
int32 read_buffer(byte* buf);
void write_buffer32(uint32 value);
void write_buffer16(uint16 value);
void write_buffer8(uint8 value);
int32_t read_buffer(byte* buf);
void write_buffer(const void* data, int size);
void write_buffer32(uint32_t value);
void write_buffer16(uint16_t value);
void write_buffer8(uint8_t value);
void clear_buffer();
void set_responsei(uint32 resp);
void set_responsei(uint32_t 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:
group* register_group(group* pgroup);
};
......
......@@ -12,80 +12,47 @@
#include "interpreter.h"
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: 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)
return false;
else if (code & 0xf0000)
else if (code & 0xf0000) // EVENT_ADD_COUNTER, EVENT_REMOVE_COUNTER
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);
else
return continuous_event.find(code) != continuous_event.end();
}
effect::effect(duel* pd) {
ref_handle = 0;
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;
effect::effect(duel* pd)
: pduel(pd) {
label.reserve(4);
label_object = 0;
hint_timing[0] = 0;
hint_timing[1] = 0;
status = 0;
condition = 0;
cost = 0;
target = 0;
value = 0;
operation = 0;
cost_checked = FALSE;
}
int32 effect::is_disable_related() {
}
int32_t effect::is_disable_related() const {
if (code == EFFECT_IMMUNE_EFFECT || code == EFFECT_DISABLE || code == EFFECT_CANNOT_DISABLE || code == EFFECT_FORBIDDEN)
return TRUE;
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)
return TRUE;
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))
return FALSE;
if (code == EFFECT_CHANGE_CODE)
return FALSE;
return TRUE;
}
// 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 fucntions: condition
int32 effect::is_available(int32 neglect_disabled) {
int32_t effect::is_available(int32_t neglect_disabled) {
if (type & EFFECT_TYPE_ACTIONS)
return FALSE;
if ((type & (EFFECT_TYPE_SINGLE | EFFECT_TYPE_XMATERIAL)) && !(type & EFFECT_TYPE_FIELD)) {
......@@ -136,7 +103,9 @@ int32 effect::is_available(int32 neglect_disabled) {
return FALSE;
if(!phandler->get_status(STATUS_EFFECT_ENABLED) && !is_flag(EFFECT_FLAG_IMMEDIATELY_APPLY))
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;
if(is_flag(EFFECT_FLAG_OWNER_RELATE) && is_can_be_forbidden() && powner->is_status(STATUS_FORBIDDEN))
return FALSE;
......@@ -153,7 +122,7 @@ int32 effect::is_available(int32 neglect_disabled) {
if (!condition)
return TRUE;
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(!(status & EFFECT_STATUS_AVAILABLE))
id = pduel->game_field->infos.field_id++;
......@@ -163,17 +132,16 @@ int32 effect::is_available(int32 neglect_disabled) {
return res;
}
// 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);
}
// check if a effect is EFFECT_TYPE_SINGLE and is ready
// check: range, enabled, condition
int32 effect::is_single_ready() {
int32_t effect::is_single_ready() {
if(type & EFFECT_TYPE_ACTIONS)
return FALSE;
if((type & (EFFECT_TYPE_SINGLE | EFFECT_TYPE_XMATERIAL)) && !(type & EFFECT_TYPE_FIELD)) {
card* phandler = get_handler();
card* powner = get_owner();
if(phandler->current.controler == PLAYER_NONE)
return FALSE;
if(is_flag(EFFECT_FLAG_SINGLE_RANGE) && !in_range(phandler))
......@@ -188,21 +156,19 @@ int32 effect::is_single_ready() {
if(!condition)
return TRUE;
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;
}
// reset_count: count of effect reset
// count_limit: left count of activation
// count_limit_max: max count of activation
int32 effect::check_count_limit(uint8 playerid) {
int32_t effect::check_count_limit(uint8_t playerid) {
if(is_flag(EFFECT_FLAG_COUNT_LIMIT)) {
if(count_limit == 0)
return FALSE;
if(count_code) {
uint32 code = count_code & 0xfffffff;
uint32 count = count_limit_max;
if(code == 1) {
if(pduel->game_field->get_effect_code((count_code & 0xf0000000) | get_handler()->fieldid, PLAYER_NONE) >= count)
uint32_t limit_code = count_code & MAX_CARD_ID;
uint32_t limit_type = count_code & 0xf0000000U;
int32_t count = count_limit_max;
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;
} else {
if(pduel->game_field->get_effect_code(count_code, playerid) >= count)
......@@ -212,9 +178,69 @@ int32 effect::check_count_limit(uint8 playerid) {
}
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
// 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))
return FALSE;
if(!check_count_limit(playerid))
......@@ -233,7 +259,7 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
&& !pduel->game_field->get_cteffect(this, playerid, FALSE))
return FALSE;
}
uint32 zone = 0xff;
uint32_t zone = 0xff;
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(e.event_cards , PARAM_TYPE_GROUP);
......@@ -265,44 +291,16 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
return FALSE;
}
// 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;
handler->filter_effect(ecode, &eset);
for(int32 i = 0; i < eset.size(); ++i) {
if(eset[i]->check_count_limit(playerid)) {
available = true;
break;
}
}
if(!available)
if(!get_required_handorset_effects(&eset, playerid, e, neglect_loc))
return FALSE;
}
if(handler->is_status(STATUS_FORBIDDEN))
return FALSE;
if(handler->is_affected_by_effect(EFFECT_CANNOT_TRIGGER))
return FALSE;
} else if(!(type & EFFECT_TYPE_CONTINUOUS)) {
card* phandler = get_handler();
if(!(phandler->get_type() & TYPE_MONSTER) && (get_active_type() & TYPE_MONSTER))
return FALSE;
if((phandler->get_type() & TYPE_CONTINUOUS) && (phandler->get_type() & TYPE_EQUIP))
if(!(phandler->get_type() & TYPE_MONSTER) && (get_active_type(FALSE) & TYPE_MONSTER))
return FALSE;
if((type & EFFECT_TYPE_QUICK_O) && is_flag(EFFECT_FLAG_DELAY) && !in_range(phandler))
return FALSE;
......@@ -321,12 +319,14 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
if(phandler->current.location == LOCATION_OVERLAY)
return FALSE;
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)
return FALSE;
if((type & EFFECT_TYPE_FIELD) && !(range & (LOCATION_DECK | LOCATION_EXTRA)))
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))
return FALSE;
if(phandler->is_status(STATUS_FORBIDDEN))
......@@ -337,7 +337,8 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
card* phandler = get_handler();
if((type & EFFECT_TYPE_FIELD) && phandler->is_status(STATUS_BATTLE_DESTROYED))
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)))
return FALSE;
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
}
pduel->game_field->save_lp_cost();
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_player = playerid;
int32 result = TRUE;
int32_t result = TRUE;
if(!(type & EFFECT_TYPE_CONTINUOUS))
result = is_action_check(playerid);
if(result)
......@@ -371,10 +372,10 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
return result;
}
// 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;
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(playerid, PARAM_TYPE_INT);
if(eset[i]->check_value_condition(2))
......@@ -382,7 +383,7 @@ int32 effect::is_action_check(uint8 playerid) {
}
eset.clear();
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(this, PARAM_TYPE_EFFECT);
pduel->lua->add_param(playerid, PARAM_TYPE_INT);
......@@ -397,7 +398,7 @@ int32 effect::is_action_check(uint8 playerid) {
return TRUE;
}
// 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) {
pduel->lua->add_param(reason_effect, PARAM_TYPE_EFFECT);
pduel->lua->add_param(playerid, PARAM_TYPE_INT);
......@@ -449,18 +450,18 @@ int32 effect::is_activate_ready(effect* reason_effect, uint8 playerid, const tev
reason_effect->cost_checked = FALSE;
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);
}
// 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();
if(!(type & EFFECT_TYPE_ACTIVATE) && (phandler->current.location & (LOCATION_ONFIELD | LOCATION_REMOVED)) && !phandler->is_position(POS_FACEUP))
return FALSE;
if(!condition)
return TRUE;
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_player = playerid;
pduel->game_field->save_lp_cost();
......@@ -483,19 +484,19 @@ int32 effect::is_condition_check(uint8 playerid, const tevent& e) {
pduel->game_field->core.reason_player = op;
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();
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_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_player = op;
pduel->game_field->restore_lp_cost();
return result;
}
int32 effect::is_target(card* pcard) {
int32_t effect::is_target(card* pcard) {
if(type & EFFECT_TYPE_ACTIONS)
return FALSE;
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) {
&& !pcard->is_position(POS_FACEUP))
return FALSE;
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;
if(is_flag(EFFECT_FLAG_SPSUM_PARAM))
return FALSE;
......@@ -531,7 +532,7 @@ int32 effect::is_target(card* 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) {
pduel->lua->add_param(this, PARAM_TYPE_EFFECT);
pduel->lua->add_param(pcard, PARAM_TYPE_CARD);
......@@ -541,10 +542,10 @@ int32 effect::is_fit_target_function(card* pcard) {
}
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))
return FALSE;
uint8 self = get_handler_player();
uint8_t self = get_handler_player();
if(is_flag(EFFECT_FLAG_ABSOLUTE_TARGET)) {
if(s_range && playerid == 0)
return TRUE;
......@@ -558,7 +559,7 @@ int32 effect::is_target_player(uint8 playerid) {
}
return FALSE;
}
int32 effect::is_player_effect_target(card* pcard) {
int32_t effect::is_player_effect_target(card* pcard) {
if(target) {
handler->pduel->lua->add_param(this, PARAM_TYPE_EFFECT);
handler->pduel->lua->add_param(pcard, PARAM_TYPE_CARD);
......@@ -568,9 +569,9 @@ int32 effect::is_player_effect_target(card* pcard) {
}
return TRUE;
}
int32 effect::is_immuned(card* pcard) {
int32_t effect::is_immuned(card* pcard) {
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];
if(peffect->is_available() && peffect->value) {
pduel->lua->add_param(this, PARAM_TYPE_EFFECT);
......@@ -581,10 +582,10 @@ int32 effect::is_immuned(card* pcard) {
}
return FALSE;
}
int32 effect::is_chainable(uint8 tp) {
int32_t effect::is_chainable(uint8_t tp) {
if(!(type & EFFECT_TYPE_ACTIONS))
return FALSE;
int32 sp = get_speed();
int32_t sp = get_speed();
// Curse of Field is the exception
if((type & EFFECT_TYPE_ACTIVATE) && (sp <= 1) && !is_flag(EFFECT_FLAG2_COF))
return FALSE;
......@@ -612,12 +613,20 @@ int32 effect::is_chainable(uint8 tp) {
}
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;
}
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
//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) {
case RESET_EVENT: {
if(!(reset_flag & RESET_EVENT))
......@@ -636,11 +645,11 @@ int32 effect::reset(uint32 reset_level, uint32 reset_type) {
case RESET_PHASE: {
if(!(reset_flag & RESET_PHASE))
return FALSE;
uint8 pid = get_owner_player();
uint8 tp = handler->pduel->game_field->infos.turn_player;
uint8_t pid = get_owner_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))
&& (reset_level & 0x3ff & reset_flag))
reset_count--;
--reset_count;
if(reset_count == 0)
return TRUE;
return FALSE;
......@@ -657,7 +666,7 @@ int32 effect::reset(uint32 reset_level, uint32 reset_type) {
}
return FALSE;
}
void effect::dec_count(uint32 playerid) {
void effect::dec_count(uint8_t playerid) {
if(!is_flag(EFFECT_FLAG_COUNT_LIMIT))
return;
if(count_limit == 0)
......@@ -665,9 +674,10 @@ void effect::dec_count(uint32 playerid) {
if(count_code == 0 || is_flag(EFFECT_FLAG_NO_TURN_RESET))
count_limit -= 1;
if(count_code) {
uint32 code = count_code & 0xfffffff;
if(code == 1)
pduel->game_field->add_effect_code((count_code & 0xf0000000) | get_handler()->fieldid, PLAYER_NONE);
uint32_t limit_code = count_code & MAX_CARD_ID;
uint32_t limit_type = count_code & 0xf0000000;
if(limit_code == EFFECT_COUNT_CODE_SINGLE)
pduel->game_field->add_effect_code(limit_type | get_handler()->activate_count_id, PLAYER_NONE);
else
pduel->game_field->add_effect_code(count_code, playerid);
}
......@@ -677,81 +687,84 @@ void effect::recharge() {
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)) {
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;
} else {
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)) {
pduel->lua->add_param(pcard, PARAM_TYPE_CARD, 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;
} else {
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)) {
pduel->lua->add_param(peffect, 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;
} else {
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)) {
pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE);
pduel->lua->get_function_value(value, 1 + extraargs, result);
} else {
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)) {
pduel->lua->add_param(pcard, PARAM_TYPE_CARD, TRUE);
pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE);
pduel->lua->get_function_value(value, 2 + extraargs, result);
} else {
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)) {
pduel->lua->add_param(peffect, PARAM_TYPE_EFFECT, TRUE);
pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE);
pduel->lua->get_function_value(value, 2 + extraargs, result);
} else {
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)) {
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;
} else {
pduel->lua->params.clear();
return (int32)value;
return value;
}
}
void* effect::get_label_object() {
return pduel->lua->get_ref_object(label_object);
}
int32 effect::get_speed() {
int32_t effect::get_speed() {
if(!(type & EFFECT_TYPE_ACTIONS))
return 0;
if(type & (EFFECT_TYPE_TRIGGER_O | EFFECT_TYPE_TRIGGER_F | EFFECT_TYPE_IGNITION))
......@@ -775,7 +788,7 @@ int32 effect::get_speed() {
}
effect* effect::clone() {
effect* ceffect = pduel->new_effect();
int32 ref = ceffect->ref_handle;
int32_t ref = ceffect->ref_handle;
*ceffect = *this;
ceffect->ref_handle = ref;
ceffect->handler = 0;
......@@ -798,7 +811,7 @@ card* effect::get_owner() const {
return handler->overlay_target;
return owner;
}
uint8 effect::get_owner_player() {
uint8_t effect::get_owner_player() const {
if(effect_owner != PLAYER_NONE)
return effect_owner;
return get_owner()->current.controler;
......@@ -810,17 +823,17 @@ card* effect::get_handler() const {
return handler->overlay_target;
return handler;
}
uint8 effect::get_handler_player() {
uint8_t effect::get_handler_player() const {
if(is_flag(EFFECT_FLAG_FIELD_ONLY))
return effect_owner;
return get_handler()->current.controler;
}
int32 effect::in_range(card* pcard) {
int32_t effect::in_range(card* pcard) const {
if(type & EFFECT_TYPE_XMATERIAL)
return handler->overlay_target ? TRUE : FALSE;
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)
return handler->overlay_target ? TRUE : FALSE;
return range & ch.triggering_location;
......@@ -836,9 +849,9 @@ void effect::set_active_type() {
if(active_type & TYPE_TRAPMONSTER)
active_type &= ~TYPE_TRAP;
}
uint32 effect::get_active_type() {
if(type & 0x7f0) {
if(active_type)
uint32_t effect::get_active_type(uint8_t uselast) {
if(type & EFFECT_TYPES_CHAIN_LINK) {
if(active_type && uselast)
return active_type;
else if((type & EFFECT_TYPE_ACTIVATE) && (get_handler()->data.type & TYPE_PENDULUM))
return TYPE_PENDULUM + TYPE_SPELL;
......@@ -847,9 +860,9 @@ uint32 effect::get_active_type() {
} else
return owner->get_type();
}
int32 effect::get_code_type() {
code_type effect::get_code_type() const {
// start from the highest bit
if (code & EVENT_CUSTOM)
if (code & 0xf0000000)
return CODE_CUSTOM;
else if (code & 0xf0000)
return CODE_COUNTER;
......
......@@ -11,110 +11,116 @@
#include "common.h"
#include "field.h"
#include "effectset.h"
#include <stdlib.h>
#include <vector>
#include <map>
class card;
class duel;
class group;
class effect;
struct tevent;
struct effect_set;
struct effect_set_v;
enum effect_flag : uint32;
enum effect_flag2 : uint32;
enum effect_flag : uint64_t;
enum effect_flag2 : uint64_t;
enum effect_category :uint64_t;
enum code_type : int32_t;
bool is_continuous_event(uint32_t code);
class effect {
public:
int32 ref_handle;
duel* pduel;
card* owner;
card* handler;
uint8 effect_owner;
uint32 description;
uint32 code;
uint32 flag[2];
uint32 id;
uint16 type;
uint16 copy_id;
uint16 range;
uint16 s_range;
uint16 o_range;
uint8 count_limit;
uint8 count_limit_max;
uint16 reset_count;
uint32 reset_flag;
uint32 count_code;
uint32 category;
uint32 hint_timing[2];
uint32 card_type;
uint32 active_type;
uint16 active_location;
uint16 active_sequence;
card* active_handler;
uint16 status;
std::vector<uint32> label;
int32 label_object;
int32 condition;
int32 cost;
int32 target;
int32 value;
int32 operation;
uint8 cost_checked;
int32_t ref_handle{ 0 };
duel* pduel{ nullptr };
card* owner{ nullptr };
card* handler{ nullptr };
uint8_t effect_owner{ PLAYER_NONE };
uint32_t description{ 0 };
uint32_t code{ 0 };
uint32_t id{ 0 };
uint32_t type{ 0 };
uint16_t copy_id{ 0 };
uint16_t range{ 0 };
uint16_t s_range{ 0 };
uint16_t o_range{ 0 };
uint8_t count_limit{ 0 }; //left count of activation
uint8_t count_limit_max{ 0 }; //max count of activation
uint16_t status{ 0 };
int32_t reset_count{ 0 };
uint32_t reset_flag{ 0 };
uint32_t count_code{ 0 };
uint64_t category{ 0 };
uint64_t flag[2]{};
uint32_t hint_timing[2]{};
uint32_t card_type{ 0 };
uint32_t active_type{ 0 };
uint16_t active_location{ 0 };
uint16_t active_sequence{ 0 };
card* active_handler{ nullptr };
std::vector<lua_Integer> label;
int32_t label_object{ 0 };
int32_t condition{ 0 };
int32_t cost{ 0 };
int32_t target{ 0 };
int32_t value{ 0 };
int32_t operation{ 0 };
uint8_t cost_checked{ FALSE };
effect_set required_handorset_effects;
LuaParamType object_type{ PARAM_TYPE_INT };
explicit effect(duel* pd);
~effect() = default;
int32 is_disable_related();
int32 is_self_destroy_related();
int32 is_can_be_forbidden();
int32 is_available(int32 neglect_disabled = FALSE);
int32 limit_counter_is_available();
int32 is_single_ready();
int32 check_count_limit(uint8 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 is_action_check(uint8 playerid);
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 is_activate_ready(uint8 playerid, const tevent& e, int32 neglect_cond = FALSE, int32 neglect_cost = FALSE, int32 neglect_target = FALSE);
int32 is_condition_check(uint8 playerid, const tevent& e);
int32 is_activate_check(uint8 playerid, const tevent& e, int32 neglect_cond = FALSE, int32 neglect_cost = FALSE, int32 neglect_target = FALSE);
int32 is_target(card* pcard);
int32 is_fit_target_function(card* pcard);
int32 is_target_player(uint8 playerid);
int32 is_player_effect_target(card* pcard);
int32 is_immuned(card* pcard);
int32 is_chainable(uint8 tp);
int32 is_hand_trigger();
int32 reset(uint32 reset_level, uint32 reset_type);
void dec_count(uint32 playerid = 2);
int32_t is_disable_related() const;
int32_t is_self_destroy_related() const;
int32_t is_can_be_forbidden() const;
int32_t is_available(int32_t neglect_disabled = FALSE);
int32_t limit_counter_is_available();
int32_t is_single_ready();
int32_t check_count_limit(uint8_t playerid);
int32_t get_required_handorset_effects(effect_set* eset, uint8_t playerid, const tevent& e, int32_t neglect_loc = FALSE);
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_t is_action_check(uint8_t playerid);
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_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_t is_condition_check(uint8_t playerid, const tevent& e);
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_t is_target(card* pcard);
int32_t is_fit_target_function(card* pcard);
int32_t is_target_player(uint8_t playerid);
int32_t is_player_effect_target(card* pcard);
int32_t is_immuned(card* pcard);
int32_t is_chainable(uint8_t tp);
int32_t is_hand_trigger() const;
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();
int32 get_value(uint32 extraargs = 0);
int32 get_value(card* pcard, uint32 extraargs = 0);
int32 get_value(effect* peffect, uint32 extraargs = 0);
void get_value(uint32 extraargs, std::vector<int32>* result);
void get_value(card* pcard, uint32 extraargs, std::vector<int32>* result);
void get_value(effect* peffect, uint32 extraargs, std::vector<int32>* result);
int32 check_value_condition(uint32 extraargs = 0);
int32_t get_value(uint32_t extraargs = 0);
int32_t get_value(card* pcard, uint32_t extraargs = 0);
int32_t get_value(effect* peffect, uint32_t extraargs = 0);
void get_value(uint32_t extraargs, std::vector<lua_Integer>& result);
void get_value(card* pcard, uint32_t extraargs, std::vector<lua_Integer>& result);
void get_value(effect* peffect, uint32_t extraargs, std::vector<lua_Integer>& result);
int32_t get_integer_value();
int32_t check_value_condition(uint32_t extraargs = 0);
void* get_label_object();
int32 get_speed();
int32_t get_speed();
effect* clone();
card* get_owner() const;
uint8 get_owner_player();
uint8_t get_owner_player() const;
card* get_handler() const;
uint8 get_handler_player();
int32 in_range(card* pcard);
int32 in_range(const chain& ch);
uint8_t get_handler_player() const;
int32_t in_range(card* pcard) const;
int32_t in_range(const chain& ch) const;
void set_activate_location();
void set_active_type();
uint32 get_active_type();
int32 get_code_type();
uint32_t get_active_type(uint8_t uselast = TRUE);
code_type get_code_type() const;
bool is_flag(effect_flag flag) const {
return !!(this->flag[0] & flag);
bool is_flag(effect_flag x) const {
return !!(flag[0] & x);
}
bool is_flag(effect_flag2 flag) const {
return !!(this->flag[1] & flag);
bool is_flag(effect_flag2 x) const {
return !!(flag[1] & x);
}
};
......@@ -123,8 +129,10 @@ public:
//#define EFFECT_STATUS_ACTIVATED 0x0002
#define EFFECT_STATUS_SPSELF 0x0004
#define EFFECT_COUNT_CODE_OATH 0x10000000
#define EFFECT_COUNT_CODE_DUEL 0x20000000
#define EFFECT_COUNT_CODE_OATH 0x10000000U
#define EFFECT_COUNT_CODE_DUEL 0x20000000U
#define EFFECT_COUNT_CODE_CHAIN 0x40000000U
#define EFFECT_COUNT_CODE_SINGLE 0x1U
//========== Reset ==========
#define RESET_SELF_TURN 0x10000000
......@@ -149,6 +157,8 @@ public:
#define RESET_OVERLAY 0x04000000
#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 ==========
#define EFFECT_TYPE_SINGLE 0x0001 //
#define EFFECT_TYPE_FIELD 0x0002 //
......@@ -166,10 +176,11 @@ public:
#define EFFECT_TYPE_GRANT 0x2000 //
#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 ==========
enum effect_flag : uint32 {
enum effect_flag : uint64_t {
EFFECT_FLAG_INITIAL = 0x0001,
EFFECT_FLAG_FUNC_VALUE = 0x0002,
EFFECT_FLAG_COUNT_LIMIT = 0x0004,
......@@ -183,7 +194,7 @@ enum effect_flag : uint32 {
EFFECT_FLAG_CANNOT_DISABLE = 0x0400,
EFFECT_FLAG_PLAYER_TARGET = 0x0800,
EFFECT_FLAG_BOTH_SIDE = 0x1000,
EFFECT_FLAG_COPY_INHERIT = 0x2000,
EFFECT_FLAG_COPY = 0x2000,
EFFECT_FLAG_DAMAGE_STEP = 0x4000,
EFFECT_FLAG_DAMAGE_CAL = 0x8000,
EFFECT_FLAG_DELAY = 0x10000,
......@@ -199,20 +210,66 @@ enum effect_flag : uint32 {
EFFECT_FLAG_CLIENT_HINT = 0x4000000,
EFFECT_FLAG_CONTINUOUS_TARGET = 0x8000000,
EFFECT_FLAG_LIMIT_ZONE = 0x10000000,
// EFFECT_FLAG_COF = 0x20000000,
EFFECT_FLAG_ACTIVATE_CONDITION = 0x20000000,
// EFFECT_FLAG_CVAL_CHECK = 0x40000000,
EFFECT_FLAG_IMMEDIATELY_APPLY = 0x80000000,
EFFECT_FLAG_COIN = 0x100000000,
EFFECT_FLAG_DICE = 0x200000000,
EFFECT_FLAG_FUSION_SUMMON = 0x400000000,
};
enum effect_flag2 : uint32 {
// EFFECT_FLAG2_MILLENNIUM_RESTRICT = 0x0001,
enum effect_flag2 : uint64_t {
EFFECT_FLAG2_REPEAT_UPDATE = 0x0001,
EFFECT_FLAG2_COF = 0x0002,
EFFECT_FLAG2_WICKED = 0x0004,
EFFECT_FLAG2_OPTION = 0x0008,
};
inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
{
return static_cast<effect_flag>(static_cast<uint32>(flag1) | static_cast<uint32>(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));
}
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 ==========
#define EFFECT_IMMUNE_EFFECT 1 //
#define EFFECT_DISABLE 2 //
......@@ -383,7 +440,7 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
#define EFFECT_TOSS_DICE_REPLACE 221
#define EFFECT_FUSION_MATERIAL 230
#define EFFECT_CHAIN_MATERIAL 231
#define EFFECT_SYNCHRO_MATERIAL 232
#define EFFECT_EXTRA_SYNCHRO_MATERIAL 232
#define EFFECT_XYZ_MATERIAL 233
#define EFFECT_FUSION_SUBSTITUTE 234
#define EFFECT_CANNOT_BE_FUSION_MATERIAL 235
......@@ -467,6 +524,12 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
#define EFFECT_CHANGE_GRAVE_RACE 366
#define EFFECT_ACTIVATION_COUNT_LIMIT 367
#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_FLIP 1001
......@@ -493,6 +556,7 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
#define EVENT_DESTROYED 1029
#define EVENT_MOVE 1030
#define EVENT_LEAVE_GRAVE 1031
#define EVENT_LEAVE_DECK 1032
#define EVENT_ADJUST 1040
#define EVENT_BREAK_EFFECT 1050
#define EVENT_SUMMON_SUCCESS 1100
......@@ -512,6 +576,7 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
#define EVENT_SUMMON_NEGATED 1114
#define EVENT_FLIP_SUMMON_NEGATED 1115
#define EVENT_SPSUMMON_NEGATED 1116
#define EVENT_SPSUMMON_SUCCESS_G_P 1117
#define EVENT_CONTROL_CHANGED 1120
#define EVENT_EQUIP 1121
#define EVENT_ATTACK_ANNOUNCE 1130
......@@ -542,16 +607,36 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
#define EVENT_REMOVE_COUNTER 0x20000
#define EVENT_CUSTOM 0x10000000
#define DOUBLE_DAMAGE 0x80000000
#define HALF_DAMAGE 0x80000001
constexpr int32_t DOUBLE_DAMAGE = INT32_MIN;
constexpr int32_t HALF_DAMAGE = INT32_MIN + 1;
// The type of event in code
#define CODE_CUSTOM 1 // header + id (28 bits)
#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
constexpr uint32_t MAX_PARAMETER = 0xffffU;
constexpr uint32_t MAX_XYZ_LEVEL = 0x0fffU;
const std::unordered_set<uint32> continuous_event({ EVENT_ADJUST, EVENT_BREAK_EFFECT, EVENT_TURN_END });
bool is_continuous_event(uint32 code);
// flag effect
#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_ */
......@@ -8,8 +8,6 @@
#ifndef EFFECTSET_H_
#define EFFECTSET_H_
#include <stdlib.h>
#include <array>
#include <vector>
#include <algorithm>
......@@ -17,100 +15,7 @@ class effect;
bool effect_sort_id(const effect* e1, const effect* e2);
struct effect_set {
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;
};
using effect_set = std::vector<effect*>;
using effect_set_v = effect_set;
#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 @@
#include "common.h"
#include "card.h"
#include "effectset.h"
#include "interpreter.h"
#include <vector>
#include <set>
#include <map>
#include <list>
#include <array>
#include <functional>
#include <unordered_map>
#include <unordered_set>
#define MAX_COIN_COUNT 20
//summon action type
#define SUMMON_IN_IDLE 0
#define SUMMON_IN_CHAIN 1
class card;
struct card_data;
class duel;
class group;
class effect;
using effect_vector = std::vector<effect*>;
struct tevent {
card* trigger_card;
group* event_cards;
effect* reason_effect;
uint32 event_code;
uint32 event_value;
uint32 reason;
uint8 event_player;
uint8 reason_player;
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) {}
card* trigger_card{ nullptr };
group* event_cards{ nullptr };
effect* reason_effect{ nullptr };
uint32_t event_code{ 0 };
uint32_t event_value{ 0 };
uint32_t reason{ 0 };
uint8_t event_player{ PLAYER_NONE };
uint8_t reason_player{ PLAYER_NONE };
bool operator< (const tevent& v) const;
};
struct optarget {
group* op_cards;
uint8 op_count;
uint8 op_player;
int32 op_param;
optarget()
: op_cards(nullptr), op_count(0), op_player(PLAYER_NONE), op_param(0) {}
group* op_cards{ nullptr };
uint8_t op_count{ 0 };
uint8_t op_player{ PLAYER_NONE };
int32_t op_param{ 0 };
};
struct chain {
using opmap = std::unordered_map<uint32, optarget>;
uint16 chain_id;
uint8 chain_count;
uint8 triggering_player;
uint8 triggering_controler;
uint16 triggering_location;
uint8 triggering_sequence;
uint8 triggering_position;
using opmap = std::unordered_map<uint32_t, optarget>;
uint16_t chain_id{ 0 };
uint8_t chain_count{ 0 };
uint8_t triggering_player{ PLAYER_NONE };
uint8_t triggering_controler{ PLAYER_NONE };
uint16_t triggering_location{ 0 };
uint8_t triggering_sequence{ 0 };
uint8_t triggering_position{ 0 };
card_state triggering_state;
effect* triggering_effect;
group* target_cards;
int32 replace_op;
uint8 target_player;
int32 target_param;
effect* disable_reason;
uint8 disable_player;
effect* triggering_effect{ nullptr };
group* target_cards{ nullptr };
int32_t replace_op{ 0 };
uint8_t target_player{ PLAYER_NONE };
int32_t target_param{ 0 };
effect* disable_reason{ nullptr };
uint8_t disable_player{ PLAYER_NONE };
tevent evt;
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);
void set_triggering_state(card* pcard);
};
struct player_info {
using card_vector = std::vector<card*>;
int32 lp;
int32 start_count;
int32 draw_count;
uint32 used_location;
uint32 disabled_location;
uint32 extra_p_count;
uint32 tag_extra_p_count;
int32_t lp{ 8000 };
int32_t start_count{ 5 };
int32_t draw_count{ 1 };
uint32_t used_location{ 0 };
uint32_t disabled_location{ 0 };
uint32_t extra_p_count{ 0 };
uint32_t tag_extra_p_count{ 0 };
int32_t szone_size{ 6 };
card_vector list_mzone;
card_vector list_szone;
card_vector list_main;
......@@ -97,15 +96,9 @@ struct player_info {
card_vector tag_list_main;
card_vector tag_list_hand;
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 {
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 effect_collection = std::unordered_set<effect*>;
using gain_effects = std::unordered_map<card*, effect*>;
using grant_effect_container = std::unordered_map<effect*, gain_effects>;
......@@ -130,70 +123,70 @@ struct field_effect {
grant_effect_container grant_effect;
};
struct field_info {
int32 field_id;
int16 copy_id;
int16 turn_id;
int16 turn_id_by_player[2];
int16 card_id;
uint16 phase;
uint8 turn_player;
uint8 priorities[2];
uint8 can_shuffle;
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) {}
uint64_t card_id{ 1 };
int32_t field_id{ 1 };
uint16_t copy_id{ 1 };
uint16_t turn_id{};
uint16_t turn_id_by_player[2]{};
uint16_t phase{};
uint8_t turn_player{};
uint8_t priorities[2]{};
uint8_t can_shuffle{ TRUE };
};
struct lpcost {
int32 count;
int32 amount;
int32 lpstack[8];
lpcost()
: count(0), amount(0), lpstack{ 0 } {}
int32_t count{};
int32_t amount{};
int32_t lpstack[8]{};
};
struct processor_unit {
uint16 type;
uint16 step;
effect* peffect;
group* ptarget;
int32 arg1;
int32 arg2;
int32 arg3;
int32 arg4;
void* ptr1;
void* ptr2;
processor_unit()
: type(0), step(0), peffect(nullptr), ptarget(nullptr), arg1(0), arg2(0), arg3(0), arg4(0), ptr1(nullptr), ptr2(nullptr) {}
uint16_t type{ 0 };
uint16_t step{ 0 };
effect* peffect{ nullptr };
group* ptarget{ nullptr };
uint32_t arg1{ 0 };
uint32_t arg2{ 0 };
uint32_t arg3{ 0 };
uint32_t arg4{ 0 };
int32_t value1{ 0 };
int32_t value2{ 0 };
int32_t value3{ 0 };
int32_t value4{ 0 };
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 {
int8 bvalue[64];
int16 svalue[32];
int32 ivalue[16];
int64 lvalue[8];
uint8_t bvalue[SIZE_RETURN_VALUE];
uint16_t svalue[SIZE_SVALUE];
int32_t ivalue[SIZE_IVALUE];
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 {
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 {
chain_limit_t(int32 f, int32 p): function(f), player(p) {}
int32 function;
int32 player;
chain_limit_t(int32_t f, int32_t p): function(f), player(p) {}
int32_t function{ 0 };
int32_t player{ PLAYER_NONE };
};
using chain_limit_list = std::vector<chain_limit_t>;
processor_list units;
processor_list subunits;
processor_unit reserved;
processor_unit damage_step_reserved;
processor_unit summon_reserved;
card_vector select_cards;
card_vector unselect_cards;
card_vector summonable_cards;
......@@ -252,6 +245,7 @@ struct processor {
card_set operated_set;
card_set discarded_set;
card_set destroy_canceled;
card_set indestructable_count_set;
card_set delayed_enable_set;
card_set set_group_pre_set;
card_set set_group_set;
......@@ -259,393 +253,394 @@ struct processor {
effect_set_v extra_mzone_effects;
effect_set_v extra_szone_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_map<uint32, uint32> effect_count_code;
std::unordered_map<uint32, uint32> effect_count_code_duel;
std::unordered_map<uint32, uint32> spsummon_once_map[2];
std::multimap<int32, card*, std::greater<int32>> xmaterial_lst;
int32 temp_var[4];
uint32 global_flag;
uint16 pre_field[2];
std::set<uint16> opp_mzone;
std::unordered_map<uint32_t, int32_t> effect_count_code[3];
std::unordered_map<uint32_t, int32_t> effect_count_code_duel[3];
std::unordered_map<uint32_t, int32_t> effect_count_code_chain[3];
std::unordered_map<uint32_t, uint32_t> spsummon_once_map[2];
std::multimap<int32_t, card*, std::greater<int32_t>> xmaterial_lst;
int32_t temp_var[4]{};
uint32_t global_flag{ 0 };
uint16_t pre_field[2]{};
std::set<uint16_t> opp_mzone;
chain_limit_list chain_limit;
chain_limit_list chain_limit_p;
uint8 chain_solving;
uint8 conti_solving;
uint8 win_player;
uint8 win_reason;
uint8 re_adjust;
effect* reason_effect;
uint8 reason_player;
card* summoning_card;
uint8 summon_depth;
uint8 summon_cancelable;
card* attacker;
card* attack_target;
uint32 limit_extra_summon_zone;
uint32 limit_extra_summon_releasable;
card* limit_tuner;
group* limit_syn;
int32 limit_syn_minc;
int32 limit_syn_maxc;
group* limit_xyz;
int32 limit_xyz_minc;
int32 limit_xyz_maxc;
group* limit_link;
card* limit_link_card;
int32 limit_link_minc;
int32 limit_link_maxc;
uint8 not_material;
uint8 attack_cancelable;
uint8 attack_rollback;
uint8 effect_damage_step;
int32 battle_damage[2];
int32 summon_count[2];
uint8 extra_summon[2];
int32 spe_effect[2];
int32 duel_options;
int32 duel_rule; //current rule: 5, Master Rule 2020
uint32 copy_reset;
uint8 copy_reset_count;
uint32 last_control_changed_id;
uint32 set_group_used_zones;
uint8 set_group_seq[7];
uint8 dice_result[5];
uint8 coin_result[5];
uint8 to_bp;
uint8 to_m2;
uint8 to_ep;
uint8 skip_m2;
uint8 chain_attack;
uint32 chain_attacker_id;
card* chain_attack_target;
uint8 attack_player;
uint8 selfdes_disabled;
uint8 overdraw[2];
int32 check_level;
uint8 shuffle_check_disabled;
uint8 shuffle_hand_check[2];
uint8 shuffle_deck_check[2];
uint8 deck_reversed;
uint8 remove_brainwashing;
uint8 flip_delayed;
uint8 damage_calculated;
uint8 hand_adjusted;
uint8 summon_state_count[2];
uint8 normalsummon_state_count[2];
uint8 flipsummon_state_count[2];
uint8 spsummon_state_count[2];
uint8 attack_state_count[2];
uint8 battle_phase_count[2];
uint8 battled_count[2];
uint8 phase_action;
uint32 hint_timing[2];
uint8 current_player;
uint8 conti_player;
std::unordered_map<uint32, std::pair<uint32, uint32>> summon_counter;
std::unordered_map<uint32, std::pair<uint32, uint32>> normalsummon_counter;
std::unordered_map<uint32, std::pair<uint32, uint32>> spsummon_counter;
std::unordered_map<uint32, std::pair<uint32, uint32>> flipsummon_counter;
std::unordered_map<uint32, std::pair<uint32, uint32>> attack_counter;
std::unordered_map<uint32, std::pair<uint32, uint32>> chain_counter;
uint8_t chain_solving{ FALSE };
uint8_t conti_solving{ FALSE };
uint8_t win_player{ 5 };
uint8_t win_reason{ 0 };
uint8_t re_adjust{ FALSE };
effect* reason_effect{ nullptr };
uint8_t reason_player{ PLAYER_NONE };
card* summoning_card{ nullptr };
uint8_t summon_depth{ 0 };
uint8_t summon_cancelable{ FALSE };
card* attacker{ nullptr };
card* attack_target{ nullptr };
uint8_t attacker_player{ PLAYER_NONE };
uint8_t attack_target_player{ PLAYER_NONE };
uint32_t limit_extra_summon_zone{ 0 };
uint32_t limit_extra_summon_releasable{ 0 };
card* limit_tuner{ nullptr };
group* limit_syn{ nullptr };
int32_t limit_syn_minc{ 0 };
int32_t limit_syn_maxc{ 0 };
group* limit_xyz{ nullptr };
int32_t limit_xyz_minc{ 0 };
int32_t limit_xyz_maxc{ 0 };
group* limit_link{ nullptr };
card* limit_link_card{ nullptr };
int32_t limit_link_minc{ 0 };
int32_t limit_link_maxc{ 0 };
uint8_t not_material{ FALSE };
uint8_t attack_cancelable{ FALSE };
uint8_t attack_rollback{ FALSE };
uint8_t effect_damage_step{ 0 };
int32_t battle_damage[2]{};
int32_t summon_count[2]{};
uint8_t extra_summon[2]{};
int32_t spe_effect[2]{};
int32_t last_select_hint[2]{ 0 };
uint32_t duel_options{ 0 };
int32_t duel_rule{ CURRENT_RULE };
uint32_t copy_reset{ 0 };
int32_t copy_reset_count{ 0 };
uint32_t last_control_changed_id{ 0 };
uint32_t set_group_used_zones{ 0 };
uint8_t set_group_seq[7]{};
uint8_t dice_result[5]{};
uint8_t coin_result[MAX_COIN_COUNT]{};
int32_t coin_count{ 0 };
bool is_target_ready{ false };
bool is_gemini_summoning{ false };
bool is_summon_negated{ false };
uint8_t to_bp{ FALSE };
uint8_t to_m2{ FALSE };
uint8_t to_ep{ FALSE };
uint8_t skip_m2{ FALSE };
uint8_t chain_attack{ FALSE };
uint32_t chain_attacker_id{ 0 };
card* chain_attack_target{ nullptr };
uint8_t attack_player{ PLAYER_NONE };
uint8_t selfdes_disabled{ FALSE };
uint8_t overdraw[2]{};
int32_t check_level{ 0 };
uint8_t shuffle_check_disabled{ FALSE };
uint8_t shuffle_hand_check[2]{};
uint8_t shuffle_deck_check[2]{};
uint8_t deck_reversed{ FALSE };
uint8_t remove_brainwashing{ FALSE };
uint8_t flip_delayed{ FALSE };
uint8_t damage_calculated{ FALSE };
uint8_t hand_adjusted{ FALSE };
uint8_t summon_state_count[2]{};
uint8_t normalsummon_state_count[2]{};
uint8_t flipsummon_state_count[2]{};
uint8_t spsummon_state_count[2]{};
uint8_t attack_state_count[2]{};
uint8_t battle_phase_count[2]{};
uint8_t battled_count[2]{};
uint8_t phase_action{ FALSE };
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;
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 {
public:
using effect_container = std::multimap<uint32, effect*>;
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;
duel* pduel{};
player_info player[2];
card* temp_card;
card* temp_card{};
field_info infos;
//lpcost cost[2];
field_effect effects;
processor core;
return_value returns;
return_value returns{};
tevent nil_event;
static int32 field_used_count[32];
explicit field(duel* pduel);
static int32_t field_used_count[32];
explicit field(duel* pd);
~field() = default;
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 move_card(uint8 playerid, card* pcard, uint8 location, uint8 sequence, uint8 pzone = FALSE);
void swap_card(card* pcard1, card* pcard2, uint8 new_sequence1, uint8 new_sequence2);
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_t new_sequence1, uint8_t new_sequence2);
void swap_card(card* pcard1, card* pcard2);
void set_control(card* pcard, uint8 playerid, uint16 reset_phase, uint8 reset_count);
card* get_field_card(uint32 playerid, uint32 location, uint32 sequence);
int32 is_location_useable(uint32 playerid, uint32 location, uint32 sequence);
int32 get_useable_count(card* pcard, uint8 playerid, uint8 location, uint8 uplayer, uint32 reason, uint32 zone = 0xff, uint32* list = 0);
int32 get_useable_count_fromex(card* pcard, uint8 playerid, uint8 uplayer, uint32 zone = 0xff, uint32* list = 0);
int32 get_spsummonable_count(card* pcard, uint8 playerid, uint32 zone = 0xff, uint32* list = 0);
int32 get_spsummonable_count_fromex(card* pcard, uint8 playerid, uint8 uplayer, uint32 zone = 0xff, uint32* list = 0);
int32 get_useable_count_other(card* pcard, uint8 playerid, uint8 location, uint8 uplayer, uint32 reason, uint32 zone = 0xff, uint32* list = 0);
int32 get_tofield_count(card* pcard, uint8 playerid, uint8 location, uint32 uplayer, uint32 reason, uint32 zone = 0xff, uint32* list = 0);
int32 get_useable_count_fromex_rule4(card* pcard, uint8 playerid, uint8 uplayer, uint32 zone = 0xff, uint32* list = 0);
int32 get_spsummonable_count_fromex_rule4(card* pcard, uint8 playerid, uint8 uplayer, uint32 zone = 0xff, uint32* list = 0);
int32 get_mzone_limit(uint8 playerid, uint8 uplayer, uint32 reason);
int32 get_szone_limit(uint8 playerid, uint8 uplayer, uint32 reason);
uint32 get_linked_zone(int32 playerid);
uint32 get_rule_zone_fromex(int32 playerid, card* pcard);
void filter_must_use_mzone(uint8 playerid, uint8 uplayer, uint32 reason, card* pcard, uint32* flag);
void get_linked_cards(uint8 self, uint8 s, uint8 o, card_set* cset);
int32 check_extra_link(int32 playerid);
int32 check_extra_link(int32 playerid, card* pcard, int32 sequence);
void get_cards_in_zone(card_set* cset, uint32 zone, int32 playerid, int32 location);
void shuffle(uint8 playerid, uint8 location);
void reset_sequence(uint8 playerid, uint8 location);
void swap_deck_and_grave(uint8 playerid);
void reverse_deck(uint8 playerid);
void tag_swap(uint8 playerid);
void add_effect(effect* peffect, uint8 owner_player = 2);
void set_control(card* pcard, uint8_t playerid, uint16_t reset_phase, uint8_t reset_count);
int32_t get_pzone_sequence(uint8_t pseq) const;
card* get_field_card(uint8_t playerid, uint32_t general_location, uint8_t sequence) const;
int32_t is_location_useable(uint8_t playerid, uint32_t general_location, uint8_t sequence) const;
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_t get_useable_count_fromex(card* pcard, uint8_t playerid, uint8_t uplayer, uint32_t zone = 0xff, uint32_t* list = nullptr);
int32_t get_spsummonable_count(card* pcard, uint8_t playerid, uint32_t zone = 0xff, uint32_t* list = nullptr);
int32_t get_spsummonable_count_fromex(card* pcard, uint8_t playerid, uint8_t uplayer, uint32_t zone = 0xff, uint32_t* list = nullptr);
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_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_t get_useable_count_fromex_rule4(card* pcard, uint8_t playerid, uint8_t uplayer, uint32_t zone = 0xff, uint32_t* list = nullptr);
int32_t get_spsummonable_count_fromex_rule4(card* pcard, uint8_t playerid, uint8_t uplayer, uint32_t zone = 0xff, uint32_t* list = nullptr);
int32_t get_mzone_limit(uint8_t playerid, uint8_t uplayer, uint32_t reason);
int32_t get_szone_limit(uint8_t playerid, uint8_t uplayer, uint32_t reason);
uint32_t get_linked_zone(int32_t playerid);
uint32_t get_rule_zone_fromex(int32_t playerid, card* pcard);
void filter_must_use_mzone(uint8_t playerid, uint8_t uplayer, uint32_t reason, card* pcard, uint32_t* flag);
void get_linked_cards(uint8_t self, uint8_t s, uint8_t o, card_set* cset);
int32_t check_extra_link(int32_t playerid);
int32_t check_extra_link(int32_t playerid, card* pcard, int32_t sequence);
void get_cards_in_zone(card_set* cset, uint32_t zone, int32_t playerid, int32_t location);
void shuffle(uint8_t playerid, uint8_t location);
void reset_sequence(uint8_t playerid, uint8_t location);
void swap_deck_and_grave(uint8_t playerid);
void reverse_deck(uint8_t playerid);
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_oath_effect(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 add_effect_code(uint32 code, uint32 playerid);
uint32 get_effect_code(uint32 code, uint32 playerid);
void dec_effect_code(uint32 code, uint32 playerid);
void add_effect_code(uint32_t code, int32_t playerid);
int32_t get_effect_code(uint32_t code, int32_t 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_inrange_cards(effect* peffect, card_set* cset);
void filter_player_effect(uint8 playerid, uint32 code, effect_set* eset, uint8 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 filter_field_card(uint8 self, uint32 location, uint32 location2, group* pgroup);
effect* is_player_affected_by_effect(uint8 playerid, uint32 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 check_release_list(uint8 playerid, int32 count, int32 use_con, int32 use_hand, int32 fun, int32 exarg, card* exc, group* exg);
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 get_summon_count_limit(uint8 playerid);
int32 get_draw_count(uint8 playerid);
void get_ritual_material(uint8 playerid, effect* peffect, card_set* material, uint8 no_level = FALSE);
void get_fusion_material(uint8 playerid, card_set* material_all, card_set* material_base, uint32 location);
void ritual_release(card_set* material);
void get_xyz_material(card* scard, int32 findex, uint32 lv, int32 maxc, group* mg);
void get_overlay_group(uint8 self, uint8 s, uint8 o, card_set* pset);
int32 get_overlay_count(uint8 self, uint8 s, uint8 o);
void filter_player_effect(uint8_t playerid, uint32_t code, effect_set* eset, uint8_t sort = TRUE);
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_t filter_field_card(uint8_t self, uint32_t location, uint32_t location2, group* pgroup);
effect* is_player_affected_by_effect(uint8_t playerid, uint32_t code);
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_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_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_t get_summon_count_limit(uint8_t playerid);
int32_t get_draw_count(uint8_t playerid);
void get_ritual_material(uint8_t playerid, effect* peffect, card_set* material, uint8_t no_level = FALSE);
void get_fusion_material(uint8_t playerid, card_set* material_all, card_set* material_base, uint32_t location);
void ritual_release(const card_set& material);
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_t self, uint8_t s, uint8_t o, card_set* pset);
int32_t get_overlay_count(uint8_t self, uint8_t s, uint8_t o);
void update_disable_check_list(effect* peffect);
void add_to_disable_check_list(card* pcard);
void adjust_disable_check_list();
void adjust_self_destroy_set();
void erase_grant_effect(effect* peffect);
int32 adjust_grant_effect();
int32_t adjust_grant_effect();
void add_unique_card(card* pcard);
void remove_unique_card(card* pcard);
effect* check_unique_onfield(card* pcard, uint8 controler, uint8 location, card* icard = 0);
int32 check_spsummon_once(card* pcard, uint8 playerid);
void check_card_counter(card* pcard, int32 counter_type, int32 playerid);
void check_card_counter(group* pgroup, int32 counter_type, int32 playerid);
void check_chain_counter(effect* peffect, int32 playerid, int32 chainid, bool cancel = false);
void set_spsummon_counter(uint8 playerid);
int32 check_spsummon_counter(uint8 playerid, uint8 ct = 1);
int32 check_lp_cost(uint8 playerid, uint32 cost, uint32 must_pay);
effect* check_unique_onfield(card* pcard, uint8_t controler, uint8_t location, card* icard = nullptr);
int32_t check_spsummon_once(card* pcard, uint8_t playerid);
void check_card_counter(card* pcard, int32_t counter_type, int32_t playerid);
void check_card_counter(group* pgroup, int32_t counter_type, int32_t playerid);
void check_chain_counter(effect* peffect, int32_t playerid, int32_t chainid, bool cancel = false);
void set_spsummon_counter(uint8_t playerid);
int32_t check_spsummon_counter(uint8_t playerid, uint8_t ct = 1);
bool is_select_hide_deck_sequence(uint8_t playerid);
int32_t check_lp_cost(uint8_t playerid, int32_t cost, uint32_t must_pay);
void save_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);
int32 effect_replace_check(uint32 code, const tevent& e);
int32 get_attack_target(card* pcard, card_vector* v, uint8 chain_attack = FALSE, bool select_target = true);
uint32_t get_field_counter(uint8_t self, uint8_t s, uint8_t o, uint16_t countertype);
int32_t effect_replace_check(uint32_t code, const tevent& e);
int32_t get_attack_target(card* pcard, card_vector* v, uint8_t chain_attack = FALSE, bool select_target = true);
bool confirm_attack_target();
void attack_all_target_check();
int32 check_synchro_material(card* pcard, int32 findex1, int32 findex2, int32 min, int32 max, card* smat, group* mg);
int32 check_tuner_material(card* pcard, card* tuner, int32 findex1, int32 findex2, int32 min, int32 max, card* smat, group* mg);
int32 check_other_synchro_material(const card_vector& nsyn, int32 lv, int32 min, int32 max, int32 mcount);
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);
static int32 check_with_sum_limit_m(const card_vector& mats, int32 acc, int32 index, int32 min, int32 max, int32 opmin, int32 must_count);
static int32 check_with_sum_greater_limit(const card_vector& mats, int32 acc, int32 index, int32 opmin);
static int32 check_with_sum_greater_limit_m(const card_vector& mats, int32 acc, int32 index, int32 opmin, int32 must_count);
int32 check_xyz_material(card* pcard, int32 findex, int32 lv, int32 min, int32 max, group* mg);
int32 is_player_can_draw(uint8 playerid);
int32 is_player_can_discard_deck(uint8 playerid, int32 count);
int32 is_player_can_discard_deck_as_cost(uint8 playerid, int32 count);
int32 is_player_can_discard_hand(uint8 playerid, card* pcard, effect* reason_effect, uint32 reason);
int32 is_player_can_action(uint8 playerid, uint32 actionlimit);
int32 is_player_can_summon(uint32 sumtype, uint8 playerid, card* pcard, uint8 toplayer);
int32 is_player_can_mset(uint32 sumtype, uint8 playerid, card* pcard, uint8 toplayer);
int32 is_player_can_sset(uint8 playerid, card* pcard);
int32 is_player_can_spsummon(uint8 playerid);
int32 is_player_can_spsummon(effect* reason_effect, uint32 sumtype, uint8 sumpos, uint8 playerid, uint8 toplayer, card* pcard);
int32 is_player_can_flipsummon(uint8 playerid, card* pcard);
int32 is_player_can_spsummon_monster(uint8 playerid, uint8 toplayer, uint8 sumpos, uint32 sumtype, card_data* pdata);
int32 is_player_can_spsummon_count(uint8 playerid, uint32 count);
int32 is_player_can_release(uint8 playerid, card* pcard);
int32 is_player_can_place_counter(uint8 playerid, card* pcard, uint16 countertype, uint16 count);
int32 is_player_can_remove_counter(uint8 playerid, card* pcard, uint8 s, uint8 o, uint16 countertype, uint16 count, uint32 reason);
int32 is_player_can_remove_overlay_card(uint8 playerid, card* pcard, uint8 s, uint8 o, uint16 count, uint32 reason);
int32 is_player_can_send_to_grave(uint8 playerid, card* pcard);
int32 is_player_can_send_to_hand(uint8 playerid, card* pcard);
int32 is_player_can_send_to_deck(uint8 playerid, card* pcard);
int32 is_player_can_remove(uint8 playerid, card* pcard, uint32 reason);
int32 is_chain_negatable(uint8 chaincount);
int32 is_chain_disablable(uint8 chaincount);
int32 is_chain_disabled(uint8 chaincount);
int32 check_chain_target(uint8 chaincount, card* pcard);
chain* get_chain(uint32 chaincount);
int32 get_cteffect(effect* peffect, int32 playerid, int32 store);
int32 get_cteffect_evt(effect* feffect, int32 playerid, const tevent& e, int32 store);
int32 check_cteffect_hint(effect* peffect, uint8 playerid);
int32 check_nonpublic_trigger(chain& ch);
int32 check_trigger_effect(const chain& ch) const;
int32 check_spself_from_hand_trigger(const chain& ch) const;
int32 is_able_to_enter_bp();
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 process();
int32 execute_cost(uint16 step, effect* peffect, uint8 triggering_player);
int32 execute_operation(uint16 step, effect* peffect, uint8 triggering_player);
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 raise_event(card_set* event_cards, uint32 event_code, effect* reason_effect, uint32 reason, uint8 reason_player, uint8 event_player, uint32 event_value);
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 check_event(uint32 code, tevent* pe = 0);
int32 check_event_c(effect* peffect, uint8 playerid, int32 neglect_con, int32 neglect_cost, int32 copy_info, tevent* pe = 0);
int32 check_hint_timing(effect* peffect);
int32 process_phase_event(int16 step, int32 phase_event);
int32 process_point_event(int16 step, int32 skip_trigger, int32 skip_freechain, int32 skip_new);
int32 process_quick_effect(int16 step, int32 skip_freechain, uint8 priority);
int32 process_instant_event();
int32 process_single_event();
int32 process_single_event(effect* peffect, const tevent& e, chain_list& tp, chain_list& ntp);
int32 process_idle_command(uint16 step);
int32 process_battle_command(uint16 step);
int32 process_damage_step(uint16 step, uint32 new_attack);
void calculate_battle_damage(effect** pdamchange, card** preason_card, uint8* battle_destroyed);
int32 process_turn(uint16 step, uint8 turn_player);
int32 add_chain(uint16 step);
void solve_continuous(uint8 playerid, effect* peffect, const tevent& e);
int32 solve_continuous(uint16 step);
int32 solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2);
int32 break_effect();
int32_t get_must_material_list(uint8_t playerid, uint32_t limit, card_set* must_list);
int32_t check_must_material(group* mg, uint8_t playerid, uint32_t limit);
void get_synchro_material(uint8_t playerid, card_set* material, effect* tuner_limit = nullptr);
//check material
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);
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);
int32_t check_other_synchro_material(const card_vector& nsyn, int32_t lv, int32_t min, int32_t max, int32_t mcount);
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);
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);
static int32_t check_with_sum_greater_limit(const card_vector& mats, int32_t acc, int32_t index, int32_t opmin);
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_t check_xyz_material(lua_State* L, card* pcard, int32_t findex, int32_t lv, int32_t min, int32_t max, group* mg);
int32_t is_player_can_draw(uint8_t playerid);
int32_t is_player_can_discard_deck(uint8_t playerid, int32_t count);
int32_t is_player_can_discard_deck_as_cost(uint8_t playerid, int32_t count);
int32_t is_player_can_discard_hand(uint8_t playerid, card* pcard, effect* reason_effect, uint32_t reason);
int32_t is_player_can_action(uint8_t playerid, uint32_t actionlimit);
int32_t is_player_can_summon(uint32_t sumtype, uint8_t playerid, card* pcard, uint8_t toplayer);
int32_t is_player_can_mset(uint32_t sumtype, uint8_t playerid, card* pcard, uint8_t toplayer);
int32_t is_player_can_sset(uint8_t playerid, card* pcard);
int32_t is_player_can_spsummon(uint8_t playerid);
int32_t is_player_can_spsummon(effect* reason_effect, uint32_t sumtype, uint8_t sumpos, uint8_t playerid, uint8_t toplayer, card* pcard);
int32_t is_player_can_flipsummon(uint8_t playerid, card* pcard);
int32_t is_player_can_spsummon_monster(uint8_t playerid, uint8_t toplayer, uint8_t sumpos, uint32_t sumtype, card_data* pdata);
int32_t is_player_can_spsummon_count(uint8_t playerid, uint32_t count);
int32_t is_player_can_release(uint8_t playerid, card* pcard, uint32_t reason);
int32_t is_player_can_place_counter(uint8_t playerid, card* pcard, uint16_t countertype, uint16_t count);
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_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_t is_player_can_send_to_grave(uint8_t playerid, card* pcard);
int32_t is_player_can_send_to_hand(uint8_t playerid, card* pcard);
int32_t is_player_can_send_to_deck(uint8_t playerid, card* pcard);
int32_t is_player_can_remove(uint8_t playerid, card* pcard, uint32_t reason);
int32_t is_chain_negatable(uint8_t chaincount);
int32_t is_chain_disablable(uint8_t chaincount);
int32_t is_chain_disabled(uint8_t chaincount);
int32_t check_chain_target(uint8_t chaincount, card* pcard);
chain* get_chain(uint32_t chaincount);
int32_t get_cteffect(effect* peffect, int32_t playerid, int32_t store);
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);
int32_t check_nonpublic_trigger(chain& ch);
int32_t check_trigger_effect(const chain& ch) const;
int32_t check_spself_from_hand_trigger(const chain& ch) const;
int32_t is_able_to_enter_bp();
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);
uint32_t process();
int32_t execute_cost(uint16_t step, effect* peffect, uint8_t triggering_player);
int32_t execute_operation(uint16_t step, effect* peffect, uint8_t triggering_player);
int32_t execute_target(uint16_t step, effect* peffect, uint8_t triggering_player);
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);
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);
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_t check_event(uint32_t code, tevent* pe = nullptr);
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_t check_hint_timing(effect* peffect);
int32_t process_phase_event(int16_t step, int32_t phase_event);
int32_t process_point_event(int16_t step, int32_t skip_trigger, int32_t skip_freechain, int32_t skip_new);
int32_t process_quick_effect(int16_t step, int32_t skip_freechain, uint8_t priority);
int32_t process_instant_event();
int32_t process_single_event();
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_t process_battle_command(uint16_t step);
int32_t process_damage_step(uint16_t step, uint32_t new_attack);
void calculate_battle_damage(effect** pdamchange, card** preason_card, uint8_t* battle_destroyed);
int32_t process_turn(uint16_t step, uint8_t turn_player);
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_all();
void refresh_location_info_instant();
int32 refresh_location_info(uint16 step);
int32 adjust_step(uint16 step);
int32_t refresh_location_info(uint16_t step);
int32_t adjust_step(uint16_t step);
//operations
int32 negate_chain(uint8 chaincount);
int32 disable_chain(uint8 chaincount, uint8 forced);
void change_chain_effect(uint8 chaincount, int32 replace_op);
void change_target(uint8 chaincount, group* targets);
void change_target_player(uint8 chaincount, uint8 playerid);
void change_target_param(uint8 chaincount, int32 param);
void remove_counter(uint32 reason, card* pcard, uint32 rplayer, uint32 s, uint32 o, uint32 countertype, uint32 count);
void remove_overlay_card(uint32 reason, card* pcard, uint32 rplayer, uint32 s, uint32 o, uint16 min, uint16 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(card* target, effect* reason_effect, uint32 reason_player, uint32 playerid, uint32 reset_phase, uint32 reset_count, uint32 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 reason_player, card* pcard1, card* pcard2, uint32 reset_phase, uint32 reset_count);
void equip(uint32 equip_player, card* equip_card, card* target, uint32 up, uint32 is_step);
void draw(effect* reason_effect, uint32 reason, uint32 reason_player, uint32 playerid, uint32 count);
void damage(effect* reason_effect, uint32 reason, uint32 reason_player, card* reason_card, uint32 playerid, uint32 amount, uint32 is_step = FALSE);
void recover(effect* reason_effect, uint32 reason, uint32 reason_player, uint32 playerid, uint32 amount, uint32 is_step = FALSE);
void summon(uint32 sumplayer, card* target, effect* proc, uint32 ignore_count, uint32 min_tribute, uint32 zone = 0x1f);
void mset(uint32 setplayer, card* target, effect* proc, uint32 ignore_count, uint32 min_tribute, uint32 zone = 0x1f);
void special_summon_rule(uint32 sumplayer, card* target, uint32 summon_type);
void special_summon(card_set* target, uint32 sumtype, uint32 sumplayer, uint32 playerid, uint32 nocheck, uint32 nolimit, uint32 positions, uint32 zone);
void special_summon_step(card* target, uint32 sumtype, uint32 sumplayer, uint32 playerid, uint32 nocheck, uint32 nolimit, uint32 positions, uint32 zone);
void special_summon_complete(effect* reason_effect, uint8 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* target, effect* reason_effect, uint32 reason, uint32 reason_player, uint32 playerid = 2, uint32 destination = 0, uint32 sequence = 0);
void release(card_set* targets, effect* reason_effect, uint32 reason, uint32 reason_player);
void release(card* target, effect* reason_effect, uint32 reason, uint32 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(card* target, effect* reason_effect, uint32 reason, uint32 reason_player, uint32 playerid, uint32 destination, uint32 sequence, uint32 position);
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 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(card* target, effect* reason_effect, uint32 reason_player, uint32 npos, uint32 flag, uint32 enable = FALSE);
void operation_replace(int32 type, int32 step, group* targets);
void select_tribute_cards(card* target, uint8 playerid, uint8 cancelable, int32 min, int32 max, uint8 toplayer, uint32 zone);
int32 remove_counter(uint16 step, uint32 reason, card* pcard, uint8 rplayer, uint8 s, uint8 o, uint16 countertype, uint16 count);
int32 remove_overlay_card(uint16 step, uint32 reason, card* pcard, uint8 rplayer, uint8 s, uint8 o, uint16 min, uint16 max);
int32 get_control(uint16 step, effect* reason_effect, uint8 reason_player, group* targets, uint8 playerid, uint16 reset_phase, uint8 reset_count, uint32 zone);
int32 swap_control(uint16 step, effect* reason_effect, uint8 reason_player, group* targets1, group* targets2, uint16 reset_phase, uint8 reset_count);
int32 self_destroy(uint16 step, card* ucard, int32 p);
int32 trap_monster_adjust(uint16 step);
int32 equip(uint16 step, uint8 equip_player, card* equip_card, card* target, uint32 up, uint32 is_step);
int32 draw(uint16 step, effect* reason_effect, uint32 reason, uint8 reason_player, uint8 playerid, uint32 count);
int32 damage(uint16 step, effect* reason_effect, uint32 reason, uint8 reason_player, card* reason_card, uint8 playerid, uint32 amount, uint32 is_step);
int32 recover(uint16 step, effect* reason_effect, uint32 reason, uint8 reason_player, uint8 playerid, uint32 amount, uint32 is_step);
int32 summon(uint16 step, uint8 sumplayer, card* target, effect* proc, uint8 ignore_count, uint8 min_tribute, uint32 zone);
int32 flip_summon(uint16 step, uint8 sumplayer, card* target);
int32 mset(uint16 step, uint8 setplayer, card* ptarget, effect* proc, uint8 ignore_count, uint8 min_tribute, uint32 zone);
int32 sset(uint16 step, uint8 setplayer, uint8 toplayer, card* ptarget, effect* reason_effect);
int32 sset_g(uint16 step, uint8 setplayer, uint8 toplayer, group* ptarget, uint8 confirm, effect* reason_effect);
int32 special_summon_rule(uint16 step, uint8 sumplayer, card* target, uint32 summon_type);
int32 special_summon_step(uint16 step, group* targets, card* target, uint32 zone);
int32 special_summon(uint16 step, effect* reason_effect, uint8 reason_player, group* targets, uint32 zone);
int32 destroy_replace(uint16 step, group* targets, card* target, uint8 battle);
int32 destroy(uint16 step, group* targets, effect* reason_effect, uint32 reason, uint8 reason_player);
int32 release_replace(uint16 step, group* targets, card* target);
int32 release(uint16 step, group* targets, effect* reason_effect, uint32 reason, uint8 reason_player);
int32 send_replace(uint16 step, group* targets, card* target);
int32 send_to(uint16 step, group* targets, effect* reason_effect, uint32 reason, uint8 reason_player);
int32 discard_deck(uint16 step, uint8 playerid, uint8 count, uint32 reason);
int32 move_to_field(uint16 step, card* target, uint32 enable, uint32 ret, uint32 pzone, uint32 zone);
int32 change_position(uint16 step, group* targets, effect* reason_effect, uint8 reason_player, uint32 enable);
int32 operation_replace(uint16 step, effect* replace_effect, group* targets, card* target, int32 is_destroy);
int32 activate_effect(uint16 step, effect* peffect);
int32 select_synchro_material(int16 step, uint8 playerid, card* pcard, int32 min, int32 max, card* smat, group* mg);
int32 select_xyz_material(int16 step, uint8 playerid, uint32 lv, card* pcard, int32 min, int32 max);
int32 select_release_cards(int16 step, uint8 playerid, uint8 cancelable, int32 min, int32 max);
int32 select_tribute_cards(int16 step, card* target, uint8 playerid, uint8 cancelable, int32 min, int32 max, uint8 toplayer, uint32 zone);
int32 toss_coin(uint16 step, effect* reason_effect, uint8 reason_player, uint8 playerid, uint8 count);
int32 toss_dice(uint16 step, effect* reason_effect, uint8 reason_player, uint8 playerid, uint8 count1, uint8 count2);
int32 rock_paper_scissors(uint16 step, uint8 repeat);
int32 select_battle_command(uint16 step, uint8 playerid);
int32 select_idle_command(uint16 step, uint8 playerid);
int32 select_effect_yes_no(uint16 step, uint8 playerid, uint32 description, card* pcard);
int32 select_yes_no(uint16 step, uint8 playerid, uint32 description);
int32 select_option(uint16 step, uint8 playerid);
int32 select_card(uint16 step, uint8 playerid, uint8 cancelable, uint8 min, uint8 max);
int32 select_unselect_card(uint16 step, uint8 playerid, uint8 cancelable, uint8 min, uint8 max, uint8 finishable);
int32 select_chain(uint16 step, uint8 playerid, uint8 spe_count, uint8 forced);
int32 select_place(uint16 step, uint8 playerid, uint32 flag, uint8 count);
int32 select_position(uint16 step, uint8 playerid, uint32 code, uint8 positions);
int32 select_tribute(uint16 step, uint8 playerid, uint8 cancelable, uint8 min, uint8 max);
int32 select_counter(uint16 step, uint8 playerid, uint16 countertype, uint16 count, uint8 s, uint8 o);
int32 select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32 min, int32 max);
int32 sort_card(int16 step, uint8 playerid);
int32 announce_race(int16 step, uint8 playerid, int32 count, int32 available);
int32 announce_attribute(int16 step, uint8 playerid, int32 count, int32 available);
int32 announce_card(int16 step, uint8 playerid);
int32 announce_number(int16 step, uint8 playerid);
int32_t negate_chain(uint8_t chaincount);
int32_t disable_chain(uint8_t chaincount, uint8_t forced);
void change_chain_effect(uint8_t chaincount, int32_t replace_op);
void change_target(uint8_t chaincount, group* targets);
void change_target_player(uint8_t chaincount, uint8_t playerid);
void change_target_param(uint8_t chaincount, int32_t param);
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_t reason, card* pcard, uint32_t rplayer, uint32_t s, uint32_t o, uint16_t min, uint16_t max);
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_t reason_player, uint32_t playerid, uint32_t reset_phase, uint32_t reset_count, uint32_t zone);
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_t reason_player, card* pcard1, card* pcard2, uint32_t reset_phase, uint32_t reset_count);
void equip(uint32_t equip_player, card* equip_card, card* target, uint32_t up, uint32_t is_step);
void draw(effect* reason_effect, uint32_t reason, uint32_t reason_player, uint32_t playerid, int32_t count);
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_t reason, uint32_t reason_player, uint32_t playerid, int32_t amount, uint32_t is_step = FALSE);
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_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_t sumplayer, card* target, uint32_t summon_type, uint32_t action_type = SUMMON_IN_IDLE);
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_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_t reason_player);
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_t reason, uint32_t reason_player, uint32_t playerid = 2, uint32_t destination = 0, uint32_t sequence = 0);
void release(const card_set& targets, effect* reason_effect, uint32_t reason, uint32_t reason_player);
void release(card* target, effect* reason_effect, uint32_t reason, uint32_t reason_player);
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_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_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(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_t reason_player, uint32_t npos, uint32_t flag, uint32_t enable = FALSE);
void operation_replace(int32_t type, int32_t step, group* targets);
void select_tribute_cards(card* target, uint8_t playerid, uint8_t cancelable, int32_t min, int32_t max, uint8_t toplayer, uint32_t zone);
// summon
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_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_t flip_summon(uint16_t step, uint8_t sumplayer, card* target, uint32_t action_type);
int32_t special_summon_rule(uint16_t step, uint8_t sumplayer, card* target, uint32_t summon_type, uint32_t action_type);
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_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_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_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_t self_destroy(uint16_t step, card* ucard, int32_t p);
int32_t trap_monster_adjust(uint16_t step);
int32_t equip(uint16_t step, uint8_t equip_player, card* equip_card, card* target, uint32_t up, uint32_t is_step);
int32_t draw(uint16_t step, effect* reason_effect, uint32_t reason, uint8_t reason_player, uint8_t playerid, int32_t count);
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_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_t sset(uint16_t step, uint8_t setplayer, uint8_t toplayer, card* ptarget, effect* reason_effect);
int32_t sset_g(uint16_t step, uint8_t setplayer, uint8_t toplayer, group* ptarget, uint8_t confirm, effect* reason_effect);
int32_t special_summon_step(uint16_t step, group* targets, card* target, uint32_t zone);
int32_t special_summon(uint16_t step, effect* reason_effect, uint8_t reason_player, group* targets, uint32_t zone);
int32_t destroy_replace(uint16_t step, group* targets, card* target, uint8_t battle);
int32_t destroy(uint16_t step, group* targets, effect* reason_effect, uint32_t reason, uint8_t reason_player);
int32_t release_replace(uint16_t step, group* targets, card* target);
int32_t release(uint16_t step, group* targets, effect* reason_effect, uint32_t reason, uint8_t reason_player);
int32_t send_replace(uint16_t step, group* targets, card* target);
int32_t send_to(uint16_t step, group* targets, effect* reason_effect, uint32_t reason, uint8_t reason_player, uint8_t send_activating);
int32_t discard_deck(uint16_t step, uint8_t playerid, uint8_t count, uint32_t reason);
int32_t move_to_field(uint16_t step, card* target, uint32_t enable, uint32_t ret, uint32_t pzone, uint32_t zone);
int32_t change_position(uint16_t step, group* targets, effect* reason_effect, uint8_t reason_player, uint32_t enable);
int32_t operation_replace(uint16_t step, effect* replace_effect, group* targets, card* target, int32_t is_destroy);
int32_t activate_effect(uint16_t step, effect* peffect);
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_t select_xyz_material(int16_t step, uint8_t playerid, uint32_t lv, card* pcard, int32_t min, int32_t max);
int32_t select_release_cards(int16_t step, uint8_t playerid, uint8_t cancelable, int32_t min, int32_t max);
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_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_t rock_paper_scissors(uint16_t step, uint8_t repeat);
bool check_response(size_t vector_size, int32_t min_len, int32_t max_len) const;
int32_t select_battle_command(uint16_t step, uint8_t playerid);
int32_t select_idle_command(uint16_t step, uint8_t playerid);
int32_t select_effect_yes_no(uint16_t step, uint8_t playerid, uint32_t description, card* pcard);
int32_t select_yes_no(uint16_t step, uint8_t playerid, uint32_t description);
int32_t select_option(uint16_t step, uint8_t playerid);
int32_t select_card(uint16_t step, uint8_t playerid, uint8_t cancelable, uint8_t min, uint8_t max);
int32_t select_unselect_card(uint16_t step, uint8_t playerid, uint8_t cancelable, uint8_t min, uint8_t max, uint8_t finishable);
int32_t select_chain(uint16_t step, uint8_t playerid, uint8_t spe_count, uint8_t forced);
int32_t select_place(uint16_t step, uint8_t playerid, uint32_t flag, uint8_t count);
int32_t select_position(uint16_t step, uint8_t playerid, uint32_t code, uint8_t positions);
int32_t select_tribute(uint16_t step, uint8_t playerid, uint8_t cancelable, uint8_t min, uint8_t max);
int32_t select_counter(uint16_t step, uint8_t playerid, uint16_t countertype, uint16_t count, uint8_t s, uint8_t o);
int32_t select_with_sum_limit(int16_t step, uint8_t playerid, int32_t acc, int32_t min, int32_t max);
int32_t sort_card(int16_t step, uint8_t 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
......@@ -718,7 +713,7 @@ public:
#define GLOBALFLAG_SCRAP_CHIMERA 0x4
//#define GLOBALFLAG_DELAYED_QUICKEFFECT 0x8
#define GLOBALFLAG_DETACH_EVENT 0x10
#define GLOBALFLAG_MUST_BE_SMATERIAL 0x20
//#define GLOBALFLAG_MUST_BE_SMATERIAL 0x20
#define GLOBALFLAG_SPSUMMON_COUNT 0x40
#define GLOBALFLAG_XMAT_COUNT_LIMIT 0x80
#define GLOBALFLAG_SELF_TOGRAVE 0x100
......@@ -726,9 +721,6 @@ public:
#define GLOBALFLAG_TUNE_MAGICIAN 0x400
#define GLOBALFLAG_ACTIVATION_COUNT 0x800
//
#define PROCESSOR_NONE 0
#define PROCESSOR_WAITING 0x10000
#define PROCESSOR_END 0x20000
#define PROCESSOR_ADJUST 1
#define PROCESSOR_HINT 2
......
......@@ -10,21 +10,15 @@
#include "duel.h"
group::group(duel* pd) {
ref_handle = 0;
pduel = pd;
is_readonly = FALSE;
it = container.begin();
}
group::group(duel* pd, card* pcard) {
container.insert(pcard);
ref_handle = 0;
pduel = pd;
is_readonly = FALSE;
it = container.begin();
}
group::group(duel* pd, const card_set& cset): container(cset) {
ref_handle = 0;
pduel = pd;
is_readonly = FALSE;
it = container.begin();
}
......@@ -9,22 +9,29 @@
#define GROUP_H_
#include "common.h"
#include "sort.h"
#include <set>
#include <list>
class card;
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:
using card_set = std::set<card*, card_sort>;
int32 ref_handle;
int32_t ref_handle{ 0 };
uint32_t is_readonly{ GTYPE_DEFAULT };
duel* pduel;
card_set container;
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();
}
......
......@@ -5,6 +5,7 @@
* Author: Argon
*/
#include <cstring>
#include "duel.h"
#include "group.h"
#include "card.h"
......@@ -17,33 +18,29 @@ interpreter::interpreter(duel* pd): coroutines(256) {
lua_state = luaL_newstate();
current_state = lua_state;
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;
call_depth = 0;
//Initial
luaL_openlibs(lua_state);
lua_pushnil(lua_state);
lua_setglobal(lua_state, "io");
lua_pushnil(lua_state);
lua_setglobal(lua_state, "os");
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");
luaL_requiref(lua_state, "base", luaopen_base, 0);
lua_pop(lua_state, 1);
luaL_requiref(lua_state, "string", luaopen_string, 1);
lua_pop(lua_state, 1);
luaL_requiref(lua_state, "utf8", luaopen_utf8, 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
scriptlib::open_cardlib(lua_state);
scriptlib::open_effectlib(lua_state);
......@@ -53,42 +50,41 @@ interpreter::interpreter(duel* pd): coroutines(256) {
//extra scripts
load_script("./script/constant.lua");
load_script("./script/utility.lua");
load_script("./script/procedure.lua");
}
interpreter::~interpreter() {
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
luaL_checkstack(lua_state, 1, NULL);
luaL_checkstack(current_state, 1, NULL);
card ** ppcard = (card**) lua_newuserdata(lua_state, sizeof(card*));
luaL_checkstack(lua_state, 1, nullptr);
card ** ppcard = (card**) lua_newuserdata(lua_state, sizeof(card*)); //+1 userdata
*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
lua_rawgeti(current_state, LUA_REGISTRYINDEX, pcard->ref_handle);
//load script
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.alias);
else
load_card_script(pcard->data.code);
luaL_checkstack(current_state, 1, nullptr);
lua_rawgeti(current_state, LUA_REGISTRYINDEX, pcard->ref_handle); //+1 userdata
load_card_script(pcard->data.get_original_code());
//stack: table cxxx, userdata
//set metatable of pointer to base script
lua_setmetatable(current_state, -2);
lua_pop(current_state, 1);
lua_setmetatable(current_state, -2); //-1
lua_pop(current_state, 1); //-1
//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);
add_param(pcard, PARAM_TYPE_CARD);
call_card_function(pcard, "initial_effect", 1, 0);
pcard->set_status(STATUS_INITIALIZING, FALSE);
}
pcard->cardid = pduel->game_field->infos.card_id++;
return OPERATION_SUCCESS;
}
void interpreter::register_effect(effect *peffect) {
if (!peffect)
return;
//create a effect in by userdata
luaL_checkstack(lua_state, 3, NULL);
//create a effect in userdata
luaL_checkstack(lua_state, 3, nullptr);
effect ** ppeffect = (effect**) lua_newuserdata(lua_state, sizeof(effect*));
*ppeffect = peffect;
peffect->ref_handle = luaL_ref(lua_state, LUA_REGISTRYINDEX);
......@@ -118,7 +114,7 @@ void interpreter::register_group(group *pgroup) {
if (!pgroup)
return;
//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*));
*ppgroup = pgroup;
pgroup->ref_handle = luaL_ref(lua_state, LUA_REGISTRYINDEX);
......@@ -134,120 +130,128 @@ void interpreter::unregister_group(group *pgroup) {
luaL_unref(lua_state, LUA_REGISTRYINDEX, pgroup->ref_handle);
pgroup->ref_handle = 0;
}
int32 interpreter::load_script(const char* script_name) {
int32 len = 0;
byte* buffer = read_script(script_name, &len);
int32_t interpreter::load_script(const char* script_name) {
int len = 0;
byte* buffer = ::read_script(script_name, &len);
if (!buffer)
return OPERATION_FAIL;
no_action++;
int32 error = luaL_loadbuffer(current_state, (char*)buffer, len, script_name) || lua_pcall(current_state, 0, 0, 0);
++no_action;
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) {
sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1));
interpreter::sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1));
handle_message(pduel, 1);
lua_pop(current_state, 1);
no_action--;
--no_action;
return OPERATION_FAIL;
}
no_action--;
--no_action;
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];
sprintf(class_name, "c%d", code);
luaL_checkstack(current_state, 1, NULL);
lua_getglobal(current_state, class_name);
//if script is not loaded, create and load it
interpreter::sprintf(class_name, "c%d", code);
luaL_checkstack(current_state, 1, nullptr);
lua_getglobal(current_state, class_name); //+1 table cxxx
if (lua_isnil(current_state, -1)) {
luaL_checkstack(current_state, 5, NULL);
lua_pop(current_state, 1);
luaL_checkstack(current_state, 5, nullptr);
lua_pop(current_state, 1); //-1
//create a table & set metatable
lua_createtable(current_state, 0, 0);
lua_setglobal(current_state, class_name);
lua_getglobal(current_state, class_name);
lua_getglobal(current_state, "Card");
lua_setmetatable(current_state, -2);
lua_pushstring(current_state, "__index");
lua_pushvalue(current_state, -2);
lua_rawset(current_state, -3);
lua_getglobal(current_state, class_name);
lua_setglobal(current_state, "self_table");
lua_pushinteger(current_state, code);
lua_setglobal(current_state, "self_code");
lua_createtable(current_state, 0, 0); //+1, {}
lua_setglobal(current_state, class_name); //-1
lua_getglobal(current_state, class_name); //+1 table cxxx
lua_getglobal(current_state, "Card"); //+1 Card, table cxxx
lua_setmetatable(current_state, -2); //-1 table cxxx
lua_pushstring(current_state, "__index"); //+1 "__index", table cxxx
lua_pushvalue(current_state, -2); //+1 table cxxx, "__index", table cxxx
lua_rawset(current_state, -3); //-2 table cxxx
card_data cdata;
int32_t res = OPERATION_SUCCESS;
::read_card(code, &cdata);
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];
sprintf(script_name, "./script/c%d.lua", code);
int32 res = load_script(script_name);
lua_pushnil(current_state);
lua_setglobal(current_state, "self_table");
lua_pushnil(current_state);
lua_setglobal(current_state, "self_code");
interpreter::sprintf(script_name, "./script/c%d.lua", code);
res = load_script(script_name);
lua_pushnil(current_state); //+1
lua_setglobal(current_state, "self_table"); //-1
lua_pushnil(current_state); //+1
lua_setglobal(current_state, "self_code"); //-1 table cxxx {__index: cxxx }
}
if(!res) {
return OPERATION_FAIL;
}
}
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)
params.emplace_front(param, type);
params.emplace_front(p, type);
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)
params.emplace_front((void*)(intptr_t)param, type);
params.emplace_front(p, type);
else
params.emplace_back((void*)(intptr_t)param, type);
params.emplace_back(p, type);
}
void interpreter::push_param(lua_State* L, bool is_coroutine) {
int32 pushed = 0;
int32_t pushed = 0;
for (const auto& it : params) {
luaL_checkstack(L, 1, NULL);
uint32 type = it.second;
luaL_checkstack(L, 1, nullptr);
auto type = it.second;
switch(type) {
case PARAM_TYPE_INT:
lua_pushinteger(L, (lua_Integer)it.first);
lua_pushinteger(L, it.first.integer);
break;
case PARAM_TYPE_STRING:
lua_pushstring(L, (const char *)it.first);
lua_pushstring(L, (const char*)it.first.ptr);
break;
case PARAM_TYPE_BOOLEAN:
lua_pushboolean(L, (int32)(intptr_t)it.first);
lua_pushboolean(L, it.first.integer);
break;
case PARAM_TYPE_CARD: {
if (it.first)
lua_rawgeti(L, LUA_REGISTRYINDEX, ((card*)it.first)->ref_handle);
if (it.first.ptr)
lua_rawgeti(L, LUA_REGISTRYINDEX, ((card*)it.first.ptr)->ref_handle);
else
lua_pushnil(L);
break;
}
case PARAM_TYPE_EFFECT: {
if (it.first)
lua_rawgeti(L, LUA_REGISTRYINDEX, ((effect*)it.first)->ref_handle);
if (it.first.ptr)
lua_rawgeti(L, LUA_REGISTRYINDEX, ((effect*)it.first.ptr)->ref_handle);
else
lua_pushnil(L);
break;
}
case PARAM_TYPE_GROUP: {
if (it.first)
lua_rawgeti(L, LUA_REGISTRYINDEX, ((group*)it.first)->ref_handle);
if (it.first.ptr)
lua_rawgeti(L, LUA_REGISTRYINDEX, ((group*)it.first.ptr)->ref_handle);
else
lua_pushnil(L);
break;
}
case PARAM_TYPE_FUNCTION: {
function2value(L, (int32)(intptr_t)it.first);
function2value(L, it.first.integer);
break;
}
case PARAM_TYPE_INDEX: {
int32 index = (int32)(intptr_t)it.first;
int32_t index = it.first.integer;
if(index > 0)
lua_pushvalue(L, index);
else if(is_coroutine) {
//copy value from current_state to new stack
lua_pushvalue(current_state, index);
int32 ref = luaL_ref(current_state, LUA_REGISTRYINDEX);
lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
luaL_unref(current_state, LUA_REGISTRYINDEX, ref);
lua_xmove(current_state, L, 1);
} else {
//the calling function is pushed before the params, so the actual index is: index - pushed -1
lua_pushvalue(L, index - pushed - 1);
......@@ -255,300 +259,300 @@ void interpreter::push_param(lua_State* L, bool is_coroutine) {
break;
}
}
pushed++;
++pushed;
}
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) {
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);
params.clear();
return OPERATION_FAIL;
}
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);
params.clear();
return OPERATION_FAIL;
}
function2value(current_state, f);
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);
lua_pop(current_state, 1);
params.clear();
return OPERATION_FAIL;
}
no_action++;
call_depth++;
++no_action;
++call_depth;
push_param(current_state);
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);
lua_pop(current_state, 1);
no_action--;
call_depth--;
--no_action;
--call_depth;
if(call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
return OPERATION_FAIL;
}
no_action--;
call_depth--;
--no_action;
--call_depth;
if(call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
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()) {
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);
params.clear();
return OPERATION_FAIL;
}
card2value(current_state, pcard);
luaL_checkstack(current_state, 1, NULL);
luaL_checkstack(current_state, 1, nullptr);
lua_getfield(current_state, -1, f);
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);
lua_pop(current_state, 2);
params.clear();
return OPERATION_FAIL;
}
no_action++;
call_depth++;
++no_action;
++call_depth;
lua_remove(current_state, -2);
push_param(current_state);
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);
lua_pop(current_state, 1);
no_action--;
call_depth--;
--no_action;
--call_depth;
if(call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
return OPERATION_FAIL;
}
no_action--;
call_depth--;
--no_action;
--call_depth;
if(call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
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()) {
sprintf(pduel->strbuffer, "\"CallCodeFunction\": incorrect parameter count");
interpreter::sprintf(pduel->strbuffer, "%s", "\"CallCodeFunction\": incorrect parameter count");
handle_message(pduel, 1);
params.clear();
return OPERATION_FAIL;
}
load_card_script(code);
luaL_checkstack(current_state, 1, NULL);
luaL_checkstack(current_state, 1, nullptr);
lua_getfield(current_state, -1, f);
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);
lua_pop(current_state, 2);
params.clear();
return OPERATION_FAIL;
}
lua_remove(current_state, -2);
no_action++;
call_depth++;
++no_action;
++call_depth;
push_param(current_state);
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);
lua_pop(current_state, 1);
no_action--;
call_depth--;
--no_action;
--call_depth;
if(call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
return OPERATION_FAIL;
}
no_action--;
call_depth--;
--no_action;
--call_depth;
if(call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
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) {
params.clear();
return TRUE;
}
no_action++;
call_depth++;
++no_action;
++call_depth;
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);
no_action--;
call_depth--;
--no_action;
--call_depth;
if(call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
return result;
}
no_action--;
call_depth--;
--no_action;
--call_depth;
if(call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
return OPERATION_FAIL;
}
int32 interpreter::check_matching(card* pcard, int32 findex, int32 extraargs) {
if(!findex || lua_isnil(current_state, findex))
int32_t interpreter::check_filter(lua_State* L, card* pcard, int32_t findex, int32_t extraargs) {
if (!findex || lua_isnil(L, findex))
return TRUE;
no_action++;
call_depth++;
luaL_checkstack(current_state, 1 + extraargs, NULL);
lua_pushvalue(current_state, findex);
interpreter::card2value(current_state, pcard);
for(int32 i = 0; i < extraargs; ++i)
lua_pushvalue(current_state, (int32)(-extraargs - 2));
if (lua_pcall(current_state, 1 + extraargs, 1, 0)) {
sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1));
++no_action;
++call_depth;
luaL_checkstack(L, 1 + extraargs, nullptr);
lua_pushvalue(L, findex);
card2value(L, pcard);
for (int32_t i = 0; i < extraargs; ++i)
lua_pushvalue(L, (int32_t)(-extraargs - 2));
if (lua_pcall(L, 1 + extraargs, 1, 0)) {
interpreter::sprintf(pduel->strbuffer, "%s", lua_tostring(L, -1));
handle_message(pduel, 1);
lua_pop(current_state, 1);
no_action--;
call_depth--;
if(call_depth == 0) {
lua_pop(L, 1);
--no_action;
--call_depth;
if (call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
return OPERATION_FAIL;
}
int32 result = lua_toboolean(current_state, -1);
lua_pop(current_state, 1);
no_action--;
call_depth--;
if(call_depth == 0) {
int32_t result = lua_toboolean(L, -1);
lua_pop(L, 1);
--no_action;
--call_depth;
if (call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
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))
return 0;
no_action++;
call_depth++;
luaL_checkstack(current_state, 1 + extraargs, NULL);
++no_action;
++call_depth;
luaL_checkstack(current_state, 1 + extraargs, nullptr);
lua_pushvalue(current_state, findex);
interpreter::card2value(current_state, pcard);
for(int32 i = 0; i < extraargs; ++i)
lua_pushvalue(current_state, (int32)(-extraargs - 2));
for(int32_t i = 0; i < extraargs; ++i)
lua_pushvalue(current_state, (int32_t)(-extraargs - 2));
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);
lua_pop(current_state, 1);
no_action--;
call_depth--;
--no_action;
--call_depth;
if(call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
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);
no_action--;
call_depth--;
--no_action;
--call_depth;
if(call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
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) {
params.clear();
return 0;
}
no_action++;
call_depth++;
++no_action;
++call_depth;
if (call_function(f, param_count, 1)) {
int32 result = 0;
int32_t result = 0;
if(lua_isboolean(current_state, -1))
result = lua_toboolean(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
result = (int32)lua_tonumber(current_state, -1);
result = (int32_t)lua_tonumber(current_state, -1);
lua_pop(current_state, 1);
no_action--;
call_depth--;
--no_action;
--call_depth;
if(call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
return result;
}
no_action--;
call_depth--;
--no_action;
--call_depth;
if(call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
return OPERATION_FAIL;
}
int32 interpreter::get_function_value(int32 f, uint32 param_count, std::vector<int32>* result) {
int32 is_success = OPERATION_FAIL;
int32_t interpreter::get_function_value(int32_t f, uint32_t param_count, std::vector<lua_Integer>& result) {
int32_t is_success = OPERATION_FAIL;
if(!f) {
params.clear();
return is_success;
}
int32 stack_top = lua_gettop(current_state);
no_action++;
call_depth++;
int32_t stack_top = lua_gettop(current_state);
++no_action;
++call_depth;
if (call_function(f, param_count, LUA_MULTRET)) {
int32 stack_newtop = lua_gettop(current_state);
for (int32 index = stack_top + 1; index <= stack_newtop; ++index) {
int32 return_value = 0;
int32_t stack_newtop = lua_gettop(current_state);
for (int32_t index = stack_top + 1; index <= stack_newtop; ++index) {
lua_Integer return_value = 0;
if(lua_isboolean(current_state, index))
return_value = lua_toboolean(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
return_value = (int32)lua_tonumber(current_state, index);
result->push_back(return_value);
return_value = static_cast<lua_Integer>(lua_tonumber(current_state, index));
result.push_back(return_value);
}
lua_settop(current_state, stack_top);
is_success = OPERATION_SUCCESS;
}
no_action--;
call_depth--;
--no_action;
--call_depth;
if(call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
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;
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);
params.clear();
return OPERATION_FAIL;
}
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);
params.clear();
return OPERATION_FAIL;
......@@ -557,124 +561,130 @@ int32 interpreter::call_coroutine(int32 f, uint32 param_count, uint32 * yield_va
lua_State* rthread;
if (it == coroutines.end()) {
rthread = lua_newthread(lua_state);
const auto threadref = luaL_ref(lua_state, LUA_REGISTRYINDEX);
function2value(rthread, f);
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);
params.clear();
return OPERATION_FAIL;
}
call_depth++;
coroutines.emplace(f, rthread);
++call_depth;
auto ret = coroutines.emplace(f, coroutine_map::mapped_type(rthread, threadref));
it = ret.first;
} else {
rthread = it->second;
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);
params.clear();
call_depth--;
--call_depth;
if(call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
return OPERATION_FAIL;
}
rthread = it->second.first;
}
push_param(rthread, true);
lua_State* prev_state = current_state;
int32_t result = 0, nresults = 0;
{
auto prev_state = current_state;
current_state = rthread;
#if (LUA_VERSION_NUM >= 504)
int32 nresults;
int32 result = lua_resume(rthread, prev_state, param_count, &nresults);
result = lua_resume(rthread, prev_state, param_count, &nresults);
#else
int32 result = lua_resume(rthread, 0, param_count);
int32 nresults = lua_gettop(rthread);
result = lua_resume(rthread, prev_state, param_count);
nresults = lua_gettop(rthread);
#endif
if (result == 0) {
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 = prev_state;
}
current_state = lua_state;
call_depth--;
if(call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
return COROUTINE_FINISH;
} else if (result == LUA_YIELD) {
if (result == LUA_YIELD)
return COROUTINE_YIELD;
} else {
coroutines.erase(f);
sprintf(pduel->strbuffer, "%s", lua_tostring(rthread, -1));
if (result != LUA_OK) {
interpreter::sprintf(pduel->strbuffer, "%s", lua_tostring(rthread, -1));
handle_message(pduel, 1);
lua_pop(rthread, 1);
current_state = lua_state;
call_depth--;
if(call_depth == 0) {
}
else if (yield_value) {
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->restore_assumes();
}
return COROUTINE_ERROR;
}
return (result == LUA_OK) ? COROUTINE_FINISH : COROUTINE_ERROR;
}
int32 interpreter::clone_function_ref(int32 func_ref) {
luaL_checkstack(current_state, 1, NULL);
int32_t interpreter::clone_function_ref(int32_t func_ref) {
luaL_checkstack(current_state, 1, nullptr);
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;
}
void* interpreter::get_ref_object(int32 ref_handler) {
void* interpreter::get_ref_object(int32_t ref_handler) {
if(ref_handler == 0)
return nullptr;
luaL_checkstack(current_state, 1, NULL);
luaL_checkstack(current_state, 1, nullptr);
lua_rawgeti(current_state, LUA_REGISTRYINDEX, ref_handler);
void* p = *(void**)lua_touserdata(current_state, -1);
lua_pop(current_state, 1);
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) {
luaL_checkstack(L, 1, NULL);
luaL_checkstack(L, 1, nullptr);
if (!pcard || pcard->ref_handle == 0)
lua_pushnil(L);
else
lua_rawgeti(L, LUA_REGISTRYINDEX, pcard->ref_handle);
}
void interpreter::group2value(lua_State* L, group* pgroup) {
luaL_checkstack(L, 1, NULL);
luaL_checkstack(L, 1, nullptr);
if (!pgroup || pgroup->ref_handle == 0)
lua_pushnil(L);
else
lua_rawgeti(L, LUA_REGISTRYINDEX, pgroup->ref_handle);
}
void interpreter::effect2value(lua_State* L, effect* peffect) {
luaL_checkstack(L, 1, NULL);
luaL_checkstack(L, 1, nullptr);
if (!peffect || peffect->ref_handle == 0)
lua_pushnil(L);
else
lua_rawgeti(L, LUA_REGISTRYINDEX, peffect->ref_handle);
}
void interpreter::function2value(lua_State* L, int32 func_ref) {
luaL_checkstack(L, 1, NULL);
void interpreter::function2value(lua_State* L, int32_t func_ref) {
luaL_checkstack(L, 1, nullptr);
if (!func_ref)
lua_pushnil(L);
else
lua_rawgeti(L, LUA_REGISTRYINDEX, func_ref);
}
int32 interpreter::get_function_handle(lua_State* L, int32 index) {
luaL_checkstack(L, 1, NULL);
int32_t interpreter::get_function_handle(lua_State* L, int32_t index) {
luaL_checkstack(L, 1, nullptr);
lua_pushvalue(L, index);
int32 ref = luaL_ref(L, LUA_REGISTRYINDEX);
int32_t ref = luaL_ref(L, LUA_REGISTRYINDEX);
return ref;
}
duel* interpreter::get_duel_info(lua_State * L) {
duel* interpreter::get_duel_info(lua_State* L) {
duel* pduel;
memcpy(&pduel, lua_getextraspace(L), LUA_EXTRASPACE);
std::memcpy(&pduel, lua_getextraspace(L), LUA_EXTRASPACE);
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 @@
#ifndef INTERPRETER_H_
#define INTERPRETER_H_
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
#include "common.h"
#include <unordered_map>
#include <list>
#include <vector>
#include <cstdio>
#include <cstring>
class card;
struct card_data;
class effect;
class group;
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 {
public:
using coroutine_map = std::unordered_map<int32, lua_State*>;
using param_list = std::list<std::pair<void*, uint32>>;
union lua_param {
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;
char msgbuf[64];
......@@ -35,41 +50,42 @@ public:
param_list params;
param_list resumes;
coroutine_map coroutines;
int32 no_action;
int32 call_depth;
int32_t no_action;
int32_t call_depth;
explicit interpreter(duel* pd);
~interpreter();
int32 register_card(card* pcard);
void register_card(card* pcard);
void register_effect(effect* peffect);
void unregister_effect(effect* peffect);
void register_group(group* pgroup);
void unregister_group(group* pgroup);
int32 load_script(const char* script_name);
int32 load_card_script(uint32 code);
void add_param(void* param, int32 type, bool front = false);
void add_param(int32 param, int32 type, bool front = false);
int32_t load_script(const char* script_name);
int32_t load_card_script(uint32_t code);
void add_param(void* param, LuaParamType 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);
int32 call_function(int32 f, uint32 param_count, int32 ret_count);
int32 call_card_function(card* pcard, const char* f, uint32 param_count, int32 ret_count);
int32 call_code_function(uint32 code, const char* f, uint32 param_count, int32 ret_count);
int32 check_condition(int32 f, uint32 param_count);
int32 check_matching(card* pcard, int32 findex, int32 extraargs);
int32 get_operation_value(card* pcard, int32 findex, int32 extraargs);
int32 get_function_value(int32 f, uint32 param_count);
int32 get_function_value(int32 f, uint32 param_count, std::vector<int32>* result);
int32 call_coroutine(int32 f, uint32 param_count, uint32* yield_value, uint16 step);
int32 clone_function_ref(int32 func_ref);
void* get_ref_object(int32 ref_handler);
int32_t call_function(int32_t f, uint32_t param_count, int32_t ret_count);
int32_t call_card_function(card* pcard, const char* f, uint32_t param_count, int32_t ret_count);
int32_t call_code_function(uint32_t code, const char* f, uint32_t param_count, int32_t ret_count);
int32_t check_condition(int32_t f, uint32_t param_count);
int32_t check_filter(lua_State* L, card* pcard, int32_t findex, int32_t extraargs);
int32_t get_operation_value(card* pcard, int32_t findex, int32_t extraargs);
int32_t get_function_value(int32_t f, uint32_t param_count);
int32_t get_function_value(int32_t f, uint32_t param_count, std::vector<lua_Integer>& result);
int32_t call_coroutine(int32_t f, uint32_t param_count, int32_t* yield_value, uint16_t step);
int32_t clone_function_ref(int32_t func_ref);
void* get_ref_object(int32_t ref_handler);
static void card2value(lua_State* L, card* pcard);
static void group2value(lua_State* L, group* pgroup);
static void effect2value(lua_State* L, effect* peffect);
static void function2value(lua_State* L, int32 pointer);
static int32 get_function_handle(lua_State* L, int32 index);
static void function2value(lua_State* L, int32_t func_ref);
static int32_t get_function_handle(lua_State* L, int32_t index);
static duel* get_duel_info(lua_State* L);
static bool is_load_script(const card_data& data);
template <size_t N, typename... TR>
static int sprintf(char (&buffer)[N], const char* format, TR... args) {
......@@ -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_YIELD 2
#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 @@
* Author: Argon
*/
#include <string.h>
#include <cstring>
#include "scriptlib.h"
#include "duel.h"
#include "field.h"
......@@ -13,7 +13,8 @@
#include "effect.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);
lua_getglobal(L, "tostring");
lua_pushvalue(L, -2);
......@@ -22,19 +23,19 @@ int32 scriptlib::debug_message(lua_State *L) {
handle_message(pduel, 2);
return 0;
}
int32 scriptlib::debug_add_card(lua_State *L) {
int32_t scriptlib::debug_add_card(lua_State *L) {
check_param_count(L, 6);
duel* pduel = interpreter::get_duel_info(L);
int32 code = (int32)lua_tointeger(L, 1);
int32 owner = (int32)lua_tointeger(L, 2);
int32 playerid = (int32)lua_tointeger(L, 3);
int32 location = (int32)lua_tointeger(L, 4);
int32 sequence = (int32)lua_tointeger(L, 5);
int32 position = (int32)lua_tointeger(L, 6);
int32 proc = lua_toboolean(L, 7);
if(owner != 0 && owner != 1)
int32_t code = (int32_t)lua_tointeger(L, 1);
int32_t owner = (int32_t)lua_tointeger(L, 2);
int32_t playerid = (int32_t)lua_tointeger(L, 3);
int32_t location = (int32_t)lua_tointeger(L, 4);
int32_t sequence = (int32_t)lua_tointeger(L, 5);
int32_t position = (int32_t)lua_tointeger(L, 6);
int32_t proc = lua_toboolean(L, 7);
if (!check_playerid(owner))
return 0;
if(playerid != 0 && playerid != 1)
if (!check_playerid(playerid))
return 0;
if(pduel->game_field->is_location_useable(playerid, location, sequence)) {
card* pcard = pduel->new_card(code);
......@@ -43,7 +44,7 @@ int32 scriptlib::debug_add_card(lua_State *L) {
position = POS_FACEDOWN_DEFENSE;
pcard->sendto_param.position = position;
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);
} else {
pduel->game_field->add_card(playerid, pcard, location, sequence);
......@@ -58,9 +59,11 @@ int32 scriptlib::debug_add_card(lua_State *L) {
interpreter::card2value(L, pcard);
return 1;
} 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);
pcard->owner = owner;
card* fcard = pduel->game_field->get_field_card(playerid, location, sequence);
fcard->xyz_add(pcard);
if(proc)
pcard->set_status(STATUS_PROC_COMPLETE, TRUE);
......@@ -69,13 +72,13 @@ int32 scriptlib::debug_add_card(lua_State *L) {
}
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);
duel* pduel = interpreter::get_duel_info(L);
uint32 playerid = (uint32)lua_tointeger(L, 1);
uint32 lp = (uint32)lua_tointeger(L, 2);
uint32 startcount = (uint32)lua_tointeger(L, 3);
uint32 drawcount = (uint32)lua_tointeger(L, 4);
int32_t playerid = (int32_t)lua_tointeger(L, 1);
int32_t lp = (int32_t)lua_tointeger(L, 2);
int32_t startcount = (int32_t)lua_tointeger(L, 3);
int32_t drawcount = (int32_t)lua_tointeger(L, 4);
if(playerid != 0 && playerid != 1)
return 0;
pduel->game_field->player[playerid].lp = lp;
......@@ -83,18 +86,18 @@ int32 scriptlib::debug_set_player_info(lua_State *L) {
pduel->game_field->player[playerid].draw_count = drawcount;
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(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
uint32 summon_type = (uint32)lua_tointeger(L, 2);
uint8 summon_location = 0;
uint32_t summon_type = (uint32_t)lua_tointeger(L, 2);
uint8_t summon_location = 0;
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);
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(L, PARAM_TYPE_CARD, 1);
check_param(L, PARAM_TYPE_CARD, 2);
......@@ -112,7 +115,7 @@ int32 scriptlib::debug_pre_equip(lua_State *L) {
}
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(L, PARAM_TYPE_CARD, 1);
check_param(L, PARAM_TYPE_CARD, 2);
......@@ -121,30 +124,23 @@ int32 scriptlib::debug_pre_set_target(lua_State *L) {
t_card->add_card_target(target);
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(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
uint32 countertype = (uint32)lua_tointeger(L, 2);
uint32 count = (uint32)lua_tointeger(L, 3);
uint16 cttype = countertype;
auto pr = pcard->counters.emplace(cttype, card::counter_map::mapped_type());
uint32_t countertype = (uint32_t)lua_tointeger(L, 2);
uint16_t count = (uint16_t)lua_tointeger(L, 3);
uint16_t cttype = countertype;
auto pr = pcard->counters.emplace(cttype, 0);
auto cmit = pr.first;
if(pr.second) {
cmit->second[0] = 0;
cmit->second[1] = 0;
}
if(countertype & COUNTER_WITHOUT_PERMIT)
cmit->second[0] += count;
else
cmit->second[1] += count;
cmit->second += count;
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);
duel* pduel = interpreter::get_duel_info(L);
uint32 flag = (uint32)lua_tointeger(L, 1);
int32 rule = (int32)lua_tointeger(L, 2);
uint32_t flag = (uint32_t)lua_tointeger(L, 1);
int32_t rule = (int32_t)lua_tointeger(L, 2);
pduel->clear();
pduel->game_field->core.duel_options |= flag;
if (rule)
......@@ -152,10 +148,10 @@ int32 scriptlib::debug_reload_field_begin(lua_State *L) {
else if (flag & DUEL_OBSOLETE_RULING)
pduel->game_field->core.duel_rule = 1;
else
pduel->game_field->core.duel_rule = 5;
pduel->game_field->core.duel_rule = CURRENT_RULE;
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);
pduel->game_field->core.shuffle_hand_check[0] = FALSE;
pduel->game_field->core.shuffle_hand_check[1] = FALSE;
......@@ -164,35 +160,31 @@ int32 scriptlib::debug_reload_field_end(lua_State *L) {
pduel->game_field->reload_field_info();
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(L, PARAM_TYPE_STRING, 1);
duel* pduel = interpreter::get_duel_info(L);
pduel->write_buffer8(MSG_AI_NAME);
const char* pstr = lua_tostring(L, 1);
int len = (int)strlen(pstr);
if(len > 100)
len = 100;
int len = (int)std::strlen(pstr);
if(len > SIZE_AI_NAME -1)
len = SIZE_AI_NAME - 1;
pduel->write_buffer16(len);
memcpy(pduel->bufferp, pstr, len);
pduel->bufferp += len;
pduel->bufferlen += len;
pduel->write_buffer(pstr, len);
pduel->write_buffer8(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(L, PARAM_TYPE_STRING, 1);
duel* pduel = interpreter::get_duel_info(L);
pduel->write_buffer8(MSG_SHOW_HINT);
const char* pstr = lua_tostring(L, 1);
int len = (int)strlen(pstr);
if(len > 1024)
len = 1024;
int len = (int)std::strlen(pstr);
if (len > SIZE_HINT_MSG - 1)
len = SIZE_HINT_MSG - 1;
pduel->write_buffer16(len);
memcpy(pduel->bufferp, pstr, len);
pduel->bufferp += len;
pduel->bufferlen += len;
pduel->write_buffer(pstr, len);
pduel->write_buffer8(0);
return 0;
}
......@@ -209,7 +201,7 @@ static const struct luaL_Reg debuglib[] = {
{ "ReloadFieldEnd", scriptlib::debug_reload_field_end },
{ "SetAIName", scriptlib::debug_set_ai_name },
{ "ShowHint", scriptlib::debug_show_hint },
{ NULL, NULL }
{ nullptr, nullptr }
};
void scriptlib::open_debuglib(lua_State *L) {
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 @@
#include "effect.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(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
......@@ -23,7 +78,7 @@ int32 scriptlib::effect_new(lua_State *L) {
interpreter::effect2value(L, peffect);
return 1;
}
int32 scriptlib::effect_newex(lua_State *L) {
int32_t scriptlib::effect_newex(lua_State *L) {
duel* pduel = interpreter::get_duel_info(L);
effect* peffect = pduel->new_effect();
peffect->effect_owner = 0;
......@@ -31,7 +86,7 @@ int32 scriptlib::effect_newex(lua_State *L) {
interpreter::effect2value(L, peffect);
return 1;
}
int32 scriptlib::effect_clone(lua_State *L) {
int32_t scriptlib::effect_clone(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
......@@ -39,7 +94,7 @@ int32 scriptlib::effect_clone(lua_State *L) {
interpreter::effect2value(L, ceffect);
return 1;
}
int32 scriptlib::effect_reset(lua_State *L) {
int32_t scriptlib::effect_reset(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
......@@ -51,55 +106,51 @@ int32 scriptlib::effect_reset(lua_State *L) {
peffect->handler->remove_effect(peffect);
return 0;
}
int32 scriptlib::effect_get_field_id(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
lua_pushinteger(L, peffect->id);
return 1;
int32_t scriptlib::effect_get_field_id(lua_State *L) {
return get_effect_property(L, MEMBER_ID);
}
int32 scriptlib::effect_set_description(lua_State *L) {
int32_t scriptlib::effect_set_description(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 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;
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(L, PARAM_TYPE_EFFECT, 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;
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(L, PARAM_TYPE_EFFECT, 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;
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 s = (uint32)lua_tointeger(L, 2);
uint32 o = (uint32)lua_tointeger(L, 3);
uint32_t s = (uint32_t)lua_tointeger(L, 2);
uint32_t o = (uint32_t)lua_tointeger(L, 3);
peffect->s_range = s;
peffect->o_range = o;
peffect->flag[0] &= ~EFFECT_FLAG_ABSOLUTE_TARGET;
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 playerid = (uint32)lua_tointeger(L, 2);
uint32 s = (uint32)lua_tointeger(L, 3);
uint32 o = (uint32)lua_tointeger(L, 4);
int32_t playerid = (int32_t)lua_tointeger(L, 2);
uint32_t s = (uint32_t)lua_tointeger(L, 3);
uint32_t o = (uint32_t)lua_tointeger(L, 4);
if(playerid == 0) {
peffect->s_range = s;
peffect->o_range = o;
......@@ -110,28 +161,30 @@ int32 scriptlib::effect_set_absolute_range(lua_State *L) {
peffect->flag[0] |= EFFECT_FLAG_ABSOLUTE_TARGET;
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 v = (uint32)lua_tointeger(L, 2);
uint32 code = 0;
uint32_t v = (uint32_t)lua_tointeger(L, 2);
uint32_t code = 0;
if(lua_gettop(L) >= 3)
code = (uint32)lua_tointeger(L, 3);
code = (uint32_t)lua_tointeger(L, 3);
if(v == 0)
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->count_limit = v;
peffect->count_limit_max = v;
peffect->count_code = code;
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 v = (uint32)lua_tointeger(L, 2);
uint32 c = (uint32)lua_tointeger(L, 3);
uint32_t v = (uint32_t)lua_tointeger(L, 2);
int32_t c = (int32_t)lua_tointeger(L, 3);
if(c == 0)
c = 1;
if(v & (RESET_PHASE) && !(v & (RESET_SELF_TURN | RESET_OPPO_TURN)))
......@@ -140,90 +193,101 @@ int32 scriptlib::effect_set_reset(lua_State *L) {
peffect->reset_count = c;
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 v = (uint32)lua_tointeger(L, 2);
if (v & 0x0ff0)
v |= EFFECT_TYPE_ACTIONS;
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)
uint32_t v = (uint32_t)lua_tointeger(L, 2);
if (v & EFFECT_TYPE_ACTIVATE) {
v = EFFECT_TYPE_FIELD | EFFECT_TYPE_ACTIVATE;
peffect->range = LOCATION_SZONE + LOCATION_FZONE + LOCATION_HAND;
if(v & EFFECT_TYPE_FLIP) {
}
else if(v & EFFECT_TYPE_FLIP) {
peffect->code = EVENT_FLIP;
if(!(v & EFFECT_TYPE_TRIGGER_O))
v |= EFFECT_TYPE_TRIGGER_F;
if (v & EFFECT_TYPE_TRIGGER_O) {
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;
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 v1 = (uint32)lua_tointeger(L, 2);
uint32 v2 = (uint32)lua_tointeger(L, 3);
peffect->flag[0] = (peffect->flag[0] & 0x4f) | (v1 & ~0x4f);
uint64_t v1 = lua_tointeger(L, 2);
uint64_t v2 = lua_tointeger(L, 3);
peffect->flag[0] = (peffect->flag[0] & INTERNAL_FLAGS) | (v1 & ~INTERNAL_FLAGS);
peffect->flag[1] = v2;
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
peffect->label.clear();
for(int32 i = 2; i <= lua_gettop(L); ++i) {
uint32 v = (uint32)lua_tointeger(L, i);
peffect->label.push_back(v);
for(int32_t i = 2; i <= lua_gettop(L); ++i) {
peffect->label.push_back(lua_tointeger(L, i));
}
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
if(lua_isnil(L, 2)) {
peffect->label_object = 0;
peffect->object_type = PARAM_TYPE_INT;
return 0;
}
if(check_param(L, PARAM_TYPE_CARD, 2, TRUE)) {
card* p = *(card**)lua_touserdata(L, 2);
peffect->label_object = p->ref_handle;
peffect->object_type = PARAM_TYPE_CARD;
} else if(check_param(L, PARAM_TYPE_EFFECT, 2, TRUE)) {
effect* p = *(effect**)lua_touserdata(L, 2);
peffect->label_object = p->ref_handle;
peffect->object_type = PARAM_TYPE_EFFECT;
} else if(check_param(L, PARAM_TYPE_GROUP, 2, TRUE)) {
group* p = *(group**)lua_touserdata(L, 2);
peffect->label_object = p->ref_handle;
peffect->object_type = PARAM_TYPE_GROUP;
} else
return luaL_error(L, "Parameter 2 should be \"Card\" or \"Effect\" or \"Group\".");
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(L, PARAM_TYPE_EFFECT, 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;
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 vs = (uint32)lua_tointeger(L, 2);
uint32 vo = vs;
uint32_t vs = (uint32_t)lua_tointeger(L, 2);
uint32_t vo = vs;
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[1] = vo;
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(L, PARAM_TYPE_EFFECT, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
......@@ -233,7 +297,7 @@ int32 scriptlib::effect_set_condition(lua_State *L) {
peffect->condition = interpreter::get_function_handle(L, 2);
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(L, PARAM_TYPE_EFFECT, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
......@@ -243,7 +307,7 @@ int32 scriptlib::effect_set_target(lua_State *L) {
peffect->target = interpreter::get_function_handle(L, 2);
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(L, PARAM_TYPE_EFFECT, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
......@@ -253,7 +317,7 @@ int32 scriptlib::effect_set_cost(lua_State *L) {
peffect->cost = interpreter::get_function_handle(L, 2);
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
......@@ -267,13 +331,13 @@ int32 scriptlib::effect_set_value(lua_State *L) {
if(lua_isboolean(L, 2))
peffect->value = lua_toboolean(L, 2);
else if(lua_isinteger(L, 2))
peffect->value = (int32)lua_tointeger(L, 2);
peffect->value = (int32_t)lua_tointeger(L, 2);
else
peffect->value = (int32)lua_tonumber(L, 2);
peffect->value = (int32_t)lua_tonumber(L, 2);
}
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
......@@ -286,47 +350,26 @@ int32 scriptlib::effect_set_operation(lua_State *L) {
peffect->operation = 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(L, PARAM_TYPE_EFFECT, 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)
return 0;
peffect->effect_owner = p;
return 0;
}
int32 scriptlib::effect_get_description(lua_State *L) {
check_param_count(L, 1);
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_t scriptlib::effect_get_description(lua_State *L) {
return get_effect_property(L, MEMBER_DESCRIPTION);
}
int32 scriptlib::effect_get_code(lua_State *L) {
check_param_count(L, 1);
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_t scriptlib::effect_get_code(lua_State *L) {
return get_effect_property(L, MEMBER_CODE);
}
int32 scriptlib::effect_get_type(lua_State *L) {
check_param_count(L, 1);
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_t scriptlib::effect_get_type(lua_State *L) {
return get_effect_property(L, MEMBER_TYPE);
}
int32 scriptlib::effect_get_property(lua_State *L) {
int32_t scriptlib::effect_get_property(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
......@@ -337,7 +380,7 @@ int32 scriptlib::effect_get_property(lua_State *L) {
}
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
......@@ -348,11 +391,11 @@ int32 scriptlib::effect_get_label(lua_State *L) {
}
for(const auto& lab : peffect->label)
lua_pushinteger(L, lab);
return (int32)peffect->label.size();
return (int32_t)peffect->label.size();
}
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
......@@ -369,141 +412,124 @@ int32 scriptlib::effect_get_label_object(lua_State *L) {
return 1;
}
}
int32 scriptlib::effect_get_category(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
if (peffect) {
lua_pushinteger(L, peffect->category);
return 1;
}
return 0;
int32_t scriptlib::effect_get_category(lua_State *L) {
return get_effect_property(L, MEMBER_CATEGORY);
}
int32_t scriptlib::effect_get_range(lua_State* L) {
return get_effect_property(L, MEMBER_RANGE);
}
int32 scriptlib::effect_get_owner(lua_State *L) {
int32_t scriptlib::effect_get_owner(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
interpreter::card2value(L, peffect->get_owner());
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
interpreter::card2value(L, peffect->get_handler());
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
lua_pushinteger(L, peffect->get_owner_player());
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
lua_pushinteger(L, peffect->get_handler_player());
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
interpreter::function2value(L, peffect->condition);
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
interpreter::function2value(L, peffect->target);
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
interpreter::function2value(L, peffect->cost);
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
if(peffect->is_flag(EFFECT_FLAG_FUNC_VALUE))
interpreter::function2value(L, peffect->value);
else
lua_pushinteger(L, (int32)peffect->value);
lua_pushinteger(L, (int32_t)peffect->value);
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
interpreter::function2value(L, peffect->operation);
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
lua_pushinteger(L, peffect->get_active_type());
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(L, PARAM_TYPE_EFFECT, 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)
lua_pushboolean(L, 1);
else
lua_pushboolean(L, 0);
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 tflag1 = (uint32)lua_tointeger(L, 2);
uint32 tflag2 = (uint32)lua_tointeger(L, 3);
uint64_t tflag1 = lua_tointeger(L, 2);
uint64_t tflag2 = lua_tointeger(L, 3);
if (peffect && (!tflag1 || (peffect->flag[0] & tflag1)) && (!tflag2 || (peffect->flag[1] & tflag2)))
lua_pushboolean(L, 1);
else
lua_pushboolean(L, 0);
return 1;
}
int32 scriptlib::effect_is_has_category(lua_State *L) {
check_param_count(L, 2);
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_t scriptlib::effect_is_has_category(lua_State *L) {
return is_effect_has_property(L, MEMBER_CATEGORY);
}
int32 scriptlib::effect_is_has_type(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 ttype = (uint32)lua_tointeger(L, 2);
if (peffect && (peffect->type & ttype))
lua_pushboolean(L, 1);
else
lua_pushboolean(L, 0);
return 1;
int32_t scriptlib::effect_is_has_type(lua_State *L) {
return is_effect_has_property(L, MEMBER_TYPE);
}
int32_t scriptlib::effect_is_has_range(lua_State* L) {
return is_effect_has_property(L, MEMBER_RANGE);
}
int32 scriptlib::effect_is_activatable(lua_State *L) {
int32_t scriptlib::effect_is_activatable(lua_State *L) {
check_param_count(L, 2);
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);
uint32 neglect_loc = 0;
uint32 neglect_target = 0;
uint32_t neglect_loc = 0;
uint32_t neglect_target = 0;
if(lua_gettop(L) > 2) {
neglect_loc = lua_toboolean(L, 3);
if (lua_gettop(L) > 3)
......@@ -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));
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(L, PARAM_TYPE_EFFECT, 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;
}
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**)lua_touserdata(L, 1);
lua_pushboolean(L, peffect->cost_checked);
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(L, PARAM_TYPE_EFFECT, 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;
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
lua_pushinteger(L, peffect->active_location);
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
lua_pushinteger(L, peffect->active_sequence);
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(L, PARAM_TYPE_EFFECT, 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));
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(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 p = (uint32)lua_tointeger(L, 2);
uint32 count = 1;
uint32 oath_only = 0;
uint32 code = peffect->count_code;
int32_t p = (int32_t)lua_tointeger(L, 2);
int32_t count = 1;
int32_t oath_only = 0;
uint32_t code = peffect->count_code;
if(lua_gettop(L) > 2) {
count = (uint32)lua_tointeger(L, 3);
count = (int32_t)lua_tointeger(L, 3);
if (lua_gettop(L) > 3)
oath_only = lua_toboolean(L, 4);
}
if (!oath_only || code & EFFECT_COUNT_CODE_OATH)
while(count) {
peffect->dec_count(p);
count--;
--count;
}
return 0;
}
......@@ -609,6 +635,7 @@ static const struct luaL_Reg effectlib[] = {
{ "GetLabel", scriptlib::effect_get_label },
{ "GetLabelObject", scriptlib::effect_get_label_object },
{ "GetCategory", scriptlib::effect_get_category },
{ "GetRange", scriptlib::effect_get_range },
{ "GetOwner", scriptlib::effect_get_owner },
{ "GetHandler", scriptlib::effect_get_handler },
{ "GetCondition", scriptlib::effect_get_condition },
......@@ -623,6 +650,7 @@ static const struct luaL_Reg effectlib[] = {
{ "IsHasProperty", scriptlib::effect_is_has_property },
{ "IsHasCategory", scriptlib::effect_is_has_category },
{ "IsHasType", scriptlib::effect_is_has_type },
{ "IsHasRange", scriptlib::effect_is_has_range },
{ "IsActivatable", scriptlib::effect_is_activatable },
{ "IsActivated", scriptlib::effect_is_activated },
{ "IsCostChecked", scriptlib::effect_is_cost_checked },
......@@ -631,7 +659,7 @@ static const struct luaL_Reg effectlib[] = {
{ "GetActivateSequence", scriptlib::effect_get_activate_sequence },
{ "CheckCountLimit", scriptlib::effect_check_count_limit },
{ "UseCountLimit", scriptlib::effect_use_count_limit },
{ NULL, NULL }
{ nullptr, nullptr }
};
void scriptlib::open_effectlib(lua_State *L) {
luaL_newlib(L, effectlib);
......
......@@ -11,13 +11,13 @@
#include "effect.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);
group* pgroup = pduel->new_group();
interpreter::group2value(L, pgroup);
return 1;
}
int32 scriptlib::group_clone(lua_State *L) {
int32_t scriptlib::group_clone(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_GROUP, 1);
group* pgroup = *(group**) lua_touserdata(L, 1);
......@@ -26,10 +26,10 @@ int32 scriptlib::group_clone(lua_State *L) {
interpreter::group2value(L, newgroup);
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);
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)) {
check_param(L, PARAM_TYPE_CARD, i + 1);
card* pcard = *(card**) lua_touserdata(L, i + 1);
......@@ -39,63 +39,70 @@ int32 scriptlib::group_from_cards(lua_State *L) {
interpreter::group2value(L, pgroup);
return 1;
}
int32 scriptlib::group_delete(lua_State *L) {
int32_t scriptlib::group_delete(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_GROUP, 1);
duel* pduel = interpreter::get_duel_info(L);
group* pgroup = *(group**) lua_touserdata(L, 1);
if(pgroup->is_readonly != 2)
if(pgroup->is_readonly != GTYPE_KEEP_ALIVE)
return 0;
pgroup->is_readonly = 0;
pgroup->is_iterator_dirty = true;
pgroup->is_readonly = GTYPE_DEFAULT;
pduel->sgroups.insert(pgroup);
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(L, PARAM_TYPE_GROUP, 1);
duel* pduel = interpreter::get_duel_info(L);
group* pgroup = *(group**) lua_touserdata(L, 1);
if(pgroup->is_readonly == 1)
if(pgroup->is_readonly == GTYPE_READ_ONLY)
return 0;
pgroup->is_readonly = 2;
pgroup->is_readonly = GTYPE_KEEP_ALIVE;
pduel->sgroups.erase(pgroup);
return 0;
}
int32 scriptlib::group_clear(lua_State *L) {
int32_t scriptlib::group_clear(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_GROUP, 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();
}
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(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_CARD, 2);
group* pgroup = *(group**) lua_touserdata(L, 1);
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);
}
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(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_CARD, 2);
group* pgroup = *(group**) lua_touserdata(L, 1);
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);
}
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(L, PARAM_TYPE_GROUP, 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())
lua_pushnil(L);
else {
......@@ -107,10 +114,11 @@ int32 scriptlib::group_get_next(lua_State *L) {
}
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(L, PARAM_TYPE_GROUP, 1);
group* pgroup = *(group**) lua_touserdata(L, 1);
pgroup->is_iterator_dirty = false;
if (pgroup->container.size()) {
pgroup->it = pgroup->container.begin();
interpreter::card2value(L, (*(pgroup->it)));
......@@ -118,35 +126,19 @@ int32 scriptlib::group_get_first(lua_State *L) {
lua_pushnil(L);
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(L, PARAM_TYPE_GROUP, 1);
group* pgroup = *(group**) lua_touserdata(L, 1);
lua_pushinteger(L, pgroup->container.size());
return 1;
}
int32 scriptlib::group_for_each(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) {
int32_t scriptlib::group_filter(lua_State *L) {
check_param_count(L, 3);
check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
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)) {
card* pexception = *(card**) lua_touserdata(L, 3);
cset.erase(pexception);
......@@ -157,21 +149,21 @@ int32 scriptlib::group_filter(lua_State *L) {
}
duel* pduel = pgroup->pduel;
group* new_group = pduel->new_group();
uint32 extraargs = lua_gettop(L) - 3;
uint32_t extraargs = lua_gettop(L) - 3;
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);
}
}
interpreter::group2value(L, new_group);
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(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
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)) {
card* pexception = *(card**) lua_touserdata(L, 3);
cset.erase(pexception);
......@@ -181,22 +173,22 @@ int32 scriptlib::group_filter_count(lua_State *L) {
cset.erase(pcard);
}
duel* pduel = pgroup->pduel;
uint32 extraargs = lua_gettop(L) - 3;
uint32 count = 0;
uint32_t extraargs = lua_gettop(L) - 3;
uint32_t count = 0;
for (auto& pcard : cset) {
if(pduel->lua->check_matching(pcard, 2, extraargs))
count++;
if(pduel->lua->check_filter(L, pcard, 2, extraargs))
++count;
}
lua_pushinteger(L, count);
return 1;
}
int32 scriptlib::group_filter_select(lua_State *L) {
int32_t scriptlib::group_filter_select(lua_State *L) {
check_action_permission(L);
check_param_count(L, 6);
check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 3);
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)) {
card* pexception = *(card**) lua_touserdata(L, 6);
cset.erase(pexception);
......@@ -206,22 +198,22 @@ int32 scriptlib::group_filter_select(lua_State *L) {
cset.erase(pcard);
}
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)
return 0;
uint32 min = (uint32)lua_tointeger(L, 4);
uint32 max = (uint32)lua_tointeger(L, 5);
uint32 extraargs = lua_gettop(L) - 6;
uint32_t min = (uint32_t)lua_tointeger(L, 4);
uint32_t max = (uint32_t)lua_tointeger(L, 5);
uint32_t extraargs = lua_gettop(L) - 6;
pduel->game_field->core.select_cards.clear();
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->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;
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]];
pgroup->container.insert(pcard);
}
......@@ -229,12 +221,12 @@ int32 scriptlib::group_filter_select(lua_State *L) {
return 1;
});
}
int32 scriptlib::group_select(lua_State *L) {
int32_t scriptlib::group_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);
field::card_set cset(pgroup->container);
card_set cset(pgroup->container);
if(check_param(L, PARAM_TYPE_CARD, 5, TRUE)) {
card* pexception = *(card**) lua_touserdata(L, 5);
cset.erase(pexception);
......@@ -244,20 +236,20 @@ int32 scriptlib::group_select(lua_State *L) {
cset.erase(pcard);
}
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)
return 0;
uint32 min = (uint32)lua_tointeger(L, 3);
uint32 max = (uint32)lua_tointeger(L, 4);
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, 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;
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]];
pgroup->container.insert(pcard);
}
......@@ -265,16 +257,16 @@ int32 scriptlib::group_select(lua_State *L) {
return 1;
});
}
int32 scriptlib::group_select_unselect(lua_State *L) {
int32_t scriptlib::group_select_unselect(lua_State *L) {
check_action_permission(L);
check_param_count(L, 3);
check_param(L, PARAM_TYPE_GROUP, 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))
unselect_group = *(group**)lua_touserdata(L, 2);
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)
return 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) {
}
}
}
uint32 finishable = FALSE;
uint32_t finishable = FALSE;
if(lua_gettop(L) > 3) {
finishable = lua_toboolean(L, 4);
}
uint32 cancelable = FALSE;
uint32_t cancelable = FALSE;
if(lua_gettop(L) > 4) {
cancelable = lua_toboolean(L, 5);
}
uint32 min = 1;
uint32_t min = 1;
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) {
max = (uint32)lua_tointeger(L, 7);
max = (uint32_t)lua_tointeger(L, 7);
}
if(min > max)
min = max;
......@@ -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);
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;
if(pduel->game_field->returns.bvalue[0] == -1) {
if(pduel->game_field->returns.ivalue[0] == -1) {
lua_pushnil(L);
} else {
card* pcard;
if((size_t)pduel->game_field->returns.bvalue[1] < pduel->game_field->core.select_cards.size())
pcard = pduel->game_field->core.select_cards[pduel->game_field->returns.bvalue[1]];
const int32_t index = 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
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);
}
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(L, PARAM_TYPE_GROUP, 1);
group* pgroup = *(group**) lua_touserdata(L, 1);
int32 playerid = (int32)lua_tointeger(L, 2);
uint32 count = (uint32)lua_tointeger(L, 3);
int32_t playerid = (int32_t)lua_tointeger(L, 2);
uint32_t count = (uint32_t)lua_tointeger(L, 3);
duel* pduel = pgroup->pduel;
group* newgroup = pduel->new_group();
if(count > pgroup->container.size())
count = (uint32)pgroup->container.size();
count = (uint32_t)pgroup->container.size();
if(count == 0) {
interpreter::group2value(L, newgroup);
return 1;
......@@ -351,7 +344,7 @@ int32 scriptlib::group_random_select(lua_State *L) {
newgroup->container = pgroup->container;
else {
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();
std::advance(cit, i);
newgroup->container.insert(*cit);
......@@ -366,12 +359,52 @@ int32 scriptlib::group_random_select(lua_State *L) {
interpreter::group2value(L, newgroup);
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(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
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)) {
card* pexception = *(card**) lua_touserdata(L, 4);
cset.erase(pexception);
......@@ -381,13 +414,17 @@ int32 scriptlib::group_is_exists(lua_State *L) {
cset.erase(pcard);
}
duel* pduel = pgroup->pduel;
uint32 count = (uint32)lua_tointeger(L, 3);
uint32 extraargs = lua_gettop(L) - 4;
uint32 fcount = 0;
uint32 result = FALSE;
uint32_t count = (uint32_t)lua_tointeger(L, 3);
uint32_t extraargs = lua_gettop(L) - 4;
uint32_t fcount = 0;
uint32_t result = FALSE;
if (count > pgroup->container.size()) {
lua_pushboolean(L, 0);
return 1;
}
for (auto& pcard : cset) {
if(pduel->lua->check_matching(pcard, 2, extraargs)) {
fcount++;
if(pduel->lua->check_filter(L, pcard, 2, extraargs)) {
++fcount;
if(fcount >= count) {
result = TRUE;
break;
......@@ -397,22 +434,22 @@ int32 scriptlib::group_is_exists(lua_State *L) {
lua_pushboolean(L, result);
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(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel;
int32 acc = (int32)lua_tointeger(L, 3);
int32 min = (int32)lua_tointeger(L, 4);
int32 max = (int32)lua_tointeger(L, 5);
int32_t acc = (int32_t)lua_tointeger(L, 3);
int32_t min = (int32_t)lua_tointeger(L, 4);
int32_t max = (int32_t)lua_tointeger(L, 5);
if(min < 0)
min = 0;
if(max < min)
max = min;
int32 extraargs = lua_gettop(L) - 5;
field::card_vector cv(pduel->game_field->core.must_select_cards);
int32 mcount = (int32)cv.size();
int32_t extraargs = lua_gettop(L) - 5;
card_vector cv(pduel->game_field->core.must_select_cards);
int32_t mcount = (int32_t)cv.size();
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);
if(it == pduel->game_field->core.must_select_cards.end())
......@@ -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));
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_param_count(L, 6);
check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 3);
group* pgroup = *(group**) lua_touserdata(L, 1);
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)
return 0;
int32 acc = (int32)lua_tointeger(L, 4);
int32 min = (int32)lua_tointeger(L, 5);
int32 max = (int32)lua_tointeger(L, 6);
int32_t acc = (int32_t)lua_tointeger(L, 4);
int32_t min = (int32_t)lua_tointeger(L, 5);
int32_t max = (int32_t)lua_tointeger(L, 6);
if(min < 0)
min = 0;
if(max < min)
max = min;
if(max > 127)
return luaL_error(L, "Parameter \"max\" exceeded 127.");
int32 extraargs = lua_gettop(L) - 6;
if(max > UINT8_MAX)
return luaL_error(L, "Parameter \"max\" exceeded 255.");
int32_t extraargs = lua_gettop(L) - 6;
pduel->game_field->core.select_cards.assign(pgroup->container.begin(), pgroup->container.end());
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);
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);
int32 mcount = (int32)cv.size();
card_vector cv(pduel->game_field->core.must_select_cards);
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());
for(auto& pcard : cv)
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) {
interpreter::group2value(L, empty_group);
return 1;
}
pduel->game_field->add_process(PROCESSOR_SELECT_SUM, 0, 0, 0, acc, playerid + (min << 16) + (max << 24));
return lua_yieldk(L, 0, (lua_KContext)pduel, [](lua_State *L, int32 status, lua_KContext ctx) {
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_t status, lua_KContext ctx) {
duel* pduel = (duel*)ctx;
group* pgroup = pduel->new_group();
int32 mcount = (int32)pduel->game_field->core.must_select_cards.size();
for(int32 i = mcount; i < pduel->game_field->returns.bvalue[0]; ++i) {
int32_t mcount = (int32_t)pduel->game_field->core.must_select_cards.size();
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]];
pgroup->container.insert(pcard);
}
......@@ -474,16 +511,16 @@ int32 scriptlib::group_select_with_sum_equal(lua_State *L) {
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(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel;
int32 acc = (int32)lua_tointeger(L, 3);
int32 extraargs = lua_gettop(L) - 3;
field::card_vector cv(pduel->game_field->core.must_select_cards);
int32 mcount = (int32)cv.size();
int32_t acc = (int32_t)lua_tointeger(L, 3);
int32_t extraargs = lua_gettop(L) - 3;
card_vector cv(pduel->game_field->core.must_select_cards);
int32_t mcount = (int32_t)cv.size();
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);
if(it == pduel->game_field->core.must_select_cards.end())
......@@ -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));
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_param_count(L, 4);
check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 3);
group* pgroup = *(group**) lua_touserdata(L, 1);
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)
return 0;
int32 acc = (int32)lua_tointeger(L, 4);
int32 extraargs = lua_gettop(L) - 4;
int32_t acc = (int32_t)lua_tointeger(L, 4);
int32_t extraargs = lua_gettop(L) - 4;
pduel->game_field->core.select_cards.assign(pgroup->container.begin(), pgroup->container.end());
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);
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);
int32 mcount = (int32)cv.size();
card_vector cv(pduel->game_field->core.must_select_cards);
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());
for(auto& pcard : cv)
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) {
return 1;
}
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;
group* pgroup = pduel->new_group();
int32 mcount = (int32)pduel->game_field->core.must_select_cards.size();
for(int32 i = mcount; i < pduel->game_field->returns.bvalue[0]; ++i) {
int32_t mcount = (int32_t)pduel->game_field->core.must_select_cards.size();
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]];
pgroup->container.insert(pcard);
}
......@@ -537,7 +574,7 @@ int32 scriptlib::group_select_with_sum_greater(lua_State *L) {
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(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
......@@ -546,8 +583,8 @@ int32 scriptlib::group_get_min_group(lua_State *L) {
if(pgroup->container.size() == 0)
return 0;
group* newgroup = pduel->new_group();
int32 min, op;
int32 extraargs = lua_gettop(L) - 2;
int32_t min, op;
int32_t extraargs = lua_gettop(L) - 2;
auto cit = pgroup->container.begin();
min = pduel->lua->get_operation_value(*cit, 2, extraargs);
newgroup->container.insert(*cit);
......@@ -566,7 +603,7 @@ int32 scriptlib::group_get_min_group(lua_State *L) {
lua_pushinteger(L, min);
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(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
......@@ -575,8 +612,8 @@ int32 scriptlib::group_get_max_group(lua_State *L) {
if(pgroup->container.size() == 0)
return 0;
group* newgroup = pduel->new_group();
int32 max, op;
int32 extraargs = lua_gettop(L) - 2;
int32_t max, op;
int32_t extraargs = lua_gettop(L) - 2;
auto cit = pgroup->container.begin();
max = pduel->lua->get_operation_value(*cit, 2, extraargs);
newgroup->container.insert(*cit);
......@@ -595,81 +632,85 @@ int32 scriptlib::group_get_max_group(lua_State *L) {
lua_pushinteger(L, max);
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(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel;
int32 extraargs = lua_gettop(L) - 2;
int32 sum = 0;
int32_t extraargs = lua_gettop(L) - 2;
int32_t sum = 0;
for(auto& pcard : pgroup->container) {
sum += pduel->lua->get_operation_value(pcard, 2, extraargs);
}
lua_pushinteger(L, sum);
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(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel;
int32 extraargs = lua_gettop(L) - 2;
std::set<uint32> er;
int32_t extraargs = lua_gettop(L) - 2;
std::set<uint32_t> er;
for(auto& pcard : pgroup->container) {
er.insert(pduel->lua->get_operation_value(pcard, 2, extraargs));
}
lua_pushinteger(L, er.size());
return 1;
}
int32 scriptlib::group_remove(lua_State *L) {
int32_t scriptlib::group_remove(lua_State *L) {
check_param_count(L, 3);
check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
card* pexception = 0;
card* pexception = nullptr;
if(!lua_isnil(L, 3)) {
check_param(L, PARAM_TYPE_CARD, 3);
pexception = *(card**) lua_touserdata(L, 3);
}
group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel;
uint32 extraargs = lua_gettop(L) - 3;
if(pgroup->is_readonly == 1)
uint32_t extraargs = lua_gettop(L) - 3;
if(pgroup->is_readonly == GTYPE_READ_ONLY)
return 0;
pgroup->is_iterator_dirty = true;
for (auto cit = pgroup->container.begin(); cit != pgroup->container.end();) {
auto rm = cit++;
if((*rm) != pexception && pduel->lua->check_matching(*rm, 2, extraargs)) {
pgroup->container.erase(rm);
if((*cit) != pexception && pduel->lua->check_filter(L, *cit, 2, extraargs)) {
cit = pgroup->container.erase(cit);
}
else
++cit;
}
return 0;
}
int32 scriptlib::group_merge(lua_State *L) {
int32_t scriptlib::group_merge(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_GROUP, 2);
group* pgroup = *(group**) lua_touserdata(L, 1);
group* mgroup = *(group**) lua_touserdata(L, 2);
if(pgroup->is_readonly == 1)
if(pgroup->is_readonly == GTYPE_READ_ONLY)
return 0;
pgroup->is_iterator_dirty = true;
pgroup->container.insert(mgroup->container.begin(), mgroup->container.end());
return 0;
}
int32 scriptlib::group_sub(lua_State *L) {
int32_t scriptlib::group_sub(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_GROUP, 2);
group* pgroup = *(group**) lua_touserdata(L, 1);
group* sgroup = *(group**) lua_touserdata(L, 2);
if(pgroup->is_readonly == 1)
if(pgroup->is_readonly == GTYPE_READ_ONLY)
return 0;
pgroup->is_iterator_dirty = true;
for (auto& pcard : sgroup->container) {
pgroup->container.erase(pcard);
}
return 0;
}
int32 scriptlib::group_equal(lua_State *L) {
int32_t scriptlib::group_equal(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_GROUP, 2);
......@@ -690,7 +731,7 @@ int32 scriptlib::group_equal(lua_State *L) {
lua_pushboolean(L, 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(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_CARD, 2);
......@@ -702,40 +743,41 @@ int32 scriptlib::group_is_contains(lua_State *L) {
lua_pushboolean(L, 0);
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(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel;
uint32 extraargs = lua_gettop(L) - 2;
for(auto& pcard : pgroup->container)
if(pduel->lua->check_matching(pcard, 2, extraargs)) {
uint32_t extraargs = lua_gettop(L) - 2;
for (auto& pcard : pgroup->container) {
if (pduel->lua->check_filter(L, pcard, 2, extraargs)) {
interpreter::card2value(L, pcard);
return 1;
}
}
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(L, PARAM_TYPE_GROUP, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
group* pgroup = *(group**) lua_touserdata(L, 1);
duel* pduel = pgroup->pduel;
int32 extraargs = lua_gettop(L) - 2;
int32 er = 0;
int32_t extraargs = lua_gettop(L) - 2;
int32_t er = 0;
for(auto& pcard : pgroup->container) {
er |= pduel->lua->get_operation_value(pcard, 2, extraargs);
}
int32 ans = 0;
int32_t ans = 0;
while(er) {
er &= er - 1;
ans++;
++ans;
}
lua_pushinteger(L, ans);
return 1;
}
int32 scriptlib::group_meta_add(lua_State* L) {
int32_t scriptlib::group_meta_add(lua_State* L) {
check_param_count(L, 2);
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);
......@@ -762,7 +804,7 @@ int32 scriptlib::group_meta_add(lua_State* L) {
interpreter::group2value(L, pgroup);
return 1;
}
int32 scriptlib::group_meta_sub(lua_State* L) {
int32_t scriptlib::group_meta_sub(lua_State* L) {
check_param_count(L, 2);
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);
......@@ -789,7 +831,7 @@ int32 scriptlib::group_meta_sub(lua_State* L) {
interpreter::group2value(L, pgroup);
return 1;
}
int32 scriptlib::group_meta_band(lua_State* L) {
int32_t scriptlib::group_meta_band(lua_State* L) {
check_param_count(L, 2);
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);
......@@ -797,7 +839,7 @@ int32 scriptlib::group_meta_band(lua_State* L) {
return luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 2);
duel* pduel = interpreter::get_duel_info(L);
group* pgroup = pduel->new_group();
field::card_set check_set;
card_set check_set;
if(check_param(L, PARAM_TYPE_CARD, 1, TRUE)) {
card* ccard = *(card**) lua_touserdata(L, 1);
check_set.insert(ccard);
......@@ -818,7 +860,7 @@ int32 scriptlib::group_meta_band(lua_State* L) {
interpreter::group2value(L, pgroup);
return 1;
}
int32 scriptlib::group_meta_bxor(lua_State* L) {
int32_t scriptlib::group_meta_bxor(lua_State* L) {
check_param_count(L, 2);
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);
......@@ -866,13 +908,13 @@ static const struct luaL_Reg grouplib[] = {
{ "GetFirst", scriptlib::group_get_first },
{ "GetCount", scriptlib::group_get_count },
{ "__len", scriptlib::group_get_count },
{ "ForEach", scriptlib::group_for_each },
{ "Filter", scriptlib::group_filter },
{ "FilterCount", scriptlib::group_filter_count },
{ "FilterSelect", scriptlib::group_filter_select },
{ "Select", scriptlib::group_select },
{ "SelectUnselect", scriptlib::group_select_unselect },
{ "RandomSelect", scriptlib::group_random_select },
{ "CancelableSelect", scriptlib::group_cancelable_select },
{ "IsExists", scriptlib::group_is_exists },
{ "CheckWithSumEqual", scriptlib::group_check_with_sum_equal },
{ "SelectWithSumEqual", scriptlib::group_select_with_sum_equal },
......@@ -894,7 +936,7 @@ static const struct luaL_Reg grouplib[] = {
{ "__sub", scriptlib::group_meta_sub },
{ "__band", scriptlib::group_meta_band },
{ "__bxor", scriptlib::group_meta_bxor },
{ NULL, NULL }
{ nullptr, nullptr }
};
void scriptlib::open_grouplib(lua_State *L) {
luaL_newlib(L, grouplib);
......
......@@ -9,61 +9,77 @@
#define MTRANDOM_H_
#include <random>
#include <vector>
#include <utility>
class mt19937 {
class mtrandom {
public:
const unsigned int rand_max;
const unsigned int rand_max{ std::mt19937::max() };
mt19937() :
rng(), rand_max((rng.max)()) {}
explicit mt19937(unsigned int seed) :
rng(seed), rand_max((rng.max)()) {}
mtrandom() :
rng() {}
mtrandom(uint32_t seq[], size_t len) {
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
void reset(unsigned int seed) {
rng.seed(seed);
void seed(uint32_t seq[], size_t len) {
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();
}
void discard(unsigned long long z) {
rng.discard(z);
}
// uniform_int_distribution
int get_random_integer(int l, int h) {
unsigned int range = (unsigned int)(h - l + 1);
unsigned int secureMax = rand_max - rand_max % range;
unsigned int x;
// old vesion, discard too many numbers
int get_random_integer_v1(int l, int h) {
uint32_t range = (h - l + 1);
uint32_t secureMax = rand_max - rand_max % range;
uint_fast32_t x;
do {
x = rng();
} while (x >= secureMax);
return (int)(l + 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;
return l + (int)(x % range);
}
// Fisher-Yates shuffle v[a]~v[b]
template<typename T>
void shuffle_vector(std::vector<T>& v, int a = -1, int b = -1) {
if (a < 0)
a = 0;
if (b < 0)
b = (int)v.size() - 1;
for (int i = a; i < b; ++i) {
int r = get_random_integer(i, b);
std::swap(v[i], v[r]);
// N % k == (N - k) % k, discard the leftmost numbers
int get_random_integer_v2(int l, int h) {
uint32_t range = (h - l + 1);
uint32_t bound = -range % range;
auto x = rng();
while (x < bound) {
x = rng();
}
return l + (int)(x % range);
}
// Fisher-Yates shuffle [first, last)
template<typename T>
void shuffle_vector_old(std::vector<T>& v, int a = -1, int b = -1) {
if (a < 0)
a = 0;
if (b < 0)
b = (int)v.size() - 1;
for (int i = a; i < b; ++i) {
int r = get_random_integer_old(i, b);
void shuffle_vector(std::vector<T>& v, int first = 0, int last = INT32_MAX, int version = 2) {
if ((size_t)last > v.size())
last = v.size();
auto distribution = &mtrandom::get_random_integer_v2;
if (version == 1)
distribution = &mtrandom::get_random_integer_v1;
for (int i = first; i < last - 1; ++i) {
int r = (this->*distribution)(i, last - 1);
std::swap(v[i], v[r]);
}
}
......
......@@ -4,8 +4,9 @@
* Created on: 2010-5-2
* Author: Argon
*/
#include <stdio.h>
#include <string.h>
#include <cstdio>
#include <cstring>
#include <set>
#include "ocgapi.h"
#include "duel.h"
#include "card.h"
......@@ -13,66 +14,83 @@
#include "effect.h"
#include "field.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 card_reader creader = default_card_reader;
static message_handler mhandler = default_message_handler;
static byte buffer[0x20000];
static byte buffer[0x100000];
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;
}
extern "C" DECL_DLLEXPORT void set_card_reader(card_reader f) {
OCGCORE_API void set_card_reader(card_reader 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;
}
byte* read_script(const char* script_name, int* 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);
}
uint32 handle_message(void* pduel, uint32 msg_type) {
return mhandler(pduel, msg_type);
uint32_t handle_message(void* pduel, uint32_t message_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;
fp = fopen(script_name, "rb");
fp = std::fopen(script_name, "rb");
if (!fp)
return 0;
int len = (int)fread(buffer, 1, sizeof(buffer), fp);
fclose(fp);
if(len >= sizeof(buffer))
return 0;
*slen = len;
return nullptr;
size_t len = std::fread(buffer, 1, sizeof buffer, fp);
std::fclose(fp);
if (len >= sizeof buffer)
return nullptr;
*slen = (int)len;
return buffer;
}
uint32 default_card_reader(uint32 code, card_data* data) {
return 0;
}
uint32 default_message_handler(void* pduel, uint32 message_type) {
return 0;
OCGCORE_API intptr_t create_duel(uint_fast32_t seed) {
duel* pduel = new duel();
duel_set.insert(pduel);
pduel->random.seed(seed);
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_set.insert(pduel);
pduel->random.reset(seed);
pduel->random.seed(seed_sequence, SEED_COUNT);
pduel->rng_version = 2;
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;
pd->game_field->core.duel_options |= options & 0xffff;
int32 duel_rule = options >> 16;
if(duel_rule)
uint16_t duel_rule = options >> 16;
uint16_t duel_options = options & 0xffff;
pd->game_field->core.duel_options |= duel_options;
if (duel_rule >= 1 && duel_rule <= CURRENT_RULE)
pd->game_field->core.duel_rule = duel_rule;
else if(options & DUEL_OBSOLETE_RULING) //provide backward compatibility with replay
pd->game_field->core.duel_rule = 1;
else if(!pd->game_field->core.duel_rule)
pd->game_field->core.duel_rule = 5;
if (pd->game_field->core.duel_rule < 1 || pd->game_field->core.duel_rule > CURRENT_RULE)
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[1] = 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) {
pd->game_field->player[0].tag_list_hand.push_back(pcard);
pcard->current.controler = 0;
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;
}
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) {
pd->game_field->player[1].tag_list_hand.push_back(pcard);
pcard->current.controler = 1;
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;
}
}
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;
if(duel_set.count(pd)) {
duel_set.erase(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;
if(lp > 0)
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
if(drawcount >= 0)
pd->game_field->player[playerid].draw_count = drawcount;
}
extern "C" DECL_DLLEXPORT void get_log_message(intptr_t pduel, byte* buf) {
strcpy((char*)buf, ((duel*)pduel)->strbuffer);
OCGCORE_API void get_log_message(intptr_t pduel, char* buf) {
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) {
int32 len = ((duel*)pduel)->read_buffer(buf);
OCGCORE_API int32_t get_message(intptr_t pduel, byte* buf) {
int32_t len = ((duel*)pduel)->read_buffer(buf);
((duel*)pduel)->clear_buffer();
return len;
}
extern "C" DECL_DLLEXPORT int32 process(intptr_t pduel) {
OCGCORE_API uint32_t process(intptr_t pduel) {
duel* pd = (duel*)pduel;
int result = pd->game_field->process();
while((result & 0xffff) == 0 && (result & 0xf0000) == 0)
uint32_t result = 0;
do {
result = pd->game_field->process();
} while ((result & PROCESSOR_BUFFER_LEN) == 0 && (result & PROCESSOR_FLAG) == 0);
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;
if(ptduel->game_field->is_location_useable(playerid, location, sequence)) {
card* pcard = ptduel->new_card(code);
......@@ -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;
if(owner > 1 || !(location & (LOCATION_DECK | LOCATION_EXTRA)))
return;
......@@ -161,7 +186,7 @@ extern "C" DECL_DLLEXPORT void new_tag_card(intptr_t pduel, uint32 code, uint8 o
pcard->owner = owner;
pcard->current.controler = owner;
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;
break;
case LOCATION_EXTRA:
......@@ -169,103 +194,109 @@ extern "C" DECL_DLLEXPORT void new_tag_card(intptr_t pduel, uint32 code, uint8 o
pcard->owner = owner;
pcard->current.controler = owner;
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;
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)
return 0;
/**
* @brief Get card information.
* @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;
card* pcard = 0;
card* pcard = nullptr;
location &= 0x7f;
if(location & LOCATION_ONFIELD)
if (location == LOCATION_MZONE || location == LOCATION_SZONE)
pcard = ptduel->game_field->get_field_card(playerid, location, sequence);
else {
field::card_vector* lst = 0;
if(location == LOCATION_HAND)
card_vector* lst = nullptr;
if (location == LOCATION_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;
else if(location == LOCATION_REMOVED)
else if (location == LOCATION_REMOVED)
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;
else if(location == LOCATION_DECK)
else if (location == LOCATION_DECK)
lst = &ptduel->game_field->player[playerid].list_main;
if(!lst || sequence >= lst->size())
pcard = 0;
else
return LEN_FAIL;
if (sequence >= (int32_t)lst->size())
return LEN_FAIL;
pcard = (*lst)[sequence];
}
if (pcard) {
return pcard->get_infos(buf, query_flag, use_cache);
}
else {
*((int32*)buf) = 4;
return 4;
buffer_write<int32_t>(buf, LEN_EMPTY);
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;
if(playerid != 0 && playerid != 1)
if (!check_playerid(playerid))
return 0;
auto& player = ptduel->game_field->player[playerid];
if(location == LOCATION_HAND)
return (int32)player.list_hand.size();
return (int32_t)player.list_hand.size();
if(location == LOCATION_GRAVE)
return (int32)player.list_grave.size();
return (int32_t)player.list_grave.size();
if(location == LOCATION_REMOVED)
return (int32)player.list_remove.size();
return (int32_t)player.list_remove.size();
if(location == LOCATION_EXTRA)
return (int32)player.list_extra.size();
return (int32_t)player.list_extra.size();
if(location == LOCATION_DECK)
return (int32)player.list_main.size();
return (int32_t)player.list_main.size();
if(location == LOCATION_MZONE) {
uint32 count = 0;
int32_t count = 0;
for(auto& pcard : player.list_mzone)
if(pcard) count++;
if(pcard)
++count;
return count;
}
if(location == LOCATION_SZONE) {
uint32 count = 0;
int32_t count = 0;
for(auto& pcard : player.list_szone)
if(pcard) count++;
if(pcard)
++count;
return count;
}
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) {
if(playerid != 0 && playerid != 1)
return 0;
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 (!check_playerid(playerid))
return LEN_FAIL;
duel* ptduel = (duel*)pduel;
auto& player = ptduel->game_field->player[playerid];
byte* p = buf;
if(location == LOCATION_MZONE) {
for(auto& pcard : player.list_mzone) {
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;
} else {
*((int32*)p) = 4;
p += 4;
buffer_write<int32_t>(p, LEN_EMPTY);
}
}
}
else if(location == LOCATION_SZONE) {
for(auto& pcard : player.list_szone) {
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;
} else {
*((int32*)p) = 4;
p += 4;
buffer_write<int32_t>(p, LEN_EMPTY);
}
}
}
else {
field::card_vector* lst = nullptr;
card_vector* lst = nullptr;
if(location == LOCATION_HAND)
lst = &player.list_hand;
else if(location == LOCATION_GRAVE)
......@@ -277,28 +308,27 @@ extern "C" DECL_DLLEXPORT int32 query_field_card(intptr_t pduel, uint8 playerid,
else if(location == LOCATION_DECK)
lst = &player.list_main;
else
return 0;
return LEN_FAIL;
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;
}
}
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;
byte* p = buf;
*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) {
auto& player = ptduel->game_field->player[playerid];
*((int*)p) = player.lp;
p += 4;
buffer_write<int32_t>(p, player.lp);
for(auto& pcard : player.list_mzone) {
if(pcard) {
*p++ = 1;
*p++ = pcard->current.position;
*p++ = (uint8)pcard->xyz_materials.size();
*p++ = (uint8_t)pcard->xyz_materials.size();
} else {
*p++ = 0;
}
......@@ -311,34 +341,31 @@ extern "C" DECL_DLLEXPORT int32 query_field_info(intptr_t pduel, byte* buf) {
*p++ = 0;
}
}
*p++ = (uint8)player.list_main.size();
*p++ = (uint8)player.list_hand.size();
*p++ = (uint8)player.list_grave.size();
*p++ = (uint8)player.list_remove.size();
*p++ = (uint8)player.list_extra.size();
*p++ = (uint8)player.extra_p_count;
*p++ = (uint8_t)player.list_main.size();
*p++ = (uint8_t)player.list_hand.size();
*p++ = (uint8_t)player.list_grave.size();
*p++ = (uint8_t)player.list_remove.size();
*p++ = (uint8_t)player.list_extra.size();
*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) {
effect* peffect = ch.triggering_effect;
*((int*)p) = peffect->get_handler()->data.code;
p += 4;
*((int*)p) = peffect->get_handler()->get_info_location();
p += 4;
buffer_write<uint32_t>(p, peffect->get_handler()->data.code);
buffer_write<uint32_t>(p, peffect->get_handler()->get_info_location());
*p++ = ch.triggering_controler;
*p++ = (uint8)ch.triggering_location;
*p++ = (uint8_t)ch.triggering_location;
*p++ = ch.triggering_sequence;
*((int*)p) = peffect->description;
p += 4;
buffer_write<uint32_t>(p, peffect->description);
}
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);
}
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);
}
extern "C" DECL_DLLEXPORT int32 preload_script(intptr_t pduel, const char* script, int32 len) {
return ((duel*)pduel)->lua->load_script(script);
OCGCORE_API int32_t preload_script(intptr_t pduel, const char* script_name) {
return ((duel*)pduel)->lua->load_script(script_name);
}
......@@ -10,49 +10,56 @@
#include "common.h"
#ifdef WIN32
#define DECL_DLLEXPORT __declspec(dllexport)
#ifdef __cplusplus
#define EXTERN_C extern "C"
#else
#define DECL_DLLEXPORT
#define EXTERN_C
#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_info;
class group;
class effect;
class interpreter;
typedef byte* (*script_reader)(const char*, int*);
typedef uint32 (*card_reader)(uint32, card_data*);
typedef uint32 (*message_handler)(void*, uint32);
typedef byte* (*script_reader)(const char* script_name, int* len);
typedef uint32_t (*card_reader)(uint32_t code, card_data* data);
typedef uint32_t (*message_handler)(intptr_t pduel, uint32_t msg_type);
extern "C" DECL_DLLEXPORT void set_script_reader(script_reader f);
extern "C" DECL_DLLEXPORT void set_card_reader(card_reader f);
extern "C" DECL_DLLEXPORT void set_message_handler(message_handler f);
OCGCORE_API void set_script_reader(script_reader f);
OCGCORE_API void set_card_reader(card_reader f);
OCGCORE_API void set_message_handler(message_handler f);
byte* read_script(const char* script_name, int* len);
uint32 read_card(uint32 code, card_data* data);
uint32 handle_message(void* pduel, uint32 message_type);
extern "C" DECL_DLLEXPORT intptr_t create_duel(uint32 seed);
extern "C" DECL_DLLEXPORT void start_duel(intptr_t pduel, int32 options);
extern "C" DECL_DLLEXPORT void end_duel(intptr_t pduel);
extern "C" DECL_DLLEXPORT void set_player_info(intptr_t pduel, int32 playerid, int32 lp, int32 startcount, int32 drawcount);
extern "C" DECL_DLLEXPORT void get_log_message(intptr_t pduel, byte* buf);
extern "C" DECL_DLLEXPORT int32 get_message(intptr_t pduel, byte* buf);
extern "C" DECL_DLLEXPORT int32 process(intptr_t pduel);
extern "C" DECL_DLLEXPORT void new_card(intptr_t pduel, uint32 code, uint8 owner, uint8 playerid, uint8 location, uint8 sequence, uint8 position);
extern "C" DECL_DLLEXPORT void new_tag_card(intptr_t pduel, uint32 code, uint8 owner, uint8 location);
extern "C" DECL_DLLEXPORT int32 query_card(intptr_t pduel, uint8 playerid, uint8 location, uint8 sequence, int32 query_flag, byte* buf, int32 use_cache);
extern "C" DECL_DLLEXPORT int32 query_field_count(intptr_t pduel, uint8 playerid, uint8 location);
extern "C" DECL_DLLEXPORT int32 query_field_card(intptr_t pduel, uint8 playerid, uint8 location, int32 query_flag, byte* buf, int32 use_cache);
extern "C" DECL_DLLEXPORT int32 query_field_info(intptr_t pduel, byte* buf);
extern "C" DECL_DLLEXPORT void set_responsei(intptr_t pduel, int32 value);
extern "C" DECL_DLLEXPORT void set_responseb(intptr_t pduel, byte* buf);
extern "C" DECL_DLLEXPORT int32 preload_script(intptr_t pduel, const char* script, int32 len);
byte* default_script_reader(const char* script_name, int* len);
uint32 default_card_reader(uint32 code, card_data* data);
uint32 default_message_handler(void* pduel, uint32 msg_type);
uint32_t read_card(uint32_t code, card_data* data);
uint32_t handle_message(void* pduel, uint32_t message_type);
OCGCORE_API intptr_t create_duel(uint_fast32_t seed);
OCGCORE_API intptr_t create_duel_v2(uint32_t seed_sequence[]);
OCGCORE_API void start_duel(intptr_t pduel, uint32_t options);
OCGCORE_API void end_duel(intptr_t pduel);
OCGCORE_API void set_player_info(intptr_t pduel, int32_t playerid, int32_t lp, int32_t startcount, int32_t drawcount);
OCGCORE_API void get_log_message(intptr_t pduel, char* buf);
OCGCORE_API int32_t get_message(intptr_t pduel, byte* buf);
OCGCORE_API uint32_t process(intptr_t pduel);
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);
OCGCORE_API void new_tag_card(intptr_t pduel, uint32_t code, uint8_t owner, uint8_t 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);
OCGCORE_API int32_t query_field_count(intptr_t pduel, uint8_t playerid, uint8_t location);
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);
OCGCORE_API int32_t query_field_info(intptr_t pduel, byte* buf);
OCGCORE_API void set_responsei(intptr_t pduel, int32_t value);
OCGCORE_API void set_responseb(intptr_t pduel, byte* buf);
OCGCORE_API int32_t preload_script(intptr_t pduel, const char* script_name);
OCGCORE_API byte* default_script_reader(const char* script_name, int* len);
#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 @@
#include <algorithm>
#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) {
pduel->write_buffer8(MSG_SELECT_BATTLECMD);
pduel->write_buffer8(playerid);
//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);
for(const auto& ch : core.select_chains) {
effect* peffect = ch.triggering_effect;
......@@ -34,7 +48,7 @@ int32 field::select_battle_command(uint16 step, uint8 playerid) {
pduel->write_buffer32(peffect->description);
}
//Attackable
pduel->write_buffer8((uint8)core.attackable_cards.size());
pduel->write_buffer8((uint8_t)core.attackable_cards.size());
for(auto& pcard : core.attackable_cards) {
pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler);
......@@ -53,11 +67,11 @@ int32 field::select_battle_command(uint16 step, uint8 playerid) {
pduel->write_buffer8(0);
return FALSE;
} else {
uint32 t = returns.ivalue[0] & 0xffff;
uint32 s = returns.ivalue[0] >> 16;
int32_t t = (uint32_t)returns.ivalue[0] & 0xffff;
int32_t s = (uint32_t)returns.ivalue[0] >> 16;
if(t < 0 || t > 3 || s < 0
|| (t == 0 && s >= core.select_chains.size())
|| (t == 1 && s >= core.attackable_cards.size())
|| (t == 0 && s >= (int32_t)core.select_chains.size())
|| (t == 1 && s >= (int32_t)core.attackable_cards.size())
|| (t == 2 && !core.to_m2)
|| (t == 3 && !core.to_ep)) {
pduel->write_buffer8(MSG_RETRY);
......@@ -66,12 +80,12 @@ int32 field::select_battle_command(uint16 step, uint8 playerid) {
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) {
pduel->write_buffer8(MSG_SELECT_IDLECMD);
pduel->write_buffer8(playerid);
//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) {
pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler);
......@@ -79,7 +93,7 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) {
pduel->write_buffer8(pcard->current.sequence);
}
//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) {
pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler);
......@@ -87,7 +101,7 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) {
pduel->write_buffer8(pcard->current.sequence);
}
//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) {
pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler);
......@@ -95,7 +109,7 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) {
pduel->write_buffer8(pcard->current.sequence);
}
//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) {
pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler);
......@@ -103,7 +117,7 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) {
pduel->write_buffer8(pcard->current.sequence);
}
//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) {
pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler);
......@@ -111,7 +125,7 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) {
pduel->write_buffer8(pcard->current.sequence);
}
//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);
for(const auto& ch : core.select_chains) {
effect* peffect = ch.triggering_effect;
......@@ -140,25 +154,25 @@ int32 field::select_idle_command(uint16 step, uint8 playerid) {
pduel->write_buffer8(0);
return FALSE;
} else {
uint32 t = returns.ivalue[0] & 0xffff;
uint32 s = returns.ivalue[0] >> 16;
int32_t t = (uint32_t)returns.ivalue[0] & 0xffff;
int32_t s = (uint32_t)returns.ivalue[0] >> 16;
if(t < 0 || t > 8 || s < 0
|| (t == 0 && s >= core.summonable_cards.size())
|| (t == 1 && s >= core.spsummonable_cards.size())
|| (t == 2 && s >= core.repositionable_cards.size())
|| (t == 3 && s >= core.msetable_cards.size())
|| (t == 4 && s >= core.ssetable_cards.size())
|| (t == 5 && s >= core.select_chains.size())
|| (t == 0 && s >= (int32_t)core.summonable_cards.size())
|| (t == 1 && s >= (int32_t)core.spsummonable_cards.size())
|| (t == 2 && s >= (int32_t)core.repositionable_cards.size())
|| (t == 3 && s >= (int32_t)core.msetable_cards.size())
|| (t == 4 && s >= (int32_t)core.ssetable_cards.size())
|| (t == 5 && s >= (int32_t)core.select_chains.size())
|| (t == 6 && (infos.phase != PHASE_MAIN1 || !core.to_bp))
|| (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);
return FALSE;
}
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((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) {
returns.ivalue[0] = 1;
......@@ -179,7 +193,7 @@ int32 field::select_effect_yes_no(uint16 step, uint8 playerid, uint32 descriptio
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((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) {
returns.ivalue[0] = 1;
......@@ -198,7 +212,7 @@ int32 field::select_yes_no(uint16 step, uint8 playerid, uint32 description) {
return TRUE;
}
}
int32 field::select_option(uint16 step, uint8 playerid) {
int32_t field::select_option(uint16_t step, uint8_t playerid) {
if(step == 0) {
returns.ivalue[0] = -1;
if(core.select_options.size() == 0)
......@@ -209,95 +223,97 @@ int32 field::select_option(uint16 step, uint8 playerid) {
}
pduel->write_buffer8(MSG_SELECT_OPTION);
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)
pduel->write_buffer32(option);
return FALSE;
} 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);
return FALSE;
}
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) {
returns.bvalue[0] = 0;
if(max == 0 || core.select_cards.empty())
return TRUE;
if(max > 127)
max = 127;
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(max > core.select_cards.size())
max = (uint8)core.select_cards.size();
max = (uint8_t)core.select_cards.size();
if(min > max)
min = max;
if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) {
returns.bvalue[0] = min;
for(uint8 i = 0; i < min; ++i)
for(uint8_t i = 0; i < min; ++i)
returns.bvalue[i + 1] = i;
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(playerid);
pduel->write_buffer8(cancelable);
pduel->write_buffer8(min);
pduel->write_buffer8(max);
pduel->write_buffer8((uint8)core.select_cards.size());
std::sort(core.select_cards.begin(), core.select_cards.end(), card::card_operation_sort);
pduel->write_buffer8((uint8_t)core.select_cards.size());
uint8_t deck_seq = 0;
for(auto& pcard : core.select_cards) {
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;
} else {
if(cancelable && returns.ivalue[0] == -1)
if (returns.ivalue[0] == -1) {
if (cancelable)
return TRUE;
if(returns.bvalue[0] < min || returns.bvalue[0] > max) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
std::set<int8> c;
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)) {
if (!check_response(core.select_cards.size(), min, max)) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
c.insert(v);
}
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) {
returns.bvalue[0] = 0;
if(core.select_cards.empty() && core.unselect_cards.empty())
return TRUE;
if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) {
returns.bvalue[0] = 1;
for(uint8 i = 0; i < 1; ++i)
for(uint8_t i = 0; i < 1; ++i)
returns.bvalue[i + 1] = i;
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(playerid);
pduel->write_buffer8(finishable);
pduel->write_buffer8(cancelable);
pduel->write_buffer8(min);
pduel->write_buffer8(max);
pduel->write_buffer8((uint8)core.select_cards.size());
std::sort(core.select_cards.begin(), core.select_cards.end(), card::card_operation_sort);
pduel->write_buffer8((uint8_t)core.select_cards.size());
uint8_t deck_seq = 0;
for(auto& pcard : core.select_cards) {
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) {
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;
} else {
......@@ -307,20 +323,14 @@ int32 field::select_unselect_card(uint16 step, uint8 playerid, uint8 cancelable,
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
if(returns.bvalue[0] == 0 || returns.bvalue[0] > 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) {
if (!check_response(core.select_cards.size() + core.unselect_cards.size(), 1, 1)) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
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) {
returns.ivalue[0] = -1;
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
}
pduel->write_buffer8(MSG_SELECT_CHAIN);
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(forced);
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
}
return FALSE;
} else {
if(!forced && returns.ivalue[0] == -1)
if (returns.ivalue[0] == -1) {
if (!forced)
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);
return FALSE;
}
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((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) {
flag = ~flag;
int32 filter;
int32 pzone = 0;
uint32_t filter;
int32_t pzone = 0;
if(flag & 0x7f) {
returns.bvalue[0] = 1;
returns.bvalue[1] = LOCATION_MZONE;
......@@ -429,13 +443,14 @@ int32 field::select_place(uint16 step, uint8 playerid, uint32 flag, uint8 count)
returns.bvalue[0] = 0;
return FALSE;
} else {
uint8 pt = 0;
uint32 selected = 0;
for(int8 i = 0; i < 1 || i < count; ++i) {
uint8 p = returns.bvalue[pt];
uint8 l = returns.bvalue[pt + 1];
uint8 s = returns.bvalue[pt + 2];
uint32 sel = 0x1u << (s + (p == playerid ? 0 : 16) + (l == LOCATION_MZONE ? 0 : 8));
uint8_t pt = 0;
uint32_t selected = 0;
int32_t len = std::max(1, (int32_t)count);
for (int32_t i = 0; i < len; ++i) {
uint8_t p = returns.bvalue[pt];
uint8_t l = returns.bvalue[pt + 1];
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)
&& ((p != 0 && p != 1)
|| ((l != LOCATION_MZONE) && (l != LOCATION_SZONE))
......@@ -443,17 +458,17 @@ int32 field::select_place(uint16 step, uint8 playerid, uint32 flag, uint8 count)
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
if(sel & (0x1 << 5))
sel |= 0x1 << (16 + 6);
if(sel & (0x1 << 6))
sel |= 0x1 << (16 + 5);
if(sel & (0x1u << 5))
sel |= 0x1u << (16 + 6);
if(sel & (0x1u << 6))
sel |= 0x1u << (16 + 5);
selected |= sel;
pt += 3;
}
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(positions == 0) {
returns.ivalue[0] = POS_FACEUP_ATTACK;
......@@ -465,11 +480,11 @@ int32 field::select_position(uint16 step, uint8 playerid, uint32 code, uint8 pos
return TRUE;
}
if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) {
if(positions & 0x4)
if((uint32_t)positions & 0x4)
returns.ivalue[0] = 0x4;
else if(positions & 0x1)
else if((uint32_t)positions & 0x1)
returns.ivalue[0] = 0x1;
else if(positions & 0x8)
else if((uint32_t)positions & 0x8)
returns.ivalue[0] = 0x8;
else
returns.ivalue[0] = 0x2;
......@@ -482,7 +497,7 @@ int32 field::select_position(uint16 step, uint8 playerid, uint32 code, uint8 pos
returns.ivalue[0] = 0;
return FALSE;
} else {
uint32 pos = returns.ivalue[0];
uint32_t pos = returns.ivalue[0];
if(pos != 0x1 && pos != 0x2 && pos != 0x4 && pos != 0x8 || !(pos & positions)) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
......@@ -490,12 +505,16 @@ int32 field::select_position(uint16 step, uint8 playerid, uint32 code, uint8 pos
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) {
returns.bvalue[0] = 0;
if(max == 0 || core.select_cards.empty())
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)
tm += pcard->release_param;
if(max > 5)
......@@ -504,34 +523,38 @@ int32 field::select_tribute(uint16 step, uint8 playerid, uint8 cancelable, uint8
max = tm;
if(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(playerid);
pduel->write_buffer8(cancelable);
pduel->write_buffer8(min);
pduel->write_buffer8(max);
pduel->write_buffer8((uint8)core.select_cards.size());
std::sort(core.select_cards.begin(), core.select_cards.end(), card::card_operation_sort);
pduel->write_buffer8((uint8_t)core.select_cards.size());
uint8_t deck_seq = 0;
for(auto& pcard : core.select_cards) {
pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler);
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);
}
return FALSE;
} else {
if(cancelable && returns.ivalue[0] == -1)
if (returns.ivalue[0] == -1) {
if (cancelable)
return TRUE;
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
if(returns.bvalue[0] > max) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
std::set<int8> c;
uint8 m = (uint8)core.select_cards.size(), tt = 0;
for(int32 i = 0; i < returns.bvalue[0]; ++i) {
int8 v = returns.bvalue[i + 1];
if(v < 0 || v >= m || c.count(v)) {
std::set<uint8_t> c;
int32_t m = (int32_t)core.select_cards.size(), tt = 0;
for(int32_t i = 0; i < returns.bvalue[0]; ++i) {
uint8_t v = returns.bvalue[i + 1];
if(v >= m || c.count(v)) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
......@@ -545,13 +568,13 @@ int32 field::select_tribute(uint16 step, uint8 playerid, uint8 cancelable, uint8
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(count == 0)
return TRUE;
uint8 avail = s;
uint8 fp = playerid;
uint32 total = 0;
uint8_t avail = s;
uint8_t fp = playerid;
uint32_t total = 0;
core.select_cards.clear();
for(int p = 0; p < 2; ++p) {
if(avail) {
......@@ -579,19 +602,21 @@ int32 field::select_counter(uint16 step, uint8 playerid, uint16 countertype, uin
pduel->write_buffer8(playerid);
pduel->write_buffer16(countertype);
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);
uint8_t deck_seq = 0;
for(auto& pcard : core.select_cards) {
pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler);
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));
}
return FALSE;
} else {
uint16 ct = 0;
for(uint32 i = 0; i < core.select_cards.size(); ++i) {
int32_t ct = 0;
for(int32_t i = 0; i < (int32_t)core.select_cards.size(); ++i) {
if(core.select_cards[i]->get_counter(countertype) < returns.svalue[i]) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
......@@ -605,21 +630,27 @@ int32 field::select_counter(uint16 step, uint8 playerid, uint16 countertype, uin
}
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)
return FALSE;
int32 o1 = oparam[index] & 0xffff;
int32 o2 = oparam[index] >> 16;
int32_t o1 = oparam[index] & 0xffff;
int32_t o2 = oparam[index] >> 16;
if(index == size - 1)
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)))
|| (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) {
returns.bvalue[0] = 0;
if(core.select_cards.empty())
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);
if(max)
pduel->write_buffer8(0);
......@@ -628,41 +659,43 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32
if(max < min)
max = min;
pduel->write_buffer8(playerid);
pduel->write_buffer32(acc & 0xffff);
pduel->write_buffer32((uint32_t)acc & 0xffff);
pduel->write_buffer8(min);
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) {
pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler);
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_buffer8((uint8)core.select_cards.size());
std::sort(core.select_cards.begin(), core.select_cards.end(), card::card_operation_sort);
pduel->write_buffer8((uint8_t)core.select_cards.size());
for(auto& pcard : core.select_cards) {
pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler);
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);
}
return FALSE;
} 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) {
int32 oparam[16];
int32 mcount = (int32)core.must_select_cards.size();
uint32_t oparam[512]{};
if(returns.bvalue[0] < min + mcount || returns.bvalue[0] > max + mcount) {
pduel->write_buffer8(MSG_RETRY);
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;
int32 m = (int32)core.select_cards.size();
for(int32 i = mcount; i < returns.bvalue[0]; ++i) {
int32 v = returns.bvalue[i + 1];
int32_t m = (int32_t)core.select_cards.size();
for(int32_t i = mcount; i < returns.bvalue[0]; ++i) {
int32_t v = returns.bvalue[i + 1];
if(v < 0 || v >= m || c.count(v)) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
......@@ -676,32 +709,31 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32
}
return TRUE;
} else {
int32 mcount = (int32)core.must_select_cards.size();
int32 sum = 0, mx = 0, mn = 0x7fffffff;
for(int32 i = 0; i < mcount; ++i) {
int32 op = core.must_select_cards[i]->sum_param;
int32 o1 = op & 0xffff;
int32 o2 = op >> 16;
int32 ms = (o2 && o2 < o1) ? o2 : o1;
int32_t sum = 0, mx = 0, mn = 0x7fffffff;
for(int32_t i = 0; i < mcount; ++i) {
uint32_t op = core.must_select_cards[i]->sum_param;
int32_t o1 = op & 0xffff;
int32_t o2 = op >> 16;
int32_t ms = (o2 && o2 < o1) ? o2 : o1;
sum += ms;
mx += (o2 > o1) ? o2 : o1;
mx += std::max(o1, o2);
if(ms < mn)
mn = ms;
}
int32 m = (int32)core.select_cards.size();
for(int32 i = mcount; i < returns.bvalue[0]; ++i) {
int32 v = returns.bvalue[i + 1];
int32_t m = (int32_t)core.select_cards.size();
for(int32_t i = mcount; i < returns.bvalue[0]; ++i) {
int32_t v = returns.bvalue[i + 1];
if(v < 0 || v >= m || c.count(v)) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
c.insert(v);
int32 op = core.select_cards[v]->sum_param;
int32 o1 = op & 0xffff;
int32 o2 = op >> 16;
int32 ms = (o2 && o2 < o1) ? o2 : o1;
uint32_t op = core.select_cards[v]->sum_param;
int32_t o1 = op & 0xffff;
int32_t o2 = op >> 16;
int32_t ms = (o2 && o2 < o1) ? o2 : o1;
sum += ms;
mx += (o2 > o1) ? o2 : o1;
mx += std::max(o1, o2);
if(ms < mn)
mn = ms;
}
......@@ -714,18 +746,20 @@ int32 field::select_with_sum_limit(int16 step, uint8 playerid, int32 acc, int32
}
return TRUE;
}
int32 field::sort_card(int16 step, uint8 playerid) {
int32_t field::sort_card(int16_t step, uint8_t playerid) {
if(step == 0) {
returns.bvalue[0] = 0;
if((playerid == 1) && (core.duel_options & DUEL_SIMPLE_AI)) {
returns.bvalue[0] = -1;
returns.bvalue[0] = 0xff;
return TRUE;
}
if(core.select_cards.empty())
return TRUE;
if (core.select_cards.size() > UINT8_MAX)
core.select_cards.resize(UINT8_MAX);
pduel->write_buffer8(MSG_SORT_CARD);
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) {
pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler);
......@@ -734,13 +768,13 @@ int32 field::sort_card(int16 step, uint8 playerid) {
}
return FALSE;
} else {
if(returns.bvalue[0] == -1)
if(returns.bvalue[0] == 0xff)
return TRUE;
std::set<int8> c;
uint8 m = (uint8)core.select_cards.size();
for(uint8 i = 0; i < m; ++i) {
int8 v = returns.bvalue[i];
if(v < 0 || v >= m || c.count(v)) {
std::set<uint8_t> c;
int32_t m = (int32_t)core.select_cards.size();
for(int32_t i = 0; i < m; ++i) {
uint8_t v = returns.bvalue[i];
if(v >= m || c.count(v)) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
......@@ -750,12 +784,12 @@ int32 field::sort_card(int16 step, uint8 playerid) {
}
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) {
int32 scount = 0;
for(int32 ft = 0x1; ft != 0x2000000; ft <<= 1) {
int32_t scount = 0;
for(uint32_t ft = 0x1; ft < (0x1U << RACES_COUNT); ft <<= 1) {
if(ft & available)
scount++;
++scount;
}
if(scount <= count) {
count = scount;
......@@ -767,15 +801,16 @@ int32 field::announce_race(int16 step, uint8 playerid, int32 count, int32 availa
pduel->write_buffer32(available);
return FALSE;
} else {
int32 rc = returns.ivalue[0];
int32 sel = 0;
for(int32 ft = 0x1; ft != 0x2000000; ft <<= 1) {
if(!(ft & rc)) continue;
int32_t rc = returns.ivalue[0];
int32_t sel = 0;
for(uint32_t ft = 0x1; ft < (0x1U << RACES_COUNT); ft <<= 1) {
if(!(ft & rc))
continue;
if(!(ft & available)) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
sel++;
++sel;
}
if(sel != count) {
pduel->write_buffer8(MSG_RETRY);
......@@ -789,12 +824,12 @@ int32 field::announce_race(int16 step, uint8 playerid, int32 count, int32 availa
}
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) {
int32 scount = 0;
for(int32 ft = 0x1; ft != 0x80; ft <<= 1) {
int32_t scount = 0;
for(int32_t ft = 0x1; ft != 0x80; ft <<= 1) {
if(ft & available)
scount++;
++scount;
}
if(scount <= count) {
count = scount;
......@@ -806,15 +841,15 @@ int32 field::announce_attribute(int16 step, uint8 playerid, int32 count, int32 a
pduel->write_buffer32(available);
return FALSE;
} else {
int32 rc = returns.ivalue[0];
int32 sel = 0;
for(int32 ft = 0x1; ft != 0x80; ft <<= 1) {
int32_t rc = returns.ivalue[0];
int32_t sel = 0;
for(int32_t ft = 0x1; ft != 0x80; ft <<= 1) {
if(!(ft & rc)) continue;
if(!(ft & available)) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
sel++;
++sel;
}
if(sel != count) {
pduel->write_buffer8(MSG_RETRY);
......@@ -828,15 +863,15 @@ int32 field::announce_attribute(int16 step, uint8 playerid, int32 count, int32 a
}
return TRUE;
}
static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcode) {
std::stack<int32> stack;
static int32_t is_declarable(card_data const& cd, const std::vector<uint32_t>& opcode) {
std::stack<int32_t> stack;
for(auto& it : opcode) {
switch(it) {
case OPCODE_ADD: {
if(stack.size() >= 2) {
int32 rhs = stack.top();
int32_t rhs = stack.top();
stack.pop();
int32 lhs = stack.top();
int32_t lhs = stack.top();
stack.pop();
stack.push(lhs + rhs);
}
......@@ -844,9 +879,9 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
}
case OPCODE_SUB: {
if(stack.size() >= 2) {
int32 rhs = stack.top();
int32_t rhs = stack.top();
stack.pop();
int32 lhs = stack.top();
int32_t lhs = stack.top();
stack.pop();
stack.push(lhs - rhs);
}
......@@ -854,9 +889,9 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
}
case OPCODE_MUL: {
if(stack.size() >= 2) {
int32 rhs = stack.top();
int32_t rhs = stack.top();
stack.pop();
int32 lhs = stack.top();
int32_t lhs = stack.top();
stack.pop();
stack.push(lhs * rhs);
}
......@@ -864,9 +899,9 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
}
case OPCODE_DIV: {
if(stack.size() >= 2) {
int32 rhs = stack.top();
int32_t rhs = stack.top();
stack.pop();
int32 lhs = stack.top();
int32_t lhs = stack.top();
stack.pop();
stack.push(lhs / rhs);
}
......@@ -874,27 +909,27 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
}
case OPCODE_AND: {
if(stack.size() >= 2) {
int32 rhs = stack.top();
int32_t rhs = stack.top();
stack.pop();
int32 lhs = stack.top();
int32_t lhs = stack.top();
stack.pop();
stack.push(lhs && rhs);
stack.push(static_cast<int32_t>(lhs && rhs));
}
break;
}
case OPCODE_OR: {
if(stack.size() >= 2) {
int32 rhs = stack.top();
int32_t rhs = stack.top();
stack.pop();
int32 lhs = stack.top();
int32_t lhs = stack.top();
stack.pop();
stack.push(lhs || rhs);
stack.push(static_cast<int32_t>(lhs || rhs));
}
break;
}
case OPCODE_NEG: {
if(stack.size() >= 1) {
int32 val = stack.top();
int32_t val = stack.top();
stack.pop();
stack.push(-val);
}
......@@ -902,15 +937,15 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
}
case OPCODE_NOT: {
if(stack.size() >= 1) {
int32 val = stack.top();
int32_t val = stack.top();
stack.pop();
stack.push(!val);
stack.push(static_cast<int32_t>(!val));
}
break;
}
case OPCODE_ISCODE: {
if(stack.size() >= 1) {
int32 code = stack.top();
int32_t code = stack.top();
stack.pop();
stack.push(cd.code == code);
}
......@@ -918,24 +953,16 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
}
case OPCODE_ISSETCARD: {
if(stack.size() >= 1) {
int32 set_code = stack.top();
int32_t set_code = stack.top();
stack.pop();
uint64 sc = cd.setcode;
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;
}
bool res = cd.is_setcode(set_code);
stack.push(res);
}
break;
}
case OPCODE_ISTYPE: {
if(stack.size() >= 1) {
int32 val = stack.top();
int32_t val = stack.top();
stack.pop();
stack.push(cd.type & val);
}
......@@ -943,7 +970,7 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
}
case OPCODE_ISRACE: {
if(stack.size() >= 1) {
int32 race = stack.top();
int32_t race = stack.top();
stack.pop();
stack.push(cd.race & race);
}
......@@ -951,7 +978,7 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
}
case OPCODE_ISATTRIBUTE: {
if(stack.size() >= 1) {
int32 attribute = stack.top();
int32_t attribute = stack.top();
stack.pop();
stack.push(cd.attribute & attribute);
}
......@@ -966,20 +993,20 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
if(stack.size() != 1 || stack.top() == 0)
return FALSE;
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) {
pduel->write_buffer8(MSG_ANNOUNCE_CARD);
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)
pduel->write_buffer32(option);
return FALSE;
} else {
int32 code = returns.ivalue[0];
int32_t code = returns.ivalue[0];
card_data data;
read_card(code, &data);
::read_card(code, &data);
if(!data.code) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
......@@ -997,17 +1024,19 @@ int32 field::announce_card(int16 step, uint8 playerid) {
}
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 (core.select_options.size() > UINT8_MAX)
core.select_options.resize(UINT8_MAX);
pduel->write_buffer8(MSG_ANNOUNCE_NUMBER);
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)
pduel->write_buffer32(option);
return FALSE;
} else {
int32 ret = returns.ivalue[0];
if(ret < 0 || ret >= (int32)core.select_options.size()) {
int32_t ret = returns.ivalue[0];
if(ret < 0 || ret >= (int32_t)core.select_options.size()) {
pduel->write_buffer8(MSG_RETRY);
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"
kind "StaticLib"
cppdialect "C++14"
files { "*.cpp", "*.h" }
links { LUA_LIB_NAME }
if BUILD_LUA then
includedirs { "../lua/src" }
else
includedirs { LUA_INCLUDE_DIR }
libdirs { LUA_LIB_DIR }
end
filter "not action:vs*"
buildoptions { "-std=c++14" }
filter "system:bsd"
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 @@
#include "scriptlib.h"
#include "duel.h"
static int32 check_data_type(lua_State* L, int32 index, const char* tname) {
int32 result = FALSE;
static int32_t check_data_type(lua_State* L, int32_t index, const char* tname) {
luaL_checkstack(L, 2, nullptr);
int32_t result = FALSE;
if(lua_getmetatable(L, index)) {
lua_getglobal(L, tname);
if(lua_rawequal(L, -1, -2))
......@@ -17,10 +18,11 @@ static int32 check_data_type(lua_State* L, int32 index, const char* tname) {
}
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) {
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)) {
result = check_data_type(L, -1, "Card");
lua_pop(L, 1);
......@@ -68,12 +70,12 @@ int32 scriptlib::check_param(lua_State* L, int32 param_type, int32 index, int32
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)
return luaL_error(L, "%d Parameters are needed.", count);
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);
if(pduel->lua->no_action)
return luaL_error(L, "Action is not allowed here.");
......
......@@ -11,618 +11,658 @@
#include "common.h"
#include "interpreter.h"
constexpr bool match_all(uint32_t x, uint32_t y) {
return (x & y) == y;
}
class scriptlib {
public:
static int32 check_param(lua_State* L, int32 param_type, int32 index, BOOL retfalse = FALSE);
static int32 check_param_count(lua_State* L, int32 count);
static int32 check_action_permission(lua_State* L);
enum effect_member : int32_t {
MEMBER_CATEGORY,
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
static int32 card_get_code(lua_State *L);
static int32 card_get_origin_code(lua_State *L);
static int32 card_get_origin_code_rule(lua_State *L);
static int32 card_get_fusion_code(lua_State *L);
static int32 card_get_link_code(lua_State *L);
static int32 card_is_fusion_code(lua_State *L);
static int32 card_is_link_code(lua_State *L);
static int32 card_is_set_card(lua_State *L);
static int32 card_is_origin_set_card(lua_State *L);
static int32 card_is_pre_set_card(lua_State *L);
static int32 card_is_fusion_set_card(lua_State *L);
static int32 card_is_link_set_card(lua_State *L);
static int32 card_get_type(lua_State *L);
static int32 card_get_origin_type(lua_State *L);
static int32 card_get_fusion_type(lua_State *L);
static int32 card_get_synchro_type(lua_State *L);
static int32 card_get_xyz_type(lua_State *L);
static int32 card_get_link_type(lua_State *L);
static int32 card_get_level(lua_State *L);
static int32 card_get_rank(lua_State *L);
static int32 card_get_link(lua_State *L);
static int32 card_get_synchro_level(lua_State *L);
static int32 card_get_ritual_level(lua_State *L);
static int32 card_get_origin_level(lua_State *L);
static int32 card_get_origin_rank(lua_State *L);
static int32 card_is_xyz_level(lua_State *L);
static int32 card_get_lscale(lua_State *L);
static int32 card_get_origin_lscale(lua_State *L);
static int32 card_get_rscale(lua_State *L);
static int32 card_get_origin_rscale(lua_State *L);
static int32 card_get_current_scale(lua_State *L);
static int32 card_is_link_marker(lua_State *L);
static int32 card_get_linked_group(lua_State *L);
static int32 card_get_linked_group_count(lua_State *L);
static int32 card_get_linked_zone(lua_State *L);
static int32 card_get_mutual_linked_group(lua_State *L);
static int32 card_get_mutual_linked_group_count(lua_State *L);
static int32 card_get_mutual_linked_zone(lua_State *L);
static int32 card_is_link_state(lua_State *L);
static int32 card_is_extra_link_state(lua_State *L);
static int32 card_get_column_group(lua_State *L);
static int32 card_get_column_group_count(lua_State *L);
static int32 card_get_column_zone(lua_State *L);
static int32 card_is_all_column(lua_State *L);
static int32 card_get_attribute(lua_State *L);
static int32 card_get_origin_attribute(lua_State *L);
static int32 card_get_fusion_attribute(lua_State *L);
static int32 card_get_link_attribute(lua_State *L);
static int32 card_get_attribute_in_grave(lua_State *L);
static int32 card_get_race(lua_State *L);
static int32 card_get_origin_race(lua_State *L);
static int32 card_get_link_race(lua_State *L);
static int32 card_get_race_in_grave(lua_State *L);
static int32 card_get_attack(lua_State *L);
static int32 card_get_origin_attack(lua_State *L);
static int32 card_get_text_attack(lua_State *L);
static int32 card_get_defense(lua_State *L);
static int32 card_get_origin_defense(lua_State *L);
static int32 card_get_text_defense(lua_State *L);
static int32 card_get_previous_code_onfield(lua_State *L);
static int32 card_get_previous_type_onfield(lua_State *L);
static int32 card_get_previous_level_onfield(lua_State *L);
static int32 card_get_previous_rank_onfield(lua_State *L);
static int32 card_get_previous_attribute_onfield(lua_State *L);
static int32 card_get_previous_race_onfield(lua_State *L);
static int32 card_get_previous_attack_onfield(lua_State *L);
static int32 card_get_previous_defense_onfield(lua_State *L);
static int32 card_get_owner(lua_State *L);
static int32 card_get_controler(lua_State *L);
static int32 card_get_previous_controler(lua_State *L);
static int32 card_set_reason(lua_State *L);
static int32 card_get_reason(lua_State *L);
static int32 card_get_reason_card(lua_State *L);
static int32 card_get_reason_player(lua_State *L);
static int32 card_get_reason_effect(lua_State *L);
static int32 card_get_position(lua_State *L);
static int32 card_get_previous_position(lua_State *L);
static int32 card_get_battle_position(lua_State *L);
static int32 card_get_location(lua_State *L);
static int32 card_get_previous_location(lua_State *L);
static int32 card_get_sequence(lua_State *L);
static int32 card_get_previous_sequence(lua_State *L);
static int32 card_get_summon_type(lua_State *L);
static int32 card_get_summon_location(lua_State *L);
static int32 card_get_summon_player(lua_State *L);
static int32 card_get_destination(lua_State *L);
static int32 card_get_leave_field_dest(lua_State *L);
static int32 card_get_turnid(lua_State *L);
static int32 card_get_fieldid(lua_State *L);
static int32 card_get_fieldidr(lua_State *L);
static int32 card_is_origin_code_rule(lua_State *L);
static int32 card_is_code(lua_State *L);
static int32 card_is_type(lua_State *L);
static int32 card_is_fusion_type(lua_State *L);
static int32 card_is_synchro_type(lua_State *L);
static int32 card_is_xyz_type(lua_State *L);
static int32 card_is_link_type(lua_State *L);
static int32 card_is_level(lua_State *L);
static int32 card_is_rank(lua_State *L);
static int32 card_is_link(lua_State *L);
static int32 card_is_attack(lua_State *L);
static int32 card_is_defense(lua_State *L);
static int32 card_is_race(lua_State *L);
static int32 card_is_link_race(lua_State *L);
static int32 card_is_attribute(lua_State *L);
static int32 card_is_fusion_attribute(lua_State *L);
static int32 card_is_link_attribute(lua_State *L);
static int32 card_is_extra_deck_monster(lua_State *L);
static int32 card_is_reason(lua_State *L);
static int32 card_is_summon_type(lua_State *L);
static int32 card_is_summon_location(lua_State *L);
static int32 card_is_summon_player(lua_State *L);
static int32 card_is_status(lua_State *L);
static int32 card_is_not_tuner(lua_State *L);
static int32 card_set_status(lua_State *L);
static int32 card_is_dual_state(lua_State *L);
static int32 card_enable_dual_state(lua_State *L);
static int32 card_set_turn_counter(lua_State *L);
static int32 card_get_turn_counter(lua_State *L);
static int32 card_set_material(lua_State *L);
static int32 card_get_material(lua_State *L);
static int32 card_get_material_count(lua_State *L);
static int32 card_get_equip_group(lua_State *L);
static int32 card_get_equip_count(lua_State *L);
static int32 card_get_equip_target(lua_State *L);
static int32 card_get_pre_equip_target(lua_State *L);
static int32 card_check_equip_target(lua_State *L);
static int32 card_check_union_target(lua_State *L);
static int32 card_get_union_count(lua_State *L);
static int32 card_get_overlay_group(lua_State *L);
static int32 card_get_overlay_count(lua_State *L);
static int32 card_get_overlay_target(lua_State *L);
static int32 card_check_remove_overlay_card(lua_State *L);
static int32 card_remove_overlay_card(lua_State *L);
static int32 card_get_attacked_group(lua_State *L);
static int32 card_get_attacked_group_count(lua_State *L);
static int32 card_get_attacked_count(lua_State *L);
static int32 card_get_battled_group(lua_State *L);
static int32 card_get_battled_group_count(lua_State *L);
static int32 card_get_attack_announced_count(lua_State *L);
static int32 card_is_direct_attacked(lua_State *L);
static int32 card_set_card_target(lua_State *L);
static int32 card_get_card_target(lua_State *L);
static int32 card_get_first_card_target(lua_State *L);
static int32 card_get_card_target_count(lua_State *L);
static int32 card_is_has_card_target(lua_State *L);
static int32 card_cancel_card_target(lua_State *L);
static int32 card_get_owner_target(lua_State *L);
static int32 card_get_owner_target_count(lua_State *L);
static int32 card_get_activate_effect(lua_State *L);
static int32 card_check_activate_effect(lua_State *L);
static int32 card_get_tuner_limit(lua_State * L);
static int32 card_get_hand_synchro(lua_State * L);
static int32 card_register_effect(lua_State *L);
static int32 card_is_has_effect(lua_State *L);
static int32 card_reset_effect(lua_State *L);
static int32 card_get_effect_count(lua_State *L);
static int32 card_register_flag_effect(lua_State *L);
static int32 card_get_flag_effect(lua_State *L);
static int32 card_reset_flag_effect(lua_State *L);
static int32 card_set_flag_effect_label(lua_State *L);
static int32 card_get_flag_effect_label(lua_State *L);
static int32 card_create_relation(lua_State *L);
static int32 card_release_relation(lua_State *L);
static int32 card_create_effect_relation(lua_State *L);
static int32 card_release_effect_relation(lua_State *L);
static int32 card_clear_effect_relation(lua_State *L);
static int32 card_is_relate_to_effect(lua_State *L);
static int32 card_is_relate_to_chain(lua_State *L);
static int32 card_is_relate_to_card(lua_State *L);
static int32 card_is_relate_to_battle(lua_State *L);
static int32 card_copy_effect(lua_State *L);
static int32 card_replace_effect(lua_State *L);
static int32 card_enable_revive_limit(lua_State *L);
static int32 card_complete_procedure(lua_State *L);
static int32 card_is_disabled(lua_State *L);
static int32 card_is_destructable(lua_State *L);
static int32 card_is_summonable(lua_State *L);
static int32 card_is_special_summonable_card(lua_State *L);
static int32 card_is_fusion_summonable_card(lua_State *L);
static int32 card_is_msetable(lua_State *L);
static int32 card_is_ssetable(lua_State *L);
static int32 card_is_special_summonable(lua_State *L);
static int32 card_is_synchro_summonable(lua_State *L);
static int32 card_is_xyz_summonable(lua_State *L);
static int32 card_is_link_summonable(lua_State *L);
static int32 card_is_can_be_summoned(lua_State *L);
static int32 card_is_can_be_special_summoned(lua_State *L);
static int32 card_is_able_to_hand(lua_State *L);
static int32 card_is_able_to_grave(lua_State *L);
static int32 card_is_able_to_deck(lua_State *L);
static int32 card_is_able_to_extra(lua_State *L);
static int32 card_is_able_to_remove(lua_State *L);
static int32 card_is_able_to_hand_as_cost(lua_State *L);
static int32 card_is_able_to_grave_as_cost(lua_State *L);
static int32 card_is_able_to_deck_as_cost(lua_State *L);
static int32 card_is_able_to_extra_as_cost(lua_State *L);
static int32 card_is_able_to_deck_or_extra_as_cost(lua_State *L);
static int32 card_is_able_to_remove_as_cost(lua_State *L);
static int32 card_is_releasable(lua_State *L);
static int32 card_is_releasable_by_effect(lua_State *L);
static int32 card_is_discardable(lua_State *L);
static int32 card_is_attackable(lua_State *L);
static int32 card_is_chain_attackable(lua_State *L);
static int32 card_is_faceup(lua_State *L);
static int32 card_is_faceup_ex(lua_State *L);
static int32 card_is_attack_pos(lua_State *L);
static int32 card_is_facedown(lua_State *L);
static int32 card_is_defense_pos(lua_State *L);
static int32 card_is_position(lua_State *L);
static int32 card_is_pre_position(lua_State *L);
static int32 card_is_controler(lua_State *L);
static int32 card_is_pre_controler(lua_State *L);
static int32 card_is_onfield(lua_State *L);
static int32 card_is_location(lua_State *L);
static int32 card_is_pre_location(lua_State *L);
static int32 card_is_level_below(lua_State *L);
static int32 card_is_level_above(lua_State *L);
static int32 card_is_rank_below(lua_State *L);
static int32 card_is_rank_above(lua_State *L);
static int32 card_is_link_below(lua_State *L);
static int32 card_is_link_above(lua_State *L);
static int32 card_is_attack_below(lua_State *L);
static int32 card_is_attack_above(lua_State *L);
static int32 card_is_defense_below(lua_State *L);
static int32 card_is_defense_above(lua_State *L);
static int32 card_is_public(lua_State *L);
static int32 card_is_forbidden(lua_State *L);
static int32 card_is_able_to_change_controler(lua_State *L);
static int32 card_is_controler_can_be_changed(lua_State *L);
static int32 card_add_counter(lua_State *L);
static int32 card_remove_counter(lua_State *L);
static int32 card_get_counter(lua_State *L);
static int32 card_enable_counter_permit(lua_State *L);
static int32 card_set_counter_limit(lua_State *L);
static int32 card_is_can_change_position(lua_State *L);
static int32 card_is_can_turn_set(lua_State *L);
static int32 card_is_can_add_counter(lua_State *L);
static int32 card_is_can_remove_counter(lua_State *L);
static int32 card_is_can_have_counter(lua_State* L);
static int32 card_is_can_overlay(lua_State *L);
static int32 card_is_can_be_fusion_material(lua_State *L);
static int32 card_is_can_be_synchro_material(lua_State *L);
static int32 card_is_can_be_ritual_material(lua_State *L);
static int32 card_is_can_be_xyz_material(lua_State *L);
static int32 card_is_can_be_link_material(lua_State *L);
static int32 card_check_fusion_material(lua_State *L);
static int32 card_check_fusion_substitute(lua_State *L);
static int32 card_is_immune_to_effect(lua_State *L);
static int32 card_is_can_be_disabled_by_effect(lua_State* L);
static int32 card_is_can_be_effect_target(lua_State *L);
static int32 card_is_can_be_battle_target(lua_State *L);
static int32 card_add_monster_attribute(lua_State *L);
static int32 card_cancel_to_grave(lua_State *L);
static int32 card_get_tribute_requirement(lua_State *L);
static int32 card_get_battle_target(lua_State *L);
static int32 card_get_attackable_target(lua_State *L);
static int32 card_set_hint(lua_State *L);
static int32 card_reverse_in_deck(lua_State *L);
static int32 card_set_unique_onfield(lua_State *L);
static int32 card_check_unique_onfield(lua_State *L);
static int32 card_reset_negate_effect(lua_State *L);
static int32 card_assume_prop(lua_State *L);
static int32 card_set_spsummon_once(lua_State *L);
static int32_t card_get_code(lua_State *L);
static int32_t card_get_origin_code(lua_State *L);
static int32_t card_get_origin_code_rule(lua_State *L);
static int32_t card_get_fusion_code(lua_State *L);
static int32_t card_get_link_code(lua_State *L);
static int32_t card_is_fusion_code(lua_State *L);
static int32_t card_is_link_code(lua_State *L);
static int32_t card_is_set_card(lua_State *L);
static int32_t card_is_origin_set_card(lua_State *L);
static int32_t card_is_pre_set_card(lua_State *L);
static int32_t card_is_fusion_set_card(lua_State *L);
static int32_t card_is_link_set_card(lua_State *L);
static int32_t card_is_special_summon_set_card(lua_State *L);
static int32_t card_get_type(lua_State *L);
static int32_t card_get_origin_type(lua_State *L);
static int32_t card_get_fusion_type(lua_State *L);
static int32_t card_get_synchro_type(lua_State *L);
static int32_t card_get_xyz_type(lua_State *L);
static int32_t card_get_link_type(lua_State *L);
static int32_t card_get_level(lua_State *L);
static int32_t card_get_rank(lua_State *L);
static int32_t card_get_link(lua_State *L);
static int32_t card_get_synchro_level(lua_State *L);
static int32_t card_get_ritual_level(lua_State *L);
static int32_t card_get_origin_level(lua_State *L);
static int32_t card_get_origin_rank(lua_State *L);
static int32_t card_is_xyz_level(lua_State *L);
static int32_t card_get_lscale(lua_State *L);
static int32_t card_get_origin_lscale(lua_State *L);
static int32_t card_get_rscale(lua_State *L);
static int32_t card_get_origin_rscale(lua_State *L);
static int32_t card_get_current_scale(lua_State *L);
static int32_t card_is_link_marker(lua_State *L);
static int32_t card_get_linked_group(lua_State *L);
static int32_t card_get_linked_group_count(lua_State *L);
static int32_t card_get_linked_zone(lua_State *L);
static int32_t card_get_mutual_linked_group(lua_State *L);
static int32_t card_get_mutual_linked_group_count(lua_State *L);
static int32_t card_get_mutual_linked_zone(lua_State *L);
static int32_t card_is_link_state(lua_State *L);
static int32_t card_is_extra_link_state(lua_State *L);
static int32_t card_get_column_group(lua_State *L);
static int32_t card_get_column_group_count(lua_State *L);
static int32_t card_get_column_zone(lua_State *L);
static int32_t card_is_all_column(lua_State *L);
static int32_t card_get_attribute(lua_State *L);
static int32_t card_get_origin_attribute(lua_State *L);
static int32_t card_get_fusion_attribute(lua_State *L);
static int32_t card_get_link_attribute(lua_State *L);
static int32_t card_get_attribute_in_grave(lua_State *L);
static int32_t card_get_race(lua_State *L);
static int32_t card_get_origin_race(lua_State *L);
static int32_t card_get_link_race(lua_State *L);
static int32_t card_get_race_in_grave(lua_State *L);
static int32_t card_get_attack(lua_State *L);
static int32_t card_get_origin_attack(lua_State *L);
static int32_t card_get_text_attack(lua_State *L);
static int32_t card_get_defense(lua_State *L);
static int32_t card_get_origin_defense(lua_State *L);
static int32_t card_get_text_defense(lua_State *L);
static int32_t card_get_previous_code_onfield(lua_State *L);
static int32_t card_get_previous_type_onfield(lua_State *L);
static int32_t card_get_previous_level_onfield(lua_State *L);
static int32_t card_get_previous_rank_onfield(lua_State *L);
static int32_t card_get_previous_attribute_onfield(lua_State *L);
static int32_t card_get_previous_race_onfield(lua_State *L);
static int32_t card_get_previous_attack_onfield(lua_State *L);
static int32_t card_get_previous_defense_onfield(lua_State *L);
static int32_t card_get_previous_overlay_count_onfield(lua_State *L);
static int32_t card_get_owner(lua_State *L);
static int32_t card_get_controler(lua_State *L);
static int32_t card_get_previous_controler(lua_State *L);
static int32_t card_set_reason(lua_State *L);
static int32_t card_get_reason(lua_State *L);
static int32_t card_get_reason_card(lua_State *L);
static int32_t card_get_reason_player(lua_State *L);
static int32_t card_get_reason_effect(lua_State *L);
static int32_t card_get_position(lua_State *L);
static int32_t card_get_previous_position(lua_State *L);
static int32_t card_get_battle_position(lua_State *L);
static int32_t card_get_location(lua_State *L);
static int32_t card_get_previous_location(lua_State *L);
static int32_t card_get_sequence(lua_State *L);
static int32_t card_get_previous_sequence(lua_State *L);
static int32_t card_get_summon_type(lua_State *L);
static int32_t card_get_summon_location(lua_State *L);
static int32_t card_get_summon_player(lua_State *L);
static int32_t card_get_destination(lua_State *L);
static int32_t card_get_leave_field_dest(lua_State *L);
static int32_t card_get_turnid(lua_State *L);
static int32_t card_get_fieldid(lua_State *L);
static int32_t card_get_fieldidr(lua_State *L);
static int32_t card_is_origin_code_rule(lua_State *L);
static int32_t card_is_code(lua_State *L);
static int32_t card_is_type(lua_State *L);
static int32_t card_is_all_types(lua_State *L);
static int32_t card_is_fusion_type(lua_State *L);
static int32_t card_is_synchro_type(lua_State *L);
static int32_t card_is_xyz_type(lua_State *L);
static int32_t card_is_link_type(lua_State *L);
static int32_t card_is_level(lua_State *L);
static int32_t card_is_rank(lua_State *L);
static int32_t card_is_link(lua_State *L);
static int32_t card_is_attack(lua_State *L);
static int32_t card_is_defense(lua_State *L);
static int32_t card_is_race(lua_State *L);
static int32_t card_is_link_race(lua_State *L);
static int32_t card_is_attribute(lua_State *L);
static int32_t card_is_fusion_attribute(lua_State *L);
static int32_t card_is_link_attribute(lua_State *L);
static int32_t card_is_non_attribute(lua_State *L);
static int32_t card_is_extra_deck_monster(lua_State *L);
static int32_t card_is_reason(lua_State *L);
static int32_t card_is_all_reasons(lua_State *L);
static int32_t card_is_summon_type(lua_State *L);
static int32_t card_is_summon_location(lua_State *L);
static int32_t card_is_summon_player(lua_State *L);
static int32_t card_get_special_summon_info(lua_State *L);
static int32_t card_is_status(lua_State *L);
static int32_t card_is_not_tuner(lua_State *L);
static int32_t card_is_tuner(lua_State* L);
static int32_t card_is_original_effect_property(lua_State* L);
static int32_t card_is_effect_property(lua_State* L);
static int32_t card_set_status(lua_State *L);
static int32_t card_is_dual_state(lua_State *L);
static int32_t card_enable_dual_state(lua_State *L);
static int32_t card_set_turn_counter(lua_State *L);
static int32_t card_get_turn_counter(lua_State *L);
static int32_t card_set_material(lua_State *L);
static int32_t card_get_material(lua_State *L);
static int32_t card_get_material_count(lua_State *L);
static int32_t card_get_equip_group(lua_State *L);
static int32_t card_get_equip_count(lua_State *L);
static int32_t card_get_equip_target(lua_State *L);
static int32_t card_get_pre_equip_target(lua_State *L);
static int32_t card_check_equip_target(lua_State *L);
static int32_t card_check_union_target(lua_State *L);
static int32_t card_get_union_count(lua_State *L);
static int32_t card_get_overlay_group(lua_State *L);
static int32_t card_get_overlay_count(lua_State *L);
static int32_t card_get_overlay_target(lua_State *L);
static int32_t card_check_remove_overlay_card(lua_State *L);
static int32_t card_remove_overlay_card(lua_State *L);
static int32_t card_get_attacked_group(lua_State *L);
static int32_t card_get_attacked_group_count(lua_State *L);
static int32_t card_get_attacked_count(lua_State *L);
static int32_t card_get_battled_group(lua_State *L);
static int32_t card_get_battled_group_count(lua_State *L);
static int32_t card_get_attack_announced_count(lua_State *L);
static int32_t card_is_direct_attacked(lua_State *L);
static int32_t card_set_card_target(lua_State *L);
static int32_t card_get_card_target(lua_State *L);
static int32_t card_get_first_card_target(lua_State *L);
static int32_t card_get_card_target_count(lua_State *L);
static int32_t card_is_has_card_target(lua_State *L);
static int32_t card_cancel_card_target(lua_State *L);
static int32_t card_get_owner_target(lua_State *L);
static int32_t card_get_owner_target_count(lua_State *L);
static int32_t card_get_activate_effect(lua_State *L);
static int32_t card_check_activate_effect(lua_State *L);
static int32_t card_get_tuner_limit(lua_State * L);
static int32_t card_get_hand_synchro(lua_State * L);
static int32_t card_register_effect(lua_State *L);
static int32_t card_is_has_effect(lua_State *L);
static int32_t card_reset_effect(lua_State *L);
static int32_t card_get_effect_count(lua_State *L);
static int32_t card_register_flag_effect(lua_State *L);
static int32_t card_get_flag_effect(lua_State *L);
static int32_t card_reset_flag_effect(lua_State *L);
static int32_t card_set_flag_effect_label(lua_State *L);
static int32_t card_get_flag_effect_label(lua_State *L);
static int32_t card_create_relation(lua_State *L);
static int32_t card_release_relation(lua_State *L);
static int32_t card_create_effect_relation(lua_State *L);
static int32_t card_release_effect_relation(lua_State *L);
static int32_t card_clear_effect_relation(lua_State *L);
static int32_t card_is_relate_to_effect(lua_State *L);
static int32_t card_is_relate_to_chain(lua_State *L);
static int32_t card_is_relate_to_card(lua_State *L);
static int32_t card_is_relate_to_battle(lua_State *L);
static int32_t card_copy_effect(lua_State *L);
static int32_t card_replace_effect(lua_State *L);
static int32_t card_enable_revive_limit(lua_State *L);
static int32_t card_complete_procedure(lua_State *L);
static int32_t card_is_disabled(lua_State *L);
static int32_t card_is_destructable(lua_State *L);
static int32_t card_is_summonable(lua_State *L);
static int32_t card_is_special_summonable_card(lua_State *L);
static int32_t card_is_fusion_summonable_card(lua_State *L);
static int32_t card_is_msetable(lua_State *L);
static int32_t card_is_ssetable(lua_State *L);
static int32_t card_is_special_summonable(lua_State *L);
static int32_t card_is_synchro_summonable(lua_State *L);
static int32_t card_is_xyz_summonable(lua_State *L);
static int32_t card_is_link_summonable(lua_State *L);
static int32_t card_is_can_be_summoned(lua_State *L);
static int32_t card_is_can_be_special_summoned(lua_State *L);
static int32_t card_is_can_be_placed_on_field(lua_State *L);
static int32_t card_is_able_to_hand(lua_State *L);
static int32_t card_is_able_to_grave(lua_State *L);
static int32_t card_is_able_to_deck(lua_State *L);
static int32_t card_is_able_to_extra(lua_State *L);
static int32_t card_is_able_to_remove(lua_State *L);
static int32_t card_is_able_to_hand_as_cost(lua_State *L);
static int32_t card_is_able_to_grave_as_cost(lua_State *L);
static int32_t card_is_able_to_deck_as_cost(lua_State *L);
static int32_t card_is_able_to_extra_as_cost(lua_State *L);
static int32_t card_is_able_to_deck_or_extra_as_cost(lua_State *L);
static int32_t card_is_able_to_remove_as_cost(lua_State *L);
static int32_t card_is_releasable(lua_State *L);
static int32_t card_is_releasable_by_effect(lua_State *L);
static int32_t card_is_discardable(lua_State *L);
static int32_t card_is_attackable(lua_State *L);
static int32_t card_is_chain_attackable(lua_State *L);
static int32_t card_is_faceup(lua_State *L);
static int32_t card_is_faceup_ex(lua_State *L);
static int32_t card_is_attack_pos(lua_State *L);
static int32_t card_is_facedown(lua_State *L);
static int32_t card_is_defense_pos(lua_State *L);
static int32_t card_is_position(lua_State *L);
static int32_t card_is_pre_position(lua_State *L);
static int32_t card_is_controler(lua_State *L);
static int32_t card_is_pre_controler(lua_State *L);
static int32_t card_is_onfield(lua_State *L);
static int32_t card_is_location(lua_State *L);
static int32_t card_is_pre_location(lua_State *L);
static int32_t card_is_level_below(lua_State *L);
static int32_t card_is_level_above(lua_State *L);
static int32_t card_is_rank_below(lua_State *L);
static int32_t card_is_rank_above(lua_State *L);
static int32_t card_is_link_below(lua_State *L);
static int32_t card_is_link_above(lua_State *L);
static int32_t card_is_attack_below(lua_State *L);
static int32_t card_is_attack_above(lua_State *L);
static int32_t card_is_defense_below(lua_State *L);
static int32_t card_is_defense_above(lua_State *L);
static int32_t card_is_has_level(lua_State *L);
static int32_t card_is_has_defense(lua_State *L);
static int32_t card_is_public(lua_State *L);
static int32_t card_is_forbidden(lua_State *L);
static int32_t card_is_able_to_change_controler(lua_State *L);
static int32_t card_is_controler_can_be_changed(lua_State *L);
static int32_t card_add_counter(lua_State *L);
static int32_t card_remove_counter(lua_State *L);
static int32_t card_get_counter(lua_State *L);
static int32_t card_enable_counter_permit(lua_State *L);
static int32_t card_set_counter_limit(lua_State *L);
static int32_t card_is_can_change_position(lua_State *L);
static int32_t card_is_can_turn_set(lua_State *L);
static int32_t card_is_can_add_counter(lua_State *L);
static int32_t card_is_can_remove_counter(lua_State *L);
static int32_t card_is_can_have_counter(lua_State* L);
static int32_t card_is_can_overlay(lua_State *L);
static int32_t card_is_can_be_fusion_material(lua_State *L);
static int32_t card_is_can_be_synchro_material(lua_State *L);
static int32_t card_is_can_be_ritual_material(lua_State *L);
static int32_t card_is_can_be_xyz_material(lua_State *L);
static int32_t card_is_can_be_link_material(lua_State *L);
static int32_t card_check_fusion_material(lua_State *L);
static int32_t card_check_fusion_substitute(lua_State *L);
static int32_t card_is_immune_to_effect(lua_State *L);
static int32_t card_is_can_be_disabled_by_effect(lua_State* L);
static int32_t card_is_can_be_effect_target(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);
//Effect functions
static int32 effect_new(lua_State *L);
static int32 effect_newex(lua_State *L);
static int32 effect_clone(lua_State *L);
static int32 effect_reset(lua_State *L);
static int32 effect_get_field_id(lua_State *L);
static int32 effect_set_description(lua_State *L);
static int32 effect_set_code(lua_State *L);
static int32 effect_set_range(lua_State *L);
static int32 effect_set_target_range(lua_State *L);
static int32 effect_set_absolute_range(lua_State *L);
static int32 effect_set_count_limit(lua_State *L);
static int32 effect_set_reset(lua_State *L);
static int32 effect_set_type(lua_State *L);
static int32 effect_set_property(lua_State *L);
static int32 effect_set_label(lua_State *L);
static int32 effect_set_label_object(lua_State *L);
static int32 effect_set_category(lua_State *L);
static int32 effect_set_hint_timing(lua_State *L);
static int32 effect_set_condition(lua_State *L);
static int32 effect_set_target(lua_State *L);
static int32 effect_set_cost(lua_State *L);
static int32 effect_set_value(lua_State *L);
static int32 effect_set_operation(lua_State *L);
static int32 effect_set_owner_player(lua_State *L);
static int32 effect_get_description(lua_State *L);
static int32 effect_get_code(lua_State *L);
static int32 effect_get_type(lua_State *L);
static int32 effect_get_property(lua_State *L);
static int32 effect_get_label(lua_State *L);
static int32 effect_get_label_object(lua_State *L);
static int32 effect_get_category(lua_State *L);
static int32 effect_get_owner(lua_State *L);
static int32 effect_get_handler(lua_State *L);
static int32 effect_get_owner_player(lua_State *L);
static int32 effect_get_handler_player(lua_State *L);
static int32 effect_get_condition(lua_State *L);
static int32 effect_get_target(lua_State *L);
static int32 effect_get_cost(lua_State *L);
static int32 effect_get_value(lua_State *L);
static int32 effect_get_operation(lua_State *L);
static int32 effect_get_active_type(lua_State *L);
static int32 effect_is_active_type(lua_State *L);
static int32 effect_is_has_property(lua_State *L);
static int32 effect_is_has_category(lua_State *L);
static int32 effect_is_has_type(lua_State *L);
static int32 effect_is_activatable(lua_State *L);
static int32 effect_is_activated(lua_State *L);
static int32 effect_is_cost_checked(lua_State *L);
static int32 effect_set_cost_check(lua_State *L);
static int32 effect_get_activate_location(lua_State *L);
static int32 effect_get_activate_sequence(lua_State *L);
static int32 effect_check_count_limit(lua_State *L);
static int32 effect_use_count_limit(lua_State *L);
static int32_t get_effect_property(lua_State* L, effect_member type);
static int32_t is_effect_has_property(lua_State* L, effect_member type);
static int32_t effect_new(lua_State *L);
static int32_t effect_newex(lua_State *L);
static int32_t effect_clone(lua_State *L);
static int32_t effect_reset(lua_State *L);
static int32_t effect_get_field_id(lua_State *L);
static int32_t effect_set_description(lua_State *L);
static int32_t effect_set_code(lua_State *L);
static int32_t effect_set_range(lua_State *L);
static int32_t effect_set_target_range(lua_State *L);
static int32_t effect_set_absolute_range(lua_State *L);
static int32_t effect_set_count_limit(lua_State *L);
static int32_t effect_set_reset(lua_State *L);
static int32_t effect_set_type(lua_State *L);
static int32_t effect_set_property(lua_State *L);
static int32_t effect_set_label(lua_State *L);
static int32_t effect_set_label_object(lua_State *L);
static int32_t effect_set_category(lua_State *L);
static int32_t effect_set_hint_timing(lua_State *L);
static int32_t effect_set_condition(lua_State *L);
static int32_t effect_set_target(lua_State *L);
static int32_t effect_set_cost(lua_State *L);
static int32_t effect_set_value(lua_State *L);
static int32_t effect_set_operation(lua_State *L);
static int32_t effect_set_owner_player(lua_State *L);
static int32_t effect_get_description(lua_State *L);
static int32_t effect_get_code(lua_State *L);
static int32_t effect_get_type(lua_State *L);
static int32_t effect_get_property(lua_State *L);
static int32_t effect_get_label(lua_State *L);
static int32_t effect_get_label_object(lua_State *L);
static int32_t effect_get_category(lua_State *L);
static int32_t effect_get_range(lua_State* L);
static int32_t effect_get_owner(lua_State *L);
static int32_t effect_get_handler(lua_State *L);
static int32_t effect_get_owner_player(lua_State *L);
static int32_t effect_get_handler_player(lua_State *L);
static int32_t effect_get_condition(lua_State *L);
static int32_t effect_get_target(lua_State *L);
static int32_t effect_get_cost(lua_State *L);
static int32_t effect_get_value(lua_State *L);
static int32_t effect_get_operation(lua_State *L);
static int32_t effect_get_active_type(lua_State *L);
static int32_t effect_is_active_type(lua_State *L);
static int32_t effect_is_has_property(lua_State *L);
static int32_t effect_is_has_category(lua_State *L);
static int32_t effect_is_has_range(lua_State* L);
static int32_t effect_is_has_type(lua_State *L);
static int32_t effect_is_activatable(lua_State *L);
static int32_t effect_is_activated(lua_State *L);
static int32_t effect_is_cost_checked(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);
//Group functions
static int32 group_new(lua_State *L);
static int32 group_clone(lua_State *L);
static int32 group_from_cards(lua_State *L);
static int32 group_delete(lua_State *L);
static int32 group_keep_alive(lua_State *L);
static int32 group_clear(lua_State *L);
static int32 group_add_card(lua_State *L);
static int32 group_remove_card(lua_State *L);
static int32 group_get_next(lua_State *L);
static int32 group_get_first(lua_State *L);
static int32 group_get_count(lua_State *L);
static int32 group_for_each(lua_State *L);
static int32 group_filter(lua_State *L);
static int32 group_filter_count(lua_State *L);
static int32 group_filter_select(lua_State *L);
static int32 group_select(lua_State *L);
static int32 group_select_unselect(lua_State *L);
static int32 group_random_select(lua_State *L);
static int32 group_is_exists(lua_State *L);
static int32 group_check_with_sum_equal(lua_State *L);
static int32 group_select_with_sum_equal(lua_State *L);
static int32 group_check_with_sum_greater(lua_State *L);
static int32 group_select_with_sum_greater(lua_State *L);
static int32 group_get_min_group(lua_State *L);
static int32 group_get_max_group(lua_State *L);
static int32 group_get_sum(lua_State *L);
static int32 group_get_class_count(lua_State *L);
static int32 group_remove(lua_State *L);
static int32 group_merge(lua_State *L);
static int32 group_sub(lua_State *L);
static int32 group_equal(lua_State *L);
static int32 group_is_contains(lua_State *L);
static int32 group_search_card(lua_State *L);
static int32 group_get_bin_class_count(lua_State *L);
static int32_t group_new(lua_State *L);
static int32_t group_clone(lua_State *L);
static int32_t group_from_cards(lua_State *L);
static int32_t group_delete(lua_State *L);
static int32_t group_keep_alive(lua_State *L);
static int32_t group_clear(lua_State *L);
static int32_t group_add_card(lua_State *L);
static int32_t group_remove_card(lua_State *L);
static int32_t group_get_next(lua_State *L);
static int32_t group_get_first(lua_State *L);
static int32_t group_get_count(lua_State *L);
static int32_t group_filter(lua_State *L);
static int32_t group_filter_count(lua_State *L);
static int32_t group_filter_select(lua_State *L);
static int32_t group_select(lua_State *L);
static int32_t group_select_unselect(lua_State *L);
static int32_t group_random_select(lua_State *L);
static int32_t group_cancelable_select(lua_State *L);
static int32_t group_is_exists(lua_State *L);
static int32_t group_check_with_sum_equal(lua_State *L);
static int32_t group_select_with_sum_equal(lua_State *L);
static int32_t group_check_with_sum_greater(lua_State *L);
static int32_t group_select_with_sum_greater(lua_State *L);
static int32_t group_get_min_group(lua_State *L);
static int32_t group_get_max_group(lua_State *L);
static int32_t group_get_sum(lua_State *L);
static int32_t group_get_class_count(lua_State *L);
static int32_t group_remove(lua_State *L);
static int32_t group_merge(lua_State *L);
static int32_t group_sub(lua_State *L);
static int32_t group_equal(lua_State *L);
static int32_t group_is_contains(lua_State *L);
static int32_t group_search_card(lua_State *L);
static int32_t group_get_bin_class_count(lua_State *L);
static void open_grouplib(lua_State *L);
//Duel functions
static int32 duel_enable_global_flag(lua_State *L);
static int32 duel_get_lp(lua_State *L);
static int32 duel_set_lp(lua_State *L);
static int32 duel_get_turn_player(lua_State *L);
static int32 duel_get_turn_count(lua_State *L);
static int32 duel_get_draw_count(lua_State *L);
static int32 duel_register_effect(lua_State *L);
static int32 duel_register_flag_effect(lua_State *L);
static int32 duel_get_flag_effect(lua_State *L);
static int32 duel_reset_flag_effect(lua_State *L);
static int32 duel_set_flag_effect_label(lua_State *L);
static int32 duel_get_flag_effect_label(lua_State *L);
static int32 duel_destroy(lua_State *L);
static int32 duel_remove(lua_State *L);
static int32 duel_sendto_grave(lua_State *L);
static int32 duel_summon(lua_State *L);
static int32 duel_special_summon_rule(lua_State *L);
static int32 duel_synchro_summon(lua_State *L);
static int32 duel_xyz_summon(lua_State *L);
static int32 duel_link_summon(lua_State *L);
static int32 duel_setm(lua_State *L);
static int32 duel_sets(lua_State *L);
static int32 duel_create_token(lua_State *L);
static int32 duel_special_summon(lua_State *L);
static int32 duel_special_summon_step(lua_State *L);
static int32 duel_special_summon_complete(lua_State *L);
static int32 duel_sendto_hand(lua_State *L);
static int32 duel_sendto_deck(lua_State *L);
static int32 duel_sendto_extra(lua_State *L);
static int32 duel_get_operated_group(lua_State *L);
static int32 duel_is_can_add_counter(lua_State *L);
static int32 duel_remove_counter(lua_State *L);
static int32 duel_is_can_remove_counter(lua_State *L);
static int32 duel_get_counter(lua_State *L);
static int32 duel_change_form(lua_State *L);
static int32 duel_release(lua_State *L);
static int32 duel_move_to_field(lua_State *L);
static int32 duel_return_to_field(lua_State *L);
static int32 duel_move_sequence(lua_State *L);
static int32 duel_swap_sequence(lua_State *L);
static int32 duel_activate_effect(lua_State *L);
static int32 duel_set_chain_limit(lua_State *L);
static int32 duel_set_chain_limit_p(lua_State *L);
static int32 duel_get_chain_material(lua_State *L);
static int32 duel_confirm_decktop(lua_State *L);
static int32 duel_confirm_extratop(lua_State *L);
static int32 duel_confirm_cards(lua_State *L);
static int32 duel_sort_decktop(lua_State *L);
static int32 duel_check_event(lua_State *L);
static int32 duel_raise_event(lua_State *L);
static int32 duel_raise_single_event(lua_State *L);
static int32 duel_check_timing(lua_State *L);
static int32 duel_is_environment(lua_State *L);
static int32_t duel_enable_global_flag(lua_State *L);
static int32_t duel_get_lp(lua_State *L);
static int32_t duel_set_lp(lua_State *L);
static int32_t duel_is_turn_player(lua_State *L);
static int32_t duel_get_turn_player(lua_State *L);
static int32_t duel_get_turn_count(lua_State *L);
static int32_t duel_get_draw_count(lua_State *L);
static int32_t duel_register_effect(lua_State *L);
static int32_t duel_register_flag_effect(lua_State *L);
static int32_t duel_get_flag_effect(lua_State *L);
static int32_t duel_reset_flag_effect(lua_State *L);
static int32_t duel_set_flag_effect_label(lua_State *L);
static int32_t duel_get_flag_effect_label(lua_State *L);
static int32_t duel_destroy(lua_State *L);
static int32_t duel_remove(lua_State *L);
static int32_t duel_sendto_grave(lua_State *L);
static int32_t duel_summon(lua_State *L);
static int32_t duel_special_summon_rule(lua_State *L);
static int32_t duel_synchro_summon(lua_State *L);
static int32_t duel_xyz_summon(lua_State *L);
static int32_t duel_link_summon(lua_State *L);
static int32_t duel_setm(lua_State *L);
static int32_t duel_sets(lua_State *L);
static int32_t duel_create_token(lua_State *L);
static int32_t duel_special_summon(lua_State *L);
static int32_t duel_special_summon_step(lua_State *L);
static int32_t duel_special_summon_complete(lua_State *L);
static int32_t duel_sendto_hand(lua_State *L);
static int32_t duel_sendto_deck(lua_State *L);
static int32_t duel_sendto_extra(lua_State *L);
static int32_t duel_get_operated_group(lua_State *L);
static int32_t duel_is_can_add_counter(lua_State *L);
static int32_t duel_remove_counter(lua_State *L);
static int32_t duel_is_can_remove_counter(lua_State *L);
static int32_t duel_get_counter(lua_State *L);
static int32_t duel_change_form(lua_State *L);
static int32_t duel_release(lua_State *L);
static int32_t duel_move_to_field(lua_State *L);
static int32_t duel_return_to_field(lua_State *L);
static int32_t duel_move_sequence(lua_State *L);
static int32_t duel_swap_sequence(lua_State *L);
static int32_t duel_activate_effect(lua_State *L);
static int32_t duel_set_chain_limit(lua_State *L);
static int32_t duel_set_chain_limit_p(lua_State *L);
static int32_t duel_get_chain_material(lua_State *L);
static int32_t duel_confirm_decktop(lua_State *L);
static int32_t duel_confirm_extratop(lua_State *L);
static int32_t duel_confirm_cards(lua_State *L);
static int32_t duel_sort_decktop(lua_State *L);
static int32_t duel_check_event(lua_State *L);
static int32_t duel_raise_event(lua_State *L);
static int32_t duel_raise_single_event(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 duel_draw(lua_State *L);
static int32 duel_damage(lua_State *L);
static int32 duel_recover(lua_State *L);
static int32 duel_rd_complete(lua_State *L);
static int32 duel_equip(lua_State *L);
static int32 duel_equip_complete(lua_State *L);
static int32 duel_get_control(lua_State *L);
static int32 duel_swap_control(lua_State *L);
static int32 duel_check_lp_cost(lua_State *L);
static int32 duel_pay_lp_cost(lua_State *L);
static int32 duel_discard_deck(lua_State *L);
static int32 duel_discard_hand(lua_State *L);
static int32 duel_disable_shuffle_check(lua_State *L);
static int32 duel_disable_self_destroy_check(lua_State *L);
static int32 duel_shuffle_deck(lua_State *L);
static int32 duel_shuffle_extra(lua_State *L);
static int32 duel_shuffle_hand(lua_State *L);
static int32 duel_shuffle_setcard(lua_State *L);
static int32 duel_change_attacker(lua_State *L);
static int32 duel_change_attack_target(lua_State *L);
static int32 duel_calculate_damage(lua_State *L);
static int32 duel_get_battle_damage(lua_State *L);
static int32 duel_change_battle_damage(lua_State *L);
static int32 duel_change_target(lua_State *L);
static int32 duel_change_target_player(lua_State *L);
static int32 duel_change_target_param(lua_State *L);
static int32 duel_break_effect(lua_State *L);
static int32 duel_change_effect(lua_State *L);
static int32 duel_negate_activate(lua_State *L);
static int32 duel_negate_effect(lua_State *L);
static int32 duel_negate_related_chain(lua_State *L);
static int32 duel_disable_summon(lua_State *L);
static int32 duel_increase_summon_count(lua_State *L);
static int32 duel_check_summon_count(lua_State *L);
static int32 duel_get_location_count(lua_State *L);
static int32 duel_get_mzone_count(lua_State *L);
static int32 duel_get_location_count_fromex(lua_State *L);
static int32 duel_get_usable_mzone_count(lua_State *L);
static int32 duel_get_linked_group(lua_State *L);
static int32 duel_get_linked_group_count(lua_State *L);
static int32 duel_get_linked_zone(lua_State *L);
static int32 duel_get_field_card(lua_State *L);
static int32 duel_check_location(lua_State *L);
static int32 duel_get_current_chain(lua_State *L);
static int32 duel_get_chain_info(lua_State *L);
static int32 duel_get_chain_event(lua_State *L);
static int32 duel_get_first_target(lua_State *L);
static int32 duel_get_targets_relate_to_chain(lua_State *L);
static int32 duel_get_current_phase(lua_State *L);
static int32 duel_skip_phase(lua_State *L);
static int32 duel_is_damage_calculated(lua_State *L);
static int32 duel_get_attacker(lua_State *L);
static int32 duel_get_attack_target(lua_State* L);
static int32 duel_get_battle_monster(lua_State* L);
static int32 duel_disable_attack(lua_State *L);
static int32 duel_chain_attack(lua_State *L);
static int32 duel_readjust(lua_State *L);
static int32 duel_adjust_instantly(lua_State *L);
static int32 duel_adjust_all(lua_State *L);
static int32_t duel_win(lua_State *L);
static int32_t duel_draw(lua_State *L);
static int32_t duel_damage(lua_State *L);
static int32_t duel_recover(lua_State *L);
static int32_t duel_rd_complete(lua_State *L);
static int32_t duel_equip(lua_State *L);
static int32_t duel_equip_complete(lua_State *L);
static int32_t duel_get_control(lua_State *L);
static int32_t duel_swap_control(lua_State *L);
static int32_t duel_check_lp_cost(lua_State *L);
static int32_t duel_pay_lp_cost(lua_State *L);
static int32_t duel_discard_deck(lua_State *L);
static int32_t duel_discard_hand(lua_State *L);
static int32_t duel_disable_shuffle_check(lua_State *L);
static int32_t duel_disable_self_destroy_check(lua_State *L);
static int32_t duel_reveal_select_deck_sequence(lua_State *L);
static int32_t duel_shuffle_deck(lua_State *L);
static int32_t duel_shuffle_extra(lua_State *L);
static int32_t duel_shuffle_hand(lua_State *L);
static int32_t duel_shuffle_setcard(lua_State *L);
static int32_t duel_change_attacker(lua_State *L);
static int32_t duel_change_attack_target(lua_State *L);
static int32_t duel_calculate_damage(lua_State *L);
static int32_t duel_get_battle_damage(lua_State *L);
static int32_t duel_change_battle_damage(lua_State *L);
static int32_t duel_change_target(lua_State *L);
static int32_t duel_change_target_player(lua_State *L);
static int32_t duel_change_target_param(lua_State *L);
static int32_t duel_break_effect(lua_State *L);
static int32_t duel_change_effect(lua_State *L);
static int32_t duel_negate_activate(lua_State *L);
static int32_t duel_negate_effect(lua_State *L);
static int32_t duel_negate_related_chain(lua_State *L);
static int32_t duel_disable_summon(lua_State *L);
static int32_t duel_increase_summon_count(lua_State *L);
static int32_t duel_check_summon_count(lua_State *L);
static int32_t duel_get_location_count(lua_State *L);
static int32_t duel_get_mzone_count(lua_State *L);
static int32_t duel_get_szone_count(lua_State *L);
static int32_t duel_get_location_count_fromex(lua_State *L);
static int32_t duel_get_usable_mzone_count(lua_State *L);
static int32_t duel_get_linked_group(lua_State *L);
static int32_t duel_get_linked_group_count(lua_State *L);
static int32_t duel_get_linked_zone(lua_State *L);
static int32_t duel_get_field_card(lua_State *L);
static int32_t duel_check_location(lua_State *L);
static int32_t duel_get_current_chain(lua_State *L);
static int32_t duel_get_ready_chain(lua_State* L);
static int32_t duel_get_chain_info(lua_State *L);
static int32_t duel_get_chain_event(lua_State *L);
static int32_t duel_get_first_target(lua_State *L);
static int32_t duel_get_targets_relate_to_chain(lua_State *L);
static int32_t duel_is_phase(lua_State *L);
static int32_t duel_is_main_phase(lua_State *L);
static int32_t duel_is_battle_phase(lua_State *L);
static int32_t duel_get_current_phase(lua_State *L);
static int32_t duel_skip_phase(lua_State *L);
static int32_t duel_is_damage_calculated(lua_State *L);
static int32_t duel_get_attacker(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 duel_get_field_group_count(lua_State *L);
static int32 duel_get_decktop_group(lua_State *L);
static int32 duel_get_extratop_group(lua_State *L);
static int32 duel_get_matching_group(lua_State *L);
static int32 duel_get_matching_count(lua_State *L);
static int32 duel_get_first_matching_card(lua_State *L);
static int32 duel_is_existing_matching_card(lua_State *L);
static int32 duel_select_matching_cards(lua_State *L);
static int32 duel_get_release_group(lua_State *L);
static int32 duel_get_release_group_count(lua_State *L);
static int32 duel_check_release_group(lua_State *L);
static int32 duel_select_release_group(lua_State *L);
static int32 duel_check_release_group_ex(lua_State *L);
static int32 duel_select_release_group_ex(lua_State *L);
static int32 duel_get_tribute_group(lua_State *L);
static int32 duel_get_tribute_count(lua_State *L);
static int32 duel_check_tribute(lua_State *L);
static int32 duel_select_tribute(lua_State *L);
static int32 duel_get_target_count(lua_State *L);
static int32 duel_is_existing_target(lua_State *L);
static int32 duel_select_target(lua_State *L);
static int32 duel_select_fusion_material(lua_State *L);
static int32 duel_set_fusion_material(lua_State *L);
static int32 duel_set_synchro_material(lua_State *L);
static int32 duel_select_synchro_material(lua_State *L);
static int32 duel_check_synchro_material(lua_State *L);
static int32 duel_select_tuner_material(lua_State *L);
static int32 duel_check_tuner_material(lua_State *L);
static int32 duel_get_ritual_material(lua_State *L);
static int32 duel_get_ritual_material_ex(lua_State *L);
static int32 duel_release_ritual_material(lua_State *L);
static int32 duel_get_fusion_material(lua_State *L);
static int32 duel_is_summon_cancelable(lua_State *L);
static int32 duel_set_must_select_cards(lua_State *L);
static int32 duel_grab_must_select_cards(lua_State *L);
static int32 duel_set_target_card(lua_State *L);
static int32 duel_clear_target_card(lua_State *L);
static int32 duel_set_target_player(lua_State *L);
static int32 duel_set_target_param(lua_State *L);
static int32 duel_set_operation_info(lua_State *L);
static int32 duel_get_operation_info(lua_State *L);
static int32 duel_get_operation_count(lua_State *L);
static int32 duel_clear_operation_info(lua_State *L);
static int32 duel_check_xyz_material(lua_State *L);
static int32 duel_select_xyz_material(lua_State *L);
static int32 duel_overlay(lua_State *L);
static int32 duel_get_overlay_group(lua_State *L);
static int32 duel_get_overlay_count(lua_State *L);
static int32 duel_check_remove_overlay_card(lua_State *L);
static int32 duel_remove_overlay_card(lua_State *L);
static int32_t duel_get_field_group(lua_State *L);
static int32_t duel_get_field_group_count(lua_State *L);
static int32_t duel_get_decktop_group(lua_State *L);
static int32_t duel_get_extratop_group(lua_State *L);
static int32_t duel_get_matching_group(lua_State *L);
static int32_t duel_get_matching_count(lua_State *L);
static int32_t duel_get_first_matching_card(lua_State *L);
static int32_t duel_is_existing_matching_card(lua_State *L);
static int32_t duel_select_matching_cards(lua_State *L);
static int32_t duel_get_release_group(lua_State *L);
static int32_t duel_get_release_group_count(lua_State *L);
static int32_t duel_check_release_group(lua_State *L);
static int32_t duel_select_release_group(lua_State *L);
static int32_t duel_check_release_group_ex(lua_State *L);
static int32_t duel_select_release_group_ex(lua_State *L);
static int32_t duel_get_tribute_group(lua_State *L);
static int32_t duel_get_tribute_count(lua_State *L);
static int32_t duel_check_tribute(lua_State *L);
static int32_t duel_select_tribute(lua_State *L);
static int32_t duel_get_target_count(lua_State *L);
static int32_t duel_is_existing_target(lua_State *L);
static int32_t duel_select_target(lua_State *L);
static int32_t duel_get_must_material(lua_State *L);
static int32_t duel_check_must_material(lua_State *L);
static int32_t duel_select_fusion_material(lua_State *L);
static int32_t duel_set_fusion_material(lua_State *L);
static int32_t duel_set_synchro_material(lua_State *L);
static int32_t duel_get_synchro_material(lua_State *L);
static int32_t duel_select_synchro_material(lua_State *L);
static int32_t duel_check_synchro_material(lua_State *L);
static int32_t duel_select_tuner_material(lua_State *L);
static int32_t duel_check_tuner_material(lua_State *L);
static int32_t duel_get_ritual_material(lua_State *L);
static int32_t duel_get_ritual_material_ex(lua_State *L);
static int32_t duel_release_ritual_material(lua_State *L);
static int32_t duel_get_fusion_material(lua_State *L);
static int32_t duel_is_summon_cancelable(lua_State *L);
static int32_t duel_set_must_select_cards(lua_State *L);
static int32_t duel_grab_must_select_cards(lua_State *L);
static int32_t duel_set_target_card(lua_State *L);
static int32_t duel_clear_target_card(lua_State *L);
static int32_t duel_set_target_player(lua_State *L);
static int32_t duel_set_target_param(lua_State *L);
static int32_t duel_set_operation_info(lua_State *L);
static int32_t duel_get_operation_info(lua_State *L);
static int32_t duel_get_operation_count(lua_State *L);
static int32_t duel_clear_operation_info(lua_State *L);
static int32_t duel_check_xyz_material(lua_State *L);
static int32_t duel_select_xyz_material(lua_State *L);
static int32_t duel_overlay(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 duel_hint_selection(lua_State *L);
static int32 duel_select_effect_yesno(lua_State *L);
static int32 duel_select_yesno(lua_State *L);
static int32 duel_select_option(lua_State *L);
static int32 duel_select_sequence(lua_State *L);
static int32 duel_select_position(lua_State *L);
static int32 duel_select_disable_field(lua_State *L);
static int32 duel_select_field(lua_State *L);
static int32 duel_announce_race(lua_State *L);
static int32 duel_announce_attribute(lua_State *L);
static int32 duel_announce_level(lua_State *L);
static int32 duel_announce_card(lua_State *L);
static int32 duel_announce_type(lua_State *L);
static int32 duel_announce_number(lua_State *L);
static int32 duel_announce_coin(lua_State *L);
static int32 duel_toss_coin(lua_State *L);
static int32 duel_toss_dice(lua_State *L);
static int32 duel_rock_paper_scissors(lua_State *L);
static int32 duel_get_coin_result(lua_State *L);
static int32 duel_get_dice_result(lua_State *L);
static int32 duel_set_coin_result(lua_State *L);
static int32 duel_set_dice_result(lua_State *L);
static int32_t duel_hint(lua_State *L);
static int32_t duel_get_last_select_hint(lua_State *L);
static int32_t duel_hint_selection(lua_State *L);
static int32_t duel_select_effect_yesno(lua_State *L);
static int32_t duel_select_yesno(lua_State *L);
static int32_t duel_select_option(lua_State *L);
static int32_t duel_select_sequence(lua_State *L);
static int32_t duel_select_position(lua_State *L);
static int32_t duel_select_disable_field(lua_State *L);
static int32_t duel_select_field(lua_State *L);
static int32_t duel_announce_race(lua_State *L);
static int32_t duel_announce_attribute(lua_State *L);
static int32_t duel_announce_level(lua_State *L);
static int32_t duel_announce_card(lua_State *L);
static int32_t duel_announce_type(lua_State *L);
static int32_t duel_announce_number(lua_State *L);
static int32_t duel_announce_coin(lua_State *L);
static int32_t duel_toss_coin(lua_State *L);
static int32_t duel_toss_dice(lua_State *L);
static int32_t duel_rock_paper_scissors(lua_State *L);
static int32_t duel_get_coin_result(lua_State *L);
static int32_t duel_get_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 duel_is_player_can_draw(lua_State *L);
static int32 duel_is_player_can_discard_deck(lua_State *L);
static int32 duel_is_player_can_discard_deck_as_cost(lua_State *L);
static int32 duel_is_player_can_summon(lua_State *L);
static int32 duel_is_player_can_mset(lua_State *L);
static int32 duel_is_player_can_sset(lua_State *L);
static int32 duel_is_player_can_spsummon(lua_State *L);
static int32 duel_is_player_can_flipsummon(lua_State *L);
static int32 duel_is_player_can_spsummon_monster(lua_State *L);
static int32 duel_is_player_can_spsummon_count(lua_State *L);
static int32 duel_is_player_can_release(lua_State *L);
static int32 duel_is_player_can_remove(lua_State *L);
static int32 duel_is_player_can_send_to_hand(lua_State *L);
static int32 duel_is_player_can_send_to_grave(lua_State *L);
static int32 duel_is_player_can_send_to_deck(lua_State *L);
static int32 duel_is_player_can_additional_summon(lua_State *L);
static int32 duel_is_chain_negatable(lua_State *L);
static int32 duel_is_chain_disablable(lua_State *L);
static int32 duel_is_chain_disabled(lua_State *L);
static int32 duel_check_chain_target(lua_State *L);
static int32 duel_check_chain_uniqueness(lua_State *L);
static int32 duel_get_activity_count(lua_State *L);
static int32 duel_check_phase_activity(lua_State *L);
static int32 duel_add_custom_activity_counter(lua_State *L);
static int32 duel_get_custom_activity_count(lua_State *L);
static int32 duel_is_able_to_enter_bp(lua_State *L);
static int32 duel_get_battled_count(lua_State *L);
static int32_t duel_is_player_affected_by_effect(lua_State *L);
static int32_t duel_is_player_can_draw(lua_State *L);
static int32_t duel_is_player_can_discard_deck(lua_State *L);
static int32_t duel_is_player_can_discard_deck_as_cost(lua_State *L);
static int32_t duel_is_player_can_summon(lua_State *L);
static int32_t duel_is_player_can_mset(lua_State *L);
static int32_t duel_is_player_can_sset(lua_State *L);
static int32_t duel_is_player_can_spsummon(lua_State *L);
static int32_t duel_is_player_can_flipsummon(lua_State *L);
static int32_t duel_is_player_can_spsummon_monster(lua_State *L);
static int32_t duel_is_player_can_spsummon_count(lua_State *L);
static int32_t duel_is_player_can_release(lua_State *L);
static int32_t duel_is_player_can_remove(lua_State *L);
static int32_t duel_is_player_can_send_to_hand(lua_State *L);
static int32_t duel_is_player_can_send_to_grave(lua_State *L);
static int32_t duel_is_player_can_send_to_deck(lua_State *L);
static int32_t duel_is_player_can_additional_summon(lua_State *L);
static int32_t duel_is_chain_solving(lua_State *L);
static int32_t duel_is_chain_negatable(lua_State *L);
static int32_t duel_is_chain_disablable(lua_State *L);
static int32_t duel_is_chain_disabled(lua_State *L);
static int32_t duel_check_chain_target(lua_State *L);
static int32_t duel_check_chain_uniqueness(lua_State *L);
static int32_t duel_get_activity_count(lua_State *L);
static int32_t duel_check_phase_activity(lua_State *L);
static int32_t duel_add_custom_activity_counter(lua_State *L);
static int32_t duel_get_custom_activity_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
static int32 duel_swap_deck_and_grave(lua_State *L);
static int32 duel_majestic_copy(lua_State *L);
static int32_t duel_swap_deck_and_grave(lua_State *L);
static int32_t duel_majestic_copy(lua_State *L);
static void open_duellib(lua_State *L);
//group metamethods
//__len is in the group lib, which is same as group_get_count
static int32 group_meta_add(lua_State *L);
static int32 group_meta_sub(lua_State *L);
static int32 group_meta_band(lua_State *L);
static int32 group_meta_bxor(lua_State *L);
static int32_t group_meta_add(lua_State *L);
static int32_t group_meta_sub(lua_State *L);
static int32_t group_meta_band(lua_State *L);
static int32_t group_meta_bxor(lua_State *L);
//preload
static int32 debug_message(lua_State *L);
static int32 debug_add_card(lua_State *L);
static int32 debug_set_player_info(lua_State *L);
static int32 debug_pre_summon(lua_State *L);
static int32 debug_pre_equip(lua_State *L);
static int32 debug_pre_set_target(lua_State *L);
static int32 debug_pre_add_counter(lua_State *L);
static int32 debug_reload_field_begin(lua_State *L);
static int32 debug_reload_field_end(lua_State *L);
static int32 debug_set_ai_name(lua_State *L);
static int32 debug_show_hint(lua_State *L);
static int32_t debug_message(lua_State *L);
static int32_t debug_add_card(lua_State *L);
static int32_t debug_set_player_info(lua_State *L);
static int32_t debug_pre_summon(lua_State *L);
static int32_t debug_pre_equip(lua_State *L);
static int32_t debug_pre_set_target(lua_State *L);
static int32_t debug_pre_add_counter(lua_State *L);
static int32_t debug_reload_field_begin(lua_State *L);
static int32_t debug_reload_field_end(lua_State *L);
static int32_t debug_set_ai_name(lua_State *L);
static int32_t debug_show_hint(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