Commit 15c1afb8 authored by wind2009's avatar wind2009

Merge remote-tracking branch 'upstream/master'

parents b67ba8a3 a3fe63a3
name: Automated Test Build
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
runs-on: windows-2022
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install lua
run: |
bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://www.lua.org/ftp/lua-5.4.6.tar.gz ; exit 0"
tar xzf lua-5.4.6.tar.gz
move lua-5.4.6 lua
- name: Premake
run: |
bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/premake/premake-core/releases/download/v5.0.0-beta2/premake-5.0.0-beta2-windows.zip ; exit 0"
7z x premake-5.0.0-beta2-windows.zip
move premake\lua.lua lua\premake5.lua
move premake\dll.lua dll.lua
.\premake5.exe vs2022 --file=dll.lua
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v2
- name: Build
run: |
msbuild build\ocgcoredll.sln /t:Build /p:"Configuration=Release;Platform=Win32"
msbuild build\ocgcoredll.sln /t:Build /p:"Configuration=Release;Platform=x64"
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
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
name: Automated Test Build
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
jobs:
build:
runs-on: windows-2022
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install lua
run: |
bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://www.lua.org/ftp/lua-5.4.6.tar.gz ; exit 0"
tar xzf lua-5.4.6.tar.gz
move lua-5.4.6 lua
- name: Premake
run: |
bash -c "curl --retry 5 --connect-timeout 30 --location --remote-header-name --remote-name https://github.com/premake/premake-core/releases/download/v5.0.0-beta2/premake-5.0.0-beta2-windows.zip ; exit 0"
7z x premake-5.0.0-beta2-windows.zip
move premake\lua.lua lua\premake5.lua
move premake\dll.lua dll.lua
.\premake5.exe vs2022 --file=dll.lua
- name: Add msbuild to PATH
uses: microsoft/setup-msbuild@v2
- name: Build
run: |
msbuild build\ocgcoredll.sln /t:Build /p:"Configuration=Release;Platform=Win32"
msbuild build\ocgcoredll.sln /t:Build /p:"Configuration=Release;Platform=x64"
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
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
.vscode/
/premake5.exe
/build
/lua
.vscode/
/premake5.exe
/build
/lua
#ifndef BUFFER_H
#define BUFFER_H
#ifndef CORE_BUFFER_H
#define CORE_BUFFER_H
#include <cstring>
#include <vector>
......@@ -34,4 +34,4 @@ inline void vector_write(std::vector<unsigned char>& buffer, T value) {
vector_write_block(buffer, &value, sizeof(T));
}
#endif //BUFFER_H
#endif // !CORE_BUFFER_H
This diff is collapsed.
......@@ -24,6 +24,9 @@ class effect;
class group;
struct chain;
using card_set = std::set<card*, card_sort>;
using card_vector = std::vector<card*>;
struct card_state {
uint32 code{ 0 };
uint32 code2{ 0 };
......@@ -113,15 +116,13 @@ public:
return std::hash<uint16>()(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, uint16>;
using effect_count = std::map<uint32, int32>;
class attacker_map : public std::unordered_map<uint16, std::pair<card*, uint32>> {
class attacker_map : public std::unordered_map<uint32, std::pair<card*, uint32>> {
public:
void addcard(card* pcard);
uint32 findcard(card* pcard);
......@@ -212,7 +213,7 @@ public:
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)); }
bool is_extra_deck_monster() const { return !!(data.type & TYPES_EXTRA_DECK); }
int32 get_infos(byte* buf, uint32 query_flag, int32 use_cache = TRUE);
uint32 get_info_location();
......@@ -265,8 +266,8 @@ public:
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);
int32 get_status(uint32 status) const;
int32 is_status(uint32 status) const;
uint32 get_column_zone(int32 location);
void get_column_cards(card_set* cset);
int32 is_all_column();
......@@ -287,8 +288,8 @@ public:
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);
int32 copy_effect(uint32 code, uint32 reset, int32 count);
int32 replace_effect(uint32 code, uint32 reset, int32 count);
void reset(uint32 id, uint32 reset_type);
void reset_effect_count();
void refresh_disable_status();
......@@ -341,7 +342,7 @@ public:
void get_unique_target(card_set* cset, int32 controler, card* icard = nullptr);
int32 check_cost_condition(int32 ecode, int32 playerid);
int32 check_cost_condition(int32 ecode, int32 playerid, int32 sumtype);
int32 is_summonable_card();
int32 is_summonable_card() const;
int32 is_spsummonable_card();
int32 is_fusion_summonable_card(uint32 summon_type);
int32 is_spsummonable(effect* proc, material_info info = null_info);
......@@ -393,31 +394,31 @@ public:
};
//Summon Type in summon_info
#define SUMMON_TYPE_NORMAL 0x10000000
#define SUMMON_TYPE_ADVANCE 0x11000000
#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
#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 0x12000000
#define SUMMON_TYPE_DUAL 0x12000000U
//bitfield blocks
#define SUMMON_VALUE_MAIN_TYPE 0xf0000000
#define SUMMON_VALUE_SUB_TYPE 0x0f000000
#define SUMMON_VALUE_LOCATION 0x00ff0000
#define SUMMON_VALUE_CUSTOM_TYPE 0x0000ffff
#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 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
......
......@@ -67,6 +67,10 @@ struct card_data {
for (int i = ctr; i < SIZE_SETCODE; ++i)
setcode[i] = 0;
}
uint32 get_original_code() const {
return is_alternative() ? alias : code;
}
};
#endif /* CARD_DATA_H_ */
......@@ -43,7 +43,9 @@ typedef signed char int8;
#define NULL 0
#endif
#define CURRENT_RULE 5 //current rule: 5, Master Rule 2020
#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 //
......@@ -108,6 +110,8 @@ typedef signed char int8;
#define TYPE_SPSUMMON 0x2000000 //
#define TYPE_LINK 0x4000000 //
#define TYPES_EXTRA_DECK (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK)
//Attributes
#define ATTRIBUTE_ALL 0x7f //
#define ATTRIBUTE_EARTH 0x01 //
......
......@@ -20,9 +20,10 @@ 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];
std::vector<byte> message_buffer;
interpreter* lua;
......
......@@ -138,7 +138,6 @@ int32 effect::is_single_ready() {
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))
......@@ -164,10 +163,11 @@ int32 effect::check_count_limit(uint8 playerid) {
if(count_limit == 0)
return FALSE;
if(count_code) {
uint32 code = count_code & MAX_CARD_ID;
uint32 limit_code = count_code & MAX_CARD_ID;
uint32 limit_type = count_code & 0xf0000000;
uint32 count = count_limit_max;
if(code == EFFECT_COUNT_CODE_SINGLE) {
if(pduel->game_field->get_effect_code((count_code & 0xf0000000) | get_handler()->fieldid, PLAYER_NONE) >= count)
if(limit_code == EFFECT_COUNT_CODE_SINGLE) {
if(pduel->game_field->get_effect_code(limit_type | get_handler()->fieldid, PLAYER_NONE) >= count)
return FALSE;
} else {
if(pduel->game_field->get_effect_code(count_code, playerid) >= count)
......@@ -299,7 +299,7 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
return FALSE;
} else if(!(type & EFFECT_TYPE_CONTINUOUS)) {
card* phandler = get_handler();
if(!(phandler->get_type() & TYPE_MONSTER) && (get_active_type() & TYPE_MONSTER))
if(!(phandler->get_type() & TYPE_MONSTER) && (get_active_type(FALSE) & TYPE_MONSTER))
return FALSE;
if((type & EFFECT_TYPE_QUICK_O) && is_flag(EFFECT_FLAG_DELAY) && !in_range(phandler))
return FALSE;
......@@ -318,7 +318,7 @@ 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)))
......@@ -657,7 +657,7 @@ int32 effect::reset(uint32 reset_level, uint32 reset_type) {
}
return FALSE;
}
void effect::dec_count(uint32 playerid) {
void effect::dec_count(uint8 playerid) {
if(!is_flag(EFFECT_FLAG_COUNT_LIMIT))
return;
if(count_limit == 0)
......@@ -665,9 +665,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 & MAX_CARD_ID;
if(code == EFFECT_COUNT_CODE_SINGLE)
pduel->game_field->add_effect_code((count_code & 0xf0000000) | get_handler()->fieldid, PLAYER_NONE);
uint32 limit_code = count_code & MAX_CARD_ID;
uint32 limit_type = count_code & 0xf0000000;
if(limit_code == EFFECT_COUNT_CODE_SINGLE)
pduel->game_field->add_effect_code(limit_type | get_handler()->fieldid, PLAYER_NONE);
else
pduel->game_field->add_effect_code(count_code, playerid);
}
......@@ -738,6 +739,9 @@ void effect::get_value(effect* peffect, uint32 extraargs, std::vector<int32>* re
result->push_back((int32)value);
}
}
int32 effect::get_integer_value() {
return is_flag(EFFECT_FLAG_FUNC_VALUE) ? 0 : value;
}
int32 effect::check_value_condition(uint32 extraargs) {
if(is_flag(EFFECT_FLAG_FUNC_VALUE)) {
pduel->lua->add_param(this, PARAM_TYPE_EFFECT, TRUE);
......@@ -836,9 +840,9 @@ void effect::set_active_type() {
if(active_type & TYPE_TRAPMONSTER)
active_type &= ~TYPE_TRAP;
}
uint32 effect::get_active_type() {
uint32 effect::get_active_type(uint8 uselast) {
if(type & 0x7f0) {
if(active_type)
if(active_type && uselast)
return active_type;
else if((type & EFFECT_TYPE_ACTIVATE) && (get_handler()->data.type & TYPE_PENDULUM))
return TYPE_PENDULUM + TYPE_SPELL;
......
......@@ -43,7 +43,7 @@ public:
uint16 o_range{ 0 };
uint8 count_limit{ 0 };
uint8 count_limit_max{ 0 };
uint16 reset_count{ 0 };
int32 reset_count{ 0 };
uint32 reset_flag{ 0 };
uint32 count_code{ 0 };
uint32 category{ 0 };
......@@ -89,7 +89,7 @@ public:
int32 is_chainable(uint8 tp);
int32 is_hand_trigger();
int32 reset(uint32 reset_level, uint32 reset_type);
void dec_count(uint32 playerid = 2);
void dec_count(uint8 playerid = PLAYER_NONE);
void recharge();
int32 get_value(uint32 extraargs = 0);
int32 get_value(card* pcard, uint32 extraargs = 0);
......@@ -97,6 +97,7 @@ public:
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 get_integer_value();
int32 check_value_condition(uint32 extraargs = 0);
void* get_label_object();
int32 get_speed();
......@@ -109,14 +110,14 @@ public:
int32 in_range(const chain& ch);
void set_activate_location();
void set_active_type();
uint32 get_active_type();
uint32 get_active_type(uint8 uselast = TRUE);
int32 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);
}
};
......@@ -213,10 +214,10 @@ enum effect_flag2 : uint32 {
EFFECT_FLAG2_WICKED = 0x0004,
EFFECT_FLAG2_OPTION = 0x0008,
};
inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
{
constexpr effect_flag operator|(effect_flag flag1, effect_flag flag2) {
return static_cast<effect_flag>(static_cast<uint32>(flag1) | static_cast<uint32>(flag2));
}
constexpr uint32 INTERNAL_FLAGS = EFFECT_FLAG_INITIAL | EFFECT_FLAG_FUNC_VALUE | EFFECT_FLAG_COUNT_LIMIT | EFFECT_FLAG_FIELD_ONLY | EFFECT_FLAG_ABSOLUTE_TARGET;
//========== Codes ==========
#define EFFECT_IMMUNE_EFFECT 1 //
#define EFFECT_DISABLE 2 //
......
......@@ -8,7 +8,6 @@
#ifndef EFFECTSET_H_
#define EFFECTSET_H_
#include <stdlib.h>
#include <array>
#include <vector>
#include <algorithm>
......
This diff is collapsed.
......@@ -11,6 +11,7 @@
#include "common.h"
#include "card.h"
#include "effectset.h"
#include "interpreter.h"
#include <vector>
#include <set>
#include <map>
......@@ -32,6 +33,8 @@ class duel;
class group;
class effect;
bool check_playerid(int32 playerid);
struct tevent {
card* trigger_card{ nullptr };
group* event_cards{ nullptr };
......@@ -77,7 +80,6 @@ struct chain {
};
struct player_info {
using card_vector = std::vector<card*>;
int32 lp{ 0 };
int32 start_count{ 0 };
int32 draw_count{ 0 };
......@@ -149,12 +151,14 @@ struct processor_unit {
uint32 arg2{ 0 };
uint32 arg3{ 0 };
uint32 arg4{ 0 };
void* ptr1{ nullptr };
void* ptr2{ nullptr };
int32 value1{ 0 };
int32 value2{ 0 };
int32 value3{ 0 };
int32 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;
......@@ -167,7 +171,6 @@ union return_value {
};
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>;
......@@ -175,7 +178,6 @@ struct processor {
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) {}
......@@ -307,7 +309,7 @@ struct processor {
int32 duel_options{ 0 };
int32 duel_rule{ CURRENT_RULE };
uint32 copy_reset{ 0 };
uint8 copy_reset_count{ 0 };
int32 copy_reset_count{ 0 };
uint32 last_control_changed_id{ 0 };
uint32 set_group_used_zones{ 0 };
uint8 set_group_seq[7]{};
......@@ -362,9 +364,7 @@ struct processor {
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>;
......@@ -393,8 +393,8 @@ public:
void swap_card(card* pcard1, card* pcard2, uint8 new_sequence1, uint8 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);
card* get_field_card(uint8 playerid, uint32 general_location, uint8 sequence);
int32 is_location_useable(uint8 playerid, uint32 general_location, uint8 sequence) const;
int32 get_useable_count(card* pcard, uint8 playerid, uint8 location, uint8 uplayer, uint32 reason, uint32 zone = 0xff, uint32* list = nullptr);
int32 get_useable_count_fromex(card* pcard, uint8 playerid, uint8 uplayer, uint32 zone = 0xff, uint32* list = nullptr);
int32 get_spsummonable_count(card* pcard, uint8 playerid, uint32 zone = 0xff, uint32* list = nullptr);
......@@ -416,6 +416,7 @@ public:
void reset_sequence(uint8 playerid, uint8 location);
void swap_deck_and_grave(uint8 playerid);
void reverse_deck(uint8 playerid);
void refresh_player_info(uint8 playerid);
void tag_swap(uint8 playerid);
void add_effect(effect* peffect, uint8 owner_player = 2);
......@@ -432,19 +433,19 @@ public:
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 = nullptr, int32 fcount = 0, int32 is_target = FALSE);
int32 filter_matching_card(lua_State* L, int32 findex, uint8 self, uint32 location1, uint32 location2, group* pgroup, card* pexception, group* pexgroup, uint32 extraargs, card** pret = nullptr, 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, uint32 reason);
int32 check_release_list(uint8 playerid, int32 count, int32 use_con, int32 use_hand, int32 fun, int32 exarg, card* exc, group* exg, uint32 reason);
int32 get_release_list(lua_State* L, 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, uint32 reason);
int32 check_release_list(lua_State* L, uint8 playerid, int32 count, int32 use_con, int32 use_hand, int32 fun, int32 exarg, card* exc, group* exg, uint32 reason);
int32 get_summon_release_list(card* target, card_set* release_list, card_set* ex_list, card_set* ex_list_oneof, group* mg = nullptr, 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_xyz_material(lua_State* L, 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 update_disable_check_list(effect* peffect);
......@@ -476,15 +477,17 @@ public:
int32 get_must_material_list(uint8 playerid, uint32 limit, card_set* must_list);
int32 check_must_material(group* mg, uint8 playerid, uint32 limit);
void get_synchro_material(uint8 playerid, card_set* material, effect* tuner_limit = nullptr);
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);
//check material
int32 check_synchro_material(lua_State* L, card* pcard, int32 findex1, int32 findex2, int32 min, int32 max, card* smat, group* mg);
int32 check_tuner_material(lua_State* L, 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 check_xyz_material(lua_State* L, 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);
......@@ -620,7 +623,7 @@ public:
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_synchro_material(int16 step, uint8 playerid, card* pcard, int32 min, int32 max, card* smat, group* mg, int32 filter1, int32 filter2);
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);
......
......@@ -16,9 +16,10 @@
class card;
class duel;
using card_set = std::set<card*, card_sort>;
class group {
public:
using card_set = std::set<card*, card_sort>;
duel* pduel;
card_set container;
card_set::iterator it;
......
......@@ -6,7 +6,6 @@
*/
#include <cstring>
#include <utility>
#include "duel.h"
#include "group.h"
#include "card.h"
......@@ -54,23 +53,19 @@ interpreter::~interpreter() {
int32 interpreter::register_card(card *pcard) {
//create a card in by userdata
luaL_checkstack(lua_state, 1, nullptr);
luaL_checkstack(current_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); //-1
//some userdata may be created in script like token so use current_state
luaL_checkstack(current_state, 1, nullptr);
lua_rawgeti(current_state, LUA_REGISTRYINDEX, pcard->ref_handle); //+1 userdata
//load script
if(pcard->data.is_alternative())
load_card_script(pcard->data.alias);
else
load_card_script(pcard->data.code);
load_card_script(pcard->data.get_original_code());
//stack: table cxxx, userdata
//set metatable of pointer to base script
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(pcard->data.code && 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);
......@@ -82,7 +77,7 @@ int32 interpreter::register_card(card *pcard) {
void interpreter::register_effect(effect *peffect) {
if (!peffect)
return;
//create a effect in by userdata
//create a effect in userdata
luaL_checkstack(lua_state, 3, nullptr);
effect ** ppeffect = (effect**) lua_newuserdata(lua_state, sizeof(effect*));
*ppeffect = peffect;
......@@ -131,11 +126,12 @@ void interpreter::unregister_group(group *pgroup) {
}
int32 interpreter::load_script(const char* script_name) {
int32 len = 0;
byte* buffer = read_script(script_name, &len);
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);
luaL_checkstack(current_state, 2, nullptr);
int32 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));
handle_message(pduel, 1);
......@@ -146,12 +142,12 @@ int32 interpreter::load_script(const char* script_name) {
--no_action;
return OPERATION_SUCCESS;
}
//push table cxxx onto the stack of current_state
int32 interpreter::load_card_script(uint32 code) {
char class_name[20];
sprintf(class_name, "c%d", code);
luaL_checkstack(current_state, 1, nullptr);
lua_getglobal(current_state, class_name); //+1 table cxxx
//if script is not loaded, create and load it
if (lua_isnil(current_state, -1)) {
luaL_checkstack(current_state, 5, nullptr);
lua_pop(current_state, 1); //-1
......@@ -164,17 +160,22 @@ int32 interpreter::load_card_script(uint32 code) {
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
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); //+1
lua_setglobal(current_state, "self_table"); //-1
lua_pushnil(current_state); //+1
lua_setglobal(current_state, "self_code"); //-1 table cxxx {__index: cxxx }
card_data cdata;
int32 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);
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;
}
......@@ -302,7 +303,7 @@ int32 interpreter::call_function(int32 f, uint32 param_count, int32 ret_count) {
}
int32 interpreter::call_card_function(card* pcard, const char* f, uint32 param_count, int32 ret_count) {
if (param_count != params.size()) {
sprintf(pduel->strbuffer, "\"CallCardFunction\"(c%d.%s): incorrect parameter count", pcard->data.code, f);
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;
......@@ -311,7 +312,7 @@ int32 interpreter::call_card_function(card* pcard, const char* f, uint32 param_c
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);
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();
......@@ -408,33 +409,33 @@ int32 interpreter::check_condition(int32 f, uint32 param_count) {
}
return OPERATION_FAIL;
}
int32 interpreter::check_matching(card* pcard, int32 findex, int32 extraargs) {
if(!findex || lua_isnil(current_state, findex))
int32 interpreter::check_filter(lua_State* L, card* pcard, int32 findex, int32 extraargs) {
if (!findex || lua_isnil(L, findex))
return TRUE;
++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));
if (lua_pcall(current_state, 1 + extraargs, 1, 0)) {
sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1));
luaL_checkstack(L, 1 + extraargs, nullptr);
lua_pushvalue(L, findex);
card2value(L, pcard);
for (int32 i = 0; i < extraargs; ++i)
lua_pushvalue(L, (int32)(-extraargs - 2));
if (lua_pcall(L, 1 + extraargs, 1, 0)) {
sprintf(pduel->strbuffer, "%s", lua_tostring(L, -1));
handle_message(pduel, 1);
lua_pop(current_state, 1);
lua_pop(L, 1);
--no_action;
--call_depth;
if(call_depth == 0) {
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);
int32 result = lua_toboolean(L, -1);
lua_pop(L, 1);
--no_action;
--call_depth;
if(call_depth == 0) {
if (call_depth == 0) {
pduel->release_script_group();
pduel->restore_assumes();
}
......@@ -586,7 +587,8 @@ int32 interpreter::call_coroutine(int32 f, uint32 param_count, int32* yield_valu
push_param(rthread, true);
int32 result = 0, nresults = 0;
{
auto prev_state = std::exchange(current_state, rthread);
auto prev_state = current_state;
current_state = rthread;
#if (LUA_VERSION_NUM >= 504)
result = lua_resume(rthread, prev_state, param_count, &nresults);
#else
......@@ -635,7 +637,7 @@ void* interpreter::get_ref_object(int32 ref_handler) {
lua_pop(current_state, 1);
return p;
}
//push the object onto the stack, +1
//push the object onto the stack of L, +1
void interpreter::card2value(lua_State* L, card* pcard) {
luaL_checkstack(L, 1, nullptr);
if (!pcard || pcard->ref_handle == 0)
......@@ -675,3 +677,6 @@ duel* interpreter::get_duel_info(lua_State * L) {
std::memcpy(&pduel, lua_getextraspace(L), LUA_EXTRASPACE);
return pduel;
}
bool interpreter::is_load_script(card_data data) {
return !(data.type & TYPE_NORMAL) || (data.type & TYPE_PENDULUM);
}
......@@ -18,11 +18,12 @@
#include <cstdio>
class card;
struct card_data;
class effect;
class group;
class duel;
enum LuaParamType {
enum LuaParamType : int32 {
PARAM_TYPE_INT = 0x01,
PARAM_TYPE_STRING = 0x02,
PARAM_TYPE_CARD = 0x04,
......@@ -70,7 +71,7 @@ public:
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 check_filter(lua_State* L, 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);
......@@ -84,6 +85,7 @@ public:
static void function2value(lua_State* L, int32 func_ref);
static int32 get_function_handle(lua_State* L, int32 index);
static duel* get_duel_info(lua_State* L);
static bool is_load_script(card_data data);
template <size_t N, typename... TR>
static int sprintf(char (&buffer)[N], const char* format, TR... args) {
......
......@@ -393,7 +393,7 @@ int32 scriptlib::card_get_current_scale(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**)lua_touserdata(L, 1);
if(pcard->current.pzone && pcard->current.sequence == (pcard->pduel->game_field->core.duel_rule >= 4 ? 0 : 6))
if(pcard->current.pzone && pcard->current.sequence == (pcard->pduel->game_field->core.duel_rule >= NEW_MASTER_RULE ? 0 : 6))
lua_pushinteger(L, pcard->get_lscale());
else
lua_pushinteger(L, pcard->get_rscale());
......@@ -411,7 +411,7 @@ int32 scriptlib::card_get_linked_group(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
card::card_set cset;
card_set cset;
pcard->get_linked_cards(&cset);
group* pgroup = pcard->pduel->new_group(cset);
interpreter::group2value(L, pgroup);
......@@ -421,7 +421,7 @@ int32 scriptlib::card_get_linked_group_count(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
card::card_set cset;
card_set cset;
pcard->get_linked_cards(&cset);
lua_pushinteger(L, cset.size());
return 1;
......@@ -444,7 +444,7 @@ int32 scriptlib::card_get_mutual_linked_group(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**)lua_touserdata(L, 1);
card::card_set cset;
card_set cset;
pcard->get_mutual_linked_cards(&cset);
group* pgroup = pcard->pduel->new_group(cset);
interpreter::group2value(L, pgroup);
......@@ -454,7 +454,7 @@ int32 scriptlib::card_get_mutual_linked_group_count(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**)lua_touserdata(L, 1);
card::card_set cset;
card_set cset;
pcard->get_mutual_linked_cards(&cset);
lua_pushinteger(L, cset.size());
return 1;
......@@ -491,7 +491,7 @@ int32 scriptlib::card_get_column_group(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
card::card_set cset;
card_set cset;
pcard->get_column_cards(&cset);
group* pgroup = pcard->pduel->new_group(cset);
interpreter::group2value(L, pgroup);
......@@ -501,7 +501,7 @@ int32 scriptlib::card_get_column_group_count(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
card::card_set cset;
card_set cset;
pcard->get_column_cards(&cset);
lua_pushinteger(L, cset.size());
return 1;
......@@ -1869,7 +1869,7 @@ int32 scriptlib::card_register_flag_effect(lua_State *L) {
card* pcard = *(card**) lua_touserdata(L, 1);
int32 code = (lua_tointeger(L, 2) & MAX_CARD_ID) | EFFECT_FLAG_EFFECT;
int32 reset = (int32)lua_tointeger(L, 3);
int32 flag = (int32)lua_tointeger(L, 4);
uint32 flag = (uint32)lua_tointeger(L, 4);
int32 count = (int32)lua_tointeger(L, 5);
int32 lab = 0;
int32 desc = 0;
......@@ -2045,7 +2045,7 @@ int32 scriptlib::card_copy_effect(lua_State *L) {
card* pcard = *(card**) lua_touserdata(L, 1);
uint32 code = (uint32)lua_tointeger(L, 2);
uint32 reset = (uint32)lua_tointeger(L, 3);
uint32 count = (uint32)lua_tointeger(L, 4);
int32 count = (int32)lua_tointeger(L, 4);
if(count == 0)
count = 1;
if(reset & RESET_PHASE && !(reset & (RESET_SELF_TURN | RESET_OPPO_TURN)))
......@@ -2059,7 +2059,7 @@ int32 scriptlib::card_replace_effect(lua_State * L) {
card* pcard = *(card**)lua_touserdata(L, 1);
uint32 code = (uint32)lua_tointeger(L, 2);
uint32 reset = (uint32)lua_tointeger(L, 3);
uint32 count = (uint32)lua_tointeger(L, 4);
int32 count = (int32)lua_tointeger(L, 4);
if(count == 0)
count = 1;
if(reset & RESET_PHASE && !(reset & (RESET_SELF_TURN | RESET_OPPO_TURN)))
......@@ -2330,6 +2330,27 @@ int32 scriptlib::card_is_can_be_special_summoned(lua_State *L) {
lua_pushboolean(L, 0);
return 1;
}
int32 scriptlib::card_is_can_be_placed_on_field(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
uint32 toplayer = pcard->pduel->game_field->core.reason_player;
if(lua_gettop(L) >= 2)
toplayer = (uint32)lua_tointeger(L, 2);
if(toplayer != 0 && toplayer != 1) {
lua_pushboolean(L, 0);
return 1;
}
uint32 tolocation = LOCATION_SZONE;
if(lua_gettop(L) >= 3)
tolocation = (uint32)lua_tointeger(L, 3);
if(pcard->is_status(STATUS_FORBIDDEN)
|| pcard->pduel->game_field->check_unique_onfield(pcard, toplayer, tolocation, NULL))
lua_pushboolean(L, 0);
else
lua_pushboolean(L, 1);
return 1;
}
int32 scriptlib::card_is_able_to_hand(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
......@@ -2535,7 +2556,7 @@ int32 scriptlib::card_is_chain_attackable(lua_State *L) {
lua_pushboolean(L, 0);
return 1;
}
field::card_vector cv;
card_vector cv;
pduel->game_field->get_attack_target(attacker, &cv, TRUE);
if(cv.size() == 0 && (monsteronly || attacker->direct_attackable == 0))
lua_pushboolean(L, 0);
......@@ -2971,7 +2992,7 @@ int32 scriptlib::card_is_can_remove_counter(lua_State *L) {
check_param_count(L, 5);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
uint32 playerid = (uint32)lua_tointeger(L, 2);
int32 playerid = (int32)lua_tointeger(L, 2);
if(playerid != 0 && playerid != 1)
return 0;
uint32 countertype = (uint32)lua_tointeger(L, 3);
......@@ -3260,7 +3281,7 @@ int32 scriptlib::card_get_attackable_target(lua_State *L) {
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
duel* pduel = pcard->pduel;
field::card_vector targets;
card_vector targets;
uint8 chain_attack = FALSE;
if(pduel->game_field->core.chain_attacker_id == pcard->fieldid)
chain_attack = TRUE;
......@@ -3569,6 +3590,7 @@ static const struct luaL_Reg cardlib[] = {
{ "IsMSetable", scriptlib::card_is_msetable },
{ "IsSSetable", scriptlib::card_is_ssetable },
{ "IsCanBeSpecialSummoned", scriptlib::card_is_can_be_special_summoned },
{ "IsCanBePlacedOnField", scriptlib::card_is_can_be_placed_on_field },
{ "IsAbleToHand", scriptlib::card_is_able_to_hand },
{ "IsAbleToDeck", scriptlib::card_is_able_to_deck },
{ "IsAbleToExtra", scriptlib::card_is_able_to_extra },
......
......@@ -32,9 +32,9 @@ int32 scriptlib::debug_add_card(lua_State *L) {
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)
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 +43,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 seq = pduel->game_field->core.duel_rule >= NEW_MASTER_RULE ? sequence * 4 : sequence + 6;
pduel->game_field->add_card(playerid, pcard, LOCATION_SZONE, seq, TRUE);
} else {
pduel->game_field->add_card(playerid, pcard, location, sequence);
......@@ -58,9 +58,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);
......@@ -72,10 +74,10 @@ int32 scriptlib::debug_add_card(lua_State *L) {
int32 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 playerid = (int32)lua_tointeger(L, 1);
int32 lp = (int32)lua_tointeger(L, 2);
int32 startcount = (int32)lua_tointeger(L, 3);
int32 drawcount = (int32)lua_tointeger(L, 4);
if(playerid != 0 && playerid != 1)
return 0;
pduel->game_field->player[playerid].lp = lp;
......@@ -126,7 +128,7 @@ int32 scriptlib::debug_pre_add_counter(lua_State *L) {
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 count = (uint16)lua_tointeger(L, 3);
uint16 cttype = countertype;
auto pr = pcard->counters.emplace(cttype, 0);
auto cmit = pr.first;
......
This diff is collapsed.
......@@ -97,7 +97,7 @@ int32 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);
int32 playerid = (int32)lua_tointeger(L, 2);
uint32 s = (uint32)lua_tointeger(L, 3);
uint32 o = (uint32)lua_tointeger(L, 4);
if(playerid == 0) {
......@@ -133,7 +133,7 @@ int32 scriptlib::effect_set_reset(lua_State *L) {
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);
int32 c = (int32)lua_tointeger(L, 3);
if(c == 0)
c = 1;
if(v & (RESET_PHASE) && !(v & (RESET_SELF_TURN | RESET_OPPO_TURN)))
......@@ -169,7 +169,7 @@ int32 scriptlib::effect_set_property(lua_State *L) {
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);
peffect->flag[0] = (peffect->flag[0] & INTERNAL_FLAGS) | (v1 & ~INTERNAL_FLAGS);
peffect->flag[1] = v2;
return 0;
}
......@@ -292,7 +292,7 @@ int32 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 p = (int32)lua_tointeger(L, 2);
if(p != 0 && p != 1)
return 0;
peffect->effect_owner = p;
......@@ -502,7 +502,7 @@ int32 scriptlib::effect_is_has_type(lua_State *L) {
int32 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 playerid = (int32)lua_tointeger(L, 2);
effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 neglect_loc = 0;
uint32 neglect_target = 0;
......@@ -554,7 +554,7 @@ int32 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 p = (int32)lua_tointeger(L, 2);
lua_pushboolean(L, peffect->check_count_limit(p));
return 1;
}
......@@ -562,12 +562,12 @@ int32 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;
int32 p = (int32)lua_tointeger(L, 2);
int32 count = 1;
int32 oath_only = 0;
uint32 code = peffect->count_code;
if(lua_gettop(L) > 2) {
count = (uint32)lua_tointeger(L, 3);
count = (int32)lua_tointeger(L, 3);
if (lua_gettop(L) > 3)
oath_only = lua_toboolean(L, 4);
}
......
......@@ -133,28 +133,12 @@ int32 scriptlib::group_get_count(lua_State *L) {
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) {
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);
......@@ -167,7 +151,7 @@ int32 scriptlib::group_filter(lua_State *L) {
group* new_group = pduel->new_group();
uint32 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);
}
}
......@@ -179,7 +163,7 @@ int32 scriptlib::group_filter_count(lua_State *L) {
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);
......@@ -192,7 +176,7 @@ int32 scriptlib::group_filter_count(lua_State *L) {
uint32 extraargs = lua_gettop(L) - 3;
uint32 count = 0;
for (auto& pcard : cset) {
if(pduel->lua->check_matching(pcard, 2, extraargs))
if(pduel->lua->check_filter(L, pcard, 2, extraargs))
++count;
}
lua_pushinteger(L, count);
......@@ -204,7 +188,7 @@ int32 scriptlib::group_filter_select(lua_State *L) {
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);
......@@ -214,7 +198,7 @@ int32 scriptlib::group_filter_select(lua_State *L) {
cset.erase(pcard);
}
duel* pduel = pgroup->pduel;
uint32 playerid = (uint32)lua_tointeger(L, 2);
int32 playerid = (int32)lua_tointeger(L, 2);
if(playerid != 0 && playerid != 1)
return 0;
uint32 min = (uint32)lua_tointeger(L, 4);
......@@ -222,7 +206,7 @@ int32 scriptlib::group_filter_select(lua_State *L) {
uint32 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));
......@@ -242,7 +226,7 @@ int32 scriptlib::group_select(lua_State *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);
......@@ -252,7 +236,7 @@ int32 scriptlib::group_select(lua_State *L) {
cset.erase(pcard);
}
duel* pduel = pgroup->pduel;
uint32 playerid = (uint32)lua_tointeger(L, 2);
int32 playerid = (int32)lua_tointeger(L, 2);
if(playerid != 0 && playerid != 1)
return 0;
uint32 min = (uint32)lua_tointeger(L, 3);
......@@ -282,7 +266,7 @@ int32 scriptlib::group_select_unselect(lua_State *L) {
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 playerid = (int32)lua_tointeger(L, 3);
if(playerid != 0 && playerid != 1)
return 0;
if(select_group->container.size() == 0 && (!unselect_group || unselect_group->container.size() == 0))
......@@ -380,7 +364,7 @@ int32 scriptlib::group_cancelable_select(lua_State *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);
......@@ -390,7 +374,7 @@ int32 scriptlib::group_cancelable_select(lua_State *L) {
cset.erase(pcard);
}
duel* pduel = pgroup->pduel;
uint32 playerid = (uint32)lua_tointeger(L, 2);
int32 playerid = (int32)lua_tointeger(L, 2);
if(playerid != 0 && playerid != 1)
return 0;
uint32 min = (uint32)lua_tointeger(L, 3);
......@@ -420,7 +404,7 @@ int32 scriptlib::group_is_exists(lua_State *L) {
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);
......@@ -439,7 +423,7 @@ int32 scriptlib::group_is_exists(lua_State *L) {
return 1;
}
for (auto& pcard : cset) {
if(pduel->lua->check_matching(pcard, 2, extraargs)) {
if(pduel->lua->check_filter(L, pcard, 2, extraargs)) {
++fcount;
if(fcount >= count) {
result = TRUE;
......@@ -464,7 +448,7 @@ int32 scriptlib::group_check_with_sum_equal(lua_State *L) {
if(max < min)
max = min;
int32 extraargs = lua_gettop(L) - 5;
field::card_vector cv(pduel->game_field->core.must_select_cards);
card_vector cv(pduel->game_field->core.must_select_cards);
int32 mcount = (int32)cv.size();
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);
......@@ -502,7 +486,7 @@ int32 scriptlib::group_select_with_sum_equal(lua_State *L) {
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);
card_vector cv(pduel->game_field->core.must_select_cards);
int32 mcount = (int32)cv.size();
cv.insert(cv.end(), pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end());
for(auto& pcard : cv)
......@@ -535,7 +519,7 @@ int32 scriptlib::group_check_with_sum_greater(lua_State *L) {
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);
card_vector cv(pduel->game_field->core.must_select_cards);
int32 mcount = (int32)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);
......@@ -565,7 +549,7 @@ int32 scriptlib::group_select_with_sum_greater(lua_State *L) {
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);
card_vector cv(pduel->game_field->core.must_select_cards);
int32 mcount = (int32)cv.size();
cv.insert(cv.end(), pduel->game_field->core.select_cards.begin(), pduel->game_field->core.select_cards.end());
for(auto& pcard : cv)
......@@ -692,7 +676,7 @@ int32 scriptlib::group_remove(lua_State *L) {
return 0;
pgroup->is_iterator_dirty = true;
for (auto cit = pgroup->container.begin(); cit != pgroup->container.end();) {
if((*cit) != pexception && pduel->lua->check_matching(*cit, 2, extraargs)) {
if((*cit) != pexception && pduel->lua->check_filter(L, *cit, 2, extraargs)) {
cit = pgroup->container.erase(cit);
}
else
......@@ -767,7 +751,7 @@ int32 scriptlib::group_search_card(lua_State *L) {
duel* pduel = pgroup->pduel;
uint32 extraargs = lua_gettop(L) - 2;
for (auto& pcard : pgroup->container) {
if (pduel->lua->check_matching(pcard, 2, extraargs)) {
if (pduel->lua->check_filter(L, pcard, 2, extraargs)) {
interpreter::card2value(L, pcard);
return 1;
}
......@@ -855,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);
......@@ -924,7 +908,6 @@ 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 },
......
......@@ -112,6 +112,8 @@ 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) {
if (!check_playerid(playerid))
return;
duel* pd = (duel*)pduel;
if(lp > 0)
pd->game_field->player[playerid].lp = lp;
......@@ -137,6 +139,8 @@ extern "C" DECL_DLLEXPORT uint32 process(intptr_t pduel) {
return result;
}
extern "C" DECL_DLLEXPORT void new_card(intptr_t pduel, uint32 code, uint8 owner, uint8 playerid, uint8 location, uint8 sequence, uint8 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);
......@@ -177,7 +181,7 @@ extern "C" DECL_DLLEXPORT void new_tag_card(intptr_t pduel, uint32 code, uint8 o
}
}
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)
if (!check_playerid(playerid))
return LEN_FAIL;
duel* ptduel = (duel*)pduel;
card* pcard = nullptr;
......@@ -185,7 +189,7 @@ extern "C" DECL_DLLEXPORT int32 query_card(intptr_t pduel, uint8 playerid, uint8
if(location & LOCATION_ONFIELD)
pcard = ptduel->game_field->get_field_card(playerid, location, sequence);
else {
field::card_vector* lst = nullptr;
card_vector* lst = nullptr;
if (location == LOCATION_HAND)
lst = &ptduel->game_field->player[playerid].list_hand;
else if (location == LOCATION_GRAVE)
......@@ -213,7 +217,7 @@ extern "C" DECL_DLLEXPORT int32 query_card(intptr_t pduel, uint8 playerid, uint8
}
extern "C" DECL_DLLEXPORT int32 query_field_count(intptr_t pduel, uint8 playerid, uint8 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)
......@@ -243,7 +247,7 @@ extern "C" DECL_DLLEXPORT int32 query_field_count(intptr_t pduel, uint8 playerid
return 0;
}
extern "C" DECL_DLLEXPORT int32 query_field_card(intptr_t pduel, uint8 playerid, uint8 location, uint32 query_flag, byte* buf, int32 use_cache) {
if(playerid != 0 && playerid != 1)
if (!check_playerid(playerid))
return LEN_FAIL;
duel* ptduel = (duel*)pduel;
auto& player = ptduel->game_field->player[playerid];
......@@ -269,7 +273,7 @@ extern "C" DECL_DLLEXPORT int32 query_field_card(intptr_t pduel, uint8 playerid,
}
}
else {
field::card_vector* lst = nullptr;
card_vector* lst = nullptr;
if(location == LOCATION_HAND)
lst = &player.list_hand;
else if(location == LOCATION_GRAVE)
......@@ -293,7 +297,7 @@ extern "C" DECL_DLLEXPORT int32 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)ptduel->game_field->core.duel_rule;
for(int playerid = 0; playerid < 2; ++playerid) {
auto& player = ptduel->game_field->player[playerid];
buffer_write<int32_t>(p, player.lp);
......
This diff is collapsed.
......@@ -609,10 +609,10 @@ uint32 field::process() {
}
case PROCESSOR_SELECT_SYNCHRO: {
int32 ret = TRUE;
if(!(it->arg1 >> 16))
ret = select_synchro_material(it->step, it->arg1 & 0xffff, (card*)it->ptarget, it->arg2 & 0xffff, it->arg2 >> 16, 0, (group*)it->peffect);
if (!(it->arg1 >> 16))
ret = select_synchro_material(it->step, it->arg1 & 0xffff, (card*)it->ptr1, it->arg2 & 0xffff, it->arg2 >> 16, nullptr, (group*)it->ptr2, it->arg3, it->arg4);
else
ret = select_synchro_material(it->step, it->arg1 & 0xffff, (card*)it->ptarget, it->arg2 & 0xffff, it->arg2 >> 16, (card*)it->peffect, 0);
ret = select_synchro_material(it->step, it->arg1 & 0xffff, (card*)it->ptr1, it->arg2 & 0xffff, it->arg2 >> 16, (card*)it->ptr2, nullptr, it->arg3, it->arg4);
if(ret)
core.units.pop_front();
else
......@@ -1444,10 +1444,10 @@ int32 field::process_point_event(int16 step, int32 skip_trigger, int32 skip_free
if((core.duel_rule >= 2) || (infos.phase != PHASE_MAIN1 && infos.phase != PHASE_MAIN2))
return FALSE;
// Obsolete ignition effect ruling
tevent e;
tevent evt;
if(core.current_chain.size() == 0 &&
(check_event(EVENT_SUMMON_SUCCESS, &e) || check_event(EVENT_SPSUMMON_SUCCESS, &e) || check_event(EVENT_FLIP_SUMMON_SUCCESS, &e))
&& e.reason_player == infos.turn_player) {
(check_event(EVENT_SUMMON_SUCCESS, &evt) || check_event(EVENT_SPSUMMON_SUCCESS, &evt) || check_event(EVENT_FLIP_SUMMON_SUCCESS, &evt))
&& evt.reason_player == infos.turn_player) {
chain newchain;
tevent e;
e.event_cards = 0;
......@@ -2043,8 +2043,8 @@ int32 field::process_single_event(effect* peffect, const tevent& e, chain_list&
}
peffect->set_active_type();
phandler->create_relation(newchain);
effect* deffect;
if(deffect = phandler->is_affected_by_effect(EFFECT_DISABLE_EFFECT)) {
effect* deffect = phandler->is_affected_by_effect(EFFECT_DISABLE_EFFECT);
if(deffect) {
effect* negeff = pduel->new_effect();
negeff->owner = deffect->owner;
negeff->type = EFFECT_TYPE_SINGLE;
......@@ -2061,7 +2061,6 @@ int32 field::process_idle_command(uint16 step) {
free_event.event_code = EVENT_FREE_CHAIN;
switch(step) {
case 0: {
effect* peffect;
bool must_attack = false;
core.select_chains.clear();
chain newchain;
......@@ -2132,7 +2131,7 @@ int32 field::process_idle_command(uint16 step) {
core.select_chains.push_back(newchain);
}
for(auto eit = effects.ignition_effect.begin(); eit != effects.ignition_effect.end();) {
peffect = eit->second;
effect* peffect = eit->second;
++eit;
peffect->set_activate_location();
newchain.triggering_effect = peffect;
......@@ -2391,7 +2390,6 @@ int32 field::process_battle_command(uint16 step) {
free_event.event_code = EVENT_FREE_CHAIN;
switch(step) {
case 0: {
effect* peffect = nullptr;
core.select_chains.clear();
chain newchain;
if(!core.chain_attack) {
......@@ -2401,13 +2399,14 @@ int32 field::process_battle_command(uint16 step) {
core.attack_player = FALSE;
core.attacker = 0;
core.attack_target = 0;
if((peffect = is_player_affected_by_effect(infos.turn_player, EFFECT_SKIP_BP))) {
effect* skip_effect = is_player_affected_by_effect(infos.turn_player, EFFECT_SKIP_BP);
if(skip_effect) {
core.units.begin()->step = 41;
core.units.begin()->arg1 = 2;
if(is_player_affected_by_effect(infos.turn_player, EFFECT_BP_TWICE))
core.units.begin()->arg2 = 1;
else core.units.begin()->arg2 = 0;
if(!peffect->value) {
if(!skip_effect->value) {
reset_phase(PHASE_BATTLE_STEP);
adjust_all();
infos.phase = PHASE_BATTLE;
......@@ -3471,24 +3470,24 @@ void field::calculate_battle_damage(effect** pdamchange, card** preason_card, ui
}
}
}
effect_set eset;
core.attacker->filter_effect(EFFECT_CHANGE_BATTLE_DAMAGE, &eset, FALSE);
core.attacker->filter_effect(EFFECT_CHANGE_INVOLVING_BATTLE_DAMAGE, &eset, FALSE);
core.attack_target->filter_effect(EFFECT_CHANGE_INVOLVING_BATTLE_DAMAGE, &eset, FALSE);
filter_player_effect(pa, EFFECT_CHANGE_BATTLE_DAMAGE, &eset, FALSE);
filter_player_effect(1 - pa, EFFECT_CHANGE_BATTLE_DAMAGE, &eset, FALSE);
eset.sort();
effect_set change_effects;
core.attacker->filter_effect(EFFECT_CHANGE_BATTLE_DAMAGE, &change_effects, FALSE);
core.attacker->filter_effect(EFFECT_CHANGE_INVOLVING_BATTLE_DAMAGE, &change_effects, FALSE);
core.attack_target->filter_effect(EFFECT_CHANGE_INVOLVING_BATTLE_DAMAGE, &change_effects, FALSE);
filter_player_effect(pa, EFFECT_CHANGE_BATTLE_DAMAGE, &change_effects, FALSE);
filter_player_effect(1 - pa, EFFECT_CHANGE_BATTLE_DAMAGE, &change_effects, FALSE);
change_effects.sort();
for(uint8 p = 0; p < 2; ++p) {
bool double_dam = false;
bool half_dam = false;
int32 dam_value = -1;
for(int32 i = 0; i < eset.size(); ++i) {
for(int32 i = 0; i < change_effects.size(); ++i) {
int32 val = -1;
if(!eset[i]->is_flag(EFFECT_FLAG_PLAYER_TARGET)) {
if(!change_effects[i]->is_flag(EFFECT_FLAG_PLAYER_TARGET)) {
pduel->lua->add_param(p, PARAM_TYPE_INT);
val = eset[i]->get_value(1);
} else if(eset[i]->is_target_player(p))
val = eset[i]->get_value();
val = change_effects[i]->get_value(1);
} else if(change_effects[i]->is_target_player(p))
val = change_effects[i]->get_value();
if(val == 0) {
dam_value = 0;
break;
......@@ -4314,7 +4313,6 @@ int32 field::solve_continuous(uint16 step) {
case 3: {
auto& clit = core.solving_continuous.front();
effect* peffect = clit.triggering_effect;
uint8 triggering_player = clit.triggering_player;
core.reason_effect = (effect*)core.units.begin()->ptarget;
core.reason_player = (uint8)core.units.begin()->arg2;
if(core.continuous_chain.back().target_cards)
......@@ -4499,7 +4497,8 @@ int32 field::solve_chain(uint16 step, uint32 chainend_arg1, uint32 chainend_arg2
destroy(fscard, 0, REASON_RULE, 1 - pcard->current.controler);
}
}
peffect->active_type = 0;
// keep last active_type until the next activate, for the using in script
// peffect->active_type = 0;
peffect->active_handler = 0;
pcard->release_relation(*cait);
if(cait->target_cards)
......
......@@ -8,6 +8,7 @@
#include "duel.h"
static int32 check_data_type(lua_State* L, int32 index, const char* tname) {
luaL_checkstack(L, 2, nullptr);
int32 result = FALSE;
if(lua_getmetatable(L, index)) {
lua_getglobal(L, tname);
......@@ -20,6 +21,7 @@ static int32 check_data_type(lua_State* L, int32 index, const char* tname) {
int32 scriptlib::check_param(lua_State* L, int32 param_type, int32 index, int32 retfalse) {
switch (param_type) {
case PARAM_TYPE_CARD: {
luaL_checkstack(L, 1, nullptr);
int32 result = FALSE;
if(lua_isuserdata(L, index) && lua_getmetatable(L, index)) {
result = check_data_type(L, -1, "Card");
......
......@@ -217,6 +217,7 @@ public:
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_can_be_placed_on_field(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);
......@@ -365,7 +366,6 @@ public:
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);
......
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