Commit 605dec57 authored by Fluorohydride's avatar Fluorohydride

xmaterial count limit

parent fa3a227c
...@@ -13,7 +13,7 @@ ...@@ -13,7 +13,7 @@
#include "interpreter.h" #include "interpreter.h"
#include <iostream> #include <iostream>
#include <cstring> #include <cstring>
#include <multimap> #include <map>
int32 field::field_used_count[32] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5}; int32 field::field_used_count[32] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5};
...@@ -1272,19 +1272,38 @@ void field::ritual_release(card_set* material) { ...@@ -1272,19 +1272,38 @@ void field::ritual_release(card_set* material) {
release(&rel, core.reason_effect, REASON_RITUAL + REASON_EFFECT + REASON_MATERIAL, core.reason_player); 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(&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(card* scard, card_set* material) { void field::get_xyz_material(card* scard, int32 findex) {
card* pcard = 0; card* pcard = 0;
int32 playerid = scard->current.controler; int32 playerid = scard->current.controler;
core.xmaterial_lst.clear();
card_vector cv;
for(int i = 0; i < 5; ++i) { for(int i = 0; i < 5; ++i) {
pcard = player[playerid].list_mzone[i]; pcard = player[playerid].list_mzone[i];
if(pcard && pcard->is_position(POS_FACEUP) && pcard->is_can_be_xyz_material(scard)) if(pcard && pcard->is_position(POS_FACEUP) && pcard->is_can_be_xyz_material(scard)
material->insert(pcard); && pduel->lua->check_matching(pcard, findex, 0))
cv.push_back(pcard);
} }
for(int i = 0; i < 5; ++i) { for(int i = 0; i < 5; ++i) {
pcard = player[1 - playerid].list_mzone[i]; pcard = player[1 - playerid].list_mzone[i];
if(pcard && pcard->is_position(POS_FACEUP) && pcard->is_can_be_xyz_material(scard) if(pcard && pcard->is_position(POS_FACEUP) && pcard->is_can_be_xyz_material(scard)
&& pcard->is_affected_by_effect(EFFECT_XYZ_MATERIAL)) && pcard->is_affected_by_effect(EFFECT_XYZ_MATERIAL) && pduel->lua->check_matching(pcard, findex, 0))
material->insert(pcard); cv.push_back(pcard);
}
if(core.global_flag & GLOBALFLAG_XMAT_COUNT_LIMIT) {
for(auto pcard : cv) {
effect* peffect = pcard->is_affected_by_effect(EFFECT_XMAT_COUNT_LIMIT);
if(peffect) {
int32 v = peffect->get_value();
core.xmaterial_lst.insert(std::make_pair(v, pcard));
} else
core.xmaterial_lst.insert(std::make_pair(0, pcard));
}
auto iter = core.xmaterial_lst.rbegin();
while((iter != core.xmaterial_lst.rend()) && (iter->first > core.xmaterial_lst.size()))
core.xmaterial_lst.erase((iter++).base());
} else {
for(auto pcard : cv)
core.xmaterial_lst.insert(std::make_pair(0, pcard));
} }
} }
void field::get_overlay_group(uint8 self, uint8 s, uint8 o, card_set* pset) { void field::get_overlay_group(uint8 self, uint8 s, uint8 o, card_set* pset) {
...@@ -1631,41 +1650,30 @@ int32 field::check_with_sum_limit(card_vector* mats, int32 acc, int32 index, int ...@@ -1631,41 +1650,30 @@ int32 field::check_with_sum_limit(card_vector* mats, int32 acc, int32 index, int
|| check_with_sum_limit(mats, acc, index + 1, count, min, max); || check_with_sum_limit(mats, acc, index + 1, count, min, max);
} }
int32 field::check_xyz_material(card* scard, int32 findex, int32 min, int32 max, group* mg) { int32 field::check_xyz_material(card* scard, int32 findex, int32 min, int32 max, group* mg) {
card_set mat, cset;
pduel->game_field->get_xyz_material(scard, &mat);
if(mg) { if(mg) {
card_vector cv;
core.xmaterial_lst.clear();
for (auto pcard : mg->container) { for (auto pcard : mg->container) {
if(pduel->lua->check_matching(pcard, findex, 0)) if(pduel->lua->check_matching(pcard, findex, 0))
cset.insert(pcard); cv.push_back(pcard);
}
} else {
for (auto pcard : mat) {
if(pduel->lua->check_matching(pcard, findex, 0))
cset.insert(pcard);
} }
} if(core.global_flag & GLOBALFLAG_XMAT_COUNT_LIMIT) {
if(core.global_flag & GLOBALFLAG_XMAT_COUNT_LIMIT) { for(auto pcard : cv) {
for(auto pcard : cset) { effect* peffect = pcard->is_affected_by_effect(EFFECT_XMAT_COUNT_LIMIT);
std::multimap<int32, card*> m; if(peffect) {
effect* peffect = pcard->is_affected_by_effect(EFFECT_XMAT_COUNT_LIMIT); int32 v = peffect->get_value();
if(peffect) { core.xmaterial_lst.insert(std::make_pair(v, pcard));
int32 v = peffect->get_value(); } else
m.insert(std::make_pair(v, pcard)); core.xmaterial_lst.insert(std::make_pair(0, pcard));
}
auto iter = m.rbegin();
while(iter != m.rend()) {
auto cur = iter++;
if(cur->first > cset.size()) {
cset.erase(cur->second);
m.erase(cur);
}
} }
auto iter = core.xmaterial_lst.rbegin();
while((iter != core.xmaterial_lst.rend()) && (iter->first > core.xmaterial_lst.size()))
core.xmaterial_lst.erase((iter++).base());
} }
return cset.size() >= min;
} else { } else {
return cset.size() >= min; pduel->game_field->get_xyz_material(scard, findex);
} }
return TRUE; return core.xmaterial_lst.size() >= min;
} }
int32 field::is_player_can_draw(uint8 playerid) { int32 field::is_player_can_draw(uint8 playerid) {
return !is_player_affected_by_effect(playerid, EFFECT_CANNOT_DRAW); return !is_player_affected_by_effect(playerid, EFFECT_CANNOT_DRAW);
......
...@@ -212,6 +212,7 @@ struct processor { ...@@ -212,6 +212,7 @@ struct processor {
std::unordered_map<card*, uint32> readjust_map; std::unordered_map<card*, uint32> readjust_map;
std::unordered_set<card*> unique_cards[2]; std::unordered_set<card*> unique_cards[2];
std::unordered_map<uint32, uint32> effect_count_code; std::unordered_map<uint32, uint32> effect_count_code;
std::multimap<int32, card*> xmaterial_lst;
ptr temp_var[4]; ptr temp_var[4];
uint32 global_flag; uint32 global_flag;
uint16 pre_field[2]; uint16 pre_field[2];
...@@ -339,7 +340,7 @@ public: ...@@ -339,7 +340,7 @@ public:
int32 get_draw_count(uint8 playerid); int32 get_draw_count(uint8 playerid);
void get_ritual_material(uint8 playerid, effect* peffect, card_set* material); void get_ritual_material(uint8 playerid, effect* peffect, card_set* material);
void ritual_release(card_set* material); void ritual_release(card_set* material);
void get_xyz_material(card* scard, card_set* material); void get_xyz_material(card* scard, int32 findex);
void get_overlay_group(uint8 self, uint8 s, uint8 o, card_set* pset); void get_overlay_group(uint8 self, uint8 s, uint8 o, card_set* pset);
int32 get_overlay_count(uint8 self, uint8 s, uint8 o); int32 get_overlay_count(uint8 self, uint8 s, uint8 o);
void update_disable_check_list(effect* peffect); void update_disable_check_list(effect* peffect);
...@@ -475,7 +476,7 @@ public: ...@@ -475,7 +476,7 @@ public:
int32 change_position(uint16 step, group* targets, effect* reason_effect, uint8 reason_player, uint32 enable); int32 change_position(uint16 step, group* targets, effect* reason_effect, uint8 reason_player, uint32 enable);
int32 operation_replace(uint16 step, effect* replace_effect, group* targets, ptr arg, ptr replace_type); int32 operation_replace(uint16 step, effect* replace_effect, group* targets, ptr arg, ptr replace_type);
int32 select_synchro_material(int16 step, uint8 playerid, card* pcard, int32 min, int32 max, group* mg); int32 select_synchro_material(int16 step, uint8 playerid, card* pcard, int32 min, int32 max, group* mg);
int32 select_xyz_material(int16 step, uint8 playerid, card* pcard, int32 min, int32 max, group* mg); int32 select_xyz_material(int16 step, uint8 playerid, card* pcard, int32 min, int32 max);
int32 select_release_cards(int16 step, uint8 playerid, uint8 check_field, uint8 cancelable, int32 min, int32 max); int32 select_release_cards(int16 step, uint8 playerid, uint8 check_field, uint8 cancelable, int32 min, int32 max);
int32 select_tribute_cards(int16 step, uint8 playerid, uint8 cancelable, int32 min, int32 max); int32 select_tribute_cards(int16 step, uint8 playerid, uint8 cancelable, int32 min, int32 max);
int32 toss_coin(uint16 step, effect* reason_effect, uint8 reason_player, uint8 playerid, uint8 count); int32 toss_coin(uint16 step, effect* reason_effect, uint8 reason_player, uint8 playerid, uint8 count);
......
...@@ -2417,6 +2417,9 @@ int32 scriptlib::duel_select_xyz_material(lua_State *L) { ...@@ -2417,6 +2417,9 @@ int32 scriptlib::duel_select_xyz_material(lua_State *L) {
uint32 playerid = lua_tointeger(L, 1); uint32 playerid = lua_tointeger(L, 1);
uint32 minc = lua_tointeger(L, 4); uint32 minc = lua_tointeger(L, 4);
uint32 maxc = lua_tointeger(L, 5); uint32 maxc = lua_tointeger(L, 5);
field::card_set mat, cset;
duel* pduel = scard->pduel;
pduel->game_field->get_xyz_material(scard, 3);
scard->pduel->game_field->add_process(PROCESSOR_SELECT_XMATERIAL, 0, 0, (group*)scard, playerid, minc + (maxc << 16)); scard->pduel->game_field->add_process(PROCESSOR_SELECT_XMATERIAL, 0, 0, (group*)scard, playerid, minc + (maxc << 16));
return lua_yield(L, 0); return lua_yield(L, 0);
} }
......
...@@ -3884,7 +3884,110 @@ int32 field::select_synchro_material(int16 step, uint8 playerid, card * pcard, i ...@@ -3884,7 +3884,110 @@ int32 field::select_synchro_material(int16 step, uint8 playerid, card * pcard, i
} }
return TRUE; return TRUE;
} }
int32 field::select_xyz_material(int16 step, uint8 playerid, card * pcard, int32 min, int32 max, group* mg) { int32 field::select_xyz_material(int16 step, uint8 playerid, card* scard, int32 min, int32 max) {
switch(step) {
case 0: {
int maxv = 0;
if(core.xmaterial_lst.size())
maxv = core.xmaterial_lst.rbegin()->first;
if(min >= maxv) {
core.select_cards.clear();
for(auto iter : core.xmaterial_lst)
core.select_cards.push_back(iter.second);
pduel->write_buffer8(MSG_HINT);
pduel->write_buffer8(HINT_SELECTMSG);
pduel->write_buffer8(playerid);
pduel->write_buffer32(513);
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, playerid, min + (max << 16));
} else
core.units.begin()->step = 1;
return FALSE;
}
case 1: {
group* pgroup = pduel->new_group();
for(int32 i = 0; i < returns.bvalue[0]; ++i) {
card* pcard = core.select_cards[returns.bvalue[i + 1]];
pgroup->container.insert(pcard);
}
pduel->lua->add_param(pgroup, PARAM_TYPE_GROUP);
return TRUE;
}
case 2: {
core.operated_set.clear();
core.select_cards.clear();
for(auto iter : core.xmaterial_lst)
core.select_cards.push_back(iter.second);
pduel->write_buffer8(MSG_HINT);
pduel->write_buffer8(HINT_SELECTMSG);
pduel->write_buffer8(playerid);
pduel->write_buffer32(513);
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, playerid, 0x10001);
return FALSE;
}
case 3: {
card* pcard = core.select_cards[returns.bvalue[1]];
core.operated_set.insert(pcard);
int pv = 0;
for(auto iter = core.xmaterial_lst.begin(); iter != core.xmaterial_lst.end(); ++iter) {
if(iter->second == pcard) {
pv = iter->first;
core.xmaterial_lst.erase(iter);
break;
}
}
min--;
max--;
if(max == 0 || core.xmaterial_lst.size() == 0) {
group* pgroup = pduel->new_group();
pgroup->container = core.operated_set;
pduel->lua->add_param(pgroup, PARAM_TYPE_GROUP);
return TRUE;
}
if(min + core.operated_set.size() < pv)
min = pv - core.operated_set.size();
core.units.begin()->arg2 = min + (max << 16);
if(min == 0) {
add_process(PROCESSOR_SELECT_YESNO, 0, 0, 0, playerid, 93);
return FALSE;
}
returns.ivalue[0] = 1;
return FALSE;
}
case 4: {
if(!returns.ivalue[0]) {
group* pgroup = pduel->new_group();
pgroup->container = core.operated_set;
pduel->lua->add_param(pgroup, PARAM_TYPE_GROUP);
return TRUE;
}
core.select_cards.clear();
for(auto iter : core.xmaterial_lst)
core.select_cards.push_back(iter.second);
int maxv = core.xmaterial_lst.rbegin()->first;
pduel->write_buffer8(MSG_HINT);
pduel->write_buffer8(HINT_SELECTMSG);
pduel->write_buffer8(playerid);
pduel->write_buffer32(513);
if(min + core.operated_set.size() >= maxv)
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, playerid, min + (max << 16));
else {
add_process(PROCESSOR_SELECT_CARD, 0, 0, 0, playerid, 0x10001);
core.units.begin()->step = 2;
}
return FALSE;
}
case 5: {
group* pgroup = pduel->new_group();
for(auto pcard : core.operated_set)
pgroup->container.insert(pcard);
for(int32 i = 0; i < returns.bvalue[0]; ++i) {
card* pcard = core.select_cards[returns.bvalue[i + 1]];
pgroup->container.insert(pcard);
}
pduel->lua->add_param(pgroup, PARAM_TYPE_GROUP);
return TRUE;
}
}
return TRUE; return TRUE;
} }
int32 field::select_release_cards(int16 step, uint8 playerid, uint8 check_field, uint8 cancelable, int32 min, int32 max) { int32 field::select_release_cards(int16 step, uint8 playerid, uint8 check_field, uint8 cancelable, int32 min, int32 max) {
......
...@@ -871,7 +871,7 @@ int32 field::process() { ...@@ -871,7 +871,7 @@ int32 field::process() {
return pduel->bufferlen; return pduel->bufferlen;
} }
case PROCESSOR_SELECT_XMATERIAL: { case PROCESSOR_SELECT_XMATERIAL: {
if (select_xyz_material(it->step, it->arg1, (card*)it->ptarget, it->arg2 & 0xffff, it->arg2 >> 16, (group*)it->peffect)) if (select_xyz_material(it->step, it->arg1, (card*)it->ptarget, it->arg2 & 0xffff, it->arg2 >> 16))
core.units.pop_front(); core.units.pop_front();
else else
core.units.begin()->step++; core.units.begin()->step++;
......
...@@ -642,7 +642,7 @@ GLOBALFLAG_SCRAP_CHIMERA =0x4 ...@@ -642,7 +642,7 @@ GLOBALFLAG_SCRAP_CHIMERA =0x4
GLOBALFLAG_DELAYED_QUICKEFFECT =0x8 GLOBALFLAG_DELAYED_QUICKEFFECT =0x8
GLOBALFLAG_DETACH_EVENT =0x10 GLOBALFLAG_DETACH_EVENT =0x10
GLOBALFLAG_MUST_BE_SMATERIAL =0x20 GLOBALFLAG_MUST_BE_SMATERIAL =0x20
GLOBALFLAG_SPSUMMON_COUNT -0x40 GLOBALFLAG_SPSUMMON_COUNT =0x40
GLOBALFLAG_XMAT_COUNT_LIMIT =0x80 GLOBALFLAG_XMAT_COUNT_LIMIT =0x80
-- --
EFFECT_COUNT_CODE_OATH =0x80000000 EFFECT_COUNT_CODE_OATH =0x80000000
......
...@@ -38,6 +38,8 @@ ...@@ -38,6 +38,8 @@
!system 81 进入结束阶段 !system 81 进入结束阶段
!system 90 是否不解放怪物通常召唤? !system 90 是否不解放怪物通常召唤?
!system 91 是否使用额外的召唤机会? !system 91 是否使用额外的召唤机会?
!system 92 是否要解放对方怪兽进行上级招呼?
!system 93 是否要继续选择素材?
!system 100 先攻 !system 100 先攻
!system 101 后攻 !system 101 后攻
!system 200 是否在[%ls]发动[%ls]的效果? !system 200 是否在[%ls]发动[%ls]的效果?
......
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