Commit bb6006e5 authored by wind2009's avatar wind2009

Merge remote-tracking branch 'upstream/master' into develop

parents dc1e9c42 556c10f4
......@@ -23,7 +23,7 @@ These functions create the game itself and then manipulate it.
- `intptr_t create_duel(uint_fast32_t seed);`
Create a the instance of the duel with a PRNG seed.
- `void start_duel(intptr_t pduel, int32 options);`
- `void start_duel(intptr_t pduel, uint32 options);`
Start the duel.
- `void end_duel(intptr_t pduel);`
......
......@@ -1104,21 +1104,18 @@ uint32 card::get_attribute() {
if(temp.attribute != UINT32_MAX) // prevent recursion, return the former value
return temp.attribute;
effect_set effects;
int32 attribute = data.attribute;
auto attribute = data.attribute;
temp.attribute = data.attribute;
filter_effect(EFFECT_ADD_ATTRIBUTE, &effects, FALSE);
filter_effect(EFFECT_REMOVE_ATTRIBUTE, &effects);
filter_effect(EFFECT_REMOVE_ATTRIBUTE, &effects, FALSE);
filter_effect(EFFECT_CHANGE_ATTRIBUTE, &effects);
for (int32 i = 0; i < effects.size(); ++i) {
if (effects[i]->code == EFFECT_ADD_ATTRIBUTE)
attribute |= effects[i]->get_value(this);
else
else if (effects[i]->code == EFFECT_REMOVE_ATTRIBUTE)
attribute &= ~(effects[i]->get_value(this));
temp.attribute = attribute;
}
effects.clear();
filter_effect(EFFECT_CHANGE_ATTRIBUTE, &effects);
for (int32 i = 0; i < effects.size(); ++i) {
attribute = effects[i]->get_value(this);
else if (effects[i]->code == EFFECT_CHANGE_ATTRIBUTE)
attribute = effects[i]->get_value(this);
temp.attribute = attribute;
}
temp.attribute = UINT32_MAX;
......@@ -1174,21 +1171,18 @@ uint32 card::get_race() {
if(temp.race != UINT32_MAX) // prevent recursion, return the former value
return temp.race;
effect_set effects;
int32 race = data.race;
auto race = data.race;
temp.race = data.race;
filter_effect(EFFECT_ADD_RACE, &effects, FALSE);
filter_effect(EFFECT_REMOVE_RACE, &effects);
filter_effect(EFFECT_REMOVE_RACE, &effects, FALSE);
filter_effect(EFFECT_CHANGE_RACE, &effects);
for (int32 i = 0; i < effects.size(); ++i) {
if (effects[i]->code == EFFECT_ADD_RACE)
race |= effects[i]->get_value(this);
else
else if (effects[i]->code == EFFECT_REMOVE_RACE)
race &= ~(effects[i]->get_value(this));
temp.race = race;
}
effects.clear();
filter_effect(EFFECT_CHANGE_RACE, &effects);
for (int32 i = 0; i < effects.size(); ++i) {
race = effects[i]->get_value(this);
else if (effects[i]->code == EFFECT_CHANGE_RACE)
race = effects[i]->get_value(this);
temp.race = race;
}
temp.race = UINT32_MAX;
......@@ -2526,7 +2520,7 @@ void card::set_special_summon_status(effect* peffect) {
}
card* pcard = peffect->get_handler();
auto cait = pduel->game_field->core.current_chain.rbegin();
if(!(peffect->type & 0x7f0) || (pcard->is_has_relation(*cait) && !(pcard->get_type() & TYPE_TRAPMONSTER))) {
if(!(peffect->type & EFFECT_TYPES_CHAIN_LINK) || (pcard->is_has_relation(*cait) && !(pcard->get_type() & TYPE_TRAPMONSTER))) {
spsummon.code = pcard->get_code();
spsummon.code2 = pcard->get_another_code();
spsummon.type = pcard->get_type();
......@@ -2947,33 +2941,32 @@ void card::filter_spsummon_procedure_g(uint8 playerid, effect_set* peset) {
}
// find an effect with code which affects this
effect* card::is_affected_by_effect(int32 code) {
effect* peffect = nullptr;
auto rg = single_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (peffect->is_available() && (!peffect->is_flag(EFFECT_FLAG_SINGLE_RANGE) || is_affect_by_effect(peffect)))
return peffect;
}
for (auto& pcard : equiping_cards) {
rg = pcard->equip_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (peffect->is_available() && is_affect_by_effect(peffect))
return peffect;
}
}
for (auto& pcard : effect_target_owner) {
rg = pcard->target_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (peffect->is_available() && peffect->is_target(this) && is_affect_by_effect(peffect))
return peffect;
}
}
for (auto& pcard : xyz_materials) {
rg = pcard->xmaterial_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (peffect->type & EFFECT_TYPE_FIELD)
continue;
if (peffect->is_available() && is_affect_by_effect(peffect))
......@@ -2981,8 +2974,8 @@ effect* card::is_affected_by_effect(int32 code) {
}
}
rg = pduel->game_field->effects.aura_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (!peffect->is_flag(EFFECT_FLAG_PLAYER_TARGET) && peffect->is_target(this)
&& peffect->is_available() && is_affect_by_effect(peffect))
return peffect;
......@@ -2990,34 +2983,33 @@ effect* card::is_affected_by_effect(int32 code) {
return nullptr;
}
effect* card::is_affected_by_effect(int32 code, card* target) {
effect* peffect = nullptr;
auto rg = single_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (peffect->is_available() && (!peffect->is_flag(EFFECT_FLAG_SINGLE_RANGE) || is_affect_by_effect(peffect))
&& peffect->get_value(target))
&& peffect->get_value(target))
return peffect;
}
for (auto& pcard : equiping_cards) {
rg = pcard->equip_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (peffect->is_available() && is_affect_by_effect(peffect) && peffect->get_value(target))
return peffect;
}
}
for (auto& pcard : effect_target_owner) {
rg = pcard->target_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (peffect->is_available() && peffect->is_target(this) && is_affect_by_effect(peffect) && peffect->get_value(target))
return peffect;
}
}
for (auto& pcard : xyz_materials) {
rg = pcard->xmaterial_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (peffect->type & EFFECT_TYPE_FIELD)
continue;
if (peffect->is_available() && is_affect_by_effect(peffect) && peffect->get_value(target))
......@@ -3025,10 +3017,10 @@ effect* card::is_affected_by_effect(int32 code, card* target) {
}
}
rg = pduel->game_field->effects.aura_effect.equal_range(code);
for (; rg.first != rg.second; ++rg.first) {
peffect = rg.first->second;
for (auto it = rg.first; it != rg.second; ++it) {
effect* const& peffect = it->second;
if (!peffect->is_flag(EFFECT_FLAG_PLAYER_TARGET) && peffect->is_available()
&& peffect->is_target(this) && is_affect_by_effect(peffect) && peffect->get_value(target))
&& peffect->is_target(this) && is_affect_by_effect(peffect) && peffect->get_value(target))
return peffect;
}
return nullptr;
......
......@@ -26,6 +26,8 @@ struct chain;
using card_set = std::set<card*, card_sort>;
using card_vector = std::vector<card*>;
using effect_container = std::multimap<uint32, effect*>;
using effect_indexer = std::unordered_map<effect*, effect_container::iterator>;
struct card_state {
uint32 code{ 0 };
......@@ -116,8 +118,6 @@ public:
return std::hash<uint16>()(v.second);
}
};
using effect_container = std::multimap<uint32, effect*>;
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>;
......
......@@ -114,6 +114,7 @@ typedef signed char int8;
#define TYPES_EXTRA_DECK (TYPE_FUSION | TYPE_SYNCHRO | TYPE_XYZ | TYPE_LINK)
//Attributes
#define ATTRIBUTES_COUNT 7
#define ATTRIBUTE_ALL 0x7f //
#define ATTRIBUTE_EARTH 0x01 //
#define ATTRIBUTE_WATER 0x02 //
......
......@@ -12,6 +12,10 @@
#include "interpreter.h"
bool effect_sort_id(const effect* e1, const effect* e2) {
int32 is_single1 = e1->is_initial_single();
int32 is_single2 = e2->is_initial_single();
if (is_single1 != is_single2)
return is_single1 > is_single2;
return e1->id < e2->id;
}
// return: code is an event reserved for EFFECT_TYPE_CONTINUOUS or not
......@@ -30,17 +34,17 @@ effect::effect(duel* pd) {
pduel = pd;
label.reserve(4);
}
int32 effect::is_disable_related() {
int32 effect::is_disable_related() const {
if (code == EFFECT_IMMUNE_EFFECT || code == EFFECT_DISABLE || code == EFFECT_CANNOT_DISABLE || code == EFFECT_FORBIDDEN)
return TRUE;
return FALSE;
}
int32 effect::is_self_destroy_related() {
int32 effect::is_self_destroy_related() const {
if(code == EFFECT_UNIQUE_CHECK || code == EFFECT_SELF_DESTROY || code == EFFECT_SELF_TOGRAVE)
return TRUE;
return FALSE;
}
int32 effect::is_can_be_forbidden() {
int32 effect::is_can_be_forbidden() const {
if (is_flag(EFFECT_FLAG_CANNOT_DISABLE) && !is_flag(EFFECT_FLAG_CANNOT_NEGATE))
return FALSE;
return TRUE;
......@@ -612,9 +616,12 @@ int32 effect::is_chainable(uint8 tp) {
}
return TRUE;
}
int32 effect::is_hand_trigger() {
int32 effect::is_hand_trigger() const {
return (range & LOCATION_HAND) && (type & EFFECT_TYPE_TRIGGER_O) && get_code_type() != CODE_PHASE;
}
int32 effect::is_initial_single() const {
return (type & EFFECT_TYPE_SINGLE) && is_flag(EFFECT_FLAG_SINGLE_RANGE) && is_flag(EFFECT_FLAG_INITIAL);
}
//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) {
......@@ -802,7 +809,7 @@ card* effect::get_owner() const {
return handler->overlay_target;
return owner;
}
uint8 effect::get_owner_player() {
uint8 effect::get_owner_player() const {
if(effect_owner != PLAYER_NONE)
return effect_owner;
return get_owner()->current.controler;
......@@ -814,17 +821,17 @@ card* effect::get_handler() const {
return handler->overlay_target;
return handler;
}
uint8 effect::get_handler_player() {
uint8 effect::get_handler_player() const {
if(is_flag(EFFECT_FLAG_FIELD_ONLY))
return effect_owner;
return get_handler()->current.controler;
}
int32 effect::in_range(card* pcard) {
int32 effect::in_range(card* pcard) const {
if(type & EFFECT_TYPE_XMATERIAL)
return handler->overlay_target ? TRUE : FALSE;
return pcard->current.is_location(range);
}
int32 effect::in_range(const chain& ch) {
int32 effect::in_range(const chain& ch) const {
if(type & EFFECT_TYPE_XMATERIAL)
return handler->overlay_target ? TRUE : FALSE;
return range & ch.triggering_location;
......@@ -841,7 +848,7 @@ void effect::set_active_type() {
active_type &= ~TYPE_TRAP;
}
uint32 effect::get_active_type(uint8 uselast) {
if(type & 0x7f0) {
if(type & EFFECT_TYPES_CHAIN_LINK) {
if(active_type && uselast)
return active_type;
else if((type & EFFECT_TYPE_ACTIVATE) && (get_handler()->data.type & TYPE_PENDULUM))
......
......@@ -36,7 +36,7 @@ public:
uint32 code{ 0 };
uint32 flag[2]{};
uint32 id{ 0 };
uint16 type{ 0 };
uint32 type{ 0 };
uint16 copy_id{ 0 };
uint16 range{ 0 };
uint16 s_range{ 0 };
......@@ -67,9 +67,9 @@ public:
explicit effect(duel* pd);
~effect() = default;
int32 is_disable_related();
int32 is_self_destroy_related();
int32 is_can_be_forbidden();
int32 is_disable_related() const;
int32 is_self_destroy_related() const;
int32 is_can_be_forbidden() const;
int32 is_available(int32 neglect_disabled = FALSE);
int32 limit_counter_is_available();
int32 is_single_ready();
......@@ -87,7 +87,8 @@ public:
int32 is_player_effect_target(card* pcard);
int32 is_immuned(card* pcard);
int32 is_chainable(uint8 tp);
int32 is_hand_trigger();
int32 is_hand_trigger() const;
int32 is_initial_single() const;
int32 reset(uint32 reset_level, uint32 reset_type);
void dec_count(uint8 playerid = PLAYER_NONE);
void recharge();
......@@ -103,11 +104,11 @@ public:
int32 get_speed();
effect* clone();
card* get_owner() const;
uint8 get_owner_player();
uint8 get_owner_player() const;
card* get_handler() const;
uint8 get_handler_player();
int32 in_range(card* pcard);
int32 in_range(const chain& ch);
uint8 get_handler_player() const;
int32 in_range(card* pcard) const;
int32 in_range(const chain& ch) const;
void set_activate_location();
void set_active_type();
uint32 get_active_type(uint8 uselast = TRUE);
......@@ -171,7 +172,8 @@ public:
#define EFFECT_TYPE_GRANT 0x2000 //
#define EFFECT_TYPE_TARGET 0x4000 //
#define EFFECT_TYPES_TRIGGER_LIKE (EFFECT_TYPE_ACTIVATE | EFFECT_TYPE_TRIGGER_O | EFFECT_TYPE_TRIGGER_F | EFFECT_TYPE_QUICK_O | EFFECT_TYPE_QUICK_F)
constexpr uint32 EFFECT_TYPES_TRIGGER_LIKE = EFFECT_TYPE_ACTIVATE | EFFECT_TYPE_TRIGGER_O | EFFECT_TYPE_TRIGGER_F | EFFECT_TYPE_QUICK_O | EFFECT_TYPE_QUICK_F;
constexpr uint32 EFFECT_TYPES_CHAIN_LINK = EFFECT_TYPES_TRIGGER_LIKE | EFFECT_TYPE_FLIP | EFFECT_TYPE_IGNITION;
//========== Flags ==========
enum effect_flag : uint32 {
......
......@@ -33,6 +33,8 @@ class duel;
class group;
class effect;
using effect_vector = std::vector<effect*>;
bool check_playerid(int32 playerid);
struct tevent {
......@@ -100,8 +102,6 @@ struct player_info {
card_vector tag_list_extra;
};
struct field_effect {
using effect_container = std::multimap<uint32, effect*>;
using effect_indexer = std::unordered_map<effect*, effect_container::iterator>;
using oath_effects = std::unordered_map<effect*, effect*>;
using effect_collection = std::unordered_set<effect*>;
using gain_effects = std::unordered_map<card*, effect*>;
......@@ -171,7 +171,6 @@ union return_value {
int64 lvalue[SIZE_LVALUE];
};
struct processor {
using effect_vector = std::vector<effect*>;
using option_vector = std::vector<uint32>;
using card_list = std::list<card*>;
using event_list = std::list<tevent>;
......@@ -364,8 +363,6 @@ struct processor {
};
class field {
public:
using effect_container = std::multimap<uint32, effect*>;
using effect_vector = std::vector<effect*>;
using card_list = std::list<card*>;
using event_list = std::list<tevent>;
using chain_list = std::list<chain>;
......
......@@ -147,7 +147,7 @@ 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 & 0x0ff0)
if (v & (EFFECT_TYPES_CHAIN_LINK | EFFECT_TYPE_CONTINUOUS))
v |= EFFECT_TYPE_ACTIONS;
else
v &= ~EFFECT_TYPE_ACTIONS;
......@@ -518,7 +518,7 @@ int32 scriptlib::effect_is_activated(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1);
lua_pushboolean(L, (peffect->type & 0x7f0));
lua_pushboolean(L, (peffect->type & EFFECT_TYPES_CHAIN_LINK));
return 1;
}
int32 scriptlib::effect_is_cost_checked(lua_State *L) {
......
......@@ -4915,7 +4915,7 @@ int32 field::change_position(uint16 step, group * targets, effect * reason_effec
flips.insert(pcard);
}
if(enable) {
if(!reason_effect || !(reason_effect->type & 0x7f0) || pcard->current.location != LOCATION_MZONE)
if(!reason_effect || !(reason_effect->type & EFFECT_TYPES_CHAIN_LINK) || pcard->current.location != LOCATION_MZONE)
pcard->enable_field_effect(true);
else
core.delayed_enable_set.insert(pcard);
......
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