Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- =begin
- ==============================================================================
- ** Battle Summons
- Author: Tsukihime
- Date: Jul 10, 2012
- ------------------------------------------------------------------------------
- ** Change log
- Jul 10
- -added summon_only_battle to game system as a flag
- Jun 24
- -fixed enemy summoning: only refresh newly summoned sprites
- Jun 12
- -assign specific summons to items/skills
- -summon ID is now the same as the actor ID
- -added remove summon functionality.
- May 30
- -summon limits and type limits added
- -summons recover all after battle
- -summon implemented as a skill
- -added Command Setup compatibility
- -added enemy summons
- -summon equip menu added
- May 20
- -option to remove all actors when summon appears
- -actors will return when the summon disappears
- May 19
- -Created summon scene/window
- -added summon command
- -summons are now treated as actors and level accordingly
- May 18
- -Initial release
- ------------------------------------------------------------------------------
- Summon battlers to fight for you!
- In the configuration, designate skills that should be treated as
- "summon skills". Then set up the skill in the database.
- Enemies can also be set up to use the summon skill.
- They will need a list of enemy ID's to choose from.
- Tag enemies with the enemy ID's they should summon
- <summons: 1,2,3>
- Then give them the summon skill in their action list
- To add a summon to your party, use the script call
- $game_party.add_summon(summon_id)
- To remove a summon from your party,
- $game_party.remove_summon(summon_id)
- To force summon a party to battle, use the call
- $game_summons.summon(id)
- ==============================================================================
- =end
- $imported = {} if $imported.nil?
- $imported["Tsuki_BattleSummon"] = true
- #==============================================================================
- # ** Configuration.
- #==============================================================================
- module Tsuki
- module Battle_Summon
- # Skill IDs that are treated as summon skills
- Summon_Skill = [3, 4, 17,18]
- Summon_Item = []
- Summon_Constraints =
- {[:skill, 3] => [3], [:skill, 4] => [4], [:skill, 17] => [5], [:skill, 18] => [6]}
- # variable used to determine the number of turns summoned
- Default_Summon_Turns = 99
- Summon_Turn_Variable = 1
- Summon_Limit = 2 # How many summons you can have in battle
- Summon_Type_Limit = 2 # How many different summons you can have in battle
- # Messages to display on successful summon in battle
- # format [user name], [summon name]
- Summon_Message = "%s has called %s to battle!"
- # Should the summon command be shown in battle?
- Enable_Summon_Command = false
- # party members leave when a summon appears
- Summon_Only_Battle = false
- # Monster Hunter add-on requires that script. It adds all captured monsters
- # to your summon list rather than the party list.
- Monster_Hunter_Addon = false
- #==============================================================================
- # ** Rest of the Script
- #==============================================================================
- def self.summon_effect?(item)
- return Summon_Skill.include?(item.id) if item.is_a?(RPG::Skill)
- return Summon_Item.include?(item.id) if item.is_a?(RPG::Item)
- return false
- end
- Enemy_Summon_Regex = /<summons:?\s*(.*)\s*>/i
- Summon_Limit_Regex = /<summon-max:?\s*(\d+)\s*>/i
- Summon_ID_Regex = /<summon:?\s*(\d+)\s*>/i
- end
- end
- module RPG
- class Actor < BaseItem
- def summon_limit
- return @summon_limit unless @summon_limit.nil?
- res = Tsuki::Battle_Summon::Summon_Limit_Regex.match(self.note)
- return @summon_limit = res ? res[1].to_i : 99
- end
- end
- class Enemy < BaseItem
- def enemy_summons
- return @enemy_summon unless @enemy_summon.nil?
- return @enemy_summon = load_notetags_enemy_summons
- end
- def load_notetags_enemy_summons
- summons = []
- self.note.split(/[\r\n]+/).each do |line|
- case line
- when Tsuki::Battle_Summon::Enemy_Summon_Regex
- $1.scan(/\d+/).each {|id| summons << id.to_i}
- end
- end
- return summons
- end
- end
- class UsableItem < BaseItem
- def summon_id
- return @summon_id unless @summon_id.nil?
- res = Tsuki::Battle_Summon::Summon_ID_Regex.match(self.note)
- return @summon_id = res ? res[1].to_i : 0
- end
- end
- end
- module DataManager
- class << self
- alias :tsuki_battle_summon_create_objects :create_game_objects
- alias :tsuki_battle_summon_make_save_contents :make_save_contents
- alias :tsuki_battle_summon_extract_save_contents :extract_save_contents
- end
- def self.create_game_objects
- tsuki_battle_summon_create_objects
- $game_summons = Game_Summons.new
- end
- def self.make_save_contents
- contents = tsuki_battle_summon_make_save_contents
- contents[:summons] = $game_summons
- contents
- end
- def self.extract_save_contents(contents)
- tsuki_battle_summon_extract_save_contents(contents)
- $game_summons = contents[:summons]
- end
- end
- module BattleManager
- class << self
- alias :tsuki_battle_summon_turn_end :turn_end
- alias :tsuki_battle_summon_gain_exp :gain_exp
- alias :tsuki_battle_summon_battle_end :battle_end
- end
- def self.turn_end
- tsuki_battle_summon_turn_end
- $game_summons.update_summons
- end
- def self.gain_exp
- tsuki_battle_summon_gain_exp
- $game_summons.battle_members.each do |summon|
- summon.gain_exp($game_troop.exp_total)
- end
- wait_for_message
- end
- def self.battle_end(result)
- tsuki_battle_summon_battle_end(result)
- $game_summons.on_battle_end
- end
- end
- class Spriteset_Battle
- def refresh_enemies
- new_enemies = $game_troop.members.reverse.collect do |enemy|
- @enemy_sprites << Sprite_Battler.new(@viewport1, enemy) if enemy.summoned?
- end
- end
- end
- class Game_System
- attr_accessor :summon_only_battle
- alias :th_battle_summon_init_system :initialize
- def initialize
- th_battle_summon_init_system
- @summon_only_battle = Tsuki::Battle_Summon::Summon_Only_Battle
- end
- end
- class Game_Action
- attr_accessor :summon_id #id of summon to call
- alias :th_battle_summon_clear_action :clear
- def clear
- th_battle_summon_clear_action
- @summon_id = 0
- end
- end
- class Game_ActionResult
- attr_accessor :called_summon
- alias :th_battle_summon_clear_results :clear
- def clear
- th_battle_summon_clear_results
- clear_summon_result
- end
- def clear_summon_result
- @called_summon = nil
- end
- def called_summon_text
- if @called_summon
- fmt = Tsuki::Battle_Summon::Summon_Message
- sprintf(fmt, @battler.name, @called_summon.name)
- else
- ""
- end
- end
- end
- class Game_Battler < Game_BattlerBase
- def is_summon_action?(item)
- return false unless item
- Tsuki::Battle_Summon.summon_effect?(item)
- end
- alias :th_summon_battler_item_apply :item_apply
- def item_apply(user, item)
- th_summon_battler_item_apply(user, item)
- summon_battler(user, item) if is_summon_action?(item)
- end
- def summon_battler(user, item)
- called_summon = user.friends_unit.summon_battler(user.actions[0].summon_id)
- if called_summon
- @result.success = true
- @result.called_summon = called_summon
- end
- end
- end
- class Game_Enemy < Game_Battler
- attr_accessor :just_summoned
- alias :th_battle_summon_init_enemy :initialize
- def initialize(index, enemy_id)
- th_battle_summon_init_enemy(index, enemy_id)
- @just_summoned = false
- init_summons
- end
- def summoned?
- if @just_summoned
- @just_summoned = false
- return true
- end
- return false
- end
- def init_summons
- @summons = enemy.enemy_summons
- end
- alias :th_battle_summon_make_enemy_actions :make_actions
- def make_actions
- th_battle_summon_make_enemy_actions
- @actions.each do |action|
- make_summon_action(action) if is_summon_action?(action.item)
- end
- end
- # pick a random target to draw a random magic from
- def make_summon_action(action)
- action.summon_id = @summons.sample
- end
- end
- class Game_Summon < Game_Actor
- attr_reader :summon_id
- attr_accessor :summon_turns
- attr_accessor :summon_index
- def initialize(actor_id)
- super(actor_id)
- @summon_id = actor_id
- @summon_turns = 0
- @summon_index = 0 # 0 if not summoned
- @dupe = false
- end
- def can_dupe?
- @dupe
- end
- def update_summon
- #~ @summon_turns -= 1
- #~ if @summon_turns <= 0 || @mp <= 0
- #~ $game_summons.unsummon(@summon_id)
- if @mp == 0; add_state(2)
- end
- end
- def die
- $game_summons.unsummon(@summon_id)
- super
- end
- def index
- $game_summons.members.index(self)
- end
- end
- class Game_Summons < Game_Unit
- include Tsuki::Battle_Summon
- def initialize
- @data = [nil]
- @ids = [nil]
- @dispatched = []
- @summon_count = 0 #how many summons are on the field
- @limit = Summon_Limit
- @type_limit = Summon_Type_Limit
- @menu_actor_id = 0
- end
- def [](summon_id)
- @data[summon_id] ||= Game_Summon.new(summon_id)
- end
- def members
- in_battle ? battle_members : all_summons
- end
- def all_summons
- @data.select {|summon| !summon.nil?}
- end
- # summons that are currently in battle
- def battle_members
- @dispatched.collect {|id| @data[id]}
- end
- def summon_actor(id)
- return if @ids.include?(id)
- summon = Game_Summon.new(id)
- @data[id] = summon
- @ids << id
- end
- def unsummon(id)
- return unless @dispatched.include?(id)
- @dispatched.delete_at(@data[id].summon_index - 1)
- @data[id].summon_index = 0
- @summon_count -= 1
- end
- def summon(id)
- return 0 unless @data[id]
- @data[id].summon_turns = [Default_Summon_Turns, $game_variables[Summon_Turn_Variable]].max
- @data[id].make_actions
- @summon_count += 1
- @data[id].summon_index = @summon_count
- @dispatched << id
- return id
- end
- def can_summon?(summon_id)
- return false if @data[summon_id].nil?
- return false if @summon_count >= @limit
- return false if @dispatched.include?(summon_id) && !@data[summon_id].can_dupe?
- return true
- end
- def update_summons
- members.each {|summon| summon.update_summon}
- end
- def on_battle_end
- alive_members.each {|summon| summon.remove_state(2) }
- @dispatched = []
- @summon_count = 0
- end
- def menu_actor
- @data[@menu_actor_id] || members[0]
- end
- def menu_actor=(summon)
- return unless summon
- @menu_actor_id = summon.summon_id
- end
- def menu_actor_next
- index = members.index(menu_actor) || -1
- index = (index + 1) % members.size
- self.menu_actor = members[index]
- end
- def menu_actor_prev
- index = members.index(menu_actor) || 1
- index = (index + members.size - 1) % members.size
- self.menu_actor = members[index]
- end
- end
- class Game_Party < Game_Unit
- include Tsuki::Battle_Summon
- alias tsuki_battle_summon_initialize_party initialize
- def initialize
- tsuki_battle_summon_initialize_party
- @summons = []
- end
- alias tsuki_battle_summon_battle_members battle_members
- def battle_members
- summons = $game_summons.battle_members
- if $game_system.summon_only_battle
- summons.empty? ? tsuki_battle_summon_battle_members : summons
- else
- members = tsuki_battle_summon_battle_members
- members.concat(summons)
- end
- end
- def summons
- @summons.collect {|id| $game_summons[id]}
- end
- # try to call a summon, return summoned_id if successful
- def summon_battler(id)
- return unless $game_summons.can_summon?(id)
- summoned_id = $game_summons.summon(id)
- return $game_summons[summoned_id]
- end
- def add_summon(summon_id)
- $game_summons.summon_actor(summon_id)
- @summons.push(summon_id) unless @summons.include?(summon_id)
- end
- def remove_summon(summon_id)
- @summons.delete(summon_id)
- end
- def clear_summons
- @summons = []
- end
- end
- class Game_Troop < Game_Unit
- # create a new enemy on the spot
- def summon_battler(enemy_id)
- return unless $data_enemies[enemy_id]
- new_enemy = Game_Enemy.new(@enemies.size, enemy_id)
- new_enemy.just_summoned = true
- new_enemy.screen_x = rand(Graphics.width / 2) + 100
- new_enemy.screen_y = rand(Graphics.height / 2) + 100
- @enemies.push(new_enemy)
- SceneManager.scene.refresh_enemies
- return new_enemy
- end
- end
- class Game_Interpreter
- def add_actor_summon(actor_id)
- $game_party.add_summon(actor_id)
- end
- def summon_battler(summon_id)
- $game_party.summon_battler(summon_id)
- end
- end
- #==============================================================================
- # ** Menu windows and scenes
- #==============================================================================
- class Window_SummonList < Window_Selectable
- #--------------------------------------------------------------------------
- # * Object Initialization
- #--------------------------------------------------------------------------
- def initialize(x, y, width, height)
- super
- @actor = nil
- @data = []
- refresh
- end
- #--------------------------------------------------------------------------
- # * Set Category
- #--------------------------------------------------------------------------
- def actor=(actor)
- return if @actor == actor
- @actor = actor
- refresh
- self.oy = 0
- end
- #--------------------------------------------------------------------------
- # * Get Digit Count
- #--------------------------------------------------------------------------
- def col_max
- return 2
- end
- def item_height
- 104
- end
- #--------------------------------------------------------------------------
- # * Get Number of Items
- #--------------------------------------------------------------------------
- def item_max
- @data ? @data.size : 1
- end
- #--------------------------------------------------------------------------
- # * Get Item
- #--------------------------------------------------------------------------
- def item
- @data && index >= 0 ? @data[index] : nil
- end
- #--------------------------------------------------------------------------
- # * Get Activation State of Selection Item
- #--------------------------------------------------------------------------
- def current_item_enabled?
- enable?(@data[index])
- end
- def enable?(summon)
- summon && !$game_summons.battle_members.include?(summon) && summon.mp > 0
- end
- def select_last
- select(0)
- end
- def make_item_list(constraint=nil)
- @data = $game_party.summons
- if constraint
- valid_summons = Tsuki::Battle_Summon::Summon_Constraints[constraint] || []
- @data = @data.select {|s| valid_summons.include?(s.summon_id) }
- end
- end
- def draw_item(index)
- summon = @data[index]
- if summon
- rect = item_rect(index)
- rect.width -= 4
- draw_summon_basic(summon, rect.x + 4, rect.y, enable?(summon))
- draw_actor_face(summon, rect.x + rect.width - 96, rect.y)
- end
- end
- def draw_summon_name(summon, x, y, enabled, width = 112)
- change_color(normal_color, enabled)
- draw_text(x, y, width, line_height, summon.name)
- end
- def draw_summon_basic(summon, x, y, enabled=true, width=172)
- return unless summon
- text_width = text_size(summon.name).width
- draw_summon_name(summon, x, y + line_height*0, enabled)
- draw_actor_level(summon, x, y + line_height*1)
- draw_actor_hp(summon, x, y + line_height*2)
- draw_actor_mp(summon, x, y + line_height*3)
- end
- def update_help
- @help_window.set_item(item)
- end
- def refresh(constraint=nil)
- make_item_list(constraint)
- create_contents
- draw_all_items
- end
- end
- class Window_SummonCommand < Window_HorzCommand
- def window_width
- Graphics.width
- end
- def make_command_list
- add_command("Equip", :equip)
- add_command("Skill", :skill)
- add_command("Status", :status)
- end
- end
- class Scene_Summons < Scene_MenuBase
- def start
- super
- create_summon_command
- create_summon_window
- end
- def create_summon_command
- @summon_command = Window_SummonCommand.new(0, 0)
- @summon_command.set_handler(:cancel, method(:return_scene))
- @summon_command.set_handler(:equip, method(:command_personal))
- @summon_command.set_handler(:skill, method(:command_personal))
- @summon_command.set_handler(:status, method(:command_personal))
- end
- def create_summon_window
- wy = @summon_command.height
- width = Graphics.width
- height = Graphics.height - wy
- @summon_window = Window_SummonList.new(0, wy, width, height)
- end
- def command_personal
- @summon_window.select_last
- @summon_window.activate
- @summon_window.set_handler(:ok, method(:on_personal_ok))
- @summon_window.set_handler(:cancel, method(:on_personal_cancel))
- end
- def on_personal_ok
- $game_summons.menu_actor = @summon_window.item
- case @summon_command.current_symbol
- when :equip
- SceneManager.call(Scene_SummonEquip)
- when :skill
- SceneManager.call(Scene_SummonSkill)
- when :status
- SceneManager.call(Scene_SummonStatus)
- end
- end
- def on_personal_cancel
- @summon_window.unselect
- @summon_command.activate
- end
- end
- class Scene_SummonSkill < Scene_Skill
- def start
- super
- @actor = $game_summons.menu_actor
- on_actor_change
- end
- def next_actor
- @actor = $game_summons.menu_actor_next
- on_actor_change
- end
- def prev_actor
- @actor = $game_summons.menu_actor_prev
- on_actor_change
- end
- end
- class Scene_SummonEquip < Scene_Equip
- def start
- super
- @actor = $game_summons.menu_actor
- on_actor_change
- end
- def next_actor
- @actor = $game_summons.menu_actor_next
- on_actor_change
- end
- def prev_actor
- @actor = $game_summons.menu_actor_prev
- on_actor_change
- end
- end
- class Scene_SummonStatus < Scene_Status
- def start
- super
- @actor = $game_summons.menu_actor
- on_actor_change
- end
- def next_actor
- @actor = $game_summons.menu_actor_next
- on_actor_change
- end
- def prev_actor
- @actor = $game_summons.menu_actor_prev
- on_actor_change
- end
- end
- #==============================================================================
- # ** Battle windows and scenes
- #==============================================================================
- class Window_BattleSummon < Window_SummonList
- def initialize(help_window, info_viewport)
- y = 0
- super(0, y, Graphics.width, info_viewport.rect.y - y)
- self.visible = false
- @help_window = help_window
- @info_viewport = info_viewport
- select(0)
- end
- def enable?(summon)
- summon && $game_summons.can_summon?(summon.summon_id) && summon.mp > 0
- end
- end
- class Window_BattleStatus < Window_Selectable
- def content_height
- $game_party.battle_members.size * line_height - standard_padding * 2
- end
- alias tsuki_battle_summon_status_refresh refresh
- def refresh
- create_contents
- tsuki_battle_summon_status_refresh
- end
- end
- class Scene_Battle < Scene_Base
- def refresh_enemies
- @spriteset.refresh_enemies
- end
- alias :battle_summon_create_battle_windows :create_all_windows
- def create_all_windows
- battle_summon_create_battle_windows
- create_summon_window
- end
- def create_summon_window
- @summon_window = Window_BattleSummon.new(@help_window, @info_viewport)
- @summon_window.set_handler(:ok, method(:on_summon_ok))
- @summon_window.set_handler(:cancel, method(:on_summon_cancel))
- end
- alias :th_battle_summon_on_skill_ok :on_skill_ok
- def on_skill_ok
- @skill = @skill_window.item
- if Tsuki::Battle_Summon.summon_effect?(@skill)
- BattleManager.actor.input.set_skill(@skill.id)
- BattleManager.actor.last_skill.object = @skill
- @skill_window.hide
- if @skill.summon_id > 0
- BattleManager.actor.input.summon_id = @skill.summon_id
- next_command
- else
- activate_summon_window([:skill, @skill.id])
- end
- else
- th_battle_summon_on_skill_ok
- end
- end
- alias :th_battle_summon_on_item_ok :on_item_ok
- def on_item_ok
- @item = @item_window.item
- if Tsuki::Battle_Summon.summon_effect?(@item)
- BattleManager.actor.input.set_item(@item.id)
- $game_party.last_item.object = @item
- @item_window.hide
- if @item.summon_id > 0
- BattleManager.actor.input.summon_id = @skill.summon_id
- next_command
- else
- activate_summon_window([:item, @item.id])
- end
- else
- th_battle_summon_on_item_ok
- end
- end
- def command_summon
- activate_summon_window
- end
- def on_summon_ok
- BattleManager.actor.input.summon_id = @summon_window.item.summon_id
- @summon_window.hide
- next_command
- end
- def on_summon_cancel
- @summon_window.hide
- @skill_window.show.activate if @skill
- @item_window.show.activate if @item
- end
- def activate_summon_window(constraint=nil)
- @summon_window.refresh(constraint)
- @summon_window.show.activate
- end
- end
- class Window_BattleLog < Window_Selectable
- alias :th_battle_summon_display_damage :display_damage
- def display_damage(target, item)
- th_battle_summon_display_damage(target, item)
- display_summon_results(target, item)
- end
- def display_summon_results(target, item)
- return unless target.result.called_summon && Tsuki::Battle_Summon.summon_effect?(item)
- add_text(target.result.called_summon_text)
- wait
- end
- end
- #==============================================================================
- # ** Update menu scene to add option
- #==============================================================================
- class Window_MenuCommand < Window_Command
- #--------------------------------------------------------------------------
- # * Add arena command to List
- #--------------------------------------------------------------------------
- alias tsuki_summons_commands add_main_commands
- def add_main_commands
- tsuki_summons_commands
- add_command("Summons", :summons)
- end
- end
- class Scene_Menu < Scene_MenuBase
- #--------------------------------------------------------------------------
- # * Add arena handler
- #--------------------------------------------------------------------------
- alias tsuki_summons_command_window create_command_window
- def create_command_window
- tsuki_summons_command_window
- @command_window.set_handler(:summons, method(:command_summons))
- end
- def command_summons
- SceneManager.call(Scene_Summons)
- end
- end
- #==============================================================================
- # ** Compatibility mods
- #==============================================================================
- if $imported["FP_InventoryPlus"]
- class Scene_Battle < Scene_Base
- # directly use item from inventory
- def on_item_ok
- @item = @item_window.item
- if Tsuki::Battle_Summon.summon_effect?(@item)
- BattleManager.actor.input.set_item(@item)
- $game_party.last_item.object = @item
- @item_window.hide
- if @item.summon_id > 0
- BattleManager.actor.input.summon_id = @item.summon_id
- next_command
- else
- activate_summon_window([:item, @item.id])
- end
- else
- th_battle_summon_on_item_ok
- end
- end
- end
- end
- if $imported["Tsuki_CommandSetup"]
- class Scene_Battle < Scene_Base
- alias :th_battle_summon_command_use_skill :command_use_skill
- def command_use_skill
- @skill = $data_skills[@actor_command_window.current_data[:ext]]
- if Tsuki::Battle_Summon.summon_effect?(@skill)
- BattleManager.actor.input.set_skill(@skill.id)
- BattleManager.actor.last_skill.object = @skill
- @skill_window.hide
- if @skill.summon_id > 0
- BattleManager.actor.input.summon_id = @skill.summon_id
- next_command
- else
- activate_summon_window([:skill, @skill.id])
- end
- else
- th_battle_summon_command_use_skill
- end
- end
- def on_summon_cancel
- @enemy_draw_window.hide
- if @skill == $data_skills[@actor_command_window.current_data[:ext]]
- @actor_command_window.activate
- else
- @summon_window.hide
- @skill_window.show.activate
- end
- end
- end
- end
- #==============================================================================
- # ** Add-ons
- #==============================================================================
- if Tsuki::Battle_Summon::Monster_Hunter_Addon
- if $imported["Tsuki_MonsterHunter"]
- module Monster_Hunter
- def self.create_game_actor(actor_id)
- return if $BTEST
- $game_summons.summon_actor(actor_id)
- end
- end
- else
- msgbox("Monster Hunter must placed above this script")
- end
- end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement