Commit 7a70bf03 authored by VanillaSalt's avatar VanillaSalt

add EFFECT_TYPE_GRANT

parent be07da20
...@@ -689,9 +689,29 @@ int32 effect::get_speed() { ...@@ -689,9 +689,29 @@ int32 effect::get_speed() {
} }
return 0; return 0;
} }
effect* effect::clone() {
effect* ceffect = pduel->new_effect();
int32 ref = ceffect->ref_handle;
*ceffect = *this;
ceffect->ref_handle = ref;
ceffect->handler = 0;
if(condition)
ceffect->condition = pduel->lua->clone_function_ref(condition);
if(cost)
ceffect->cost = pduel->lua->clone_function_ref(cost);
if(target)
ceffect->target = pduel->lua->clone_function_ref(target);
if(operation)
ceffect->operation = pduel->lua->clone_function_ref(operation);
if(value && is_flag(EFFECT_FLAG_FUNC_VALUE))
ceffect->value = pduel->lua->clone_function_ref(value);
return ceffect;
}
card* effect::get_owner() const { card* effect::get_owner() const {
if(active_handler)
return active_handler;
if(type & EFFECT_TYPE_XMATERIAL) if(type & EFFECT_TYPE_XMATERIAL)
return active_handler ? active_handler : handler->overlay_target; return handler->overlay_target;
return owner; return owner;
} }
uint8 effect::get_owner_player() { uint8 effect::get_owner_player() {
...@@ -700,8 +720,10 @@ uint8 effect::get_owner_player() { ...@@ -700,8 +720,10 @@ uint8 effect::get_owner_player() {
return get_owner()->current.controler; return get_owner()->current.controler;
} }
card* effect::get_handler() const { card* effect::get_handler() const {
if(active_handler)
return active_handler;
if(type & EFFECT_TYPE_XMATERIAL) if(type & EFFECT_TYPE_XMATERIAL)
return active_handler ? active_handler : handler->overlay_target; return handler->overlay_target;
return handler; return handler;
} }
uint8 effect::get_handler_player() { uint8 effect::get_handler_player() {
......
...@@ -90,6 +90,7 @@ public: ...@@ -90,6 +90,7 @@ public:
void get_value(effect* peffect, uint32 extraargs, std::vector<int32>* result); void get_value(effect* peffect, uint32 extraargs, std::vector<int32>* result);
int32 check_value_condition(uint32 extraargs = 0); int32 check_value_condition(uint32 extraargs = 0);
int32 get_speed(); int32 get_speed();
effect* clone();
card* get_owner() const; card* get_owner() const;
uint8 get_owner_player(); uint8 get_owner_player();
card* get_handler() const; card* get_handler() const;
...@@ -149,6 +150,7 @@ public: ...@@ -149,6 +150,7 @@ public:
#define EFFECT_TYPE_QUICK_F 0x0400 // #define EFFECT_TYPE_QUICK_F 0x0400 //
#define EFFECT_TYPE_CONTINUOUS 0x0800 // #define EFFECT_TYPE_CONTINUOUS 0x0800 //
#define EFFECT_TYPE_XMATERIAL 0x1000 // #define EFFECT_TYPE_XMATERIAL 0x1000 //
#define EFFECT_TYPE_GRANT 0x2000 //
//========== Flags ========== //========== Flags ==========
enum effect_flag : uint32 { enum effect_flag : uint32 {
......
...@@ -1011,6 +1011,8 @@ void field::add_effect(effect* peffect, uint8 owner_player) { ...@@ -1011,6 +1011,8 @@ void field::add_effect(effect* peffect, uint8 owner_player) {
it = effects.aura_effect.insert(std::make_pair(peffect->code, peffect)); it = effects.aura_effect.insert(std::make_pair(peffect->code, peffect));
if(peffect->code == EFFECT_SPSUMMON_COUNT_LIMIT) if(peffect->code == EFFECT_SPSUMMON_COUNT_LIMIT)
effects.spsummon_count_eff.insert(peffect); effects.spsummon_count_eff.insert(peffect);
if(peffect->type & EFFECT_TYPE_GRANT)
effects.grant_effect.insert(std::make_pair(peffect, field_effect::gain_effects()));
} else { } else {
if (peffect->type & EFFECT_TYPE_IGNITION) if (peffect->type & EFFECT_TYPE_IGNITION)
it = effects.ignition_effect.insert(std::make_pair(peffect->code, peffect)); it = effects.ignition_effect.insert(std::make_pair(peffect->code, peffect));
...@@ -1069,6 +1071,8 @@ void field::remove_effect(effect* peffect) { ...@@ -1069,6 +1071,8 @@ void field::remove_effect(effect* peffect) {
effects.aura_effect.erase(it); effects.aura_effect.erase(it);
if(peffect->code == EFFECT_SPSUMMON_COUNT_LIMIT) if(peffect->code == EFFECT_SPSUMMON_COUNT_LIMIT)
effects.spsummon_count_eff.erase(peffect); effects.spsummon_count_eff.erase(peffect);
if(peffect->type & EFFECT_TYPE_GRANT)
effects.grant_effect.erase(peffect);
} else { } else {
if (peffect->type & EFFECT_TYPE_IGNITION) if (peffect->type & EFFECT_TYPE_IGNITION)
effects.ignition_effect.erase(it); effects.ignition_effect.erase(it);
...@@ -1875,6 +1879,45 @@ void field::adjust_self_destroy_set() { ...@@ -1875,6 +1879,45 @@ void field::adjust_self_destroy_set() {
if(!core.self_tograve_set.empty()) if(!core.self_tograve_set.empty())
add_process(PROCESSOR_SELF_DESTROY, 20, 0, 0, 0, 0); add_process(PROCESSOR_SELF_DESTROY, 20, 0, 0, 0, 0);
} }
int32 field::adjust_grant_effect() {
int32 adjusted = FALSE;
for(auto eit = effects.grant_effect.begin(); eit != effects.grant_effect.end(); ++eit) {
effect* peffect = eit->first;
if(!peffect->is_available() || !peffect->label_object)
continue;
card_set cset;
filter_affected_cards(peffect, &cset);
card_set add_set;
for(auto cit = cset.begin(); cit != cset.end(); ++cit) {
card* pcard = *cit;
if(pcard->is_affect_by_effect(peffect) && !eit->second.count(pcard))
add_set.insert(pcard);
}
card_set remove_set;
for(auto cit = eit->second.begin(); cit != eit->second.end(); ++cit) {
card* pcard = cit->first;
if(!peffect->is_target(pcard) || !pcard->is_affect_by_effect(peffect))
remove_set.insert(pcard);
}
for(auto cit = add_set.begin(); cit != add_set.end(); ++cit) {
card* pcard = *cit;
effect* geffect = (effect*)peffect->label_object;
effect* ceffect = geffect->clone();
ceffect->owner = pcard;
pcard->add_effect(ceffect);
eit->second.insert(std::make_pair(pcard, ceffect));
}
for(auto cit = remove_set.begin(); cit != remove_set.end(); ++cit) {
card* pcard = *cit;
auto it = eit->second.find(pcard);
pcard->remove_effect(it->second);
eit->second.erase(it);
}
if(!add_set.empty() || !remove_set.empty())
adjusted = TRUE;
}
return adjusted;
}
void field::add_unique_card(card* pcard) { void field::add_unique_card(card* pcard) {
uint8 con = pcard->current.controler; uint8 con = pcard->current.controler;
if(pcard->unique_pos[0]) if(pcard->unique_pos[0])
...@@ -1883,7 +1926,6 @@ void field::add_unique_card(card* pcard) { ...@@ -1883,7 +1926,6 @@ void field::add_unique_card(card* pcard) {
core.unique_cards[1 - con].insert(pcard); core.unique_cards[1 - con].insert(pcard);
pcard->unique_fieldid = 0; pcard->unique_fieldid = 0;
} }
void field::remove_unique_card(card* pcard) { void field::remove_unique_card(card* pcard) {
uint8 con = pcard->current.controler; uint8 con = pcard->current.controler;
if(con == PLAYER_NONE) if(con == PLAYER_NONE)
...@@ -1912,7 +1954,6 @@ effect* field::check_unique_onfield(card* pcard, uint8 controler, uint8 location ...@@ -1912,7 +1954,6 @@ effect* field::check_unique_onfield(card* pcard, uint8 controler, uint8 location
return pcard->unique_effect; return pcard->unique_effect;
return 0; return 0;
} }
int32 field::check_spsummon_once(card* pcard, uint8 playerid) { int32 field::check_spsummon_once(card* pcard, uint8 playerid) {
if(pcard->spsummon_code == 0) if(pcard->spsummon_code == 0)
return TRUE; return TRUE;
......
...@@ -91,6 +91,8 @@ struct field_effect { ...@@ -91,6 +91,8 @@ struct field_effect {
typedef std::unordered_map<effect*, effect_container::iterator> effect_indexer; typedef std::unordered_map<effect*, effect_container::iterator> effect_indexer;
typedef std::unordered_map<effect*, effect*> oath_effects; typedef std::unordered_map<effect*, effect*> oath_effects;
typedef std::unordered_set<effect*> effect_collection; typedef std::unordered_set<effect*> effect_collection;
typedef std::unordered_map<card*, effect*> gain_effects;
typedef std::unordered_map<effect*, gain_effects> grant_effect_container;
effect_container aura_effect; effect_container aura_effect;
effect_container ignition_effect; effect_container ignition_effect;
...@@ -109,6 +111,8 @@ struct field_effect { ...@@ -109,6 +111,8 @@ struct field_effect {
std::list<card*> disable_check_list; std::list<card*> disable_check_list;
std::unordered_set<card*> disable_check_set; std::unordered_set<card*> disable_check_set;
grant_effect_container grant_effect;
}; };
struct field_info { struct field_info {
int32 field_id; int32 field_id;
...@@ -399,6 +403,7 @@ public: ...@@ -399,6 +403,7 @@ public:
void add_to_disable_check_list(card* pcard); void add_to_disable_check_list(card* pcard);
void adjust_disable_check_list(); void adjust_disable_check_list();
void adjust_self_destroy_set(); void adjust_self_destroy_set();
int32 adjust_grant_effect();
void add_unique_card(card* pcard); void add_unique_card(card* pcard);
void remove_unique_card(card* pcard); void remove_unique_card(card* pcard);
effect* check_unique_onfield(card* pcard, uint8 controler, uint8 location, card* icard = 0); effect* check_unique_onfield(card* pcard, uint8 controler, uint8 location, card* icard = 0);
......
...@@ -1145,6 +1145,11 @@ int32 interpreter::call_coroutine(int32 f, uint32 param_count, uint32 * yield_va ...@@ -1145,6 +1145,11 @@ int32 interpreter::call_coroutine(int32 f, uint32 param_count, uint32 * yield_va
return COROUTINE_ERROR; return COROUTINE_ERROR;
} }
} }
int32 interpreter::clone_function_ref(int32 func_ref) {
lua_rawgeti(current_state, LUA_REGISTRYINDEX, func_ref);
int32 ref = luaL_ref(current_state, LUA_REGISTRYINDEX);
return ref;
}
//Convert a pointer to a lua value, +1 -0 //Convert a pointer to a lua value, +1 -0
void interpreter::card2value(lua_State* L, card* pcard) { void interpreter::card2value(lua_State* L, card* pcard) {
if (!pcard || pcard->ref_handle == 0) if (!pcard || pcard->ref_handle == 0)
......
...@@ -68,6 +68,7 @@ public: ...@@ -68,6 +68,7 @@ public:
int32 get_function_value(int32 f, uint32 param_count); int32 get_function_value(int32 f, uint32 param_count);
int32 get_function_value(int32 f, uint32 param_count, std::vector<int32>* result); int32 get_function_value(int32 f, uint32 param_count, std::vector<int32>* result);
int32 call_coroutine(int32 f, uint32 param_count, uint32* yield_value, uint16 step); int32 call_coroutine(int32 f, uint32 param_count, uint32* yield_value, uint16 step);
int32 interpreter::clone_function_ref(int32 func_ref);
static void card2value(lua_State* L, card* pcard); static void card2value(lua_State* L, card* pcard);
static void group2value(lua_State* L, group* pgroup); static void group2value(lua_State* L, group* pgroup);
......
...@@ -3669,30 +3669,10 @@ int32 scriptlib::duel_majestic_copy(lua_State *L) { ...@@ -3669,30 +3669,10 @@ int32 scriptlib::duel_majestic_copy(lua_State *L) {
effect* peffect = eit->second; effect* peffect = eit->second;
if(!(peffect->type & 0x7c)) continue; if(!(peffect->type & 0x7c)) continue;
if(!peffect->is_flag(EFFECT_FLAG_INITIAL)) continue; if(!peffect->is_flag(EFFECT_FLAG_INITIAL)) continue;
effect* ceffect = pduel->new_effect(); effect* ceffect = peffect->clone();
int32 ref = ceffect->ref_handle;
*ceffect = *peffect;
ceffect->ref_handle = ref;
ceffect->owner = pcard; ceffect->owner = pcard;
ceffect->handler = 0;
ceffect->flag[0] &= ~EFFECT_FLAG_INITIAL; ceffect->flag[0] &= ~EFFECT_FLAG_INITIAL;
ceffect->effect_owner = PLAYER_NONE; ceffect->effect_owner = PLAYER_NONE;
if(peffect->condition) {
lua_rawgeti(L, LUA_REGISTRYINDEX, peffect->condition);
ceffect->condition = luaL_ref(L, LUA_REGISTRYINDEX);
}
if(peffect->cost) {
lua_rawgeti(L, LUA_REGISTRYINDEX, peffect->cost);
ceffect->cost = luaL_ref(L, LUA_REGISTRYINDEX);
}
if(peffect->target) {
lua_rawgeti(L, LUA_REGISTRYINDEX, peffect->target);
ceffect->target = luaL_ref(L, LUA_REGISTRYINDEX);
}
if(peffect->operation) {
lua_rawgeti(L, LUA_REGISTRYINDEX, peffect->operation);
ceffect->operation = luaL_ref(L, LUA_REGISTRYINDEX);
}
ceffect->reset_flag = RESET_EVENT + 0x1fe0000 + RESET_PHASE + PHASE_END + RESET_SELF_TURN + RESET_OPPO_TURN; ceffect->reset_flag = RESET_EVENT + 0x1fe0000 + RESET_PHASE + PHASE_END + RESET_SELF_TURN + RESET_OPPO_TURN;
ceffect->reset_count = 0x1; ceffect->reset_count = 0x1;
ceffect->recharge(); ceffect->recharge();
......
...@@ -34,32 +34,7 @@ int32 scriptlib::effect_clone(lua_State *L) { ...@@ -34,32 +34,7 @@ int32 scriptlib::effect_clone(lua_State *L) {
check_param_count(L, 1); check_param_count(L, 1);
check_param(L, PARAM_TYPE_EFFECT, 1); check_param(L, PARAM_TYPE_EFFECT, 1);
effect* peffect = *(effect**) lua_touserdata(L, 1); effect* peffect = *(effect**) lua_touserdata(L, 1);
duel* pduel = peffect->pduel; effect* ceffect = peffect->clone();
effect* ceffect = pduel->new_effect();
int32 ref = ceffect->ref_handle;
*ceffect = *peffect;
ceffect->ref_handle = ref;
ceffect->handler = 0;
if(peffect->condition) {
lua_rawgeti(L, LUA_REGISTRYINDEX, peffect->condition);
ceffect->condition = luaL_ref(L, LUA_REGISTRYINDEX);
}
if(peffect->cost) {
lua_rawgeti(L, LUA_REGISTRYINDEX, peffect->cost);
ceffect->cost = luaL_ref(L, LUA_REGISTRYINDEX);
}
if(peffect->target) {
lua_rawgeti(L, LUA_REGISTRYINDEX, peffect->target);
ceffect->target = luaL_ref(L, LUA_REGISTRYINDEX);
}
if(peffect->operation) {
lua_rawgeti(L, LUA_REGISTRYINDEX, peffect->operation);
ceffect->operation = luaL_ref(L, LUA_REGISTRYINDEX);
}
if(peffect->value && peffect->is_flag(EFFECT_FLAG_FUNC_VALUE)) {
lua_rawgeti(L, LUA_REGISTRYINDEX, peffect->value);
ceffect->value = luaL_ref(L, LUA_REGISTRYINDEX);
}
interpreter::effect2value(L, ceffect); interpreter::effect2value(L, ceffect);
return 1; return 1;
} }
......
...@@ -5155,7 +5155,12 @@ int32 field::adjust_step(uint16 step) { ...@@ -5155,7 +5155,12 @@ int32 field::adjust_step(uint16 step) {
add_process(PROCESSOR_CONTROL_ADJUST, 0, 0, 0, 0, 0); add_process(PROCESSOR_CONTROL_ADJUST, 0, 0, 0, 0, 0);
} }
} }
core.units.begin()->step = 8; core.units.begin()->step = 7;
return FALSE;
}
case 8: {
if(adjust_grant_effect())
core.re_adjust = TRUE;
return FALSE; return FALSE;
} }
case 9: { case 9: {
......
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