Commit c1b1fc2c authored by Chen Bill's avatar Chen Bill Committed by GitHub

do not load script for normal monsters (#605)

* add scope operator

* add card_data::get_original_code

* do not load script for normal monsters

* add const INTERNAL_FLAGS

* use luaL_checkstack in scriptlib

* update enum LuaParamType

* use luaL_loadbuffer in load_script

* fix warning
parent 03c81af7
...@@ -431,10 +431,7 @@ uint32 card::get_info_location() { ...@@ -431,10 +431,7 @@ uint32 card::get_info_location() {
} }
// get the printed code on card // get the printed code on card
uint32 card::get_original_code() const { uint32 card::get_original_code() const {
if (data.is_alternative()) return data.get_original_code();
return data.alias;
else
return data.code;
} }
// get the original code in duel (can be different from printed code) // get the original code in duel (can be different from printed code)
std::tuple<uint32, uint32> card::get_original_code_rule() const { std::tuple<uint32, uint32> card::get_original_code_rule() const {
...@@ -1980,7 +1977,7 @@ void card::remove_effect(effect* peffect, effect_container::iterator it) { ...@@ -1980,7 +1977,7 @@ void card::remove_effect(effect* peffect, effect_container::iterator it) {
} }
if (peffect->is_flag(EFFECT_FLAG_INITIAL) && peffect->copy_id && is_status(STATUS_EFFECT_REPLACED)) { if (peffect->is_flag(EFFECT_FLAG_INITIAL) && peffect->copy_id && is_status(STATUS_EFFECT_REPLACED)) {
set_status(STATUS_EFFECT_REPLACED, FALSE); set_status(STATUS_EFFECT_REPLACED, FALSE);
if (!(data.type & TYPE_NORMAL) || (data.type & TYPE_PENDULUM)) { if (interpreter::is_load_script(data)) {
set_status(STATUS_INITIALIZING, TRUE); set_status(STATUS_INITIALIZING, TRUE);
pduel->lua->add_param(this, PARAM_TYPE_CARD); pduel->lua->add_param(this, PARAM_TYPE_CARD);
pduel->lua->call_card_function(this, "initial_effect", 1, 0); pduel->lua->call_card_function(this, "initial_effect", 1, 0);
......
...@@ -67,6 +67,10 @@ struct card_data { ...@@ -67,6 +67,10 @@ struct card_data {
for (int i = ctr; i < SIZE_SETCODE; ++i) for (int i = ctr; i < SIZE_SETCODE; ++i)
setcode[i] = 0; setcode[i] = 0;
} }
uint32 get_original_code() const {
return is_alternative() ? alias : code;
}
}; };
#endif /* CARD_DATA_H_ */ #endif /* CARD_DATA_H_ */
...@@ -213,10 +213,10 @@ enum effect_flag2 : uint32 { ...@@ -213,10 +213,10 @@ enum effect_flag2 : uint32 {
EFFECT_FLAG2_WICKED = 0x0004, EFFECT_FLAG2_WICKED = 0x0004,
EFFECT_FLAG2_OPTION = 0x0008, EFFECT_FLAG2_OPTION = 0x0008,
}; };
inline effect_flag operator|(effect_flag flag1, effect_flag flag2) constexpr effect_flag operator|(effect_flag flag1, effect_flag flag2) {
{
return static_cast<effect_flag>(static_cast<uint32>(flag1) | static_cast<uint32>(flag2)); return static_cast<effect_flag>(static_cast<uint32>(flag1) | static_cast<uint32>(flag2));
} }
constexpr uint32 INTERNAL_FLAGS = EFFECT_FLAG_INITIAL | EFFECT_FLAG_FUNC_VALUE | EFFECT_FLAG_COUNT_LIMIT | EFFECT_FLAG_FIELD_ONLY | EFFECT_FLAG_ABSOLUTE_TARGET;
//========== Codes ========== //========== Codes ==========
#define EFFECT_IMMUNE_EFFECT 1 // #define EFFECT_IMMUNE_EFFECT 1 //
#define EFFECT_DISABLE 2 // #define EFFECT_DISABLE 2 //
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
*/ */
#include <cstring> #include <cstring>
#include <utility>
#include "duel.h" #include "duel.h"
#include "group.h" #include "group.h"
#include "card.h" #include "card.h"
...@@ -50,23 +49,19 @@ interpreter::~interpreter() { ...@@ -50,23 +49,19 @@ interpreter::~interpreter() {
int32 interpreter::register_card(card *pcard) { int32 interpreter::register_card(card *pcard) {
//create a card in by userdata //create a card in by userdata
luaL_checkstack(lua_state, 1, nullptr); luaL_checkstack(lua_state, 1, nullptr);
luaL_checkstack(current_state, 1, nullptr);
card ** ppcard = (card**) lua_newuserdata(lua_state, sizeof(card*)); //+1 userdata card ** ppcard = (card**) lua_newuserdata(lua_state, sizeof(card*)); //+1 userdata
*ppcard = pcard; *ppcard = pcard;
pcard->ref_handle = luaL_ref(lua_state, LUA_REGISTRYINDEX); //-1 pcard->ref_handle = luaL_ref(lua_state, LUA_REGISTRYINDEX); //-1
//some userdata may be created in script like token so use current_state //some userdata may be created in script like token so use current_state
luaL_checkstack(current_state, 1, nullptr);
lua_rawgeti(current_state, LUA_REGISTRYINDEX, pcard->ref_handle); //+1 userdata lua_rawgeti(current_state, LUA_REGISTRYINDEX, pcard->ref_handle); //+1 userdata
//load script load_card_script(pcard->data.get_original_code());
if(pcard->data.is_alternative())
load_card_script(pcard->data.alias);
else
load_card_script(pcard->data.code);
//stack: table cxxx, userdata //stack: table cxxx, userdata
//set metatable of pointer to base script //set metatable of pointer to base script
lua_setmetatable(current_state, -2); //-1 lua_setmetatable(current_state, -2); //-1
lua_pop(current_state, 1); //-1 lua_pop(current_state, 1); //-1
//Initial //Initial
if(pcard->data.code && (!(pcard->data.type & TYPE_NORMAL) || (pcard->data.type & TYPE_PENDULUM))) { if(pcard->data.code && is_load_script(pcard->data)) {
pcard->set_status(STATUS_INITIALIZING, TRUE); pcard->set_status(STATUS_INITIALIZING, TRUE);
add_param(pcard, PARAM_TYPE_CARD); add_param(pcard, PARAM_TYPE_CARD);
call_card_function(pcard, "initial_effect", 1, 0); call_card_function(pcard, "initial_effect", 1, 0);
...@@ -78,7 +73,7 @@ int32 interpreter::register_card(card *pcard) { ...@@ -78,7 +73,7 @@ int32 interpreter::register_card(card *pcard) {
void interpreter::register_effect(effect *peffect) { void interpreter::register_effect(effect *peffect) {
if (!peffect) if (!peffect)
return; return;
//create a effect in by userdata //create a effect in userdata
luaL_checkstack(lua_state, 3, nullptr); luaL_checkstack(lua_state, 3, nullptr);
effect ** ppeffect = (effect**) lua_newuserdata(lua_state, sizeof(effect*)); effect ** ppeffect = (effect**) lua_newuserdata(lua_state, sizeof(effect*));
*ppeffect = peffect; *ppeffect = peffect;
...@@ -127,11 +122,12 @@ void interpreter::unregister_group(group *pgroup) { ...@@ -127,11 +122,12 @@ void interpreter::unregister_group(group *pgroup) {
} }
int32 interpreter::load_script(const char* script_name) { int32 interpreter::load_script(const char* script_name) {
int32 len = 0; int32 len = 0;
byte* buffer = read_script(script_name, &len); byte* buffer = ::read_script(script_name, &len);
if (!buffer) if (!buffer)
return OPERATION_FAIL; return OPERATION_FAIL;
++no_action; ++no_action;
int32 error = luaL_loadbuffer(current_state, (char*)buffer, len, script_name) || lua_pcall(current_state, 0, 0, 0); luaL_checkstack(current_state, 2, nullptr);
int32 error = luaL_loadbuffer(current_state, (const char*)buffer, len, script_name) || lua_pcall(current_state, 0, 0, 0);
if (error) { if (error) {
sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1)); sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1));
handle_message(pduel, 1); handle_message(pduel, 1);
...@@ -142,12 +138,12 @@ int32 interpreter::load_script(const char* script_name) { ...@@ -142,12 +138,12 @@ int32 interpreter::load_script(const char* script_name) {
--no_action; --no_action;
return OPERATION_SUCCESS; return OPERATION_SUCCESS;
} }
//push table cxxx onto the stack of current_state
int32 interpreter::load_card_script(uint32 code) { int32 interpreter::load_card_script(uint32 code) {
char class_name[20]; char class_name[20];
sprintf(class_name, "c%d", code); sprintf(class_name, "c%d", code);
luaL_checkstack(current_state, 1, nullptr); luaL_checkstack(current_state, 1, nullptr);
lua_getglobal(current_state, class_name); //+1 table cxxx lua_getglobal(current_state, class_name); //+1 table cxxx
//if script is not loaded, create and load it
if (lua_isnil(current_state, -1)) { if (lua_isnil(current_state, -1)) {
luaL_checkstack(current_state, 5, nullptr); luaL_checkstack(current_state, 5, nullptr);
lua_pop(current_state, 1); //-1 lua_pop(current_state, 1); //-1
...@@ -160,17 +156,22 @@ int32 interpreter::load_card_script(uint32 code) { ...@@ -160,17 +156,22 @@ int32 interpreter::load_card_script(uint32 code) {
lua_pushstring(current_state, "__index"); //+1 "__index", table cxxx lua_pushstring(current_state, "__index"); //+1 "__index", table cxxx
lua_pushvalue(current_state, -2); //+1 table cxxx, "__index", table cxxx lua_pushvalue(current_state, -2); //+1 table cxxx, "__index", table cxxx
lua_rawset(current_state, -3); //-2 table cxxx lua_rawset(current_state, -3); //-2 table cxxx
card_data cdata;
int32 res = OPERATION_SUCCESS;
::read_card(code, &cdata);
if (is_load_script(cdata)) {
lua_getglobal(current_state, class_name); //+1 lua_getglobal(current_state, class_name); //+1
lua_setglobal(current_state, "self_table"); //-1 lua_setglobal(current_state, "self_table"); //-1
lua_pushinteger(current_state, code); //+1 lua_pushinteger(current_state, code); //+1
lua_setglobal(current_state, "self_code"); //-1 lua_setglobal(current_state, "self_code"); //-1
char script_name[64]; char script_name[64];
sprintf(script_name, "./script/c%d.lua", code); sprintf(script_name, "./script/c%d.lua", code);
int32 res = load_script(script_name); res = load_script(script_name);
lua_pushnil(current_state); //+1 lua_pushnil(current_state); //+1
lua_setglobal(current_state, "self_table"); //-1 lua_setglobal(current_state, "self_table"); //-1
lua_pushnil(current_state); //+1 lua_pushnil(current_state); //+1
lua_setglobal(current_state, "self_code"); //-1 table cxxx {__index: cxxx } lua_setglobal(current_state, "self_code"); //-1 table cxxx {__index: cxxx }
}
if(!res) { if(!res) {
return OPERATION_FAIL; return OPERATION_FAIL;
} }
...@@ -298,7 +299,7 @@ int32 interpreter::call_function(int32 f, uint32 param_count, int32 ret_count) { ...@@ -298,7 +299,7 @@ int32 interpreter::call_function(int32 f, uint32 param_count, int32 ret_count) {
} }
int32 interpreter::call_card_function(card* pcard, const char* f, uint32 param_count, int32 ret_count) { int32 interpreter::call_card_function(card* pcard, const char* f, uint32 param_count, int32 ret_count) {
if (param_count != params.size()) { if (param_count != params.size()) {
sprintf(pduel->strbuffer, "\"CallCardFunction\"(c%d.%s): incorrect parameter count", pcard->data.code, f); sprintf(pduel->strbuffer, "\"CallCardFunction\"(c%d.%s): incorrect parameter count", pcard->data.get_original_code(), f);
handle_message(pduel, 1); handle_message(pduel, 1);
params.clear(); params.clear();
return OPERATION_FAIL; return OPERATION_FAIL;
...@@ -307,7 +308,7 @@ int32 interpreter::call_card_function(card* pcard, const char* f, uint32 param_c ...@@ -307,7 +308,7 @@ int32 interpreter::call_card_function(card* pcard, const char* f, uint32 param_c
luaL_checkstack(current_state, 1, nullptr); luaL_checkstack(current_state, 1, nullptr);
lua_getfield(current_state, -1, f); lua_getfield(current_state, -1, f);
if (!lua_isfunction(current_state, -1)) { if (!lua_isfunction(current_state, -1)) {
sprintf(pduel->strbuffer, "\"CallCardFunction\"(c%d.%s): attempt to call an error function", pcard->data.code, f); sprintf(pduel->strbuffer, "\"CallCardFunction\"(c%d.%s): attempt to call an error function", pcard->data.get_original_code(), f);
handle_message(pduel, 1); handle_message(pduel, 1);
lua_pop(current_state, 2); lua_pop(current_state, 2);
params.clear(); params.clear();
...@@ -582,7 +583,8 @@ int32 interpreter::call_coroutine(int32 f, uint32 param_count, int32* yield_valu ...@@ -582,7 +583,8 @@ int32 interpreter::call_coroutine(int32 f, uint32 param_count, int32* yield_valu
push_param(rthread, true); push_param(rthread, true);
int32 result = 0, nresults = 0; int32 result = 0, nresults = 0;
{ {
auto prev_state = std::exchange(current_state, rthread); auto prev_state = current_state;
current_state = rthread;
#if (LUA_VERSION_NUM >= 504) #if (LUA_VERSION_NUM >= 504)
result = lua_resume(rthread, prev_state, param_count, &nresults); result = lua_resume(rthread, prev_state, param_count, &nresults);
#else #else
...@@ -631,7 +633,7 @@ void* interpreter::get_ref_object(int32 ref_handler) { ...@@ -631,7 +633,7 @@ void* interpreter::get_ref_object(int32 ref_handler) {
lua_pop(current_state, 1); lua_pop(current_state, 1);
return p; return p;
} }
//push the object onto the stack, +1 //push the object onto the stack of L, +1
void interpreter::card2value(lua_State* L, card* pcard) { void interpreter::card2value(lua_State* L, card* pcard) {
luaL_checkstack(L, 1, nullptr); luaL_checkstack(L, 1, nullptr);
if (!pcard || pcard->ref_handle == 0) if (!pcard || pcard->ref_handle == 0)
...@@ -671,3 +673,6 @@ duel* interpreter::get_duel_info(lua_State * L) { ...@@ -671,3 +673,6 @@ duel* interpreter::get_duel_info(lua_State * L) {
std::memcpy(&pduel, lua_getextraspace(L), LUA_EXTRASPACE); std::memcpy(&pduel, lua_getextraspace(L), LUA_EXTRASPACE);
return pduel; return pduel;
} }
inline bool interpreter::is_load_script(card_data data) {
return !(data.type & TYPE_NORMAL) || (data.type & TYPE_PENDULUM);
}
...@@ -18,11 +18,12 @@ ...@@ -18,11 +18,12 @@
#include <cstdio> #include <cstdio>
class card; class card;
struct card_data;
class effect; class effect;
class group; class group;
class duel; class duel;
enum LuaParamType { enum LuaParamType : int32 {
PARAM_TYPE_INT = 0x01, PARAM_TYPE_INT = 0x01,
PARAM_TYPE_STRING = 0x02, PARAM_TYPE_STRING = 0x02,
PARAM_TYPE_CARD = 0x04, PARAM_TYPE_CARD = 0x04,
...@@ -84,6 +85,7 @@ public: ...@@ -84,6 +85,7 @@ public:
static void function2value(lua_State* L, int32 func_ref); static void function2value(lua_State* L, int32 func_ref);
static int32 get_function_handle(lua_State* L, int32 index); static int32 get_function_handle(lua_State* L, int32 index);
static duel* get_duel_info(lua_State* L); static duel* get_duel_info(lua_State* L);
static bool is_load_script(card_data data);
template <size_t N, typename... TR> template <size_t N, typename... TR>
static int sprintf(char (&buffer)[N], const char* format, TR... args) { static int sprintf(char (&buffer)[N], const char* format, TR... args) {
......
...@@ -4248,8 +4248,7 @@ int32 scriptlib::duel_is_player_can_draw(lua_State * L) { ...@@ -4248,8 +4248,7 @@ int32 scriptlib::duel_is_player_can_draw(lua_State * L) {
if(count == 0) if(count == 0)
lua_pushboolean(L, pduel->game_field->is_player_can_draw(playerid)); lua_pushboolean(L, pduel->game_field->is_player_can_draw(playerid));
else else
lua_pushboolean(L, pduel->game_field->is_player_can_draw(playerid) lua_pushboolean(L, (int)(pduel->game_field->is_player_can_draw(playerid) && (pduel->game_field->player[playerid].list_main.size() >= count)));
&& (pduel->game_field->player[playerid].list_main.size() >= count));
return 1; return 1;
} }
int32 scriptlib::duel_is_player_can_discard_deck(lua_State * L) { int32 scriptlib::duel_is_player_can_discard_deck(lua_State * L) {
......
...@@ -169,7 +169,7 @@ int32 scriptlib::effect_set_property(lua_State *L) { ...@@ -169,7 +169,7 @@ int32 scriptlib::effect_set_property(lua_State *L) {
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 v1 = (uint32)lua_tointeger(L, 2); uint32 v1 = (uint32)lua_tointeger(L, 2);
uint32 v2 = (uint32)lua_tointeger(L, 3); uint32 v2 = (uint32)lua_tointeger(L, 3);
peffect->flag[0] = (peffect->flag[0] & 0x4f) | (v1 & ~0x4f); peffect->flag[0] = (peffect->flag[0] & INTERNAL_FLAGS) | (v1 & ~INTERNAL_FLAGS);
peffect->flag[1] = v2; peffect->flag[1] = v2;
return 0; return 0;
} }
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include "duel.h" #include "duel.h"
static int32 check_data_type(lua_State* L, int32 index, const char* tname) { static int32 check_data_type(lua_State* L, int32 index, const char* tname) {
luaL_checkstack(L, 2, nullptr);
int32 result = FALSE; int32 result = FALSE;
if(lua_getmetatable(L, index)) { if(lua_getmetatable(L, index)) {
lua_getglobal(L, tname); lua_getglobal(L, tname);
...@@ -20,6 +21,7 @@ static int32 check_data_type(lua_State* L, int32 index, const char* tname) { ...@@ -20,6 +21,7 @@ static int32 check_data_type(lua_State* L, int32 index, const char* tname) {
int32 scriptlib::check_param(lua_State* L, int32 param_type, int32 index, int32 retfalse) { int32 scriptlib::check_param(lua_State* L, int32 param_type, int32 index, int32 retfalse) {
switch (param_type) { switch (param_type) {
case PARAM_TYPE_CARD: { case PARAM_TYPE_CARD: {
luaL_checkstack(L, 1, nullptr);
int32 result = FALSE; int32 result = FALSE;
if(lua_isuserdata(L, index) && lua_getmetatable(L, index)) { if(lua_isuserdata(L, index) && lua_getmetatable(L, index)) {
result = check_data_type(L, -1, "Card"); result = check_data_type(L, -1, "Card");
......
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