#============================================================================== # ** Advanced_Targeting # processes targeting based on rules supplied by skills notes and the global # rules object #------------------------------------------------------------------------------ # by Steven Scott (geri_khan) # for instructions please see page # http://forums.rpgmakerweb.com/index.php?/topic/17950-advanced-skill-targeting/ # free for non-commercial use but please credit! #============================================================================== # THIS IS THE YANFLY'S COMPATIBLE VERSION # YOU WILL NEED THE ACE CORE ENGINE AND ACE BATTLE ENGINE # http://yanflychannel.wordpress.com/rmvxa/ # place this below both scripts in the Materials section # TWO IMPORTANT THINGS YOU NEED TO DO # 1) CHANGE THIS v v v v v v v v AST_FORCED_ACTION_STATE_ID = 28 # the state number of the forced action state. Without this, AST-induced # forced actions will not work and the script may be screwy. Create a state # that expires at turn end and battle end, and insert it's number there. # 2) YOU WILL ALSO REQUIRE SEVERAL IMAGES: # AN "INVALID CHOICE" IMAGE IN \system CALLED "crossout" # IT IS SCALED AUTOMATICALLY, SO SIZE DOES NOT MATTER # LEFT AND RIGHT ARROWS CALLED "moreleft" and "moreright" # ALSO IN \system # JUST ADD THEM THROUGH RESOURCE MANAGER# # FEEL FREE TO TAKE THE IMAGES FROM THE DEMO PROJECT, # EVEN THOUGH THEY BE BAD. AST_VERBOSE = true # determines whether you get lots of puts spam to your console about who's # picking what action AST_ALERT_WINDOW_TONE = Tone.new(128,0,0,0) # the colour of the Alert Window's background AST_DRAW_ENEMY_HP = true AST_DRAW_ENEMY_MP = true AST_DRAW_ENEMY_TP = true AST_DRAW_ENEMY_ICONS = true # specify if players can see various enemy details while choosing targets AST_SHOW_ALERT_ON_CURSOROVER = true # if true, immediately shows reasons why an enemy cannot be targeted when # the cursor is moved over the character, without waiting for the player # to attempt to select it AST_SHOW_UNTARGETABLE = false # if true, when a battler cannot be targeted they will appear in the targeting # window with your "crossout" icon over them. If false, they will not appear. AST_NO_TARGETS = "No available targets" # the string that will be displayed in yanfly's battle help and the Alert popup # if there are no targets at all AST_MAX_FACES = 8 # determines the maximum number of characters that will be displayed in the # Battle_Actor and Battle_Enemy screens before they are forced to scroll # instead of yanfly making the portraits any narrower class Advanced_Targeting < Game_Unit #-------------------------------------------------------------------------- # * Object Initialization #-------------------------------------------------------------------------- def initialize(targetside,actor,action,executing) #executing = false means the unit is being called to get a # targetlist to display #executing = true means the unit is being called to execute # an action super() $Targeting_Rules.reset_members @targetside = targetside @action = action @actor = actor @friends = @actor.friends_unit @opponents = @actor.opponents_unit @verbose = AST_VERBOSE @executing = executing setup end #-------------------------------------------------------------------------- # * Get Members #-------------------------------------------------------------------------- def members @targets end #-------------------------------------------------------------------------- # * Clear #-------------------------------------------------------------------------- def clear @targets = [] end #-------------------------------------------------------------------------- # * swap_if_confused # swaps friends and opponents in case of confusion. #-------------------------------------------------------------------------- def swap_if_confused case @actor.confusion_level when 3 @friends,@opponents = @opponents,@friends if @targetside == "friend" @targetside = "enemy" else @targetside = "friend" end when 2 if rand(2) == 0 # do nothing else @friends,@opponents = @opponents,@friends if @targetside == "friend" @targetside = "enemy" else @targetside = "friend" end end end end #-------------------------------------------------------------------------- # * Setup #-------------------------------------------------------------------------- def setup printf "\n\n" if @verbose == true puts @actor.name + " is getting a target list" if @verbose == true swap_if_confused if @action == nil basic_choice elsif @action.note.include? "ASTstart" advanced_choice else basic_choice end end #-------------------------------------------------------------------------- # * Basic Choice # used when no special rules are being applied #-------------------------------------------------------------------------- def basic_choice clear basic_friend basic_opponent @startat = 0 @targets.each do |member| if !member.state?(member.forced_action_state_id) member.ASTset_forced_action(-1) #member.ASTkillafter(0) if member.AST_kill_after <2 end end process_targeting_rules end #-------------------------------------------------------------------------- # * Basic friend # adds friends #-------------------------------------------------------------------------- def basic_friend if @targetside=="friend" push_unit(@friends.members) end end #-------------------------------------------------------------------------- # * basic opponent # adds opponents #-------------------------------------------------------------------------- def basic_opponent if @targetside=="enemy" push_unit(@opponents.members) end end #-------------------------------------------------------------------------- # * push unit # pushes supplied unit to the array of targets #-------------------------------------------------------------------------- def push_unit(unit) unit.each do |member| @targets.push(member) end end #-------------------------------------------------------------------------- # * process_targeting_rules # despite the name, processes global rules #-------------------------------------------------------------------------- def process_targeting_rules puts "*** starting global rules evaluation ***" if @verbose == true n=0 while n< $Targeting_Rules.rules.length @reason = $Targeting_Rules.reasons[n] evaluate_units($Targeting_Rules.rules[n]) n+=1 end end #-------------------------------------------------------------------------- # * advanced_choice # processes the more complex AST commands #-------------------------------------------------------------------------- def advanced_choice clear @startat = 0 @globalstartat = 0 forcedaction = -1 killafter = 0 randomise = false repeats = false randomnum = 0 @reason = "This creature is untargetable" puts "*** starting skill rules evaluation ***" if @verbose == true @action.note.split( /\n */ ).each do |line| puts line if @verbose == true bits=line.split( /: */ ) bits[1] = "" if bits.length==1 bits[0] = bits[0].chomp bits[1] = bits[1].chomp case when bits[0]=="ASTinclude" push_unit(@friends.members) if bits[1]=="friend" if bits[1]=="opponent" push_unit(@opponents.members) end push_unit($game_party.members) if bits[1]=="party" push_unit($game_troop.members) if bits[1]=="troop" when bits[0]=="ASTremove" evaluate_units(bits[1]) when bits[0]=="ASTpreserve" @startat = @targets.length when bits[0]=="ASTpreserveglobal" @globalstartat = @targets.length when bits[0]=="ASTforceaction" forcedaction = bits[1].to_i when bits[0]=="ASTkillafter" killafter = 1 when bits[0]=="ASTremovecaster" evaluate_units("a==b") when bits[0]=="ASTrandom" @targets = randomise(bits[1].to_i) if @executing == true when bits[0]=="ASTstart" @reason = bits[1] when bits[0]=="ASTreason" @reason = bits[1] end end $Targeting_Rules.puts_rules if @verbose == true @startat = @globalstartat process_targeting_rules @targets = @targets.uniq puts "--------------" if @verbose == true puts "VIABLE TARGETS" if @verbose == true @targets.each do |member| member.ASTkillafter(killafter) if @executing == true member.ASTset_forced_action(forcedaction) if @executing == true puts member.name + " forced action " + member.AST_forced_action.to_s if @verbose == true end puts "--------------" if @verbose == true end #-------------------------------------------------------------------------- # * evaluate_units # evaluates an ASTremove's code or global rule, and removes battlers # accordingly #-------------------------------------------------------------------------- def evaluate_units(code) n=@startat while n<@targets.size a=@actor b=@targets[n] if eval(code) puts "slicing " + @targets[n].name + " because " + code if @verbose == true @targets.slice!(n) b.set_reason(@reason) else n+=1 end end end #-------------------------------------------------------------------------- # * randomise # returns an array of n random targets #-------------------------------------------------------------------------- def randomise(number) n=0 preserved = [] randomized = [] while n<@targets.size if @targets[n].alive? and @targets[n].exist? preserved.push(@targets[n]) if n<@startat randomized.push(@targets[n]) if n>=@startat end n+=1 end number = [number,randomized.length].min randomized = randomized.shuffle return preserved + randomized.take(number) end end #============================================================================== # ** Targeting_Rules # manages global targeting rules # set @verbose = true for detailed puts spam in the console #------------------------------------------------------------------------------ # by Steven Scott (geri_khan) # for instructions please see page # http://forums.rpgmakerweb.com/index.php?/topic/17950-advanced-skill-targeting/ # free for non-commercial use but please credit! #============================================================================== class Targeting_Rules < Game_Unit #-------------------------------------------------------------------------- # * initialize #-------------------------------------------------------------------------- def initialize super @rules = [] @expiration = [] # never, oneturn, afterbattle @reasons = [] @verbose = AST_VERBOSE reset_members end #-------------------------------------------------------------------------- # * members #-------------------------------------------------------------------------- def members @members end #-------------------------------------------------------------------------- # * reset_members #-------------------------------------------------------------------------- def reset_members @members = [] @members = $game_troop.members + $game_party.members end #-------------------------------------------------------------------------- # * verbose # I heard you like puts, so I put puts in your puts and so on #-------------------------------------------------------------------------- def verbose @verbose end #-------------------------------------------------------------------------- # * rules #-------------------------------------------------------------------------- def rules @rules end #-------------------------------------------------------------------------- # * reasons #-------------------------------------------------------------------------- def reasons @reasons end #-------------------------------------------------------------------------- # * create_rule # creates a new rule, or updates an existing one #-------------------------------------------------------------------------- def create_rule(code,expires="never",reason) found = false n=0 code = code.gsub("\n", "") expires = expires.gsub("\n", "") reason = reason.gsub("\n", "") while n < @rules.length if @rules[n] == code @expiration[n] = expires @reasons[n] = reason found = true puts "Rule updated: " + @rules[n] + " expires " + @expiration[n] if @verbose == true end n+=1 end if found == false @rules.push(code) @expiration.push(expires) @reasons.push(reason) puts "Rule created: " + @rules.last + " expires " + @expiration.last if @verbose == true end end #-------------------------------------------------------------------------- # * remove_rule #-------------------------------------------------------------------------- def remove_rule(code) n=0 code = code.gsub("\n", "") while n < @rules.length if @rules[n] == code puts "Rule deleted: " + @rules[n] + " expires " + @expiration[n] if @verbose == true @rules.slice!(n) @expiration.slice!(n) @reasons.slice!(n) else n+=1 end end end #-------------------------------------------------------------------------- # * puts_rules # puts all rules to the console #-------------------------------------------------------------------------- def puts_rules return if @verbose == false puts "current global rules" n=0 while n < @rules.length puts n.to_s + ": " + @rules[n] + " expires " + @expiration[n] n+=1 end end #-------------------------------------------------------------------------- # * check expires #-------------------------------------------------------------------------- def check_expires(code,condition) # condition = "oneturn" or "afterbattle" n=0 while n < @rules.length if @expiration[n] == condition and @rules[n] == code puts "Rule expired: " + @rules[n] + " expires " + @expiration[n] if @verbose == true @rules.slice!(n) @expiration.slice!(n) @reasons.slice!(n) else n+=1 end end end #-------------------------------------------------------------------------- # * turn end # checks rule expiration on turn end #-------------------------------------------------------------------------- def turn_end $Targeting_Rules.rules.each do |rule| $Targeting_Rules.check_expires(rule,"oneturn") end end #-------------------------------------------------------------------------- # * after battle # checks rule expiration after battle #-------------------------------------------------------------------------- def after_battle $Targeting_Rules.rules.each do |rule| $Targeting_Rules.check_expires(rule,"afterbattle") end end end #============================================================================== # ** aliases and redefs # lots of little changes needed to make this work #------------------------------------------------------------------------------ # by Steven Scott (geri_khan) # for instructions please see page # # free for non-commercial use but please credit! #============================================================================== #-------------------------------------------------------------------------- # * Game_BattlerBase #-------------------------------------------------------------------------- class Game_BattlerBase #-------------------------------------------------------------------------- # * forced_action_state_id #-------------------------------------------------------------------------- def forced_action_state_id return AST_FORCED_ACTION_STATE_ID end end #-------------------------------------------------------------------------- # * Game_Battler #-------------------------------------------------------------------------- class Game_Battler attr_accessor :AST_forced_action # AST forced action attr_accessor :AST_kill_after # AST kill battler after acting, for exploding zombies etc attr_reader :unique_id # unique ID for this battler attr_reader :targeting_array # array of unique_ids that are the battler's action targets attr_reader :AST_reason # reason why battler could not be targeted #-------------------------------------------------------------------------- # * Clear - ALIAS #-------------------------------------------------------------------------- alias gk_AST_game_battler_initialize initialize def initialize gk_AST_game_battler_initialize @AST_forced_action = -1 @AST_kill_after = 0 set_default_reason generate_unique_id clear_targeting_array end #-------------------------------------------------------------------------- # * set default reason #-------------------------------------------------------------------------- def set_default_reason @AST_reason = "This creature is currently untargetable" end #-------------------------------------------------------------------------- # * generate unique ID #-------------------------------------------------------------------------- def generate_unique_id @unique_id = rand(100000) + rand(100000) end #-------------------------------------------------------------------------- # * Clear targeting array #-------------------------------------------------------------------------- def clear_targeting_array @targeting_array = [] end #-------------------------------------------------------------------------- # * make targets from unit # creates a targeting_array based on a unit #-------------------------------------------------------------------------- def make_targets_from_unit(unit) clear_targeting_array unit.each do |member| @targeting_array.push(member.unique_id) end end #-------------------------------------------------------------------------- # * get battler from targets #-------------------------------------------------------------------------- def get_battler_from_targets(battler_id) @targeting_array.index battler_id end #-------------------------------------------------------------------------- # * get unit # creates a unit, and performs target correction/smoothing if it does not # conform with the targeting array (IE battler and unit states have changed # between selecting a skill and it execting) #-------------------------------------------------------------------------- def get_unit(myside,action=nil,executing=false,targindex=nil) @targets=Advanced_Targeting.new(myside,self,action,executing) puts @targets.members.length return @targets if executing == false or targindex < 0 if @targeting_array.empty? make_targets_from_unit(@targets.members) end targbattler = @targeting_array[targindex] battlerindex = @targets.members.index{ |member| member.unique_id == targbattler } if battlerindex == nil @actions[0].target_index = -1 else @actions[0].target_index = battlerindex end @targets end #-------------------------------------------------------------------------- # * get menu entries # returns 2D-arrays of battlers and their selection status #-------------------------------------------------------------------------- def get_menu_entries(unit) source_index = @targeting_array.clone temp = [] negatives = 0 $Targeting_Rules.members.each do |member| n=source_index.index(member.unique_id) if n != nil if validate_targeting(member) or member.actor? temp.push([member,n]) end else if validate_targeting(member) or member.actor? temp.push([member,-10]) end end end final = [] postfinal = [] temp.each do |entry| temp_id = entry[0].unique_id n= unit.index{ |member| member.unique_id == temp_id } if n != nil final.push(entry) else postfinal.push(entry) if entry[1] != -10 end end final + postfinal end #-------------------------------------------------------------------------- # * validate targeting # determines whether a target is invalidated by death or visibility #-------------------------------------------------------------------------- def validate_targeting(subject) return true if BattleManager.actor.actions[0].item.for_dead_friend? and subject.actor? and subject.dead? return true if subject.alive? and subject.exist? return false end #-------------------------------------------------------------------------- # * set reason # set reason why this battler could not be targeted #-------------------------------------------------------------------------- def set_reason(reason) @AST_reason = reason end #-------------------------------------------------------------------------- # * on battle start - ALIAS #-------------------------------------------------------------------------- alias gk_AST_game_battler_on_battle_start on_battle_start def on_battle_start set_default_reason gk_AST_game_battler_on_battle_start generate_unique_id end #-------------------------------------------------------------------------- # * on action end - ALIAS #-------------------------------------------------------------------------- alias gk_AST_game_battler_on_action_end on_action_end def on_action_end gk_AST_game_battler_on_action_end clear_targeting_array end #-------------------------------------------------------------------------- # * on turn end - ALIAS #-------------------------------------------------------------------------- alias gk_AST_game_battler_on_turn_end on_turn_end def on_turn_end set_default_reason gk_AST_game_battler_on_turn_end end #-------------------------------------------------------------------------- # * die - ALIAS #-------------------------------------------------------------------------- alias gk_AST_game_battler_die die def die gk_AST_game_battler_die @AST_kill_after = 0 clear_targeting_array end #-------------------------------------------------------------------------- # * make_actions - ALIAS #-------------------------------------------------------------------------- alias gk_AST_game_battler_make_actions make_actions def make_actions @AST_forced_action = -1 remove_state(forced_action_state_id) @AST_kill_after = 0 gk_AST_game_battler_make_actions end #-------------------------------------------------------------------------- # * force action - ALIAS #-------------------------------------------------------------------------- alias gk_AST_game_battler_force_action force_action def force_action(skill_id, target_index) add_state(forced_action_state_id) if state?(forced_action_state_id) gk_AST_game_battler_force_action(skill_id, target_index) @AST_kill_after =2 if @AST_kill_after == 1 ASTset_forced_action(-1) end end #-------------------------------------------------------------------------- # * AST set forced action #-------------------------------------------------------------------------- def ASTset_forced_action(action) @AST_forced_action = action if @AST_forced_action == -1 end #-------------------------------------------------------------------------- # * AST kill after #-------------------------------------------------------------------------- def ASTkillafter(yeanay) @AST_kill_after = yeanay if @AST_kill_after == 0 end #-------------------------------------------------------------------------- # * AST reset #-------------------------------------------------------------------------- def AST_reset remove_state(forced_action_state_id) @AST_forced_action = -1 @AST_kill_after = 0 end #-------------------------------------------------------------------------- # * item_apply - ALIAS #-------------------------------------------------------------------------- alias gk_AST_game_battler_item_apply item_apply def item_apply(user, item) gk_AST_game_battler_item_apply(user,item) if @result.hit? and @AST_forced_action > -1 force_action(@AST_forced_action, -1) end end end #-------------------------------------------------------------------------- # * Game_Action #-------------------------------------------------------------------------- class Game_Action #-------------------------------------------------------------------------- # * Get Allied Units - ALIAS #-------------------------------------------------------------------------- alias gk_AST_game_action_friends_unit friends_unit def friends_unit gk_AST_game_action_friends_unit subject.get_unit("friend",@item.object,true,@target_index) end #-------------------------------------------------------------------------- # * Get Enemy Units - ALIAS #-------------------------------------------------------------------------- alias gk_AST_game_action_opponents_unit opponents_unit def opponents_unit gk_AST_game_action_opponents_unit subject.get_unit("enemy",@item.object,true,@target_index) end #-------------------------------------------------------------------------- # * make_targets - ALIAS # this method no longer protects against confusion when forcing # a battler to act. Be careful to remove it before calling forced # actions in events/scripts! #-------------------------------------------------------------------------- alias gk_AST_game_action_make_target make_targets def make_targets if forcing && subject.confusion? [confusion_target] end gk_AST_game_action_make_target end end class Game_Interpreter #-------------------------------------------------------------------------- # * add target rule # call this to add a new global targeting rule #-------------------------------------------------------------------------- def add_target_rule(code,expires="never",reason="This character is untargetable") $Targeting_Rules.create_rule(code, expires, reason) end #-------------------------------------------------------------------------- # * rem atrget rule # call this to remove a global targeting rule #-------------------------------------------------------------------------- def rem_target_rule(code,expires="never") $Targeting_Rules.remove_rule(code) end #-------------------------------------------------------------------------- # * force action #-------------------------------------------------------------------------- def command_339 iterate_battler(@params[0], @params[1]) do |battler| next if battler.death_state? battler.ASTset_forced_action(@params[2]) battler.force_action(@params[2], @params[3]) Fiber.yield while BattleManager.action_forced? end end end #-------------------------------------------------------------------------- # * Window_BattleActor #-------------------------------------------------------------------------- class Window_BattleActor #-------------------------------------------------------------------------- # * initialize - ALIAS #-------------------------------------------------------------------------- alias gk_AST_window_battleactor_initialize initialize def initialize(info_viewport, side = "friend") create_unit @unitgot = false @side = side @unitside = $game_party.battle_members if side == "friend" @unitside = $game_troop.alive_members if side == "enemy" gk_AST_window_battleactor_initialize(info_viewport) @leftcol = 0 end #-------------------------------------------------------------------------- # * item_max - ALIAS #-------------------------------------------------------------------------- alias gk_AST_window_battleactor_item_max item_max def item_max a=0 if defined? @entries and @entries.length > 0 a=@entries.length else a=gk_AST_window_battleactor_item_max end a end def cursor_right(wrap = false) return if @entries.length == 0 super cols = [col_max,AST_MAX_FACES,@entries.length].min if @index > @leftcol+(cols/2) @leftcol = [@index-(cols/2),@entries.length-cols].min end update_cursor quick_refresh end def cursor_left(wrap = false) return if @entries.length == 0 super cols = [col_max,AST_MAX_FACES,@entries.length].min if @index <= @leftcol+(cols/2)-1 @leftcol = [@index-(cols/2),0].max end update_cursor quick_refresh end def cursor_down(wrap = false) #do nothing end def cursor_up(wrap = false) #do nothing end def update_cursor super if !cursor_all and @index>= 0 rect = item_rect(@index).clone rect.x = rect.x - rect.width * @leftcol cursor_rect.set(rect) end if defined? @entries and @entries.length>0 entry = @entries[@index] if AST_SHOW_ALERT_ON_CURSOROVER == true and entry[1] == -10 SceneManager.scene.show_alert(enemy.AST_reason) elsif AST_SHOW_ALERT_ON_CURSOROVER == true SceneManager.scene.hide_alert end end end def recalc_left cols = [col_max,AST_MAX_FACES,@entries.length].min if @index > @leftcol+(cols/2) @leftcol = [@index-(cols/2),@entries.length-cols].min end if @index <= @leftcol+(cols/2)-1 @leftcol = [@index-(cols/2),0].max end end #-------------------------------------------------------------------------- # overwrite method: item_rect # overwitten to implement the AST_MAX_FACES option #-------------------------------------------------------------------------- def item_rect(index) rect = Rect.new rect.width = contents.width / [$game_party.max_battle_members,AST_MAX_FACES].min rect.height = contents.height rect.x = index * rect.width if YEA::BATTLE::BATTLESTATUS_CENTER_FACES rect.x += (contents.width - $game_party.members.size * rect.width) / 2 end rect.y = 0 return rect end #-------------------------------------------------------------------------- # * refresh - ALIAS #-------------------------------------------------------------------------- alias gk_AST_window_battleactor_refresh refresh def refresh create_unit if !defined? @entries or @entries.length == 0 draw_empty return end gk_AST_window_battleactor_refresh end def quick_refresh if !defined? @entries or @entries.length == 0 draw_empty return end gk_AST_window_battleactor_refresh end #-------------------------------------------------------------------------- # * activate - ALIAS #-------------------------------------------------------------------------- alias gk_AST_window_battleactor_activate activate def activate recalc_left update_cursor quick_refresh gk_AST_window_battleactor_activate #@leftcol = [[index,@entries.length-4].min,0].max select(-1) if @entries.length == 0 if select_all? @leftcol = 0 @scrollspeed = 0.02 else @scrollspeed = 0 end end #-------------------------------------------------------------------------- # * hide - ALIAS #-------------------------------------------------------------------------- alias gk_AST_window_battleactor_hide hide def hide gk_AST_window_battleactor_hide @unitgot = false end #-------------------------------------------------------------------------- # * create_unit # creates a unit and entries list to use to build the targets list #-------------------------------------------------------------------------- def create_unit if !defined? BattleManager.actor.actions[0] @unit = $game_party.battle_members elsif !defined? @unit or @unitgot == false @unit = BattleManager.actor.get_unit(@side,BattleManager.actor.actions[0].item,false).members BattleManager.actor.make_targets_from_unit(@unit) @entries=BattleManager.actor.get_menu_entries(@unitside) @unitgot = true end @entries.select! { |entry| entry[1] != -10 } if defined?(@entries) and !AST_SHOW_UNTARGETABLE end #-------------------------------------------------------------------------- # * draw_empty # having 0 items should no longer be an issue, but left in just in case #-------------------------------------------------------------------------- def draw_empty update_padding update_tone create_contents rect = Rect.new(0,0,contents_width,contents_height) draw_text(rect,AST_NO_TARGETS,1) end #-------------------------------------------------------------------------- # * draw_item - ALIAS #-------------------------------------------------------------------------- # not totally happy with this aliasing, since under normal circumstances # the script will never call the alias. But best I can think of. alias gk_AST_window_battleactor_draw_item draw_item def draw_item(index) if index==0 update_padding update_tone create_contents end #return if index <= @leftcol-1 if !defined? @entries or $Targeting_Rules.members.length == 0 gk_AST_window_battleactor_draw_item(index) else entry = @entries[index] return if index.nil? clear_item(index) actor = entry[0] rect = item_rect(index) rect.x = rect.x - rect.width * @leftcol return if actor.nil? # drawing actor details next if actor.actor? draw_actor_face(actor, rect.x+2, rect.y+2, actor.alive?) draw_crossout(rect) if entry[1] == -10 draw_actor_action(actor, rect.x, rect.y) draw_actor_icons(actor, rect.x, line_height*1, rect.width) gx = YEA::BATTLE::BATTLESTATUS_HPGAUGE_Y_PLUS contents.font.size = YEA::BATTLE::BATTLESTATUS_TEXT_FONT_SIZE draw_actor_hp(actor, rect.x+2, line_height*2+gx, rect.width-4) if draw_tp?(actor) && draw_mp?(actor) dw = rect.width/2-2 dw += 1 if $imported["YEA-CoreEngine"] && YEA::CORE::GAUGE_OUTLINE draw_actor_tp(actor, rect.x+2, line_height*3, dw) dw = rect.width - rect.width/2 - 2 draw_actor_mp(actor, rect.x+rect.width/2, line_height*3, dw) elsif draw_tp?(actor) && !draw_mp?(actor) draw_actor_tp(actor, rect.x+2, line_height*3, rect.width-4) else draw_actor_mp(actor, rect.x+2, line_height*3, rect.width-4) end end # drawing enemy details next if actor.enemy? enemyrect = Rect.new(rect.x+2,rect.y+2,rect.width-4,rect.height-4) SceneManager.scene.spriteset.draw_sprite_to_contents(actor,enemyrect,contents,255) draw_crossout(rect) if entry[1] == -10 gx = YEA::BATTLE::BATTLESTATUS_HPGAUGE_Y_PLUS contents.font.size = YEA::BATTLE::BATTLESTATUS_TEXT_FONT_SIZE draw_actor_icons(actor, rect.x, line_height*1, rect.width) if AST_DRAW_ENEMY_ICONS draw_actor_hp(actor, rect.x+2, line_height*2+gx, rect.width-4) if AST_DRAW_ENEMY_HP if AST_DRAW_ENEMY_TP && AST_DRAW_ENEMY_MP dw = rect.width/2-2 dw += 1 if $imported["YEA-CoreEngine"] && YEA::CORE::GAUGE_OUTLINE draw_actor_tp(actor, rect.x+2, line_height*3, dw) dw = rect.width - rect.width/2 - 2 draw_actor_mp(actor, rect.x+rect.width/2, line_height*3, dw) elsif AST_DRAW_ENEMY_TP && !AST_DRAW_ENEMY_MP draw_actor_tp(actor, rect.x+2, line_height*3, rect.width-4) elsif AST_DRAW_ENEMY_MP draw_actor_mp(actor, rect.x+2, line_height*3, rect.width-4) end end draw_actor_name(actor, rect.x, rect.y, rect.width-8) # draw the left and right arrow icons if @leftcol > 0 leftarrow = Cache.system("moreleft") rect = Rect.new(0,0,leftarrow.width,leftarrow.height) contents.blt(0, window_height/2-leftarrow.height,leftarrow,rect,255) end if @leftcol < @entries.length - AST_MAX_FACES rightarrow = Cache.system("moreright") rect = Rect.new(0,0,rightarrow.width,rightarrow.height) contents.blt(contents.width-rightarrow.width, window_height/2-rightarrow.height,rightarrow,rect,255) end end end #-------------------------------------------------------------------------- # * draw_crossout # draws an icon over a character's portrait indicating they cannot # be targeted. requires an image in System\ called "crossout" #-------------------------------------------------------------------------- def draw_crossout(rect) crossbmp = Cache.system("crossout") outrect = Rect.new(rect.x+5,rect.y+5,rect.width-10,rect.height-10) crossrect = Rect.new(0,0,crossbmp.width,crossbmp.height) contents.stretch_blt(outrect,crossbmp,crossrect) end #-------------------------------------------------------------------------- # * result # returns the index of the selected character #-------------------------------------------------------------------------- def result return -20 if @entries.length == 0 return -20 if @entries.count { |entry| entry[1] == -10 } == @entries.length return -2 if cursor_all entry = @entries[index] entry[1] end #-------------------------------------------------------------------------- # * enemy # despite name, returns details on both actors and enemies #-------------------------------------------------------------------------- def enemy if @entries.length > 0 entry = @entries[index] entry[0] else nil end end #-------------------------------------------------------------------------- # * update # taken directly from yanfly's and slightly modified to avoid crashes #-------------------------------------------------------------------------- def update super return unless active return if @entries.length == 0 return if enemy.actor? enemy.sprite_effect_type = :whiten return unless select_all? for enemy in $game_troop.alive_members enemy.sprite_effect_type = :whiten end return if @entries.length < 5 cols = [col_max,AST_MAX_FACES,@entries.length].min if Input.trigger?(:RIGHT) @leftcol = [@leftcol + 1,@entries.length-cols].min quick_refresh Sound.play_cursor end if Input.trigger?(:LEFT) @leftcol = [@leftcol-1,0].max quick_refresh Sound.play_cursor end end #-------------------------------------------------------------------------- # * select_all # also direct from Yanfly's, since I cut out the BattleEnemy window #-------------------------------------------------------------------------- def select_all? return true if @select_flag == :all return true if @select_flag == :random return false end end #-------------------------------------------------------------------------- # * Window_BattleEnemy # Window_BattleActor carries out all the functions of Window_BattleEnemy # now. This is mainly here for compatibility. #-------------------------------------------------------------------------- Object.send(:remove_const, :Window_BattleEnemy) class Window_BattleEnemy < Window_BattleActor def initialize(info_viewport,side="enemy") super(info_viewport,side) end end #-------------------------------------------------------------------------- # * Scene_Battle #-------------------------------------------------------------------------- class Scene_Battle # here's how it goes here. process_forced_action has been overwritten. # however it calls process_forced_action_beta, which calls the # the original process_forced_action though an alias. # hopefully that makes sense alias gk_AST_scene_battle_process_forced_action process_forced_action #-------------------------------------------------------------------------- # * process_forced_action_beta - KINDA ALIASED? #-------------------------------------------------------------------------- def process_forced_action_beta gk_forced = false gk_victimindex = -1 if BattleManager.action_forced? and BattleManager.next_action_forced_battler != nil gk_victim = BattleManager.next_action_forced_battler gk_victimindex = BattleManager.next_action_forced_battler.index gk_forced = true end reset_forced_actions(gk_victimindex) gk_AST_scene_battle_process_forced_action if gk_forced == true if gk_victim.AST_kill_after == 2 gk_victim.add_state(1) gk_victim.perform_collapse_effect if gk_victim.enemy? and gk_victim.state?(1) end end end #-------------------------------------------------------------------------- # * process forced action - KINDA ALIASED? #-------------------------------------------------------------------------- # this is not the original process_forced_action. It's a wrapper for the # original, which is now beta up there def process_forced_action escape = false n=0 actiontaken = false while escape == false member = all_battle_members[n] if member == subject and member.AST_forced_action > -1 and member.state?(member.forced_action_state_id) member.force_action(member.AST_forced_action,-1) end if member.state?(member.forced_action_state_id) and member.exist? and member.alive? BattleManager.force_action(member) process_forced_action_beta actiontaken = true end member.AST_reset n+=1 if n == all_battle_members.length escape = true if actiontaken == false n=0 if actiontaken == true actiontaken = false end end #process_forced_action_beta if BattleManager.action_forced? end #-------------------------------------------------------------------------- # * reset forced actions # removes @AST_forced_action and @AST_kill_after from everyone who does # not have a force action state, to tidy up #-------------------------------------------------------------------------- def reset_forced_actions(exemption=-1) n=0 while n= @closeat end #-------------------------------------------------------------------------- # * show #-------------------------------------------------------------------------- def show @closetimer = 0 @closeat = 150 super end #-------------------------------------------------------------------------- # * update tone #-------------------------------------------------------------------------- def update_tone self.tone.set(AST_ALERT_WINDOW_TONE) end #-------------------------------------------------------------------------- # * on actor cancel - ALIAS # thank you Napoleon! I assume you didn't have a problem with people # using this. # http://forums.rpgmakerweb.com/index.php?/topic/17735-problem-with-putting-a-string-in-a-string/#entry171348 #-------------------------------------------------------------------------- def wrap_text(txt, col = 80) txt.gsub(/(.{1,#{col}})( +|$\n?)|(.{1,#{col}})/,"\\1\\3\n") end end class Window_BattleHelp < Window_Help def update_battler_name return unless @actor_window.active || @enemy_window.active if @actor_window.active battler = @actor_window.enemy elsif @enemy_window.active battler = @enemy_window.enemy end if battler.nil? refresh_nil_name return end if special_display? refresh_special_case(battler) else refresh_battler_name(battler) if battler_name(battler) != @text end end def refresh_nil_name contents.clear reset_font_settings change_color(normal_color) @text = AST_NO_TARGETS #dy = icons.size <= 0 ? line_height / 2 : 0 dy = 0 draw_text(0, dy, contents.width, line_height, @text, 1) end end class Spriteset_Battle def draw_sprite_to_contents(battler, rect, contents, enabled) @enemy_sprites.each do |enemy| enemy.blt_to_contents(battler, rect, contents, enabled) end end end class Sprite_Battler def blt_to_contents(src_battler, rect, contents, enabled) if src_battler == @battler and @use_sprite == true cenx = bitmap.width/2 ceny = bitmap.height/2 rectox = cenx - rect.width/2 rectoy = ceny - rect.height/2 rectw = rectox + rect.width-4 recth = rectoy + rect.height-4 rect2 = Rect.new(rectox,rectoy,rectw,recth) contents.blt(rect.x,rect.y,bitmap,rect2,enabled) end end end class Game_Unit #-------------------------------------------------------------------------- # * return member # return's a member from a battler's unique ID #-------------------------------------------------------------------------- def return_member(battler_id) members.index {|member| member.unique_id == battler_id } end end