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() {
}
// get the printed code on card
uint32 card::get_original_code() const {
if (data.is_alternative())
return data.alias;
else
return data.code;
return data.get_original_code();
}
// get the original code in duel (can be different from printed code)
std::tuple<uint32, uint32> card::get_original_code_rule() const {
......@@ -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)) {
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);
pduel->lua->add_param(this, PARAM_TYPE_CARD);
pduel->lua->call_card_function(this, "initial_effect", 1, 0);
......
......@@ -67,6 +67,10 @@ struct card_data {
for (int i = ctr; i < SIZE_SETCODE; ++i)
setcode[i] = 0;
}
uint32 get_original_code() const {
return is_alternative() ? alias : code;
}
};
#endif /* CARD_DATA_H_ */
......@@ -213,10 +213,10 @@ enum effect_flag2 : uint32 {
EFFECT_FLAG2_WICKED = 0x0004,
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));
}
constexpr uint32 INTERNAL_FLAGS = EFFECT_FLAG_INITIAL | EFFECT_FLAG_FUNC_VALUE | EFFECT_FLAG_COUNT_LIMIT | EFFECT_FLAG_FIELD_ONLY | EFFECT_FLAG_ABSOLUTE_TARGET;
//========== Codes ==========
#define EFFECT_IMMUNE_EFFECT 1 //
#define EFFECT_DISABLE 2 //
......
......@@ -6,7 +6,6 @@
*/
#include <cstring>
#include <utility>
#include "duel.h"
#include "group.h"
#include "card.h"
......@@ -50,23 +49,19 @@ interpreter::~interpreter() {
int32 interpreter::register_card(card *pcard) {
//create a card in by userdata
luaL_checkstack(lua_state, 1, nullptr);
luaL_checkstack(current_state, 1, nullptr);
card ** ppcard = (card**) lua_newuserdata(lua_state, sizeof(card*)); //+1 userdata
*ppcard = pcard;
pcard->ref_handle = luaL_ref(lua_state, LUA_REGISTRYINDEX); //-1
//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
//load script
if(pcard->data.is_alternative())
load_card_script(pcard->data.alias);
else
load_card_script(pcard->data.code);
load_card_script(pcard->data.get_original_code());
//stack: table cxxx, userdata
//set metatable of pointer to base script
lua_setmetatable(current_state, -2); //-1
lua_pop(current_state, 1); //-1
//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);
add_param(pcard, PARAM_TYPE_CARD);
call_card_function(pcard, "initial_effect", 1, 0);
......@@ -78,7 +73,7 @@ int32 interpreter::register_card(card *pcard) {
void interpreter::register_effect(effect *peffect) {
if (!peffect)
return;
//create a effect in by userdata
//create a effect in userdata
luaL_checkstack(lua_state, 3, nullptr);
effect ** ppeffect = (effect**) lua_newuserdata(lua_state, sizeof(effect*));
*ppeffect = peffect;
......@@ -127,11 +122,12 @@ void interpreter::unregister_group(group *pgroup) {
}
int32 interpreter::load_script(const char* script_name) {
int32 len = 0;
byte* buffer = read_script(script_name, &len);
byte* buffer = ::read_script(script_name, &len);
if (!buffer)
return OPERATION_FAIL;
++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) {
sprintf(pduel->strbuffer, "%s", lua_tostring(current_state, -1));
handle_message(pduel, 1);
......@@ -142,12 +138,12 @@ int32 interpreter::load_script(const char* script_name) {
--no_action;
return OPERATION_SUCCESS;
}
//push table cxxx onto the stack of current_state
int32 interpreter::load_card_script(uint32 code) {
char class_name[20];
sprintf(class_name, "c%d", code);
luaL_checkstack(current_state, 1, nullptr);
lua_getglobal(current_state, class_name); //+1 table cxxx
//if script is not loaded, create and load it
if (lua_isnil(current_state, -1)) {
luaL_checkstack(current_state, 5, nullptr);
lua_pop(current_state, 1); //-1
......@@ -160,17 +156,22 @@ int32 interpreter::load_card_script(uint32 code) {
lua_pushstring(current_state, "__index"); //+1 "__index", table cxxx
lua_pushvalue(current_state, -2); //+1 table cxxx, "__index", 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_setglobal(current_state, "self_table"); //-1
lua_pushinteger(current_state, code); //+1
lua_setglobal(current_state, "self_code"); //-1
char script_name[64];
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_setglobal(current_state, "self_table"); //-1
lua_pushnil(current_state); //+1
lua_setglobal(current_state, "self_code"); //-1 table cxxx {__index: cxxx }
}
if(!res) {
return OPERATION_FAIL;
}
......@@ -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) {
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);
params.clear();
return OPERATION_FAIL;
......@@ -307,7 +308,7 @@ int32 interpreter::call_card_function(card* pcard, const char* f, uint32 param_c
luaL_checkstack(current_state, 1, nullptr);
lua_getfield(current_state, -1, f);
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);
lua_pop(current_state, 2);
params.clear();
......@@ -582,7 +583,8 @@ int32 interpreter::call_coroutine(int32 f, uint32 param_count, int32* yield_valu
push_param(rthread, true);
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)
result = lua_resume(rthread, prev_state, param_count, &nresults);
#else
......@@ -631,7 +633,7 @@ void* interpreter::get_ref_object(int32 ref_handler) {
lua_pop(current_state, 1);
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) {
luaL_checkstack(L, 1, nullptr);
if (!pcard || pcard->ref_handle == 0)
......@@ -671,3 +673,6 @@ duel* interpreter::get_duel_info(lua_State * L) {
std::memcpy(&pduel, lua_getextraspace(L), LUA_EXTRASPACE);
return pduel;
}
inline bool interpreter::is_load_script(card_data data) {
return !(data.type & TYPE_NORMAL) || (data.type & TYPE_PENDULUM);
}
......@@ -18,11 +18,12 @@
#include <cstdio>
class card;
struct card_data;
class effect;
class group;
class duel;
enum LuaParamType {
enum LuaParamType : int32 {
PARAM_TYPE_INT = 0x01,
PARAM_TYPE_STRING = 0x02,
PARAM_TYPE_CARD = 0x04,
......@@ -84,6 +85,7 @@ public:
static void function2value(lua_State* L, int32 func_ref);
static int32 get_function_handle(lua_State* L, int32 index);
static duel* get_duel_info(lua_State* L);
static bool is_load_script(card_data data);
template <size_t N, typename... TR>
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) {
if(count == 0)
lua_pushboolean(L, pduel->game_field->is_player_can_draw(playerid));
else
lua_pushboolean(L, pduel->game_field->is_player_can_draw(playerid)
&& (pduel->game_field->player[playerid].list_main.size() >= count));
lua_pushboolean(L, (int)(pduel->game_field->is_player_can_draw(playerid) && (pduel->game_field->player[playerid].list_main.size() >= count)));
return 1;
}
int32 scriptlib::duel_is_player_can_discard_deck(lua_State * L) {
......
......@@ -169,7 +169,7 @@ int32 scriptlib::effect_set_property(lua_State *L) {
effect* peffect = *(effect**) lua_touserdata(L, 1);
uint32 v1 = (uint32)lua_tointeger(L, 2);
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;
return 0;
}
......
......@@ -8,6 +8,7 @@
#include "duel.h"
static int32 check_data_type(lua_State* L, int32 index, const char* tname) {
luaL_checkstack(L, 2, nullptr);
int32 result = FALSE;
if(lua_getmetatable(L, index)) {
lua_getglobal(L, 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) {
switch (param_type) {
case PARAM_TYPE_CARD: {
luaL_checkstack(L, 1, nullptr);
int32 result = FALSE;
if(lua_isuserdata(L, index) && lua_getmetatable(L, index)) {
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