Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
mercury233 committed Oct 21, 2024
2 parents 8327d70 + 8da5c41 commit b30ab3f
Show file tree
Hide file tree
Showing 20 changed files with 156 additions and 145 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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);`
Expand Down Expand Up @@ -60,7 +60,7 @@ Get all cards in some location.

- `void set_responseb(intptr_t pduel, byte* buf);`

- `int32 preload_script(intptr_t pduel, const char* script, int32 len);`
- `int32 preload_script(intptr_t pduel, const char* script_name);`


# Lua functions
Expand Down
90 changes: 41 additions & 49 deletions card.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -2064,7 +2058,7 @@ int32 card::replace_effect(uint32 code, uint32 reset, int32 count) {
for(auto i = indexer.begin(); i != indexer.end();) {
auto rm = i++;
effect* peffect = rm->first;
auto it = rm->second;
auto& it = rm->second;
if (peffect->is_flag(EFFECT_FLAG_INITIAL | EFFECT_FLAG_COPY_INHERIT))
remove_effect(peffect, it);
}
Expand Down Expand Up @@ -2168,7 +2162,7 @@ void card::reset(uint32 id, uint32 reset_type) {
for (auto i = indexer.begin(); i != indexer.end();) {
auto rm = i++;
effect* peffect = rm->first;
auto it = rm->second;
auto& it = rm->second;
if (peffect->reset(id, reset_type))
remove_effect(peffect, it);
}
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -2726,8 +2720,8 @@ void card::filter_disable_related_cards() {
// return value:
// -2 = this has a EFFECT_LIMIT_SUMMON_PROC, 0 available
// -1 = this has a EFFECT_LIMIT_SUMMON_PROC, at least 1 available
// 0 = no EFFECT_LIMIT_SUMMON_PROC, and ordinary summon ia not available
// 1 = no EFFECT_LIMIT_SUMMON_PROC, and ordinary summon ia available
// 0 = no EFFECT_LIMIT_SUMMON_PROC, and ordinary summon is not available
// 1 = no EFFECT_LIMIT_SUMMON_PROC, and ordinary summon is available
int32 card::filter_summon_procedure(uint8 playerid, effect_set* peset, uint8 ignore_count, uint8 min_tribute, uint32 zone) {
effect_set eset;
filter_effect(EFFECT_LIMIT_SUMMON_PROC, &eset);
Expand Down Expand Up @@ -2947,88 +2941,86 @@ 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))
return peffect;
}
}
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;
}
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))
return peffect;
}
}
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;
Expand Down Expand Up @@ -3671,8 +3663,8 @@ int32 card::is_setable_szone(uint8 playerid, uint8 ignore_fd) {
return TRUE;
}
int32 card::is_affect_by_effect(effect* reason_effect) {
if(is_status(STATUS_SUMMONING) && reason_effect->code != EFFECT_CANNOT_DISABLE_SUMMON && reason_effect->code != EFFECT_CANNOT_DISABLE_SPSUMMON)
return FALSE;
if (is_status(STATUS_SUMMONING))
return reason_effect && (reason_effect->code == EFFECT_CANNOT_DISABLE_SUMMON || reason_effect->code == EFFECT_CANNOT_DISABLE_SPSUMMON);
if(!reason_effect || reason_effect->is_flag(EFFECT_FLAG_IGNORE_IMMUNE))
return TRUE;
if(reason_effect->is_immuned(this))
Expand Down
4 changes: 2 additions & 2 deletions card.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 };
Expand Down Expand Up @@ -116,8 +118,6 @@ class card {
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>;
Expand Down
1 change: 1 addition & 0 deletions common.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 //
Expand Down
2 changes: 1 addition & 1 deletion duel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ int32 duel::read_buffer(byte* buf) {
}
void duel::release_script_group() {
for(auto& pgroup : sgroups) {
if(pgroup->is_readonly == 0) {
if(pgroup->is_readonly == GTYPE_DEFAULT) {
lua->unregister_group(pgroup);
groups.erase(pgroup);
delete pgroup;
Expand Down
25 changes: 16 additions & 9 deletions effect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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))
Expand Down
Loading

0 comments on commit b30ab3f

Please sign in to comment.