Commit 9c0c3f6d authored by salix5's avatar salix5

select_place()

parent 9b9a984d
......@@ -472,16 +472,19 @@ card* field::get_field_card(uint8 playerid, uint8 location, uint8 sequence) {
}
return 0;
}
// return: the given slot in LOCATION_MZONE or all LOCATION_SZONE is available or not
int32 field::is_location_useable(uint8 playerid, uint8 location, uint8 sequence) {
if (location != LOCATION_MZONE && location != LOCATION_SZONE)
return TRUE;
int32 flag = player[playerid].disabled_location | player[playerid].used_location;
if (location == LOCATION_MZONE && flag & (1 << sequence))
if (location == LOCATION_MZONE && flag & (0x1u << sequence))
return FALSE;
if (location == LOCATION_SZONE && flag & (256 << sequence))
if (location == LOCATION_SZONE && flag & (0x100u << sequence))
return FALSE;
return TRUE;
}
// return: usable count of LOCATION_MZONE or real LOCATION_SZONE
// store local flag in list
int32 field::get_useable_count(uint8 playerid, uint8 location, uint8 uplayer, uint32 reason, uint32* list) {
if (location != LOCATION_MZONE && location != LOCATION_SZONE)
return 0;
......
......@@ -130,6 +130,8 @@ struct processor_unit {
group* ptarget;
ptr arg1;
ptr arg2;
ptr arg3;
ptr arg4;
};
union return_value {
int8 bvalue[64];
......@@ -207,8 +209,8 @@ struct processor {
card_set destroy_canceled;
card_set delayed_enable_set;
effect_set_v disfield_effects;
effect_set_v extraz_effects;
effect_set_v extraz_effects_e;
effect_set_v extram_effects;
effect_set_v extras_effects;
std::set<effect*> reseted_effects;
std::list<effect*> delayed_tp;
std::list<effect*> delayed_ntp;
......@@ -422,7 +424,7 @@ public:
int32 check_chain_target(uint8 chaincount, card* pcard);
int32 is_able_to_enter_bp();
void add_process(uint16 type, uint16 step, effect* peffect, group* target, ptr arg1, ptr arg2);
void add_process(uint16 type, uint16 step, effect* peffect, group* target, ptr arg1, ptr arg2, ptr arg3 = 0, ptr arg4 = 0);
int32 process();
int32 execute_cost(uint16 step, effect* peffect, uint8 triggering_player);
int32 execute_operation(uint16 step, effect* peffect, uint8 triggering_player);
......@@ -685,7 +687,7 @@ public:
#define PROCESSOR_SELECT_OPTION_S 121
#define PROCESSOR_SELECT_CARD_S 122
#define PROCESSOR_SELECT_EFFECTYN_S 123
#define PROCESSOR_SELECT_PLACE_S 125
//#define PROCESSOR_SELECT_PLACE_S 125
#define PROCESSOR_SELECT_POSITION_S 126
#define PROCESSOR_SELECT_TRIBUTE_S 127
#define PROCESSOR_SORT_CARDS_S 128
......
......@@ -2744,7 +2744,7 @@ int32 scriptlib::duel_select_disable_field(lua_State * L) {
count = ct1 + ct2 + ct3 + ct4;
if(count == 0)
return 0;
pduel->game_field->add_process(PROCESSOR_SELECT_DISFIELD_S, 0, 0, 0, playerid + (count << 16), flag);
pduel->game_field->add_process(PROCESSOR_SELECT_DISFIELD_S, 0, 0, 0, playerid, flag, count);
return lua_yield(L, 0);
}
int32 scriptlib::duel_announce_race(lua_State * L) {
......
......@@ -3457,7 +3457,7 @@ int32 field::send_to(uint16 step, group * targets, effect * reason_effect, uint3
uint32 flag;
get_useable_count(pcard->current.controler, LOCATION_SZONE, pcard->current.controler, LOCATION_REASON_TOFIELD, &flag);
flag = ((flag << 8) & 0xff00) | 0xffffe0ff;
add_process(PROCESSOR_SELECT_PLACE, 0, 0, 0, 0x10000 + pcard->current.controler, flag);
add_process(PROCESSOR_SELECT_PLACE, 0, 0, 0, pcard->current.controler, flag, 1);
return FALSE;
}
case 8: {
......@@ -3788,15 +3788,13 @@ int32 field::move_to_field(uint16 step, card * target, uint32 enable, uint32 ret
} else if(!is_equip && location == LOCATION_SZONE && (target->data.type & TYPE_PENDULUM)) {
uint32 flag = 0;
if(is_location_useable(playerid, LOCATION_SZONE, 6))
flag |= 1 << 14;
flag |= 0x1u << 14;
if(is_location_useable(playerid, LOCATION_SZONE, 7))
flag |= 1 << 15;
flag |= 0x1u << 15;
if(move_player != playerid)
flag = flag << 16;
pduel->write_buffer8(MSG_SELECT_PLACE);
pduel->write_buffer8(move_player);
pduel->write_buffer8(1);
pduel->write_buffer32(~flag);
flag = ~flag;
add_process(PROCESSOR_SELECT_PLACE, 0, 0, 0, move_player, flag, 1);
} else {
uint32 flag;
uint32 lreason = (target->current.location == LOCATION_MZONE) ? LOCATION_REASON_CONTROL : LOCATION_REASON_TOFIELD;
......@@ -3824,7 +3822,7 @@ int32 field::move_to_field(uint16 step, card * target, uint32 enable, uint32 ret
flag = ((flag << 16) & 0xff0000) | 0xff00ffff;
}
flag |= 0xe0e0e0e0;
add_process(PROCESSOR_SELECT_PLACE, 0, 0, 0, 0x10000 + move_player, flag);
add_process(PROCESSOR_SELECT_PLACE, 0, 0, 0, move_player, flag, 1);
}
return FALSE;
}
......
......@@ -387,8 +387,9 @@ int32 field::select_place(uint16 step, uint8 playerid, uint32 flag, uint8 count)
p = returns.bvalue[pt];
l = returns.bvalue[pt + 1];
s = returns.bvalue[pt + 2];
if((p != 0 && p != 1) || ((l != LOCATION_MZONE) && (l != LOCATION_SZONE)) || s >= 5
|| ((1 << s) & (flag >> (((p == playerid) ? 0 : 16) + ((l == LOCATION_MZONE) ? 0 : 8))))) {
if((p != 0 && p != 1)
|| ((l != LOCATION_MZONE) && (l != LOCATION_SZONE))
|| ((0x1u << s) & (flag >> (((p == playerid) ? 0 : 16) + ((l == LOCATION_MZONE) ? 0 : 8))))) {
pduel->write_buffer8(MSG_RETRY);
return FALSE;
}
......
......@@ -14,7 +14,7 @@
#include "ocgapi.h"
#include <iterator>
void field::add_process(uint16 type, uint16 step, effect* peffect, group* target, ptr arg1, ptr arg2) {
void field::add_process(uint16 type, uint16 step, effect* peffect, group* target, ptr arg1, ptr arg2, ptr arg3, ptr arg4) {
processor_unit new_unit;
new_unit.type = type;
new_unit.step = step;
......@@ -22,6 +22,8 @@ void field::add_process(uint16 type, uint16 step, effect* peffect, group* target
new_unit.ptarget = target;
new_unit.arg1 = arg1;
new_unit.arg2 = arg2;
new_unit.arg3 = arg3;
new_unit.arg4 = arg4;
core.subunits.push_back(new_unit);
}
int32 field::process() {
......@@ -122,7 +124,7 @@ int32 field::process() {
}
case PROCESSOR_SELECT_DISFIELD:
case PROCESSOR_SELECT_PLACE: {
if (select_place(it->step, it->arg1 & 0xffff, it->arg2, (it->arg1 >> 16) & 0xffff)) {
if (select_place(it->step, it->arg1, it->arg2, it->arg3)) {
core.units.pop_front();
return pduel->bufferlen;
} else {
......@@ -663,8 +665,6 @@ int32 field::process() {
}
return pduel->bufferlen;
}
case PROCESSOR_SELECT_PLACE_S:
break;
case PROCESSOR_SELECT_POSITION_S: {
if(it->step == 0) {
add_process(PROCESSOR_SELECT_POSITION, 0, it->peffect, it->ptarget, it->arg1, it->arg2);
......@@ -809,7 +809,7 @@ int32 field::process() {
}
case PROCESSOR_SELECT_DISFIELD_S: {
if(it->step == 0) {
add_process(PROCESSOR_SELECT_DISFIELD, 0, it->peffect, it->ptarget, it->arg1, it->arg2);
add_process(PROCESSOR_SELECT_DISFIELD, 0, it->peffect, it->ptarget, it->arg1, it->arg2, it->arg3);
it->step++;
} else {
int32 playerid = it->arg1 & 0xffff;
......@@ -4787,13 +4787,13 @@ int32 field::refresh_location_info(uint16 step) {
case 0: {
effect_set eset;
uint32 value;
int32 p;
uint32 p;
core.units.begin()->arg2 = player[0].disabled_location | (player[1].disabled_location << 16);
player[0].disabled_location = 0;
player[1].disabled_location = 0;
core.disfield_effects.clear();
core.extraz_effects.clear();
core.extraz_effects_e.clear();
core.extram_effects.clear();
core.extras_effects.clear();
filter_field_effect(EFFECT_DISABLE_FIELD, &eset);
for (int32 i = 0; i < eset.size(); ++i) {
value = eset[i]->get_value();
......@@ -4809,10 +4809,8 @@ int32 field::refresh_location_info(uint16 step) {
p = eset[i]->get_handler_player();
value = eset[i]->get_value();
player[p].disabled_location |= (value >> 16) & 0x1f;
if(field_used_count[(value >> 16) & 0x1f] == 0)
core.extraz_effects_e.add_item(eset[i]);
else if((uint32)field_used_count[(value >> 16) & 0x1f] < (value & 0xffff))
core.extraz_effects.add_item(eset[i]);
if((uint32)field_used_count[(value >> 16) & 0x1f] < (value & 0xffff))
core.extram_effects.add_item(eset[i]);
}
eset.clear();
filter_field_effect(EFFECT_USE_EXTRA_SZONE, &eset);
......@@ -4820,10 +4818,8 @@ int32 field::refresh_location_info(uint16 step) {
p = eset[i]->get_handler_player();
value = eset[i]->get_value();
player[p].disabled_location |= (value >> 8) & 0x1f00;
if(field_used_count[(value >> 16) & 0x1f] == 0)
core.extraz_effects_e.add_item(eset[i]);
else if((uint32)field_used_count[(value >> 16) & 0x1f] < (value & 0xffff))
core.extraz_effects.add_item(eset[i]);
if((uint32)field_used_count[(value >> 16) & 0x1f] < (value & 0xffff))
core.extras_effects.add_item(eset[i]);
}
return FALSE;
}
......@@ -4861,106 +4857,82 @@ int32 field::refresh_location_info(uint16 step) {
return FALSE;
}
case 3: {
if(core.extraz_effects.count == 0) {
// If the blocking number is not reached, we should block more slots.
if(core.extram_effects.count == 0) {
core.units.begin()->step = 4;
return FALSE;
}
effect* peffect = core.extraz_effects[0];
effect* peffect = core.extram_effects[0];
core.units.begin()->peffect = peffect;
core.extraz_effects.remove_item(0);
int32 p = peffect->get_handler_player();
int32 loc = (peffect->code == EFFECT_USE_EXTRA_MZONE) ? LOCATION_MZONE : LOCATION_SZONE;
if((loc == LOCATION_MZONE && ((player[p].disabled_location & 0x1f) == 0x1f))
|| (loc == LOCATION_SZONE && ((player[p].disabled_location & 0x1f00) == 0x1f00))) {
core.units.begin()->step = 2;
return FALSE;
}
int32 val = peffect->get_value();
int32 count1 = (val & 0xffff) - field_used_count[(val >> 16) & 0x1f];
uint32 flag = 0;
int32 count2 = get_useable_count(p, loc, PLAYER_NONE, 0, &flag);
if(count1 > count2)
count1 = count2;
if(count1 == 0) {
core.extram_effects.remove_item(0);
uint32 p = peffect->get_handler_player();
uint32 mzone_flag = (player[p].disabled_location | player[p].used_location) & 0x1f;
if(mzone_flag == 0x1f) {
core.units.begin()->step = 4;
return FALSE;
}
core.units.begin()->arg1 = count1;
if(loc == LOCATION_SZONE)
flag = ((flag << 8) & 0xff00) | 0xffff00ff;
else
flag = (flag & 0xff) | 0xffffff00;
flag |= 0xe0e0e0e0;
add_process(PROCESSOR_SELECT_DISFIELD, 0, 0, 0, p + (count1 << 16), flag);
int32 val = peffect->get_value();
int32 dis_count = (val & 0xffff) - field_used_count[(val >> 16) & 0x1f];
int32 empty_count = 5 - field_used_count[mzone_flag];
uint32 flag = mzone_flag | 0xffffff00;
if(dis_count > empty_count)
dis_count = empty_count;
core.units.begin()->arg1 = dis_count;
add_process(PROCESSOR_SELECT_DISFIELD, 0, 0, 0, p, flag, dis_count);
return FALSE;
}
case 4: {
uint32 count1 = core.units.begin()->arg1;
uint32 selflag = 0;
uint8 s, pt = 0;
for(uint32 i = 0; i < count1; ++i) {
uint32 dis_count = core.units.begin()->arg1;
uint32 mzone_flag = 0;
uint8 s = 0, pt = 0;
for(uint32 i = 0; i < dis_count; ++i) {
s = returns.bvalue[pt + 2];
selflag |= 1 << s;
mzone_flag |= 0x1u << s;
pt += 3;
}
effect* peffect = core.units.begin()->peffect;
if(peffect->code == EFFECT_USE_EXTRA_MZONE)
player[peffect->get_handler_player()].disabled_location |= selflag;
else
player[peffect->get_handler_player()].disabled_location |= selflag << 8;
peffect->value = ((int32)peffect->value) | (selflag << 16);
player[peffect->get_handler_player()].disabled_location |= mzone_flag;
peffect->value = (int32)(peffect->value | (mzone_flag << 16));
core.units.begin()->step = 2;
return FALSE;
}
case 5: {
if(core.extraz_effects_e.count == 0) {
// EFFECT_USE_EXTRA_SZONE version
if(core.extras_effects.count == 0) {
core.units.begin()->step = 6;
return FALSE;
}
effect* peffect = core.extraz_effects_e[0];
effect* peffect = core.extras_effects[0];
core.units.begin()->peffect = peffect;
core.extraz_effects_e.remove_item(0);
int32 p = peffect->get_handler_player();
int32 loc = (peffect->code == EFFECT_USE_EXTRA_MZONE) ? LOCATION_MZONE : LOCATION_SZONE;
if(((loc == LOCATION_MZONE) && ((player[p].disabled_location & 0x1f) == 0x1f))
|| ((loc == LOCATION_SZONE) && ((player[p].disabled_location & 0x1f00) == 0x1f00))) {
core.units.begin()->step = 4;
return FALSE;
}
int32 val = peffect->get_value();
int32 count1 = (val & 0xffff) - field_used_count[(val >> 16) & 0x1f];
uint32 flag = 0;
int32 count2 = get_useable_count(p, loc, PLAYER_NONE, 0, &flag);
if(count1 > count2)
count1 = count2;
if(count1 == 0) {
core.extras_effects.remove_item(0);
uint32 p = peffect->get_handler_player();
uint32 szone_flag = ((player[p].disabled_location | player[p].used_location) & 0x1f00) >> 8;
if(szone_flag == 0x1f) {
core.units.begin()->step = 6;
return FALSE;
}
core.units.begin()->arg1 = count1;
if(loc == LOCATION_SZONE)
flag = ((flag << 8) & 0xff00) | 0xffff00ff;
else
flag = (flag & 0xff) | 0xffffff00;
flag |= 0xe0e0e0e0;
add_process(PROCESSOR_SELECT_DISFIELD, 0, 0, 0, p + (count1 << 16), flag);
int32 val = peffect->get_value();
uint32 dis_count = (val & 0xffff) - field_used_count[(val >> 16) & 0x1f];
uint32 empty_count = 5 - field_used_count[szone_flag];
uint32 flag = (szone_flag << 8) | 0xffff00ff;
if(dis_count > empty_count)
dis_count = empty_count;
core.units.begin()->arg1 = dis_count;
add_process(PROCESSOR_SELECT_DISFIELD, 0, 0, 0, p, flag, dis_count);
return FALSE;
}
case 6: {
uint32 count1 = core.units.begin()->arg1;
uint32 selflag = 0;
uint8 s, pt = 0;
for(uint32 i = 0; i < count1; ++i) {
uint32 dis_count = core.units.begin()->arg1;
uint32 szone_flag = 0;
uint8 s = 0, pt = 0;
for(uint32 i = 0; i < dis_count; ++i) {
s = returns.bvalue[pt + 2];
selflag |= 1 << s;
szone_flag |= 0x1u << s;
pt += 3;
}
effect* peffect = core.units.begin()->peffect;
if(peffect->code == EFFECT_USE_EXTRA_MZONE)
player[peffect->get_handler_player()].disabled_location |= selflag;
else
player[peffect->get_handler_player()].disabled_location |= selflag << 8;
peffect->value = ((int32)peffect->value) | (selflag << 16);
player[peffect->get_handler_player()].disabled_location |= szone_flag << 8;
peffect->value = (int32)(peffect->value | (szone_flag << 16));
core.units.begin()->step = 4;
return FALSE;
}
......
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