Commit f73e175c authored by nanahira's avatar nanahira

Merge branch 'develop'

parents 768b0323 d3a70f2e
#ifndef CORE_BUFFER_H
#define CORE_BUFFER_H
#include <cstdio>
#include <cstring>
#include <vector>
......@@ -21,7 +22,7 @@ inline void buffer_write_block(unsigned char*& p, const void* src, size_t size)
}
template<typename T>
inline void buffer_write(unsigned char*& p, T value) {
buffer_write_block(p, &value,sizeof(T));
buffer_write_block(p, &value, sizeof(T));
}
inline void vector_write_block(std::vector<unsigned char>& buffer, const void* src, size_t size) {
......@@ -34,4 +35,11 @@ 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 diff is collapsed.
......@@ -30,6 +30,9 @@ using effect_container = std::multimap<uint32, effect*>;
using effect_indexer = std::unordered_map<effect*, effect_container::iterator>;
using effect_collection = std::unordered_set<effect*>;
using effect_filter = bool(*)(card* self, effect* peffect);
using effect_filter_target = bool(*)(card* self, effect* peffect, card* target);
struct card_state {
uint32 code{ 0 };
uint32 code2{ 0 };
......@@ -56,7 +59,7 @@ struct card_state {
uint8 reason_player{ PLAYER_NONE };
effect* reason_effect{ nullptr };
bool is_location(int32 loc) const;
bool is_location(uint32 loc) const;
bool is_main_mzone() const {
return location == LOCATION_MZONE && sequence >= 0 && sequence <= 4;
}
......@@ -106,12 +109,6 @@ struct material_info {
};
const material_info null_info;
constexpr uint32 CARD_MARINE_DOLPHIN = 78734254;
constexpr uint32 CARD_TWINKLE_MOSS = 13857930;
constexpr uint32 CARD_TIMAEUS = 1784686;
constexpr uint32 CARD_CRITIAS = 11082056;
constexpr uint32 CARD_HERMOS = 46232525;
class card {
public:
struct effect_relation_hash {
......@@ -153,7 +150,6 @@ public:
uint8 location{ 0 };
uint8 sequence{ 0 };
};
static const std::unordered_map<uint32, uint32> second_code;
int32 ref_handle;
duel* pduel;
......@@ -218,12 +214,15 @@ public:
effect_indexer indexer;
effect_relation relate_effect;
effect_set_v immune_effect;
effect_collection initial_effect;
effect_collection owning_effect;
uint8 to_leave_fromex;
explicit card(duel* pd);
~card() = default;
static bool card_operation_sort(card* c1, card* c2);
static bool check_card_setcode(uint32 code, uint32 value);
bool is_extra_deck_monster() const { return !!(data.type & TYPES_EXTRA_DECK); }
int32 get_infos(byte* buf, uint32 query_flag, int32 use_cache = TRUE);
......@@ -232,7 +231,6 @@ public:
std::tuple<uint32, uint32> get_original_code_rule() const;
uint32 get_code();
uint32 get_another_code();
static bool check_card_setcode(uint32 code, uint32 value);
int32 is_set_card(uint32 set_code);
int32 is_origin_set_card(uint32 set_code);
int32 is_pre_set_card(uint32 set_code);
......@@ -268,14 +266,14 @@ public:
uint32 get_lscale();
uint32 get_rscale();
uint32 get_link_marker();
int32 is_link_marker(uint32 dir);
uint32 is_link_marker(uint32 dir);
uint32 get_linked_zone();
void get_linked_cards(card_set* cset);
uint32 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);
int32 is_position(uint32 pos) const;
void set_status(uint32 status, int32 enabled);
int32 get_status(uint32 status) const;
int32 is_status(uint32 status) const;
......@@ -284,13 +282,13 @@ public:
int32 is_all_column();
uint8 get_select_sequence(uint8 *deck_seq_pointer);
uint32 get_select_info_location(uint8 *deck_seq_pointer);
int32 is_treated_as_not_on_field();
int32 is_treated_as_not_on_field() const;
void equip(card* target, uint32 send_msg = TRUE);
void unequip();
int32 get_union_count();
int32 get_old_union_count();
void xyz_overlay(card_set* materials);
void xyz_overlay(const card_set& materials);
void xyz_add(card* mat);
void xyz_remove(card* mat);
void apply_field_effect();
......@@ -330,9 +328,12 @@ public:
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 code, effect_filter f, T& eset);
void filter_effect_container(const effect_container& container, uint32 code, effect_filter f, effect_collection& eset);
void filter_effect(uint32 code, effect_set* eset, uint8 sort = TRUE);
void filter_single_continuous_effect(uint32 code, effect_set* eset, uint8 sort = TRUE);
void filter_self_effect(uint32 code, effect_set* eset, uint8 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);
......@@ -341,7 +342,9 @@ public:
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* find_effect(const effect_container& container, uint32 code, effect_filter f);
effect* find_effect_with_target(const effect_container& container, uint32 code, effect_filter_target f, card* target);
effect* is_affected_by_effect(uint32 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);
......@@ -404,6 +407,8 @@ public:
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 is_original_effect_property(int32 filter);
int32 is_effect_property(int32 filter);
};
//Summon Type in summon_info
......
#ifndef CARD_DATA_H_
#define CARD_DATA_H_
#include <unordered_map>
#include "common.h"
constexpr int CARD_ARTWORK_VERSIONS_OFFSET = 20;
constexpr int SIZE_SETCODE = 16;
constexpr int CARD_BLACK_LUSTER_SOLDIER2 = 5405695;
constexpr uint32 CARD_BLACK_LUSTER_SOLDIER2 = 5405695;
//double name
constexpr uint32 CARD_MARINE_DOLPHIN = 78734254;
constexpr uint32 CARD_TWINKLE_MOSS = 13857930;
constexpr uint32 CARD_TIMAEUS = 1784686;
constexpr uint32 CARD_CRITIAS = 11082056;
constexpr uint32 CARD_HERMOS = 46232525;
const std::unordered_map<uint32, uint32> second_code = {
{CARD_MARINE_DOLPHIN, 17955766u},
{CARD_TWINKLE_MOSS, 17732278u},
{CARD_TIMAEUS, 10000050u},
{CARD_CRITIAS, 10000060u},
{CARD_HERMOS, 10000070u},
};
struct card_data {
uint32 code{};
......
......@@ -49,17 +49,17 @@ typedef signed char int8;
#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
......
......@@ -55,7 +55,7 @@ void duel::clear() {
card* duel::new_card(uint32 code) {
card* pcard = new card(this);
cards.insert(pcard);
if(code)
if (code != TEMP_CARD_ID)
::read_card(code, &(pcard->data));
pcard->data.code = code;
lua->register_card(pcard);
......@@ -102,9 +102,10 @@ void duel::delete_effect(effect* peffect) {
delete peffect;
}
int32 duel::read_buffer(byte* buf) {
if(message_buffer.size())
std::memcpy(buf, message_buffer.data(), message_buffer.size());
return (int32)message_buffer.size();
auto size = buffer_size();
if (size)
std::memcpy(buf, message_buffer.data(), size);
return (int32)size;
}
void duel::release_script_group() {
for(auto& pgroup : sgroups) {
......
......@@ -14,6 +14,7 @@
#include <set>
#include <unordered_set>
#include <cstring>
#include <vector>
class card;
class group;
......@@ -41,6 +42,9 @@ public:
~duel();
void clear();
uint32 buffer_size() const {
return (uint32)message_buffer.size() & PROCESSOR_BUFFER_LEN;
}
card* new_card(uint32 code);
group* new_group();
group* new_group(card* pcard);
......
......@@ -625,6 +625,11 @@ int32 effect::is_hand_trigger() const {
int32 effect::is_initial_single() const {
return (type & EFFECT_TYPE_SINGLE) && is_flag(EFFECT_FLAG_SINGLE_RANGE) && is_flag(EFFECT_FLAG_INITIAL);
}
int32 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) {
......@@ -695,7 +700,7 @@ int32 effect::get_value(uint32 extraargs) {
return res;
} else {
pduel->lua->params.clear();
return (int32)value;
return value;
}
}
int32 effect::get_value(card* pcard, uint32 extraargs) {
......@@ -706,7 +711,7 @@ int32 effect::get_value(card* pcard, uint32 extraargs) {
return res;
} else {
pduel->lua->params.clear();
return (int32)value;
return value;
}
}
int32 effect::get_value(effect* peffect, uint32 extraargs) {
......@@ -717,36 +722,36 @@ int32 effect::get_value(effect* peffect, uint32 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 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 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 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::get_integer_value() {
......@@ -759,7 +764,7 @@ int32 effect::check_value_condition(uint32 extraargs) {
return res;
} else {
pduel->lua->params.clear();
return (int32)value;
return value;
}
}
void* effect::get_label_object() {
......@@ -868,7 +873,7 @@ uint32 effect::get_active_type(uint8 uselast) {
} else
return owner->get_type();
}
int32 effect::get_code_type() const {
code_type effect::get_code_type() const {
// start from the highest bit
if (code & 0xf0000000)
return CODE_CUSTOM;
......
......@@ -11,9 +11,7 @@
#include "common.h"
#include "field.h"
#include "effectset.h"
#include <stdlib.h>
#include <vector>
#include <map>
class card;
class duel;
......@@ -22,8 +20,12 @@ class effect;
struct tevent;
struct effect_set;
struct effect_set_v;
enum effect_flag : uint32;
enum effect_flag2 : uint32;
enum effect_flag : uint64;
enum effect_flag2 : uint64;
enum effect_category :uint64;
enum code_type : int32;
bool is_continuous_event(uint32 code);
class effect {
public:
......@@ -34,7 +36,6 @@ public:
uint8 effect_owner{ PLAYER_NONE };
uint32 description{ 0 };
uint32 code{ 0 };
uint32 flag[2]{};
uint32 id{ 0 };
uint32 type{ 0 };
uint16 copy_id{ 0 };
......@@ -43,18 +44,19 @@ public:
uint16 o_range{ 0 };
uint8 count_limit{ 0 };
uint8 count_limit_max{ 0 };
uint16 status{ 0 };
int32 reset_count{ 0 };
uint32 reset_flag{ 0 };
uint32 count_code{ 0 };
uint32 category{ 0 };
uint64 category{ 0 };
uint64 flag[2]{};
uint32 hint_timing[2]{};
uint32 card_type{ 0 };
uint32 active_type{ 0 };
uint16 active_location{ 0 };
uint16 active_sequence{ 0 };
card* active_handler{ nullptr };
uint16 status{ 0 };
std::vector<uint32> label;
std::vector<lua_Integer> label;
int32 label_object{ 0 };
int32 condition{ 0 };
int32 cost{ 0 };
......@@ -90,15 +92,16 @@ public:
int32 is_chainable(uint8 tp);
int32 is_hand_trigger() const;
int32 is_initial_single() const;
int32 is_monster_effect() const;
int32 reset(uint32 reset_level, uint32 reset_type);
void dec_count(uint8 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);
void get_value(uint32 extraargs, std::vector<lua_Integer>& result);
void get_value(card* pcard, uint32 extraargs, std::vector<lua_Integer>& result);
void get_value(effect* peffect, uint32 extraargs, std::vector<lua_Integer>& result);
int32 get_integer_value();
int32 check_value_condition(uint32 extraargs = 0);
void* get_label_object();
......@@ -113,7 +116,7 @@ public:
void set_activate_location();
void set_active_type();
uint32 get_active_type(uint8 uselast = TRUE);
int32 get_code_type() const;
code_type get_code_type() const;
bool is_flag(effect_flag x) const {
return !!(flag[0] & x);
......@@ -173,6 +176,8 @@ public:
#define RESET_OVERLAY 0x04000000
#define RESET_MSCHANGE 0x08000000
constexpr uint32 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 //
......@@ -194,7 +199,7 @@ constexpr uint32 EFFECT_TYPES_TRIGGER_LIKE = EFFECT_TYPE_ACTIVATE | EFFECT_TYPE_
constexpr uint32 EFFECT_TYPES_CHAIN_LINK = EFFECT_TYPES_TRIGGER_LIKE | EFFECT_TYPE_FLIP | EFFECT_TYPE_IGNITION;
//========== Flags ==========
enum effect_flag : uint32 {
enum effect_flag : uint64 {
EFFECT_FLAG_INITIAL = 0x0001,
EFFECT_FLAG_FUNC_VALUE = 0x0002,
EFFECT_FLAG_COUNT_LIMIT = 0x0004,
......@@ -208,7 +213,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,
......@@ -227,8 +232,11 @@ enum effect_flag : uint32 {
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 {
enum effect_flag2 : uint64 {
EFFECT_FLAG2_REPEAT_UPDATE = 0x0001,
EFFECT_FLAG2_COF = 0x0002,
EFFECT_FLAG2_WICKED = 0x0004,
......@@ -238,9 +246,52 @@ enum effect_flag2 : uint32 {
EFFECT_FLAG2_ACTIVATE_MONSTER_SZONE = 0x0400,
};
constexpr effect_flag operator|(effect_flag flag1, effect_flag flag2) {
return static_cast<effect_flag>(static_cast<uint32>(flag1) | static_cast<uint32>(flag2));
return static_cast<effect_flag>(static_cast<uint64>(flag1) | static_cast<uint64>(flag2));
}
constexpr uint32 INTERNAL_FLAGS = EFFECT_FLAG_INITIAL | EFFECT_FLAG_FUNC_VALUE | EFFECT_FLAG_COUNT_LIMIT | EFFECT_FLAG_FIELD_ONLY | EFFECT_FLAG_ABSOLUTE_TARGET;
constexpr uint64 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 {
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, uint64> 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 //
......@@ -583,10 +634,12 @@ constexpr int32 HALF_DAMAGE = 0x80000001;
#define MAX_CARD_ID 0xfffffff
// The type of effect 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
enum code_type : int32 {
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> continuous_event{
EVENT_ADJUST,
......@@ -595,6 +648,11 @@ const std::unordered_set<uint32> continuous_event{
EVENT_PRE_BATTLE_DAMAGE,
EVENT_SPSUMMON_SUCCESS_G_P,
};
bool is_continuous_event(uint32 code);
const std::unordered_set<uint32> affect_summoning_effect{
EFFECT_CANNOT_DISABLE_SUMMON,
EFFECT_CANNOT_DISABLE_SPSUMMON,
EVENT_BE_PRE_MATERIAL,
};
#endif /* EFFECT_H_ */
......@@ -26,10 +26,6 @@ struct effect_set {
void remove_item(int index) {
if (index < 0 || index >= count)
return;
if(index == count - 1) {
--count;
return;
}
for(int i = index; i < count - 1; ++i)
container[i] = container[i + 1];
--count;
......@@ -86,10 +82,7 @@ struct effect_set_v {
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);
std::sort(container.begin(), container.end(), effect_sort_id);
}
effect* const& get_last() const {
assert(container.size());
......
......@@ -492,7 +492,21 @@ void field::set_control(card* pcard, uint8 playerid, uint16 reset_phase, uint8 r
pcard->current.controler = playerid;
}
card* field::get_field_card(uint8 playerid, uint32 general_location, uint8 sequence) {
int32 field::get_pzone_sequence(uint8 pseq) const {
if (core.duel_rule >= NEW_MASTER_RULE) {
if(!pseq)
return 0;
else
return 4;
}
else {
if (!pseq)
return 6;
else
return 7;
}
}
card* field::get_field_card(uint8 playerid, uint32 general_location, uint8 sequence) const {
if (!check_playerid(playerid))
return nullptr;
switch(general_location) {
......@@ -518,12 +532,9 @@ card* field::get_field_card(uint8 playerid, uint32 general_location, uint8 seque
break;
}
case LOCATION_PZONE: {
if(sequence == 0) {
card* pcard = player[playerid].list_szone[core.duel_rule >= NEW_MASTER_RULE ? 0 : 6];
return (pcard && pcard->current.pzone) ? pcard : 0;
} else if(sequence == 1) {
card* pcard = player[playerid].list_szone[core.duel_rule >= NEW_MASTER_RULE ? 4 : 7];
return (pcard && pcard->current.pzone) ? pcard : 0;
if(sequence == 0 || sequence == 1) {
card* pcard = player[playerid].list_szone[get_pzone_sequence(sequence)];
return (pcard && pcard->current.pzone) ? pcard : nullptr;
} else
return nullptr;
break;
......@@ -573,33 +584,28 @@ int32 field::is_location_useable(uint8 playerid, uint32 general_location, uint8
if (general_location == LOCATION_MZONE) {
if (sequence >= (int32)player[playerid].list_mzone.size())
return FALSE;
if(flag & (0x1u << sequence))
if(flag & (0x1U << sequence))
return FALSE;
if(sequence >= 5) {
uint32 oppo = player[1 - playerid].disabled_location | player[1 - playerid].used_location;
if(oppo & (0x1u << (11 - sequence)))
if(oppo & (0x1U << (11 - sequence)))
return FALSE;
}
} else if (general_location == LOCATION_SZONE) {
if (sequence >= player[playerid].szone_size)
return FALSE;
if(flag & (0x100u << sequence))
if(flag & (0x100U << sequence))
return FALSE;
} else if (general_location == LOCATION_FZONE) {
if (sequence >= 1)
return FALSE;
if(flag & (0x100u << (5 + sequence)))
if(flag & (0x100U << (5 + sequence)))
return FALSE;
} else if (general_location == LOCATION_PZONE) {
if (sequence >= 2)
return FALSE;
if(core.duel_rule >= NEW_MASTER_RULE) {
if(flag & (0x100u << (sequence * 4)))
return FALSE;
} else {
if(flag & (0x100u << (6 + sequence)))
return FALSE;
}
if (flag & (0x100U << get_pzone_sequence(sequence)))
return FALSE;
}
return TRUE;
}
......@@ -814,11 +820,11 @@ int32 field::get_szone_limit(uint8 playerid, uint8 uplayer, uint32 reason) {
}
uint32 field::get_linked_zone(int32 playerid) {
uint32 zones = 0;
for(auto& pcard : player[playerid].list_mzone) {
for(const auto& pcard : player[playerid].list_mzone) {
if(pcard)
zones |= pcard->get_linked_zone() & 0xff;
zones |= pcard->get_linked_zone() & 0xffff;
}
for(auto& pcard : player[1 - playerid].list_mzone) {
for(const auto& pcard : player[1 - playerid].list_mzone) {
if(pcard)
zones |= pcard->get_linked_zone() >> 16;
}
......@@ -892,19 +898,19 @@ int32 field::check_extra_link(int32 playerid) {
if(!player[playerid].list_mzone[5] || !player[playerid].list_mzone[6])
return FALSE;
card* pcard = player[playerid].list_mzone[5];
uint32 checked = 1u << 5;
uint32 checked = 0x1u << 5;
uint32 linked_zone = pcard->get_mutual_linked_zone();
while(true) {
if((linked_zone >> 6) & 1)
if((linked_zone >> 6) & 0x1U)
return TRUE;
int32 checking = (int32)(linked_zone & ~checked);
uint32 checking = linked_zone & ~checked;
if(!checking)
return FALSE;
int32 rightmost = checking & (-checking);
checked |= (uint32)rightmost;
if(rightmost < 0x10000) {
uint32 rightmost = checking & (-checking);
checked |= rightmost;
if(rightmost < 0x10000U) {
for(int32 i = 0; i < 7; ++i) {
if(rightmost & 1) {
if(rightmost & 0x1U) {
pcard = player[playerid].list_mzone[i];
linked_zone |= pcard->get_mutual_linked_zone();
break;
......@@ -914,7 +920,7 @@ int32 field::check_extra_link(int32 playerid) {
} else {
rightmost >>= 16;
for(int32 i = 0; i < 7; ++i) {
if(rightmost & 1) {
if(rightmost & 0x1U) {
pcard = player[1 - playerid].list_mzone[i];
uint32 zone = pcard->get_mutual_linked_zone();
linked_zone |= (zone << 16) | (zone >> 16);
......@@ -1187,6 +1193,8 @@ void field::tag_swap(uint8 playerid) {
pduel->write_buffer32(pcard->data.code | (pcard->is_position(POS_FACEUP) ? 0x80000000 : 0));
}
void field::add_effect(effect* peffect, uint8 owner_player) {
if (!peffect)
return;
if (effects.indexer.find(peffect) != effects.indexer.end())
return;
effect_container::iterator it;
......@@ -1358,7 +1366,7 @@ void field::add_effect_code(uint32 code, uint32 playerid) {
count_map = &core.effect_count_code_duel;
else if(code & EFFECT_COUNT_CODE_CHAIN)
count_map = &core.effect_count_code_chain;
++(*count_map)[code + (playerid << 30)];
(*count_map)[code + (playerid << 30)]++;
}
uint32 field::get_effect_code(uint32 code, uint32 playerid) {
auto* count_map = &core.effect_count_code;
......@@ -1528,7 +1536,7 @@ int32 field::filter_matching_card(lua_State* L, int32 findex, uint8 self, uint32
}
if(location & LOCATION_PZONE) {
for(int32 i = 0; i < 2; ++i) {
card* pcard = player[self].list_szone[core.duel_rule >= NEW_MASTER_RULE ? i * 4 : i + 6];
card* pcard = player[self].list_szone[get_pzone_sequence(i)];
if(pcard && pcard->current.pzone && !pcard->is_treated_as_not_on_field()
&& pcard != pexception && !(pexgroup && pexgroup->has_card(pcard))
&& pduel->lua->check_filter(L, pcard, findex, extraargs)
......@@ -1654,7 +1662,7 @@ int32 field::filter_field_card(uint8 self, uint32 location1, uint32 location2, g
}
if(location & LOCATION_PZONE) {
for(int32 i = 0; i < 2; ++i) {
card* pcard = player[self].list_szone[core.duel_rule >= NEW_MASTER_RULE ? i * 4 : i + 6];
card* pcard = player[self].list_szone[get_pzone_sequence(i)];
if(pcard && pcard->current.pzone) {
result.insert(pcard);
}
......@@ -1680,7 +1688,7 @@ int32 field::filter_field_card(uint8 self, uint32 location1, uint32 location2, g
}
if (pgroup)
pgroup->container.insert(result.begin(), result.end());
return result.size();
return (int32)result.size();
}
effect* field::is_player_affected_by_effect(uint8 playerid, uint32 code) {
auto rg = effects.aura_effect.equal_range(code);
......@@ -1945,11 +1953,11 @@ void field::get_fusion_material(uint8 playerid, card_set* material_all, card_set
}
material_all->insert(material_base->begin(), material_base->end());
}
void field::ritual_release(card_set* material) {
void field::ritual_release(const card_set& material) {
card_set rel;
card_set rem;
card_set tgy;
for(auto& pcard : *material) {
for(const auto& pcard : material) {
if(pcard->current.location == LOCATION_GRAVE)
rem.insert(pcard);
else if(pcard->current.location == LOCATION_OVERLAY || pcard->current.location == LOCATION_EXTRA)
......@@ -1957,9 +1965,9 @@ void field::ritual_release(card_set* material) {
else
rel.insert(pcard);
}
send_to(&tgy, core.reason_effect, REASON_RITUAL + REASON_EFFECT + REASON_MATERIAL, core.reason_player, PLAYER_NONE, LOCATION_GRAVE, 0, POS_FACEUP);
release(&rel, core.reason_effect, REASON_RITUAL + REASON_EFFECT + REASON_MATERIAL, core.reason_player);
send_to(&rem, core.reason_effect, REASON_RITUAL + REASON_EFFECT + REASON_MATERIAL, core.reason_player, PLAYER_NONE, LOCATION_REMOVED, 0, POS_FACEUP);
send_to(tgy, core.reason_effect, REASON_RITUAL + REASON_EFFECT + REASON_MATERIAL, core.reason_player, PLAYER_NONE, LOCATION_GRAVE, 0, POS_FACEUP);
release(rel, core.reason_effect, REASON_RITUAL + REASON_EFFECT + REASON_MATERIAL, core.reason_player);
send_to(rem, core.reason_effect, REASON_RITUAL + REASON_EFFECT + REASON_MATERIAL, core.reason_player, PLAYER_NONE, LOCATION_REMOVED, 0, POS_FACEUP);
}
void field::get_xyz_material(lua_State* L, card* scard, int32 findex, uint32 lv, int32 maxc, group* mg) {
core.xmaterial_lst.clear();
......@@ -2142,6 +2150,8 @@ int32 field::adjust_grant_effect() {
effect* geffect = (effect*)peffect->get_label_object();
if (geffect->type & EFFECT_TYPE_GRANT)
continue;
if (geffect->code == EFFECT_UNIQUE_CHECK)
continue;
card_set cset;
if(peffect->is_available())
filter_affected_cards(peffect, &cset);
......@@ -2156,9 +2166,6 @@ int32 field::adjust_grant_effect() {
if(!pcard->is_affect_by_effect(peffect) || !cset.count(pcard))
remove_set.insert(pcard);
}
//X gains an effect from itself will break card::remove_effect
if (!peffect->is_flag(EFFECT_FLAG_FIELD_ONLY))
add_set.erase(peffect->handler);
for(auto& pcard : add_set) {
effect* ceffect = geffect->clone();
ceffect->owner = pcard;
......
......@@ -16,8 +16,6 @@
#include <set>
#include <map>
#include <list>
#include <array>
#include <functional>
#include <unordered_map>
#include <unordered_set>
......@@ -128,10 +126,10 @@ struct field_effect {
};
struct field_info {
int32 field_id{ 1 };
int16 copy_id{ 1 };
int16 turn_id{};
int16 turn_id_by_player[2]{};
int16 card_id{ 1 };
uint16 copy_id{ 1 };
uint16 turn_id{};
uint16 turn_id_by_player[2]{};
uint16 card_id{ 1 };
uint16 phase{};
uint8 turn_player{};
uint8 priorities[2]{};
......@@ -393,7 +391,9 @@ 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(uint8 playerid, uint32 general_location, uint8 sequence);
int32 get_pzone_sequence(uint8 pseq) const;
card* get_field_card(uint8 playerid, uint32 general_location, uint8 sequence) const;
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);
......@@ -444,7 +444,7 @@ public:
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 ritual_release(const card_set& material);
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);
......@@ -530,7 +530,7 @@ public:
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_event(const 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 = nullptr);
int32 check_event_c(effect* peffect, uint8 playerid, int32 neglect_con, int32 neglect_cost, int32 copy_info, tevent* pe = nullptr);
......@@ -567,9 +567,9 @@ public:
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(const 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, const card_set& targets1, const 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, int32 count);
......@@ -578,17 +578,17 @@ public:
void summon(uint32 sumplayer, card* target, effect* proc, uint32 ignore_count, uint32 min_tribute, uint32 zone = 0x1f, uint32 action_type = SUMMON_IN_IDLE);
void mset(uint32 setplayer, card* target, effect* proc, uint32 ignore_count, uint32 min_tribute, uint32 zone = 0x1f, uint32 action_type = SUMMON_IN_IDLE);
void special_summon_rule(uint32 sumplayer, card* target, uint32 summon_type, uint32 action_type = SUMMON_IN_IDLE);
void special_summon(card_set* target, uint32 sumtype, uint32 sumplayer, uint32 playerid, uint32 nocheck, uint32 nolimit, uint32 positions, uint32 zone);
void special_summon(const card_set& target, uint32 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_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(const 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, uint8 send_activating = FALSE);
void send_to(const card_set& targets, effect* reason_effect, uint32 reason, uint32 reason_player, uint32 playerid, uint32 destination, uint32 sequence, uint32 position, uint8 send_activating = FALSE);
void send_to(card* target, effect* reason_effect, uint32 reason, uint32 reason_player, uint32 playerid, uint32 destination, uint32 sequence, uint32 position, uint8 send_activating = FALSE);
void move_to_field(card* target, uint32 move_player, uint32 playerid, uint32 destination, uint32 positions, uint32 enable = FALSE, uint32 ret = 0, uint32 pzone = FALSE, uint32 zone = 0xff);
void change_position(card_set* targets, effect* reason_effect, uint32 reason_player, uint32 au, uint32 ad, uint32 du, uint32 dd, uint32 flag, uint32 enable = FALSE);
void change_position(const card_set& targets, effect* reason_effect, uint32 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);
......@@ -632,7 +632,7 @@ public:
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);
bool check_response(int32 vector_size, int32 min_len, int32 max_len) const;
bool check_response(size_t vector_size, int32 min_len, int32 max_len) const;
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);
......
......@@ -134,7 +134,9 @@ interpreter::interpreter(duel* pd): coroutines(256) {
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, nullptr);
card ** ppcard = (card**) lua_newuserdata(lua_state, sizeof(card*)); //+1 userdata
......@@ -149,14 +151,13 @@ int32 interpreter::register_card(card *pcard) {
lua_setmetatable(current_state, -2); //-1
lua_pop(current_state, 1); //-1
//Initial
if(pcard->data.code && is_load_script(pcard->data)) {
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)
......@@ -596,7 +597,7 @@ int32 interpreter::get_function_value(int32 f, uint32 param_count) {
}
return OPERATION_FAIL;
}
int32 interpreter::get_function_value(int32 f, uint32 param_count, std::vector<int32>* result) {
int32 interpreter::get_function_value(int32 f, uint32 param_count, std::vector<lua_Integer>& result) {
int32 is_success = OPERATION_FAIL;
if(!f) {
params.clear();
......@@ -608,14 +609,14 @@ int32 interpreter::get_function_value(int32 f, uint32 param_count, std::vector<i
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;
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;
......@@ -763,11 +764,13 @@ int32 interpreter::get_function_handle(lua_State* L, int32 index) {
int32 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;
std::memcpy(&pduel, lua_getextraspace(L), LUA_EXTRASPACE);
return pduel;
}
bool interpreter::is_load_script(card_data data) {
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);
}
......@@ -58,7 +58,7 @@ public:
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);
......@@ -76,7 +76,7 @@ public:
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);
int32 get_function_value(int32 f, uint32 param_count, std::vector<lua_Integer>& result);
int32 call_coroutine(int32 f, uint32 param_count, int32* yield_value, uint16 step);
int32 clone_function_ref(int32 func_ref);
void* get_ref_object(int32 ref_handler);
......@@ -87,7 +87,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);
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) {
......
......@@ -524,10 +524,14 @@ 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 >= NEW_MASTER_RULE ? 0 : 6))
lua_pushinteger(L, pcard->get_lscale());
if (pcard->current.pzone) {
if (pcard->current.sequence == pcard->pduel->game_field->get_pzone_sequence(0))
lua_pushinteger(L, pcard->get_lscale());
else
lua_pushinteger(L, pcard->get_rscale());
}
else
lua_pushinteger(L, pcard->get_rscale());
lua_pushinteger(L, pcard->data.lscale);
return 1;
}
int32 scriptlib::card_is_link_marker(lua_State *L) {
......@@ -1476,6 +1480,24 @@ int32 scriptlib::card_is_tuner(lua_State* L) {
lua_pushboolean(L, pcard->is_tuner(scard));
return 1;
}
int32 scriptlib::card_is_original_effect_property(lua_State* L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
card* pcard = *(card**)lua_touserdata(L, 1);
int32 filter = interpreter::get_function_handle(L, 2);
lua_pushboolean(L, pcard->is_original_effect_property(filter));
return 1;
}
int32 scriptlib::card_is_effect_property(lua_State* L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1);
check_param(L, PARAM_TYPE_FUNCTION, 2);
card* pcard = *(card**)lua_touserdata(L, 1);
int32 filter = interpreter::get_function_handle(L, 2);
lua_pushboolean(L, pcard->is_effect_property(filter));
return 1;
}
int32 scriptlib::card_set_status(lua_State *L) {
check_param_count(L, 3);
check_param(L, PARAM_TYPE_CARD, 1);
......@@ -1937,6 +1959,10 @@ int32 scriptlib::card_register_effect(lua_State *L) {
pduel->game_field->core.reseted_effects.insert(peffect);
return 0;
}
for (auto& entry : category_checklist) {
if (peffect->category & entry.first)
peffect->flag[0] |= entry.second;
}
int32 id;
if (peffect->handler)
id = -1;
......@@ -2000,12 +2026,12 @@ 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);
uint32 flag = (uint32)lua_tointeger(L, 4);
uint64 flag = lua_tointeger(L, 4);
int32 count = (int32)lua_tointeger(L, 5);
int32 lab = 0;
lua_Integer lab = 0;
int32 desc = 0;
if(lua_gettop(L) >= 6)
lab = (int32)lua_tointeger(L, 6);
lab = lua_tointeger(L, 6);
if(lua_gettop(L) >= 7)
desc = (int32)lua_tointeger(L, 7);
if(count == 0)
......@@ -2049,7 +2075,7 @@ int32 scriptlib::card_set_flag_effect_label(lua_State *L) {
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
uint32 code = (lua_tointeger(L, 2) & MAX_CARD_ID) | EFFECT_FLAG_EFFECT;
int32 lab = (int32)lua_tointeger(L, 3);
auto lab = lua_tointeger(L, 3);
auto eit = pcard->single_effect.find(code);
if(eit == pcard->single_effect.end())
lua_pushboolean(L, FALSE);
......@@ -3691,6 +3717,8 @@ static const struct luaL_Reg cardlib[] = {
{ "IsStatus", scriptlib::card_is_status },
{ "IsNotTuner", scriptlib::card_is_not_tuner },
{ "IsTuner", scriptlib::card_is_tuner },
{ "IsOriginalEffectProperty", scriptlib::card_is_original_effect_property },
{ "IsEffectProperty", scriptlib::card_is_effect_property },
{ "SetStatus", scriptlib::card_set_status },
{ "IsDualState", scriptlib::card_is_dual_state },
{ "EnableDualState", scriptlib::card_enable_dual_state },
......
......@@ -49,7 +49,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 >= NEW_MASTER_RULE ? sequence * 4 : sequence + 6;
int32 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);
......
This diff is collapsed.
......@@ -20,16 +20,6 @@ int32 scriptlib::effect_set_owner(lua_State *L) {
peffect->owner = pcard;
return 0;
}
int32 scriptlib::effect_get_range(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->range);
return 1;
}
return 0;
}
int32 scriptlib::effect_get_count_limit(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1);
......@@ -46,6 +36,61 @@ int32 scriptlib::effect_get_count_limit(lua_State *L) {
return args;
}
int32 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 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 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 x = lua_tointeger(L, 2);
if (value & x)
lua_pushboolean(L, 1);
else
lua_pushboolean(L, 0);
return 1;
}
int32 scriptlib::effect_new(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
......@@ -86,11 +131,7 @@ int32 scriptlib::effect_reset(lua_State *L) {
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;
return get_effect_property(L, MEMBER_ID);
}
int32 scriptlib::effect_set_description(lua_State *L) {
check_param_count(L, 2);
......@@ -181,19 +222,27 @@ int32 scriptlib::effect_set_type(lua_State *L) {
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 v = (uint32)lua_tointeger(L, 2);
if (v & EFFECT_TYPE_ACTIVATE) {
v = EFFECT_TYPE_FIELD | EFFECT_TYPE_ACTIVATE;
peffect->range = LOCATION_SZONE + LOCATION_FZONE + LOCATION_HAND;
}
else if(v & EFFECT_TYPE_FLIP) {
peffect->code = EVENT_FLIP;
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;
if(v & (EFFECT_TYPE_ACTIVATE | EFFECT_TYPE_IGNITION | EFFECT_TYPE_QUICK_O | EFFECT_TYPE_QUICK_F))
v |= EFFECT_TYPE_FIELD;
if(v & EFFECT_TYPE_ACTIVATE)
peffect->range = LOCATION_SZONE + LOCATION_FZONE + LOCATION_HAND;
if(v & EFFECT_TYPE_FLIP) {
peffect->code = EVENT_FLIP;
if(!(v & EFFECT_TYPE_TRIGGER_O))
v |= EFFECT_TYPE_TRIGGER_F;
}
peffect->type = v;
return 0;
}
......@@ -201,8 +250,8 @@ int32 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);
uint64 v1 = lua_tointeger(L, 2);
uint64 v2 = lua_tointeger(L, 3);
peffect->flag[0] = (peffect->flag[0] & INTERNAL_FLAGS) | (v1 & ~INTERNAL_FLAGS);
peffect->flag[1] = v2;
return 0;
......@@ -213,8 +262,7 @@ int32 scriptlib::effect_set_label(lua_State *L) {
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);
peffect->label.push_back(lua_tointeger(L, i));
}
return 0;
}
......@@ -337,34 +385,13 @@ int32 scriptlib::effect_set_owner_player(lua_State *L) {
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;
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;
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;
return get_effect_property(L, MEMBER_TYPE);
}
int32 scriptlib::effect_get_property(lua_State *L) {
check_param_count(L, 1);
......@@ -410,14 +437,10 @@ int32 scriptlib::effect_get_label_object(lua_State *L) {
}
}
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;
return get_effect_property(L, MEMBER_CATEGORY);
}
int32 scriptlib::effect_get_range(lua_State* L) {
return get_effect_property(L, MEMBER_RANGE);
}
int32 scriptlib::effect_get_owner(lua_State *L) {
check_param_count(L, 1);
......@@ -507,8 +530,8 @@ int32 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 tflag1 = lua_tointeger(L, 2);
uint64 tflag2 = lua_tointeger(L, 3);
if (peffect && (!tflag1 || (peffect->flag[0] & tflag1)) && (!tflag2 || (peffect->flag[1] & tflag2)))
lua_pushboolean(L, 1);
else
......@@ -516,26 +539,13 @@ int32 scriptlib::effect_is_has_property(lua_State *L) {
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;
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;
return is_effect_has_property(L, MEMBER_TYPE);
}
int32 scriptlib::effect_is_has_range(lua_State* L) {
return is_effect_has_property(L, MEMBER_RANGE);
}
int32 scriptlib::effect_is_activatable(lua_State *L) {
check_param_count(L, 2);
......@@ -619,7 +629,6 @@ int32 scriptlib::effect_use_count_limit(lua_State *L) {
static const struct luaL_Reg effectlib[] = {
{ "SetOwner", scriptlib::effect_set_owner },
{ "GetRange", scriptlib::effect_get_range },
{ "GetCountLimit", scriptlib::effect_get_count_limit },
{ "CreateEffect", scriptlib::effect_new },
......@@ -653,6 +662,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 },
......@@ -667,6 +677,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 },
......
......@@ -6,6 +6,7 @@
*/
#include <cstdio>
#include <cstring>
#include <set>
#include "ocgapi.h"
#include "duel.h"
#include "card.h"
......@@ -14,7 +15,6 @@
#include "field.h"
#include "interpreter.h"
#include "buffer.h"
#include <set>
static script_reader sreader = default_script_reader;
static card_reader creader = default_card_reader;
......@@ -35,6 +35,10 @@ byte* read_script(const char* script_name, int* len) {
return sreader(script_name, len);
}
uint32 read_card(uint32 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) {
......@@ -132,7 +136,9 @@ extern "C" DECL_DLLEXPORT void set_player_info(intptr_t pduel, int32 playerid, i
pd->game_field->player[playerid].draw_count = drawcount;
}
extern "C" DECL_DLLEXPORT void get_log_message(intptr_t pduel, char* buf) {
std::strcpy(buf, ((duel*)pduel)->strbuffer);
duel* pd = (duel*)pduel;
buf[0] = '\0';
std::strncat(buf, pd->strbuffer, sizeof pd->strbuffer - 1);
}
extern "C" DECL_DLLEXPORT int32 get_message(intptr_t pduel, byte* buf) {
int32 len = ((duel*)pduel)->read_buffer(buf);
......
......@@ -19,6 +19,7 @@
#define LEN_FAIL 0
#define LEN_EMPTY 4
#define LEN_HEADER 8
#define TEMP_CARD_ID 0
class card;
struct card_data;
......
This diff is collapsed.
......@@ -14,14 +14,14 @@
#include <algorithm>
#include <stack>
bool field::check_response(int32 vector_size, int32 min_len, int32 max_len) const {
bool field::check_response(size_t vector_size, int32 min_len, int32 max_len) const {
const int32 len = returns.bvalue[0];
if (len < min_len || len > max_len)
return false;
std::set<uint8> index_set;
for (int32 i = 0; i < len; ++i) {
uint8 index = returns.bvalue[1 + i];
if (index >=vector_size || index_set.count(index)) {
if (index >= (int32)vector_size || index_set.count(index)) {
return false;
}
index_set.insert(index);
......@@ -787,7 +787,7 @@ int32 field::sort_card(int16 step, uint8 playerid) {
int32 field::announce_race(int16 step, uint8 playerid, int32 count, int32 available) {
if(step == 0) {
int32 scount = 0;
for(int32 ft = 0x1; ft < (1 << RACES_COUNT); ft <<= 1) {
for(uint32 ft = 0x1; ft < (0x1U << RACES_COUNT); ft <<= 1) {
if(ft & available)
++scount;
}
......@@ -803,8 +803,9 @@ int32 field::announce_race(int16 step, uint8 playerid, int32 count, int32 availa
} else {
int32 rc = returns.ivalue[0];
int32 sel = 0;
for(int32 ft = 0x1; ft < (1 << RACES_COUNT); ft <<= 1) {
if(!(ft & rc)) continue;
for(uint32 ft = 0x1; ft < (0x1U << RACES_COUNT); ft <<= 1) {
if(!(ft & rc))
continue;
if(!(ft & available)) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
......@@ -912,7 +913,7 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
stack.pop();
int32 lhs = stack.top();
stack.pop();
stack.push(lhs && rhs);
stack.push(static_cast<int32>(lhs && rhs));
}
break;
}
......@@ -922,7 +923,7 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
stack.pop();
int32 lhs = stack.top();
stack.pop();
stack.push(lhs || rhs);
stack.push(static_cast<int32>(lhs || rhs));
}
break;
}
......@@ -938,7 +939,7 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
if(stack.size() >= 1) {
int32 val = stack.top();
stack.pop();
stack.push(!val);
stack.push(static_cast<int32>(!val));
}
break;
}
......
......@@ -37,7 +37,7 @@ workspace "ocgcoredll"
filter { "configurations:Release", "action:vs*" }
flags { "LinkTimeOptimization" }
staticruntime "On"
disablewarnings { "4267", "4334" }
disablewarnings { "4334" }
filter "action:vs*"
buildoptions { "/utf-8" }
......
This diff is collapsed.
......@@ -17,6 +17,14 @@ constexpr bool match_all(uint32 x, uint32 y) {
class scriptlib {
public:
enum effect_member : int32 {
MEMBER_CATEGORY,
MEMBER_CODE,
MEMBER_DESCRIPTION,
MEMBER_ID,
MEMBER_RANGE,
MEMBER_TYPE,
};
static int32 check_param(lua_State* L, int32 param_type, int32 index, int32 retfalse = FALSE);
static int32 check_param_count(lua_State* L, int32 count);
static int32 check_action_permission(lua_State* L);
......@@ -29,7 +37,6 @@ public:
static int32 card_is_xyz_summonable_by_rose(lua_State *L);
static int32 card_get_removed_overlay_count(lua_State *L);
static int32 effect_set_owner(lua_State *L);
static int32 effect_get_range(lua_State *L);
static int32 effect_get_count_limit(lua_State *L);
static int32 duel_get_master_rule(lua_State *L);
static int32 duel_read_card(lua_State *L);
......@@ -165,6 +172,8 @@ public:
static int32 card_is_status(lua_State *L);
static int32 card_is_not_tuner(lua_State *L);
static int32 card_is_tuner(lua_State* L);
static int32 card_is_original_effect_property(lua_State* L);
static int32 card_is_effect_property(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);
......@@ -323,6 +332,8 @@ public:
static void open_cardlib(lua_State *L);
//Effect functions
static int32 get_effect_property(lua_State* L, effect_member type);
static int32 is_effect_has_property(lua_State* L, effect_member type);
static int32 effect_new(lua_State *L);
static int32 effect_newex(lua_State *L);
static int32 effect_clone(lua_State *L);
......@@ -354,6 +365,7 @@ public:
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_range(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);
......@@ -367,6 +379,7 @@ public:
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_range(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);
......
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