Commit 6cb447a4 authored by mercury233's avatar mercury233
parents c6590e59 88ce3d3f
......@@ -2477,7 +2477,7 @@ int32 field::get_attack_target(card* pcard, card_vector* v, uint8 chain_attack,
return atype;
if((mcount == 0 || pcard->is_affected_by_effect(EFFECT_DIRECT_ATTACK) || core.attack_player)
&& !pcard->is_affected_by_effect(EFFECT_CANNOT_DIRECT_ATTACK)
&& !(extra_count_m && pcard->announce_count > extra_count)
&& !(!chain_attack && extra_count_m && pcard->announce_count > extra_count)
&& !(chain_attack && core.chain_attack_target))
pcard->direct_attackable = 1;
return atype;
......
......@@ -20,6 +20,8 @@
#include <unordered_map>
#include <unordered_set>
#define MAX_COIN_COUNT 20
class card;
struct card_data;
class duel;
......@@ -315,7 +317,9 @@ struct processor {
uint32 set_group_used_zones;
uint8 set_group_seq[7];
uint8 dice_result[5];
uint8 coin_result[5];
uint8 coin_result[MAX_COIN_COUNT];
int32 coin_count;
uint8 to_bp;
uint8 to_m2;
uint8 to_ep;
......@@ -361,7 +365,7 @@ struct processor {
limit_tuner(nullptr), limit_syn(nullptr), limit_syn_minc(0), limit_syn_maxc(0), limit_xyz(nullptr), limit_xyz_minc(0), limit_xyz_maxc(0), limit_link(nullptr), limit_link_card(nullptr),
limit_link_minc(0), limit_link_maxc(0), not_material(FALSE), attack_cancelable(FALSE), attack_rollback(FALSE), effect_damage_step(0), battle_damage{ 0 }, summon_count{ 0 }, extra_summon{ FALSE },
spe_effect{ 0 }, duel_options(0), duel_rule(0), copy_reset(0), copy_reset_count(0), last_control_changed_id(0), set_group_used_zones(0), set_group_seq{ 0 }, dice_result{ 0 }, coin_result{ 0 },
to_bp(FALSE), to_m2(FALSE), to_ep(FALSE), skip_m2(FALSE), chain_attack(FALSE), chain_attacker_id(0), chain_attack_target(nullptr), attack_player(PLAYER_NONE), selfdes_disabled(FALSE),
coin_count(0), to_bp(FALSE), to_m2(FALSE), to_ep(FALSE), skip_m2(FALSE), chain_attack(FALSE), chain_attacker_id(0), chain_attack_target(nullptr), attack_player(PLAYER_NONE), selfdes_disabled(FALSE),
overdraw{ FALSE }, check_level(0), shuffle_check_disabled(FALSE), shuffle_hand_check{ FALSE }, shuffle_deck_check{ FALSE }, deck_reversed(FALSE), remove_brainwashing(FALSE), flip_delayed(FALSE),
damage_calculated(FALSE), hand_adjusted(FALSE), summon_state_count{ 0 }, normalsummon_state_count{ 0 }, flipsummon_state_count{ 0 }, spsummon_state_count{ 0 }, attack_state_count{ 0 },
battle_phase_count{ 0 }, battled_count{ 0 }, phase_action(FALSE), hint_timing{ 0 }, current_player(PLAYER_NONE), conti_player(PLAYER_NONE) {}
......@@ -629,7 +633,7 @@ public:
int32 select_xyz_material(int16 step, uint8 playerid, uint32 lv, card* pcard, int32 min, int32 max);
int32 select_release_cards(int16 step, uint8 playerid, uint8 cancelable, int32 min, int32 max);
int32 select_tribute_cards(int16 step, card* target, uint8 playerid, uint8 cancelable, int32 min, int32 max, uint8 toplayer, uint32 zone);
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, int32 count);
int32 toss_dice(uint16 step, effect* reason_effect, uint8 reason_player, uint8 playerid, uint8 count1, uint8 count2);
int32 rock_paper_scissors(uint16 step, uint8 repeat);
......
......@@ -962,6 +962,17 @@ int32 scriptlib::card_is_type(lua_State *L) {
lua_pushboolean(L, 0);
return 1;
}
int32 scriptlib::card_is_all_types(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
uint32 ttype = (uint32)lua_tointeger(L, 2);
if((pcard->get_type() & ttype) == ttype)
lua_pushboolean(L, 1);
else
lua_pushboolean(L, 0);
return 1;
}
int32 scriptlib::card_is_fusion_type(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1);
......@@ -1209,6 +1220,17 @@ int32 scriptlib::card_is_reason(lua_State *L) {
lua_pushboolean(L, 0);
return 1;
}
int32 scriptlib::card_is_all_reasons(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
uint32 treason = (uint32)lua_tointeger(L, 2);
if((pcard->current.reason & treason) == treason)
lua_pushboolean(L, 1);
else
lua_pushboolean(L, 0);
return 1;
}
int32 scriptlib::card_is_summon_type(lua_State *L) {
check_param_count(L, 2);
check_param(L, PARAM_TYPE_CARD, 1);
......@@ -2695,6 +2717,29 @@ int32 scriptlib::card_is_defense_above(lua_State *L) {
}
return 1;
}
int32 scriptlib::card_is_has_level(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
if((pcard->data.type & (TYPE_XYZ | TYPE_LINK))
|| (pcard->status & STATUS_NO_LEVEL)
|| (!(pcard->data.type & TYPE_MONSTER) && !(pcard->get_type() & TYPE_MONSTER) && !pcard->is_affected_by_effect(EFFECT_PRE_MONSTER)))
lua_pushboolean(L, 0);
else
lua_pushboolean(L, 1);
return 1;
}
int32 scriptlib::card_is_has_defense(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
card* pcard = *(card**) lua_touserdata(L, 1);
if((pcard->data.type & TYPE_LINK)
|| (!(pcard->data.type & TYPE_MONSTER) && !(pcard->get_type() & TYPE_MONSTER) && !pcard->is_affected_by_effect(EFFECT_PRE_MONSTER)))
lua_pushboolean(L, 0);
else
lua_pushboolean(L, 1);
return 1;
}
int32 scriptlib::card_is_public(lua_State *L) {
check_param_count(L, 1);
check_param(L, PARAM_TYPE_CARD, 1);
......@@ -3358,6 +3403,7 @@ static const struct luaL_Reg cardlib[] = {
{ "IsOriginalCodeRule", scriptlib::card_is_origin_code_rule },
{ "IsCode", scriptlib::card_is_code },
{ "IsType", scriptlib::card_is_type },
{ "IsAllTypes", scriptlib::card_is_all_types },
{ "IsFusionType", scriptlib::card_is_fusion_type },
{ "IsSynchroType", scriptlib::card_is_synchro_type },
{ "IsXyzType", scriptlib::card_is_xyz_type },
......@@ -3375,6 +3421,7 @@ static const struct luaL_Reg cardlib[] = {
{ "IsNonAttribute", scriptlib::card_is_non_attribute },
{ "IsExtraDeckMonster", scriptlib::card_is_extra_deck_monster },
{ "IsReason", scriptlib::card_is_reason },
{ "IsAllReasons", scriptlib::card_is_all_reasons },
{ "IsSummonType", scriptlib::card_is_summon_type },
{ "IsSummonLocation", scriptlib::card_is_summon_location },
{ "IsSummonPlayer", scriptlib::card_is_summon_player },
......@@ -3493,6 +3540,8 @@ static const struct luaL_Reg cardlib[] = {
{ "IsAttackAbove", scriptlib::card_is_attack_above },
{ "IsDefenseBelow", scriptlib::card_is_defense_below },
{ "IsDefenseAbove", scriptlib::card_is_defense_above },
{ "IsHasLevel", scriptlib::card_is_has_level },
{ "IsHasDefense", scriptlib::card_is_has_defense },
{ "IsPublic", scriptlib::card_is_public },
{ "IsForbidden", scriptlib::card_is_forbidden },
{ "IsAbleToChangeControler", scriptlib::card_is_able_to_change_controler },
......
......@@ -44,6 +44,16 @@ int32 scriptlib::duel_set_lp(lua_State *L) {
pduel->write_buffer32(lp);
return 0;
}
int32 scriptlib::duel_is_turn_player(lua_State *L) {
check_param_count(L, 1);
int32 playerid = (int32)lua_tointeger(L, 1);
duel* pduel = interpreter::get_duel_info(L);
if(pduel->game_field->infos.turn_player == playerid)
lua_pushboolean(L, 1);
else
lua_pushboolean(L, 0);
return 1;
}
int32 scriptlib::duel_get_turn_player(lua_State *L) {
duel* pduel = interpreter::get_duel_info(L);
lua_pushinteger(L, pduel->game_field->infos.turn_player);
......@@ -498,9 +508,6 @@ int32 scriptlib::duel_sets(lua_State *L) {
pgroup = pduel->new_group(pcard);
} else if(check_param(L, PARAM_TYPE_GROUP, 2, TRUE)) {
pgroup = *(group**) lua_touserdata(L, 2);
if(pgroup->container.empty()) {
return 0;
}
pduel = pgroup->pduel;
} else
return luaL_error(L, "Parameter %d should be \"Card\" or \"Group\".", 2);
......@@ -613,10 +620,13 @@ int32 scriptlib::duel_sendto_hand(lua_State *L) {
if(lua_isnil(L, 2) || (playerid != 0 && playerid != 1))
playerid = PLAYER_NONE;
uint32 reason = (uint32)lua_tointeger(L, 3);
uint32 reason_player = pduel->game_field->core.reason_player;
if (lua_gettop(L) >= 4)
reason_player = (uint32)lua_tointeger(L, 4);
if(pcard)
pduel->game_field->send_to(pcard, pduel->game_field->core.reason_effect, reason, pduel->game_field->core.reason_player, playerid, LOCATION_HAND, 0, POS_FACEUP);
pduel->game_field->send_to(pcard, pduel->game_field->core.reason_effect, reason, reason_player, playerid, LOCATION_HAND, 0, POS_FACEUP);
else
pduel->game_field->send_to(&(pgroup->container), pduel->game_field->core.reason_effect, reason, pduel->game_field->core.reason_player, playerid, LOCATION_HAND, 0, POS_FACEUP);
pduel->game_field->send_to(&(pgroup->container), pduel->game_field->core.reason_effect, reason, reason_player, playerid, LOCATION_HAND, 0, POS_FACEUP);
return lua_yieldk(L, 0, (lua_KContext)pduel, [](lua_State *L, int32 status, lua_KContext ctx) {
duel* pduel = (duel*)ctx;
lua_pushinteger(L, pduel->game_field->returns.ivalue[0]);
......@@ -2234,6 +2244,34 @@ int32 scriptlib::duel_get_targets_relate_to_chain(lua_State* L) {
interpreter::group2value(L, pgroup);
return 1;
}
int32 scriptlib::duel_is_phase(lua_State *L) {
check_param_count(L, 1);
uint32 pphase = (uint32)lua_tointeger(L, 1);
duel* pduel = interpreter::get_duel_info(L);
if(pduel->game_field->infos.phase == pphase)
lua_pushboolean(L, 1);
else
lua_pushboolean(L, 0);
return 1;
}
int32 scriptlib::duel_is_main_phase(lua_State *L) {
duel* pduel = interpreter::get_duel_info(L);
uint16 phase = pduel->game_field->infos.phase;
if(phase == PHASE_MAIN1 || phase == PHASE_MAIN2)
lua_pushboolean(L, 1);
else
lua_pushboolean(L, 0);
return 1;
}
int32 scriptlib::duel_is_battle_phase(lua_State *L) {
duel* pduel = interpreter::get_duel_info(L);
uint16 phase = pduel->game_field->infos.phase;
if((phase >= PHASE_BATTLE_START) && (phase <= PHASE_BATTLE))
lua_pushboolean(L, 1);
else
lua_pushboolean(L, 0);
return 1;
}
int32 scriptlib::duel_get_current_phase(lua_State *L) {
duel* pduel = interpreter::get_duel_info(L);
lua_pushinteger(L, pduel->game_field->infos.phase);
......@@ -3970,14 +4008,14 @@ int32 scriptlib::duel_toss_coin(lua_State * L) {
duel* pduel = interpreter::get_duel_info(L);
int32 playerid = (int32)lua_tointeger(L, 1);
int32 count = (int32)lua_tointeger(L, 2);
if((playerid != 0 && playerid != 1) || count <= 0)
if((playerid != 0 && playerid != 1) || count == 0 || count < -1)
return 0;
if(count > 5)
count = 5;
if(count > MAX_COIN_COUNT)
count = MAX_COIN_COUNT;
pduel->game_field->add_process(PROCESSOR_TOSS_COIN, 0, pduel->game_field->core.reason_effect, 0, (pduel->game_field->core.reason_player << 16) + playerid, count);
return lua_yieldk(L, 0, (lua_KContext)pduel, [](lua_State *L, int32 status, lua_KContext ctx) {
duel* pduel = (duel*)ctx;
int32 count = (int32)lua_tointeger(L, 2);
int32 count = pduel->game_field->core.coin_count;
for(int32 i = 0; i < count; ++i)
lua_pushinteger(L, pduel->game_field->core.coin_result[i]);
return count;
......@@ -4024,9 +4062,9 @@ int32 scriptlib::duel_rock_paper_scissors(lua_State * L) {
}
int32 scriptlib::duel_get_coin_result(lua_State * L) {
duel* pduel = interpreter::get_duel_info(L);
for(int32 i = 0; i < 5; ++i)
for(int32 i = 0; i < pduel->game_field->core.coin_count; ++i)
lua_pushinteger(L, pduel->game_field->core.coin_result[i]);
return 5;
return pduel->game_field->core.coin_count;
}
int32 scriptlib::duel_get_dice_result(lua_State * L) {
duel* pduel = interpreter::get_duel_info(L);
......@@ -4037,7 +4075,7 @@ int32 scriptlib::duel_get_dice_result(lua_State * L) {
int32 scriptlib::duel_set_coin_result(lua_State * L) {
duel* pduel = interpreter::get_duel_info(L);
int32 res;
for(int32 i = 0; i < 5; ++i) {
for(int32 i = 0; i < MAX_COIN_COUNT; ++i) {
res = (int32)lua_tointeger(L, i + 1);
if(res != 0 && res != 1)
res = 0;
......@@ -4642,6 +4680,7 @@ static const struct luaL_Reg duellib[] = {
{ "EnableGlobalFlag", scriptlib::duel_enable_global_flag },
{ "GetLP", scriptlib::duel_get_lp },
{ "SetLP", scriptlib::duel_set_lp },
{ "IsTurnPlayer", scriptlib::duel_is_turn_player },
{ "GetTurnPlayer", scriptlib::duel_get_turn_player },
{ "GetTurnCount", scriptlib::duel_get_turn_count },
{ "GetDrawCount", scriptlib::duel_get_draw_count },
......@@ -4741,6 +4780,9 @@ static const struct luaL_Reg duellib[] = {
{ "GetChainEvent", scriptlib::duel_get_chain_event },
{ "GetFirstTarget", scriptlib::duel_get_first_target },
{ "GetTargetsRelateToChain", scriptlib::duel_get_targets_relate_to_chain },
{ "IsPhase", scriptlib::duel_is_phase },
{ "IsMainPhase", scriptlib::duel_is_main_phase },
{ "IsBattlePhase", scriptlib::duel_is_battle_phase },
{ "GetCurrentPhase", scriptlib::duel_get_current_phase },
{ "SkipPhase", scriptlib::duel_skip_phase },
{ "IsDamageCalculated", scriptlib::duel_is_damage_calculated },
......
......@@ -445,7 +445,7 @@ int32 field::draw(uint16 step, effect* reason_effect, uint32 reason, uint8 reaso
card_set* drawed_set = (card_set*)core.units.begin()->ptarget;
core.operated_set.swap(*drawed_set);
delete drawed_set;
returns.ivalue[0] = count;
returns.ivalue[0] = (int32)core.operated_set.size();
return TRUE;
}
}
......@@ -6311,7 +6311,11 @@ int32 field::select_tribute_cards(int16 step, card* target, uint8 playerid, uint
}
return TRUE;
}
int32 field::toss_coin(uint16 step, effect * reason_effect, uint8 reason_player, uint8 playerid, uint8 count) {
int32 field::toss_coin(uint16 step, effect * reason_effect, uint8 reason_player, uint8 playerid, int32 count) {
if (count == 0 || count < -1)
return TRUE;
if (count > MAX_COIN_COUNT)
count = MAX_COIN_COUNT;
switch(step) {
case 0: {
effect_set eset;
......@@ -6323,7 +6327,7 @@ int32 field::toss_coin(uint16 step, effect * reason_effect, uint8 reason_player,
e.reason = 0;
e.reason_effect = reason_effect;
e.reason_player = reason_player;
for(uint8 i = 0; i < 5; ++i)
for(int32 i = 0; i < MAX_COIN_COUNT; ++i)
core.coin_result[i] = 0;
auto pr = effects.continuous_effect.equal_range(EFFECT_TOSS_COIN_REPLACE);
for(auto eit = pr.first; eit != pr.second;) {
......@@ -6335,12 +6339,33 @@ int32 field::toss_coin(uint16 step, effect * reason_effect, uint8 reason_player,
}
}
if(!peffect) {
pduel->write_buffer8(MSG_TOSS_COIN);
pduel->write_buffer8(playerid);
pduel->write_buffer8(count);
for(int32 i = 0; i < count; ++i) {
core.coin_result[i] = pduel->get_next_integer(0, 1);
pduel->write_buffer8(core.coin_result[i]);
if (count > 0) {
pduel->write_buffer8(MSG_TOSS_COIN);
pduel->write_buffer8(playerid);
pduel->write_buffer8((uint8)count);
core.coin_count = count;
for (int32 i = 0; i < count; ++i) {
core.coin_result[i] = pduel->get_next_integer(0, 1);
pduel->write_buffer8(core.coin_result[i]);
}
}
else if (count == -1) {
core.coin_count = 0;
for (int32 i = 0; i < MAX_COIN_COUNT; ++i) {
core.coin_result[i] = pduel->get_next_integer(0, 1);
if (!core.coin_result[i]) {
core.coin_count = i + 1;
break;
}
}
if (!core.coin_count)
core.coin_count = MAX_COIN_COUNT;
pduel->write_buffer8(MSG_TOSS_COIN);
pduel->write_buffer8(playerid);
pduel->write_buffer8((uint8)core.coin_count);
for (int32 i = 0; i < core.coin_count; ++i) {
pduel->write_buffer8(core.coin_result[i]);
}
}
raise_event((card*)0, EVENT_TOSS_COIN_NEGATE, reason_effect, 0, reason_player, playerid, count);
process_instant_event();
......@@ -6352,7 +6377,7 @@ int32 field::toss_coin(uint16 step, effect * reason_effect, uint8 reason_player,
return FALSE;
}
case 1: {
raise_event((card*)0, EVENT_TOSS_COIN, reason_effect, 0, reason_player, playerid, count);
raise_event((card*)0, EVENT_TOSS_COIN, reason_effect, 0, reason_player, playerid, core.coin_count);
process_instant_event();
return TRUE;
}
......
......@@ -111,6 +111,7 @@ public:
static int32 card_is_origin_code_rule(lua_State *L);
static int32 card_is_code(lua_State *L);
static int32 card_is_type(lua_State *L);
static int32 card_is_all_types(lua_State *L);
static int32 card_is_fusion_type(lua_State *L);
static int32 card_is_synchro_type(lua_State *L);
static int32 card_is_xyz_type(lua_State *L);
......@@ -128,6 +129,7 @@ public:
static int32 card_is_non_attribute(lua_State *L);
static int32 card_is_extra_deck_monster(lua_State *L);
static int32 card_is_reason(lua_State *L);
static int32 card_is_all_reasons(lua_State *L);
static int32 card_is_summon_type(lua_State *L);
static int32 card_is_summon_location(lua_State *L);
static int32 card_is_summon_player(lua_State *L);
......@@ -246,6 +248,8 @@ public:
static int32 card_is_attack_above(lua_State *L);
static int32 card_is_defense_below(lua_State *L);
static int32 card_is_defense_above(lua_State *L);
static int32 card_is_has_level(lua_State *L);
static int32 card_is_has_defense(lua_State *L);
static int32 card_is_public(lua_State *L);
static int32 card_is_forbidden(lua_State *L);
static int32 card_is_able_to_change_controler(lua_State *L);
......@@ -383,6 +387,7 @@ public:
static int32 duel_enable_global_flag(lua_State *L);
static int32 duel_get_lp(lua_State *L);
static int32 duel_set_lp(lua_State *L);
static int32 duel_is_turn_player(lua_State *L);
static int32 duel_get_turn_player(lua_State *L);
static int32 duel_get_turn_count(lua_State *L);
static int32 duel_get_draw_count(lua_State *L);
......@@ -483,6 +488,9 @@ public:
static int32 duel_get_chain_event(lua_State *L);
static int32 duel_get_first_target(lua_State *L);
static int32 duel_get_targets_relate_to_chain(lua_State *L);
static int32 duel_is_phase(lua_State *L);
static int32 duel_is_main_phase(lua_State *L);
static int32 duel_is_battle_phase(lua_State *L);
static int32 duel_get_current_phase(lua_State *L);
static int32 duel_skip_phase(lua_State *L);
static int32 duel_is_damage_calculated(lua_State *L);
......
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