Commit ffdb247f authored by salix5's avatar salix5

spsummon

parent fad22485
......@@ -61,6 +61,7 @@ card::card() {
memset(&temp, 0xff, sizeof(card_state));
unique_pos[0] = unique_pos[1] = 0;
spsummon_counter[0] = spsummon_counter[1] = 0;
spsummon_counter_rst[0] = spsummon_counter_rst[1] = 0;
unique_code = 0;
assume_type = 0;
assume_value = 0;
......@@ -861,6 +862,7 @@ void card::apply_field_effect() {
if(unique_code && (current.location & LOCATION_ONFIELD))
pduel->game_field->add_unique_card(this);
spsummon_counter[0] = spsummon_counter[1] = 0;
spsummon_counter_rst[0] = spsummon_counter_rst[1] = 0;
}
void card::cancel_field_effect() {
if (current.controler == PLAYER_NONE)
......
......@@ -110,6 +110,7 @@ public:
uint32 unique_code;
uint32 spsummon_code;
uint16 spsummon_counter[2];
uint16 spsummon_counter_rst[2];
uint8 assume_type;
uint32 assume_value;
effect* unique_effect;
......
......@@ -1464,23 +1464,37 @@ void field::check_chain_counter(effect* peffect, int32 playerid, int32 chainid,
}
}
}
void field::set_spsummon_counter(uint8 playerid, bool add) {
if(add)
void field::set_spsummon_counter(uint8 playerid, bool add, bool chain) {
if(add){
core.spsummon_state_count[playerid]++;
else
core.spsummon_state_count[playerid]--;
if(chain)
core.spsummon_state_count_rst[playerid]++;
}
else{
if(chain){
core.spsummon_state_count[playerid]-=core.spsummon_state_count_rst[playerid];
core.spsummon_state_count_rst[playerid] = 0;
}
else
core.spsummon_state_count[playerid]--;
}
if(core.global_flag & GLOBALFLAG_SPSUMMON_COUNT) {
for(auto iter = effects.spsummon_count_eff.begin(); iter != effects.spsummon_count_eff.end(); ++iter) {
effect* peffect = *iter;
card* pcard = peffect->handler;
if(pcard->is_status(STATUS_EFFECT_ENABLED) && !pcard->is_status(STATUS_DISABLED) && pcard->is_position(POS_FACEUP)) {
if(((playerid == pcard->current.controler) && peffect->s_range) || ((playerid != pcard->current.controler) && peffect->o_range)) {
if(add)
if(add){
if(pcard->is_status(STATUS_EFFECT_ENABLED) && !pcard->is_status(STATUS_DISABLED) && pcard->is_position(POS_FACEUP)) {
if(((playerid == pcard->current.controler) && peffect->s_range) || ((playerid != pcard->current.controler) && peffect->o_range)) {
pcard->spsummon_counter[playerid]++;
else if(pcard->spsummon_counter[playerid] > 0)
pcard->spsummon_counter[playerid]--;
if(chain)
pcard->spsummon_counter_rst[playerid]++;
}
}
}
else{
pcard->spsummon_counter[playerid]-=pcard->spsummon_counter_rst[playerid];
pcard->spsummon_counter_rst[playerid] = 0;
}
}
}
}
......@@ -1885,14 +1899,6 @@ int32 field::is_player_can_spsummon(uint8 playerid) {
return FALSE;
}
eset.clear();
filter_player_effect(playerid, EFFECT_SPSUMMON_COUNT_LIMIT, &eset);
for(int32 i = 0; i < eset.count; ++i) {
pduel->lua->add_param(core.reason_effect, PARAM_TYPE_EFFECT);
pduel->lua->add_param(playerid, PARAM_TYPE_INT);
int32 v = eset[i]->get_value(2);
if(v <= 0)
return FALSE;
}
return TRUE;
}
int32 field::is_player_can_spsummon(effect * peffect, uint32 sumtype, uint8 sumpos, uint8 playerid, uint8 toplayer, card * pcard) {
......@@ -1915,14 +1921,10 @@ int32 field::is_player_can_spsummon(effect * peffect, uint32 sumtype, uint8 sump
return FALSE;
}
eset.clear();
filter_player_effect(playerid, EFFECT_SPSUMMON_COUNT_LIMIT, &eset);
for(int32 i = 0; i < eset.count; ++i) {
pduel->lua->add_param(core.reason_effect, PARAM_TYPE_EFFECT);
pduel->lua->add_param(playerid, PARAM_TYPE_INT);
int32 v = eset[i]->get_value(2);
if(v <= 0)
return FALSE;
}
if(!check_spsummon_once(pcard, playerid))
return FALSE;
if(!check_spsummon_counter(playerid))
return FALSE;
return TRUE;
}
int32 field::is_player_can_flipsummon(uint8 playerid, card * pcard) {
......
......@@ -214,6 +214,7 @@ struct processor {
std::unordered_map<uint32, uint32> effect_count_code;
std::unordered_map<uint32, uint32> effect_count_code_duel;
std::unordered_map<uint32, uint32> spsummon_once_map[2];
std::unordered_map<uint32, uint32> spsummon_once_map_rst[2];
std::multimap<int32, card*, std::greater<int32> > xmaterial_lst;
ptr temp_var[4];
uint32 global_flag;
......@@ -269,6 +270,9 @@ struct processor {
uint8 normalsummon_state_count[2];
uint8 flipsummon_state_count[2];
uint8 spsummon_state_count[2];
uint8 spsummon_state_count_rst[2];
uint8 spsummon_state_count_tmp[2];
bool spsummon_rst;
uint8 attack_state_count[2];
uint8 battle_phase_count[2];
uint8 phase_action;
......@@ -362,7 +366,7 @@ public:
int32 check_spsummon_once(card* pcard, uint8 playerid);
void check_card_counter(card* pcard, int32 counter_type, int32 playerid);
void check_chain_counter(effect* peffect, int32 playerid, int32 chainid, bool cancel = false);
void set_spsummon_counter(uint8 playerid, bool add = true);
void set_spsummon_counter(uint8 playerid, bool add = true, bool chain = false);
int32 check_spsummon_counter(uint8 playerid, uint8 ct = 1);
int32 check_lp_cost(uint8 playerid, uint32 cost);
......
......@@ -2384,7 +2384,7 @@ int32 field::special_summon(uint16 step, effect * reason_effect, uint8 reason_pl
if(!cvs.empty()) {
if(cvs.size() > 1)
std::sort(cvs.begin(), cvs.end(), card::card_operation_sort);
set_spsummon_counter(infos.turn_player);
//set_spsummon_counter(infos.turn_player);
core.hint_timing[infos.turn_player] |= TIMING_SPSUMMON;
for(auto cvit = cvs.begin(); cvit != cvs.end(); ++cvit)
add_process(PROCESSOR_SPSUMMON_STEP, 0, 0, targets, 0, (ptr)(*cvit));
......@@ -2392,7 +2392,7 @@ int32 field::special_summon(uint16 step, effect * reason_effect, uint8 reason_pl
if(!cvo.empty()) {
if(cvo.size() > 1)
std::sort(cvo.begin(), cvo.end(), card::card_operation_sort);
set_spsummon_counter(1 - infos.turn_player);
//set_spsummon_counter(1 - infos.turn_player);
core.hint_timing[1 - infos.turn_player] |= TIMING_SPSUMMON;
for(auto cvit = cvo.begin(); cvit != cvo.end(); ++cvit)
add_process(PROCESSOR_SPSUMMON_STEP, 0, 0, targets, 0, (ptr)(*cvit));
......@@ -2400,12 +2400,23 @@ int32 field::special_summon(uint16 step, effect * reason_effect, uint8 reason_pl
return FALSE;
}
case 1: {
bool tp=false, ntp=false;
if(targets->container.size() == 0) {
returns.ivalue[0] = 0;
core.operated_set.clear();
pduel->delete_group(targets);
return TRUE;
}
for(auto cit = targets->container.begin(); cit != targets->container.end(); ++cit) {
if((*cit)->summon_player == infos.turn_player)
tp=true;
else
ntp=true;
}
if(tp)
set_spsummon_counter(infos.turn_player);
if(ntp)
set_spsummon_counter(1-infos.turn_player);
for(auto cit = targets->container.begin(); cit != targets->container.end(); ++cit) {
(*cit)->set_status(STATUS_SUMMON_TURN, TRUE);
if((*cit)->is_position(POS_FACEUP))
......@@ -3626,6 +3637,7 @@ int32 field::change_position(uint16 step, group * targets, effect * reason_effec
pcard->enable_field_effect(FALSE);
pcard->summon_info &= 0xdf00ffff;
pcard->spsummon_counter[0] = pcard->spsummon_counter[1] = 0;
pcard->spsummon_counter_rst[0] = pcard->spsummon_counter_rst[1] = 0;
}
if((npos & POS_FACEDOWN) && pcard->equiping_cards.size()) {
for(auto csit = pcard->equiping_cards.begin(); csit != pcard->equiping_cards.end();) {
......
......@@ -4030,11 +4030,14 @@ int32 field::process_turn(uint16 step, uint8 turn_player) {
core.normalsummon_state_count[p] = 0;
core.flipsummon_state_count[p] = 0;
core.spsummon_state_count[p] = 0;
core.spsummon_state_count_rst[p] = 0;
core.spsummon_rst=false;
core.attack_state_count[p] = 0;
core.battle_phase_count[p] = 0;
core.summon_count[p] = 0;
core.extra_summon[p] = 0;
core.spsummon_once_map[p].clear();
core.spsummon_once_map_rst[p].clear();
}
for(auto rit = effects.rechargeable.begin(); rit != effects.rechargeable.end(); ++rit)
if(!((*rit)->flag & EFFECT_FLAG_NO_TURN_RESET))
......@@ -4055,8 +4058,10 @@ int32 field::process_turn(uint16 step, uint8 turn_player) {
for(auto iter = effects.spsummon_count_eff.begin(); iter != effects.spsummon_count_eff.end(); ++iter) {
effect* peffect = *iter;
card* pcard = peffect->handler;
if(!(peffect->flag & EFFECT_FLAG_NO_TURN_RESET))
if(!(peffect->flag & EFFECT_FLAG_NO_TURN_RESET)){
pcard->spsummon_counter[0] = pcard->spsummon_counter[1] = 0;
pcard->spsummon_counter_rst[0] = pcard->spsummon_counter_rst[1] = 0;
}
}
}
infos.turn_id++;
......@@ -4442,14 +4447,32 @@ int32 field::add_chain(uint16 step) {
}
core.phase_action = TRUE;
if(clit.opinfos.count(0x200)) {
set_spsummon_counter(clit.triggering_player);
core.spsummon_rst=true;
set_spsummon_counter(clit.triggering_player, true, true);
if(clit.opinfos[0x200].op_player == PLAYER_ALL)
set_spsummon_counter(1-clit.triggering_player, true, true);
if((core.global_flag & GLOBALFLAG_SPSUMMON_ONCE) && (peffect->flag & EFFECT_FLAG_CARD_TARGET)) {
auto& optarget = clit.opinfos[0x200];
if(optarget.op_cards) {
for(auto& spcard : optarget.op_cards->container) {
if(spcard->spsummon_code) {
uint8 sumpl = optarget.op_player ? 1 : 0;
core.spsummon_once_map[sumpl][spcard->spsummon_code]++;
if(optarget.op_cards){
if(optarget.op_player == PLAYER_ALL){
auto spcard=optarget.op_cards->container.begin();
uint32 plr=optarget.op_param;
if((*spcard)->spsummon_code){
core.spsummon_once_map[plr][(*spcard)->spsummon_code]++;
core.spsummon_once_map_rst[plr][(*spcard)->spsummon_code]++;
}
++spcard;
if((*spcard)->spsummon_code){
core.spsummon_once_map[1-plr][(*spcard)->spsummon_code]++;
core.spsummon_once_map_rst[1-plr][(*spcard)->spsummon_code]++;
}
}
else{
for(auto spcard = optarget.op_cards->container.begin(); spcard != optarget.op_cards->container.end(); ++spcard) {
if((*spcard)->spsummon_code){
core.spsummon_once_map[clit.triggering_player][(*spcard)->spsummon_code]++;
core.spsummon_once_map_rst[clit.triggering_player][(*spcard)->spsummon_code]++;
}
}
}
}
......@@ -4564,6 +4587,18 @@ int32 field::solve_chain(uint16 step, uint32 skip_new) {
chain_array::reverse_iterator cait = core.current_chain.rbegin();
switch(step) {
case 0: {
if(core.spsummon_rst){
set_spsummon_counter(0, false, true);
set_spsummon_counter(1, false, true);
for(int plr=0;plr<=1;++plr){
for(auto iter = core.spsummon_once_map[plr].begin(); iter != core.spsummon_once_map[plr].end(); ++iter){
auto spcode=iter->first;
core.spsummon_once_map[plr][spcode]-= core.spsummon_once_map_rst[plr][spcode];
core.spsummon_once_map_rst[plr][spcode]=0;
}
}
core.spsummon_rst=false;
}
pduel->write_buffer8(MSG_CHAIN_SOLVING);
pduel->write_buffer8(cait->chain_count);
add_to_disable_check_list(cait->triggering_effect->handler);
......@@ -4589,20 +4624,20 @@ int32 field::solve_chain(uint16 step, uint32 skip_new) {
raise_event((card*)0, EVENT_CHAIN_NEGATED, peffect, 0, cait->triggering_player, cait->triggering_player, cait->chain_count);
process_instant_event();
core.units.begin()->step = 9;
if(cait->opinfos.count(0x200)) {
/*if(cait->opinfos.count(0x200)) {
set_spsummon_counter(cait->triggering_player, false);
if((core.global_flag & GLOBALFLAG_SPSUMMON_ONCE) && (peffect->flag & EFFECT_FLAG_CARD_TARGET)) {
auto& optarget = cait->opinfos[0x200];
if(optarget.op_cards) {
for(auto& spcard : optarget.op_cards->container) {
if(spcard->spsummon_code) {
for(auto spcard = optarget.op_cards->container.begin(); spcard!=optarget.op_cards->container.end(); ++spcard) {
if((*spcard)->spsummon_code) {
uint8 sumpl = optarget.op_player ? 1 : 0;
core.spsummon_once_map[sumpl][spcard->spsummon_code]--;
core.spsummon_once_map[sumpl][(*spcard)->spsummon_code]--;
}
}
}
}
}
}*/
return FALSE;
}
for(auto oeit = effects.oath.begin(); oeit != effects.oath.end(); ++oeit)
......@@ -4628,6 +4663,8 @@ int32 field::solve_chain(uint16 step, uint32 skip_new) {
return FALSE;
}
case 2: {
core.spsummon_state_count_tmp[0] = core.spsummon_state_count[0];
core.spsummon_state_count_tmp[1] = core.spsummon_state_count[1];
card* pcard = cait->triggering_effect->handler;
if(is_chain_disablable(cait->chain_count)) {
if((cait->flag & CHAIN_DISABLE_EFFECT) || pcard->is_affected_by_effect(EFFECT_DISABLE_CHAIN)
......@@ -4642,7 +4679,7 @@ int32 field::solve_chain(uint16 step, uint32 skip_new) {
return FALSE;
}
}
core.units.begin()->arg2 = core.spsummon_state_count[cait->triggering_player];
//core.units.begin()->arg2 = core.spsummon_state_count[cait->triggering_player];
if(cait->replace_op) {
core.units.begin()->peffect = (effect*)(size_t)cait->triggering_effect->operation;
cait->triggering_effect->operation = cait->replace_op;
......@@ -4655,7 +4692,7 @@ int32 field::solve_chain(uint16 step, uint32 skip_new) {
return FALSE;
}
case 3: {
effect* peffect = cait->triggering_effect;
/*effect* peffect = cait->triggering_effect;
if(core.units.begin()->peffect) {
peffect->operation = (ptr)core.units.begin()->peffect;
if(cait->opinfos.count(0x200)) {
......@@ -4663,10 +4700,10 @@ int32 field::solve_chain(uint16 step, uint32 skip_new) {
if((core.global_flag & GLOBALFLAG_SPSUMMON_ONCE) && (peffect->flag & EFFECT_FLAG_CARD_TARGET)) {
auto& optarget = cait->opinfos[0x200];
if(optarget.op_cards) {
for(auto& spcard : optarget.op_cards->container) {
if(spcard->spsummon_code) {
for(auto spcard = optarget.op_cards->container.begin(); spcard!= optarget.op_cards->container.end(); ++spcard) {
if((*spcard)->spsummon_code) {
uint8 sumpl = optarget.op_player ? 1 : 0;
core.spsummon_once_map[sumpl][spcard->spsummon_code]--;
core.spsummon_once_map[sumpl][(*spcard)->spsummon_code]--;
}
}
}
......@@ -4675,7 +4712,7 @@ int32 field::solve_chain(uint16 step, uint32 skip_new) {
} else {
if(cait->opinfos.count(0x200) && (core.units.begin()->arg2 != core.spsummon_state_count[cait->triggering_player]))
set_spsummon_counter(cait->triggering_player, false);
}
}*/
if(core.special_summoning.size())
core.special_summoning.clear();
if(core.equiping_cards.size())
......@@ -4683,6 +4720,42 @@ int32 field::solve_chain(uint16 step, uint32 skip_new) {
return FALSE;
}
case 4: {
if(core.units.begin()->peffect == 0){
if(cait->opinfos.count(0x200)){
if(core.spsummon_state_count_tmp[cait->triggering_player] == core.spsummon_state_count[cait->triggering_player])
set_spsummon_counter(cait->triggering_player);
if(cait->opinfos[0x200].op_player == PLAYER_ALL && core.spsummon_state_count_tmp[1-cait->triggering_player] == core.spsummon_state_count[1-cait->triggering_player])
set_spsummon_counter(1-cait->triggering_player);
//sometimes it may add twice, only works for once per turn
if(cait->triggering_effect->flag & EFFECT_FLAG_CARD_TARGET) {
auto& optarget = cait->opinfos[0x200];
if(optarget.op_cards){
if(optarget.op_player == PLAYER_ALL){
auto spcard=optarget.op_cards->container.begin();
uint32 plr=optarget.op_param;
if((core.global_flag & GLOBALFLAG_SPSUMMON_ONCE) && (*spcard)->spsummon_code){
core.spsummon_once_map[plr][(*spcard)->spsummon_code]++;
++spcard;
core.spsummon_once_map[1-plr][(*spcard)->spsummon_code]++;
}
spcard=optarget.op_cards->container.begin();
check_card_counter(*spcard, 3, plr);
++spcard;
check_card_counter(*spcard, 3, 1-plr);
}
else{
for(auto spcard = optarget.op_cards->container.begin(); spcard!=optarget.op_cards->container.end(); ++spcard) {
if((core.global_flag & GLOBALFLAG_SPSUMMON_ONCE) && (*spcard)->spsummon_code)
core.spsummon_once_map[cait->triggering_player][(*spcard)->spsummon_code]++;
check_card_counter(*spcard, 3, cait->triggering_player);
}
}
}
}
}
}
core.spsummon_state_count_tmp[0]=0;
core.spsummon_state_count_tmp[1]=0;
core.chain_solving = FALSE;
effect_vector::iterator eit;
event_list::iterator evit;
......
......@@ -28,7 +28,7 @@ function c43434803.target(e,tp,eg,ep,ev,re,r,rp,chk,chkc)
local sc=sg:GetFirst()
local oc=og:GetFirst()
local g=Group.FromCards(sc,oc)
Duel.SetOperationInfo(0,CATEGORY_SPECIAL_SUMMON,g,2,PLAYER_ALL,0)
Duel.SetOperationInfo(0,CATEGORY_SPECIAL_SUMMON,g,2,PLAYER_ALL,g:GetFirst():GetOwner())
e:SetLabelObject(sc)
end
function c43434803.operation(e,tp,eg,ep,ev,re,r,rp)
......
......@@ -29,7 +29,7 @@ function c47778083.target(e,tp,eg,ep,ev,re,r,rp,chk,chkc)
local sc=sg:GetFirst()
local oc=og:GetFirst()
local g=Group.FromCards(sc,oc)
Duel.SetOperationInfo(0,CATEGORY_SPECIAL_SUMMON,g,2,0,0)
Duel.SetOperationInfo(0,CATEGORY_SPECIAL_SUMMON,g,2,PLAYER_ALL,1-g:GetFirst():GetOwner())
e:SetLabelObject(sc)
end
function c47778083.operation(e,tp,eg,ep,ev,re,r,rp)
......
......@@ -34,7 +34,7 @@ function c58551308.sptg(e,tp,eg,ep,ev,re,r,rp,chk,chkc)
Duel.Hint(HINT_SELECTMSG,1-tp,HINTMSG_SPSUMMON)
local g2=Duel.SelectTarget(1-tp,c58551308.filter,1-tp,LOCATION_GRAVE,0,1,1,e:GetHandler(),e,1-tp)
g1:Merge(g2)
Duel.SetOperationInfo(0,CATEGORY_SPECIAL_SUMMON,g1,g1:GetCount(),0,0)
Duel.SetOperationInfo(0,CATEGORY_SPECIAL_SUMMON,g1,g1:GetCount(),PLAYER_ALL,g1:GetFirst():GetOwner())
end
function c58551308.spop(e,tp,eg,ep,ev,re,r,rp)
local g=Duel.GetChainInfo(0,CHAININFO_TARGET_CARDS)
......
......@@ -31,7 +31,7 @@ function c84136000.target(e,tp,eg,ep,ev,re,r,rp,chk,chkc)
Duel.Hint(HINT_SELECTMSG,1-tp,HINTMSG_SPSUMMON)
local g2=Duel.SelectTarget(1-tp,c84136000.spfilter,1-tp,LOCATION_GRAVE,0,1,1,nil,e,1-tp)
g1:Merge(g2)
Duel.SetOperationInfo(0,CATEGORY_SPECIAL_SUMMON,g1,2,0,0)
Duel.SetOperationInfo(0,CATEGORY_SPECIAL_SUMMON,g1,2,PLAYER_ALL,g1:GetFirst():GetOwner())
end
function c84136000.activate(e,tp,eg,ep,ev,re,r,rp)
local g=Duel.GetChainInfo(0,CHAININFO_TARGET_CARDS)
......
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