Mattsuharu1991

Card Game Quick Effect

May 31st, 2026
53
0
Never
3
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 27.69 KB | None | 0 0
  1. #==============================================================================
  2. # SISTEMA YGO DE QUICK EFFECT V5: Con Kill Switch (Modo Debug)
  3. #==============================================================================
  4.  
  5. $MISCELLA_SYSTEM_ON = true # <--- Mantenelo en 'false' para probar a UCT.
  6. # Trace Card Destruction / MP (same flag as CardGameScript): $YTGO_CARD_TRACE = true in F12 console
  7. $YTGO_CARD_TRACE = false unless defined?($YTGO_CARD_TRACE)
  8.  
  9. #==============================================================================
  10. # 1. SISTEMA GENÉRICO DE AURAS
  11. #==============================================================================
  12. class Game_Party < Game_Unit
  13. attr_accessor :active_auras
  14.  
  15. unless method_defined?(:ygo_auras_battle_start)
  16. alias_method :ygo_auras_battle_start, :on_battle_start
  17. end
  18. def on_battle_start
  19. ygo_auras_battle_start
  20. @active_auras = [] if $MISCELLA_SYSTEM_ON
  21. end
  22.  
  23. def add_aura(aura_name)
  24. @active_auras ||= []
  25. @active_auras << aura_name unless @active_auras.include?(aura_name)
  26. end
  27.  
  28. def has_aura?(aura_name)
  29. return false if @active_auras.nil?
  30. @active_auras.include?(aura_name)
  31. end
  32. end
  33.  
  34. class Game_Actor < Game_Battler
  35. unless method_defined?(:pc27_cg_on_turn_end_aura)
  36. alias_method :pc27_cg_on_turn_end_aura, :on_turn_end
  37. end
  38. def on_turn_end
  39. $game_party.active_auras = [] if $MISCELLA_SYSTEM_ON
  40. pc27_cg_on_turn_end_aura
  41. end
  42.  
  43. def can_pay_card_cost?(card)
  44. return false unless card
  45.  
  46. # 1. Chequeo de MP base (si usás el sistema nativo de RPG Maker)
  47. return false if card.respond_to?(:mp_cost) && self.mp < card.mp_cost
  48.  
  49. # 2. Chequeo de requerimientos personalizados (tu método actual)
  50. return false if self.respond_to?(:custom_req_met?) && !self.custom_req_met?(card)
  51.  
  52. # 3. Extraer el texto del costo de las notas
  53. cost_name = nil
  54. if card.note =~ /<card cost:\s*(.+?)>/i || card.note =~ /<spell_cost:\s*(.+?)>/i
  55. cost_name = $1.to_s.strip.downcase
  56. end
  57.  
  58. # 4. Evaluación matemática
  59. if cost_name
  60. if cost_name =~ /discard(\d+)/i
  61. amount = $1.to_i
  62. return false if self.hand.size < amount
  63. elsif cost_name =~ /pay_lp_(\d+)/i
  64. amount = $1.to_i
  65. # En Yu-Gi-Oh no podés suicidarte para pagar un costo
  66. return false if self.hp <= amount
  67. end
  68. # Podés seguir agregando "elsif" acá en el futuro para costos como "banish1", etc.
  69. end
  70.  
  71. return true
  72. end
  73.  
  74. end
  75.  
  76. #==============================================================================
  77. # 2. UI: VENTANAS DE RESPUESTA RÁPIDA Y NIVELES
  78. #==============================================================================
  79. # (La UI no interfiere con la lógica base, la dejamos intacta para evitar errores de clase no encontrada)
  80. class Window_ActivationNotice < Window_Base
  81. def initialize
  82. super(0, 0, 340, 100)
  83. self.x = 4
  84. self.y = (Graphics.height - self.height) / 2 - 140
  85. self.z = 10000
  86. self.visible = false
  87. self.contents_opacity = 0
  88. end
  89.  
  90. def display_activation(item, target = nil, attacker = nil)
  91. contents.clear
  92. self.visible = true
  93. change_color(normal_color)
  94. if item.id == 1
  95. attacker_name = attacker ? attacker.name : "Opponent"
  96. text_part = "#{attacker_name} attacks "
  97. tw = text_size(text_part).width
  98. target_w = target ? text_size(target.name).width : 0
  99. if target && (tw + target_w > contents.width)
  100. draw_text(0, 0, contents.width, line_height, text_part)
  101. change_color(text_color(14))
  102. draw_text(0, line_height, contents.width, line_height, target.name)
  103. change_color(normal_color)
  104. draw_text(0, line_height * 2, contents.width, line_height, "Activate a response?")
  105. else
  106. draw_text(0, 0, contents.width, line_height, text_part)
  107. if target
  108. change_color(text_color(14))
  109. draw_text(tw, 0, contents.width - tw, line_height, target.name)
  110. change_color(normal_color)
  111. end
  112. draw_text(0, line_height, contents.width, line_height, "Activate a response?")
  113. end
  114. else
  115. attacker_name = attacker ? attacker.name : "Your opponent"
  116. draw_text(0, 0, contents.width, line_height, "#{attacker_name} activates:")
  117. draw_icon(item.icon_index, 0, line_height + 4)
  118. draw_text(28, line_height + 4, contents.width - 28, line_height, item.name)
  119. end
  120. self.contents_opacity = 255
  121. end
  122.  
  123. def display_damage_activation(target)
  124. contents.clear
  125. self.visible = true
  126. change_color(text_color(14))
  127. draw_text(0, 0, contents.width, line_height, "#{target.name} took damage!")
  128. change_color(normal_color)
  129. draw_text(0, line_height, contents.width, line_height, "Activate a response?")
  130.  
  131. self.contents_opacity = 255
  132. end
  133.  
  134. end
  135.  
  136. class Sprite_CardPreview < Sprite
  137. def initialize(viewport = nil)
  138. super(viewport)
  139. self.z = 10001
  140. self.visible = false
  141. end
  142.  
  143. def show_card(item_id)
  144. begin
  145. self.bitmap = Cache.picture("Card#{item_id}")
  146. self.x = 350
  147. self.y = (Graphics.height / 2) - 190
  148. self.visible = true
  149. rescue
  150. self.visible = false
  151. end
  152. end
  153. end
  154.  
  155. class Window_QuickPrompt < Window_Command
  156. def initialize
  157. super(0, 0)
  158. self.x = 4
  159. self.y = (Graphics.height - self.height) / 2 - 50
  160. self.z = 10000
  161. self.openness = 0
  162. self.active = false
  163. self.visible = false
  164. @responses = []
  165. end
  166.  
  167. def window_width; return 340; end
  168.  
  169. def set_responses(responses)
  170. @responses = responses
  171. refresh
  172. self.height = window_height
  173. self.y = (Graphics.height - self.height) / 2 - 50
  174. end
  175.  
  176. def make_command_list
  177. if @responses && [email protected]?
  178. @responses.each do |resp|
  179. card = resp[:card]
  180. owner = resp[:owner]
  181. suffix = $game_party.battle_members.size > 1 ? " (#{owner.name})" : ""
  182. if resp[:trigger_type] == :set_and_faceup
  183. command_text = "Activate #{card.name} & its effect#{suffix}"
  184. elsif resp[:was_face_down]
  185. command_text = "Activate #{card.name}#{suffix}"
  186. else
  187. command_text = "Use effect of #{card.name}#{suffix}"
  188. end
  189. add_command(command_text, :yes, true, resp)
  190. end
  191. end
  192. add_command("Cancel", :no)
  193. end
  194.  
  195. # --- NUEVO: Sobrescribimos draw_item para inyectar el icono ---
  196. def draw_item(index)
  197. change_color(normal_color, command_enabled?(index))
  198. rect = item_rect_for_text(index)
  199.  
  200. # Recuperamos la información guardada en :ext
  201. resp = @list[index][:ext]
  202.  
  203. # Si existe una carta asignada a esta opción, dibujamos su icono
  204. if resp && resp.is_a?(Hash) && resp[:card]
  205. draw_icon(resp[:card].icon_index, rect.x, rect.y)
  206. rect.x += 28 # Empujamos el texto hacia la derecha
  207. rect.width -= 28 # Reducimos el ancho para que no se corte
  208. end
  209.  
  210. draw_text(rect, command_name(index), alignment)
  211. end
  212.  
  213. end
  214.  
  215. class Window_MiscellaLevelChoice < Window_Command
  216. def initialize(actor, valid_levels)
  217. @actor = actor
  218. @valid_levels = valid_levels
  219. super(0, 0)
  220. self.x = (Graphics.width - self.width) / 2
  221. self.y = (Graphics.height - self.height) / 2
  222. self.z = 10000
  223. end
  224. def window_width; return 240; end
  225. def make_command_list
  226. @valid_levels.each { |lvl| add_command("Summon Level #{lvl}", :select_level, true, lvl) }
  227. add_command("Cancel", :cancel)
  228. end
  229. end
  230.  
  231. #==============================================================================
  232. # 3. NÚCLEO DE BATALLA: ESCENA Y LÓGICA DE CARTAS (CON KILL SWITCH)
  233. #==============================================================================
  234. class Scene_Battle < Scene_Base
  235.  
  236. unless method_defined?(:ygo_v3_create_windows)
  237. alias_method :ygo_v3_create_windows, :create_all_windows
  238. end
  239. def create_all_windows
  240. ygo_v3_create_windows
  241. @activation_notice = Window_ActivationNotice.new
  242. @card_preview = Sprite_CardPreview.new
  243. @quick_prompt = Window_QuickPrompt.new
  244. @quick_prompt.set_handler(:yes, method(:on_quick_yes))
  245. @quick_prompt.set_handler(:no, method(:on_quick_no))
  246. @quick_prompt.set_handler(:cancel, method(:on_quick_no))
  247.  
  248. @miscella_level_window = Window_MiscellaLevelChoice.new(nil, [])
  249. @miscella_level_window.set_handler(:select_level, method(:on_miscella_level_ok))
  250. @miscella_level_window.set_handler(:cancel, method(:on_miscella_level_cancel))
  251. @miscella_level_window.hide.deactivate
  252. end
  253.  
  254. unless method_defined?(:ygo_auras_turn_end)
  255. alias_method :ygo_auras_turn_end, :turn_end
  256. end
  257. def turn_end
  258. $game_party.active_auras = [] if $MISCELLA_SYSTEM_ON
  259. ygo_auras_turn_end
  260. end
  261.  
  262. unless method_defined?(:pc27_cg_command_end_turn_aura)
  263. alias_method :pc27_cg_command_end_turn_aura, :command_end_turn
  264. end
  265. def command_end_turn
  266. $game_party.active_auras = [] if $MISCELLA_SYSTEM_ON
  267. pc27_cg_command_end_turn_aura
  268. end
  269.  
  270. # --- Uso de Cartas ---
  271. alias ygo_v3_use_item_check use_item unless method_defined?(:ygo_v3_use_item_check)
  272. def use_item
  273. return ygo_v3_use_item_check if @is_interrupt_effect && @subject && [email protected]?
  274. original_subject = @subject
  275. if $MISCELLA_SYSTEM_ON && @subject && @subject.enemy?
  276. item = @subject.current_action.item rescue nil
  277. if item
  278. @current_quick_subject = @subject
  279. @attack_negated = false
  280. target = @subject.current_action.make_targets.compact[0] rescue nil
  281. check_generic_quick_responses(item, target)
  282. end
  283. end
  284. if @attack_negated
  285. wait(90)
  286. $game_message.clear
  287. $game_message.background = 1
  288. $game_message.position = 1
  289. $game_message.add("Attack Negated!")
  290. if @message_window
  291. @message_window.openness = 255
  292. @message_window.visible = true
  293. end
  294. wait_for_message
  295. return
  296. end
  297. @subject = original_subject if original_subject
  298. ygo_v3_use_item_check
  299. end
  300.  
  301. unless method_defined?(:pc27_grave_bug_fix)
  302. alias_method :pc27_grave_bug_fix, :on_skill_ok
  303. end
  304.  
  305. def on_skill_ok
  306. if $MISCELLA_SYSTEM_ON
  307. @subject = BattleManager.actor
  308. if @subject && @subject.current_zone == :graveyard
  309. @skill = @skill_window.item
  310. handle_graveyard_skill(@skill)
  311. return
  312. end
  313. end
  314. pc27_grave_bug_fix
  315. end
  316.  
  317. # --- Activación Manual ---
  318. unless method_defined?(:pc27_safe_resolve_card)
  319. alias_method :pc27_safe_resolve_card, :resolve_card_effect
  320. end
  321.  
  322. def resolve_card_effect(skill)
  323. if $MISCELLA_SYSTEM_ON && @current_card_action == :hand_effect
  324. if skill.hand_impact == "miscellahand" || skill.note =~ /<quick_response_hand:\s*(.+?)>/i
  325. aura_name = :miscella
  326. aura_name = $1.to_s.strip.downcase.to_sym if $1
  327. $game_party.add_aura(aura_name)
  328. RPG::SE.new("Magic1", 80, 100).play rescue nil
  329. BattleManager.actor.popup_destroyed_card(skill.icon_index, "Protected!") if BattleManager.actor.respond_to?(:popup_destroyed_card)
  330. end
  331. end
  332. # --- FIX MP: REVISIÓN INTELIGENTE DE COSTOS ---
  333. tiene_costo_extra = (skill.note =~ /<card cost:/i || skill.note =~ /<spell_cost:/i)
  334. tiene_impacto = (skill.note =~ /<card impact:/i || skill.note =~ /<spell_impact:/i || skill.note =~ /<hand_impact:/i)
  335. # Field flip / set activation already calls pay_skill_cost in CardGameScript when !card.cost — do not pay again here.
  336. if !tiene_costo_extra && tiene_impacto && @current_card_action != :field_effect
  337. if defined?($YTGO_CARD_TRACE) && $YTGO_CARD_TRACE
  338. puts("[YTGO-CARD] resolve_card_effect pay_skill_cost id=#{skill.id} mp=#{BattleManager.actor.mp rescue '?' } zone_act=#{@current_card_action.inspect}")
  339. end
  340. BattleManager.actor.pay_skill_cost(skill) if BattleManager.actor.respond_to?(:pay_skill_cost)
  341. elsif defined?($YTGO_CARD_TRACE) && $YTGO_CARD_TRACE && tiene_impacto
  342. puts("[YTGO-CARD] resolve_card_effect SKIP pay id=#{skill.id} act=#{@current_card_action.inspect} tiene_costo_extra=#{!!tiene_costo_extra}")
  343. end
  344. # ----------------------------------------------
  345.  
  346. pc27_safe_resolve_card(skill)
  347. end
  348.  
  349. unless method_defined?(:ygo_miscella_restore_taken)
  350. alias_method :ygo_miscella_restore_taken, :restore_taken_cards
  351. end
  352.  
  353. def restore_taken_cards(target)
  354. if $MISCELLA_SYSTEM_ON
  355. begin
  356. if target == :proceed && @temp_effect_data && @temp_effect_data[1]
  357. effect_name = @temp_effect_data[1]
  358. effect_data = PC27::CG::CARD_EFFECT[effect_name] rescue nil
  359. if effect_data.is_a?(Array) && effect_data.size >= 6
  360. destination = effect_data[5]
  361. if destination == :miscella_chain_summon
  362. taken_cards = @temp_effect_data[3].dup
  363. @temp_effect_data[3] = []
  364. process_banish_triggers(taken_cards)
  365. @card_select_window.actor.banish += taken_cards
  366. next_effect = "miscella_sp_summon"
  367. @current_card_action = :field_effect
  368. BattleManager.actor.current_zone = :deck
  369. invoke_card_impact(next_effect)
  370. return true
  371. end
  372. end
  373. end
  374. rescue
  375. end
  376. end
  377. ygo_miscella_restore_taken(target)
  378. end
  379.  
  380. def proceed_selection
  381. @added_card_name = nil
  382. if @temp_effect_data && @temp_effect_data[3] && !@temp_effect_data[3].empty?
  383. @added_card_name = @temp_effect_data[3][0].name
  384. end
  385. @card_select_window.hide.deactivate
  386. @card_select_window.sort_index = -1
  387. restore_selected_cards
  388. player = @active_effect_owner || BattleManager.actor || $game_party.members[0]
  389. unless @current_card_action == :field_effect
  390. player.current_zone = :hand
  391. end
  392.  
  393. if @temp_effect_data[0] == :cost
  394. effect_data = PC27::CG::CARD_EFFECT[@temp_effect_data[1]]
  395. is_chain = effect_data && effect_data[5].to_s.include?("chain")
  396. restore_taken_cards(:proceed)
  397.  
  398. if @is_interrupt_effect
  399. puts "[DEBUG] Costo pagado. Saltando a impacto."
  400. skill_to_use = @skill || @active_effect_card
  401. impact_to_use = nil
  402. if skill_to_use.note =~ /<card impact:\s*(.+?)>/i ||
  403. skill_to_use.note =~ /<spell_impact:\s*(.+?)>/i ||
  404. skill_to_use.note =~ /<field_impact:\s*(.+?)>/i
  405. impact_to_use = $1.to_s.strip.downcase
  406. end
  407. @temp_effect_data = []
  408. invoke_card_impact(impact_to_use) if impact_to_use
  409. else
  410. unless is_chain
  411. if player && player.respond_to?(:input) && player.input
  412. player.input.set_skill(@skill.id)
  413. player.last_skill.object = @skill
  414. end
  415. @temp_effect_data = []
  416. next_command
  417. end
  418. end
  419. elsif @temp_effect_data[0] == :impact
  420. unless restore_taken_cards(:proceed)
  421. finish_proceed_selection
  422. end
  423. end
  424. end
  425.  
  426. def handle_graveyard_skill(skill)
  427. if BattleManager.actor.state?(18)
  428. is_misc = (skill.grave_impact == "miscella" || skill.note =~ /<grave[-_ ]impact:\s*miscella>/i)
  429. if is_misc || (skill.grave_impact && BattleManager.actor.leads_to_special_summon?(skill.grave_impact))
  430. Sound.play_buzzer
  431. @skill_window.activate
  432. return
  433. end
  434. end
  435. if skill.grave_impact == "miscella" || skill.note =~ /<grave[-_ ]impact:\s*miscella>/i
  436. process_miscella_grave_effect(skill)
  437. elsif skill.grave_impact && skill.grave_impact != "" && skill.grave_impact != false
  438. @current_card_action = :grave_effect
  439. invoke_card_impact(skill.grave_impact)
  440. else
  441. Sound.play_buzzer
  442. @skill_window.activate
  443. end
  444. end
  445.  
  446. def process_miscella_grave_effect(skill)
  447. actor = BattleManager.actor
  448. grave_dinos = actor.grave.select { |c| c.subtype == 9 rescue false }
  449. return Sound.play_buzzer.tap { $game_message.add("No monster zones!"); @skill_window.activate } unless actor.free_monster_zone_available?
  450. valid_levels = []
  451. actor.deck.each do |c|
  452. next unless (c.subtype == 9 rescue false)
  453. next if (c.note =~ /<special_only:/i) && !c.properly_summoned
  454. valid_levels << c.level if c.level > 0 && c.level <= grave_dinos.size && !valid_levels.include?(c.level)
  455. end
  456. return Sound.play_buzzer.tap { @skill_window.activate } if valid_levels.empty?
  457. @miscella_level_window.dispose if @miscella_level_window
  458. @miscella_level_window = Window_MiscellaLevelChoice.new(actor, valid_levels.sort)
  459. @miscella_level_window.set_handler(:select_level, method(:on_miscella_level_ok))
  460. @miscella_level_window.set_handler(:cancel, method(:on_miscella_level_cancel))
  461. @skill_window.deactivate
  462. @miscella_level_window.show.activate
  463. end
  464.  
  465. def on_miscella_level_ok
  466. chosen_level = @miscella_level_window.current_ext
  467. @miscella_level_window.hide.deactivate
  468. actor, miscella_card = BattleManager.actor, @skill_window.item
  469. idx = actor.grave.index(miscella_card)
  470. actor.grave.delete_at(idx) if idx
  471. actor.banish.push(miscella_card)
  472. amount_needed = chosen_level - 1
  473. PC27::CG::CARD_EFFECT["miscella_sp_summon"] = [:takem, 0, :deck, :deck, [0, 0, 0, 9, chosen_level, 0, 0, 0, 0, 0, 0], :special_summon, 1]
  474. if amount_needed > 0
  475. PC27::CG::CARD_EFFECT["miscella_banish_cost"] = [:takem, 0, :grave, :grave, [0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0], :miscella_chain_summon, amount_needed]
  476. invoke_card_impact("miscella_banish_cost")
  477. else
  478. invoke_card_impact("miscella_sp_summon")
  479. end
  480. end
  481. unless method_defined?(:ygo_miscella_restore_taken)
  482. alias_method :ygo_miscella_restore_taken, :restore_taken_cards
  483. end
  484.  
  485. def on_miscella_level_cancel; @miscella_level_window.hide.deactivate; @skill_window.activate; end
  486.  
  487. def check_generic_quick_responses(enemy_item, target = nil)
  488. return if @is_interrupt_effect
  489. puts "[DEBUG] check_generic_quick_responses: Evaluando item enemigo #{enemy_item ? enemy_item.name : 'N/A'}"
  490. responses = gather_quick_responses(enemy_item, target)
  491. return if responses.empty?
  492.  
  493. @skill_window.hide.deactivate if @skill_window
  494. @card_select_window.hide.deactivate if @card_select_window
  495. @actor_command_window.hide.deactivate if @actor_command_window
  496.  
  497. if enemy_item
  498. @activation_notice.display_activation(enemy_item, target, @current_quick_subject)
  499. @card_preview.show_card(enemy_item.id) unless enemy_item.id == 1
  500. end
  501.  
  502. @quick_prompt.set_responses(responses)
  503. @quick_prompt.visible = true
  504. @quick_prompt.open
  505. @quick_prompt.activate
  506. @quick_prompt.select(0)
  507.  
  508. update_basic while @quick_prompt.active
  509.  
  510. @activation_notice.visible = @card_preview.visible = false
  511. end
  512.  
  513. def on_quick_yes
  514. @last_state_card_id = nil
  515. resp = @quick_prompt.current_ext
  516. @quick_prompt.close; @quick_prompt.deactivate; @quick_prompt.visible = false
  517. @activation_notice.visible = false
  518. @card_preview.visible = false
  519. @is_interrupt_effect = true
  520. player = resp[:owner]
  521. card = resp[:card]
  522. if resp[:source] == :hand
  523. hand_idx = player.hand.index(card)
  524. player.hand.delete_at(hand_idx) if hand_idx
  525. player.grave.push(card)
  526. $game_party.add_aura(resp[:aura])
  527. player.popup_destroyed_card(card.icon_index, "Protected!")
  528. RPG::SE.new("Magic1", 80, 100).play rescue nil
  529. @is_interrupt_effect = false
  530. elsif resp[:source] == :field
  531. idx = resp[:index]
  532. state = player.st_zones_state[idx]
  533. if resp[:was_face_down]
  534. player.pay_skill_cost(card) if player.respond_to?(:pay_skill_cost)
  535. end
  536. state[:face_down] = false
  537. @field_map_window.refresh if @field_map_window
  538. RPG::SE.new("Magic1", 80, 100).play rescue nil
  539. player.popup_destroyed_card(card.icon_index, "Activated!") rescue nil
  540. cost_name = nil
  541. if card.note =~ /<card cost:\s*(.+?)>/i || card.note =~ /<spell_cost:\s*(.+?)>/i
  542. cost_name = $1.to_s.strip.downcase
  543. end
  544. impact_name = nil
  545. if resp[:trigger_type] == :faceup || resp[:trigger_type] == :set_and_faceup
  546. if card.note =~ /<faceup_impact:\s*(.+?)>/i
  547. impact_name = $1.to_s.strip.downcase
  548. end
  549. else
  550. if card.note =~ /<card impact:\s*(.+?)>/i || card.note =~ /<spell_impact:\s*(.+?)>/i || card.note =~ /<field_impact:\s*(.+?)>/i
  551. impact_name = $1.to_s.strip.downcase
  552. end
  553. end
  554. @skill = card
  555. @item = card
  556. @selected_card = card
  557. @active_effect_card = card
  558. @current_processing_card = card
  559. $temp_active_card = card
  560. $chain_memory_card = card
  561. @active_effect_zone_type = :spell
  562. @active_effect_zone_index = idx
  563. @current_quick_owner = player
  564. if cost_name
  565. @current_card_action = :card_cost
  566. $chain_memory_card.instance_variable_set(:@quick_queued_impact, impact_name) if impact_name
  567. invoke_card_cost(cost_name)
  568. elsif impact_name
  569. @current_card_action = :field_effect
  570. invoke_card_impact(impact_name)
  571. else
  572. @is_interrupt_effect = false
  573. end
  574. end
  575. end
  576.  
  577. def on_quick_no
  578. puts "[DEBUG] on_quick_no: Jugador canceló la respuesta."
  579. @quick_prompt.close
  580. @quick_prompt.deactivate
  581. @quick_prompt.visible = false
  582. @is_interrupt_effect = false
  583. @activation_notice.visible = false
  584. @card_preview.visible = false
  585. end
  586.  
  587. def gather_quick_responses(enemy_item, target = nil)
  588. valid_responses = []
  589. $game_party.battle_members.each do |player|
  590. next unless player.alive?
  591. if player.respond_to?(:hand)
  592. player.hand.each do |card|
  593. if card.note =~ /<quick_response_hand:\s*(.+?)>/i
  594. valid_responses << {:card => card, :source => :hand, :aura => $1.to_s.strip.downcase.to_sym, :owner => player}
  595. end
  596. end
  597. end
  598. if player.respond_to?(:st_zones)
  599. player.st_zones.each_with_index do |card, index|
  600. next unless card
  601. state = player.st_zones_state[index]
  602. next unless state
  603. next unless player.can_pay_card_cost?(card)
  604. set_cond = card.note =~ /<quick_response_set:\s*(.+?)>/i ? $1.to_s.strip.downcase : nil
  605. faceup_cond = card.note =~ /<quick_response_faceup:\s*(.+?)>/i ? $1.to_s.strip.downcase : nil
  606. set_met = false
  607. faceup_met = false
  608. if set_cond == "any" || (set_cond == "attack" && enemy_item && enemy_item.id == 1)
  609. set_met = true
  610. elsif set_cond =~ /attack_dmg_(\d+)/ && enemy_item && enemy_item.id == 1 && target
  611. threshold = $1.to_i
  612. expected_dmg = [eval(enemy_item.damage.formula), 0].max rescue 0
  613. set_met = true if expected_dmg >= threshold
  614. end
  615. if faceup_cond == "any" || (faceup_cond == "attack" && enemy_item && enemy_item.id == 1)
  616. faceup_met = true
  617. elsif faceup_cond =~ /attack_dmg_(\d+)/ && enemy_item && enemy_item.id == 1 && target
  618. threshold = $1.to_i
  619. expected_dmg = [eval(enemy_item.damage.formula), 0].max rescue 0
  620. faceup_met = true if expected_dmg >= threshold
  621. end
  622. if state[:face_down]
  623. if set_met
  624. valid_responses << {:card => card, :source => :field, :index => index, :owner => player, :was_face_down => true, :trigger_type => :set, :condition => set_cond}
  625. if faceup_met
  626. valid_responses << {:card => card, :source => :field, :index => index, :owner => player, :was_face_down => true, :trigger_type => :set_and_faceup, :condition => faceup_cond}
  627. end
  628. end
  629. else
  630. if faceup_met
  631. valid_responses << {:card => card, :source => :field, :index => index, :owner => player, :was_face_down => false, :trigger_type => :faceup, :condition => faceup_cond}
  632. end
  633. end
  634. end
  635. end
  636. end
  637. return valid_responses
  638. end
  639.  
  640. alias pc27_post_dmg_invoke_item invoke_item
  641. def invoke_item(target, item)
  642. pc27_post_dmg_invoke_item(target, item)
  643.  
  644. # Si el que recibió el ataque es un Actor y perdió HP
  645. if $game_party.in_battle && target.is_a?(Game_Actor) && target.result.hp_damage > 0
  646. check_damage_responses(target)
  647. end
  648. end
  649.  
  650. # 2. Mostramos el menú SOLAMENTE al jugador herido
  651. def check_damage_responses(target)
  652. return if @is_interrupt_effect
  653. puts "[DEBUG] check_damage_responses: Evaluando daño en #{target.name}"
  654. responses = gather_damage_responses(target)
  655. return if responses.empty?
  656.  
  657. @skill_window.hide.deactivate if @skill_window
  658. @card_select_window.hide.deactivate if @card_select_window
  659. @actor_command_window.hide.deactivate if @actor_command_window
  660.  
  661. @activation_notice.display_damage_activation(target)
  662. @quick_prompt.set_responses(responses)
  663. @quick_prompt.visible = true
  664. @quick_prompt.open
  665. @quick_prompt.activate
  666. @quick_prompt.select(0)
  667.  
  668. # Igual que arriba, solo esperamos al Sí o No.
  669. update_basic while @quick_prompt.active
  670.  
  671. @activation_notice.visible = false
  672. end
  673.  
  674. # 3. Recolectamos trampas con la etiqueta de Daño exclusivas del herido
  675. def gather_damage_responses(player)
  676. valid_responses = []
  677. return valid_responses unless player && player.alive?
  678.  
  679. if player.respond_to?(:st_zones)
  680. player.st_zones.each_with_index do |card, index|
  681. next unless card
  682. state = player.st_zones_state[index]
  683.  
  684. # Debe estar seteada boca abajo y tener la etiqueta de daño
  685. if state && state[:face_down]
  686. if card.note =~ /<quick_response_damage>/i
  687.  
  688. next unless player.can_pay_card_cost?(card)
  689.  
  690. valid_responses << {:card => card, :source => :field, :index => index, :owner => player}
  691. end
  692. end
  693. end
  694. end
  695.  
  696. return valid_responses
  697. end
  698.  
  699. alias archo_ygo_freeze_scene_update update unless method_defined?(:archo_ygo_freeze_scene_update)
  700. def update
  701. if @is_interrupt_effect
  702. # Si estamos en modo interrupción, SOLO actualizamos las ventanas.
  703. # El 'return' evita que Yanfly procese turnos o ataques enemigos.
  704. update_basic
  705. return
  706. end
  707. archo_ygo_freeze_scene_update
  708. end
  709.  
  710. alias pc27_qe_force_cleanup execute_finish_proceed_cleanup unless method_defined?(:pc27_qe_force_cleanup)
  711. def execute_finish_proceed_cleanup
  712. if @is_interrupt_effect
  713. card = @active_effect_card || @skill || @selected_card
  714. player = @active_effect_owner || @current_quick_owner || $game_party.members[0]
  715. if card && [24, 25, 29, 31].include?(card.subtype)
  716. if player && player.st_zones
  717. idx_to_clear = nil
  718. if @active_effect_zone_type == :spell && @active_effect_zone_index
  719. if player.st_zones[@active_effect_zone_index] && player.st_zones[@active_effect_zone_index].equal?(card)
  720. idx_to_clear = @active_effect_zone_index
  721. end
  722. end
  723. if idx_to_clear && player.st_zones[idx_to_clear]
  724. actual_card = player.st_zones[idx_to_clear]
  725. player.st_zones[idx_to_clear] = nil
  726. idx_field = player.field.index { |c| c && c.equal?(actual_card) }
  727. player.field.delete_at(idx_field) if idx_field
  728. player.grave.push(actual_card) unless player.grave.any? { |c| c.equal?(actual_card) }
  729. @field_map_window.refresh if defined?(@field_map_window) && @field_map_window
  730. @minifield_window.refresh if defined?(@minifield_window) && @minifield_window
  731. end
  732. end
  733. end
  734. end
  735. pc27_qe_force_cleanup
  736. end
  737.  
  738. end
Advertisement
Comments
  • User was banned
  • User was banned
  • User was banned
Add Comment
Please, Sign In to add comment