Commit b88b9708 authored by Chen Bill's avatar Chen Bill Committed by GitHub

Use array to store setcode (#541)

* card_data: add is_setcode()

* card: update is_set_card()

* card_state: setcode use uint16_t

* card_data: add is_alternative()

* use array

* fix card_data
parent 6981843a
...@@ -421,7 +421,7 @@ uint32 card::get_info_location() { ...@@ -421,7 +421,7 @@ uint32 card::get_info_location() {
} }
// get the printed code on card // get the printed code on card
uint32 card::get_original_code() const { uint32 card::get_original_code() const {
if (data.alias && (data.alias < data.code + CARD_ARTWORK_VERSIONS_OFFSET) && (data.code < data.alias + CARD_ARTWORK_VERSIONS_OFFSET)) if (data.is_alternative())
return data.alias; return data.alias;
else else
return data.code; return data.code;
...@@ -476,95 +476,66 @@ uint32 card::get_another_code() { ...@@ -476,95 +476,66 @@ uint32 card::get_another_code() {
return otcode; return otcode;
return 0; return 0;
} }
int32 card::is_set_card(uint32 set_code) { inline bool check_setcode(uint16_t setcode, uint32 value) {
uint32 code = get_code(); uint16_t settype = value & 0x0fff;
uint64 setcode; uint16_t setsubtype = value & 0xf000;
if (code == data.code) { return (setcode & 0x0fff) == settype && (setcode & 0xf000 & setsubtype) == setsubtype;
setcode = data.setcode; }
} else { bool card::check_card_setcode(uint32 code, uint32 value) {
card_data dat; card_data dat;
::read_card(code, &dat); ::read_card(code, &dat);
setcode = dat.setcode; return dat.is_setcode(value);
}
int32 card::is_set_card(uint32 set_code) {
uint32 code1 = get_code();
card_data dat1;
if (code1 == data.code) {
if (data.is_setcode(set_code))
return TRUE;
} }
uint32 settype = set_code & 0xfff; else {
uint32 setsubtype = set_code & 0xf000; if (check_card_setcode(code1, set_code))
while(setcode) {
if ((setcode & 0xfff) == settype && (setcode & 0xf000 & setsubtype) == setsubtype)
return TRUE; return TRUE;
setcode = setcode >> 16;
} }
uint32 code2 = get_another_code();
if (code2 && check_card_setcode(code2, set_code))
return TRUE;
//add set code //add set code
effect_set eset; effect_set eset;
filter_effect(EFFECT_ADD_SETCODE, &eset); filter_effect(EFFECT_ADD_SETCODE, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
uint32 value = eset[i]->get_value(this); uint32 value = eset[i]->get_value(this);
if ((value & 0xfff) == settype && (value & 0xf000 & setsubtype) == setsubtype) uint16_t new_setcode = value & 0xffff;
return TRUE; if (check_setcode(new_setcode, set_code))
}
//another code
uint32 code2 = get_another_code();
uint64 setcode2;
if (code2 != 0) {
card_data dat;
::read_card(code2, &dat);
setcode2 = dat.setcode;
} else {
return FALSE;
}
while(setcode2) {
if ((setcode2 & 0xfff) == settype && (setcode2 & 0xf000 & setsubtype) == setsubtype)
return TRUE; return TRUE;
setcode2 = setcode2 >> 16;
} }
return FALSE; return FALSE;
} }
int32 card::is_origin_set_card(uint32 set_code) { int32 card::is_origin_set_card(uint32 set_code) {
uint64 setcode = data.setcode; if (data.is_setcode(set_code))
uint32 settype = set_code & 0xfff; return TRUE;
uint32 setsubtype = set_code & 0xf000; uint32 code2 = std::get<1>(get_original_code_rule());
while(setcode) { if (code2 && check_card_setcode(code2, set_code))
if((setcode & 0xfff) == settype && (setcode & 0xf000 & setsubtype) == setsubtype)
return TRUE; return TRUE;
setcode = setcode >> 16;
}
return FALSE; return FALSE;
} }
int32 card::is_pre_set_card(uint32 set_code) { int32 card::is_pre_set_card(uint32 set_code) {
uint32 code = previous.code; uint32 code = previous.code;
uint64 setcode;
if (code == data.code) { if (code == data.code) {
setcode = data.setcode; if (data.is_setcode(set_code))
} else {
card_data dat;
::read_card(code, &dat);
setcode = dat.setcode;
}
uint32 settype = set_code & 0xfff;
uint32 setsubtype = set_code & 0xf000;
while(setcode) {
if ((setcode & 0xfff) == settype && (setcode & 0xf000 & setsubtype) == setsubtype)
return TRUE; return TRUE;
setcode = setcode >> 16;
} }
//add set code else {
for(auto& presetcode : previous.setcode) { if (check_card_setcode(code, set_code))
if (presetcode && (presetcode & 0xfff) == settype && (presetcode & 0xf000 & setsubtype) == setsubtype)
return TRUE; return TRUE;
} }
//another code
uint32 code2 = previous.code2; uint32 code2 = previous.code2;
uint64 setcode2; if (code2 && check_card_setcode(code2, set_code))
if (code2 != 0) { return TRUE;
card_data dat; //add set code
::read_card(code2, &dat); for(auto& presetcode : previous.setcode) {
setcode2 = dat.setcode; if (check_setcode(presetcode, set_code))
} else {
return FALSE;
}
while(setcode2) {
if ((setcode2 & 0xfff) == settype && (setcode2 & 0xf000 & setsubtype) == setsubtype)
return TRUE; return TRUE;
setcode2 = setcode2 >> 16;
} }
return FALSE; return FALSE;
} }
...@@ -573,26 +544,19 @@ int32 card::is_fusion_set_card(uint32 set_code) { ...@@ -573,26 +544,19 @@ int32 card::is_fusion_set_card(uint32 set_code) {
return TRUE; return TRUE;
if(pduel->game_field->core.not_material) if(pduel->game_field->core.not_material)
return FALSE; return FALSE;
uint32 settype = set_code & 0xfff;
uint32 setsubtype = set_code & 0xf000;
effect_set eset; effect_set eset;
filter_effect(EFFECT_ADD_FUSION_CODE, &eset); filter_effect(EFFECT_ADD_FUSION_CODE, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
uint32 code = eset[i]->get_value(this); uint32 code = eset[i]->get_value(this);
card_data dat; if (check_card_setcode(code, set_code))
::read_card(code, &dat);
uint64 setcode = dat.setcode;
while(setcode) {
if ((setcode & 0xfff) == settype && (setcode & 0xf000 & setsubtype) == setsubtype)
return TRUE; return TRUE;
setcode = setcode >> 16;
}
} }
eset.clear(); eset.clear();
filter_effect(EFFECT_ADD_FUSION_SETCODE, &eset); filter_effect(EFFECT_ADD_FUSION_SETCODE, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
uint32 setcode = eset[i]->get_value(this); uint32 value = eset[i]->get_value(this);
if ((setcode & 0xfff) == settype && (setcode & 0xf000 & setsubtype) == setsubtype) uint16_t new_setcode = value & 0xffff;
if (check_setcode(new_setcode, set_code))
return TRUE; return TRUE;
} }
return FALSE; return FALSE;
...@@ -606,53 +570,22 @@ int32 card::is_link_set_card(uint32 set_code) { ...@@ -606,53 +570,22 @@ int32 card::is_link_set_card(uint32 set_code) {
filter_effect(EFFECT_ADD_LINK_CODE, &eset); filter_effect(EFFECT_ADD_LINK_CODE, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
uint32 code = eset[i]->get_value(this); uint32 code = eset[i]->get_value(this);
card_data dat; if (check_card_setcode(code, set_code))
::read_card(code, &dat);
uint64 setcode = dat.setcode;
while(setcode) {
if ((setcode & 0xfff) == settype && (setcode & 0xf000 & setsubtype) == setsubtype)
return TRUE; return TRUE;
setcode = setcode >> 16;
}
} }
return FALSE; return FALSE;
} }
int32 card::is_special_summon_set_card(uint32 set_code) { int32 card::is_special_summon_set_card(uint32 set_code) {
uint32 code = spsummon.code; uint32 code = spsummon.code;
uint64 setcode; if (check_card_setcode(code, set_code))
if (code == data.code) { return TRUE;
setcode = data.setcode; uint32 code2 = spsummon.code2;
} else { if (code2 && check_card_setcode(code2, set_code))
card_data dat;
::read_card(code, &dat);
setcode = dat.setcode;
}
uint32 settype = set_code & 0xfff;
uint32 setsubtype = set_code & 0xf000;
while(setcode) {
if ((setcode & 0xfff) == settype && (setcode & 0xf000 & setsubtype) == setsubtype)
return TRUE; return TRUE;
setcode = setcode >> 16;
}
//add set code //add set code
for(auto& spsetcode : spsummon.setcode) { for(auto& spsetcode : spsummon.setcode) {
if (spsetcode && (spsetcode & 0xfff) == settype && (spsetcode & 0xf000 & setsubtype) == setsubtype) if (check_setcode(spsetcode, set_code))
return TRUE;
}
//another code
uint32 code2 = spsummon.code2;
uint64 setcode2;
if (code2 != 0) {
card_data dat;
::read_card(code2, &dat);
setcode2 = dat.setcode;
} else {
return FALSE;
}
while(setcode2) {
if ((setcode2 & 0xfff) == settype && (setcode2 & 0xf000 & setsubtype) == setsubtype)
return TRUE; return TRUE;
setcode2 = setcode2 >> 16;
} }
return FALSE; return FALSE;
} }
...@@ -2611,7 +2544,7 @@ void card::set_special_summon_status(effect* peffect) { ...@@ -2611,7 +2544,7 @@ void card::set_special_summon_status(effect* peffect) {
effect_set eset; effect_set eset;
pcard->filter_effect(EFFECT_ADD_SETCODE, &eset); pcard->filter_effect(EFFECT_ADD_SETCODE, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
spsummon.setcode.push_back((uint32)eset[i]->get_value(pcard)); spsummon.setcode.push_back((uint32)eset[i]->get_value(pcard) & 0xffff);
} }
spsummon.reason_effect = peffect; spsummon.reason_effect = peffect;
spsummon.reason_player = peffect->get_handler_player(); spsummon.reason_player = peffect->get_handler_player();
...@@ -2630,7 +2563,7 @@ void card::set_special_summon_status(effect* peffect) { ...@@ -2630,7 +2563,7 @@ void card::set_special_summon_status(effect* peffect) {
effect_set eset; effect_set eset;
pcard->filter_effect(EFFECT_ADD_SETCODE, &eset); pcard->filter_effect(EFFECT_ADD_SETCODE, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
spsummon.setcode.push_back((uint32)eset[i]->get_value(pcard)); spsummon.setcode.push_back((uint32)eset[i]->get_value(pcard) & 0xffff);
} }
spsummon.reason_effect = cait->triggering_effect; spsummon.reason_effect = cait->triggering_effect;
spsummon.reason_player = cait->triggering_player; spsummon.reason_player = cait->triggering_player;
......
...@@ -26,7 +26,7 @@ struct chain; ...@@ -26,7 +26,7 @@ struct chain;
struct card_state { struct card_state {
uint32 code{ 0 }; uint32 code{ 0 };
uint32 code2{ 0 }; uint32 code2{ 0 };
std::vector<uint32> setcode; std::vector<uint16_t> setcode;
uint32 type{ 0 }; uint32 type{ 0 };
uint32 level{ 0 }; uint32 level{ 0 };
uint32 rank{ 0 }; uint32 rank{ 0 };
...@@ -218,6 +218,7 @@ public: ...@@ -218,6 +218,7 @@ public:
std::tuple<uint32, uint32> get_original_code_rule() const; std::tuple<uint32, uint32> get_original_code_rule() const;
uint32 get_code(); uint32 get_code();
uint32 get_another_code(); uint32 get_another_code();
static bool check_card_setcode(uint32 code, uint32 value);
int32 is_set_card(uint32 set_code); int32 is_set_card(uint32 set_code);
int32 is_origin_set_card(uint32 set_code); int32 is_origin_set_card(uint32 set_code);
int32 is_pre_set_card(uint32 set_code); int32 is_pre_set_card(uint32 set_code);
...@@ -434,6 +435,4 @@ constexpr uint32 DEFAULT_SUMMON_TYPE = SUMMON_VALUE_MAIN_TYPE | SUMMON_VALUE_SUB ...@@ -434,6 +435,4 @@ constexpr uint32 DEFAULT_SUMMON_TYPE = SUMMON_VALUE_MAIN_TYPE | SUMMON_VALUE_SUB
#define SUMMON_INFO_REASON_EFFECT 0x200 #define SUMMON_INFO_REASON_EFFECT 0x200
#define SUMMON_INFO_REASON_PLAYER 0x400 #define SUMMON_INFO_REASON_PLAYER 0x400
#define CARD_ARTWORK_VERSIONS_OFFSET 10
#endif /* CARD_H_ */ #endif /* CARD_H_ */
#ifndef CARD_DATA_H_ #ifndef CARD_DATA_H_
#define CARD_DATA_H_ #define CARD_DATA_H_
#include "common.h"
constexpr int CARD_ARTWORK_VERSIONS_OFFSET = 10;
constexpr int SIZE_SETCODE = 16;
struct card_data { struct card_data {
uint32 code{ 0 }; uint32 code{};
uint32 alias{ 0 }; uint32 alias{};
uint64 setcode{ 0 }; uint16_t setcode[SIZE_SETCODE]{};
uint32 type{ 0 }; uint32 type{};
uint32 level{ 0 }; uint32 level{};
uint32 attribute{ 0 }; uint32 attribute{};
uint32 race{ 0 }; uint32 race{};
int32 attack{ 0 }; int32 attack{};
int32 defense{ 0 }; int32 defense{};
uint32 lscale{ 0 }; uint32 lscale{};
uint32 rscale{ 0 }; uint32 rscale{};
uint32 link_marker{ 0 }; uint32 link_marker{};
void clear() { void clear() {
code = 0; code = 0;
alias = 0; alias = 0;
setcode = 0; for (auto& x : setcode)
x = 0;
type = 0; type = 0;
level = 0; level = 0;
attribute = 0; attribute = 0;
...@@ -29,6 +35,35 @@ struct card_data { ...@@ -29,6 +35,35 @@ struct card_data {
rscale = 0; rscale = 0;
link_marker = 0; link_marker = 0;
} }
bool is_setcode(uint32 value) const {
uint16_t settype = value & 0x0fff;
uint16_t setsubtype = value & 0xf000;
for (auto& x : setcode) {
if ((x & 0x0fff) == settype && (x & 0xf000 & setsubtype) == setsubtype)
return true;
if (!x)
return false;
}
return false;
}
bool is_alternative() const {
return alias && (alias < code + CARD_ARTWORK_VERSIONS_OFFSET) && (code < alias + CARD_ARTWORK_VERSIONS_OFFSET);
}
void set_setcode(uint64 value) {
int ctr = 0;
while (value) {
if (value & 0xffff) {
setcode[ctr] = value & 0xffff;
++ctr;
}
value >>= 16;
}
for (int i = ctr; i < SIZE_SETCODE; ++i)
setcode[i] = 0;
}
}; };
#endif /* CARD_DATA_H_ */ #endif /* CARD_DATA_H_ */
...@@ -56,7 +56,7 @@ int32 interpreter::register_card(card *pcard) { ...@@ -56,7 +56,7 @@ int32 interpreter::register_card(card *pcard) {
//some userdata may be created in script like token so use current_state //some userdata may be created in script like token so use current_state
lua_rawgeti(current_state, LUA_REGISTRYINDEX, pcard->ref_handle); lua_rawgeti(current_state, LUA_REGISTRYINDEX, pcard->ref_handle);
//load script //load script
if(pcard->data.alias && (pcard->data.alias < pcard->data.code + CARD_ARTWORK_VERSIONS_OFFSET) && (pcard->data.code < pcard->data.alias + CARD_ARTWORK_VERSIONS_OFFSET)) if(pcard->data.is_alternative())
load_card_script(pcard->data.alias); load_card_script(pcard->data.alias);
else else
load_card_script(pcard->data.code); load_card_script(pcard->data.code);
......
...@@ -4308,8 +4308,10 @@ int32 scriptlib::duel_is_player_can_spsummon_monster(lua_State * L) { ...@@ -4308,8 +4308,10 @@ int32 scriptlib::duel_is_player_can_spsummon_monster(lua_State * L) {
::read_card(code, &dat); ::read_card(code, &dat);
dat.code = code; dat.code = code;
dat.alias = 0; dat.alias = 0;
if(!lua_isnil(L, 3)) if(!lua_isnil(L, 3)) {
dat.setcode = lua_tointeger(L, 3); uint64 setcode_list = lua_tointeger(L, 3);
dat.set_setcode(setcode_list);
}
if(!lua_isnil(L, 4)) if(!lua_isnil(L, 4))
dat.type = (uint32)lua_tointeger(L, 4); dat.type = (uint32)lua_tointeger(L, 4);
if(!lua_isnil(L, 5)) if(!lua_isnil(L, 5))
......
...@@ -22,7 +22,6 @@ ...@@ -22,7 +22,6 @@
class card; class card;
struct card_data; struct card_data;
struct card_info;
class group; class group;
class effect; class effect;
class interpreter; class interpreter;
......
...@@ -3956,7 +3956,7 @@ int32 field::send_to(uint16 step, group * targets, effect * reason_effect, uint3 ...@@ -3956,7 +3956,7 @@ int32 field::send_to(uint16 step, group * targets, effect * reason_effect, uint3
effect_set eset; effect_set eset;
pcard->filter_effect(EFFECT_ADD_SETCODE, &eset); pcard->filter_effect(EFFECT_ADD_SETCODE, &eset);
for(int32 i = 0; i < eset.size(); ++i) { for(int32 i = 0; i < eset.size(); ++i) {
pcard->previous.setcode.push_back((uint32)eset[i]->get_value(pcard)); pcard->previous.setcode.push_back((uint32)eset[i]->get_value(pcard) & 0xffff);
} }
} }
} }
......
...@@ -920,15 +920,7 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod ...@@ -920,15 +920,7 @@ static int32 is_declarable(card_data const& cd, const std::vector<uint32>& opcod
if(stack.size() >= 1) { if(stack.size() >= 1) {
int32 set_code = stack.top(); int32 set_code = stack.top();
stack.pop(); stack.pop();
uint64 sc = cd.setcode; bool res = cd.is_setcode(set_code);
bool res = false;
uint32 settype = set_code & 0xfff;
uint32 setsubtype = set_code & 0xf000;
while(sc) {
if((sc & 0xfff) == settype && (sc & 0xf000 & setsubtype) == setsubtype)
res = true;
sc = sc >> 16;
}
stack.push(res); stack.push(res);
} }
break; break;
......
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