Commit 45f3eb3d authored by mercury233's avatar mercury233
parents 8f605218 e9200055
#Ygopro script engine.
# YGOPro script engine.
##Introduction
The core logic and lua script processor of YGOPro. this library can be made external of the project and used to power server technologies. It mantains a state engine that is manipulated by Lua scripts using manipulation functions it exposes.
## Introduction
The core logic and lua script processor of YGOPro. This library can be made external of the project and used to power server technologies. It maintains a state engine that is manipulated by Lua scripts using manipulation functions it exposes.
##Compiling
###1.) Download Fluorohydride/ygopro
## Compiling
### 1.) Download Fluorohydride/ygopro
Start by downloading the most parent of the source code. The team developing this project are the defacto edge and experts in our community. The most upto date `ocgcore` is a compiled dll version of the `Fluorohydride/ygopro/ocgcore` folders project.
###2.) Install Premake4 and Visual Studio 2010 (or later).
Download premake4.exe, put it in `c:\windows` or a similar folder that is globally accessiable via `cmd` or PowerShell. Install Visual Studio 2010, it is the system used for the guide because other parts of the project use C# and most the development team are Windows users.
### 2.) Install Premake4 and Visual Studio 2010 (or later).
Download premake4.exe, put it in `c:\windows` or a similar folder that is globally accessible via `cmd` or PowerShell. Install Visual Studio 2010, it is the system used for the guide because other parts of the project use C# and most the development team are Windows users.
###3.) Download dependencies
Dependencies are absent from the main project. There is information on how to build them but the easist thing to do is to download the following folders from a [soarqin/ygopro](https://github.com/soarqin/ygopro) fork and simply copy them into the `Fluorohydride/ygopro` folder.
### 3.) Download dependencies
Dependencies are absent from the main project. There is information on how to build them but the easiest thing to do is to download the following folders from a [soarqin/ygopro](https://github.com/soarqin/ygopro) fork and simply copy them into the `Fluorohydride/ygopro` folder.
* event
* freetype
* irrklang
* irrlict
* irrlicht
* lua
* sqlite3
###4.) Create the project files
### 4.) Create the project files
Run the following commands from the command line in the `Fluorohydride/ygopro` folder.
` premake4 /help `
......@@ -28,27 +27,26 @@ Run the following commands from the command line in the `Fluorohydride/ygopro` f
If you are not using Visual Studio 2010 or higher, make the needed adjustments. In the file system open `Fluorohydride/ygopro/build` folder open the `ygo` project.
### Build the system
### 5.) Build the system
Make sure the code actually compiles. Compile them in the following order one by one:
* lua
* sqlite3
* ocgcore
This should provide you with `ocgcore.lib` in the build output folder. `YGOCore` requires a `*.dll`; in `ocgcore` project properities change it to a dynamically linked library. Recompile, it should fail with an error indicating missing dependencies. Right click the project, add a existing file. Add `lua.lib` from the build folder to the project. It should now compile.
This should provide you with `ocgcore.lib` in the build output folder. `YGOCore` requires a `*.dll`; in `ocgcore` project properties change it to a dynamically linked library. Recompile, it should fail with an error indicating missing dependencies. Right click the project, add an existing file. Add `lua.lib` from the build folder to the project. It should now compile.
##Exposed Functions
## Exposed Functions
These three function need to be provided to the core so it can get card and database information.
- `void set_script_reader(script_reader f);` : Interface provided returns scripts based on number that corrosponses to a lua file, send in a string.
- `void set_card_reader(card_reader f);` : Inferface provided function that provides database information from the `data` table of `cards.cdb`.
- `void set_script_reader(script_reader f);` : Interface provided returns scripts based on number that corresponds to a lua file, send in a string.
- `void set_card_reader(card_reader f);` : Interface provided function that provides database information from the `data` table of `cards.cdb`.
- `void set_message_handler(message_handler f);` : Interface provided function that handles errors
These functions create the game itself and then manipulate it.
- `ptr create_duel(uint32 seed);` : Create a the instance of the duel using a random number.
- `void start_duel(ptr pduel, int32 options);` : Starts the duel
- `void end_duel(ptr pduel);` : ends the duel
- `void set_player_info(ptr pduel, int32 playerid, int32 lp, int32 startcount, int32 drawcount);` sets the duel up
......@@ -58,12 +56,12 @@ These functions create the game itself and then manipulate it.
- `void new_card(ptr pduel, uint32 code, uint8 owner, uint8 playerid, uint8 location, uint8 sequence, uint8 position);` : add a card to the duel state.
- `void new_tag_card(ptr pduel, uint32 code, uint8 owner, uint8 location);` : add a new card to the tag pool.
- `int32 query_card(ptr pduel, uint8 playerid, uint8 location, uint8 sequence, int32 query_flag, byte* buf, int32 use_cache);` : find out about a card in a specific spot.
- `int32 query_field_count(ptr pduel, uint8 playerid, uint8 location);`Get the number of cards in a specific field/zone.
- `int32 query_field_count(ptr pduel, uint8 playerid, uint8 location);` : Get the number of cards in a specific field/zone.
- `int32 query_field_card(ptr pduel, uint8 playerid, uint8 location, int32 query_flag, byte* buf, int32 use_cache);`
- `int32 query_field_info(ptr pduel, byte* buf);`
- `void set_responsei(ptr pduel, int32 value);`
- `void set_responseb(ptr pduel, byte* buf);`
- `int32 preload_script(ptr pduel, char* script, int32 len);`
#Lua functions
# Lua functions
`interpreter.cpp`
This diff is collapsed.
......@@ -33,6 +33,7 @@ struct card_data {
int32 defense;
uint32 lscale;
uint32 rscale;
uint32 link_marker;
};
struct card_state {
......@@ -42,6 +43,7 @@ struct card_state {
uint32 type;
uint32 level;
uint32 rank;
uint32 link;
uint32 lscale;
uint32 rscale;
uint32 attribute;
......@@ -55,9 +57,11 @@ struct card_state {
uint8 sequence;
uint8 position;
uint32 reason;
bool pzone;
card* reason_card;
uint8 reason_player;
effect* reason_effect;
bool is_location(int32 loc) const;
};
struct query_cache {
......@@ -66,6 +70,7 @@ struct query_cache {
uint32 type;
uint32 level;
uint32 rank;
uint32 link;
uint32 attribute;
uint32 race;
int32 attack;
......@@ -77,6 +82,7 @@ struct query_cache {
int32 is_disabled;
uint32 lscale;
uint32 rscale;
uint32 link_marker;
};
class card {
......@@ -172,12 +178,16 @@ public:
int32 is_fusion_set_card(uint32 set_code);
uint32 get_type();
uint32 get_fusion_type();
uint32 get_synchro_type();
uint32 get_xyz_type();
uint32 get_link_type();
int32 get_base_attack();
int32 get_attack();
int32 get_base_defense();
int32 get_defense();
uint32 get_level();
uint32 get_rank();
uint32 get_link();
uint32 get_synchro_level(card* pcard);
uint32 get_ritual_level(card* pcard);
uint32 check_xyz_level(card* pcard, uint32 lv);
......@@ -186,6 +196,12 @@ public:
uint32 get_race();
uint32 get_lscale();
uint32 get_rscale();
uint32 get_link_marker();
int32 is_link_marker(uint32 dir);
uint32 get_linked_zone();
void get_linked_cards(card_set* cset);
uint32 get_mutual_linked_zone();
int32 is_link_state();
int32 is_position(int32 pos);
void set_status(uint32 status, int32 enabled);
int32 get_status(uint32 status);
......@@ -237,8 +253,10 @@ public:
void filter_single_continuous_effect(int32 code, effect_set* eset, uint8 sort = TRUE);
void filter_immune_effect();
void filter_disable_related_cards();
int32 filter_summon_procedure(uint8 playerid, effect_set* eset, uint8 ignore_count, uint8 min_tribute);
int32 filter_set_procedure(uint8 playerid, effect_set* eset, uint8 ignore_count, uint8 min_tribute);
int32 filter_summon_procedure(uint8 playerid, effect_set* eset, uint8 ignore_count, uint8 min_tribute, uint32 zone);
int32 check_summon_procedure(effect* peffect, uint8 playerid, uint8 ignore_count, uint8 min_tribute, uint32 zone);
int32 filter_set_procedure(uint8 playerid, effect_set* eset, uint8 ignore_count, uint8 min_tribute, uint32 zone);
int32 check_set_procedure(effect* peffect, uint8 playerid, uint8 ignore_count, uint8 min_tribute, uint32 zone);
void filter_spsummon_procedure(uint8 playerid, effect_set* eset, uint32 summon_type);
void filter_spsummon_procedure_g(uint8 playerid, effect_set* eset);
effect* is_affected_by_effect(int32 code);
......@@ -250,17 +268,19 @@ public:
int32 check_unique_code(card* pcard);
void get_unique_target(card_set* cset, int32 controler);
int32 check_cost_condition(int32 ecode, int32 playerid);
int32 check_cost_condition(int32 ecode, int32 playerid, int32 sumtype);
int32 is_summonable_card();
int32 is_fusion_summonable_card(uint32 summon_type);
int32 is_spsummonable(effect* peffect);
int32 is_summonable(effect* peffect, uint8 min_tribute);
int32 is_can_be_summoned(uint8 playerid, uint8 ingore_count, effect* peffect, uint8 min_tribute);
int32 is_summonable(effect* peffect, uint8 min_tribute, uint32 zone = 0x1f);
int32 is_can_be_summoned(uint8 playerid, uint8 ingore_count, effect* peffect, uint8 min_tribute, uint32 zone = 0x1f);
int32 get_summon_tribute_count();
int32 get_set_tribute_count();
int32 is_can_be_flip_summoned(uint8 playerid);
int32 is_special_summonable(uint8 playerid, uint32 summon_type);
int32 is_can_be_special_summoned(effect* reason_effect, uint32 sumtype, uint8 sumpos, uint8 sumplayer, uint8 toplayer, uint8 nocheck, uint8 nolimit);
int32 is_setable_mzone(uint8 playerid, uint8 ignore_count, effect* peffect, uint8 min_tribute);
int32 is_can_be_special_summoned(effect* reason_effect, uint32 sumtype, uint8 sumpos, uint8 sumplayer, uint8 toplayer, uint8 nocheck, uint8 nolimit, uint32 zone);
int32 is_setable_mzone(uint8 playerid, uint8 ignore_count, effect* peffect, uint8 min_tribute, uint32 zone = 0x1f);
int32 is_setable_szone(uint8 playerid, uint8 ignore_fd = 0);
int32 is_affect_by_effect(effect* peffect);
int32 is_destructable();
......@@ -285,13 +305,14 @@ public:
int32 is_capable_change_position(uint8 playerid);
int32 is_capable_turn_set(uint8 playerid);
int32 is_capable_change_control();
int32 is_control_can_be_changed();
int32 is_control_can_be_changed(int32 ignore_mzone, uint32 zone);
int32 is_capable_be_battle_target(card* pcard);
int32 is_capable_be_effect_target(effect* peffect, uint8 playerid);
int32 is_can_be_fusion_material(card* fcard);
int32 is_can_be_synchro_material(card* scard, card* tuner = 0);
int32 is_can_be_ritual_material(card* scard);
int32 is_can_be_xyz_material(card* scard);
int32 is_can_be_link_material(card* scard);
};
//Locations
......@@ -343,6 +364,7 @@ public:
#define TYPE_XYZ 0x800000 //
#define TYPE_PENDULUM 0x1000000 //
#define TYPE_SPSUMMON 0x2000000 //
#define TYPE_LINK 0x4000000 //
//Attributes
#define ATTRIBUTE_EARTH 0x01 //
......@@ -404,17 +426,20 @@ public:
#define REASON_REPLACE 0x1000000 //
#define REASON_DRAW 0x2000000 //
#define REASON_REDIRECT 0x4000000 //
//#define REASON_REVEAL 0x8000000 //
#define REASON_LINK 0x10000000 //
//Summon Type
#define SUMMON_TYPE_NORMAL 0x10000000
#define SUMMON_TYPE_ADVANCE 0x11000000
#define SUMMON_TYPE_DUAL 0x12000000
#define SUMMON_TYPE_FLIP 0x20000000
#define SUMMON_TYPE_SPECIAL 0x40000000
#define SUMMON_TYPE_FUSION 0x43000000
#define SUMMON_TYPE_RITUAL 0x45000000
#define SUMMON_TYPE_SYNCHRO 0x46000000
#define SUMMON_TYPE_XYZ 0x49000000
#define SUMMON_TYPE_NORMAL 0x10000000
#define SUMMON_TYPE_ADVANCE 0x11000000
#define SUMMON_TYPE_DUAL 0x12000000
#define SUMMON_TYPE_FLIP 0x20000000
#define SUMMON_TYPE_SPECIAL 0x40000000
#define SUMMON_TYPE_FUSION 0x43000000
#define SUMMON_TYPE_RITUAL 0x45000000
#define SUMMON_TYPE_SYNCHRO 0x46000000
#define SUMMON_TYPE_XYZ 0x49000000
#define SUMMON_TYPE_PENDULUM 0x4a000000
#define SUMMON_TYPE_LINK 0x4c000000
//Status
#define STATUS_DISABLED 0x0001 //
#define STATUS_TO_ENABLE 0x0002 //
......@@ -474,6 +499,7 @@ public:
#define QUERY_IS_PUBLIC 0x100000
#define QUERY_LSCALE 0x200000
#define QUERY_RSCALE 0x400000
#define QUERY_LINK 0x800000
#define ASSUME_CODE 1
#define ASSUME_TYPE 2
......@@ -483,4 +509,14 @@ public:
#define ASSUME_RACE 6
#define ASSUME_ATTACK 7
#define ASSUME_DEFENSE 8
#define LINK_MARKER_BOTTOM_LEFT 0001
#define LINK_MARKER_BOTTOM 0002
#define LINK_MARKER_BOTTOM_RIGHT 0004
#define LINK_MARKER_LEFT 0010
#define LINK_MARKER_RIGHT 0040
#define LINK_MARKER_TOP_LEFT 0100
#define LINK_MARKER_TOP 0200
#define LINK_MARKER_TOP_RIGHT 0400
#endif /* CARD_H_ */
......@@ -77,7 +77,7 @@ int32 effect::is_available() {
card* powner = get_owner();
if (phandler->current.controler == PLAYER_NONE)
return FALSE;
if(is_flag(EFFECT_FLAG_SINGLE_RANGE) && !in_range(phandler->current.location, phandler->current.sequence))
if(is_flag(EFFECT_FLAG_SINGLE_RANGE) && !in_range(phandler))
return FALSE;
if(is_flag(EFFECT_FLAG_SINGLE_RANGE) && !phandler->get_status(STATUS_EFFECT_ENABLED) && !is_flag(EFFECT_FLAG_IMMEDIATELY_APPLY))
return FALSE;
......@@ -116,7 +116,7 @@ int32 effect::is_available() {
if (!is_flag(EFFECT_FLAG_FIELD_ONLY)) {
if(phandler->current.controler == PLAYER_NONE)
return FALSE;
if(!in_range(phandler->current.location, phandler->current.sequence))
if(!in_range(phandler))
return FALSE;
if(!phandler->get_status(STATUS_EFFECT_ENABLED) && !is_flag(EFFECT_FLAG_IMMEDIATELY_APPLY))
return FALSE;
......@@ -170,7 +170,7 @@ int32 effect::check_count_limit(uint8 playerid) {
// check if an EFFECT_TYPE_ACTIONS effect can be activated
// for triggering effects, it checks EFFECT_FLAG_DAMAGE_STEP, EFFECT_FLAG_SET_AVAILABLE
// for continuous effect, it checks EFFECT_FLAG_AVAILABLE_BD
int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_cond, int32 neglect_cost, int32 neglect_target) {
int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_cond, int32 neglect_cost, int32 neglect_target, int32 neglect_loc) {
if(!(type & EFFECT_TYPE_ACTIONS))
return FALSE;
if(!check_count_limit(playerid))
......@@ -192,9 +192,10 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
if(handler->data.type & TYPE_MONSTER) {
if(!(handler->data.type & TYPE_PENDULUM))
return FALSE;
if(pduel->game_field->player[playerid].list_szone[6] && pduel->game_field->player[playerid].list_szone[7])
if(!pduel->game_field->is_location_useable(playerid, LOCATION_PZONE, 0)
&& !pduel->game_field->is_location_useable(playerid, LOCATION_PZONE, 1))
return FALSE;
} else if(!(handler->data.type & TYPE_FIELD)
} else if(!(handler->data.type & TYPE_FIELD)
&& pduel->game_field->get_useable_count(playerid, LOCATION_SZONE, playerid, LOCATION_REASON_TOFIELD) <= 0)
return FALSE;
} else if(handler->current.location == LOCATION_SZONE) {
......@@ -209,7 +210,7 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
}
// check activate in hand/in set turn
int32 ecode = 0;
if(handler->current.location == LOCATION_HAND) {
if(handler->current.location == LOCATION_HAND && !neglect_loc) {
if(handler->data.type & TYPE_TRAP)
ecode = EFFECT_TRAP_ACT_IN_HAND;
else if((handler->data.type & TYPE_SPELL) && pduel->game_field->infos.turn_player != playerid) {
......@@ -242,7 +243,7 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
} else if(!(type & EFFECT_TYPE_CONTINUOUS)) {
card* phandler = get_handler();
if((phandler->data.type & TYPE_MONSTER) && (phandler->current.location & LOCATION_SZONE)
&& !in_range(phandler->current.location, phandler->current.sequence))
&& !in_range(phandler))
return FALSE;
if((phandler->current.location & (LOCATION_ONFIELD | LOCATION_REMOVED))) {
// effects which can be activated while face-down:
......@@ -275,7 +276,7 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
if(((type & EFFECT_TYPE_FIELD) || ((type & EFFECT_TYPE_SINGLE) && is_flag(EFFECT_FLAG_SINGLE_RANGE))) && (phandler->current.location & LOCATION_ONFIELD)
&& (!phandler->is_position(POS_FACEUP) || !phandler->is_status(STATUS_EFFECT_ENABLED)))
return FALSE;
if((type & EFFECT_TYPE_SINGLE) && is_flag(EFFECT_FLAG_SINGLE_RANGE) && !in_range(phandler->current.location, phandler->current.sequence))
if((type & EFFECT_TYPE_SINGLE) && is_flag(EFFECT_FLAG_SINGLE_RANGE) && !in_range(phandler))
return FALSE;
if(is_flag(EFFECT_FLAG_OWNER_RELATE) && is_can_be_forbidden() && owner->is_status(STATUS_FORBIDDEN))
return FALSE;
......@@ -309,7 +310,7 @@ int32 effect::is_activateable(uint8 playerid, const tevent& e, int32 neglect_con
int32 effect::is_action_check(uint8 playerid) {
effect_set eset;
pduel->game_field->filter_player_effect(playerid, EFFECT_CANNOT_ACTIVATE, &eset);
for(int i = 0; i < eset.size(); ++i) {
for(int32 i = 0; i < eset.size(); ++i) {
pduel->lua->add_param(this, PARAM_TYPE_EFFECT);
pduel->lua->add_param(playerid, PARAM_TYPE_INT);
if(eset[i]->check_value_condition(2))
......@@ -317,7 +318,7 @@ int32 effect::is_action_check(uint8 playerid) {
}
eset.clear();
pduel->game_field->filter_player_effect(playerid, EFFECT_ACTIVATE_COST, &eset);
for(int i = 0; i < eset.size(); ++i) {
for(int32 i = 0; i < eset.size(); ++i) {
pduel->lua->add_param(eset[i], PARAM_TYPE_EFFECT);
pduel->lua->add_param(this, PARAM_TYPE_EFFECT);
pduel->lua->add_param(playerid, PARAM_TYPE_INT);
......@@ -423,7 +424,7 @@ int32 effect::is_activate_check(uint8 playerid, const tevent& e, int32 neglect_c
int32 effect::is_target(card* pcard) {
if(type & EFFECT_TYPE_ACTIONS)
return FALSE;
if(type & (EFFECT_TYPE_SINGLE | EFFECT_TYPE_EQUIP | EFFECT_TYPE_XMATERIAL))
if(type & (EFFECT_TYPE_SINGLE | EFFECT_TYPE_EQUIP | EFFECT_TYPE_XMATERIAL) && !(type & EFFECT_TYPE_FIELD))
return TRUE;
if(pcard && !is_flag(EFFECT_FLAG_SET_AVAILABLE) && (pcard->current.location & LOCATION_ONFIELD)
&& !pcard->is_position(POS_FACEUP))
......@@ -433,18 +434,18 @@ int32 effect::is_target(card* pcard) {
return FALSE;
if(is_flag(EFFECT_FLAG_ABSOLUTE_TARGET)) {
if(pcard->current.controler == 0) {
if (!(s_range & pcard->current.location))
if(!pcard->current.is_location(s_range))
return FALSE;
} else {
if(!(o_range & pcard->current.location))
if(!pcard->current.is_location(o_range))
return FALSE;
}
} else {
if(pcard->current.controler == get_handler_player()) {
if(!(s_range & pcard->current.location))
if(!pcard->current.is_location(s_range))
return FALSE;
} else {
if(!(o_range & pcard->current.location))
if(!pcard->current.is_location(o_range))
return FALSE;
}
}
......@@ -463,9 +464,9 @@ int32 effect::is_target_player(uint8 playerid) {
return FALSE;
uint8 self = get_handler_player();
if(is_flag(EFFECT_FLAG_ABSOLUTE_TARGET)) {
if(s_range && playerid == 0 )
if(s_range && playerid == 0)
return TRUE;
if(o_range && playerid == 1 )
if(o_range && playerid == 1)
return TRUE;
} else {
if(s_range && self == playerid)
......@@ -488,7 +489,7 @@ int32 effect::is_player_effect_target(card* pcard) {
int32 effect::is_immuned(card* pcard) {
effect_set_v effects = pcard->immune_effect;
effect* peffect;
for (int i = 0; i < effects.count; ++i) {
for (int32 i = 0; i < effects.size(); ++i) {
peffect = effects.at(i);
if(peffect->value) {
pduel->lua->add_param(this, PARAM_TYPE_EFFECT);
......@@ -678,14 +679,13 @@ uint8 effect::get_handler_player() {
return effect_owner;
return get_handler()->current.controler;
}
int32 effect::in_range(int32 loc, int32 seq) {
int32 effect::in_range(card* pcard) {
if(type & EFFECT_TYPE_XMATERIAL)
return handler->overlay_target ? TRUE : FALSE;
return pcard->current.is_location(range);
}
int32 effect::in_range(const chain& ch) {
if(type & EFFECT_TYPE_XMATERIAL)
return (int32)(!!handler->overlay_target);
if(loc != LOCATION_SZONE)
return range & loc;
if(seq < 5)
return range & LOCATION_SZONE;
if(seq == 5)
return range & (LOCATION_SZONE | LOCATION_FZONE);
return range & LOCATION_PZONE;
return handler->overlay_target ? TRUE : FALSE;
return range & ch.triggering_location;
}
......@@ -67,7 +67,7 @@ public:
int32 is_can_be_forbidden();
int32 is_available();
int32 check_count_limit(uint8 playerid);
int32 is_activateable(uint8 playerid, const tevent& e, int32 neglect_cond = FALSE, int32 neglect_cost = FALSE, int32 neglect_target = FALSE);
int32 is_activateable(uint8 playerid, const tevent& e, int32 neglect_cond = FALSE, int32 neglect_cost = FALSE, int32 neglect_target = FALSE, int32 neglect_loc = FALSE);
int32 is_action_check(uint8 playerid);
int32 is_activate_ready(uint8 playerid, const tevent& e, int32 neglect_cond = FALSE, int32 neglect_cost = FALSE, int32 neglect_target = FALSE);
int32 is_condition_check(uint8 playerid, const tevent& e);
......@@ -89,7 +89,8 @@ public:
uint8 get_owner_player();
card* get_handler() const;
uint8 get_handler_player();
int32 in_range(int32 loc, int32 seq);
int32 in_range(card* pcard);
int32 in_range(const chain& ch);
bool is_flag(effect_flag flag) const {
return !!(this->flag[0] & flag);
}
......@@ -356,6 +357,7 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
#define EFFECT_CANNOT_BE_SYNCHRO_MATERIAL 236
#define EFFECT_SYNCHRO_MATERIAL_CUSTOM 237
#define EFFECT_CANNOT_BE_XYZ_MATERIAL 238
#define EFFECT_CANNOT_BE_LINK_MATERIAL 239
#define EFFECT_SYNCHRO_LEVEL 240
#define EFFECT_RITUAL_LEVEL 241
#define EFFECT_XYZ_LEVEL 242
......@@ -414,6 +416,7 @@ inline effect_flag operator|(effect_flag flag1, effect_flag flag2)
//#define EFFECT_REMOVE_FUSION_ATTRIBUTE 350
#define EFFECT_CHANGE_FUSION_ATTRIBUTE 351
#define EFFECT_EXTRA_FUSION_MATERIAL 352
#define EFFECT_TUNER_MATERIAL_LIMIT 353
#define EVENT_STARTUP 1000
#define EVENT_FLIP 1001
......
......@@ -84,6 +84,9 @@ struct effect_set_v {
container.clear();
count = 0;
}
int size() const {
return count;
}
void sort() {
if(count < 2)
return;
......
This diff is collapsed.
This diff is collapsed.
......@@ -28,8 +28,12 @@ static const struct luaL_Reg cardlib[] = {
{ "GetType", scriptlib::card_get_type },
{ "GetOriginalType", scriptlib::card_get_origin_type },
{ "GetFusionType", scriptlib::card_get_fusion_type },
{ "GetSynchroType", scriptlib::card_get_synchro_type },
{ "GetXyzType", scriptlib::card_get_xyz_type },
{ "GetLinkType", scriptlib::card_get_link_type },
{ "GetLevel", scriptlib::card_get_level },
{ "GetRank", scriptlib::card_get_rank },
{ "GetLink", scriptlib::card_get_link },
{ "GetSynchroLevel", scriptlib::card_get_synchro_level },
{ "GetRitualLevel", scriptlib::card_get_ritual_level },
{ "GetOriginalLevel", scriptlib::card_get_origin_level },
......@@ -39,6 +43,11 @@ static const struct luaL_Reg cardlib[] = {
{ "GetOriginalLeftScale", scriptlib::card_get_origin_lscale },
{ "GetRightScale", scriptlib::card_get_rscale },
{ "GetOriginalRightScale", scriptlib::card_get_origin_rscale },
{ "IsLinkMarker", scriptlib::card_is_link_marker },
{ "GetLinkedGroup", scriptlib::card_get_linked_group },
{ "GetLinkedGroupCount", scriptlib::card_get_linked_group_count },
{ "GetLinkedZone", scriptlib::card_get_linked_zone },
{ "IsLinkState", scriptlib::card_is_link_state },
{ "GetAttribute", scriptlib::card_get_attribute },
{ "GetOriginalAttribute", scriptlib::card_get_origin_attribute },
{ "GetFusionAttribute", scriptlib::card_get_fusion_attribute },
......@@ -83,10 +92,14 @@ static const struct luaL_Reg cardlib[] = {
{ "IsCode", scriptlib::card_is_code },
{ "IsType", scriptlib::card_is_type },
{ "IsFusionType", scriptlib::card_is_fusion_type },
{ "IsSynchroType", scriptlib::card_is_synchro_type },
{ "IsXyzType", scriptlib::card_is_xyz_type },
{ "IsLinkType", scriptlib::card_is_link_type },
{ "IsRace", scriptlib::card_is_race },
{ "IsAttribute", scriptlib::card_is_attribute },
{ "IsFusionAttribute", scriptlib::card_is_fusion_attribute },
{ "IsReason", scriptlib::card_is_reason },
{ "IsSummonType", scriptlib::card_is_summon_type },
{ "IsStatus", scriptlib::card_is_status },
{ "IsNotTuner", scriptlib::card_is_not_tuner },
{ "SetStatus", scriptlib::card_set_status },
......@@ -209,6 +222,7 @@ static const struct luaL_Reg cardlib[] = {
{ "IsCanBeSynchroMaterial", scriptlib::card_is_can_be_synchro_material },
{ "IsCanBeRitualMaterial", scriptlib::card_is_can_be_ritual_material },
{ "IsCanBeXyzMaterial", scriptlib::card_is_can_be_xyz_material },
{ "IsCanBeLinkMaterial", scriptlib::card_is_can_be_link_material },
{ "CheckFusionMaterial", scriptlib::card_check_fusion_material },
{ "CheckFusionSubstitute", scriptlib::card_check_fusion_substitute },
{ "IsImmuneToEffect", scriptlib::card_is_immune_to_effect },
......@@ -227,6 +241,7 @@ static const struct luaL_Reg cardlib[] = {
{ "ResetNegateEffect", scriptlib::card_reset_negate_effect },
{ "AssumeProperty", scriptlib::card_assume_prop },
{ "SetSPSummonOnce", scriptlib::card_set_spsummon_once },
{ "CheckMZoneFromEx", scriptlib::card_check_mzone_from_ex },
{ NULL, NULL }
};
......@@ -355,6 +370,7 @@ static const struct luaL_Reg duellib[] = {
{ "MoveToField", scriptlib::duel_move_to_field },
{ "ReturnToField", scriptlib::duel_return_to_field },
{ "MoveSequence", scriptlib::duel_move_sequence },
{ "SwapSequence", scriptlib::duel_swap_sequence },
{ "SetChainLimit", scriptlib::duel_set_chain_limit },
{ "SetChainLimitTillChainEnd", scriptlib::duel_set_chain_limit_p },
{ "GetChainMaterial", scriptlib::duel_get_chain_material },
......@@ -401,6 +417,11 @@ static const struct luaL_Reg duellib[] = {
{ "IncreaseSummonedCount", scriptlib::duel_increase_summon_count },
{ "CheckSummonedCount", scriptlib::duel_check_summon_count },
{ "GetLocationCount", scriptlib::duel_get_location_count },
{ "GetLocationCountFromEx", scriptlib::duel_get_location_count_fromex },
{ "GetUsableMZoneCount", scriptlib::duel_get_usable_mzone_count },
{ "GetLinkedGroup", scriptlib::duel_get_linked_group },
{ "GetLinkedGroupCount", scriptlib::duel_get_linked_group_count },
{ "GetLinkedZone", scriptlib::duel_get_linked_zone },
{ "GetFieldCard", scriptlib::duel_get_field_card },
{ "CheckLocation", scriptlib::duel_check_location },
{ "GetCurrentChain", scriptlib::duel_get_current_chain },
......@@ -479,6 +500,7 @@ static const struct luaL_Reg duellib[] = {
{ "AnnounceCoin", scriptlib::duel_announce_coin },
{ "TossCoin", scriptlib::duel_toss_coin },
{ "TossDice", scriptlib::duel_toss_dice },
{ "RockPaperScissors", scriptlib::duel_rock_paper_scissors },
{ "GetCoinResult", scriptlib::duel_get_coin_result },
{ "GetDiceResult", scriptlib::duel_get_dice_result },
{ "SetCoinResult", scriptlib::duel_set_coin_result },
......
This diff is collapsed.
......@@ -144,8 +144,15 @@ int32 scriptlib::debug_reload_field_begin(lua_State *L) {
check_param_count(L, 1);
duel* pduel = interpreter::get_duel_info(L);
uint32 flag = lua_tointeger(L, 1);
int32 rule = lua_tointeger(L, 2);
pduel->clear();
pduel->game_field->core.duel_options = flag;
if (rule)
pduel->game_field->core.duel_rule = rule;
else if (flag & DUEL_OBSOLETE_RULING)
pduel->game_field->core.duel_rule = 1;
else
pduel->game_field->core.duel_rule = 3;
return 0;
}
int32 scriptlib::debug_reload_field_end(lua_State *L) {
......
This diff is collapsed.
......@@ -527,7 +527,10 @@ int32 scriptlib::effect_is_activatable(lua_State *L) {
check_param(L, PARAM_TYPE_EFFECT, 1);
uint32 playerid = lua_tointeger(L, 2);
effect* peffect = *(effect**) lua_touserdata(L, 1);
lua_pushboolean(L, peffect->is_activateable(playerid, peffect->pduel->game_field->nil_event));
uint32 neglect_loc = 0;
if(lua_gettop(L) > 2)
neglect_loc = lua_toboolean(L, 3);
lua_pushboolean(L, peffect->is_activateable(playerid, peffect->pduel->game_field->nil_event, 0, 0, 0, neglect_loc));
return 1;
}
int32 scriptlib::effect_is_activated(lua_State * L) {
......
......@@ -15,11 +15,11 @@
#include "interpreter.h"
#include <set>
script_reader sreader = default_script_reader;
card_reader creader = default_card_reader;
message_handler mhandler = default_message_handler;
byte buffer[0x10000];
std::set<duel*> duel_set;
static script_reader sreader = default_script_reader;
static card_reader creader = default_card_reader;
static message_handler mhandler = default_message_handler;
static byte buffer[0x20000];
static std::set<duel*> duel_set;
extern "C" DECL_DLLEXPORT void set_script_reader(script_reader f) {
sreader = f;
......@@ -46,7 +46,7 @@ byte* default_script_reader(const char* script_name, int* slen) {
return 0;
fseek(fp, 0, SEEK_END);
uint32 len = ftell(fp);
if (len > 0x10000) {
if (len > sizeof(buffer)) {
fclose(fp);
return 0;
}
......@@ -70,7 +70,14 @@ extern "C" DECL_DLLEXPORT ptr create_duel(uint32 seed) {
}
extern "C" DECL_DLLEXPORT void start_duel(ptr pduel, int options) {
duel* pd = (duel*)pduel;
pd->game_field->core.duel_options |= options;
pd->game_field->core.duel_options |= options & 0xffff;
int32 duel_rule = options >> 16;
if(duel_rule)
pd->game_field->core.duel_rule = duel_rule;
else if(options & DUEL_OBSOLETE_RULING) //provide backward compatibility with replay
pd->game_field->core.duel_rule = 1;
else if(!pd->game_field->core.duel_rule)
pd->game_field->core.duel_rule = 3;
pd->game_field->core.shuffle_hand_check[0] = FALSE;
pd->game_field->core.shuffle_hand_check[1] = FALSE;
pd->game_field->core.shuffle_deck_check[0] = FALSE;
......@@ -212,26 +219,27 @@ extern "C" DECL_DLLEXPORT int32 query_field_count(ptr pduel, uint8 playerid, uin
duel* ptduel = (duel*)pduel;
if(playerid != 0 && playerid != 1)
return 0;
auto& player = ptduel->game_field->player[playerid];
if(location == LOCATION_HAND)
return ptduel->game_field->player[playerid].list_hand.size();
return player.list_hand.size();
if(location == LOCATION_GRAVE)
return ptduel->game_field->player[playerid].list_grave.size();
return player.list_grave.size();
if(location == LOCATION_REMOVED)
return ptduel->game_field->player[playerid].list_remove.size();
return player.list_remove.size();
if(location == LOCATION_EXTRA)
return ptduel->game_field->player[playerid].list_extra.size();
return player.list_extra.size();
if(location == LOCATION_DECK)
return ptduel->game_field->player[playerid].list_main.size();
return player.list_main.size();
if(location == LOCATION_MZONE) {
uint32 count = 0;
for(uint32 i = 0; i < 5; ++i)
if(ptduel->game_field->player[playerid].list_mzone[i]) count++;
for(auto cit = player.list_mzone.begin(); cit != player.list_mzone.end(); ++cit)
if(*cit) count++;
return count;
}
if(location == LOCATION_SZONE) {
uint32 count = 0;
for(uint32 i = 0; i < 8; ++i)
if(ptduel->game_field->player[playerid].list_szone[i]) count++;
for(auto cit = player.list_szone.begin(); cit != player.list_szone.end(); ++cit)
if(*cit) count++;
return count;
}
return 0;
......@@ -240,12 +248,12 @@ extern "C" DECL_DLLEXPORT int32 query_field_card(ptr pduel, uint8 playerid, uint
if(playerid != 0 && playerid != 1)
return 0;
duel* ptduel = (duel*)pduel;
card* pcard;
auto& player = ptduel->game_field->player[playerid];
uint32 ct = 0, clen;
byte* p = buf;
if(location == LOCATION_MZONE) {
for(uint32 i = 0; i < 5; ++i) {
pcard = ptduel->game_field->player[playerid].list_mzone[i];
for(auto cit = player.list_mzone.begin(); cit != player.list_mzone.end(); ++cit) {
card* pcard = *cit;
if(pcard) {
ct += clen = pcard->get_infos(p, query_flag, use_cache);
p += clen;
......@@ -256,8 +264,8 @@ extern "C" DECL_DLLEXPORT int32 query_field_card(ptr pduel, uint8 playerid, uint
}
}
} else if(location == LOCATION_SZONE) {
for(uint32 i = 0; i < 8; ++i) {
pcard = ptduel->game_field->player[playerid].list_szone[i];
for(auto cit = player.list_szone.begin(); cit != player.list_szone.end(); ++cit) {
card* pcard = *cit;
if(pcard) {
ct += clen = pcard->get_infos(p, query_flag, use_cache);
p += clen;
......@@ -270,15 +278,15 @@ extern "C" DECL_DLLEXPORT int32 query_field_card(ptr pduel, uint8 playerid, uint
} else {
field::card_vector* lst;
if(location == LOCATION_HAND)
lst = &ptduel->game_field->player[playerid].list_hand;
lst = &player.list_hand;
else if(location == LOCATION_GRAVE)
lst = &ptduel->game_field->player[playerid].list_grave;
lst = &player.list_grave;
else if(location == LOCATION_REMOVED)
lst = &ptduel->game_field->player[playerid].list_remove;
lst = &player.list_remove;
else if(location == LOCATION_EXTRA)
lst = &ptduel->game_field->player[playerid].list_extra;
lst = &player.list_extra;
else if(location == LOCATION_DECK)
lst = &ptduel->game_field->player[playerid].list_main;
lst = &player.list_main;
for(auto cit = lst->begin(); cit != lst->end(); ++cit) {
ct += clen = (*cit)->get_infos(p, query_flag, use_cache);
p += clen;
......@@ -289,12 +297,13 @@ extern "C" DECL_DLLEXPORT int32 query_field_card(ptr pduel, uint8 playerid, uint
extern "C" DECL_DLLEXPORT int32 query_field_info(ptr pduel, byte* buf) {
duel* ptduel = (duel*)pduel;
*buf++ = MSG_RELOAD_FIELD;
card* pcard;
*buf++ = ptduel->game_field->core.duel_rule;
for(int playerid = 0; playerid < 2; ++playerid) {
*((int*)(buf)) = ptduel->game_field->player[playerid].lp;
auto& player = ptduel->game_field->player[playerid];
*((int*)(buf)) = player.lp;
buf += 4;
for(uint32 i = 0; i < 5; ++i) {
pcard = ptduel->game_field->player[playerid].list_mzone[i];
for(auto cit = player.list_mzone.begin(); cit != player.list_mzone.end(); ++cit) {
card* pcard = *cit;
if(pcard) {
*buf++ = 1;
*buf++ = pcard->current.position;
......@@ -303,8 +312,8 @@ extern "C" DECL_DLLEXPORT int32 query_field_info(ptr pduel, byte* buf) {
*buf++ = 0;
}
}
for(uint32 i = 0; i < 8; ++i) {
pcard = ptduel->game_field->player[playerid].list_szone[i];
for(auto cit = player.list_szone.begin(); cit != player.list_szone.end(); ++cit) {
card* pcard = *cit;
if(pcard) {
*buf++ = 1;
*buf++ = pcard->current.position;
......@@ -312,12 +321,12 @@ extern "C" DECL_DLLEXPORT int32 query_field_info(ptr pduel, byte* buf) {
*buf++ = 0;
}
}
*buf++ = ptduel->game_field->player[playerid].list_main.size();
*buf++ = ptduel->game_field->player[playerid].list_hand.size();
*buf++ = ptduel->game_field->player[playerid].list_grave.size();
*buf++ = ptduel->game_field->player[playerid].list_remove.size();
*buf++ = ptduel->game_field->player[playerid].list_extra.size();
*buf++ = ptduel->game_field->player[playerid].extra_p_count;
*buf++ = player.list_main.size();
*buf++ = player.list_hand.size();
*buf++ = player.list_grave.size();
*buf++ = player.list_remove.size();
*buf++ = player.list_extra.size();
*buf++ = player.extra_p_count;
}
*buf++ = ptduel->game_field->core.current_chain.size();
for(auto chit = ptduel->game_field->core.current_chain.begin(); chit != ptduel->game_field->core.current_chain.end(); ++chit) {
......@@ -327,7 +336,7 @@ extern "C" DECL_DLLEXPORT int32 query_field_info(ptr pduel, byte* buf) {
*((int*)(buf)) = peffect->get_handler()->get_info_location();
buf += 4;
*buf++ = chit->triggering_controler;
*buf++ = chit->triggering_location;
*buf++ = (uint8)chit->triggering_location;
*buf++ = chit->triggering_sequence;
*((int*)(buf)) = peffect->description;
buf += 4;
......
This diff is collapsed.
......@@ -336,10 +336,10 @@ int32 field::select_place(uint16 step, uint8 playerid, uint32 flag, uint8 count)
flag = ~flag;
int32 filter;
int32 pzone = 0;
if(flag & 0x1f) {
if(flag & 0x7f) {
returns.bvalue[0] = 1;
returns.bvalue[1] = LOCATION_MZONE;
filter = flag & 0x1f;
filter = flag & 0x7f;
} else if(flag & 0x1f00) {
returns.bvalue[0] = 1;
returns.bvalue[1] = LOCATION_SZONE;
......@@ -349,10 +349,10 @@ int32 field::select_place(uint16 step, uint8 playerid, uint32 flag, uint8 count)
returns.bvalue[1] = LOCATION_SZONE;
filter = (flag >> 14) & 0x3;
pzone = 1;
} else if(flag & 0x1f0000) {
} else if(flag & 0x7f0000) {
returns.bvalue[0] = 0;
returns.bvalue[1] = LOCATION_MZONE;
filter = (flag >> 16) & 0x1f;
filter = (flag >> 16) & 0x7f;
} else if(flag & 0x1f000000) {
returns.bvalue[0] = 0;
returns.bvalue[1] = LOCATION_SZONE;
......@@ -364,7 +364,9 @@ int32 field::select_place(uint16 step, uint8 playerid, uint32 flag, uint8 count)
pzone = 1;
}
if(!pzone) {
if(filter & 0x4) returns.bvalue[2] = 2;
if(filter & 0x40) returns.bvalue[2] = 6;
else if(filter & 0x20) returns.bvalue[2] = 5;
else if(filter & 0x4) returns.bvalue[2] = 2;
else if(filter & 0x2) returns.bvalue[2] = 1;
else if(filter & 0x8) returns.bvalue[2] = 3;
else if(filter & 0x1) returns.bvalue[2] = 0;
......@@ -500,22 +502,21 @@ int32 field::select_counter(uint16 step, uint8 playerid, uint16 countertype, uin
if(step == 0) {
if(count == 0)
return TRUE;
card* pcard;
uint8 avail = s;
uint8 fp = playerid;
uint32 total = 0;
core.select_cards.clear();
for(int p = 0; p < 2; ++p) {
if(avail) {
for(int j = 0; j < 5; ++j) {
pcard = player[fp].list_mzone[j];
for(auto cit = player[fp].list_mzone.begin(); cit != player[fp].list_mzone.end(); ++cit) {
card* pcard = *cit;
if(pcard && pcard->get_counter(countertype)) {
core.select_cards.push_back(pcard);
total += pcard->get_counter(countertype);
}
}
for(int j = 0; j < 8; ++j) {
pcard = player[fp].list_szone[j];
for(auto cit = player[fp].list_szone.begin(); cit != player[fp].list_szone.end(); ++cit) {
card* pcard = *cit;
if(pcard && pcard->get_counter(countertype)) {
core.select_cards.push_back(pcard);
total += pcard->get_counter(countertype);
......@@ -536,7 +537,7 @@ int32 field::select_counter(uint16 step, uint8 playerid, uint16 countertype, uin
pduel->write_buffer8(core.select_cards.size());
std::sort(core.select_cards.begin(), core.select_cards.end(), card::card_operation_sort);
for(uint32 i = 0; i < core.select_cards.size(); ++i) {
pcard = core.select_cards[i];
card* pcard = core.select_cards[i];
pduel->write_buffer32(pcard->data.code);
pduel->write_buffer8(pcard->current.controler);
pduel->write_buffer8(pcard->current.location);
......
This diff is collapsed.
This diff is collapsed.
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